// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // Copyright by contributors to this project. // SPDX-License-Identifier: (Apache-2.0 OR MIT) /// Basic credential identity provider. pub mod basic; /// X.509 certificate identity provider. #[cfg(feature = "x509")] pub mod x509 { pub use mls_rs_identity_x509::*; } pub use mls_rs_core::identity::{ Credential, CredentialType, CustomCredential, MlsCredential, SigningIdentity, }; #[cfg(test)] pub(crate) mod test_utils { #[cfg(feature = "std")] use alloc::boxed::Box; use alloc::vec; use alloc::vec::Vec; use mls_rs_core::{ crypto::{CipherSuite, CipherSuiteProvider, SignatureSecretKey}, error::IntoAnyError, extension::ExtensionList, identity::{ Credential, CredentialType, IdentityProvider, MemberValidationContext, SigningIdentity, }, time::MlsTime, }; use crate::crypto::test_utils::test_cipher_suite_provider; use super::basic::{BasicCredential, BasicIdentityProvider}; #[derive(Debug)] #[cfg_attr(feature = "std", derive(thiserror::Error))] #[cfg_attr( feature = "std", error("expected basic or custom credential type 42 found: {0:?}") )] pub struct BasicWithCustomProviderError(CredentialType); impl IntoAnyError for BasicWithCustomProviderError { #[cfg(feature = "std")] fn into_dyn_error(self) -> Result, Self> { Ok(self.into()) } } #[derive(Debug, Clone)] pub struct BasicWithCustomProvider { pub(crate) basic: BasicIdentityProvider, pub(crate) allow_any_custom: bool, supported_cred_types: Vec, } impl BasicWithCustomProvider { pub const CUSTOM_CREDENTIAL_TYPE: u16 = 42; pub fn new(basic: BasicIdentityProvider) -> BasicWithCustomProvider { BasicWithCustomProvider { basic, allow_any_custom: false, supported_cred_types: vec![ CredentialType::BASIC, Self::CUSTOM_CREDENTIAL_TYPE.into(), ], } } pub fn with_credential_type(mut self, cred_type: CredentialType) -> Self { self.supported_cred_types.push(cred_type); self } #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] async fn resolve_custom_identity( &self, signing_id: &SigningIdentity, ) -> Result, BasicWithCustomProviderError> { self.basic .identity(signing_id, &Default::default()) .await .or_else(|_| { signing_id .credential .as_custom() .map(|c| { if c.credential_type == CredentialType::from(Self::CUSTOM_CREDENTIAL_TYPE) || self.allow_any_custom { Ok(c.data.to_vec()) } else { Err(BasicWithCustomProviderError(c.credential_type)) } }) .transpose()? .ok_or_else(|| { BasicWithCustomProviderError(signing_id.credential.credential_type()) }) }) } } impl Default for BasicWithCustomProvider { fn default() -> Self { Self::new(BasicIdentityProvider::new()) } } #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] #[cfg_attr(mls_build_async, maybe_async::must_be_async)] impl IdentityProvider for BasicWithCustomProvider { type Error = BasicWithCustomProviderError; async fn validate_member( &self, _signing_identity: &SigningIdentity, _timestamp: Option, _context: MemberValidationContext<'_>, ) -> Result<(), Self::Error> { //TODO: Is it actually beneficial to check the key, or does that already happen elsewhere before //this point? Ok(()) } async fn validate_external_sender( &self, _signing_identity: &SigningIdentity, _timestamp: Option, _extensions: Option<&ExtensionList>, ) -> Result<(), Self::Error> { //TODO: Is it actually beneficial to check the key, or does that already happen elsewhere before //this point? Ok(()) } async fn identity( &self, signing_id: &SigningIdentity, _extensions: &ExtensionList, ) -> Result, Self::Error> { self.resolve_custom_identity(signing_id).await } async fn valid_successor( &self, predecessor: &SigningIdentity, successor: &SigningIdentity, _extensions: &ExtensionList, ) -> Result { let predecessor = self.resolve_custom_identity(predecessor).await?; let successor = self.resolve_custom_identity(successor).await?; Ok(predecessor == successor) } fn supported_types(&self) -> Vec { self.supported_cred_types.clone() } } #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] pub async fn get_test_signing_identity( cipher_suite: CipherSuite, identity: &[u8], ) -> (SigningIdentity, SignatureSecretKey) { let provider = test_cipher_suite_provider(cipher_suite); let (secret_key, public_key) = provider.signature_key_generate().await.unwrap(); let basic = get_test_basic_credential(identity.to_vec()); (SigningIdentity::new(basic, public_key), secret_key) } pub fn get_test_basic_credential(identity: Vec) -> Credential { BasicCredential::new(identity).into_credential() } }