Skip to main content

de_mls/mls_crypto/
credentials.rs

1//! MLS-specific credential bundle: signing keypair + credential.
2//!
3//! Built once per user from an [`crate::identity::Identity`] at User init
4//! and shared across every per-conversation `MlsService` via
5//! `Arc<MlsCredentials>`. The signing key is the long-lived MLS identity;
6//! the credential's serialized content is the user's identity bytes —
7//! the link back to whatever real-world identifier the
8//! [`crate::identity::Identity`] represents.
9
10use openmls::credentials::{BasicCredential, CredentialWithKey};
11use openmls_basic_credential::SignatureKeyPair;
12
13use crate::{
14    identity::Identity,
15    mls_crypto::{MlsError, service::CIPHERSUITE},
16};
17
18/// MLS credential + signing keypair for one user, shared across all
19/// conversations they belong to.
20#[derive(Debug)]
21pub struct MlsCredentials {
22    credential: CredentialWithKey,
23    signer: SignatureKeyPair,
24}
25
26impl MlsCredentials {
27    /// Build credentials from an [`Identity`]. Generates a fresh
28    /// signing keypair (held only in this struct, not stored in MLS
29    /// keystore until consumed by a service / KP build) and bundles it
30    /// with a basic credential whose serialized content is
31    /// `identity.identity_bytes()`.
32    pub fn from_identity<I: Identity + ?Sized>(identity: &I) -> Result<Self, MlsError> {
33        let credential = BasicCredential::new(identity.identity_bytes().to_vec());
34        let signer = SignatureKeyPair::new(CIPHERSUITE.signature_algorithm())?;
35        Ok(Self {
36            credential: CredentialWithKey {
37                credential: credential.into(),
38                signature_key: signer.to_public_vec().into(),
39            },
40            signer,
41        })
42    }
43
44    /// MLS credential bundle — public part of the identity, embedded in
45    /// every signed MLS message we produce.
46    pub fn credential(&self) -> &CredentialWithKey {
47        &self.credential
48    }
49
50    /// MLS signing keypair — owns the private key used to sign MLS
51    /// messages and proposals.
52    pub fn signer(&self) -> &SignatureKeyPair {
53        &self.signer
54    }
55}