Add UnverifiedSigner

This commit is contained in:
Jazz Turner-Baggs
2026-07-28 16:19:24 -07:00
parent 1efb377de7
commit 68cd44ab86
7 changed files with 45 additions and 12 deletions
+3 -1
View File
@@ -2,6 +2,7 @@ mod direct_v1;
pub mod group_v1;
mod group_v2;
pub mod mls_extensions;
mod mls_utils;
pub use crate::errors::ChatError;
use crate::outcomes::ConvoOutcome;
@@ -11,6 +12,7 @@ use crate::types::ConvoMetadata;
pub use direct_v1::DirectV1Convo;
pub use group_v1::GroupV1Convo;
pub use group_v2::{GroupV2Clock, GroupV2Convo};
pub use mls_utils::UnverifiedSender;
use shared_traits::IdentIdRef;
pub type ConversationId = String;
@@ -47,7 +49,7 @@ pub(crate) trait GroupConvo<S: ExternalServices>: Convo<S> + std::fmt::Debug + S
/// Each current member's MLS leaf-credential content (hex-encoded), self
/// included.
fn members(&self) -> Result<Vec<Vec<u8>>, ChatError>;
fn members(&self) -> Result<Vec<UnverifiedSender>, ChatError>;
// All GroupConvos MUST return ConvoMetadata
// the return type is Option<_> to support legacy ConvoTypes which
// are being phased out.
@@ -13,7 +13,7 @@ use std::collections::VecDeque;
use tracing::debug;
use crate::conversation::ConversationIdRef;
use crate::conversation::mls_utils::signer_for_sender;
use crate::conversation::mls_utils::{UnverifiedSender, signer_for_sender};
use crate::inbox_v2::MlsProvider;
use crate::service_context::{ExternalServices, ServiceContext};
@@ -349,11 +349,11 @@ impl<S: ExternalServices> GroupConvo<S> for GroupV1Convo {
self.send_payload(cx, commit.to_bytes()?)
}
fn members(&self) -> Result<Vec<Vec<u8>>, ChatError> {
fn members(&self) -> Result<Vec<UnverifiedSender>, ChatError> {
Ok(self
.mls_group
.members()
.map(|m| m.credential.serialized_content().to_vec())
.map(|m| UnverifiedSender::from(m))
.collect())
}
@@ -25,13 +25,13 @@ use openmls::prelude::tls_codec::Deserialize as _;
use openmls::prelude::{KeyPackageIn, OpenMlsProvider as _, ProtocolVersion};
use openmls_traits::crypto::OpenMlsCrypto;
use prost::Message;
use shared_traits::{IdentId, IdentIdRef};
use shared_traits::{IdentId, IdentIdRef, SignerId};
use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tracing::{info, instrument};
use crate::IdentityProvider;
use crate::conversation::{ConversationIdRef, ExternalServices, ServiceContext};
use crate::conversation::{ConversationIdRef, ExternalServices, ServiceContext, UnverifiedSender};
use crate::{
ConvoOutcome, DeliveryService, RegistrationService,
conversation::{ChatError, Convo, GroupConvo, Identified},
@@ -376,13 +376,22 @@ where
result.and(flushed)
}
fn members(&self) -> Result<Vec<Vec<u8>>, ChatError> {
fn members(&self) -> Result<Vec<UnverifiedSender>, ChatError> {
// Guarantee the local member is listed so callers see the full roster.
let mut members = self.conversation.members()?;
let self_id = self.conversation.member_id_bytes().to_vec();
if !members.contains(&self_id) {
members.push(self_id);
}
let members = members
.into_iter()
.map(|cred| UnverifiedSender {
// TODO: (!) Replace is actual SenderId.
signer_id: SignerId::from(b"".as_slice()),
cred,
})
.collect();
Ok(members)
}
@@ -1,7 +1,9 @@
use openmls::{
credentials::CredentialType,
framing::{ProcessedMessage, Sender},
group::MlsGroup,
group::{Member, MlsGroup},
};
use tracing::warn;
use crate::{ChatError, SignerId};
@@ -25,3 +27,22 @@ pub fn signer_for_sender(
};
Ok(sender_sig_key.into())
}
#[derive(Debug, Clone)]
pub struct UnverifiedSender {
pub signer_id: SignerId,
pub cred: Vec<u8>,
}
impl From<Member> for UnverifiedSender {
fn from(value: Member) -> Self {
if CredentialType::Basic != value.credential.credential_type() {
warn!(credtype = ?value.credential, "Incorrect credentialType");
};
let cred = value.credential.serialized_content().to_vec();
let signer_id = SignerId::from(value.signature_key);
Self { signer_id, cred }
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
use crate::causal_history::{CausalHistoryStore, MissingMessage};
use crate::conversation::{
ConversationIdRef, DirectV1Convo, GroupV1Convo, GroupV2Convo, Identified,
ConversationIdRef, DirectV1Convo, GroupV1Convo, GroupV2Convo, Identified, UnverifiedSender,
};
use crate::service_context::{ExternalServices, ServiceContext};
use crate::service_traits::AuthVerifyService;
@@ -294,7 +294,7 @@ impl<'a, S: ExternalServices + 'static> Core<S> {
/// Each member's MLS leaf-credential content (hex-encoded); errors if
/// `convo_id` names a direct (non-group) conversation.
pub fn group_members(&mut self, convo_id: &str) -> Result<Vec<Vec<u8>>, ChatError> {
pub fn group_members(&mut self, convo_id: &str) -> Result<Vec<UnverifiedSender>, ChatError> {
if self.cached_convos.contains_key(convo_id) {
let convo = self
.cached_convos
+1 -1
View File
@@ -13,7 +13,7 @@ mod utils;
pub use causal_history::{Frontier, MissingMessage};
pub use chat_sqlite::ChatStorage;
pub use chat_sqlite::StorageConfig;
pub use conversation::GroupV2Clock;
pub use conversation::{GroupV2Clock, UnverifiedSender};
pub use core::{ConversationId, Core};
/// Timing/policy for GroupV2 conversations (de-mls's per-conversation config).
/// Defaults to the de-mls library defaults; inject via
+2 -1
View File
@@ -12,10 +12,11 @@ use crate::{ConversationId, types::AddressedEnvelope};
/// An AuthVerifyService is responsible for verifying that a provided Credential is valid
/// for the given signer. Implementations must return AuthResult::Valid only if the two can
/// be cryptogrpahically bound together.
pub trait AuthVerifyService: Debug {
pub trait AuthVerifyService: Debug + Clone {
fn validate(&self, signer: &[u8], credential: &[u8]) -> AuthResult;
}
#[derive(Debug, PartialEq)]
pub enum AuthResult {
Valid,
Mismatch,