mirror of
https://github.com/mii443/RustySecrets.git
synced 2025-08-23 00:35:38 +00:00
Refactoring to keep same sanitisation of shares between lib & bin.
This commit is contained in:
@ -4,6 +4,7 @@ pub use std::io::prelude::*;
|
|||||||
use std::error;
|
use std::error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::num;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
@ -42,3 +43,10 @@ pub fn other_io_err(descr: &'static str, detail: Option<String>) -> io::Error {
|
|||||||
Error::new(descr, detail)
|
Error::new(descr, detail)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// maps a ParseIntError to an io::Error
|
||||||
|
pub fn pie2io(p: num::ParseIntError) -> io::Error {
|
||||||
|
convert::From::from(
|
||||||
|
Error::new("Integer parsing error", Some(p.to_string()))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -32,8 +32,54 @@ pub fn generate_shares(k: u8, n: u8, secret: Vec<u8>) -> io::Result<Vec<Vec<u8>>
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recover_secret(k: u8, shares: Vec<(u8,Vec<u8>)>) -> io::Result<Vec<u8>> {
|
pub fn process_shares(shares_strings: Vec<String>) -> io::Result<(u8, Vec<(u8,Vec<u8>)>)> {
|
||||||
assert!(!shares.is_empty());
|
let mut opt_k_l: Option<(u8, usize)> = None;
|
||||||
|
let mut counter = 0u8;
|
||||||
|
let mut shares: Vec<(u8,Vec<u8>)> = Vec::new();
|
||||||
|
|
||||||
|
for line in shares_strings {
|
||||||
|
let parts: Vec<_> = line.trim().split('-').collect();
|
||||||
|
if parts.len() < 3 || parts.len() > 4 {
|
||||||
|
return Err(other_io_err("Share parse error: Expected 3 or 4 \
|
||||||
|
parts separated by a minus sign", None));
|
||||||
|
}
|
||||||
|
let (k, n, p3) = {
|
||||||
|
let mut iter = parts.into_iter();
|
||||||
|
let k = try!(iter.next().unwrap().parse::<u8>().map_err(pie2io));
|
||||||
|
let n = try!(iter.next().unwrap().parse::<u8>().map_err(pie2io));
|
||||||
|
let p3 = iter.next().unwrap();
|
||||||
|
(k, n, p3)
|
||||||
|
};
|
||||||
|
if k < 1 || n < 1 {
|
||||||
|
return Err(other_io_err("Share parse error: Illegal K,N parameters", None));
|
||||||
|
}
|
||||||
|
let data = try!(
|
||||||
|
p3.from_base64().map_err(|_| other_io_err(
|
||||||
|
"Share parse error: Base64 decoding of data block failed", None ))
|
||||||
|
);
|
||||||
|
if let Some((ck, cl)) = opt_k_l {
|
||||||
|
if ck != k || cl != data.len() {
|
||||||
|
return Err(other_io_err("Incompatible shares", None));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
opt_k_l = Some((k, data.len()));
|
||||||
|
}
|
||||||
|
if shares.iter().all(|s| s.0 != n) {
|
||||||
|
shares.push((n, data));
|
||||||
|
counter += 1;
|
||||||
|
if counter == k {
|
||||||
|
return Ok((k, shares));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(other_io_err("Not enough shares provided!", None))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recover_secret(shares_strings: Vec<String>) -> io::Result<Vec<u8>> {
|
||||||
|
assert!(!shares_strings.is_empty());
|
||||||
|
|
||||||
|
let (k, shares) = try!(process_shares(shares_strings));
|
||||||
|
|
||||||
let slen = shares[0].1.len();
|
let slen = shares[0].1.len();
|
||||||
let mut col_in = Vec::with_capacity(k as usize);
|
let mut col_in = Vec::with_capacity(k as usize);
|
||||||
let mut secret = Vec::with_capacity(slen);
|
let mut secret = Vec::with_capacity(slen);
|
||||||
|
64
src/main.rs
64
src/main.rs
@ -4,12 +4,10 @@ use getopts::Options;
|
|||||||
|
|
||||||
use std::str;
|
use std::str;
|
||||||
use lib::custom_error::*;
|
use lib::custom_error::*;
|
||||||
use lib::serialize::base64::{ FromBase64 };
|
|
||||||
mod lib;
|
mod lib;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::num;
|
|
||||||
|
|
||||||
enum Action {
|
enum Action {
|
||||||
Encode(u8, u8), // k and n parameter
|
Encode(u8, u8), // k and n parameter
|
||||||
@ -117,58 +115,19 @@ fn perform_encode_from_io(k: u8, n: u8) -> io::Result<()> {
|
|||||||
return Ok(()) as io::Result<()>;
|
return Ok(()) as io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// reads shares from stdin and returns Ok(k, shares) on success
|
fn perform_decode_from_io() -> io::Result<()> {
|
||||||
/// where shares is a Vec<(u8, Vec<u8>)> representing x-coordinates
|
let stdin = io::stdin();
|
||||||
/// and share data.
|
|
||||||
fn read_shares() -> io::Result<(u8, Vec<(u8,Vec<u8>)>)> {
|
|
||||||
let stdin = io::stdin();
|
|
||||||
let stdin = io::BufReader::new(stdin.lock());
|
let stdin = io::BufReader::new(stdin.lock());
|
||||||
let mut opt_k_l: Option<(u8, usize)> = None;
|
let mut shares: Vec<String> = Vec::new();
|
||||||
let mut counter = 0u8;
|
|
||||||
let mut shares: Vec<(u8,Vec<u8>)> = Vec::new();
|
|
||||||
for line in stdin.lines() {
|
for line in stdin.lines() {
|
||||||
let line = try!(line);
|
match line {
|
||||||
let parts: Vec<_> = line.trim().split('-').collect();
|
Ok(share) => shares.push(share),
|
||||||
if parts.len() < 3 || parts.len() > 4 {
|
Err(_) => {}
|
||||||
return Err(other_io_err("Share parse error: Expected 3 or 4 \
|
|
||||||
parts separated by a minus sign", None));
|
|
||||||
}
|
|
||||||
let (k, n, p3) = {
|
|
||||||
let mut iter = parts.into_iter();
|
|
||||||
let k = try!(iter.next().unwrap().parse::<u8>().map_err(pie2io));
|
|
||||||
let n = try!(iter.next().unwrap().parse::<u8>().map_err(pie2io));
|
|
||||||
let p3 = iter.next().unwrap();
|
|
||||||
(k, n, p3)
|
|
||||||
};
|
|
||||||
if k < 1 || n < 1 {
|
|
||||||
return Err(other_io_err("Share parse error: Illegal K,N parameters", None));
|
|
||||||
}
|
|
||||||
let data = try!(
|
|
||||||
p3.from_base64().map_err(|_| other_io_err(
|
|
||||||
"Share parse error: Base64 decoding of data block failed", None ))
|
|
||||||
);
|
|
||||||
if let Some((ck, cl)) = opt_k_l {
|
|
||||||
if ck != k || cl != data.len() {
|
|
||||||
return Err(other_io_err("Incompatible shares", None));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
opt_k_l = Some((k, data.len()));
|
|
||||||
}
|
|
||||||
if shares.iter().all(|s| s.0 != n) {
|
|
||||||
shares.push((n, data));
|
|
||||||
counter += 1;
|
|
||||||
if counter == k {
|
|
||||||
return Ok((k, shares));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(other_io_err("Not enough shares provided!", None))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn perform_decode_from_io() -> io::Result<()> {
|
return match lib::recover_secret(shares) {
|
||||||
let (k, shares) = try!(read_shares());
|
|
||||||
|
|
||||||
return match lib::recover_secret(k, shares) {
|
|
||||||
Ok(secret) => {
|
Ok(secret) => {
|
||||||
let mut out = io::stdout();
|
let mut out = io::stdout();
|
||||||
try!(out.write_all(&*secret));
|
try!(out.write_all(&*secret));
|
||||||
@ -187,10 +146,3 @@ fn parse_k_n(s: &str) -> io::Result<(u8, u8)> {
|
|||||||
let n = try!(s2.parse().map_err(pie2io));
|
let n = try!(s2.parse().map_err(pie2io));
|
||||||
Ok((k, n))
|
Ok((k, n))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// maps a ParseIntError to an io::Error
|
|
||||||
fn pie2io(p: num::ParseIntError) -> io::Error {
|
|
||||||
convert::From::from(
|
|
||||||
Error::new("Integer parsing error", Some(p.to_string()))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user