key directory
This commit is contained in:
parent
d9b6ab1128
commit
6cdc220406
@ -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> {
|
||||||
|
{
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
cache.insert(loaded_key);
|
self.cache.insert(key_file.id.clone(), key_file);
|
||||||
loaded_key
|
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 ::std::str::from_utf8(&json_data) {
|
||||||
match Json::from_str(::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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user