2022-05-18 10:24:37 +00:00
|
|
|
//! 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};
|
|
|
|
|
2022-05-19 13:17:58 +00:00
|
|
|
//use sodiumoxide::crypto::box_ as publicbox;
|
2022-05-19 13:14:36 +00:00
|
|
|
use sodiumoxide::crypto::secretbox::xsalsa20poly1305 as secretbox;
|
2022-05-19 12:33:49 +00:00
|
|
|
|
2022-05-19 13:14:36 +00:00
|
|
|
pub use sodiumoxide::crypto::box_::{
|
|
|
|
gen_keypair, PublicKey, SecretKey, PUBLICKEYBYTES, SECRETKEYBYTES,
|
|
|
|
};
|
2022-05-18 10:24:37 +00:00
|
|
|
pub use sodiumoxide::crypto::secretbox::xsalsa20poly1305::{gen_key, Key, KEYBYTES};
|
|
|
|
|
|
|
|
pub fn open(cryptoblob: &[u8], key: &Key) -> Result<Vec<u8>> {
|
2022-05-19 13:14:36 +00:00
|
|
|
use secretbox::{Nonce, NONCEBYTES};
|
2022-05-19 12:33:49 +00:00
|
|
|
|
2022-05-18 10:24:37 +00:00
|
|
|
if cryptoblob.len() < NONCEBYTES {
|
|
|
|
return Err(anyhow!("Cyphertext too short"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Decrypt -> get Zstd data
|
|
|
|
let nonce = Nonce::from_slice(&cryptoblob[..NONCEBYTES]).unwrap();
|
2022-05-19 12:33:49 +00:00
|
|
|
let zstdblob = secretbox::open(&cryptoblob[NONCEBYTES..], &nonce, key)
|
2022-05-18 10:24:37 +00:00
|
|
|
.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>> {
|
2022-05-19 13:14:36 +00:00
|
|
|
use secretbox::{gen_nonce, NONCEBYTES};
|
2022-05-19 12:33:49 +00:00
|
|
|
|
2022-05-18 10:24:37 +00:00
|
|
|
// Compress data using zstd
|
2023-05-15 16:23:23 +00:00
|
|
|
let mut reader = plainblob;
|
2022-05-18 10:24:37 +00:00
|
|
|
let zstdblob = zstd_encode(&mut reader, 0)?;
|
|
|
|
|
|
|
|
// Encrypt
|
|
|
|
let nonce = gen_nonce();
|
2022-05-19 12:33:49 +00:00
|
|
|
let cryptoblob = secretbox::seal(&zstdblob, &nonce, key);
|
2022-05-18 10:24:37 +00:00
|
|
|
|
|
|
|
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)?;
|
|
|
|
|
2023-05-15 16:23:23 +00:00
|
|
|
seal(&wr, key)
|
2022-05-18 10:24:37 +00:00
|
|
|
}
|