crypto: Verify one-time keys using the device.

master
Damir Jelić 2020-07-14 12:49:40 +02:00
parent 68125f5de6
commit c25f4c0642
3 changed files with 36 additions and 54 deletions

View File

@ -22,7 +22,7 @@ use serde_json::{json, Value};
#[cfg(test)] #[cfg(test)]
use super::OlmMachine; use super::OlmMachine;
use matrix_sdk_common::api::r0::keys::{AlgorithmAndDeviceId, DeviceKeys, KeyAlgorithm}; use matrix_sdk_common::api::r0::keys::{AlgorithmAndDeviceId, DeviceKeys, KeyAlgorithm, SignedKey};
use matrix_sdk_common::events::Algorithm; use matrix_sdk_common::events::Algorithm;
use matrix_sdk_common::identifiers::{DeviceId, UserId}; use matrix_sdk_common::identifiers::{DeviceId, UserId};
@ -162,6 +162,13 @@ impl Device {
self.is_signed_by_device(&mut json!(&device_keys)) self.is_signed_by_device(&mut json!(&device_keys))
} }
pub(crate) fn verify_one_time_key(
&self,
one_time_key: &SignedKey,
) -> Result<(), SignatureError> {
self.is_signed_by_device(&mut json!(&one_time_key))
}
/// Mark the device as deleted. /// Mark the device as deleted.
pub(crate) fn mark_as_deleted(&self) { pub(crate) fn mark_as_deleted(&self) {
self.deleted.store(true, Ordering::Relaxed); self.deleted.store(true, Ordering::Relaxed);

View File

@ -48,6 +48,24 @@ use matrix_sdk_common::identifiers::UserId;
use olm_rs::utility::OlmUtility; use olm_rs::utility::OlmUtility;
use serde_json::Value; use serde_json::Value;
/// Verify a signed JSON object.
///
/// The object must have a signatures key associated with an object of the
/// form `user_id: {key_id: signature}`.
///
/// Returns Ok if the signature was successfully verified, otherwise an
/// SignatureError.
///
/// # Arguments
///
/// * `user_id` - The user who signed the JSON object.
///
/// * `key_id` - The id of the key that signed the JSON object.
///
/// * `signing_key` - The public ed25519 key which was used to sign the JSON
/// object.
///
/// * `json` - The JSON object that should be verified.
pub(crate) fn verify_json( pub(crate) fn verify_json(
user_id: &UserId, user_id: &UserId,
key_id: &str, key_id: &str,

View File

@ -20,7 +20,7 @@ use std::mem;
use std::path::Path; use std::path::Path;
use std::result::Result as StdResult; use std::result::Result as StdResult;
use super::error::{EventError, MegolmError, MegolmResult, OlmError, OlmResult, SignatureError}; use super::error::{EventError, MegolmError, MegolmResult, OlmError, OlmResult};
use super::olm::{ use super::olm::{
Account, GroupSessionKey, IdentityKeys, InboundGroupSession, OlmMessage, OutboundGroupSession, Account, GroupSessionKey, IdentityKeys, InboundGroupSession, OlmMessage, OutboundGroupSession,
Session, Session,
@ -29,7 +29,6 @@ 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::{
@ -343,24 +342,10 @@ impl OlmMachine {
continue; continue;
}; };
let signing_key = if let Some(k) = device.get_key(KeyAlgorithm::Ed25519) { if let Err(e) = device.verify_one_time_key(&one_time_key) {
k
} else {
warn!( warn!(
"Tried to create an Olm session for {} {}, but the "Failed to verify the one-time key signatures for {} {}: {:?}",
device is missing the signing key", user_id, device_id, e
user_id, device_id
);
continue;
};
if self
.verify_json(user_id, device_id, signing_key, &mut json!(&one_time_key))
.is_err()
{
warn!(
"Failed to verify the one-time key signatures for {} {}",
user_id, device_id
); );
continue; continue;
} }
@ -487,34 +472,6 @@ impl OlmMachine {
Ok(changed_devices) Ok(changed_devices)
} }
/// Verify a signed JSON object.
///
/// The object must have a signatures key associated with an object of the
/// form `user_id: {key_id: signature}`.
///
/// Returns Ok if the signature was successfully verified, otherwise an
/// SignatureError.
///
/// # Arguments
///
/// * `user_id` - The user who signed the JSON object.
///
/// * `device_id` - The device that signed the JSON object.
///
/// * `user_key` - The public ed25519 key which was used to sign the JSON
/// object.
///
/// * `json` - The JSON object that should be verified.
fn verify_json(
&self,
user_id: &UserId,
device_id: &str,
user_key: &str,
json: &mut Value,
) -> Result<(), SignatureError> {
verify_json(user_id, device_id, user_key, json)
}
/// 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.
/// ///
/// Returns an empty error if no keys need to be uploaded. /// Returns an empty error if no keys need to be uploaded.
@ -1307,7 +1264,7 @@ mod test {
use serde_json::json; use serde_json::json;
use crate::machine::{OlmMachine, OneTimeKeys}; use crate::machine::{OlmMachine, OneTimeKeys};
use crate::Device; use crate::{verify_json, Device};
use matrix_sdk_common::api::r0::{ use matrix_sdk_common::api::r0::{
keys, to_device::send_event_to_device::Request as ToDeviceRequest, keys, to_device::send_event_to_device::Request as ToDeviceRequest,
@ -1545,7 +1502,7 @@ mod test {
let identity_keys = machine.account.identity_keys(); let identity_keys = machine.account.identity_keys();
let ed25519_key = identity_keys.ed25519(); let ed25519_key = identity_keys.ed25519();
let ret = machine.verify_json( let ret = verify_json(
&machine.user_id, &machine.user_id,
&machine.device_id, &machine.device_id,
ed25519_key, ed25519_key,
@ -1576,7 +1533,7 @@ mod test {
let mut device_keys = machine.account.device_keys().await; let mut device_keys = machine.account.device_keys().await;
let ret = machine.verify_json( let ret = verify_json(
&machine.user_id, &machine.user_id,
&machine.device_id, &machine.device_id,
"fake_key", "fake_key",
@ -1596,7 +1553,7 @@ mod test {
let mut one_time_key = one_time_keys.values_mut().next().unwrap(); let mut one_time_key = one_time_keys.values_mut().next().unwrap();
let ret = machine.verify_json( let ret = verify_json(
&machine.user_id, &machine.user_id,
&machine.device_id, &machine.device_id,
ed25519_key, ed25519_key,
@ -1618,7 +1575,7 @@ mod test {
.await .await
.expect("Can't prepare initial key upload"); .expect("Can't prepare initial key upload");
let ret = machine.verify_json( let ret = verify_json(
&machine.user_id, &machine.user_id,
&machine.device_id, &machine.device_id,
ed25519_key, ed25519_key,
@ -1626,7 +1583,7 @@ mod test {
); );
assert!(ret.is_ok()); assert!(ret.is_ok());
let ret = machine.verify_json( let ret = verify_json(
&machine.user_id, &machine.user_id,
&machine.device_id, &machine.device_id,
ed25519_key, ed25519_key,