tests and serialization fixes
This commit is contained in:
parent
f198e53891
commit
89c5d9f6f6
@ -161,8 +161,11 @@ pub enum KeyFileKdf {
|
||||
/// Encrypted password or other arbitrary message
|
||||
/// with settings for password derived key generator for decrypting content
|
||||
pub struct KeyFileCrypto {
|
||||
/// Cipher type
|
||||
pub cipher_type: CryptoCipherType,
|
||||
/// Cipher text (encrypted message)
|
||||
pub cipher_text: Bytes,
|
||||
/// password derived key geberator function settings
|
||||
pub kdf: KeyFileKdf,
|
||||
}
|
||||
|
||||
@ -173,10 +176,10 @@ impl KeyFileCrypto {
|
||||
Some(obj) => obj
|
||||
};
|
||||
|
||||
let cipher_type = match as_object["cipher"].as_string() {
|
||||
None => { return Err(CryptoParseError::NoCipherType); }
|
||||
let cipher_type = match try!(as_object.get("cipher").ok_or(CryptoParseError::NoCipherType)).as_string() {
|
||||
None => { return Err(CryptoParseError::InvalidCipherType(Mismatch { expected: "aes-128-ctr".to_owned(), found: "not a json string".to_owned() })); }
|
||||
Some("aes-128-ctr") => CryptoCipherType::Aes128Ctr(
|
||||
match as_object["cipherparams"].as_object() {
|
||||
match try!(as_object.get("cipherparams").ok_or(CryptoParseError::NoCipherParameters)).as_object() {
|
||||
None => { return Err(CryptoParseError::NoCipherParameters); },
|
||||
Some(cipher_param) => match U128::from_str(match cipher_param["iv"].as_string() {
|
||||
None => { return Err(CryptoParseError::NoInitialVector); },
|
||||
@ -194,7 +197,7 @@ impl KeyFileCrypto {
|
||||
}
|
||||
};
|
||||
|
||||
let kdf = match (as_object["kdf"].as_string(), as_object["kdfparams"].as_object()) {
|
||||
let kdf = match (try!(as_object.get("kdf").ok_or(CryptoParseError::NoKdf)).as_string(), try!(as_object.get("kdfparams").ok_or(CryptoParseError::NoKdfType)).as_object()) {
|
||||
(None, _) => { return Err(CryptoParseError::NoKdfType); },
|
||||
(Some("scrypt"), Some(kdf_params)) =>
|
||||
match KdfScryptParams::from_json(kdf_params) {
|
||||
@ -226,10 +229,23 @@ impl KeyFileCrypto {
|
||||
|
||||
fn to_json(&self) -> Json {
|
||||
let mut map = BTreeMap::new();
|
||||
map.insert("cipher_type".to_owned(), Json::String("aes-128-ctr".to_owned()));
|
||||
map.insert("cipher_text".to_owned(), Json::String(
|
||||
match self.cipher_type {
|
||||
CryptoCipherType::Aes128Ctr(iv) => {
|
||||
map.insert("cipher".to_owned(), Json::String("aes-128-ctr".to_owned()));
|
||||
let mut cipher_params = BTreeMap::new();
|
||||
cipher_params.insert("iv".to_owned(), Json::String(format!("{:?}", iv)));
|
||||
map.insert("cipherparams".to_owned(), Json::Object(cipher_params));
|
||||
}
|
||||
}
|
||||
map.insert("ciphertext".to_owned(), Json::String(
|
||||
self.cipher_text.iter().map(|b| format!("{:02x}", b)).collect::<Vec<String>>().join("")));
|
||||
map.insert("kdf".to_owned(), match self.kdf {
|
||||
|
||||
map.insert("kdf".to_owned(), Json::String(match self.kdf {
|
||||
KeyFileKdf::Pbkdf2(_) => "pbkdf2".to_owned(),
|
||||
KeyFileKdf::Scrypt(_) => "scrypt".to_owned()
|
||||
}));
|
||||
|
||||
map.insert("kdfparams".to_owned(), match self.kdf {
|
||||
KeyFileKdf::Pbkdf2(ref pbkdf2_params) => pbkdf2_params.to_json(),
|
||||
KeyFileKdf::Scrypt(ref scrypt_params) => scrypt_params.to_json()
|
||||
});
|
||||
@ -313,6 +329,7 @@ enum CryptoParseError {
|
||||
NoInitialVector,
|
||||
NoCipherParameters,
|
||||
InvalidInitialVector(FromHexError),
|
||||
NoKdf,
|
||||
NoKdfType,
|
||||
Scrypt(ScryptParseError),
|
||||
KdfPbkdf2(Pbkdf2ParseError)
|
||||
@ -340,6 +357,13 @@ impl KeyFileContent {
|
||||
}
|
||||
}
|
||||
|
||||
/// returns key file version if it is known
|
||||
pub fn version(&self) -> Option<u64> {
|
||||
match self.version {
|
||||
KeyFileVersion::V3(declared) => Some(declared)
|
||||
}
|
||||
}
|
||||
|
||||
fn from_json(json: &Json) -> Result<KeyFileContent, KeyFileParseError> {
|
||||
let as_object = match json.as_object() {
|
||||
None => { return Err(KeyFileParseError::InvalidJsonFormat); },
|
||||
@ -414,7 +438,7 @@ impl KeyDirectory {
|
||||
}
|
||||
|
||||
/// saves (inserts or updates) given key
|
||||
pub fn save(&mut self, key_file: KeyFileContent) -> Result<(), ::std::io::Error> {
|
||||
pub fn save(&mut self, key_file: KeyFileContent) -> Result<(Uuid), ::std::io::Error> {
|
||||
{
|
||||
let mut file = try!(fs::File::create(self.key_path(&key_file.id)));
|
||||
let json = key_file.to_json();
|
||||
@ -422,8 +446,9 @@ impl KeyDirectory {
|
||||
let json_bytes = json_text.into_bytes();
|
||||
try!(file.write(&json_bytes));
|
||||
}
|
||||
self.cache.insert(key_file.id.clone(), key_file);
|
||||
Ok(())
|
||||
let id = key_file.id.clone();
|
||||
self.cache.insert(id.clone(), key_file);
|
||||
Ok(id.clone())
|
||||
}
|
||||
|
||||
/// returns key given by id if corresponding file exists and no load error occured
|
||||
@ -491,7 +516,7 @@ impl KeyDirectory {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{KeyFileContent, KeyFileVersion, KeyFileKdf, KeyFileParseError, CryptoParseError, uuid_from_string, uuid_to_string};
|
||||
use super::{KeyFileContent, KeyFileVersion, KeyFileKdf, KeyFileParseError, CryptoParseError, uuid_from_string, uuid_to_string, KeyFileCrypto};
|
||||
use common::*;
|
||||
|
||||
#[test]
|
||||
@ -699,6 +724,24 @@ mod tests {
|
||||
Err(other_error) => { panic!("should be error of invalid initial vector, got {:?}", other_error); }
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_create_key_with_new_id() {
|
||||
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
|
||||
let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, U128::zero(), H256::random(), 32, 32));
|
||||
assert!(!uuid_to_string(&key.id).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_load_json_from_itself() {
|
||||
let cipher_text: Bytes = FromHex::from_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaa22222222222222222222222").unwrap();
|
||||
let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, U128::zero(), H256::random(), 32, 32));
|
||||
let json = key.to_json();
|
||||
|
||||
let loaded_key = KeyFileContent::from_json(&json).unwrap();
|
||||
|
||||
assert_eq!(loaded_key.id, key.id);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -710,9 +753,18 @@ mod specs {
|
||||
#[test]
|
||||
fn can_initiate_key_directory() {
|
||||
let temp_path = RandomTempPath::create_dir();
|
||||
|
||||
let directory = KeyDirectory::new(&temp_path.as_path());
|
||||
|
||||
assert!(directory.path().len() > 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_save_key() {
|
||||
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
|
||||
let temp_path = RandomTempPath::create_dir();
|
||||
let mut directory = KeyDirectory::new(&temp_path.as_path());
|
||||
|
||||
let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, U128::zero(), H256::random(), 32, 32)));
|
||||
|
||||
assert!(uuid.is_ok());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user