crypto: Allow only a identity to be verified when the verification finishes

QR code based verification doesn't verify a device when users are
verifying each other, generalize the logic that marks stuff as verified
so we can verify either only a device or an user identity or both.
master
Damir Jelić 2021-06-08 16:31:04 +02:00
parent ada71586ac
commit 7f364fd615
1 changed files with 66 additions and 59 deletions

View File

@ -43,7 +43,7 @@ use tracing::{error, info, trace, warn};
use crate::{ use crate::{
error::SignatureError, error::SignatureError,
olm::PrivateCrossSigningIdentity, olm::PrivateCrossSigningIdentity,
store::{Changes, CryptoStore, DeviceChanges}, store::{Changes, CryptoStore},
CryptoStoreError, LocalTrust, ReadOnlyDevice, UserIdentities, CryptoStoreError, LocalTrust, ReadOnlyDevice, UserIdentities,
}; };
@ -257,9 +257,18 @@ impl IdentitiesBeingVerified {
verified_devices: Option<&[ReadOnlyDevice]>, verified_devices: Option<&[ReadOnlyDevice]>,
verified_identities: Option<&[UserIdentities]>, verified_identities: Option<&[UserIdentities]>,
) -> Result<VerificationResult, CryptoStoreError> { ) -> Result<VerificationResult, CryptoStoreError> {
if let Some(device) = self.mark_device_as_verified(verified_devices).await? { let device = self.mark_device_as_verified(verified_devices).await?;
let identity = self.mark_identity_as_verified(verified_identities).await?; let identity = self.mark_identity_as_verified(verified_identities).await?;
if device.is_none() && identity.is_none() {
// Something wen't wrong if nothing was verified, we use key
// mismatch here, since it's the closest to nothing was verified
return Ok(VerificationResult::Cancel(CancelCode::KeyMismatch));
}
let mut changes = Changes::default();
let signature_request = if let Some(device) = device {
// We only sign devices of our own user here. // We only sign devices of our own user here.
let signature_request = if device.user_id() == self.user_id() { let signature_request = if device.user_id() == self.user_id() {
match self.private_identity.sign_device(&device).await { match self.private_identity.sign_device(&device).await {
@ -288,69 +297,67 @@ impl IdentitiesBeingVerified {
None None
}; };
let mut changes = Changes { changes.devices.changed.push(device);
devices: DeviceChanges { changed: vec![device], ..Default::default() }, signature_request
..Default::default() } else {
}; None
};
let identity_signature_request = if let Some(i) = identity { let identity_signature_request = if let Some(i) = identity {
// We only sign other users here. // We only sign other users here.
let request = if let Some(i) = i.other() { let request = if let Some(i) = i.other() {
// Signing can fail if the user signing key is missing. // Signing can fail if the user signing key is missing.
match self.private_identity.sign_user(i).await { match self.private_identity.sign_user(i).await {
Ok(r) => Some(r), Ok(r) => Some(r),
Err(SignatureError::MissingSigningKey) => { Err(SignatureError::MissingSigningKey) => {
warn!( warn!(
"Can't sign the public cross signing keys for {}, \ "Can't sign the public cross signing keys for {}, \
no private user signing key found", no private user signing key found",
i.user_id() i.user_id()
); );
None None
}
Err(e) => {
error!(
"Error signing the public cross signing keys for {} {:?}",
i.user_id(),
e
);
None
}
} }
} else { Err(e) => {
None error!(
}; "Error signing the public cross signing keys for {} {:?}",
i.user_id(),
changes.identities.changed.push(i); e
);
request None
}
}
} else { } else {
None None
}; };
// If there are two signature upload requests, merge them. Otherwise changes.identities.changed.push(i);
// use the one we have or None. request
//
// Realistically at most one request will be used but let's make
// this future proof.
let merged_request = if let Some(mut r) = signature_request {
if let Some(user_request) = identity_signature_request {
r.signed_keys.extend(user_request.signed_keys);
Some(r)
} else {
Some(r)
}
} else {
identity_signature_request
};
// TODO store the signature upload request as well.
self.store.save_changes(changes).await?;
Ok(merged_request
.map(VerificationResult::SignatureUpload)
.unwrap_or(VerificationResult::Ok))
} else { } else {
Ok(VerificationResult::Cancel(CancelCode::UserMismatch)) None
} };
// If there are two signature upload requests, merge them. Otherwise
// use the one we have or None.
//
// Realistically at most one request will be used but let's make
// this future proof.
let merged_request = if let Some(mut r) = signature_request {
if let Some(user_request) = identity_signature_request {
r.signed_keys.extend(user_request.signed_keys);
Some(r)
} else {
Some(r)
}
} else {
identity_signature_request
};
// TODO store the signature upload request as well.
self.store.save_changes(changes).await?;
Ok(merged_request
.map(VerificationResult::SignatureUpload)
.unwrap_or(VerificationResult::Ok))
} }
async fn mark_identity_as_verified( async fn mark_identity_as_verified(