Skip to content

Commit

Permalink
feat: Added support for Credential validation
Browse files Browse the repository at this point in the history
  • Loading branch information
OtaK committed Jan 26, 2024
1 parent 3b5ceeb commit 6fc58b2
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 0 deletions.
3 changes: 3 additions & 0 deletions openmls/src/credentials/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! This module exposes [`CredentialError`].
use crate::error::LibraryError;
use openmls_traits::authentication_service::CredentialAuthenticationStatus;
use thiserror::Error;

/// An error that occurs in methods of a [`super::Credential`].
Expand All @@ -26,4 +27,6 @@ pub enum CredentialError {
/// x509 certificate chain is either unordered or a child is missigned by its issuer
#[error("Invalid x509 certificate chain.")]
InvalidCertificateChain,
#[error("The Authentication Service callback rejected this credential for the following reason: {0}")]
AuthenticationServiceValidationFailure(CredentialAuthenticationStatus),
}
51 changes: 51 additions & 0 deletions openmls/src/credentials/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
use std::io::{Read, Write};

use openmls_traits::{
authentication_service::{AuthenticationServiceDelegate, CredentialAuthenticationStatus},
OpenMlsCryptoProvider,
};
use serde::{Deserialize, Serialize};
use tls_codec::{TlsDeserialize, TlsSerialize, TlsSize, VLBytes};

Expand Down Expand Up @@ -271,6 +275,53 @@ impl Credential {
MlsCredentialType::X509(cert) => cert.identity.as_slice(),
}
}

pub async fn validate(
&self,
backend: &impl OpenMlsCryptoProvider,
) -> Result<(), CredentialError> {
let tmp_certs = if let MlsCredentialType::X509(x509_certs) = &self.credential {
Some(
x509_certs
.certificates
.iter()
.map(|bytes| bytes.as_slice())
.collect::<Vec<_>>(),
)
} else {
None
};

let credential_ref = match &self.credential {
MlsCredentialType::Basic(basic_cred) => {
openmls_traits::authentication_service::CredentialRef::Basic {
identity: basic_cred.identity.as_slice(),
}
}

MlsCredentialType::X509(_) => {
let credential_ref = openmls_traits::authentication_service::CredentialRef::X509 {
certificates: tmp_certs.as_ref().unwrap().as_slice(),
};
credential_ref
}
};

let credential_authentication = backend
.authentication_service()
.validate_credential(credential_ref)
.await;

if credential_authentication != CredentialAuthenticationStatus::Valid {
return Err(CredentialError::AuthenticationServiceValidationFailure(
credential_authentication,
));
}

drop(tmp_certs);

Ok(())
}
}

impl From<MlsCredentialType> for Credential {
Expand Down
1 change: 1 addition & 0 deletions openmls_rust_crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ repository = "https://github.com/openmls/openmls/tree/main/openmls_rust_crypto"
readme = "README.md"

[dependencies]
async-trait = { workspace = true }
openmls_traits = { version = "0.2.0", path = "../traits" }
openmls_memory_keystore = { version = "0.2.0", path = "../memory_keystore" }
# Rust Crypto dependencies
Expand Down
21 changes: 21 additions & 0 deletions openmls_rust_crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ use openmls_traits::OpenMlsCryptoProvider;
mod provider;
pub use provider::*;

#[derive(Debug)]
pub struct DummyAuthenticationService;

#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
impl openmls_traits::authentication_service::AuthenticationServiceDelegate
for DummyAuthenticationService
{
async fn validate_credential<'a>(
&'a self,
_credential: openmls_traits::authentication_service::CredentialRef<'a>,
) -> openmls_traits::authentication_service::CredentialAuthenticationStatus {
Default::default()
}
}

#[derive(Default, Debug)]
pub struct OpenMlsRustCrypto {
crypto: RustCrypto,
Expand All @@ -19,6 +35,7 @@ impl OpenMlsCryptoProvider for OpenMlsRustCrypto {
type CryptoProvider = RustCrypto;
type RandProvider = RustCrypto;
type KeyStoreProvider = MemoryKeyStore;
type AuthenticationServiceProvider = DummyAuthenticationService;

fn crypto(&self) -> &Self::CryptoProvider {
&self.crypto
Expand All @@ -31,4 +48,8 @@ impl OpenMlsCryptoProvider for OpenMlsRustCrypto {
fn key_store(&self) -> &Self::KeyStoreProvider {
&self.key_store
}

fn authentication_service(&self) -> &Self::AuthenticationServiceProvider {
&DummyAuthenticationService
}
}
38 changes: 38 additions & 0 deletions traits/src/authentication_service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum CredentialRef<'a> {
Basic { identity: &'a [u8] },
X509 { certificates: &'a [&'a [u8]] },
}

#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
pub enum CredentialAuthenticationStatus {
#[default]
Valid,
Invalid,
Expired,
Revoked,
}

impl std::fmt::Display for CredentialAuthenticationStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Valid => "valid",
Self::Invalid => "invalid",
Self::Expired => "expired",
Self::Revoked => "revoked",
}
)
}
}

#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
pub trait AuthenticationServiceDelegate: std::fmt::Debug + Send + Sync {
async fn validate_credential<'a>(
&'a self,
credential: CredentialRef<'a>,
) -> CredentialAuthenticationStatus;
}
5 changes: 5 additions & 0 deletions traits/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! This module defines a number of traits that are used by the public
//! API of OpenMLS.
pub mod authentication_service;
pub mod crypto;
pub mod key_store;
pub mod random;
Expand All @@ -17,6 +18,7 @@ pub trait OpenMlsCryptoProvider: Send + Sync {
type CryptoProvider: crypto::OpenMlsCrypto;
type RandProvider: random::OpenMlsRand;
type KeyStoreProvider: key_store::OpenMlsKeyStore;
type AuthenticationServiceProvider: authentication_service::AuthenticationServiceDelegate;

/// Get the crypto provider.
fn crypto(&self) -> &Self::CryptoProvider;
Expand All @@ -26,4 +28,7 @@ pub trait OpenMlsCryptoProvider: Send + Sync {

/// Get the key store provider.
fn key_store(&self) -> &Self::KeyStoreProvider;

/// Get the authentication service
fn authentication_service(&self) -> &Self::AuthenticationServiceProvider;
}

0 comments on commit 6fc58b2

Please sign in to comment.