Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9275f4b
chore: crypto: remove old x509 impl from TransactionContext
istankovic Apr 1, 2026
3b01438
chore: crypto: remove unused import
istankovic Apr 1, 2026
eec987f
chore: crypto: silence clippy
istankovic Apr 1, 2026
3719880
chore: e2e-identity: move acme/identity to under acquisition
istankovic Apr 1, 2026
c5309e5
chore: e2e-identity: move CertificateError to the acquisition module
istankovic Apr 1, 2026
5983774
chore: e2e-identity: adjust imports after the move
istankovic Apr 1, 2026
12f8054
chore: e2e-identity: add CertificateError::X509Check variant
istankovic Apr 1, 2026
1c461f6
chore: e2e-identity: use correct error types
istankovic Apr 1, 2026
6c0b828
chore: e2e-identity: PKI environment is not optional when validating …
istankovic Apr 1, 2026
c2ca92a
chore: e2e-identity: PKI environment is not optional when extracting …
istankovic Apr 1, 2026
9931098
chore: e2e-identity: extend CertificateError with more variants
istankovic Apr 2, 2026
5777d48
chore: e2e-identity: identity: use CertificateError instead of RustyA…
istankovic Apr 2, 2026
56a543f
chore: e2e-identity: thumbprint: use CertificateError instead of Rust…
istankovic Apr 2, 2026
20a3b14
chore: e2e-identity: extend X509CredentialConfiguration with a domain…
istankovic Apr 2, 2026
6791463
chore: e2e-identity: move certificate checks out of the acme module
istankovic Apr 1, 2026
d89ec0b
chore: e2e-identity: hook the new verification code into the acquisition
istankovic Apr 1, 2026
defb707
chore: keystore-dump: the old enrollment is going away
istankovic Apr 2, 2026
81ccb11
chore: e2e-identity: remove the old enrollment type
istankovic Apr 2, 2026
a7b64d4
chore: e2e-identity: remove RustyE2eIdentity and related code
istankovic Apr 2, 2026
3bc2f3c
chore: e2e-identity: expose WireIdentityReader
istankovic Apr 2, 2026
c5c709a
chore: e2e-identity: expose compute_raw_key_thumbprint
istankovic Apr 2, 2026
d9d42ea
test: e2e-identity: make rand_client_id take a domain parameter
istankovic Apr 2, 2026
fc28f22
test: e2e-identity: specify the domain centrally
istankovic Apr 2, 2026
dda0a0d
test: e2e-identity: add PKI environment to identity tests
istankovic Apr 2, 2026
b2e571d
test: e2e-identity: we can't get a valid status because we don't have…
istankovic Apr 2, 2026
a6da2de
chore: crypto: add MissingPKIEnvironment variant to the credential er…
istankovic Apr 7, 2026
e9fae4a
chore: crypto: provide PKI environment to extract_identity
istankovic Apr 7, 2026
06ce638
chore: crypto: remove get_new_crl_distribution_points
istankovic Apr 8, 2026
5cfc285
chore: Cargo.lock: update to newer rust-pki
istankovic Apr 10, 2026
cadfde9
chore: e2e-identity: acquisition: adjust for the change in get_trust_…
istankovic Apr 10, 2026
5c916dd
chore: e2e-identity: make restore_pki_env always return some inner PK…
istankovic Apr 10, 2026
e073102
fear: e2e-identity: allow adding additional trust anchors
istankovic Apr 10, 2026
af6e8f8
test: e2e-identity: use a more general pem::Pem type for the root CA …
istankovic Apr 10, 2026
b510544
test: e2e-identity: add the root CA cert to the PKI environment
istankovic Apr 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ pub use openmls::{
group_info::VerifiableGroupInfo,
},
};
use wire_e2e_identity::{
legacy::{E2eiEnrollment, device_status::DeviceStatus},
pki_env::PkiEnvironment,
};
use wire_e2e_identity::{legacy::device_status::DeviceStatus, pki_env::PkiEnvironment};

