Skip to content

Commit

Permalink
feat!: remove PerDomainTrustAnchor extension altogether. Backward inc…
Browse files Browse the repository at this point in the history
…ompatible changes !
  • Loading branch information
beltram committed Dec 20, 2023
1 parent a7ff1d1 commit a44b81f
Show file tree
Hide file tree
Showing 17 changed files with 51 additions and 2,120 deletions.
69 changes: 0 additions & 69 deletions crypto-ffi/bindings/js/CoreCrypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,25 +187,6 @@ export interface ConversationConfiguration {
* Implementation specific configuration
*/
custom?: CustomConfiguration;
/**
* Trust anchors to be added in the group's context extensions
*/
perDomainTrustAnchors?: PerDomainTrustAnchor[];
}

/**
* A wrapper containing the configuration for trust anchors to be added in the group's context
* extensions
*/
export interface PerDomainTrustAnchor {
/**
* Domain name of the owning backend this anchor refers to. One of the certificate in the chain has to have this domain in its SANs
*/
domain_name: string;
/**
* PEM encoded (partial) certificate chain. This contains the certificate chain for the CA certificate issuing the E2E Identity certificates
*/
intermediate_certificate_chain: string;
}

/**
Expand Down Expand Up @@ -1017,14 +998,12 @@ export class CoreCrypto {
ciphersuite,
externalSenders,
custom = {},
perDomainTrustAnchors = [],
} = configuration || {};
const config = new ConversationConfigurationFfi(
ciphersuite,
externalSenders,
custom?.keyRotationSpan,
custom?.wirePolicy,
perDomainTrustAnchors as any[]
);
const ret = await CoreCryptoError.asyncMapErr(
this.#cc.create_conversation(
Expand Down Expand Up @@ -1117,54 +1096,6 @@ export class CoreCrypto {
);
}

/**
* Updates the trust anchors for a conversation. This should be called when a federated event happens (new team added/removed).
* Clients should add and/or remove trust anchors from the new backend to the conversation. The method will check
* for duplicated domains and the validity of the certificate chain.
*
* **CAUTION**: {@link CoreCrypto.commitAccepted} **HAS TO** be called afterwards **ONLY IF** the Delivery Service responds
* '200 OK' to the {@link CommitBundle} upload. It will "merge" the commit locally i.e. increment the local group
* epoch, use new encryption secrets etc...
*
* @param conversationId - The ID of the conversation
* @param removeDomainNames - Domains to remove from the trust anchors
* @param addTrustAnchors - New trust anchors to add to the conversation
*
* @returns A {@link CommitBundle}
*/
async updateTrustAnchorsFromConversation(
conversationId: ConversationId,
removeDomainNames: string[],
addTrustAnchors: PerDomainTrustAnchor[]
): Promise<CommitBundle> {
try {
const ffiRet: CoreCryptoFfiTypes.CommitBundle =
await CoreCryptoError.asyncMapErr(
this.#cc.update_trust_anchors_from_conversation(
conversationId,
removeDomainNames,
addTrustAnchors
)
);

const gi = ffiRet.group_info;

const ret: CommitBundle = {
welcome: ffiRet.welcome,
commit: ffiRet.commit,
groupInfo: {
encryptionType: gi.encryption_type,
ratchetTreeType: gi.ratchet_tree_type,
payload: gi.payload,
},
};

return ret;
} catch (e) {
throw CoreCryptoError.fromStdError(e as Error);
}
}

