use super::CredentialBundle;
use crate::{
prelude::CryptoError,
prelude::{CertificateBundle, Client, ClientId, CryptoResult},
};
use mls_crypto_provider::MlsCryptoProvider;
use openmls_traits::types::SignatureScheme;
use std::collections::{HashMap, HashSet};
#[derive(Debug, Clone)]
pub enum ClientIdentifier {
Basic(ClientId),
X509(HashMap<SignatureScheme, CertificateBundle>),
}
impl ClientIdentifier {
pub fn get_id(&self) -> CryptoResult<std::borrow::Cow<ClientId>> {
match self {
ClientIdentifier::Basic(id) => Ok(std::borrow::Cow::Borrowed(id)),
ClientIdentifier::X509(certs) => {
let cert = certs.values().next().ok_or(CryptoError::ImplementationError)?;
let id = cert.get_client_id()?;
Ok(std::borrow::Cow::Owned(id))
}
}
}
pub fn generate_credential_bundles(
self,
backend: &MlsCryptoProvider,
signature_schemes: HashSet<SignatureScheme>,
) -> CryptoResult<Vec<(SignatureScheme, ClientId, CredentialBundle)>> {
match self {
ClientIdentifier::Basic(id) => signature_schemes.iter().try_fold(
Vec::with_capacity(signature_schemes.len()),
|mut acc, &sc| -> CryptoResult<_> {
let cb = Client::new_basic_credential_bundle(&id, sc, backend)?;
acc.push((sc, id.clone(), cb));
Ok(acc)
},
),
ClientIdentifier::X509(certs) => {
let cap = certs.len();
certs
.into_iter()
.try_fold(Vec::with_capacity(cap), |mut acc, (sc, cert)| -> CryptoResult<_> {
let id = cert.get_client_id()?;
let cb = Client::new_x509_credential_bundle(cert)?;
acc.push((sc, id, cb));
Ok(acc)
})
}
}
}
}