Skip to main content

core_crypto/mls/session/
identifier.rs

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