Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ internal class E2EITest : HasMockDeliveryService() {
assert(pkiEnv2 != null)
}

@Ignore("Temporarily broken until PKI environment is decoupled from session initialization implemented with WPB-22816")
@Test
fun sample_e2ei_enrollment_should_succeed() = runTest {
val aliceId = genClientId()
Expand Down
5 changes: 2 additions & 3 deletions crypto-ffi/src/credential.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use core_crypto::{Ciphersuite as CryptoCiphersuite, Credential as CryptoCredential, RustCrypto};
use core_crypto::{Ciphersuite as CryptoCiphersuite, Credential as CryptoCredential};

use crate::{Ciphersuite, CoreCryptoResult, CredentialType, SignatureScheme, client_id::ClientId};

Expand All @@ -16,9 +16,8 @@ pub struct Credential(pub(crate) CryptoCredential);

impl Credential {
fn basic_impl(ciphersuite: Ciphersuite, client_id: &Arc<ClientId>) -> CoreCryptoResult<Self> {
let crypto = RustCrypto::default();
let client_id_ref = client_id.as_ref().as_ref();
CryptoCredential::basic(CryptoCiphersuite::from(ciphersuite), client_id_ref.to_owned(), crypto)
CryptoCredential::basic(CryptoCiphersuite::from(ciphersuite), client_id_ref.to_owned())
.map(Into::into)
.map_err(Into::into)
}
Expand Down
4 changes: 2 additions & 2 deletions crypto/benches/utils/mls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use core_crypto::{
CertificateBundle, Ciphersuite, ClientId, ClientIdentifier, ConnectionType, ConversationId, CoreCrypto,
Credential as CcCredential, CredentialFindFilters, CredentialRef, CredentialType, Database, DatabaseKey,
HistorySecret, MlsCommitBundle, MlsConversationConfiguration, MlsCryptoProvider, MlsGroupInfoBundle, MlsTransport,
MlsTransportData, MlsTransportResponse, RustCrypto,
MlsTransportData, MlsTransportResponse,
};
use criterion::BenchmarkId;
use openmls::{
Expand Down Expand Up @@ -179,7 +179,7 @@ pub async fn new_central(

let credential = match certificate_bundle {
Some(certificate_bundle) => CcCredential::x509(ciphersuite, certificate_bundle.to_owned()).unwrap(),
None => CcCredential::basic(ciphersuite, client_id, RustCrypto::default()).unwrap(),
None => CcCredential::basic(ciphersuite, client_id).unwrap(),
};
let credential_ref = ctx.add_credential(credential).await.unwrap();

Expand Down
6 changes: 3 additions & 3 deletions crypto/src/e2e_identity/enrollment/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use super::{Error, Result};
use crate::{
Ciphersuite, MlsError,
e2e_identity::crypto::E2eiSignatureKeypair,
mls_provider::{MlsCryptoProvider, RustCrypto},
mls_provider::{CRYPTO, RustCrypto},
};

impl super::E2eiEnrollment {
pub(crate) fn new_sign_key(ciphersuite: Ciphersuite, backend: &MlsCryptoProvider) -> Result<E2eiSignatureKeypair> {
let (sk, _) = backend
pub(crate) fn new_sign_key(ciphersuite: Ciphersuite) -> Result<E2eiSignatureKeypair> {
let (sk, _) = CRYPTO
.signature_key_gen(ciphersuite.signature_algorithm())
.map_err(MlsError::wrap("performing signature keygen"))?;
E2eiSignatureKeypair::try_new(ciphersuite.signature_algorithm(), sk)
Expand Down
22 changes: 9 additions & 13 deletions crypto/src/e2e_identity/enrollment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ mod crypto;
#[cfg(test)]
pub mod test_utils;

use core_crypto_keystore::CryptoKeystoreMls as _;
use openmls_traits::{OpenMlsCryptoProvider as _, random::OpenMlsRand as _};
use core_crypto_keystore::CryptoKeystoreMls;
use openmls_traits::random::OpenMlsRand as _;
use wire_e2e_identity::{RustyE2eIdentity, prelude::E2eiAcmeAuthorization};
use zeroize::Zeroize as _;

use super::{EnrollmentHandle, Error, Json, Result, crypto::E2eiSignatureKeypair, id::QualifiedE2eiClientId, types};
use crate::{Ciphersuite, ClientId, KeystoreError, MlsError, mls_provider::MlsCryptoProvider};
use crate::{Ciphersuite, ClientId, KeystoreError, MlsError, mls_provider::CRYPTO};

/// Wire end to end identity solution for fetching a x509 certificate which identifies a client.
#[derive(Debug, serde::Serialize, serde::Deserialize)]
Expand Down Expand Up @@ -54,15 +54,14 @@ impl E2eiEnrollment {
handle: String,
team: Option<String>,
expiry_sec: u32,
backend: &MlsCryptoProvider,
ciphersuite: Ciphersuite,
sign_keypair: Option<E2eiSignatureKeypair>,
has_called_new_oidc_challenge_request: bool,
) -> Result<Self> {
let alg = ciphersuite.try_into()?;
let sign_sk = sign_keypair
.map(Ok)
.unwrap_or_else(|| Self::new_sign_key(ciphersuite, backend))?;
.unwrap_or_else(|| Self::new_sign_key(ciphersuite))?;

let client_id = QualifiedE2eiClientId::try_from(client_id.as_slice())?;
let client_id = String::try_from(client_id)?;
Expand Down Expand Up @@ -441,26 +440,23 @@ impl E2eiEnrollment {
Ok(certificates)
}

pub(crate) async fn stash(self, backend: &MlsCryptoProvider) -> Result<EnrollmentHandle> {
pub(crate) async fn stash(self, database: impl CryptoKeystoreMls) -> Result<EnrollmentHandle> {
// should be enough to prevent collisions
const HANDLE_SIZE: usize = 32;

let content = serde_json::to_vec(&self)?;
let handle = backend
.crypto()
let handle = CRYPTO
.random_vec(HANDLE_SIZE)
.map_err(MlsError::wrap("generating random vector of bytes"))?;
backend
.key_store()
database
.save_e2ei_enrollment(&handle, &content)
.await
.map_err(KeystoreError::wrap("saving e2ei enrollment"))?;
Ok(handle)
}

pub(crate) async fn stash_pop(backend: &MlsCryptoProvider, handle: EnrollmentHandle) -> Result<Self> {
let content = backend
.key_store()
pub(crate) async fn stash_pop(database: impl CryptoKeystoreMls, handle: EnrollmentHandle) -> Result<Self> {
let content = database
.pop_e2ei_enrollment(&handle)
.await
.map_err(KeystoreError::wrap("popping e2ei enrollment"))?
Expand Down
2 changes: 1 addition & 1 deletion crypto/src/e2e_identity/enrollment/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
pub(crate) const E2EI_DISPLAY_NAME: &str = "Alice Smith";
pub(crate) const E2EI_HANDLE: &str = "alice_wire";
pub(crate) const E2EI_CLIENT_ID: &str = "bd4c7053-1c5a-4020-9559-cd7bf7961954:4959bc6ab12f2846@world.com";
pub(crate) const E2EI_CLIENT_ID_URI: &str = "vUxwUxxaQCCVWc1795YZVA!4959bc6ab12f2846@world.com";
pub(crate) const E2EI_CLIENT_ID_URI: &str = "wireapp://vUxwUxxaQCCVWc1795YZVA!4959bc6ab12f2846@world.com";
pub(crate) const E2EI_EXPIRY: u32 = 90 * 24 * 3600;
pub(crate) const NEW_HANDLE: &str = "new_alice_wire";
pub(crate) const NEW_DISPLAY_NAME: &str = "New Alice Smith";
Expand Down
6 changes: 3 additions & 3 deletions crypto/src/ephemeral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ pub(crate) async fn generate_history_secret(ciphersuite: Ciphersuite) -> Result<
.session()
.await
.map_err(RecursiveError::transaction("Getting mls session"))?;
let credential = Credential::basic(ciphersuite, client_id.clone(), &session.crypto_provider).map_err(
RecursiveError::mls_credential("generating basic credential for ephemeral client"),
)?;
let credential = Credential::basic(ciphersuite, client_id.clone()).map_err(RecursiveError::mls_credential(
"generating basic credential for ephemeral client",
))?;
let credential_ref = tx
.add_credential(credential)
.await
Expand Down
14 changes: 5 additions & 9 deletions crypto/src/mls/credential/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use self::{
credential_type::CredentialType,
error::Error,
};
use crate::{Ciphersuite, ClientId, ClientIdRef, ClientIdentifier, MlsError, RecursiveError};
use crate::{Ciphersuite, ClientId, ClientIdRef, ClientIdentifier, MlsError, RecursiveError, mls_provider::CRYPTO};

/// A cryptographic credential.
///
Expand Down Expand Up @@ -86,9 +86,9 @@ impl Credential {
///
/// The earliest validity of this credential is always 0. It will be updated once the credential is added to a
/// session.
pub fn basic(ciphersuite: Ciphersuite, client_id: ClientId, crypto: impl OpenMlsCrypto) -> Result<Self> {
pub fn basic(ciphersuite: Ciphersuite, client_id: ClientId) -> Result<Self> {
let signature_scheme = ciphersuite.signature_algorithm();
let (private_key, public_key) = crypto
let (private_key, public_key) = CRYPTO
.signature_key_gen(signature_scheme)
.map_err(MlsError::wrap("generating signature key"))?;
let signature_key_pair = SignatureKeyPair::from_raw(signature_scheme, private_key, public_key);
Expand Down Expand Up @@ -158,13 +158,9 @@ impl Credential {
/// Create a credential from an identifier
// currently only used in test code, but generally applicable
#[cfg_attr(not(test), expect(dead_code))]
pub(crate) fn from_identifier(
identifier: &ClientIdentifier,
ciphersuite: Ciphersuite,
crypto: impl OpenMlsCrypto,
) -> Result<Self> {
pub(crate) fn from_identifier(identifier: &ClientIdentifier, ciphersuite: Ciphersuite) -> Result<Self> {
match identifier {
ClientIdentifier::Basic(client_id) => Self::basic(ciphersuite, client_id.clone(), crypto),
ClientIdentifier::Basic(client_id) => Self::basic(ciphersuite, client_id.clone()),
ClientIdentifier::X509(certs) => {
let signature_scheme = ciphersuite.signature_algorithm();
let cert = certs
Expand Down
8 changes: 2 additions & 6 deletions crypto/src/mls/key_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@
//!
//! On the other hand, the `KeyPackage` API isn't strictly ideal, so we improve on it here.

use std::sync::LazyLock;

pub use openmls::prelude::KeyPackage as Keypackage;
use openmls::prelude::{KeyPackageRef as KpHashRef, Lifetime, SignatureScheme};

use crate::{Ciphersuite, CredentialType, MlsError, mls_provider::RustCrypto};

static CRYPTO: LazyLock<RustCrypto> = LazyLock::new(RustCrypto::default);
use crate::{Ciphersuite, CredentialType, MlsError, mls_provider::CRYPTO};

/// Extensions on the `KeyPackage` type for nicer usage patterns.
pub trait KeypackageExt {
Expand All @@ -36,7 +32,7 @@ pub trait KeypackageExt {
impl KeypackageExt for Keypackage {
fn make_ref(&self) -> Result<KeypackageRef, MlsError> {
let hash_ref = self
.hash_ref(&*CRYPTO)
.hash_ref(CRYPTO.as_ref())
.map_err(MlsError::wrap("computing keypackage hash ref"))?;

let ciphersuite = <Self as KeypackageExt>::ciphersuite(self);
Expand Down
25 changes: 13 additions & 12 deletions crypto/src/mls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ mod tests {

use crate::{
CertificateBundle, ClientIdentifier, CoreCrypto, CredentialType,
mls::HasSessionAndCrypto,
test_utils::{x509::X509TestChain, *},
transaction_context::Error as TransactionError,
};
Expand Down Expand Up @@ -86,22 +85,29 @@ mod tests {
.await;
}

// TODO: This test has to be disabled because of the session rewrite. We have to create a session first right now.
// It must be enabled and working again with WPB-22816.
#[ignore]
#[apply(all_cred_cipher)]
async fn can_2_phase_init_central(mut case: TestContext) {
let db = case.create_persistent_db().await;
Box::pin(async move {
use std::sync::Arc;

use crate::{ClientId, Credential};
use crate::{
ClientId, Credential,
e2e_identity::{pki_env::PkiEnvironment, pki_env_hooks::test::DummyPkiEnvironmentHooks},
};

let x509_test_chain = X509TestChain::init_empty(case.signature_scheme());

// phase 1: init without initialized mls_client
let cc = CoreCrypto::new(db);
let cc = CoreCrypto::new(db.clone());
let context = cc.new_transaction().await.unwrap();

let hooks = Arc::new(DummyPkiEnvironmentHooks);
let pki_env = PkiEnvironment::new(hooks, db).await.expect("creating pki environment");
cc.set_pki_environment(Some(pki_env))
.await
.expect("setting pki environment");

x509_test_chain.register_with_central(&context).await;

// phase 2: init mls_client
Expand All @@ -120,12 +126,7 @@ mod tests {
.await
.unwrap();

let credential = Credential::from_identifier(
&identifier,
case.ciphersuite(),
&context.crypto_provider().await.unwrap(),
)
.unwrap();
let credential = Credential::from_identifier(&identifier, case.ciphersuite()).unwrap();
let credential_ref = context.add_credential(credential).await.unwrap();

// expect mls_client to work
Expand Down
6 changes: 5 additions & 1 deletion crypto/src/mls_provider/crypto_provider.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::sync::{Arc, RwLock, RwLockWriteGuard};
use std::sync::{Arc, LazyLock, RwLock, RwLockWriteGuard};

use aes_gcm::{
Aes128Gcm, Aes256Gcm, KeyInit,
Expand All @@ -21,6 +21,10 @@ use tls_codec::SecretVLBytes;

use super::{EntropySeed, MlsProviderError};

/// Singleton for `RustCrypto`
/// Because of the reseed feature we have to use this
pub(crate) static CRYPTO: LazyLock<Arc<RustCrypto>> = LazyLock::new(|| Arc::new(RustCrypto::default()));

/// The type that implements
/// - key generation
/// - AEAD encryption & decryption
Expand Down
9 changes: 6 additions & 3 deletions crypto/src/mls_provider/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// TODO: remove this expect(unreachable_pub) once the E2EI parts have been coupled.
#![expect(unreachable_pub)]
use std::sync::Arc;

pub use core_crypto_keystore::{Database, DatabaseKey};

mod crypto_provider;
mod error;
mod pki;

pub(crate) use crypto_provider::CRYPTO;
pub use crypto_provider::RustCrypto;
pub use error::{MlsProviderError, MlsProviderResult};
use openmls_traits::{
Expand Down Expand Up @@ -68,7 +71,7 @@ impl std::ops::DerefMut for EntropySeed {
/// The MLS crypto provider
#[derive(Debug, Clone)]
pub struct MlsCryptoProvider {
crypto: RustCrypto,
crypto: Arc<RustCrypto>,
key_store: Database,
pki_env: PkiEnvironmentProvider,
}
Expand All @@ -82,7 +85,7 @@ impl MlsCryptoProvider {
pub fn new(key_store: Database) -> Self {
Self {
key_store,
crypto: Default::default(),
crypto: Arc::clone(&CRYPTO),
pki_env: Default::default(),
}
}
Expand All @@ -91,7 +94,7 @@ impl MlsCryptoProvider {
pub fn new_with_pki_env(key_store: Database, pki_env: PkiEnvironmentProvider) -> Self {
Self {
key_store,
crypto: Default::default(),
crypto: Arc::clone(&CRYPTO),
pki_env,
}
}
Expand Down
4 changes: 2 additions & 2 deletions crypto/src/mls_provider/pki.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use openmls_traits::{
use spki::{SignatureAlgorithmIdentifier, der::referenced::RefToOwned};

use super::error::{MlsProviderError, MlsProviderResult};
use crate::mls_provider::CRYPTO;

#[derive(Debug, Clone, Default)]
pub struct PkiEnvironmentProvider(Arc<RwLock<Option<wire_e2e_identity::prelude::x509::revocation::PkiEnvironment>>>);
Expand Down Expand Up @@ -711,9 +712,8 @@ impl PkiKeypair {
}

pub fn rand_unchecked(alg: SignatureScheme) -> Self {
let provider = super::RustCrypto::default();
use openmls_traits::crypto::OpenMlsCrypto;
Self::new(alg, provider.signature_key_gen(alg).unwrap().0).unwrap()
Self::new(alg, CRYPTO.signature_key_gen(alg).unwrap().0).unwrap()
}

pub fn rand(alg: SignatureScheme, crypto: &super::RustCrypto) -> super::MlsProviderResult<Self> {
Expand Down
7 changes: 1 addition & 6 deletions crypto/src/proteus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,12 +647,7 @@ mod tests {
};
let transport = Arc::new(CoreCryptoTransportSuccessProvider::default());
transaction.mls_init(identifier.clone(), transport).await.unwrap();
let credential = Credential::from_identifier(
&identifier,
case.ciphersuite(),
&transaction.mls_provider().await.unwrap(),
)
.unwrap();
let credential = Credential::from_identifier(&identifier, case.ciphersuite()).unwrap();
let credential_ref = transaction.add_credential(credential).await.unwrap();

// expect MLS to work
Expand Down
3 changes: 1 addition & 2 deletions crypto/src/test_utils/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,11 @@ impl SessionContext {

/// Create, save, and add a new credential of the type relevant to this test
pub async fn new_credential(&mut self, case: &TestContext, signer: Option<&X509Certificate>) -> Arc<Credential> {
let backend = &self.transaction.mls_provider().await.unwrap();
let session = self.session().await;
let client_id = session.id();

let credential = match case.credential_type {
CredentialType::Basic => Credential::basic(case.ciphersuite(), client_id, backend).unwrap(),
CredentialType::Basic => Credential::basic(case.ciphersuite(), client_id).unwrap(),
CredentialType::X509 => {
let cert_bundle = CertificateBundle::rand(&client_id, signer.unwrap());
Credential::x509(case.ciphersuite(), cert_bundle).unwrap()
Expand Down
Loading
Loading