1use std::{error::Error, marker::PhantomData};
2
3use aes_gcm::{
4 aead::{generic_array::GenericArray, Aead, OsRng},
5 AeadCore, Aes256Gcm, Key, KeyInit,
6};
7use argon2::{password_hash::SaltString, Argon2};
8use serde::{Deserialize, Serialize};
9
10use crate::errors::{DecryptionError, EncryptionError};
11
12#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
13pub struct Encrypted<Data> {
14 nonce: Vec<u8>,
15 data: Vec<u8>,
16 #[serde(skip)]
17 data_type: PhantomData<Data>,
18}
19pub struct Decrypted<Data> {
21 data: Vec<u8>,
22 data_type: PhantomData<Data>,
23}
24
25impl<'de, Data: Deserialize<'de>> Decrypted<Data> {
26 pub fn deserialize(&'de self) -> Data {
27 bincode::deserialize(&self.data).unwrap()
28 }
29}
30
31impl<'de, Data: Serialize + Deserialize<'de>> Encrypted<Data> {
32 pub fn decrypt(&self, key: Key<Aes256Gcm>) -> Result<Decrypted<Data>, Box<dyn Error>> {
33 let cipher = Aes256Gcm::new(&key);
34 let decrypt = cipher
35 .decrypt(
36 GenericArray::from_slice(self.nonce.as_slice()),
37 self.data.as_ref(),
38 )
39 .map_err(|_| DecryptionError::Decryption)?;
40 Ok(Decrypted {
41 data: decrypt,
42 data_type: PhantomData,
43 })
44 }
45
46 pub fn encrypt(data: &Data, key: Key<Aes256Gcm>) -> Result<Encrypted<Data>, Box<dyn Error>> {
47 let cipher = Aes256Gcm::new(&key);
48 let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
49 let encoded = bincode::serialize(data)?;
50 let encrypted = cipher
51 .encrypt(&nonce, encoded.as_ref())
52 .map_err(|_| EncryptionError::Encryption)?;
53 Ok(Encrypted {
54 data: encrypted,
55 nonce: nonce.to_vec(),
56 data_type: PhantomData,
57 })
58 }
59}
60
61pub trait SecureData {
62 type Item;
63 fn salt(&self) -> &str;
64 fn data(&self) -> &Encrypted<Self::Item>;
65 fn encrypt<'de>(
67 data: &Self::Item,
68 key: Key<Aes256Gcm>,
69 ) -> Result<Encrypted<Self::Item>, Box<dyn Error>>
70 where
71 Self::Item: Serialize + Deserialize<'de>,
72 {
73 Encrypted::encrypt(data, key)
74 }
75 fn decrypt<'de>(&self, key: Key<Aes256Gcm>) -> Result<Decrypted<Self::Item>, Box<dyn Error>>
76 where
77 Self::Item: Serialize + Deserialize<'de> + 'de,
78 {
79 Encrypted::decrypt(self.data(), key)
80 }
81 fn key(&self, password: String) -> Key<Aes256Gcm> {
90 Self::get_key(self.salt(), password)
91 }
92 fn get_key(salt: &str, password: String) -> Key<Aes256Gcm> {
93 let salt_string = SaltString::from_b64(salt).unwrap();
94 let mut salt_arr = [0u8; 64];
95 let salt_bytes = salt_string.decode_b64(&mut salt_arr).unwrap();
96
97 let mut output_key = [0u8; 32];
98 let argon2 = Argon2::default();
99 argon2
100 .hash_password_into(password.as_bytes(), salt_bytes, &mut output_key)
101 .unwrap();
102
103 output_key.into()
104 }
105}