pub use crate::{
build_metadata::{BUILD_METADATA, BuildMetadata},
Expand Down
4 changes: 3 additions & 1 deletion crypto/src/mls/conversation/own_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use core_crypto_keystore::Database;
use openmls::prelude::{
ConfirmationTag, ContentType, CredentialWithKey, FramedContentBodyIn, MlsMessageIn, MlsMessageInBody, Sender,
};
use openmls_traits::OpenMlsCryptoProvider as _;

use super::{Error, Result};
use crate::{
Expand Down Expand Up @@ -98,8 +99,9 @@ impl MlsConversation {
credential: own_leaf.credential().clone(),
signature_key: own_leaf.signature_key().clone(),
};
let provider = client.crypto_provider.authentication_service();
let identity = own_leaf_credential_with_key
.extract_identity(self.ciphersuite(), None)
.extract_identity(self.ciphersuite(), provider.borrow().await.as_ref())
.map_err(RecursiveError::mls_credential("extracting identity"))?;

Ok(MlsConversationDecryptMessage {
Expand Down
19 changes: 16 additions & 3 deletions crypto/src/mls/conversation/pending_conversation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,22 @@ impl PendingConversation {
credential: own_leaf.credential().clone(),
signature_key: own_leaf.signature_key().clone(),
};
let identity = own_leaf_credential_with_key
.extract_identity(conversation.ciphersuite(), None)
.map_err(RecursiveError::mls_credential("extracting identity"))?;
let pki_env = self
.context
.pki_environment_option()
.await
.map_err(RecursiveError::transaction("getting PKI environment"))?;
let identity = match pki_env {
Some(pki_env) => {
let provider = pki_env.mls_pki_env_provider();
own_leaf_credential_with_key
.extract_identity(conversation.ciphersuite(), provider.borrow().await.as_ref())
.map_err(RecursiveError::mls_credential("extracting identity"))?
}
None => own_leaf_credential_with_key
.extract_identity(conversation.ciphersuite(), None)
.map_err(RecursiveError::mls_credential("extracting identity"))?,
};

Ok(MlsConversationDecryptMessage {
app_msg: None,
Expand Down
23 changes: 2 additions & 21 deletions crypto/src/mls/credential/crl.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::collections::HashSet;

use core_crypto_keystore::{entities::E2eiCrl, traits::FetchFromDatabase};
use openmls::{
group::MlsGroup,
prelude::{Certificate, MlsCredentialType},
};
use wire_e2e_identity::{NewCrlDistributionPoints, x509_check::extract_crl_uris};
use wire_e2e_identity::x509_check::extract_crl_uris;

use super::{Error, Result};
use crate::{KeystoreError, RecursiveError};
use crate::RecursiveError;

#[derive(
Debug,
Expand Down Expand Up @@ -52,24 +51,6 @@ pub(crate) fn extract_dp(cert: &Certificate) -> Result<CrlUris> {
})
}

pub(crate) async fn get_new_crl_distribution_points(
database: &impl FetchFromDatabase,
mut crl_dps: HashSet<String>,
) -> Result<NewCrlDistributionPoints> {
if crl_dps.is_empty() {
return Ok(None.into());
}

let stored_crls = database
.load_all::<E2eiCrl>()
.await
.map_err(KeystoreError::wrap("finding all e2e crl"))?;
let stored_crl_dps: HashSet<&str> = stored_crls.iter().map(|crl| crl.distribution_point.as_str()).collect();
crl_dps.retain(|dp| !stored_crl_dps.contains(&dp.as_str()));

Ok(Some(crl_dps).into())
}

impl CrlUris {
fn new() -> Self {
HashSet::new().into()
Expand Down
2 changes: 2 additions & 0 deletions crypto/src/mls/credential/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub enum Error {
InvalidIdentity,
#[error("No credential for the given public key ({0:?}) was found in this database")]
CredentialNotFound(SignaturePublicKey),
#[error("missing PKI environment")]
MissingPKIEnvironment,
/// Unsupported credential type.
///
/// Supported credential types:
Expand Down
1 change: 1 addition & 0 deletions crypto/src/mls/credential/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ impl CredentialExt for openmls::prelude::Certificate {
cs: Ciphersuite,
env: Option<&wire_e2e_identity::x509_check::revocation::PkiEnvironment>,
) -> Result<WireIdentity> {
let env = env.ok_or_else(|| Error::MissingPKIEnvironment)?;
let leaf = self.certificates.first().ok_or(Error::InvalidIdentity)?;
let leaf = leaf.as_slice();
use wire_e2e_identity::WireIdentityReader as _;
Expand Down
8 changes: 6 additions & 2 deletions crypto/src/mls/credential/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ impl fmt::Debug for CertificateBundle {

impl CertificateBundle {
/// Reads the client_id from the leaf certificate
pub fn get_client_id(&self) -> Result<ClientId> {
pub fn get_client_id(
&self,
env: Option<&wire_e2e_identity::x509_check::revocation::PkiEnvironment>,
) -> Result<ClientId> {
let env = env.ok_or_else(|| Error::MissingPKIEnvironment)?;
let leaf = self.certificate_chain.first().ok_or(Error::InvalidIdentity)?;

let hash_alg = match self.signature_scheme {
Expand All @@ -79,7 +83,7 @@ impl CertificateBundle {
};

let identity = leaf
.extract_identity(None, hash_alg)
.extract_identity(env, hash_alg)
.map_err(|_| Error::InvalidIdentity)?;

use wire_e2e_identity::legacy::id as legacy_id;
Expand Down
3 changes: 2 additions & 1 deletion crypto/src/mls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ mod tests {
CertificateBundle::rand_identifier(&session_id, &[x509_test_chain.find_local_intermediate_ca()])
}
};
let provider = cc.get_pki_environment().await.unwrap().mls_pki_env_provider();
let session_id = identifier
.get_id()
.get_id(provider.borrow().await.as_ref())
.expect("get session_id from identifier")
.into_owned();
context
Expand Down
10 changes: 6 additions & 4 deletions crypto/src/mls/session/e2e_identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ impl<D> Session<D> {
_credential_type: CredentialType,
env: Option<&wire_e2e_identity::x509_check::revocation::PkiEnvironment>,
) -> E2eiConversationState {
let env = match env {
Some(e) => e,
None => return E2eiConversationState::NotEnabled,
};

let mut is_e2ei = false;
let mut state = E2eiConversationState::Verified;

Expand All @@ -138,10 +143,7 @@ impl<D> Session<D> {
use openmls_x509_credential::X509Ext as _;
let is_time_valid = cert.is_time_valid().unwrap_or(false);
let is_time_invalid = !is_time_valid;
let is_revoked_or_invalid = env
.map(|e| e.validate_cert_and_revocation(&cert).is_err())
.unwrap_or(false);

let is_revoked_or_invalid = env.validate_cert_and_revocation(&cert).is_err();
let is_invalid = invalid_identity || is_time_invalid || is_revoked_or_invalid;
if is_invalid {
state = E2eiConversationState::NotVerified;
Expand Down
7 changes: 5 additions & 2 deletions crypto/src/mls/session/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ pub enum ClientIdentifier {
impl ClientIdentifier {
/// Extract the unique [ClientId] from an identifier. Use with parsimony as, in case of a x509
/// certificate this leads to parsing the certificate
pub fn get_id(&self) -> Result<std::borrow::Cow<'_, ClientIdRef>> {
pub fn get_id(
&self,
env: Option<&wire_e2e_identity::x509_check::revocation::PkiEnvironment>,
) -> Result<std::borrow::Cow<'_, ClientIdRef>> {
match self {
ClientIdentifier::Basic(id) => Ok(std::borrow::Cow::Borrowed(id)),
ClientIdentifier::X509(certs) => {
Expand All @@ -28,7 +31,7 @@ impl ClientIdentifier {
// that's not a getter's job
let cert = certs.values().next().ok_or(Error::NoX509CertificateBundle)?;
let id = cert
.get_client_id()
.get_client_id(env)
.map_err(RecursiveError::mls_credential("getting client id"))?;
Ok(std::borrow::Cow::Owned(id))
}
Expand Down
3 changes: 3 additions & 0 deletions crypto/src/mls_provider/crypto_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ impl RustCrypto {
Ok(())
}

// TODO: remove this expect(unused) once we start using it again or we drop
// it completely (see WPB-23594)
#[expect(unused)]
pub(crate) fn normalize_p521_secret_key(sk: &[u8]) -> zeroize::Zeroizing<[u8; 66]> {
normalize_p521_secret_key(sk)
}
Expand Down
3 changes: 2 additions & 1 deletion crypto/src/proteus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,8 +645,9 @@ mod tests {
CertificateBundle::rand_identifier(&session_id, &[x509_test_chain.find_local_intermediate_ca()])
}
};
let provider = cc.get_pki_environment().await.unwrap().mls_pki_env_provider();
let session_id = identifier
.get_id()
.get_id(provider.borrow().await.as_ref())
.expect("Getting session id from identifier")
.into_owned();
transaction.mls_init(session_id, transport).await.unwrap();
Expand Down
13 changes: 10 additions & 3 deletions crypto/src/test_utils/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,22 @@ impl SessionContext {
if let openmls::prelude::MlsCredentialType::X509(certificate) =
&expected_credential.mls_credential().mls_credential()
{
let mls_identity = certificate.extract_identity(case.ciphersuite(), None).unwrap();
let session = self.session().await;
let provider = session.crypto_provider;
let guard = provider.authentication_service().borrow().await;
let env = match guard.as_ref() {
Some(env) => env,
None => unreachable!("PKI environment must be set"),
};
let mls_identity = certificate.extract_identity(case.ciphersuite(), Some(env)).unwrap();
let mls_client_id = mls_identity.client_id.as_bytes();

let decrypted_identity = &decrypted.identity;

let leaf: Vec<u8> = certificate.certificates.first().unwrap().clone().into();
let identity = leaf
.as_slice()
.extract_identity(None, case.ciphersuite().e2ei_hash_alg())
.extract_identity(env, case.ciphersuite().e2ei_hash_alg())
.unwrap();
let identity = WireIdentity::try_from((identity, leaf.as_slice())).unwrap();

Expand All @@ -263,7 +270,7 @@ impl SessionContext {
);
let chain = x509_cert::Certificate::load_pem_chain(decrypted_x509_identity.certificate.as_bytes()).unwrap();
let leaf = chain.first().unwrap();
let cert_identity = leaf.extract_identity(None, case.ciphersuite().e2ei_hash_alg()).unwrap();
let cert_identity = leaf.extract_identity(env, case.ciphersuite().e2ei_hash_alg()).unwrap();

let cert_identity = WireIdentity::try_from((cert_identity, leaf.to_der().unwrap().as_slice())).unwrap();
assert_eq!(cert_identity.client_id, identity.client_id);
Expand Down
36 changes: 25 additions & 11 deletions crypto/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use std::{collections::HashMap, sync::Arc};

use async_lock::RwLock;
use openmls::framing::MlsMessageOut;
use openmls_traits::OpenMlsCryptoProvider as _;
pub use openmls_traits::types::SignatureScheme;
use wire_e2e_identity::pki_env::PkiEnvironment;

Expand Down Expand Up @@ -118,18 +119,8 @@ impl SessionContext {
.unwrap();

let core_crypto = CoreCrypto::new(db.clone());

let transaction = core_crypto.new_transaction().await.unwrap();

let session_id = identifier
.get_id()
.map_err(RecursiveError::mls_client("getting client id"))?
.into_owned();
transaction
.mls_init(session_id, context.transport.clone())
.await
.map_err(RecursiveError::transaction("mls init"))?;

// Setup the X509 PKI environment
if let Some(chain) = chain.as_ref() {
let dummy_hooks = Arc::new(DummyPkiEnvironmentHooks);
Expand All @@ -143,6 +134,25 @@ impl SessionContext {
chain.register_with_central(&transaction).await;
}

let pki_env = core_crypto.get_pki_environment().await;
let session_id = match pki_env {
Some(pki_env) => {
let provider = pki_env.mls_pki_env_provider();
identifier
.get_id(provider.borrow().await.as_ref())
.map_err(RecursiveError::mls_client("getting client id"))?
.into_owned()
}
None => identifier
.get_id(None)
.map_err(RecursiveError::mls_client("getting client id"))?
.into_owned(),
};
transaction
.mls_init(session_id, context.transport.clone())
.await
.map_err(RecursiveError::transaction("mls init"))?;

let session = transaction.session().await.unwrap();

let credential = Credential::from_identifier(&identifier, context.ciphersuite())
Expand Down Expand Up @@ -306,7 +316,11 @@ impl SessionContext {
CredentialType::X509 => {
let signer = signer.expect("Missing intermediate CA");
let cert = CertificateBundle::rand(&session_id, signer);
let session_id = cert.get_client_id().expect("Getting client id from certificate bundle");
let session = self.session.read().await;
let guard = session.crypto_provider.authentication_service().borrow().await;
let session_id = cert
.get_client_id(guard.as_ref())
.expect("Getting client id from certificate bundle");

let credential = Credential::x509(case.ciphersuite(), cert).expect("creating x509 credential");

Expand Down
11 changes: 9 additions & 2 deletions crypto/src/test_utils/test_conversation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync::Arc;

use openmls::{group::QueuedProposal, prelude::group_info::VerifiableGroupInfo};
use openmls_traits::OpenMlsCryptoProvider as _;

use super::{CredentialType, MessageExt as _, MlsTransportTestExt, SessionContext, TestContext, TestError};
use crate::{
Expand Down Expand Up @@ -385,7 +386,11 @@ impl<'a> TestConversation<'a> {
let credential = credential_ref.load(&database).await.unwrap();
let mls_credential_with_key = credential.to_mls_credential_with_key();
let ciphersuite = self.case.ciphersuite();
let local_identity = mls_credential_with_key.extract_identity(ciphersuite, None).unwrap();
let session = self.actor().session().await;
let provider = session.crypto_provider.authentication_service();
let local_identity = mls_credential_with_key
.extract_identity(ciphersuite, provider.borrow().await.as_ref())
.unwrap();

assert_eq!(&local_identity.client_id.as_bytes(), &cid.0);
assert_eq!(
Expand All @@ -404,7 +409,9 @@ impl<'a> TestConversation<'a> {
};

assert_eq!(credential.credential.identity(), &cid.0);
let keystore_identity = credential.extract_identity(ciphersuite, None).unwrap();
let keystore_identity = credential
.extract_identity(ciphersuite, provider.borrow().await.as_ref())
.unwrap();
assert_eq!(
keystore_identity.x509_identity.as_ref().unwrap().display_name,
new_display_name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,6 @@ impl TransactionContext {
self.e2ei_register_intermediate_ca(inter_ca).await
}

pub(crate) async fn e2ei_register_intermediate_ca_der(&self, cert_der: &[u8]) -> Result<NewCrlDistributionPoints> {
let inter_ca = x509_cert::Certificate::from_der(cert_der)?;
self.e2ei_register_intermediate_ca(inter_ca).await
}

async fn e2ei_register_intermediate_ca(
&self,
inter_ca: x509_cert::Certificate,
Expand Down
Loading
Loading