Skip to content

Commit

Permalink
[uniffi] Make mls-rs-crypto-openssl optional
Browse files Browse the repository at this point in the history
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<dyn CryptoProvider>
}
```

fail because the `CryptoProvider` trait has an associated type, which
I cannot specify at this point.
  • Loading branch information
mgeisler committed May 8, 2024
1 parent 310df89 commit 454ae27
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 10 deletions.
7 changes: 6 additions & 1 deletion mls-rs-uniffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }

Expand Down
14 changes: 11 additions & 3 deletions mls-rs-uniffi/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<ClientGroupStorage, client_builder::BaseConfig>,
>,
>;
Expand Down
10 changes: 4 additions & 6 deletions mls-rs-uniffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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!();

Expand Down Expand Up @@ -320,7 +319,7 @@ impl TryFrom<mls_rs::CipherSuite> for CipherSuite {
pub async fn generate_signature_keypair(
cipher_suite: CipherSuite,
) -> Result<SignatureKeypair, Error> {
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()))?;
Expand Down Expand Up @@ -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());
Expand All @@ -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())
Expand Down

0 comments on commit 454ae27

Please sign in to comment.