From 71f7b8a485147e61deae3c2975872ff755a13d0c Mon Sep 17 00:00:00 2001 From: Jazz Turner-Baggs <473256+jazzz@users.noreply.github.com> Date: Mon, 9 Feb 2026 09:55:58 -0800 Subject: [PATCH] FFI Integration fixes (#48) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make conversation store easier to use * fix: Bug in Inbox id’s * Clean up warnings * Add DH decryption for Inbox --- conversations/src/context.rs | 6 ++--- conversations/src/conversation.rs | 8 ++----- conversations/src/errors.rs | 2 -- conversations/src/identity.rs | 5 ----- conversations/src/inbox/inbox.rs | 29 ++++++++++++++++--------- conversations/src/inbox/introduction.rs | 2 +- 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/conversations/src/context.rs b/conversations/src/context.rs index 1a0f86f..49db263 100644 --- a/conversations/src/context.rs +++ b/conversations/src/context.rs @@ -41,9 +41,10 @@ impl Context { .invite_to_private_convo(remote_bundle, content) .unwrap_or_else(|_| todo!("Log/Surface Error")); + let remote_id = Inbox::inbox_identifier_for_key(remote_bundle.installation_key); let payload_bytes = payloads .into_iter() - .map(|p| p.to_envelope(convo.id().to_string())) + .map(|p| p.to_envelope(remote_id.clone())) .collect(); let convo_id = self.add_convo(Box::new(convo)); @@ -77,8 +78,7 @@ impl Context { // TODO: Impl Conversation hinting let convo_id = env.conversation_hint; - let enc = EncryptedPayload::decode(payload)?; - + let enc = EncryptedPayload::decode(env.payload)?; match convo_id { c if c == self.inbox.id() => self.dispatch_to_inbox(enc), c if self.store.has(&c) => self.dispatch_to_convo(&c, enc), diff --git a/conversations/src/conversation.rs b/conversations/src/conversation.rs index 8fd474f..934526e 100644 --- a/conversations/src/conversation.rs +++ b/conversations/src/conversation.rs @@ -50,16 +50,12 @@ impl ConversationStore { self.conversations.contains_key(id) } - pub fn get(&self, id: ConversationId) -> Option<&(dyn Convo + '_)> { - self.conversations.get(id).map(|c| c.as_ref()) - } - pub fn get_mut(&mut self, id: &str) -> Option<&mut (dyn Convo + '_)> { Some(self.conversations.get_mut(id)?.as_mut()) } - pub fn conversation_ids(&self) -> impl Iterator + '_ { - self.conversations.keys().cloned() + pub fn conversation_ids(&self) -> Vec { + self.conversations.keys().cloned().collect() } } diff --git a/conversations/src/errors.rs b/conversations/src/errors.rs index 5b6b438..d551960 100644 --- a/conversations/src/errors.rs +++ b/conversations/src/errors.rs @@ -24,8 +24,6 @@ pub enum ChatError { #[derive(Error, Debug)] pub enum EncryptionError { - #[error("encryption: {0}")] - Encryption(String), #[error("decryption: {0}")] Decryption(String), } diff --git a/conversations/src/identity.rs b/conversations/src/identity.rs index c5646a7..44dd79e 100644 --- a/conversations/src/identity.rs +++ b/conversations/src/identity.rs @@ -1,4 +1,3 @@ -use blake2::{Blake2b512, Digest}; use std::fmt; use crate::crypto::{PublicKey, StaticSecret}; @@ -23,10 +22,6 @@ impl Identity { } } - pub fn address(&self) -> String { - hex::encode(Blake2b512::digest(self.public_key())) - } - pub fn public_key(&self) -> PublicKey { PublicKey::from(&self.secret) } diff --git a/conversations/src/inbox/inbox.rs b/conversations/src/inbox/inbox.rs index 66888b7..3a32a62 100644 --- a/conversations/src/inbox/inbox.rs +++ b/conversations/src/inbox/inbox.rs @@ -1,3 +1,4 @@ +use blake2::{Blake2b512, Digest}; use chat_proto::logoschat::encryption::EncryptedPayload; use hex; use prost::Message; @@ -43,7 +44,7 @@ impl<'a> std::fmt::Debug for Inbox { impl Inbox { pub fn new(ident: Rc) -> Self { - let local_convo_id = ident.address(); + let local_convo_id = Self::inbox_identifier_for_key(ident.public_key()); Self { ident, local_convo_id, @@ -139,10 +140,16 @@ impl Inbox { match frame.frame_type.unwrap() { proto::inbox_v1_frame::FrameType::InvitePrivateV1(_invite_private_v1) => { - let convo = PrivateV1Convo::new_responder(seed_key, ephemeral_key.clone().into()); + let mut convo = + PrivateV1Convo::new_responder(seed_key, ephemeral_key.clone().into()); - // TODO: Update PrivateV1 Constructor with DR, initial_message - Ok((Box::new(convo), None)) + let Some(enc_payload) = _invite_private_v1.initial_message else { + return Err(ChatError::Protocol("Invite: missing initial".into())); + }; + + let content = convo.handle_frame(enc_payload)?; + + Ok((Box::new(convo), content)) } } } @@ -186,7 +193,7 @@ impl Inbox { ); // TODO: Decrypt Content - let frame = proto::InboxV1Frame::decode(bytes)?; + let frame = self.decrypt_frame(bytes)?; Ok((seed_key, frame)) } @@ -202,12 +209,9 @@ impl Inbox { Ok(handshake) } - fn decrypt_frame( - enc_payload: proto::InboxHandshakeV1, - ) -> Result { - let frame_bytes = enc_payload.payload; + fn decrypt_frame(&self, enc_frame_bytes: Bytes) -> Result { // TODO: decrypt payload - let frame = proto::InboxV1Frame::decode(frame_bytes)?; + let frame = proto::InboxV1Frame::decode(enc_frame_bytes)?; Ok(frame) } @@ -216,6 +220,11 @@ impl Inbox { .get(key) .ok_or_else(|| return ChatError::UnknownEphemeralKey()) } + + pub fn inbox_identifier_for_key(pubkey: PublicKey) -> String { + // TODO: Implement ID according to spec + hex::encode(Blake2b512::digest(pubkey)) + } } impl Id for Inbox { diff --git a/conversations/src/inbox/introduction.rs b/conversations/src/inbox/introduction.rs index 0955e11..fc686dc 100644 --- a/conversations/src/inbox/introduction.rs +++ b/conversations/src/inbox/introduction.rs @@ -50,7 +50,7 @@ impl TryFrom<&[u8]> for Introduction { .map_err(|_| ChatError::InvalidKeyLength)?; let installation_key = PublicKey::from(installation_bytes); - let ephemeral_bytes: [u8; 32] = hex::decode(parts[1]) + let ephemeral_bytes: [u8; 32] = hex::decode(parts[2]) .map_err(|_| ChatError::BadParsing("ephemeral_key"))? .try_into() .map_err(|_| ChatError::InvalidKeyLength)?;