feat(xchacha): spawn gen_key, encrypt & decrypt blocking
This commit is contained in:
@@ -13,6 +13,7 @@ rmp-serde = "0.15"
|
|||||||
serde_bytes = "0.11"
|
serde_bytes = "0.11"
|
||||||
uuid = "0.8"
|
uuid = "0.8"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
|
agnostik = {git = "https://github.com/chpio/agnostik.git", branch = "tokio1"}
|
||||||
|
|
||||||
[dependencies.crdt-enc]
|
[dependencies.crdt-enc]
|
||||||
path = "../crdt-enc"
|
path = "../crdt-enc"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use ::agnostik::spawn_blocking;
|
||||||
use ::anyhow::{Context, Error, Result};
|
use ::anyhow::{Context, Error, Result};
|
||||||
use ::async_trait::async_trait;
|
use ::async_trait::async_trait;
|
||||||
use ::chacha20poly1305::{
|
use ::chacha20poly1305::{
|
||||||
@@ -29,20 +30,26 @@ impl EncHandler {
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crdt_enc::cryptor::Cryptor for EncHandler {
|
impl crdt_enc::cryptor::Cryptor for EncHandler {
|
||||||
async fn gen_key(&self) -> Result<VersionBytes> {
|
async fn gen_key(&self) -> Result<VersionBytes> {
|
||||||
|
spawn_blocking(|| {
|
||||||
let mut key = [0u8; KEY_LEN];
|
let mut key = [0u8; KEY_LEN];
|
||||||
thread_rng()
|
thread_rng()
|
||||||
.try_fill_bytes(&mut key)
|
.try_fill_bytes(&mut key)
|
||||||
.context("Unable to get random data for secret key")?;
|
.context("Unable to get random data for secret key")?;
|
||||||
Ok(VersionBytes::new(KEY_VERSION, key.into()))
|
Ok(VersionBytes::new(KEY_VERSION, key.into()))
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn encrypt(&self, key: VersionBytesRef<'_>, clear_text: &[u8]) -> Result<Vec<u8>> {
|
async fn encrypt(&self, key: VersionBytesRef<'_>, clear_text: Vec<u8>) -> Result<Vec<u8>> {
|
||||||
key.ensure_version(KEY_VERSION)
|
key.ensure_version(KEY_VERSION)
|
||||||
.context("not matching key version")?;
|
.context("not matching key version")?;
|
||||||
if key.as_ref().len() != KEY_LEN {
|
if key.as_ref().len() != KEY_LEN {
|
||||||
return Err(Error::msg("Invalid key length"));
|
return Err(Error::msg("Invalid key length"));
|
||||||
}
|
}
|
||||||
let key = Key::from_slice(key.as_ref());
|
let key = key.as_ref().to_vec();
|
||||||
|
|
||||||
|
spawn_blocking(move || {
|
||||||
|
let key = Key::from_slice(&key);
|
||||||
let aead = XChaCha20Poly1305::new(key);
|
let aead = XChaCha20Poly1305::new(key);
|
||||||
let mut nonce = [0u8; NONCE_LEN];
|
let mut nonce = [0u8; NONCE_LEN];
|
||||||
thread_rng()
|
thread_rng()
|
||||||
@@ -50,7 +57,7 @@ impl crdt_enc::cryptor::Cryptor for EncHandler {
|
|||||||
.context("Unable to get random data for nonce")?;
|
.context("Unable to get random data for nonce")?;
|
||||||
let xnonce = XNonce::from_slice(&nonce);
|
let xnonce = XNonce::from_slice(&nonce);
|
||||||
let enc_data = aead
|
let enc_data = aead
|
||||||
.encrypt(xnonce, clear_text)
|
.encrypt(xnonce, clear_text.as_ref())
|
||||||
.context("Encryption failed")?;
|
.context("Encryption failed")?;
|
||||||
let enc_box = EncBox {
|
let enc_box = EncBox {
|
||||||
nonce: Cow::Borrowed(nonce.as_ref()),
|
nonce: Cow::Borrowed(nonce.as_ref()),
|
||||||
@@ -62,16 +69,21 @@ impl crdt_enc::cryptor::Cryptor for EncHandler {
|
|||||||
let version_box_bytes =
|
let version_box_bytes =
|
||||||
rmp_serde::to_vec_named(&version_box).context("failed to encode version box")?;
|
rmp_serde::to_vec_named(&version_box).context("failed to encode version box")?;
|
||||||
Ok(version_box_bytes)
|
Ok(version_box_bytes)
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn decrypt(&self, key: VersionBytesRef<'_>, enc_data: &[u8]) -> Result<Vec<u8>> {
|
async fn decrypt(&self, key: VersionBytesRef<'_>, enc_data: Vec<u8>) -> Result<Vec<u8>> {
|
||||||
key.ensure_version(KEY_VERSION)
|
key.ensure_version(KEY_VERSION)
|
||||||
.context("not matching key version")?;
|
.context("not matching key version")?;
|
||||||
if key.as_ref().len() != KEY_LEN {
|
if key.as_ref().len() != KEY_LEN {
|
||||||
return Err(Error::msg("Invalid key length"));
|
return Err(Error::msg("Invalid key length"));
|
||||||
}
|
}
|
||||||
|
let key = key.as_ref().to_vec();
|
||||||
|
|
||||||
|
spawn_blocking(move || {
|
||||||
let version_box: VersionBytesRef =
|
let version_box: VersionBytesRef =
|
||||||
rmp_serde::from_read_ref(enc_data).context("failed to parse version box")?;
|
rmp_serde::from_read_ref(&enc_data).context("failed to parse version box")?;
|
||||||
version_box
|
version_box
|
||||||
.ensure_version(DATA_VERSION)
|
.ensure_version(DATA_VERSION)
|
||||||
.context("not matching version of encryption box")?;
|
.context("not matching version of encryption box")?;
|
||||||
@@ -87,6 +99,8 @@ impl crdt_enc::cryptor::Cryptor for EncHandler {
|
|||||||
.decrypt(&xnonce, enc_box.enc_data.as_ref())
|
.decrypt(&xnonce, enc_box.enc_data.as_ref())
|
||||||
.context("Decryption failed")?;
|
.context("Decryption failed")?;
|
||||||
Ok(clear_text)
|
Ok(clear_text)
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn gen_key(&self) -> Result<VersionBytes>;
|
async fn gen_key(&self) -> Result<VersionBytes>;
|
||||||
async fn encrypt(&self, key: VersionBytesRef<'_>, clear_text: &[u8]) -> Result<Vec<u8>>;
|
async fn encrypt(&self, key: VersionBytesRef<'_>, clear_text: Vec<u8>) -> Result<Vec<u8>>;
|
||||||
async fn decrypt(&self, key: VersionBytesRef<'_>, enc_data: &[u8]) -> Result<Vec<u8>>;
|
async fn decrypt(&self, key: VersionBytesRef<'_>, enc_data: Vec<u8>) -> Result<Vec<u8>>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ where
|
|||||||
Ok((clear_text, states_to_remove, ops_to_remove, key))
|
Ok((clear_text, states_to_remove, ops_to_remove, key))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let data_enc = self.cryptor.encrypt(key.key(), &clear_text).await.unwrap();
|
let data_enc = self.cryptor.encrypt(key.key(), clear_text).await.unwrap();
|
||||||
|
|
||||||
let enc_data = VersionBytes::new(self.current_data_version, data_enc);
|
let enc_data = VersionBytes::new(self.current_data_version, data_enc);
|
||||||
|
|
||||||
@@ -436,7 +436,7 @@ where
|
|||||||
|
|
||||||
let clear_text = self
|
let clear_text = self
|
||||||
.cryptor
|
.cryptor
|
||||||
.decrypt(key.key(), state.as_ref())
|
.decrypt(key.key(), state.into_inner())
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("failed decrypting remote state {}", name))?;
|
.with_context(|| format!("failed decrypting remote state {}", name))?;
|
||||||
|
|
||||||
@@ -500,7 +500,7 @@ where
|
|||||||
data.ensure_versions(SUPPORTED_VERSIONS)?;
|
data.ensure_versions(SUPPORTED_VERSIONS)?;
|
||||||
let clear_text = self
|
let clear_text = self
|
||||||
.cryptor
|
.cryptor
|
||||||
.decrypt(key.key(), data.as_ref())
|
.decrypt(key.key(), data.into_inner())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -684,7 +684,7 @@ where
|
|||||||
|
|
||||||
let data_enc = self
|
let data_enc = self
|
||||||
.cryptor
|
.cryptor
|
||||||
.encrypt(key.key(), &clear_text.serialize())
|
.encrypt(key.key(), clear_text.serialize())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user