diff options
Diffstat (limited to 'aero-user/src/cryptoblob.rs')
-rw-r--r-- | aero-user/src/cryptoblob.rs | 67 |
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) +} |