crypto: Add settings to customize SAS accepting

Offer specifying settings to SAS accept() requests to limit the allowed
verification methods.
master
Jan Veen 2021-03-11 21:10:26 +01:00
parent e5585b57e8
commit e9be23f853
4 changed files with 97 additions and 18 deletions

View File

@ -12,7 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use matrix_sdk_base::crypto::{OutgoingVerificationRequest, ReadOnlyDevice, Sas as BaseSas};
use matrix_sdk_base::crypto::{
AcceptSettings, OutgoingVerificationRequest, ReadOnlyDevice, Sas as BaseSas,
};
use crate::{error::Result, Client};
@ -26,7 +28,14 @@ pub struct Sas {
impl Sas {
/// Accept the interactive verification flow.
pub async fn accept(&self) -> Result<()> {
if let Some(req) = self.inner.accept() {
self.accept_with_settings(Default::default()).await
}
/// Accept the interactive verification flow with specific settings.
///
/// Pass `settings` to customizes the accept-request before sending it.
pub async fn accept_with_settings(&self, settings: AcceptSettings) -> Result<()> {
if let Some(req) = self.inner.accept_with_settings(settings) {
match req {
OutgoingVerificationRequest::ToDevice(r) => {
self.client.send_to_device(&r).await?;

View File

@ -55,4 +55,4 @@ pub use requests::{
OutgoingVerificationRequest, RoomMessageRequest, ToDeviceRequest,
};
pub use store::CryptoStoreError;
pub use verification::{Sas, VerificationRequest};
pub use verification::{AcceptSettings, Sas, VerificationRequest};

View File

@ -18,7 +18,7 @@ mod sas;
pub use machine::VerificationMachine;
pub use requests::VerificationRequest;
pub use sas::{Sas, VerificationResult};
pub use sas::{AcceptSettings, Sas, VerificationResult};
#[cfg(test)]
pub(crate) mod test {

View File

@ -27,8 +27,12 @@ use tracing::{error, info, trace, warn};
use matrix_sdk_common::{
api::r0::keys::upload_signatures::Request as SignatureUploadRequest,
events::{
key::verification::cancel::CancelCode, AnyMessageEvent, AnyMessageEventContent,
AnyToDeviceEvent, AnyToDeviceEventContent,
key::verification::{
accept::{AcceptEventContent, AcceptMethod, AcceptToDeviceEventContent},
cancel::CancelCode,
ShortAuthenticationString,
},
AnyMessageEvent, AnyMessageEventContent, AnyToDeviceEvent, AnyToDeviceEventContent,
},
identifiers::{DeviceId, EventId, RoomId, UserId},
uuid::Uuid,
@ -253,18 +257,35 @@ 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<OutgoingVerificationRequest> {
self.inner.lock().unwrap().accept().map(|c| match c {
AcceptContent::ToDevice(c) => {
let content = AnyToDeviceEventContent::KeyVerificationAccept(c);
self.content_to_request(content).into()
}
AcceptContent::Room(room_id, content) => RoomMessageRequest {
room_id,
txn_id: Uuid::new_v4(),
content: AnyMessageEventContent::KeyVerificationAccept(content),
}
.into(),
})
self.accept_with_settings(Default::default())
}
/// Accept the SAS verification customizing the accept method.
///
/// This does nothing if the verification was already accepted, otherwise it
/// returns an `AcceptEventContent` that needs to be sent out.
///
/// Specify a function modifying the attributes of the accept request.
pub fn accept_with_settings(
&self,
settings: AcceptSettings,
) -> Option<OutgoingVerificationRequest> {
self.inner
.lock()
.unwrap()
.accept()
.map(|c| match settings.apply(c) {
AcceptContent::ToDevice(c) => {
let content = AnyToDeviceEventContent::KeyVerificationAccept(c);
self.content_to_request(content).into()
}
AcceptContent::Room(room_id, content) => RoomMessageRequest {
room_id,
txn_id: Uuid::new_v4(),
content: AnyMessageEventContent::KeyVerificationAccept(content),
}
.into(),
})
}
/// Confirm the Sas verification.
@ -654,6 +675,55 @@ impl Sas {
}
}
/// Customize the accept-reply for a verification process
#[derive(Debug)]
pub struct AcceptSettings {
allowed_methods: Vec<ShortAuthenticationString>,
}
impl Default for AcceptSettings {
fn default() -> Self {
Self {
allowed_methods: vec![
ShortAuthenticationString::Decimal,
ShortAuthenticationString::Emoji,
],
}
}
}
impl AcceptSettings {
/// Create settings with exactly the specified SAS methods
pub fn with_allowed_methods(methods: Vec<ShortAuthenticationString>) -> Self {
Self {
allowed_methods: methods,
}
}
fn apply(self, mut content: AcceptContent) -> AcceptContent {
match &mut content {
AcceptContent::ToDevice(AcceptToDeviceEventContent {
method: AcceptMethod::MSasV1(c),
..
}) => {
c.short_authentication_string = self.allowed_methods;
content
}
AcceptContent::Room(
_,
AcceptEventContent {
method: AcceptMethod::MSasV1(c),
..
},
) => {
c.short_authentication_string = self.allowed_methods;
content
}
_ => content,
}
}
}
#[cfg(test)]
mod test {
use std::{convert::TryFrom, sync::Arc};