diff --git a/matrix_sdk_crypto/src/verification/sas.rs b/matrix_sdk_crypto/src/verification/sas.rs index 475e3e63..134ab1bc 100644 --- a/matrix_sdk_crypto/src/verification/sas.rs +++ b/matrix_sdk_crypto/src/verification/sas.rs @@ -1,10 +1,17 @@ use crate::Device; -use matrix_sdk_common::events::key::verification::{ - accept::AcceptEvent, - start::{StartEvent, StartEventContent}, - HashAlgorithm, KeyAgreementProtocol, MessageAuthenticationCode, ShortAuthenticationString, - VerificationMethod, +use olm_rs::sas::OlmSas; + +use matrix_sdk_common::events::{ + key::verification::{ + accept::AcceptEvent, + key::KeyEvent, + mac::MacEvent, + start::{MSasV1Content, MSasV1ContentOptions, StartEvent, StartEventContent}, + HashAlgorithm, KeyAgreementProtocol, MessageAuthenticationCode, ShortAuthenticationString, + VerificationMethod, + }, + ToDeviceEvent, }; use matrix_sdk_common::identifiers::{DeviceId, UserId}; use matrix_sdk_common::uuid::Uuid; @@ -15,13 +22,6 @@ struct SasIds { other_device: Device, } -struct ProtocolDefinitions { - key_agreement_protocols: Vec, - hashes: Vec, - message_auth_codes: Vec, - short_auth_string: Vec, -} - struct AcceptedProtocols { method: VerificationMethod, key_agreement_protocol: KeyAgreementProtocol, @@ -31,43 +31,61 @@ struct AcceptedProtocols { } struct Sas { + inner: OlmSas, ids: SasIds, verification_flow_id: Uuid, - protocol_definitions: ProtocolDefinitions, state: S, } +impl Sas { + pub fn user_id(&self) -> &UserId { + &self.ids.own_user_id + } +} + impl Sas { fn new(own_user_id: UserId, own_device_id: &DeviceId, other_device: Device) -> Sas { + let verification_flow_id = Uuid::new_v4(); + Sas { + inner: OlmSas::new(), ids: SasIds { own_user_id, own_device_id: own_device_id.into(), other_device, }, - verification_flow_id: Uuid::new_v4(), + verification_flow_id, - protocol_definitions: ProtocolDefinitions { - short_auth_string: vec![ - ShortAuthenticationString::Decimal, - ShortAuthenticationString::Emoji, - ], - key_agreement_protocols: vec![KeyAgreementProtocol::Curve25519], - message_auth_codes: vec![MessageAuthenticationCode::HkdfHmacSha256], - hashes: vec![HashAlgorithm::Sha256], + state: Created { + protocol_definitions: MSasV1ContentOptions { + transaction_id: verification_flow_id.to_string(), + from_device: own_device_id.into(), + short_authentication_string: vec![ + ShortAuthenticationString::Decimal, + ShortAuthenticationString::Emoji, + ], + key_agreement_protocols: vec![KeyAgreementProtocol::Curve25519HkdfSha256], + message_authentication_codes: vec![MessageAuthenticationCode::HkdfHmacSha256], + hashes: vec![HashAlgorithm::Sha256], + }, }, - - state: Created {}, } } + fn get_start_event(&self) -> StartEventContent { + StartEventContent::MSasV1( + MSasV1Content::new(self.state.protocol_definitions.clone()) + .expect("Invalid initial protocol definitions."), + ) + } + fn into_accepted(self, event: &AcceptEvent) -> Sas { let content = &event.content; Sas { + inner: self.inner, ids: self.ids, verification_flow_id: self.verification_flow_id, - protocol_definitions: self.protocol_definitions, state: Accepted { commitment: content.commitment.clone(), accepted_protocols: AcceptedProtocols { @@ -82,16 +100,20 @@ impl Sas { } } -struct Created {} +struct Created { + protocol_definitions: MSasV1ContentOptions, +} -struct Started {} +struct Started { + protocol_definitions: MSasV1Content, +} impl Sas { fn from_start_event( - own_user_id: UserId, + own_user_id: &UserId, own_device_id: &DeviceId, other_device: Device, - event: &StartEvent, + event: &ToDeviceEvent, ) -> Sas { let content = if let StartEventContent::MSasV1(content) = &event.content { content @@ -100,26 +122,134 @@ impl Sas { }; Sas { + inner: OlmSas::new(), + ids: SasIds { - own_user_id, + own_user_id: own_user_id.clone(), own_device_id: own_device_id.into(), other_device, }, + verification_flow_id: Uuid::new_v4(), - protocol_definitions: ProtocolDefinitions { - short_auth_string: content.short_authentication_string.clone(), - key_agreement_protocols: content.key_agreement_protocols.clone(), - message_auth_codes: content.message_authentication_codes.clone(), - hashes: content.hashes.clone(), + state: Started { + protocol_definitions: content.clone(), }, - - state: Started {}, } } + + fn into_key_received(self, event: &KeyEvent) -> Sas { + todo!() + } } struct Accepted { accepted_protocols: AcceptedProtocols, commitment: String, } + +impl Sas { + fn into_key_received(self, event: &KeyEvent) -> Sas { + todo!() + } +} + +struct KeyReceived { + accepted_protocols: AcceptedProtocols, +} + +impl Sas { + fn into_mac_received(self, event: &MacEvent) -> Sas { + todo!() + } + + fn confirm(self) -> Sas { + todo!() + } +} + +struct Confirmed { + accepted_protocols: AcceptedProtocols, +} + +impl Sas { + fn confirm(self) -> Sas { + todo!() + } +} + +struct MacReceived { + verified_devices: Vec, + verified_master_keys: Vec, +} + +impl Sas { + fn into_done(self, event: &MacEvent) -> Sas { + todo!() + } +} + +struct Done { + verified_devices: Vec, + verified_master_keys: Vec, +} + +#[cfg(test)] +mod test { + use std::convert::TryFrom; + + use crate::{Account, Device}; + use matrix_sdk_common::events::key::verification::{ + accept::AcceptEvent, + key::KeyEvent, + mac::MacEvent, + start::{MSasV1Content, MSasV1ContentOptions, StartEvent, StartEventContent}, + }; + use matrix_sdk_common::events::{AnyToDeviceEvent, ToDeviceEvent}; + use matrix_sdk_common::identifiers::{DeviceId, UserId}; + + use super::{Created, Sas, Started}; + + fn alice_id() -> UserId { + UserId::try_from("@alice:example.org").unwrap() + } + + fn alice_device_id() -> Box { + "JLAFKJWSCS".into() + } + + fn bob_id() -> UserId { + UserId::try_from("@bob:example.org").unwrap() + } + + fn bob_device_id() -> Box { + "BOBDEVCIE".into() + } + + fn wrap_start_event( + sender: &UserId, + content: StartEventContent, + ) -> ToDeviceEvent { + ToDeviceEvent { + sender: sender.clone(), + content, + } + } + + #[tokio::test] + async fn create_sas() { + let alice = Account::new(&alice_id(), &alice_device_id()); + let alice_device = Device::from_account(&alice).await; + + let bob = Account::new(&bob_id(), &bob_device_id()); + let bob_device = Device::from_account(&bob).await; + + let alice_sas = Sas::::new(alice_id(), &alice_device_id(), bob_device); + + let start_content = alice_sas.get_start_event(); + let event = wrap_start_event(alice_sas.user_id(), start_content); + + let bob_sas = + Sas::::from_start_event(bob.user_id(), bob.device_id(), alice_device, &event); + } +}