Skip to content

Commit

Permalink
Create dummy identity with in memory keystore
Browse files Browse the repository at this point in the history
  • Loading branch information
richardhuaaa committed Oct 23, 2023
1 parent 4639280 commit 0abf678
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 7 deletions.
15 changes: 9 additions & 6 deletions xmtp_mls/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::configuration::CIPHERSUITE;
use crate::xmtp_openmls_provider::XmtpOpenMlsProvider;
use crate::StorageError;
use crate::{
client::{Client, Network},
Expand Down Expand Up @@ -109,13 +111,14 @@ where
// Fetch the Identity based upon the identity strategy.
let identity = match self.identity_strategy {
IdentityStrategy::CachedOnly(_) => {
// TODO
Identity {}
}
IdentityStrategy::CreateIfNotFound(_owner) => {
// TODO
Identity {}
// TODO: persistence/retrieval
unimplemented!()
}
IdentityStrategy::CreateIfNotFound(_owner) => Identity::new(
CIPHERSUITE,
&XmtpOpenMlsProvider::default(),
"unimplemented".as_bytes(), // TODO
),
#[cfg(test)]
IdentityStrategy::ExternalIdentity(a) => a,
};
Expand Down
4 changes: 4 additions & 0 deletions xmtp_mls/src/configuration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use openmls_traits::types::Ciphersuite;

// TODO confirm ciphersuite choice
pub const CIPHERSUITE: Ciphersuite = Ciphersuite::MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519;
49 changes: 48 additions & 1 deletion xmtp_mls/src/identity.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
use openmls::{
prelude::{Credential, CredentialType, CredentialWithKey, CryptoConfig},
prelude_test::KeyPackage,
versions::ProtocolVersion,
};
use openmls_basic_credential::SignatureKeyPair;
use openmls_traits::{types::Ciphersuite, OpenMlsProvider};
use thiserror::Error;
use xmtp_cryptography::signature::SignatureError;

Expand All @@ -11,4 +18,44 @@ pub enum IdentityError {
BadAssocation(#[from] AssociationError),
}

pub struct Identity {}
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Identity {
pub(crate) credential_with_key: CredentialWithKey,
pub(crate) signer: SignatureKeyPair,
}

impl Identity {
pub(crate) fn new(
ciphersuite: Ciphersuite,
provider: &impl OpenMlsProvider,
id: &[u8],
) -> Self {
let credential = Credential::new(id.to_vec(), CredentialType::Basic).unwrap();
let signature_keys = SignatureKeyPair::new(ciphersuite.signature_algorithm()).unwrap();
let credential_with_key = CredentialWithKey {
credential,
signature_key: signature_keys.to_public_vec().into(),
};
signature_keys.store(provider.key_store()).unwrap();

// TODO: Make OpenMLS not delete this once used
let _last_resort_key_package = KeyPackage::builder()
.build(
CryptoConfig {
ciphersuite,
version: ProtocolVersion::default(),
},
provider,
&signature_keys,
credential_with_key.clone(),
)
.unwrap();

// TODO: upload

Self {
credential_with_key,
signer: signature_keys,
}
}
}
2 changes: 2 additions & 0 deletions xmtp_mls/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
pub mod association;
pub mod builder;
pub mod client;
mod configuration;
pub mod identity;
pub mod mock_xmtp_api_client;
pub mod owner;
pub mod storage;
pub mod types;
mod xmtp_openmls_provider;

pub use client::{Client, Network};
use storage::StorageError;
Expand Down
59 changes: 59 additions & 0 deletions xmtp_mls/src/storage/in_memory_key_store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use openmls_traits::key_store::{MlsEntity, OpenMlsKeyStore};
use std::{collections::HashMap, sync::RwLock};

#[derive(Debug, Default)]
pub struct InMemoryKeyStore {
values: RwLock<HashMap<Vec<u8>, Vec<u8>>>,
}

impl OpenMlsKeyStore for InMemoryKeyStore {
/// The error type returned by the [`OpenMlsKeyStore`].
type Error = InMemoryKeyStoreError;

/// Store a value `v` that implements the [`ToKeyStoreValue`] trait for
/// serialization for ID `k`.
///
/// Returns an error if storing fails.
fn store<V: MlsEntity>(&self, k: &[u8], v: &V) -> Result<(), Self::Error> {
let value = serde_json::to_vec(v).map_err(|_| InMemoryKeyStoreError::SerializationError)?;
// We unwrap here, because this is the only function claiming a write
// lock on `credential_bundles`. It only holds the lock very briefly and
// should not panic during that period.
let mut values = self.values.write().unwrap();
values.insert(k.to_vec(), value);
Ok(())
}

/// Read and return a value stored for ID `k` that implements the
/// [`FromKeyStoreValue`] trait for deserialization.
///
/// Returns [`None`] if no value is stored for `k` or reading fails.
fn read<V: MlsEntity>(&self, k: &[u8]) -> Option<V> {
// We unwrap here, because the two functions claiming a write lock on
// `init_key_package_bundles` (this one and `generate_key_package_bundle`) only
// hold the lock very briefly and should not panic during that period.
let values = self.values.read().unwrap();
if let Some(value) = values.get(k) {
serde_json::from_slice(value).ok()
} else {
None
}
}

/// Delete a value stored for ID `k`.
///
/// Returns an error if storing fails.
fn delete<V: MlsEntity>(&self, k: &[u8]) -> Result<(), Self::Error> {
// We just delete both ...
let mut values = self.values.write().unwrap();
values.remove(k);
Ok(())
}
}

/// Errors thrown by the key store.
#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
pub enum InMemoryKeyStoreError {
#[error("Error serializing value.")]
SerializationError,
}
1 change: 1 addition & 0 deletions xmtp_mls/src/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod encrypted_store;
mod errors;
pub mod in_memory_key_store;

pub use encrypted_store::{DbConnection, EncryptedMessageStore, EncryptionKey, StorageOption};
pub use errors::StorageError;
28 changes: 28 additions & 0 deletions xmtp_mls/src/xmtp_openmls_provider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use openmls_rust_crypto::RustCrypto;
use openmls_traits::OpenMlsProvider;

use crate::storage::in_memory_key_store::InMemoryKeyStore;

#[derive(Default, Debug)]
pub struct XmtpOpenMlsProvider {
crypto: RustCrypto,
key_store: InMemoryKeyStore,
}

impl OpenMlsProvider for XmtpOpenMlsProvider {
type CryptoProvider = RustCrypto;
type RandProvider = RustCrypto;
type KeyStoreProvider = InMemoryKeyStore;

fn crypto(&self) -> &Self::CryptoProvider {
&self.crypto
}

fn rand(&self) -> &Self::RandProvider {
&self.crypto
}

fn key_store(&self) -> &Self::KeyStoreProvider {
&self.key_store
}
}

0 comments on commit 0abf678

Please sign in to comment.