key directory

This commit is contained in:
Nikolay Volf 2016-02-12 01:43:37 +03:00
parent d9b6ab1128
commit 6cdc220406

View File

@ -18,6 +18,7 @@
//! module for managing key files, decrypting and encrypting arbitrary data //! module for managing key files, decrypting and encrypting arbitrary data
use common::*; use common::*;
use std::path::{PathBuf};
const CURRENT_DECLARED_VERSION: u64 = 3; const CURRENT_DECLARED_VERSION: u64 = 3;
@ -240,47 +241,83 @@ struct KeyFileContent {
struct KeyDirectory { struct KeyDirectory {
cache: HashMap<Uuid, KeyFileContent>, cache: HashMap<Uuid, KeyFileContent>,
path: Path path: Path,
} }
#[derive(Debug)] #[derive(Debug)]
enum KeyLoadError { enum KeyLoadError {
NotFound, NotFound,
FileTooBig(OutOfBounds<u64>), InvalidEncoding,
FileParseError(KeyFileParseError) FileTooLarge(OutOfBounds<u64>),
FileParseError(KeyFileParseError),
FileReadError(::std::io::Error)
} }
use std::fs;
impl KeyDirectory { impl KeyDirectory {
fn get(&mut self, id: Uuid) -> &KeyFileContent { fn key_path(&self, id: &Uuid) -> PathBuf {
match cache.get(id) { let mut path = self.path.to_path_buf();
Ok(content) => content, path.push(&id);
None => { path
match self.load(id) { }
} fn save(&mut self, key_file: KeyFileContent) -> Result<(), ::std::io::Error> {
cache.insert(loaded_key); {
loaded_key let mut file = try!(fs::File::create(self.key_path(&key_file.id)));
let json = key_file.to_json();
let json_text = format!("{}", json.pretty());
let json_bytes = json_text.into_bytes();
try!(file.write(&json_bytes));
}
self.cache.insert(key_file.id.clone(), key_file);
Ok(())
}
fn get(&mut self, id: &Uuid) -> Option<&KeyFileContent> {
let path = {
let mut path = self.path.to_path_buf();
path.push(&id);
path
};
Some(self.cache.entry(id.to_owned()).or_insert(
match KeyDirectory::load_key(&path, id) {
Ok(loaded_key) => loaded_key,
Err(error) => { return None; }
} }
))
}
fn load_key(path: &PathBuf, id: &Uuid) -> Result<KeyFileContent, KeyLoadError> {
match fs::File::open(path.clone()) {
Ok(mut open_file) => {
match open_file.metadata() {
Ok(metadata) =>
if metadata.len() > MAX_KEY_FILE_LEN { Err(KeyLoadError::FileTooLarge(OutOfBounds { min: Some(2), max: Some(MAX_KEY_FILE_LEN), found: metadata.len() })) }
else { KeyDirectory::load_from_file(&mut open_file, metadata.len()) },
Err(read_error) => Err(KeyLoadError::FileReadError(read_error))
}
},
Err(read_error) => Err(KeyLoadError::FileReadError(read_error))
} }
} }
fn load(&mut self, id: Uuid) -> Result<KeyFileContent, KeyLoadError> { fn load_from_file(file: &mut fs::File, size: u64) -> Result<KeyFileContent, KeyLoadError> {
let mut path = self.path.clone(); let mut json_data = vec![0u8; size as usize];
path.push(id);
match ::std::fs::File::open(path.clone()) { match file.read_to_end(&mut json_data) {
Ok(open_file) => { Ok(_) => {},
match open_file.metadata().len() { Err(read_error) => { return Err(KeyLoadError::FileReadError(read_error)); }
0...MAX_KEY_FILE_LEN =>
}
}
} }
}
fn load_from_file(file: fs::File) -> Result<KeyFileContent, KeyLoadError> {
match Json::from_str(::std::str::from_utf8(json_data)) {
match ::std::str::from_utf8(&json_data) {
Ok(ut8_string) => match Json::from_str(ut8_string) {
Ok(json) => match KeyFileContent::new(&json) {
Ok(key_file_content) => Ok(key_file_content),
Err(parse_error) => Err(KeyLoadError::FileParseError(parse_error))
},
Err(json_error) => Err(KeyLoadError::FileParseError(KeyFileParseError::InvalidJsonFormat))
},
Err(error) => Err(KeyLoadError::InvalidEncoding)
} }
} }
} }