From e3af0ef0e88e7346cec193e5909354d17783b930 Mon Sep 17 00:00:00 2001 From: Thomas Heck Date: Sun, 7 Mar 2021 16:09:57 +0100 Subject: [PATCH] fix: pass keys properly to/from key cryptor as `ReadCtx` --- crdt-enc-gpgme/src/lib.rs | 110 +++++++++++++++++------------------- crdt-enc/src/key_cryptor.rs | 5 +- crdt-enc/src/lib.rs | 61 ++++++++++++++------ 3 files changed, 98 insertions(+), 78 deletions(-) diff --git a/crdt-enc-gpgme/src/lib.rs b/crdt-enc-gpgme/src/lib.rs index 7d5ef5e..f8d07f3 100644 --- a/crdt-enc-gpgme/src/lib.rs +++ b/crdt-enc-gpgme/src/lib.rs @@ -1,11 +1,23 @@ use ::anyhow::{Context, Error, Result}; use ::async_trait::async_trait; -use ::crdt_enc::{key_cryptor::Keys, utils::VersionBytes, CoreSubHandle, Info}; -use ::crdts::{CmRDT, CvRDT, MVReg, Orswot}; +use ::crdt_enc::{ + key_cryptor::Keys, + utils::VersionBytes, + utils::{decode_version_bytes_mvreg_custom, encode_version_bytes_mvreg_custom}, + CoreSubHandle, Info, +}; +use ::crdts::{ctx::ReadCtx, CvRDT, MVReg, Orswot}; use ::serde::{Deserialize, Serialize}; use ::std::{convert::Infallible, fmt::Debug, sync::Mutex as SyncMutex}; use ::uuid::Uuid; +const CURRENT_VERSION: Uuid = Uuid::from_u128(0xe69cb68e_7fbb_41aa_8d22_87eace7a04c9); + +// needs to be sorted! +const SUPPORTED_VERSIONS: &[Uuid] = &[ + Uuid::from_u128(0xe69cb68e_7fbb_41aa_8d22_87eace7a04c9), // current +]; + pub fn init() { gpgme::init(); } @@ -69,7 +81,7 @@ impl crdt_enc::key_cryptor::KeyCryptor for KeyHandler { &self, new_remote_meta: Option>, ) -> Result<()> { - let (keys, core) = { + let (remote_meta, core) = { let mut data = self .data .lock() @@ -79,67 +91,47 @@ impl crdt_enc::key_cryptor::KeyCryptor for KeyHandler { data.remote_meta.merge(new_remote_meta); } - let keys = data.remote_meta.read().val.into_iter().try_fold( - Keys::default(), - |mut acc, vb| { - // TODO: check version - // TODO: decrypt key - let keys = rmp_serde::from_read_ref(&vb).context("")?; - acc.merge(keys); - Result::<_, Error>::Ok(acc) - }, - )?; - - let core = dyn_clone::clone_box(&**data.core.as_ref().context("core is none")?); - - (keys, core) - }; - - core.set_keys(keys).await?; - - Ok(()) - } - - async fn set_keys(&self, new_keys: Keys) -> Result<()> { - let (rm, core) = { - let mut data = self - .data - .lock() - .map_err(|err| Error::msg(err.to_string()))?; - - let read_ctx = data.remote_meta.read(); - - let mut keys = read_ctx - .val - .iter() - .try_fold(Keys::default(), |mut acc, vb| { - // TODO: check version - // TODO: decrypt key - let keys = rmp_serde::from_read_ref(&vb).context("")?; - acc.merge(keys); - Result::<_, Error>::Ok(acc) - })?; - - keys.merge(new_keys); - - let actor = data.info.as_ref().context("info is none")?.actor(); - let write_ctx = read_ctx.derive_add_ctx(actor); - - let op = data.remote_meta.write( - VersionBytes::new( - // TODO - Uuid::nil(), - rmp_serde::to_vec_named(&keys)?, - ), - write_ctx, - ); - data.remote_meta.apply(op); - let core = dyn_clone::clone_box(&**data.core.as_ref().context("core is none")?); (data.remote_meta.clone(), core) }; + let keys_ctx = + decode_version_bytes_mvreg_custom(&remote_meta, SUPPORTED_VERSIONS, |buf| async move { + // TODO: decrypt key + Ok(buf) + }) + .await?; + + core.set_keys(keys_ctx).await?; + + Ok(()) + } + + async fn set_keys(&self, new_keys: ReadCtx) -> Result<()> { + let (mut rm, core) = { + let data = self + .data + .lock() + .map_err(|err| Error::msg(err.to_string()))?; + + let core = dyn_clone::clone_box(&**data.core.as_ref().context("core is none")?); + (data.remote_meta.clone(), core) + }; + + encode_version_bytes_mvreg_custom( + &mut rm, + new_keys, + core.info().actor(), + CURRENT_VERSION, + |buf| async move { + // TODO: encrypt key + Ok(buf) + }, + ) + .await?; + + self.set_remote_meta(Some(rm.clone())).await?; core.set_remote_meta_key_cryptor(rm).await?; Ok(()) diff --git a/crdt-enc/src/key_cryptor.rs b/crdt-enc/src/key_cryptor.rs index 7e863a4..e4e7bc3 100644 --- a/crdt-enc/src/key_cryptor.rs +++ b/crdt-enc/src/key_cryptor.rs @@ -4,7 +4,7 @@ use crate::{ }; use ::anyhow::Result; use ::async_trait::async_trait; -use ::crdts::{CmRDT, CvRDT, MVReg, Orswot}; +use ::crdts::{ctx::ReadCtx, CmRDT, CvRDT, MVReg, Orswot}; use ::serde::{Deserialize, Serialize}; use ::std::{ borrow::Borrow, @@ -28,7 +28,8 @@ where Ok(()) } - async fn set_keys(&self, keys: Keys) -> Result<()>; + /// It needs to give a new `ReadCtx` to the core (`core.set_keys`) + async fn set_keys(&self, keys: ReadCtx) -> Result<()>; } #[derive(Clone, Debug, Serialize, Deserialize, Default)] diff --git a/crdt-enc/src/lib.rs b/crdt-enc/src/lib.rs index 80730df..65a4f5f 100644 --- a/crdt-enc/src/lib.rs +++ b/crdt-enc/src/lib.rs @@ -11,7 +11,7 @@ use crate::{ }; use ::anyhow::{Context, Error, Result}; use ::async_trait::async_trait; -use ::crdts::{CmRDT, CvRDT, MVReg, VClock}; +use ::crdts::{ctx::ReadCtx, CmRDT, CvRDT, MVReg, VClock}; use ::dyn_clone::DynClone; use ::futures::{ lock::Mutex as AsyncMutex, @@ -47,7 +47,7 @@ where async fn read_remote(&self) -> Result<()>; async fn read_remote_meta(&self) -> Result<()>; - async fn set_keys(&self, keys: Keys) -> Result<()>; + async fn set_keys(&self, keys: ReadCtx) -> Result<()>; async fn set_remote_meta_storage(&self, remote_meta: MVReg) -> Result<()>; async fn set_remote_meta_cryptor(&self, remote_meta: MVReg) -> Result<()>; @@ -101,7 +101,7 @@ where self.read_remote_meta().await } - async fn set_keys(&self, keys: Keys) -> Result<()> { + async fn set_keys(&self, keys: ReadCtx) -> Result<()> { self.set_keys(keys).await } @@ -221,7 +221,7 @@ pub struct Core { struct CoreMutData { local_meta: Option, remote_meta: RemoteMeta, - keys: Keys, + keys: Option>, state: StateWrapper, read_states: HashSet, read_remote_metas: HashSet, @@ -248,7 +248,7 @@ where let core_data = SyncMutex::new(CoreMutData { local_meta: None, remote_meta: RemoteMeta::default(), - keys: Keys::default(), + keys: None, state: StateWrapper { next_op_versions: Default::default(), state: Default::default(), @@ -316,17 +316,19 @@ where core.read_remote_meta_(true).await?; - let insert_new_key = core.with_mut_data(|data| Ok(data.keys.latest_key().is_none()))?; - + let insert_new_key = + core.with_mut_data(|data| Ok(data.keys.as_ref().unwrap().val.latest_key().is_none()))?; if insert_new_key { let new_key = core.cryptor.gen_key().await?; - let keys = core.with_mut_data(|data| { - data.keys.insert_latest_key(actor, Key::new(new_key)); - Ok(data.keys.clone()) + let keys_ctx = core.with_mut_data(|data| { + let mut keys_ctx = data.keys.take().unwrap(); + keys_ctx.val.insert_latest_key(actor, Key::new(new_key)); + Ok(keys_ctx) })?; - core.key_cryptor.set_keys(keys).await?; + // give keys to kc, it gives us a new key ctx back + core.key_cryptor.set_keys(keys_ctx).await?; } Ok(core) @@ -379,7 +381,13 @@ where .map(|dot| (dot.actor.clone(), dot.counter - 1)) .collect(); - let key = data.keys.latest_key().context("no latest key")?; + let key = data + .keys + .as_ref() + .unwrap() + .val + .latest_key() + .context("no latest key")?; Ok((clear_text, states_to_remove, ops_to_remove, key)) })?; @@ -409,9 +417,9 @@ where Ok(()) } - async fn set_keys(self: &Arc, keys: Keys) -> Result<()> { + async fn set_keys(self: &Arc, keys: ReadCtx) -> Result<()> { self.with_mut_data(|data| { - data.keys.merge(keys); + data.keys = Some(keys); Ok(()) })?; @@ -442,7 +450,13 @@ where .filter(|name| !data.read_states.contains(name)) .collect(); - let key = data.keys.latest_key().context("no latest key")?; + let key = data + .keys + .as_ref() + .unwrap() + .val + .latest_key() + .context("no latest key")?; Ok((states_to_read, key)) })?; @@ -506,7 +520,13 @@ where .map(|actor| (actor, data.state.next_op_versions.get(&actor))) .collect(); - let key = data.keys.latest_key().context("no latest key")?; + let key = data + .keys + .as_ref() + .unwrap() + .val + .latest_key() + .context("no latest key")?; Ok((ops_to_read, key)) })?; @@ -696,7 +716,14 @@ where let clear_text = rmp_serde::to_vec_named(&ops)?; let clear_text = VersionBytes::new(self.current_data_version, clear_text); - let key = self.with_mut_data(|data| data.keys.latest_key().context("no latest key"))?; + let key = self.with_mut_data(|data| { + data.keys + .as_ref() + .unwrap() + .val + .latest_key() + .context("no latest key") + })?; let data_enc = self .cryptor