|
|
|
@ -17,6 +17,7 @@ use rustc_serialize::base64;
|
|
|
|
|
use rustc_serialize::base64::{FromBase64, ToBase64};
|
|
|
|
|
use std::convert::TryFrom;
|
|
|
|
|
use std::convert::TryInto;
|
|
|
|
|
use std::error::Error;
|
|
|
|
|
use std::io;
|
|
|
|
|
|
|
|
|
|
pub struct EncryptedValue {
|
|
|
|
@ -85,6 +86,29 @@ impl FromSql for EncryptedValue {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl EncryptedValue {
|
|
|
|
|
pub fn decrypt_to_bytes(&self, master_key: [u8; 32]) -> Vec<u8> {
|
|
|
|
|
let mut hmac = Hmac::new(Sha256::new(), &master_key);
|
|
|
|
|
hmac.input(&self.ciphertext);
|
|
|
|
|
if hmac.result() != self.mac {
|
|
|
|
|
panic!("Mac did not match, corrupted data");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut cipher = aes::ctr(KeySize::KeySize256, &master_key, &self.iv);
|
|
|
|
|
let mut output: Vec<u8> = vec![0; self.ciphertext.len()];
|
|
|
|
|
cipher.process(&self.ciphertext, output.as_mut_slice());
|
|
|
|
|
output
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn decrypt_to_string(
|
|
|
|
|
&self,
|
|
|
|
|
master_key: [u8; 32],
|
|
|
|
|
) -> Result<String, std::string::FromUtf8Error> {
|
|
|
|
|
let decrypted_bytes = self.decrypt_to_bytes(master_key);
|
|
|
|
|
String::from_utf8(decrypted_bytes)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn get_master_key(db_conn: &db::DbHandle, master_password: &str) -> io::Result<[u8; 32]> {
|
|
|
|
|
let scrypt_params: ScryptParams = ScryptParams::new(12, 16, 2);
|
|
|
|
|
let salt: Vec<u8> = get_salt(db_conn)?;
|
|
|
|
|