core_crypto/mls/session/
identifier.rs

1use std::collections::HashMap;
2
3use openmls::prelude::CredentialType;
4use openmls_traits::types::SignatureScheme;
5
6use super::error::{Error, Result};
7use crate::{CertificateBundle, ClientId, RecursiveError, mls::session::id::ClientIdRef};
8
9/// Used by consumers to initializes a MLS client. Encompasses all the client types available.
10/// Could be enriched later with Verifiable Presentations.
11#[derive(Debug, Clone, derive_more::From)]
12pub enum ClientIdentifier {
13    /// Basic keypair
14    Basic(ClientId),
15    /// X509 certificate
16    X509(HashMap<SignatureScheme, CertificateBundle>),
17}
18
19impl ClientIdentifier {
20    /// Extract the unique [ClientId] from an identifier. Use with parsimony as, in case of a x509
21    /// certificate this leads to parsing the certificate
22    pub fn get_id(
23        &self,
24        env: Option<&wire_e2e_identity::x509_check::revocation::PkiEnvironment>,
25    ) -> Result<std::borrow::Cow<'_, ClientIdRef>> {
26        match self {
27            ClientIdentifier::Basic(id) => Ok(std::borrow::Cow::Borrowed(id)),
28            ClientIdentifier::X509(certs) => {
29                // since ClientId has uniqueness constraints, it is the same for all certificates.
30                // hence no need to compute it for every certificate then verify its uniqueness
31                // that's not a getter's job
32                let cert = certs.values().next().ok_or(Error::NoX509CertificateBundle)?;
33                let id = cert
34                    .get_client_id(env)
35                    .map_err(RecursiveError::mls_credential("getting client id"))?;
36                Ok(std::borrow::Cow::Owned(id))
37            }
38        }
39    }
40
41    /// The credential type for this identifier
42    pub fn credential_type(&self) -> CredentialType {
43        match self {
44            ClientIdentifier::Basic(_) => CredentialType::Basic,
45            ClientIdentifier::X509(_) => CredentialType::X509,
46        }
47    }
48}