rvault/src/storage/sealing/simple.rs

48 lines
1.8 KiB
Rust

use aes_gcm_siv::{
AeadCore, Aes256GcmSiv, KeyInit,
aead::{Aead, OsRng, generic_array::GenericArray},
};
use base64::{Engine, prelude::BASE64_STANDARD};
use crate::DbPool;
use super::{write_new_root_key, Sealing, UnsealResult};
/// Pair of protected root key and nonce
#[derive(PartialEq)]
pub struct SimpleSealing(Vec<u8>, Vec<u8>);
impl Sealing for SimpleSealing {
fn new(protected_rk: Vec<u8>, nonce: Vec<u8>) -> Self {
Self(protected_rk, nonce)
}
async fn unseal(&mut self, key: String) -> UnsealResult {
let key = BASE64_STANDARD.decode(key).unwrap();
let cipher = Aes256GcmSiv::new_from_slice(&key).unwrap();
debug_assert_eq!(self.1.len(), 12);
let nonce = aes_gcm_siv::aead::generic_array::GenericArray::from_slice(self.1.as_slice());
UnsealResult::DoneConfidential(cipher.decrypt(nonce, self.0.as_ref()).unwrap())
}
}
/// Initialize the vault with a simple password
#[allow(unused)]
pub async fn init_simple(pool: &DbPool) -> String {
let root_key = Aes256GcmSiv::generate_key(&mut OsRng);
let nonce: GenericArray<u8, <Aes256GcmSiv as AeadCore>::NonceSize> =
Aes256GcmSiv::generate_nonce(&mut OsRng); // 96-bits; unique per message
let root_key = root_key.as_slice().to_owned();
let (user_key, protected_rk) = {
let key = Aes256GcmSiv::generate_key(&mut OsRng);
let cipher = Aes256GcmSiv::new(&key);
let nonce: &[u8] = nonce.as_slice();
debug_assert_eq!(nonce.len(), 12);
let nonce = aes_gcm_siv::aead::generic_array::GenericArray::from_slice(nonce);
let enc = cipher.encrypt(nonce, root_key.as_slice()).unwrap();
(key, enc)
};
write_new_root_key(pool, protected_rk, "simple", Some(nonce.as_slice())).await;
BASE64_STANDARD.encode(user_key)
}