encrypt_stuff/symmetric/
encryption.rs

1use aead::{generic_array::GenericArray, Aead, AeadCore, Key, KeyInit, KeySizeUser, OsRng};
2use secrecy::{ExposeSecret, Secret, SecretVec, Zeroize};
3use serde::{Deserialize, Serialize};
4use std::marker::PhantomData;
5
6use crate::serialization::{decode::Decoder, encode::Encoder};
7
8/// represents the encrypted form of the data, can be serialized and deserialized
9#[derive(Debug, Serialize, Deserialize)]
10pub struct Encrypted<Data> {
11    nonce: Vec<u8>,
12    data: Vec<u8>,
13    #[serde(skip)]
14    phantom: PhantomData<Data>,
15}
16
17/// represents data that has been decrypted, but still needs to be deserialized
18/// assumes the data is sensitive and wraps it in a `[Secret]`
19#[derive(Deserialize)]
20pub struct Decrypted<Data> {
21    data: SecretVec<u8>,
22    #[serde(skip)]
23    phantom: PhantomData<Data>,
24}
25
26/// represents data that has been decrypted, but still needs to be deserialized
27/// doesn't make the assumption that data is sensitive
28#[derive(Debug, Deserialize)]
29pub struct DecryptedExposed<Data> {
30    data: Vec<u8>,
31    #[serde(skip)]
32    phantom: PhantomData<Data>,
33}
34type GenericErr = Box<(dyn std::error::Error)>;
35
36/// general trait for encrypting serializable data
37pub trait Encryption {
38    type Cipher: Aead + AeadCore + KeyInit + KeySizeUser;
39    type Scheme: Encoder + Decoder;
40
41    fn encode<Data>(data: &Encrypted<Data>) -> Result<Vec<u8>, GenericErr> {
42        Self::Scheme::encode(data)
43    }
44
45    fn decode<Data>(data: &[u8]) -> Result<Encrypted<Data>, Box<(dyn std::error::Error)>> {
46        Self::Scheme::decode(data)
47    }
48
49    fn extract<'de, Data: Deserialize<'de> + Zeroize>(
50        decrypted: &'de Decrypted<Data>,
51    ) -> Result<Secret<Data>, Box<(dyn std::error::Error)>> {
52        Self::Scheme::decode(decrypted.data.expose_secret()).map(|x| Secret::new(x))
53    }
54
55    fn extract_exposed<'de, Data: Deserialize<'de>>(
56        decrypted: &'de DecryptedExposed<Data>,
57    ) -> Result<Data, Box<(dyn std::error::Error)>> {
58        Self::Scheme::decode(&decrypted.data)
59    }
60
61    /// convert the data to it's serialized form and then encypt it using `[Cipher]`
62    fn encrypt<Data: Serialize>(
63        data: &Data,
64        key: &Key<Self::Cipher>,
65    ) -> Result<Encrypted<Data>, GenericErr> {
66        let cipher = Self::Cipher::new(key);
67        let nonce = Self::Cipher::generate_nonce(&mut OsRng);
68        let serialized = Self::Scheme::encode(data)?;
69        let encrypted = cipher.encrypt(&nonce, serialized.as_ref())?;
70        Ok(Encrypted {
71            nonce: nonce.to_vec(),
72            data: encrypted,
73            phantom: PhantomData,
74        })
75    }
76
77    /// decrypt the data to it's serialized form, pre-emptively wraps data in
78    /// a [Secret]
79    fn decrypt<Data>(
80        encrypted: &Encrypted<Data>,
81        key: &GenericArray<u8, <Self::Cipher as KeySizeUser>::KeySize>,
82    ) -> Result<Decrypted<Data>, GenericErr> {
83        let cipher = Self::Cipher::new(key);
84        let data = cipher.decrypt(
85            GenericArray::from_slice(encrypted.nonce.as_ref()),
86            encrypted.data.as_ref(),
87        )?;
88        Ok(Decrypted {
89            data: data.into(),
90            phantom: PhantomData,
91        })
92    }
93
94    /// decrypt the data to it's serialized form
95    fn decrypt_exposed<Data>(
96        encrypted: &Encrypted<Data>,
97        key: &GenericArray<u8, <Self::Cipher as KeySizeUser>::KeySize>,
98    ) -> Result<DecryptedExposed<Data>, GenericErr> {
99        let cipher = Self::Cipher::new(key);
100        let data = cipher.decrypt(
101            GenericArray::from_slice(encrypted.nonce.as_ref()),
102            encrypted.data.as_ref(),
103        )?;
104        Ok(DecryptedExposed {
105            data,
106            phantom: PhantomData,
107        })
108    }
109}