From 6ded76a5a7afe5bf3ed5d21eec13ecb646151967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 10 Jul 2020 17:10:34 +0200 Subject: [PATCH] crypto: Move the device_keys() method into the account. --- matrix_sdk_crypto/src/machine.rs | 55 ++----------------------- matrix_sdk_crypto/src/olm.rs | 70 +++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 53 deletions(-) diff --git a/matrix_sdk_crypto/src/machine.rs b/matrix_sdk_crypto/src/machine.rs index 29addb22..7e4cf13a 100644 --- a/matrix_sdk_crypto/src/machine.rs +++ b/matrix_sdk_crypto/src/machine.rs @@ -94,11 +94,6 @@ impl std::fmt::Debug for OlmMachine { } impl OlmMachine { - const ALGORITHMS: &'static [&'static Algorithm] = &[ - &Algorithm::OlmV1Curve25519AesSha2, - &Algorithm::MegolmV1AesSha2, - ]; - const MAX_TO_DEVICE_MESSAGES: usize = 20; /// Create a new memory based OlmMachine. @@ -568,50 +563,6 @@ impl OlmMachine { } } - /// Sign the device keys and return a JSON Value to upload them. - async fn device_keys(&self) -> DeviceKeys { - let identity_keys = self.account.identity_keys(); - - let mut keys = BTreeMap::new(); - - keys.insert( - AlgorithmAndDeviceId(KeyAlgorithm::Curve25519, self.device_id.clone()), - identity_keys.curve25519().to_owned(), - ); - keys.insert( - AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, self.device_id.clone()), - identity_keys.ed25519().to_owned(), - ); - - let device_keys = json!({ - "user_id": self.user_id, - "device_id": self.device_id, - "algorithms": OlmMachine::ALGORITHMS, - "keys": keys, - }); - - let mut signatures = BTreeMap::new(); - - let mut signature = BTreeMap::new(); - signature.insert( - AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, self.device_id.clone()), - self.sign_json(&device_keys).await, - ); - signatures.insert(self.user_id.clone(), signature); - - DeviceKeys { - user_id: self.user_id.clone(), - device_id: self.device_id.clone(), - algorithms: vec![ - Algorithm::OlmV1Curve25519AesSha2, - Algorithm::MegolmV1AesSha2, - ], - keys, - signatures, - unsigned: None, - } - } - /// Generate, sign and prepare one-time keys to be uploaded. /// /// If no one-time keys need to be uploaded returns an empty error. @@ -743,7 +694,7 @@ impl OlmMachine { let shared = self.account.shared(); let device_keys = if !shared { - Some(self.device_keys().await) + Some(self.account.device_keys().await) } else { None }; @@ -1803,7 +1754,7 @@ mod test { async fn test_device_key_signing() { let machine = OlmMachine::new(&user_id(), &alice_device_id()); - let mut device_keys = machine.device_keys().await; + let mut device_keys = machine.account.device_keys().await; let identity_keys = machine.account.identity_keys(); let ed25519_key = identity_keys.ed25519(); @@ -1836,7 +1787,7 @@ mod test { async fn test_invalid_signature() { let machine = OlmMachine::new(&user_id(), &alice_device_id()); - let mut device_keys = machine.device_keys().await; + let mut device_keys = machine.account.device_keys().await; let ret = machine.verify_json( &machine.user_id, diff --git a/matrix_sdk_crypto/src/olm.rs b/matrix_sdk_crypto/src/olm.rs index 6997e959..47dfe4e5 100644 --- a/matrix_sdk_crypto/src/olm.rs +++ b/matrix_sdk_crypto/src/olm.rs @@ -19,6 +19,8 @@ use std::sync::Arc; use matrix_sdk_common::locks::Mutex; use serde::Serialize; +use serde_json::{json, Value}; +use std::collections::BTreeMap; use zeroize::Zeroize; pub use olm_rs::account::IdentityKeys; @@ -34,8 +36,11 @@ pub use olm_rs::{ utility::OlmUtility, }; -use matrix_sdk_common::api::r0::keys::SignedKey; use matrix_sdk_common::identifiers::{DeviceId, RoomId, UserId}; +use matrix_sdk_common::{ + api::r0::keys::{AlgorithmAndDeviceId, DeviceKeys, KeyAlgorithm, SignedKey}, + events::Algorithm, +}; /// Account holding identity keys for which sessions can be created. /// @@ -61,6 +66,11 @@ impl fmt::Debug for Account { } impl Account { + const ALGORITHMS: &'static [&'static Algorithm] = &[ + &Algorithm::OlmV1Curve25519AesSha2, + &Algorithm::MegolmV1AesSha2, + ]; + /// Create a fresh new account, this will generate the identity key-pair. pub fn new(user_id: &UserId, device_id: &DeviceId) -> Self { let account = OlmAccount::new(); @@ -162,6 +172,64 @@ impl Account { }) } + /// Sign the device keys of the account and return them so they can be + /// uploaded. + pub async fn device_keys(&self) -> DeviceKeys { + let identity_keys = self.identity_keys(); + + let mut keys = BTreeMap::new(); + + keys.insert( + AlgorithmAndDeviceId(KeyAlgorithm::Curve25519, (*self.device_id).clone()), + identity_keys.curve25519().to_owned(), + ); + keys.insert( + AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, (*self.device_id).clone()), + identity_keys.ed25519().to_owned(), + ); + + let device_keys = json!({ + "user_id": (*self.user_id).clone(), + "device_id": (*self.device_id).clone(), + "algorithms": Account::ALGORITHMS, + "keys": keys, + }); + + let mut signatures = BTreeMap::new(); + + let mut signature = BTreeMap::new(); + signature.insert( + AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, (*self.device_id).clone()), + self.sign_json(&device_keys).await, + ); + signatures.insert((*self.user_id).clone(), signature); + + DeviceKeys { + user_id: (*self.user_id).clone(), + device_id: (*self.device_id).clone(), + algorithms: vec![ + Algorithm::OlmV1Curve25519AesSha2, + Algorithm::MegolmV1AesSha2, + ], + keys, + signatures, + unsigned: None, + } + } + + /// Convert a JSON value to the canonical representation and sign the JSON + /// string. + /// + /// # Arguments + /// + /// * `json` - The value that should be converted into a canonical JSON + /// string. + pub async fn sign_json(&self, json: &Value) -> String { + let canonical_json = cjson::to_string(json) + .unwrap_or_else(|_| panic!(format!("Can't serialize {} to canonical JSON", json))); + self.sign(&canonical_json).await + } + /// Create a new session with another account given a one-time key. /// /// Returns the newly created session or a `OlmSessionError` if creating a