crypto: Ignore key verification requests that have an invalid timestamp
parent
c4b1d3bc44
commit
533a5b92b0
|
@ -35,6 +35,7 @@ use ruma::{
|
||||||
},
|
},
|
||||||
identifiers::{DeviceId, RoomId, UserId},
|
identifiers::{DeviceId, RoomId, UserId},
|
||||||
serde::CanonicalJsonValue,
|
serde::CanonicalJsonValue,
|
||||||
|
MilliSecondsSinceUnixEpoch,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::FlowId;
|
use super::FlowId;
|
||||||
|
@ -53,6 +54,16 @@ impl AnyEvent<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn timestamp(&self) -> Option<&MilliSecondsSinceUnixEpoch> {
|
||||||
|
match self {
|
||||||
|
AnyEvent::Room(e) => Some(e.origin_server_ts()),
|
||||||
|
AnyEvent::ToDevice(e) => match e {
|
||||||
|
AnyToDeviceEvent::KeyVerificationRequest(e) => Some(&e.content.timestamp),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn verification_content(&self) -> Option<AnyVerificationContent> {
|
pub fn verification_content(&self) -> Option<AnyVerificationContent> {
|
||||||
match self {
|
match self {
|
||||||
AnyEvent::Room(e) => match e {
|
AnyEvent::Room(e) => match e {
|
||||||
|
|
|
@ -16,8 +16,8 @@ use std::{convert::TryFrom, sync::Arc};
|
||||||
|
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use matrix_sdk_common::{locks::Mutex, uuid::Uuid};
|
use matrix_sdk_common::{locks::Mutex, uuid::Uuid};
|
||||||
use ruma::{DeviceId, UserId};
|
use ruma::{uint, DeviceId, MilliSecondsSinceUnixEpoch, UInt, UserId};
|
||||||
use tracing::{info, warn};
|
use tracing::{info, trace, warn};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
cache::VerificationCache,
|
cache::VerificationCache,
|
||||||
|
@ -98,6 +98,30 @@ impl VerificationMachine {
|
||||||
self.verifications.get_sas(transaction_id)
|
self.verifications.get_sas(transaction_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
fn is_timestamp_valid(timestamp: &MilliSecondsSinceUnixEpoch) -> bool {
|
||||||
|
// The event should be ignored if the event is older than 10 minutes
|
||||||
|
let old_timestamp_threshold: UInt = uint!(600);
|
||||||
|
// The event should be ignored if the event is 5 minutes or more into the
|
||||||
|
// future.
|
||||||
|
let timestamp_threshold: UInt = uint!(300);
|
||||||
|
|
||||||
|
let timestamp = timestamp.as_secs();
|
||||||
|
let now = MilliSecondsSinceUnixEpoch::now().as_secs();
|
||||||
|
|
||||||
|
!(now.saturating_sub(timestamp) > old_timestamp_threshold
|
||||||
|
|| timestamp.saturating_sub(now) > timestamp_threshold)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
fn is_timestamp_valid(timestamp: &MilliSecondsSinceUnixEpoch) -> bool {
|
||||||
|
// TODO the non-wasm method with the same name uses
|
||||||
|
// `MilliSecondsSinceUnixEpoch::now()` which internally uses
|
||||||
|
// `SystemTime::now()` this panics under WASM, thus we're returning here
|
||||||
|
// true for now.
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn queue_up_content(
|
fn queue_up_content(
|
||||||
&self,
|
&self,
|
||||||
recipient: &UserId,
|
recipient: &UserId,
|
||||||
|
@ -184,17 +208,34 @@ impl VerificationMachine {
|
||||||
"Received a new verification request",
|
"Received a new verification request",
|
||||||
);
|
);
|
||||||
|
|
||||||
let request = VerificationRequest::from_request(
|
if let Some(timestamp) = event.timestamp() {
|
||||||
self.verifications.clone(),
|
if Self::is_timestamp_valid(timestamp) {
|
||||||
self.account.clone(),
|
let request = VerificationRequest::from_request(
|
||||||
self.private_identity.lock().await.clone(),
|
self.verifications.clone(),
|
||||||
self.store.clone(),
|
self.account.clone(),
|
||||||
event.sender(),
|
self.private_identity.lock().await.clone(),
|
||||||
flow_id,
|
self.store.clone(),
|
||||||
r,
|
event.sender(),
|
||||||
);
|
flow_id,
|
||||||
|
r,
|
||||||
|
);
|
||||||
|
|
||||||
self.requests.insert(request.flow_id().as_str().to_owned(), request);
|
self.requests.insert(request.flow_id().as_str().to_owned(), request);
|
||||||
|
} else {
|
||||||
|
trace!(
|
||||||
|
sender = event.sender().as_str(),
|
||||||
|
from_device = r.from_device().as_str(),
|
||||||
|
timestamp =? timestamp,
|
||||||
|
"The received verification request was too old or too far into the future",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
sender = event.sender().as_str(),
|
||||||
|
from_device = r.from_device().as_str(),
|
||||||
|
"The key verification request didn't contain a valid timestamp"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AnyVerificationContent::Cancel(c) => {
|
AnyVerificationContent::Cancel(c) => {
|
||||||
if let Some(verification) = self.get_request(flow_id.as_str()) {
|
if let Some(verification) = self.get_request(flow_id.as_str()) {
|
||||||
|
|
Loading…
Reference in New Issue