Skip to content

Commit

Permalink
Add support for last resort key packages (#331)
Browse files Browse the repository at this point in the history
* Add support for last resort key packages

* Remove top up key packages
  • Loading branch information
neekolas authored Nov 13, 2023
1 parent 15626cb commit 56687a5
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 115 deletions.
50 changes: 25 additions & 25 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions mls_validation_service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ path = "src/main.rs"
prost = { version = "0.11", features = ["prost-derive"] }
tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread", "full"] }
tonic = "^0.9"
xmtp_proto = { path = "../xmtp_proto", features = ["proto_full", "grpc", "tonic"] }
openmls = { git= "https://github.com/openmls/openmls", features = ["test-utils"] }
openmls_traits = { git= "https://github.com/openmls/openmls" }
openmls_basic_credential = { git= "https://github.com/openmls/openmls" }
openmls_rust_crypto = { git= "https://github.com/openmls/openmls" }
xmtp_proto = { path = "../xmtp_proto", features = [
"proto_full",
"grpc",
"tonic",
] }
openmls = { git = "https://github.com/xmtp/openmls", features = ["test-utils"] }
openmls_traits = { git = "https://github.com/xmtp/openmls" }
openmls_basic_credential = { git = "https://github.com/xmtp/openmls" }
openmls_rust_crypto = { git = "https://github.com/xmtp/openmls" }
xmtp_mls = { path = "../xmtp_mls" }
serde = "1.0.189"
hex = "0.4.3"
Expand All @@ -25,4 +29,4 @@ env_logger = "0.10.0"

[dev-dependencies]
ethers = "2.0.10"
rand = "0.8.5"
rand = "0.8.5"
24 changes: 15 additions & 9 deletions xmtp_mls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,33 @@ native = ["libsqlite3-sys/bundled-sqlcipher-vendored-openssl"]
[dependencies]
anyhow = "1.0.71"
async-trait = "0.1.68"
diesel = { version = "2.1.3", features = ["sqlite", "r2d2", "returning_clauses_for_sqlite_3_35"] }
diesel = { version = "2.1.3", features = [
"sqlite",
"r2d2",
"returning_clauses_for_sqlite_3_35",
] }
diesel_migrations = { version = "2.1.0", features = ["sqlite"] }
ethers = "2.0.4"
ethers-core = "2.0.4"
futures = "0.3.28"
hex = "0.4.3"
libsqlite3-sys = { version = "0.26.0", optional = true}
openmls = { git= "https://github.com/xmtp/openmls", features = ["test-utils"] }
openmls_traits = { git= "https://github.com/xmtp/openmls" }
openmls_basic_credential = { git= "https://github.com/xmtp/openmls" }
openmls_rust_crypto = { git= "https://github.com/xmtp/openmls" }
libsqlite3-sys = { version = "0.26.0", optional = true }
openmls = { git = "https://github.com/xmtp/openmls", branch = "main", features = [
"test-utils",
] }
openmls_traits = { git = "https://github.com/xmtp/openmls", branch = "main" }
openmls_basic_credential = { git = "https://github.com/xmtp/openmls", branch = "main" }
openmls_rust_crypto = { git = "https://github.com/xmtp/openmls", branch = "main" }
prost = { version = "0.11", features = ["prost-derive"] }
rand = "0.8.5"
serde = "1.0.160"
serde_json = "1.0.96"
thiserror = "1.0.40"
tokio = { version = "1.28.1", features = ["macros"] }
tokio = { version = "1.28.1", features = ["macros"] }
log = "0.4.17"
tracing = "0.1.37"
tracing = "0.1.37"
toml = "0.7.4"
xmtp_cryptography = { path = "../xmtp_cryptography"}
xmtp_cryptography = { path = "../xmtp_cryptography" }
xmtp_proto = { path = "../xmtp_proto", features = ["proto_full"] }
tls_codec = "0.3.0"

Expand Down
47 changes: 0 additions & 47 deletions xmtp_mls/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,6 @@ where
Ok(())
}

pub async fn top_up_key_packages(&self) -> Result<(), ClientError> {
let key_packages: Result<Vec<Vec<u8>>, ClientError> = (0..KEY_PACKAGE_TOP_UP_AMOUNT)
.map(|_| -> Result<Vec<u8>, ClientError> {
let kp = self.identity.new_key_package(&self.mls_provider())?;
let kp_bytes = kp.tls_serialize_detached()?;

Ok(kp_bytes)
})
.collect();

self.api_client.upload_key_packages(key_packages?).await?;

Ok(())
}

