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, Vec); impl Sealing for SimpleSealing { fn new(protected_rk: Vec, nonce: Vec) -> 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::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) }