1#![forbid(unsafe_code)]
2
3use std::error::Error;
38use std::fmt::Display;
39use std::sync::Mutex;
40
41use base64::engine::general_purpose;
42use base64::Engine;
43use once_cell::sync::Lazy;
44use ring::aead::{
45 Aad, BoundKey, Nonce, NonceSequence, OpeningKey, SealingKey, UnboundKey, AES_256_GCM, NONCE_LEN,
46};
47use ring::digest::{self, digest};
48use ring::error::{self, Unspecified};
49use ring::rand::{SecureRandom, SystemRandom};
50use serde::de::DeserializeOwned;
51use serde::{Deserialize, Serialize};
52use serde::{Deserializer, Serializer};
53
54static MASTER_KEY: Lazy<Mutex<Vec<u8>>> = Lazy::new(|| Mutex::new(vec![]));
55
56#[allow(dead_code)]
57pub fn serialize<S: Serializer, T: Serialize>(v: T, s: S) -> Result<S::Ok, S::Error> {
58 let base64 = e(v).map_err(serde::ser::Error::custom)?;
59 String::serialize(&base64, s)
60}
61
62#[allow(dead_code)]
63pub fn deserialize<'de, D: Deserializer<'de>, T: DeserializeOwned>(de: D) -> Result<T, D::Error> {
64 let base64 = String::deserialize(de)?;
65 d(base64).map_err(serde::de::Error::custom)
66}
67
68pub fn setup(master_key: Vec<u8>) {
69 *MASTER_KEY.lock().unwrap() = master_key;
70}
71
72pub fn e<T: Serialize>(source: T) -> Result<String, Box<dyn Error>> {
73 let nonce = generate_random_nonce();
74 let serialized = serde_json::to_string(&source).map(|t| t.as_bytes().to_vec())?;
75 let mut encrypted = encrypt(serialized, nonce)?;
76 let mut nonce_encrypted = nonce.to_vec();
77 nonce_encrypted.append(&mut encrypted);
78 Ok(general_purpose::URL_SAFE_NO_PAD.encode(nonce_encrypted))
79}
80
81pub fn d<T: DeserializeOwned>(source: String) -> Result<T, Box<dyn Error>> {
82 let decoded = general_purpose::URL_SAFE_NO_PAD.decode(source.as_bytes())?;
83 let nonce = decoded[..NONCE_LEN].try_into().unwrap();
84 let data = decoded[NONCE_LEN..].to_vec();
85 let decrypted = decrypt(data, nonce)?;
86 let decrypted = std::str::from_utf8(&decrypted)?;
87 Ok(serde_json::from_str(decrypted)?)
88}
89
90fn encrypt(mut data: Vec<u8>, nonce: [u8; NONCE_LEN]) -> Result<Vec<u8>, Box<dyn Error>> {
91 let key = MASTER_KEY.lock().unwrap();
92 let (key, nonce) = prepare_key(&key, nonce);
93 let mut encryption_key = SealingKey::new(key, nonce);
94 encryption_key
95 .seal_in_place_append_tag(Aad::empty(), &mut data)
96 .map_err(|e| CryptError::EncryptionError(e))?;
97
98 Ok(data)
99}
100
101fn decrypt(mut data: Vec<u8>, nonce: [u8; NONCE_LEN]) -> Result<Vec<u8>, Box<dyn Error>> {
102 let key = MASTER_KEY.lock().unwrap();
103 let (key, nonce) = prepare_key(&key, nonce);
104 let mut decryption_key = OpeningKey::new(key, nonce);
105 decryption_key
106 .open_in_place(Aad::empty(), &mut data)
107 .map_err(|e| CryptError::DecryptionError(e))?;
108 let length = data.len() - AES_256_GCM.tag_len();
109
110 Ok(data[..length].to_vec())
111}
112
113#[derive(Debug)]
114pub enum CryptError {
115 DecryptionError(Unspecified),
116 EncryptionError(Unspecified),
117}
118
119impl Display for CryptError {
120 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121 match self {
122 Self::DecryptionError(e) => e.fmt(f),
123 Self::EncryptionError(e) => e.fmt(f),
124 }
125 }
126}
127
128impl Error for CryptError {}
129
130struct INonceSequence(Option<Nonce>);
131
132impl INonceSequence {
133 fn new(nonce: Nonce) -> Self {
134 Self(Some(nonce))
135 }
136}
137
138impl NonceSequence for INonceSequence {
139 fn advance(&mut self) -> Result<Nonce, error::Unspecified> {
140 self.0.take().ok_or(error::Unspecified)
141 }
142}
143
144fn generate_random_nonce() -> [u8; NONCE_LEN] {
145 let rand_gen = SystemRandom::new();
146 let mut raw_nonce = [0u8; NONCE_LEN];
147 rand_gen.fill(&mut raw_nonce).unwrap();
148 raw_nonce
149}
150
151fn prepare_key(key: &Vec<u8>, nonce: [u8; NONCE_LEN]) -> (UnboundKey, INonceSequence) {
152 let digest = digest(&digest::SHA256, key.as_slice());
153 let key = digest.as_ref();
154 let nonce_sequence = INonceSequence::new(Nonce::assume_unique_for_key(nonce));
155 (UnboundKey::new(&AES_256_GCM, key).unwrap(), nonce_sequence)
156}
157
158#[cfg(test)]
159mod test {
160 use ring::rand::{SecureRandom, SystemRandom};
161 use serde::{Deserialize, Serialize};
162
163 use crate::setup;
164
165 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
166 struct Other {
167 #[serde(with = "crate")]
168 field: Vec<u8>,
169 plain: String,
170 }
171
172 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
173 struct Test {
174 #[serde(with = "crate")]
175 field: Vec<u8>,
176 #[serde(with = "crate")]
177 other: Other,
178 plain: String,
179 }
180
181 #[test]
182 fn flow() -> Result<(), serde_json::Error> {
183 let mut key: [u8; 256] = [0; 256];
184 let rand_gen = SystemRandom::new();
185 rand_gen.fill(&mut key).unwrap();
186
187 setup(key.to_vec());
188 let instance = Test {
189 field: "a secret message".as_bytes().to_vec(),
190 other: Other {
191 field: "another secret message".as_bytes().to_vec(),
192 plain: "this is a plain nested string".to_string(),
193 },
194 plain: "this is a plain string".to_string(),
195 };
196
197 let serialized = serde_json::to_string(&instance)?;
198 let deserialized: Test = serde_json::from_str(&serialized)?;
199
200 assert_eq!(deserialized, instance);
201 Ok(())
202 }
203
204 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
205 struct Example {
206 #[serde(with = "crate")]
207 private: String,
208 public: String,
209 }
210
211 #[test]
212 fn readme() -> Result<(), serde_json::Error> {
213 let mut key: [u8; 256] = [0; 256];
214 let rand_gen = SystemRandom::new();
215 rand_gen.fill(&mut key).unwrap();
216
217 setup(key.to_vec());
218 let data = Example {
219 private: "private data".to_string(),
220 public: "public data".to_string(),
221 };
222
223 let serialized = serde_json::to_string(&data)?;
224 let deserialized: Example = serde_json::from_str(&serialized)?;
225
226 assert_eq!(deserialized, data);
227 Ok(())
228 }
229}