async fn get_all_active_installation_ids(
&self,
wallet_addresses: Vec<String>,
Expand Down Expand Up @@ -243,38 +228,6 @@ mod tests {
assert_eq!(installation_ids.len(), 1);
}

#[tokio::test]
async fn test_top_up_key_packages() {
let wallet = generate_local_wallet();
let wallet_address = wallet.get_address();
let client = ClientBuilder::new_test_client(wallet.clone().into()).await;

client.register_identity().await.unwrap();
client.top_up_key_packages().await.unwrap();

let key_packages = client
.get_key_packages_for_wallet_addresses(vec![wallet_address.clone()])
.await
.unwrap();

assert_eq!(key_packages.len(), 1);

let key_package = key_packages.first().unwrap();
assert_eq!(key_package.wallet_address, wallet_address);

let key_packages_2 = client
.get_key_packages_for_wallet_addresses(vec![wallet_address.clone()])
.await
.unwrap();

assert_eq!(key_packages_2.len(), 1);

// Ensure we got back different key packages
let key_package_2 = key_packages_2.first().unwrap();
assert_eq!(key_package_2.wallet_address, wallet_address);
assert!(!(key_package_2.eq(key_package)));
}

#[tokio::test]
async fn test_find_groups() {
let client = ClientBuilder::new_test_client(generate_local_wallet().into()).await;
Expand Down
75 changes: 47 additions & 28 deletions xmtp_mls/src/identity.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use std::default;

Check warning on line 1 in xmtp_mls/src/identity.rs

View workflow job for this annotation

GitHub Actions / Test

unused import: `std::default`

use openmls::{
extensions::LastResortExtension,
prelude::{
Credential, CredentialType, CredentialWithKey, CryptoConfig, KeyPackage, KeyPackageNewError,
Capabilities, Credential, CredentialType, CredentialWithKey, CryptoConfig, Extension,
ExtensionType, Extensions, KeyPackage, KeyPackageNewError,
},
versions::ProtocolVersion,
};
Expand Down Expand Up @@ -52,49 +56,50 @@ impl Identity {

let credential = Identity::create_credential(&signature_keys, owner)?;

// The builder automatically stores it in the key store
// TODO: Make OpenMLS not delete this once used
let _last_resort_key_package = KeyPackage::builder().build(
CryptoConfig {
ciphersuite: CIPHERSUITE,
version: ProtocolVersion::default(),
},
provider,
&signature_keys,
CredentialWithKey {
credential: credential.clone(),
signature_key: signature_keys.to_public_vec().into(),
},
)?;

let identity = Self {
account_address: owner.get_address(),
installation_keys: signature_keys,
credential,
};
identity.new_key_package(&provider)?;
StoredIdentity::from(&identity).store(&mut store.conn()?)?;

// TODO: upload credential_with_key and last_resort_key_package

Ok(identity)
}

// ONLY CREATES LAST RESORT KEY PACKAGES
// TODO: Implement key package rotation https://github.com/xmtp/libxmtp/issues/293
pub(crate) fn new_key_package(
&self,
provider: &XmtpOpenMlsProvider,
) -> Result<KeyPackage, IdentityError> {
let kp = KeyPackage::builder().build(
CryptoConfig {
ciphersuite: CIPHERSUITE,
version: ProtocolVersion::default(),
},
provider,
&self.installation_keys,
CredentialWithKey {
credential: self.credential.clone(),
signature_key: self.installation_keys.to_public_vec().into(),
},
)?;
let last_resort = Extension::LastResort(LastResortExtension::default());
let extensions = Extensions::single(last_resort);
let capabilities = Capabilities::new(
None,
Some(&[CIPHERSUITE]),
Some(&[ExtensionType::LastResort]),
None,
None,
);
// TODO: Set expiration
let kp = KeyPackage::builder()
.leaf_node_capabilities(capabilities)
.key_package_extensions(extensions)
.build(
CryptoConfig {
ciphersuite: CIPHERSUITE,
version: ProtocolVersion::default(),
},
provider,
&self.installation_keys,
CredentialWithKey {
credential: self.credential.clone(),
signature_key: self.installation_keys.to_public_vec().into(),
},
)?;

Ok(kp)
}
Expand All @@ -121,6 +126,7 @@ impl Identity {

#[cfg(test)]
mod tests {
use openmls::prelude::ExtensionType;
use xmtp_cryptography::utils::generate_local_wallet;

use super::Identity;
Expand All @@ -136,4 +142,17 @@ mod tests {
)
.unwrap();
}

#[test]
fn test_key_package_extensions() {
let store = EncryptedMessageStore::new_test();
let provider = XmtpOpenMlsProvider::new(&store);
let identity = Identity::new(&store, &provider, &generate_local_wallet()).unwrap();

let new_key_package = identity.new_key_package(&provider).unwrap();
assert!(new_key_package
.extensions()
.contains(ExtensionType::LastResort));
assert!(new_key_package.last_resort())
}
}

0 comments on commit 56687a5

Please sign in to comment.