crypto: Add settings to customize SAS accepting
Offer specifying settings to SAS accept() requests to limit the allowed verification methods.
This commit is contained in:
parent
e5585b57e8
commit
e9be23f853
4 changed files with 97 additions and 18 deletions
|
@ -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?;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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};
|
||||
|
|
Loading…
Reference in a new issue