aboutsummaryrefslogtreecommitdiff
path: root/aero-user/src/cryptoblob.rs
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2024-05-29 10:14:51 +0200
committerQuentin Dufour <quentin@deuxfleurs.fr>2024-05-29 10:14:51 +0200
commitb9ce5886033677f6c65a4b873e17574fdb8df31d (patch)
tree9ed1d721361027d7d6fef0ecad65d7e1b74a7ddb /aero-user/src/cryptoblob.rs
parent0dcf69f180f5a7b71b6ad2ac67e4cdd81e5154f1 (diff)
parent5954de6efbb040b8b47daf0c7663a60f3db1da6e (diff)
downloadaerogramme-b9ce5886033677f6c65a4b873e17574fdb8df31d.tar.gz
aerogramme-b9ce5886033677f6c65a4b873e17574fdb8df31d.zip
Merge branch 'caldav'
Diffstat (limited to 'aero-user/src/cryptoblob.rs')
-rw-r--r--aero-user/src/cryptoblob.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/aero-user/src/cryptoblob.rs b/aero-user/src/cryptoblob.rs
new file mode 100644
index 0000000..327a642
--- /dev/null
+++ b/aero-user/src/cryptoblob.rs
@@ -0,0 +1,67 @@
+//! Helper functions for secret-key encrypted blobs
+//! that contain Zstd encrypted data
+
+use anyhow::{anyhow, Result};
+use serde::{Deserialize, Serialize};
+use zstd::stream::{decode_all as zstd_decode, encode_all as zstd_encode};
+
+//use sodiumoxide::crypto::box_ as publicbox;
+use sodiumoxide::crypto::secretbox::xsalsa20poly1305 as secretbox;
+
+pub use sodiumoxide::crypto::box_::{
+ gen_keypair, PublicKey, SecretKey, PUBLICKEYBYTES, SECRETKEYBYTES,
+};
+pub use sodiumoxide::crypto::secretbox::xsalsa20poly1305::{gen_key, Key, KEYBYTES};
+
+pub fn open(cryptoblob: &[u8], key: &Key) -> Result<Vec<u8>> {
+ use secretbox::{Nonce, NONCEBYTES};
+
+ if cryptoblob.len() < NONCEBYTES {
+ return Err(anyhow!("Cyphertext too short"));
+ }
+
+ // Decrypt -> get Zstd data
+ let nonce = Nonce::from_slice(&cryptoblob[..NONCEBYTES]).unwrap();
+ let zstdblob = secretbox::open(&cryptoblob[NONCEBYTES..], &nonce, key)
+ .map_err(|_| anyhow!("Could not decrypt blob"))?;
+
+ // Decompress zstd data
+ let mut reader = &zstdblob[..];
+ let data = zstd_decode(&mut reader)?;
+
+ Ok(data)
+}
+
+pub fn seal(plainblob: &[u8], key: &Key) -> Result<Vec<u8>> {
+ use secretbox::{gen_nonce, NONCEBYTES};
+
+ // Compress data using zstd
+ let mut reader = plainblob;
+ let zstdblob = zstd_encode(&mut reader, 0)?;
+
+ // Encrypt
+ let nonce = gen_nonce();
+ let cryptoblob = secretbox::seal(&zstdblob, &nonce, key);
+
+ let mut res = Vec::with_capacity(NONCEBYTES + cryptoblob.len());
+ res.extend(nonce.as_ref());
+ res.extend(cryptoblob);
+
+ Ok(res)
+}
+
+pub fn open_deserialize<T: for<'de> Deserialize<'de>>(cryptoblob: &[u8], key: &Key) -> Result<T> {
+ let blob = open(cryptoblob, key)?;
+
+ Ok(rmp_serde::decode::from_read_ref::<_, T>(&blob)?)
+}
+
+pub fn seal_serialize<T: Serialize>(obj: T, key: &Key) -> Result<Vec<u8>> {
+ let mut wr = Vec::with_capacity(128);
+ let mut se = rmp_serde::Serializer::new(&mut wr)
+ .with_struct_map()
+ .with_string_variants();
+ obj.serialize(&mut se)?;
+
+ seal(&wr, key)
+}