1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use aead::{generic_array::GenericArray, Aead, AeadCore, KeyInit, KeySizeUser, OsRng};
use secrecy::{ExposeSecret, Secret, SecretVec, Zeroize};
use serde::{Deserialize, Serialize};
use std::marker::PhantomData;

use crate::error::EncryptionError;

/// represents the encrypted form of the data, can be serialized and deserialized
#[derive(Debug, Serialize, Deserialize)]
pub struct Encrypted<Data> {
    nonce: Vec<u8>,
    data: Vec<u8>,
    #[serde(skip)]
    phantom: PhantomData<Data>,
}

/// represents data that has been decrypted, but still needs to be deserialized
/// assumes the data is sensitive and wraps it in a `[Secret]`
#[derive(Deserialize)]
pub struct Decrypted<Data> {
    data: SecretVec<u8>,
    #[serde(skip)]
    phantom: PhantomData<Data>,
}

/// represents data that has been decrypted, but still needs to be deserialized
/// doesn't make the assumption that data is sensitive
#[derive(Debug, Deserialize)]
pub struct DecryptedExposed<Data> {
    data: Vec<u8>,
    #[serde(skip)]
    phantom: PhantomData<Data>,
}

impl<'a, Data> Decrypted<Data>
where
    Data: Deserialize<'a> + Zeroize,
{
    pub fn deserialize(&'a self) -> Result<Secret<Data>, bitcode::Error> {
        bitcode::deserialize(self.data.expose_secret()).map(|res| Secret::new(res))
    }
}

impl<'a, Data> DecryptedExposed<Data>
where
    Data: Deserialize<'a>,
{
    pub fn deserialize(&'a self) -> Result<Data, bitcode::Error> {
        bitcode::deserialize(&self.data)
    }
}

impl<'de, Data> Encrypted<Data>
where
    Data: Serialize + Deserialize<'de>,
{
    pub fn encode(&self) -> Result<Vec<u8>, bitcode::Error> {
        bitcode::serialize(&self)
    }

    pub fn decode(bytes: &[u8]) -> Result<Self, bitcode::Error> {
        bitcode::deserialize(bytes)
    }
}

/// general trait for encrypting serializable data
pub trait Encryption {
    type Cipher: Aead + AeadCore + KeyInit + KeySizeUser;
    /// convert the data to it's serialized form and then encypt it using `[Cipher]`
    fn encrypt<Data: Serialize>(
        data: &Data,
        key: &GenericArray<u8, <Self::Cipher as KeySizeUser>::KeySize>,
    ) -> Result<Encrypted<Data>, EncryptionError> {
        let cipher = Self::Cipher::new(key);
        let nonce = Self::Cipher::generate_nonce(&mut OsRng);
        let serialized = bitcode::serialize(data)?;
        let encrypted = cipher.encrypt(&nonce, serialized.as_ref())?;
        Ok(Encrypted {
            nonce: nonce.to_vec(),
            data: encrypted,
            phantom: PhantomData,
        })
    }

    /// decrypt the data to it's serialized form, pre-emptively wraps data in
    /// a [Secret]
    fn decrypt<Data>(
        encrypted: &Encrypted<Data>,
        key: &GenericArray<u8, <Self::Cipher as KeySizeUser>::KeySize>,
    ) -> Result<Decrypted<Data>, EncryptionError> {
        let cipher = Self::Cipher::new(key);
        let data = cipher.decrypt(
            GenericArray::from_slice(encrypted.nonce.as_ref()),
            encrypted.data.as_ref(),
        )?;
        Ok(Decrypted {
            data: data.into(),
            phantom: PhantomData,
        })
    }

    /// decrypt the data to it's serialized form
    fn decrypt_exposed<Data>(
        encrypted: &Encrypted<Data>,
        key: &GenericArray<u8, <Self::Cipher as KeySizeUser>::KeySize>,
    ) -> Result<DecryptedExposed<Data>, EncryptionError> {
        let cipher = Self::Cipher::new(key);
        let data = cipher.decrypt(
            GenericArray::from_slice(encrypted.nonce.as_ref()),
            encrypted.data.as_ref(),
        )?;
        Ok(DecryptedExposed {
            data,
            phantom: PhantomData,
        })
    }
}