From 454ae27d9e4761d6229785c11404222c421895ac Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Wed, 8 May 2024 13:51:31 +0200 Subject: [PATCH] [uniffi] Make mls-rs-crypto-openssl optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For Android, we will be using a crypto provider based on BoringSSL. It is therefore important that mls-rs-uniffi becomes agnostic to the crypto provider. This PR handles this very simply: by requiring two things: - the user sets a Cargo feature to depend on the right crypto provider implementation, - that the crypto provider has a suitable `new()` method that can be used to instantiate it. A better alternative would be to make the choice of crypto provider dynamic via a trait. Unfortunately, I don’t think this is supported with UniFFI because it doesn’t support associated types in exported traits and because it also doesn’t support generic exported types. Making a single non-generic type which uses ```rust struct CryptoProviderAdapter { crypto_provider: Box } ``` fail because the `CryptoProvider` trait has an associated type, which I cannot specify at this point. --- mls-rs-uniffi/Cargo.toml | 7 ++++++- mls-rs-uniffi/src/config.rs | 14 +++++++++++--- mls-rs-uniffi/src/lib.rs | 10 ++++------ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/mls-rs-uniffi/Cargo.toml b/mls-rs-uniffi/Cargo.toml index 9b5bca70..04f077cd 100644 --- a/mls-rs-uniffi/Cargo.toml +++ b/mls-rs-uniffi/Cargo.toml @@ -14,15 +14,20 @@ rust-version = "1.68.2" crate-type = ["lib", "cdylib"] name = "mls_rs_uniffi" +[features] +openssl = ["mls-rs-crypto-openssl"] +default = ["openssl"] + [dependencies] async-trait = "0.1.77" maybe-async = "0.2.10" mls-rs = { version = "0.39.0", path = "../mls-rs" } mls-rs-core = { version = "0.18.0", path = "../mls-rs-core" } -mls-rs-crypto-openssl = { version = "0.9.0", path = "../mls-rs-crypto-openssl" } thiserror = "1.0.57" uniffi = { git = "https://github.com/mozilla/uniffi-rs/", rev = "eeb785c", version = "0.27.0" } +mls-rs-crypto-openssl = { version = "0.9.0", path = "../mls-rs-crypto-openssl", optional = true } + [target.'cfg(mls_build_async)'.dependencies] tokio = { version = "1.36.0", features = ["sync"] } diff --git a/mls-rs-uniffi/src/config.rs b/mls-rs-uniffi/src/config.rs index 4bf2e6b0..43ccb505 100644 --- a/mls-rs-uniffi/src/config.rs +++ b/mls-rs-uniffi/src/config.rs @@ -6,9 +6,8 @@ use mls_rs::{ identity::basic, storage_provider::in_memory::InMemoryGroupStateStorage, }; -use mls_rs_crypto_openssl::OpensslCryptoProvider; -use self::group_state::{GroupStateStorage, GroupStateStorageAdapter}; +use crate::config::group_state::{GroupStateStorage, GroupStateStorageAdapter}; use crate::Error; pub mod group_state; @@ -56,10 +55,19 @@ impl mls_rs_core::group::GroupStateStorage for ClientGroupStorage { } } +#[cfg(not(any(feature = "openssl")))] +compile_error!( + "The crypto provider must be set by enabling exactly one of the \ + following Cargo features: [\"openssl\"]." +); + +#[cfg(feature = "openssl")] +pub type UniFFICryptoProvider = mls_rs_crypto_openssl::OpensslCryptoProvider; + pub type UniFFIConfig = client_builder::WithIdentityProvider< basic::BasicIdentityProvider, client_builder::WithCryptoProvider< - OpensslCryptoProvider, + UniFFICryptoProvider, WithGroupStateStorage, >, >; diff --git a/mls-rs-uniffi/src/lib.rs b/mls-rs-uniffi/src/lib.rs index 4dc45e1d..7f722bda 100644 --- a/mls-rs-uniffi/src/lib.rs +++ b/mls-rs-uniffi/src/lib.rs @@ -21,8 +21,8 @@ mod config; use std::sync::Arc; -pub use config::ClientConfig; -use config::UniFFIConfig; +pub use config::{client_config_default, ClientConfig}; +use config::{UniFFIConfig, UniFFICryptoProvider}; #[cfg(not(mls_build_async))] use std::sync::Mutex; @@ -36,7 +36,6 @@ use mls_rs::mls_rules; use mls_rs::{CipherSuiteProvider, CryptoProvider}; use mls_rs_core::identity; use mls_rs_core::identity::{BasicCredential, IdentityProvider}; -use mls_rs_crypto_openssl::OpensslCryptoProvider; uniffi::setup_scaffolding!(); @@ -320,7 +319,7 @@ impl TryFrom for CipherSuite { pub async fn generate_signature_keypair( cipher_suite: CipherSuite, ) -> Result { - let crypto_provider = mls_rs_crypto_openssl::OpensslCryptoProvider::default(); + let crypto_provider = UniFFICryptoProvider::new(); let cipher_suite_provider = crypto_provider .cipher_suite_provider(cipher_suite.into()) .ok_or(MlsError::UnsupportedCipherSuite(cipher_suite.into()))?; @@ -364,7 +363,6 @@ impl Client { let cipher_suite = signature_keypair.cipher_suite; let public_key = signature_keypair.public_key; let secret_key = signature_keypair.secret_key; - let crypto_provider = OpensslCryptoProvider::new(); let basic_credential = BasicCredential::new(id); let signing_identity = identity::SigningIdentity::new(basic_credential.into_credential(), public_key.into()); @@ -373,7 +371,7 @@ impl Client { .with_single_welcome_message(true); let mls_rules = mls_rules::DefaultMlsRules::new().with_commit_options(commit_options); let client = mls_rs::Client::builder() - .crypto_provider(crypto_provider) + .crypto_provider(UniFFICryptoProvider::new()) .identity_provider(basic::BasicIdentityProvider::new()) .signing_identity(signing_identity, secret_key.into(), cipher_suite.into()) .group_state_storage(client_config.group_state_storage.into())