diff --git a/matrix_sdk_crypto/src/device.rs b/matrix_sdk_crypto/src/device.rs index 12036565..afead375 100644 --- a/matrix_sdk_crypto/src/device.rs +++ b/matrix_sdk_crypto/src/device.rs @@ -18,7 +18,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use atomic::Atomic; -use olm_rs::utility::OlmUtility; use serde_json::{json, Value}; #[cfg(test)] @@ -28,6 +27,7 @@ use matrix_sdk_common::events::Algorithm; use matrix_sdk_common::identifiers::{DeviceId, UserId}; use crate::error::SignatureError; +use crate::verify_json; /// A device represents a E2EE capable client of an user. #[derive(Debug, Clone)] @@ -152,44 +152,7 @@ impl Device { .get_key(KeyAlgorithm::Ed25519) .ok_or(SignatureError::MissingSigningKey)?; - let json_object = json.as_object_mut().ok_or(SignatureError::NotAnObject)?; - let unsigned = json_object.remove("unsigned"); - let signatures = json_object.remove("signatures"); - - let canonical_json = cjson::to_string(json_object)?; - - if let Some(u) = unsigned { - json_object.insert("unsigned".to_string(), u); - } - - let key_id = AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, self.device_id.to_string()); - - let signatures = signatures.ok_or(SignatureError::NoSignatureFound)?; - let signature_object = signatures - .as_object() - .ok_or(SignatureError::NoSignatureFound)?; - let signature = signature_object - .get(&self.user_id.to_string()) - .ok_or(SignatureError::NoSignatureFound)?; - let signature = signature - .get(key_id.to_string()) - .ok_or(SignatureError::NoSignatureFound)?; - let signature = signature.as_str().ok_or(SignatureError::NoSignatureFound)?; - - let utility = OlmUtility::new(); - - let ret = if utility - .ed25519_verify(signing_key, &canonical_json, signature) - .is_ok() - { - Ok(()) - } else { - Err(SignatureError::VerificationError) - }; - - json_object.insert("signatures".to_string(), signatures); - - ret + verify_json(&self.user_id, &self.device_id, signing_key, json) } pub(crate) fn verify_device_keys( diff --git a/matrix_sdk_crypto/src/lib.rs b/matrix_sdk_crypto/src/lib.rs index 3e65406a..bfecfe5a 100644 --- a/matrix_sdk_crypto/src/lib.rs +++ b/matrix_sdk_crypto/src/lib.rs @@ -41,3 +41,55 @@ pub use olm::{Account, InboundGroupSession, OutboundGroupSession, Session}; #[cfg(feature = "sqlite-cryptostore")] pub use store::sqlite::SqliteStore; pub use store::{CryptoStore, CryptoStoreError}; + +use error::SignatureError; +use matrix_sdk_common::api::r0::keys::{AlgorithmAndDeviceId, KeyAlgorithm}; +use matrix_sdk_common::identifiers::UserId; +use olm_rs::utility::OlmUtility; +use serde_json::Value; + +pub(crate) fn verify_json( + user_id: &UserId, + key_id: &str, + signing_key: &str, + json: &mut Value, +) -> Result<(), SignatureError> { + let json_object = json.as_object_mut().ok_or(SignatureError::NotAnObject)?; + let unsigned = json_object.remove("unsigned"); + let signatures = json_object.remove("signatures"); + + let canonical_json = cjson::to_string(json_object)?; + + if let Some(u) = unsigned { + json_object.insert("unsigned".to_string(), u); + } + + let key_id = AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, key_id.to_string()); + + let signatures = signatures.ok_or(SignatureError::NoSignatureFound)?; + let signature_object = signatures + .as_object() + .ok_or(SignatureError::NoSignatureFound)?; + let signature = signature_object + .get(user_id.as_str()) + .ok_or(SignatureError::NoSignatureFound)?; + let signature = signature + .get(key_id.to_string()) + .ok_or(SignatureError::NoSignatureFound)?; + let signature = signature.as_str().ok_or(SignatureError::NoSignatureFound)?; + + let utility = OlmUtility::new(); + + let ret = if utility + .ed25519_verify(signing_key, &canonical_json, signature) + .is_ok() + { + Ok(()) + } else { + Err(SignatureError::VerificationError) + }; + + json_object.insert("signatures".to_string(), signatures); + + ret +} diff --git a/matrix_sdk_crypto/src/machine.rs b/matrix_sdk_crypto/src/machine.rs index 172d047e..6cc85a95 100644 --- a/matrix_sdk_crypto/src/machine.rs +++ b/matrix_sdk_crypto/src/machine.rs @@ -22,13 +22,14 @@ use std::result::Result as StdResult; use super::error::{EventError, MegolmError, MegolmResult, OlmError, OlmResult, SignatureError}; use super::olm::{ - Account, GroupSessionKey, IdentityKeys, InboundGroupSession, OlmMessage, OlmUtility, - OutboundGroupSession, Session, + Account, GroupSessionKey, IdentityKeys, InboundGroupSession, OlmMessage, OutboundGroupSession, + Session, }; use super::store::memorystore::MemoryStore; #[cfg(feature = "sqlite-cryptostore")] use super::store::sqlite::SqliteStore; use super::{device::Device, store::Result as StoreError, CryptoStore}; +use crate::verify_json; use matrix_sdk_common::api; use matrix_sdk_common::events::{ @@ -511,45 +512,7 @@ impl OlmMachine { user_key: &str, json: &mut Value, ) -> Result<(), SignatureError> { - let json_object = json.as_object_mut().ok_or(SignatureError::NotAnObject)?; - let unsigned = json_object.remove("unsigned"); - let signatures = json_object.remove("signatures"); - - let canonical_json = cjson::to_string(json_object)?; - - if let Some(u) = unsigned { - json_object.insert("unsigned".to_string(), u); - } - - // TODO this should be part of ruma-client-api. - let key_id_string = format!("{}:{}", KeyAlgorithm::Ed25519, device_id); - - let signatures = signatures.ok_or(SignatureError::NoSignatureFound)?; - let signature_object = signatures - .as_object() - .ok_or(SignatureError::NoSignatureFound)?; - let signature = signature_object - .get(&user_id.to_string()) - .ok_or(SignatureError::NoSignatureFound)?; - let signature = signature - .get(key_id_string) - .ok_or(SignatureError::NoSignatureFound)?; - let signature = signature.as_str().ok_or(SignatureError::NoSignatureFound)?; - - let utility = OlmUtility::new(); - - let ret = if utility - .ed25519_verify(&user_key, &canonical_json, signature) - .is_ok() - { - Ok(()) - } else { - Err(SignatureError::VerificationError) - }; - - json_object.insert("signatures".to_string(), signatures); - - ret + verify_json(user_id, device_id, user_key, json) } /// Get a tuple of device and one-time keys that need to be uploaded.