/**
* Ingest a TLS-serialized MLS welcome message to join an existing MLS group
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,20 +206,17 @@ class MLSClient(private val cc: com.wire.crypto.CoreCrypto) {
* @param ciphersuite of the conversation. A credential for the given ciphersuite must already have been created
* @param creatorCredentialType kind of credential the creator wants to create the group with
* @param externalSenders keys fetched from backend for validating external remove proposals
* @param perDomainTrustAnchors 🚧 in progress. Leave empty for now
*/
suspend fun createConversation(
id: MLSGroupId,
ciphersuite: Ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519,
creatorCredentialType: CredentialType = CredentialType.Basic,
externalSenders: List<ExternalSenderKey> = emptyList(),
perDomainTrustAnchors: List<com.wire.crypto.PerDomainTrustAnchor> = emptyList(),
) {
val cfg = com.wire.crypto.ConversationConfiguration(
ciphersuite.lower(),
externalSenders.map { it.lower() },
defaultGroupConfiguration,
perDomainTrustAnchors
)

cc.createConversation(id.lower(), creatorCredentialType.lower(), cfg)
Expand Down Expand Up @@ -259,23 +256,6 @@ class MLSClient(private val cc: com.wire.crypto.CoreCrypto) {
return cc.encryptMessage(id.lower(), message.lower()).toMlsMessage()
}

/**
* Creates a Commit with a GroupContextExtension Proposal for updating the TrustAnchors of the group
*
* 🚧 Work in progress
*
* @param id conversation identifier
* @param removeDomainNames domains to remove, can intersect [addTrustAnchors]]
* @param addTrustAnchors new Anchors to add
*/
suspend fun updateTrustAnchorsFromConversation(
id: MLSGroupId,
removeDomainNames: List<String>,
addTrustAnchors: List<com.wire.crypto.PerDomainTrustAnchor>,
): CommitBundle {
return cc.updateTrustAnchorsFromConversation(id.lower(), removeDomainNames, addTrustAnchors).lift()
}

/**
* Decrypts a message for a given conversation
*
Expand Down
38 changes: 2 additions & 36 deletions crypto-ffi/bindings/swift/Sources/CoreCrypto/CoreCrypto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public struct ProteusAutoPrekeyBundle: ConvertToInner {
public struct ConversationConfiguration: ConvertToInner {
typealias Inner = CoreCryptoSwift.ConversationConfiguration
func convert() -> Inner {
return CoreCryptoSwift.ConversationConfiguration(ciphersuite: self.ciphersuite, externalSenders: self.externalSenders, custom: self.custom.convert(), self.perDomainTrustAnchor.convert())
return CoreCryptoSwift.ConversationConfiguration(ciphersuite: self.ciphersuite, externalSenders: self.externalSenders, custom: self.custom.convert())
}

/// Conversation ciphersuite
Expand All @@ -213,32 +213,11 @@ public struct ConversationConfiguration: ConvertToInner {
public var externalSenders: [[UInt8]]
/// Implementation specific configuration
public var custom: CustomConfiguration
/// Trust anchors to be added in the group's context extensions
public var perDomainTrustAnchor: PerDomainTrustAnchor

public init(ciphersuite: UInt16, externalSenders: [[UInt8]], custom: CustomConfiguration, perDomainTrustAnchor: PerDomainTrustAnchor) {
public init(ciphersuite: UInt16, externalSenders: [[UInt8]], custom: CustomConfiguration) {
self.ciphersuite = ciphersuite
self.externalSenders = externalSenders
self.custom = custom
self.perDomainTrustAnchor = perDomainTrustAnchor
}
}

/// A wrapper containing the configuration for trust anchors to be added in the group's context extensions
public struct PerDomainTrustAnchor: ConvertToInner {
typealias Inner = CoreCryptoSwift.PerDomainTrustAnchor
func convert() -> Inner {
return CoreCryptoSwift.PerDomainTrustAnchor(domain_name: self.domainName, intermediate_certificate_chain: self.intermediateCertificateChain)
}

/// Domain name in which the trust anchor belongs to
public var domainName: String
/// PEM encoded certificate chain
public var intermediateCertificateChain: String

public init(domainName: String, intermediateCertificateChain: String) {
self.domainName = domainName
self.intermediateCertificateChain = intermediateCertificateChain
}
}

Expand Down Expand Up @@ -849,19 +828,6 @@ public class CoreCryptoWrapper {
return try await self.coreCrypto.encryptMessage(conversationId: conversationId, message: message)
}

/// Updates the trust anchors for a conversation
///
/// - parameter conversationId - The ID of the conversation
/// - parameter removeDomainNames - Domains to remove from the trust anchors
/// - parameter addTrustAnchors - New trust anchors to add to the conversation
///
/// - returns: A ``CommitBundle`` byte array to fan out to the Delivery Service
public func updateTrustAnchorsFromConversation(conversationId: ConversationId, removeDomainNames: [string], addTrustAnchors: [PerDomainTrustAnchor]) async throws -> CommitBundle {
return try await self.coreCrypto.update_trust_anchors_from_conversation(conversationId: conversationId, removeDomainNames: removeDomainNames, addTrustAnchors: addTrustAnchors.map({ (anchor) -> CoreCryptoSwift.PerDomainTrustAnchor in
return anchor.convert()
})).convertTo()
}

/// Creates a new add proposal within a group
///
/// - parameter conversationId: conversation identifier
Expand Down
40 changes: 0 additions & 40 deletions crypto-ffi/src/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,14 +503,6 @@ pub struct ConversationConfiguration {
pub ciphersuite: Ciphersuite,
pub external_senders: Vec<Vec<u8>>,
pub custom: CustomConfiguration,
pub per_domain_trust_anchors: Vec<PerDomainTrustAnchor>,
}

#[derive(Debug, Clone, uniffi::Record)]
/// See [core_crypto::prelude::PerDomainTrustAnchor]
pub struct PerDomainTrustAnchor {
pub domain_name: String,
pub intermediate_certificate_chain: String,
}

impl TryInto<MlsConversationConfiguration> for ConversationConfiguration {
Expand All @@ -521,24 +513,11 @@ impl TryInto<MlsConversationConfiguration> for ConversationConfiguration {
ciphersuite: self.ciphersuite.into(),
..Default::default()
};

cfg.set_raw_external_senders(self.external_senders);

cfg.per_domain_trust_anchors = self.per_domain_trust_anchors.into_iter().map(|a| a.into()).collect();

Ok(cfg)
}
}

impl From<PerDomainTrustAnchor> for core_crypto::prelude::PerDomainTrustAnchor {
fn from(cfg: PerDomainTrustAnchor) -> Self {
Self {
domain_name: cfg.domain_name,
intermediate_certificate_chain: cfg.intermediate_certificate_chain,
}
}
}

#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, uniffi::Enum)]
#[repr(u8)]
pub enum MlsWirePolicy {
Expand Down Expand Up @@ -1030,25 +1009,6 @@ impl CoreCrypto {
.await?)
}

/// See [core_crypto::mls::MlsCentral::update_trust_anchors_from_conversation]
pub async fn update_trust_anchors_from_conversation(
&self,
id: ConversationId,
remove_domain_names: Vec<String>,
add_trust_anchors: Vec<PerDomainTrustAnchor>,
) -> CoreCryptoResult<CommitBundle> {
self.central
.lock()
.await
.update_trust_anchors_from_conversation(
&id,
remove_domain_names,
add_trust_anchors.into_iter().map(|a| a.into()).collect(),
)
.await?
.try_into()
}

/// See [core_crypto::mls::MlsCentral::conversation_exists]
pub async fn conversation_exists(&self, conversation_id: Vec<u8>) -> bool {
self.central.lock().await.conversation_exists(&conversation_id).await
Expand Down
80 changes: 0 additions & 80 deletions crypto-ffi/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,25 +784,6 @@ pub struct ConversationConfiguration {
ciphersuite: Option<Ciphersuite>,
external_senders: Vec<Vec<u8>>,
custom: CustomConfiguration,
per_domain_trust_anchors: Vec<PerDomainTrustAnchor>,
}

#[wasm_bindgen]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PerDomainTrustAnchor {
domain_name: String,
intermediate_certificate_chain: String,
}

#[wasm_bindgen]
impl PerDomainTrustAnchor {
#[wasm_bindgen(constructor)]
pub fn new(domain_name: String, intermediate_certificate_chain: String) -> Self {
Self {
domain_name,
intermediate_certificate_chain,
}
}
}

#[wasm_bindgen]
Expand All @@ -813,7 +794,6 @@ impl ConversationConfiguration {
external_senders: Option<Vec<Uint8Array>>,
key_rotation_span: Option<u32>,
wire_policy: Option<WirePolicy>,
per_domain_trust_anchors: js_sys::Array,
) -> WasmCryptoResult<ConversationConfiguration> {
let external_senders = external_senders
.map(|exs| exs.iter().cloned().map(|jsv| jsv.to_vec()).collect())
Expand All @@ -822,27 +802,10 @@ impl ConversationConfiguration {
ciphersuite,
external_senders,
custom: CustomConfiguration::new(key_rotation_span, wire_policy),
per_domain_trust_anchors: if per_domain_trust_anchors.is_null() {
vec![]
} else {
per_domain_trust_anchors
.into_iter()
.map(|js_anchor| Ok(serde_wasm_bindgen::from_value(js_anchor)?))
.collect::<WasmCryptoResult<Vec<_>>>()?
},
})
}
}

impl From<PerDomainTrustAnchor> for core_crypto::prelude::PerDomainTrustAnchor {
fn from(wasm_cfg: PerDomainTrustAnchor) -> Self {
Self {
domain_name: wasm_cfg.domain_name,
intermediate_certificate_chain: wasm_cfg.intermediate_certificate_chain,
}
}
}

impl TryInto<MlsConversationConfiguration> for ConversationConfiguration {
type Error = CoreCryptoError;
fn try_into(mut self) -> WasmCryptoResult<MlsConversationConfiguration> {
Expand All @@ -858,8 +821,6 @@ impl TryInto<MlsConversationConfiguration> for ConversationConfiguration {
cfg.ciphersuite = mls_ciphersuite.into();
}

cfg.per_domain_trust_anchors = self.per_domain_trust_anchors.into_iter().map(|a| a.into()).collect();

Ok(cfg)
}
}
Expand Down Expand Up @@ -1688,47 +1649,6 @@ impl CoreCrypto {
)
}

/// Returns: [`WasmCryptoResult<CommitBundle>`]
///
/// see [core_crypto::mls::MlsCentral::update_trust_anchors_from_conversation]
pub fn update_trust_anchors_from_conversation(
&self,
conversation_id: ConversationId,
remove_domain_names: Box<[js_sys::JsString]>,
add_trust_anchors: js_sys::Array,
) -> Promise {
let this = self.inner.clone();
future_to_promise(
async move {
let add_trust_anchors = if add_trust_anchors.is_null() {
vec![]
} else {
add_trust_anchors
.into_iter()
.map(|js_anchor| -> WasmCryptoResult<PerDomainTrustAnchor> {
Ok(serde_wasm_bindgen::from_value(js_anchor)?)
})
.map(|result| Ok(result?.into()))
.collect::<WasmCryptoResult<Vec<_>>>()?
};
let commit = this
.write()
.await
.update_trust_anchors_from_conversation(
&conversation_id.to_vec(),
remove_domain_names.iter().map(String::from).collect(),
add_trust_anchors,
)
.await
.map_err(CoreCryptoError::from)?;
let commit: CommitBundle = commit.try_into()?;

WasmCryptoResult::Ok(serde_wasm_bindgen::to_value(&commit)?)
}
.err_into(),
)
}

/// Returns: [`WasmCryptoResult<js_sys::Uint8Array>`]
///
/// see [core_crypto::mls::MlsCentral::new_add_proposal]
Expand Down
2 changes: 1 addition & 1 deletion crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub mod prelude {
handshake::{MlsCommitBundle, MlsConversationCreationMessage, MlsProposalBundle},
*,
},
credential::{trust_anchor::PerDomainTrustAnchor, typ::MlsCredentialType, x509::CertificateBundle},
credential::{typ::MlsCredentialType, x509::CertificateBundle},
external_commit::MlsConversationInitBundle,
proposal::{MlsProposal, MlsProposalRef},
MlsCentral,
Expand Down
Loading

0 comments on commit a44b81f

Please sign in to comment.