Skip to content

Commit

Permalink
feat: add e2ei_is_enabled for clients to spot if their MLS client i…
Browse files Browse the repository at this point in the history
…s enrolled for end-to-end identity
  • Loading branch information
beltram committed Jul 29, 2023
1 parent 068196a commit 1521ad7
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 0 deletions.
10 changes: 10 additions & 0 deletions crypto-ffi/bindings/js/CoreCrypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1735,6 +1735,16 @@ export class CoreCrypto {
return await CoreCryptoError.asyncMapErr(this.#cc.e2ei_is_degraded(conversationId));
}

/**
* Returns true when end-to-end-identity is enabled for the given Ciphersuite
*
* @param ciphersuite of the credential to check
* @returns true end-to-end identity is enabled for the given ciphersuite
*/
async e2eiIsEnabled(ciphersuite: Ciphersuite): Promise<boolean> {
return await CoreCryptoError.asyncMapErr(this.#cc.e2ei_is_enabled(ciphersuite));
}

/**
* Returns the current version of {@link CoreCrypto}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ interface MLSClient {
suspend fun deriveSecret(groupId: MLSGroupId, keyLength: UInt): ByteArray

suspend fun e2eiIsDegraded(groupId: MLSGroupId): Boolean

suspend fun e2eiIsEnabled(ciphersuite: Ciphersuite): Boolean
}

@Suppress("TooManyFunctions")
Expand Down Expand Up @@ -279,6 +281,10 @@ class MLSClientImpl(
return cc.e2eiIsDegraded(groupId.toUByteList())
}

override suspend fun e2eiIsEnabled(ciphersuite: Ciphersuite): Boolean {
return cc.e2eiIsEnabled(ciphersuite)
}

companion object {

private val keyRotationDuration: Duration = 30.toDuration(DurationUnit.DAYS)
Expand Down
8 changes: 8 additions & 0 deletions crypto-ffi/bindings/swift/Sources/CoreCrypto/CoreCrypto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,14 @@ public class CoreCryptoWrapper {
return try await self.coreCrypto.e2eiIsDegraded(conversationId: conversationId)
}

/// Returns true when end-to-end-identity is enabled for the given Ciphersuite
///
/// - parameter ciphersuite: of the credential to check
/// - returns: true end-to-end identity is enabled for the given ciphersuite
public func e2eiIsEnabled(ciphersuite: UInt16) async throws -> Bool {
return try await self.coreCrypto.e2eiIsEnabled(ciphersuite: ciphersuite)
}

/// - returns: The CoreCrypto version
public static func version() -> String {
return CoreCryptoSwift.version()
Expand Down
6 changes: 6 additions & 0 deletions crypto-ffi/src/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,12 @@ impl CoreCrypto {
let is_degraded = self.central.lock().await.e2ei_is_degraded(&conversation_id).await?;
Ok(is_degraded)
}

/// See [core_crypto::mls::MlsCentral::e2ei_is_enabled]
pub async fn e2ei_is_enabled(&self, ciphersuite: Ciphersuite) -> CryptoResult<bool> {
let sc = MlsCiphersuite::from(ciphersuite).signature_algorithm();
self.central.lock().await.e2ei_is_enabled(sc)
}
}

#[cfg_attr(not(feature = "proteus"), allow(unused_variables))]
Expand Down
20 changes: 20 additions & 0 deletions crypto-ffi/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2485,6 +2485,26 @@ impl CoreCrypto {
.err_into(),
)
}

/// Returns [`WasmCryptoResult<bool>`]
///
/// see [core_crypto::mls::MlsCentral::e2ei_is_enabled]
pub fn e2ei_is_enabled(&self, ciphersuite: Ciphersuite) -> Promise {
let sc = MlsCiphersuite::from(ciphersuite).signature_algorithm();
let this = self.inner.clone();
future_to_promise(
async move {
let is_enabled = this
.write()
.await
.e2ei_is_enabled(sc)
.map_err(CoreCryptoError::from)?
.into();
WasmCryptoResult::Ok(is_enabled)
}
.err_into(),
)
}
}

#[derive(Debug)]
Expand Down
78 changes: 78 additions & 0 deletions crypto/src/e2e_identity/enabled.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//! Utility for clients to get the current state of E2EI when the app resumes

use crate::prelude::{CryptoError, CryptoResult, MlsCentral, MlsCredentialType};
use openmls_traits::types::SignatureScheme;

impl MlsCentral {
/// Returns true when end-to-end-identity is enabled for the given SignatureScheme
pub fn e2ei_is_enabled(&self, signature_scheme: SignatureScheme) -> CryptoResult<bool> {
let client = self.mls_client.as_ref().ok_or(CryptoError::MlsNotInitialized)?;
let maybe_x509 = client.find_most_recent_credential_bundle(signature_scheme, MlsCredentialType::X509);
match maybe_x509 {
None => {
client
.find_most_recent_credential_bundle(signature_scheme, MlsCredentialType::Basic)
.ok_or(CryptoError::CredentialNotFound)?;
Ok(false)
}
Some(_) => Ok(true),
}
}
}

#[cfg(test)]
pub mod tests {
use crate::{prelude::MlsCredentialType, test_utils::*, CryptoError};
use openmls_traits::types::SignatureScheme;
use wasm_bindgen_test::*;

wasm_bindgen_test_configure!(run_in_browser);

#[apply(all_cred_cipher)]
#[wasm_bindgen_test]
pub async fn should_be_false_when_basic_and_true_when_x509(case: TestCase) {
run_test_with_client_ids(case.clone(), ["alice"], move |[cc]| {
Box::pin(async move {
let e2ei_is_enabled = cc.e2ei_is_enabled(case.signature_scheme()).unwrap();
match case.credential_type {
MlsCredentialType::Basic => assert!(!e2ei_is_enabled),
MlsCredentialType::X509 => assert!(e2ei_is_enabled),
};
})
})
.await
}

#[apply(all_cred_cipher)]
#[wasm_bindgen_test]
pub async fn should_fail_when_no_client(case: TestCase) {
run_test_wo_clients(case.clone(), move |cc| {
Box::pin(async move {
assert!(matches!(
cc.e2ei_is_enabled(case.signature_scheme()).unwrap_err(),
CryptoError::MlsNotInitialized
));
})
})
.await
}

#[apply(all_cred_cipher)]
#[wasm_bindgen_test]
pub async fn should_fail_when_no_credential_for_given_signature_scheme(case: TestCase) {
run_test_with_client_ids(case.clone(), ["alice"], move |[cc]| {
Box::pin(async move {
// just return something different from the signature scheme the MlsCentral was initialized with
let other_sc = match case.signature_scheme() {
SignatureScheme::ED25519 => SignatureScheme::ECDSA_SECP256R1_SHA256,
_ => SignatureScheme::ED25519,
};
assert!(matches!(
cc.e2ei_is_enabled(other_sc).unwrap_err(),
CryptoError::CredentialNotFound
));
})
})
.await
}
}
1 change: 1 addition & 0 deletions crypto/src/e2e_identity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{

mod crypto;
pub(crate) mod degraded;
pub mod enabled;
pub mod error;
pub(crate) mod identity;
pub(crate) mod rotate;
Expand Down

0 comments on commit 1521ad7

Please sign in to comment.