crypto: Refactor out the json verification method.

master
Damir Jelić 2020-07-14 12:23:42 +02:00
parent b602d3007d
commit 68125f5de6
3 changed files with 58 additions and 80 deletions

View File

@ -18,7 +18,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use atomic::Atomic; use atomic::Atomic;
use olm_rs::utility::OlmUtility;
use serde_json::{json, Value}; use serde_json::{json, Value};
#[cfg(test)] #[cfg(test)]
@ -28,6 +27,7 @@ use matrix_sdk_common::events::Algorithm;
use matrix_sdk_common::identifiers::{DeviceId, UserId}; use matrix_sdk_common::identifiers::{DeviceId, UserId};
use crate::error::SignatureError; use crate::error::SignatureError;
use crate::verify_json;
/// A device represents a E2EE capable client of an user. /// A device represents a E2EE capable client of an user.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -152,44 +152,7 @@ impl Device {
.get_key(KeyAlgorithm::Ed25519) .get_key(KeyAlgorithm::Ed25519)
.ok_or(SignatureError::MissingSigningKey)?; .ok_or(SignatureError::MissingSigningKey)?;
let json_object = json.as_object_mut().ok_or(SignatureError::NotAnObject)?; verify_json(&self.user_id, &self.device_id, signing_key, json)
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
} }
pub(crate) fn verify_device_keys( pub(crate) fn verify_device_keys(

View File

@ -41,3 +41,55 @@ pub use olm::{Account, InboundGroupSession, OutboundGroupSession, Session};
#[cfg(feature = "sqlite-cryptostore")] #[cfg(feature = "sqlite-cryptostore")]
pub use store::sqlite::SqliteStore; pub use store::sqlite::SqliteStore;
pub use store::{CryptoStore, CryptoStoreError}; 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
}

View File

@ -22,13 +22,14 @@ use std::result::Result as StdResult;
use super::error::{EventError, MegolmError, MegolmResult, OlmError, OlmResult, SignatureError}; use super::error::{EventError, MegolmError, MegolmResult, OlmError, OlmResult, SignatureError};
use super::olm::{ use super::olm::{
Account, GroupSessionKey, IdentityKeys, InboundGroupSession, OlmMessage, OlmUtility, Account, GroupSessionKey, IdentityKeys, InboundGroupSession, OlmMessage, OutboundGroupSession,
OutboundGroupSession, Session, Session,
}; };
use super::store::memorystore::MemoryStore; use super::store::memorystore::MemoryStore;
#[cfg(feature = "sqlite-cryptostore")] #[cfg(feature = "sqlite-cryptostore")]
use super::store::sqlite::SqliteStore; use super::store::sqlite::SqliteStore;
use super::{device::Device, store::Result as StoreError, CryptoStore}; use super::{device::Device, store::Result as StoreError, CryptoStore};
use crate::verify_json;
use matrix_sdk_common::api; use matrix_sdk_common::api;
use matrix_sdk_common::events::{ use matrix_sdk_common::events::{
@ -511,45 +512,7 @@ impl OlmMachine {
user_key: &str, user_key: &str,
json: &mut Value, json: &mut Value,
) -> Result<(), SignatureError> { ) -> Result<(), SignatureError> {
let json_object = json.as_object_mut().ok_or(SignatureError::NotAnObject)?; verify_json(user_id, device_id, user_key, json)
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
} }
/// Get a tuple of device and one-time keys that need to be uploaded. /// Get a tuple of device and one-time keys that need to be uploaded.