crypto: Return requests when you want to accept a verification.

This commit is contained in:
Damir Jelić 2020-07-29 12:47:36 +02:00
parent 27f918e52d
commit 117ebeaf4b
4 changed files with 109 additions and 64 deletions

View file

@ -51,7 +51,7 @@ pub use models::Room;
pub use state::{AllRooms, ClientState};
#[cfg(feature = "encryption")]
pub use matrix_sdk_crypto::{Device, TrustState};
pub use matrix_sdk_crypto::{Device, Sas, TrustState};
#[cfg(feature = "messages")]
#[cfg_attr(docsrs, doc(cfg(feature = "messages")))]

View file

@ -12,23 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::BTreeMap;
use std::sync::Arc;
use dashmap::DashMap;
use matrix_sdk_common::{
api::r0::to_device::{send_event_to_device::Request as ToDeviceRequest, DeviceIdOrAllDevices},
api::r0::to_device::send_event_to_device::Request as ToDeviceRequest,
events::{
key::verification::start::StartEventContent, AnyToDeviceEvent, AnyToDeviceEventContent,
EventType,
},
identifiers::{DeviceId, UserId},
locks::RwLock,
uuid::Uuid,
};
use super::Sas;
use super::{content_to_request, Sas};
use crate::{Account, CryptoStore, CryptoStoreError};
#[derive(Clone, Debug)]
@ -53,35 +50,13 @@ impl VerificationMachine {
self.verifications.get(transaction_id).map(|s| s.clone())
}
fn content_to_request(
&self,
recipient: &UserId,
recipient_device: &DeviceId,
content: AnyToDeviceEventContent,
) -> ToDeviceRequest {
let mut messages = BTreeMap::new();
let mut user_messages = BTreeMap::new();
user_messages.insert(
DeviceIdOrAllDevices::DeviceId(recipient_device.into()),
serde_json::value::to_raw_value(&content).expect("Can't serialize to-device content"),
);
messages.insert(recipient.clone(), user_messages);
ToDeviceRequest {
txn_id: Uuid::new_v4().to_string(),
event_type: EventType::KeyVerificationAccept,
messages,
}
}
fn queue_up_content(
&self,
recipient: &UserId,
recipient_device: &DeviceId,
content: AnyToDeviceEventContent,
) {
let request = self.content_to_request(recipient, recipient_device, content);
let request = content_to_request(recipient, recipient_device, content);
self.outgoing_to_device_messages
.insert(request.txn_id.clone(), request);
@ -165,7 +140,7 @@ mod test {
};
use super::{Sas, VerificationMachine};
use crate::verification::test::wrap_any_to_device_content;
use crate::verification::test::{get_content_from_request, wrap_any_to_device_content};
use crate::{store::memorystore::MemoryStore, Account, CryptoStore, Device};
fn alice_id() -> UserId {
@ -222,12 +197,7 @@ mod test {
let mut event = alice
.accept()
.map(|c| {
wrap_any_to_device_content(
alice.user_id(),
AnyToDeviceEventContent::KeyVerificationAccept(c),
)
})
.map(|c| wrap_any_to_device_content(alice.user_id(), get_content_from_request(&c)))
.unwrap();
let mut event = bob
@ -247,23 +217,8 @@ mod test {
let txn_id = request.txn_id.clone();
let mut event = wrap_any_to_device_content(
alice.user_id(),
AnyToDeviceEventContent::KeyVerificationKey(
serde_json::from_str(
request
.messages
.values()
.next()
.unwrap()
.values()
.next()
.unwrap()
.get(),
)
.unwrap(),
),
);
let mut event =
wrap_any_to_device_content(alice.user_id(), get_content_from_request(&request));
drop(request);
alice_machine.mark_requests_as_sent(&txn_id);

View file

@ -17,9 +17,17 @@ use std::convert::TryInto;
use olm_rs::sas::OlmSas;
use matrix_sdk_common::api::r0::keys::{AlgorithmAndDeviceId, KeyAlgorithm};
use matrix_sdk_common::events::{key::verification::mac::MacEventContent, ToDeviceEvent};
use matrix_sdk_common::identifiers::DeviceId;
use matrix_sdk_common::{
api::r0::{
keys::{AlgorithmAndDeviceId, KeyAlgorithm},
to_device::{send_event_to_device::Request as ToDeviceRequest, DeviceIdOrAllDevices},
},
events::{
key::verification::mac::MacEventContent, AnyToDeviceEventContent, EventType, ToDeviceEvent,
},
identifiers::{DeviceId, UserId},
uuid::Uuid,
};
use crate::{Account, Device};
@ -400,10 +408,45 @@ fn get_decimal(sas: &OlmSas, ids: &SasIds, flow_id: &str, we_started: bool) -> (
(first + 1000, second + 1000, third + 1000)
}
pub(crate) fn content_to_request(
recipient: &UserId,
recipient_device: &DeviceId,
content: AnyToDeviceEventContent,
) -> ToDeviceRequest {
let mut messages = BTreeMap::new();
let mut user_messages = BTreeMap::new();
user_messages.insert(
DeviceIdOrAllDevices::DeviceId(recipient_device.into()),
serde_json::value::to_raw_value(&content).expect("Can't serialize to-device content"),
);
messages.insert(recipient.clone(), user_messages);
let event_type = match content {
AnyToDeviceEventContent::KeyVerificationAccept(_) => EventType::KeyVerificationAccept,
AnyToDeviceEventContent::KeyVerificationStart(_) => EventType::KeyVerificationStart,
AnyToDeviceEventContent::KeyVerificationKey(_) => EventType::KeyVerificationKey,
AnyToDeviceEventContent::KeyVerificationMac(_) => EventType::KeyVerificationMac,
AnyToDeviceEventContent::KeyVerificationCancel(_) => EventType::KeyVerificationCancel,
_ => unreachable!(),
};
ToDeviceRequest {
txn_id: Uuid::new_v4().to_string(),
event_type,
messages,
}
}
#[cfg(test)]
mod test {
use matrix_sdk_common::events::{AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent};
use matrix_sdk_common::identifiers::UserId;
use serde_json::Value;
use matrix_sdk_common::{
api::r0::to_device::send_event_to_device::Request as ToDeviceRequest,
events::{AnyToDeviceEvent, AnyToDeviceEventContent, EventType, ToDeviceEvent},
identifiers::UserId,
};
pub(crate) fn wrap_any_to_device_content(
sender: &UserId,
@ -438,4 +481,38 @@ mod test {
_ => unreachable!(),
}
}
pub(crate) fn get_content_from_request(request: &ToDeviceRequest) -> AnyToDeviceEventContent {
let json: Value = serde_json::from_str(
request
.messages
.values()
.next()
.unwrap()
.values()
.next()
.unwrap()
.get(),
)
.unwrap();
match request.event_type {
EventType::KeyVerificationStart => {
AnyToDeviceEventContent::KeyVerificationStart(serde_json::from_value(json).unwrap())
}
EventType::KeyVerificationKey => {
AnyToDeviceEventContent::KeyVerificationKey(serde_json::from_value(json).unwrap())
}
EventType::KeyVerificationAccept => AnyToDeviceEventContent::KeyVerificationAccept(
serde_json::from_value(json).unwrap(),
),
EventType::KeyVerificationMac => {
AnyToDeviceEventContent::KeyVerificationMac(serde_json::from_value(json).unwrap())
}
EventType::KeyVerificationCancel => AnyToDeviceEventContent::KeyVerificationCancel(
serde_json::from_value(json).unwrap(),
),
_ => unreachable!(),
}
}
}

View file

@ -20,6 +20,7 @@ use std::{
use olm_rs::{sas::OlmSas, utility::OlmUtility};
use matrix_sdk_common::{
api::r0::to_device::send_event_to_device::Request as ToDeviceRequest,
events::{
key::verification::{
accept::AcceptEventContent,
@ -36,7 +37,9 @@ use matrix_sdk_common::{
uuid::Uuid,
};
use super::{get_decimal, get_emoji, get_mac_content, receive_mac_event, SasIds};
use super::{
content_to_request, get_decimal, get_emoji, get_mac_content, receive_mac_event, SasIds,
};
use crate::{Account, Device};
#[derive(Clone, Debug)]
@ -136,8 +139,11 @@ impl Sas {
///
/// This does nothing if the verification was already accepted, otherwise it
/// returns an `AcceptEventContent` that needs to be sent out.
pub fn accept(&self) -> Option<AcceptEventContent> {
self.inner.lock().unwrap().accept()
pub fn accept(&self) -> Option<ToDeviceRequest> {
self.inner.lock().unwrap().accept().map(|c| {
let content = AnyToDeviceEventContent::KeyVerificationAccept(c);
self.content_to_request(content)
})
}
/// Confirm the Sas verification.
@ -197,6 +203,10 @@ impl Sas {
pub(crate) fn verified_devices(&self) -> Option<Arc<Vec<Box<DeviceId>>>> {
self.inner.lock().unwrap().verified_devices()
}
pub(crate) fn content_to_request(&self, content: AnyToDeviceEventContent) -> ToDeviceRequest {
content_to_request(self.other_user_id(), self.other_device_id(), content)
}
}
#[derive(Clone, Debug)]
@ -1053,7 +1063,7 @@ impl SasState<Canceled> {
mod test {
use std::convert::TryFrom;
use crate::verification::test::wrap_any_to_device_content;
use crate::verification::test::{get_content_from_request, wrap_any_to_device_content};
use crate::{Account, Device};
use matrix_sdk_common::events::{AnyToDeviceEvent, EventContent, ToDeviceEvent};
use matrix_sdk_common::identifiers::{DeviceId, UserId};
@ -1178,9 +1188,12 @@ mod test {
let event = wrap_to_device_event(alice.user_id(), content);
let bob = Sas::from_start_event(bob, alice_device, &event).unwrap();
let event = wrap_to_device_event(bob.user_id(), bob.accept().unwrap());
let mut event = wrap_any_to_device_content(
bob.user_id(),
get_content_from_request(&bob.accept().unwrap()),
);
let content = alice.receive_event(&mut AnyToDeviceEvent::KeyVerificationAccept(event));
let content = alice.receive_event(&mut event);
assert!(!alice.can_be_presented());
assert!(!bob.can_be_presented());