feat: upgrade OpenMLS 0.5 → 0.8 for security patches and GREASE support

Migrates all MLS code in quicprochat-core from OpenMLS 0.5 to 0.8:
- StorageProvider replaces OpenMlsKeyStore (keystore.rs full rewrite)
- HybridCryptoProvider updated for new OpenMlsProvider trait
- Group operations updated for new API signatures
- MLS state persistence via MemoryStorage serialization
- tls_codec 0.3 → 0.4, openmls_traits/rust_crypto 0.2 → 0.5
This commit is contained in:
2026-03-08 17:50:15 +01:00
parent 077f48f19c
commit a05da9b751
20 changed files with 1433 additions and 657 deletions

View File

@@ -77,10 +77,8 @@ pub async fn create_dm(
// Save conversation with MLS state.
let member_keys = member.member_identities();
let mls_blob = member
.group_ref()
.map(bincode::serialize)
.transpose()
.map_err(|e| SdkError::Storage(format!("serialize MLS group: {e}")))?;
.serialize_mls_state()
.map_err(|e| SdkError::Storage(format!("serialize MLS state: {e}")))?;
let conv = Conversation {
id: conv_id.clone(),
@@ -147,10 +145,8 @@ pub fn create_group(
let member_keys = member.member_identities();
let mls_blob = member
.group_ref()
.map(bincode::serialize)
.transpose()
.map_err(|e| SdkError::Storage(format!("serialize MLS group: {e}")))?;
.serialize_mls_state()
.map_err(|e| SdkError::Storage(format!("serialize MLS state: {e}")))?;
let conv = Conversation {
id: conv_id.clone(),
@@ -252,10 +248,8 @@ pub fn join_from_welcome(
let member_keys = member.member_identities();
let mls_blob = member
.group_ref()
.map(bincode::serialize)
.transpose()
.map_err(|e| SdkError::Storage(format!("serialize MLS group: {e}")))?;
.serialize_mls_state()
.map_err(|e| SdkError::Storage(format!("serialize MLS state: {e}")))?;
// Upsert conversation — the stub may already exist from create_dm.
let existing = conv_store
@@ -509,10 +503,8 @@ pub fn save_mls_state(
.ok_or_else(|| SdkError::ConversationNotFound(conv_id.hex()))?;
conv.mls_group_blob = member
.group_ref()
.map(bincode::serialize)
.transpose()
.map_err(|e| SdkError::Storage(format!("serialize MLS group: {e}")))?;
.serialize_mls_state()
.map_err(|e| SdkError::Storage(format!("serialize MLS state: {e}")))?;
conv.member_keys = member.member_identities();
conv.is_hybrid = member.is_hybrid();
@@ -529,16 +521,19 @@ pub fn restore_mls_state(
conv: &Conversation,
identity: &Arc<IdentityKeypair>,
) -> Result<GroupMember, SdkError> {
let group_blob = conv
let storage_blob = conv
.mls_group_blob
.as_ref()
.ok_or_else(|| SdkError::Crypto("no MLS group blob in conversation".into()))?;
let mls_group = bincode::deserialize(group_blob)
.map_err(|e| SdkError::Crypto(format!("deserialize MLS group: {e}")))?;
let ks = quicprochat_core::DiskKeyStore::ephemeral();
let member = GroupMember::new_with_state(Arc::clone(identity), ks, Some(mls_group), conv.is_hybrid);
let group_id = conv.id.0.as_slice();
let member = GroupMember::new_from_storage_bytes(
Arc::clone(identity),
storage_blob,
group_id,
conv.is_hybrid,
)
.map_err(|e| SdkError::Crypto(format!("restore MLS state: {e}")))?;
Ok(member)
}