Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
b23c919
refactor: e2e-identity: remove PkiEnvironmentProvider
istankovic Apr 22, 2026
75e4219
chore: e2e-identity: we don't need to check for the inner PKI environ…
istankovic Apr 22, 2026
7b68336
chore: e2e-identity: move credential validation to PkiEnvironment
istankovic Apr 22, 2026
9501ae6
chore: e2e-identity: we don't need to check for the inner PKI environ…
istankovic Apr 22, 2026
b6645fd
chore: e2e-identity: drop {set,refresh}_time_of_interest
istankovic Apr 27, 2026
56590cb
chore: e2e-identity: add a a now() helper to get the current time
istankovic Apr 27, 2026
6b4b9db
chore: e2e-identity: refresh_time_of_interest is no more
istankovic Apr 22, 2026
39ab0da
chore: e2e-identity: validate_credential no longer needs a mutable se…
istankovic Apr 27, 2026
c58deb6
chore: e2e-identity: remove the `toi` field from the inner PKI enviro…
istankovic Apr 27, 2026
a178d12
chore: e2e-identity: use the now() helper to get time of interest
istankovic Apr 27, 2026
7642b5c
chore: e2e-identity: remove PkiEnvironmentParams.time_of_interest
istankovic Apr 27, 2026
ffd7646
chore: remove usages of PkiEnvironmentParams.time_of_interest
istankovic Apr 27, 2026
38c8b79
chore: e2e-identity: add PkiEnvironment::set_pki_environment_provider
istankovic Apr 27, 2026
14d3cce
chore: crypto-ffi: PkiEnvironment is no longer Clone
istankovic Apr 27, 2026
80975bb
test: e2e-identity: PkiEnvironment is no longer Clone, wrap it inside…
istankovic Apr 27, 2026
c4cf93e
chore: crypto: add a new authentication service type
istankovic Apr 27, 2026
078f13d
refactor: crypto: drop the RwLock and use the new AuthenticationService
istankovic Apr 27, 2026
e475e48
chore: e2e-identity: add PkiEnvironment::validate_cert
istankovic Apr 27, 2026
060b2d7
chore: e2e-identity: allow adding intermediate certs to the PKI env
istankovic Apr 27, 2026
27012b0
chore: e2e-identity: store trust anchors to the database
istankovic Apr 27, 2026
5445301
chore: crypto: remove init_certificates tests
istankovic Apr 29, 2026
0276fc3
chore: crypto: remove cert and CRL registration functions
istankovic Apr 29, 2026
506fb61
chore: crypto-ffi: remove e2ei_is_pki_env_setup
istankovic Apr 29, 2026
39bb802
chore: crypto: remove init_certificates module
istankovic Apr 29, 2026
02dcd99
chore: crypto: save CRLs via the PKI environment
istankovic Apr 29, 2026
9e384e0
test: crypto: remove X509TestChain::init_for_random_clients
istankovic Apr 29, 2026
4cb5a4b
test: crypto: remove can_generate_session test
istankovic Apr 29, 2026
9045320
test: crypto: remove X509TestChain::register_with_provider
istankovic Apr 29, 2026
0b26c7d
chore: e2e-identity: remove set_pki_environment_provider, it is now u…
istankovic Apr 29, 2026
f5d448a
test: crypto: don't check for federated certs
istankovic Apr 29, 2026
8fdf3da
test: crypto: remove the now unused `is_federated` field
istankovic Apr 29, 2026
ff85eb5
test: crypto: remove sessions_with_pki_env
istankovic Apr 29, 2026
f681bba
test: crypto: remove sessions_basic_with_pki_env
istankovic Apr 29, 2026
3a3098d
test: crypto: add certificates and CRLs to the session's PKI environment
istankovic Apr 29, 2026
abff0c5
chore: crypto: remove some more usages of mls_pki_env_provider
istankovic Apr 30, 2026
69d5d6b
chore: crypto: provide outer PKI env in calls to extract_identity
istankovic Apr 30, 2026
2797333
chore: e2e-identity: make extract_identity accept the outer PKI env
istankovic Apr 30, 2026
6ba109a
chore: e2e-identity: call extract_identity with the outer PKI env
istankovic Apr 30, 2026
178ab0f
chore: e2e-identity: add a way to get all trust anchors from the PKI …
istankovic Apr 30, 2026
fe10837
chore: e2e-identity: use the outer PKI env to get trust anchors
istankovic Apr 30, 2026
ed27597
chore: e2e-identity: remove mls_pki_env_provider
istankovic Apr 30, 2026
61daa34
chore: e2e-identity: remove a call to update_pki_environment_provider
istankovic Apr 30, 2026
334b914
chore: e2e-identity: remove update_pki_environment_provider
istankovic Apr 30, 2026
ae3aab6
chore: e2e-identity: add a mutex around the inner PKI environment
istankovic Apr 30, 2026
4d60315
chore: bring back Arc and RwLock to CoreCrypto.pki_environment
istankovic May 5, 2026
7153a92
chore: e2e-identity: add a way to create a PKI env with dummy hooks
istankovic May 5, 2026
5f924b8
test: e2e-identity: fix tests
istankovic May 5, 2026
a411aff
chore: e2e-identity: don't use db transactions
istankovic May 6, 2026
dcbc3dc
chore: e2e-identity: remove validate_crl function of the inner PKI en…
istankovic May 6, 2026
8e0702c
chore: crypto-ffi: remove unused derive_more::Into derive
istankovic May 6, 2026
1c32bfb
chore: crypto-ffi: add a way to clone the internal, Rust PKI env
istankovic May 6, 2026
ef4d5ad
chore: crypto-ffi: get the internal PKI env by calling clone_inner()
istankovic May 6, 2026
f10b143
test: crypto: remove x509 test cases from all_cred_cipher
istankovic May 7, 2026
375adc9
test: crypto: ignore x509 tests
istankovic May 7, 2026
9330ede
chore: e2e-identity: WireIdentityReader::extract_identity has to be a…
istankovic May 8, 2026
c4ee6b1
chore: crypto: adjust for extract_identity now being async
istankovic May 8, 2026
480a121
fixup! chore: e2e-identity: move credential validation to PkiEnvironment
istankovic May 8, 2026
ef18ac2
chore: e2e-identity: remove unnecessary use
istankovic May 8, 2026
8ad61c8
chore: e2e-identity: simplify error checking in validate_cert
istankovic May 8, 2026
3a988b2
chore: e2e-identity: add a comment to revisit credential status check…
istankovic May 8, 2026
b4c1f49
fixup! chore: crypto: add a new authentication service type
istankovic May 8, 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
6 changes: 1 addition & 5 deletions crypto-ffi/src/core_crypto/e2ei/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ pub(crate) mod identities;
impl CoreCryptoFfi {
/// Returns true if the PKI environment has been set up and its provider is configured.
pub async fn e2ei_is_pki_env_setup(&self) -> bool {
if let Some(pki_env) = self.inner.get_pki_environment().await {
return pki_env.provider_is_setup().await;
};

false
self.inner.get_pki_environment().read().await.is_some()
}

/// Returns true if end-to-end identity is enabled for the given ciphersuite.
Expand Down
5 changes: 0 additions & 5 deletions crypto-ffi/src/core_crypto_context/e2ei.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,4 @@ impl CoreCryptoContext {
.collect::<CoreCryptoResult<HashMap<_, _>>>()?;
Ok(user_ids)
}

/// Returns true if the PKI environment has been set up.
pub async fn e2ei_is_pki_env_setup(&self) -> bool {
self.inner.e2ei_is_pki_env_setup().await
}
}
2 changes: 1 addition & 1 deletion crypto-ffi/src/e2ei/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl X509CredentialAcquisition {
) -> CoreCryptoResult<Self> {
let ciphersuite = config.ciphersuite;
let inner = wire_e2e_identity::X509CredentialAcquisition::try_new(
Arc::new(pki_environment.as_ref().clone().into()),
pki_environment.clone_inner(),
config.try_into_core()?,
)?;

Expand Down
25 changes: 16 additions & 9 deletions crypto-ffi/src/pki_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,14 @@ impl pki_env::hooks::PkiEnvironmentHooks for PkiEnvironmentHooksShim {
}

/// The PKI environment used for certificate management during X509 credential acquisition.
#[derive(derive_more::From, derive_more::Into, Clone, uniffi::Object)]
pub struct PkiEnvironment(wire_e2e_identity::pki_env::PkiEnvironment);
#[derive(uniffi::Object)]
pub struct PkiEnvironment(Arc<wire_e2e_identity::pki_env::PkiEnvironment>);

impl PkiEnvironment {
pub(crate) fn clone_inner(&self) -> Arc<wire_e2e_identity::pki_env::PkiEnvironment> {
self.0.clone()
}
}

#[cfg_attr(feature = "wasm", uniffi::export)]
impl PkiEnvironment {
Expand All @@ -232,7 +238,7 @@ impl PkiEnvironment {
pub async fn new(hooks: Arc<dyn PkiEnvironmentHooks>, database: Arc<Database>) -> CoreCryptoResult<Self> {
let shim = Arc::new(PkiEnvironmentHooksShim::new(hooks));
let pki_env = wire_e2e_identity::pki_env::PkiEnvironment::new(shim, database.as_ref().clone().into()).await?;
Ok(pki_env.into())
Ok(Self(Arc::new(pki_env)))
}
}

Expand All @@ -249,18 +255,19 @@ pub async fn create_pki_environment(
#[uniffi::export]
impl CoreCryptoFfi {
/// Set the PKI environment of the CoreCrypto instance.
pub async fn set_pki_environment(&self, pki_environment: Option<Arc<PkiEnvironment>>) -> CoreCryptoResult<()> {
let pki_environment = pki_environment.as_ref().map(|p| p.as_ref().clone()).map(Into::into);
pub async fn set_pki_environment(&self, pki_environment: Option<Arc<PkiEnvironment>>) {
self.inner
.set_pki_environment(pki_environment)
.await
.map_err(Into::into)
.set_pki_environment(pki_environment.map(|env| env.0.clone()))
.await;
}

/// Get the PKI environment of the CoreCrypto instance.
///
/// Returns null if it is not set.
pub async fn get_pki_environment(&self) -> Option<Arc<PkiEnvironment>> {
self.inner.get_pki_environment().await.map(PkiEnvironment).map(Arc::new)
let pki_env = self.inner.get_pki_environment();
(*pki_env.read().await)
.as_ref()
.map(|env| Arc::new(PkiEnvironment(env.clone())))
}
}
18 changes: 7 additions & 11 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl MlsTransport for CoreCryptoTransportNotImplementedProvider {
#[derive(Debug, Clone)]
pub struct CoreCrypto {
database: Database,
pki_environment: Arc<RwLock<Option<PkiEnvironment>>>,
pki_environment: Arc<RwLock<Option<Arc<PkiEnvironment>>>>,
mls: Arc<RwLock<Option<mls::session::Session<Database>>>>,
#[cfg(feature = "proteus")]
proteus: Arc<Mutex<Option<proteus::ProteusCentral>>>,
Expand All @@ -148,23 +148,19 @@ impl CoreCrypto {
}

/// Set the session's PKI Environment
pub async fn set_pki_environment(&self, pki_environment: Option<PkiEnvironment>) -> Result<()> {
pub async fn set_pki_environment(&self, pki_environment: Option<Arc<PkiEnvironment>>) {
*self.pki_environment.write().await = pki_environment;
if let Some(mls_session) = self.mls.write().await.as_mut() {
mls_session
.crypto_provider
.set_pki_environment_provider(pki_environment.as_ref().map(|p| p.mls_pki_env_provider()))
.await
.set_pki_environment(self.pki_environment.clone())
.await;
}

let mut guard = self.pki_environment.write().await;
*guard = pki_environment;

Ok(())
}

/// Get the session's PKI Environment
pub async fn get_pki_environment(&self) -> Option<PkiEnvironment> {
self.pki_environment.read().await.clone()
pub fn get_pki_environment(&self) -> Arc<RwLock<Option<Arc<PkiEnvironment>>>> {
self.pki_environment.clone()
}

/// Get the mls session if initialized
Expand Down
12 changes: 6 additions & 6 deletions crypto/src/mls/conversation/conversation_guard/decrypt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,11 @@ impl ConversationGuard {
let credential = message.credential();
let epoch = message.epoch();

let pki_env = provider.authentication_service().pki_env();
let guard = pki_env.read().await;
let identity = credential
.extract_identity(
self.ciphersuite().await,
provider.authentication_service().borrow().await.as_ref(),
)
.extract_identity(self.ciphersuite().await, guard.as_ref().map(|v| &**v))
.await
.map_err(RecursiveError::mls_credential("extracting identity"))?;

let sender_client_id: ClientId = credential.credential.identity().to_owned().into();
Expand Down Expand Up @@ -464,7 +464,7 @@ impl ConversationGuard {

async fn validate_commit(&self, commit: &StagedCommit) -> Result<()> {
let backend = self.crypto_provider().await?;
if backend.authentication_service().is_env_setup().await {
if backend.is_pki_env_setup().await {
let credentials: Vec<_> = commit
.add_proposals()
.filter_map(|add_proposal| {
Expand All @@ -477,7 +477,7 @@ impl ConversationGuard {
self.ciphersuite().await,
credentials.iter(),
crate::CredentialType::X509,
backend.authentication_service().borrow().await.as_ref(),
backend.authentication_service(),
)
.await;
if state != E2eiConversationState::Verified {
Expand Down
81 changes: 47 additions & 34 deletions crypto/src/mls/conversation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ use std::{
};

use core_crypto_keystore::Database;
use itertools::Itertools as _;
use log::trace;
use openmls::{
group::{MlsGroup, QueuedProposal},
Expand Down Expand Up @@ -195,14 +194,12 @@ pub trait Conversation<'a>: ConversationWithMls<'a> {
/// Credential generated by Wire's end-to-end identity enrollment
async fn e2ei_conversation_state(&'a self) -> Result<E2eiConversationState> {
let backend = self.crypto_provider().await?;
let authentication_service = backend.authentication_service();
authentication_service.refresh_time_of_interest().await;
let inner = self.conversation().await;
let state = Session::<Database>::compute_conversation_state(
inner.ciphersuite(),
inner.group.members_credentials(),
CredentialType::X509,
authentication_service.borrow().await.as_ref(),
backend.authentication_service(),
)
.await;
Ok(state)
Expand All @@ -222,20 +219,24 @@ pub trait Conversation<'a>: ConversationWithMls<'a> {
}
let mls_provider = self.crypto_provider().await?;
let auth_service = mls_provider.authentication_service();
auth_service.refresh_time_of_interest().await;
let auth_service = auth_service.borrow().await;
let env = auth_service.as_ref();
let conversation = self.conversation().await;
conversation
.members_with_key()
.into_iter()
.filter(|(id, _)| device_ids.iter().any(|client_id| client_id.borrow() == id))
.map(|(_, c)| {
c.extract_identity(conversation.ciphersuite(), env)
.map_err(RecursiveError::mls_credential("extracting identity"))
})
.collect::<Result<Vec<_>, _>>()
.map_err(Into::into)

let pki_env = auth_service.pki_env();
let guard = pki_env.read().await;

let mut identities = vec![];
for (id, credential) in conversation.members_with_key() {
if device_ids.iter().all(|client_id| client_id.borrow() != id) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect the any check to have better short-circuit behavior than this all implementation.

continue;
}
identities.push(
credential
.extract_identity(conversation.ciphersuite(), guard.as_ref().map(|v| &**v))
.await
.map_err(RecursiveError::mls_credential("extracting identity"))?,
);
}
Ok(identities)
}

/// From a given conversation, get the identity of the users (device holders) supplied.
Expand All @@ -252,25 +253,33 @@ pub trait Conversation<'a>: ConversationWithMls<'a> {
}
let mls_provider = self.crypto_provider().await?;
let auth_service = mls_provider.authentication_service();
auth_service.refresh_time_of_interest().await;
let auth_service = auth_service.borrow().await;
let env = auth_service.as_ref();
let conversation = self.conversation().await;
let user_ids = user_ids.iter().map(|uid| uid.as_bytes()).collect::<Vec<_>>();

conversation
.members_with_key()
.iter()
.filter_map(|(id, c)| UserId::try_from(id.as_slice()).ok().zip(Some(c)))
.filter(|(uid, _)| user_ids.contains(uid))
.map(|(uid, c)| {
let uid = String::try_from(uid).map_err(RecursiveError::mls_client("getting user identities"))?;
let identity = c
.extract_identity(conversation.ciphersuite(), env)
.map_err(RecursiveError::mls_credential("extracting identity"))?;
Ok((uid, identity))
})
.process_results(|iter| iter.into_group_map())
let pki_env = auth_service.pki_env();
let guard = pki_env.read().await;

let mut identities = HashMap::new();
for (id, credential) in conversation.members_with_key() {
let uid = match UserId::try_from(id.as_slice()) {
Ok(uid) => uid,
Err(_) => continue,
};

if !user_ids.contains(&uid) {
continue;
}

let uid = String::try_from(uid).map_err(RecursiveError::mls_client("getting user identities"))?;
let identity = credential
.extract_identity(conversation.ciphersuite(), guard.as_ref().map(|v| &**v))
.await
.map_err(RecursiveError::mls_credential("extracting identity"))?;
let value = identities.entry(uid).or_insert_with(Vec::new);
value.push(identity);
}

Ok(identities)
}

/// Generate a new [`crate::HistorySecret`].
Expand Down Expand Up @@ -575,6 +584,8 @@ mod tests {
);
}

// TODO: ignore this test for now, until we fix the test suite (WPB-25356)
#[ignore]
#[macro_rules_attribute::apply(smol_macros::test)]
async fn should_read_device_identities() {
let case = TestContext::default_x509();
Expand Down Expand Up @@ -635,7 +646,7 @@ mod tests {
.await
}

// TODO: ignore this test for now, until we rework the test suite & CRL handling (WPB-19580).
// TODO: ignore this test for now, until we fix the test suite (WPB-25356)
#[ignore]
#[macro_rules_attribute::apply(smol_macros::test)]
async fn should_read_revoked_device() {
Expand Down Expand Up @@ -723,6 +734,8 @@ mod tests {
.await
}

// TODO: ignore this test for now, until we fix the test suite (WPB-25356)
#[ignore]
#[macro_rules_attribute::apply(smol_macros::test)]
async fn should_read_users() {
let case = TestContext::default_x509();
Expand Down
6 changes: 4 additions & 2 deletions crypto/src/mls/conversation/own_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ impl MlsConversation {
credential: own_leaf.credential().clone(),
signature_key: own_leaf.signature_key().clone(),
};
let provider = provider.authentication_service();
let pki_env = provider.authentication_service().pki_env();
let guard = pki_env.read().await;
let identity = own_leaf_credential_with_key
.extract_identity(self.ciphersuite(), provider.borrow().await.as_ref())
.extract_identity(self.ciphersuite(), guard.as_ref().map(|v| &**v))
.await
.map_err(RecursiveError::mls_credential("extracting identity"))?;

Ok(MlsDecryptMessage {
Expand Down
19 changes: 7 additions & 12 deletions crypto/src/mls/conversation/pending_conversation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,20 +178,15 @@ impl PendingConversation {
};
let pki_env = self
.context
.pki_environment_option()
.pki_environment()
.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"))?,
};
let guard = pki_env.read().await;

let identity = own_leaf_credential_with_key
.extract_identity(conversation.ciphersuite(), guard.as_ref().map(|v| &**v))
.await
.map_err(RecursiveError::mls_credential("extracting identity"))?;

Ok(MlsDecryptMessage {
app_msg: None,
Expand Down
Loading
Loading