crypto: If our own identity passed a SAS flow, mark it as verified.
parent
3990e50ca6
commit
317a141e07
|
@ -15,7 +15,10 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::{
|
||||||
|
atomic::{AtomicBool, Ordering},
|
||||||
|
Arc,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde_json::to_value;
|
use serde_json::to_value;
|
||||||
|
@ -29,8 +32,10 @@ use crate::{error::SignatureError, verify_json, ReadOnlyDevice};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MasterPubkey(Arc<CrossSigningKey>);
|
pub struct MasterPubkey(Arc<CrossSigningKey>);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SelfSigningPubkey(Arc<CrossSigningKey>);
|
pub struct SelfSigningPubkey(Arc<CrossSigningKey>);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct UserSigningPubkey(Arc<CrossSigningKey>);
|
pub struct UserSigningPubkey(Arc<CrossSigningKey>);
|
||||||
|
|
||||||
|
@ -182,6 +187,12 @@ impl UserIdentities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for UserIdentities {
|
||||||
|
fn eq(&self, other: &UserIdentities) -> bool {
|
||||||
|
self.user_id() == other.user_id()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct UserIdentity {
|
pub struct UserIdentity {
|
||||||
user_id: Arc<UserId>,
|
user_id: Arc<UserId>,
|
||||||
|
@ -287,6 +298,14 @@ impl OwnUserIdentity {
|
||||||
self.user_signing_key
|
self.user_signing_key
|
||||||
.verify_master_key(&identity.master_key)
|
.verify_master_key(&identity.master_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mark_as_verified(&self) {
|
||||||
|
self.verified.store(true, Ordering::SeqCst)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_verified(&self) -> bool {
|
||||||
|
self.verified.load(Ordering::SeqCst)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -189,8 +189,15 @@ impl Sas {
|
||||||
(content, guard.is_done())
|
(content, guard.is_done())
|
||||||
};
|
};
|
||||||
|
|
||||||
if done && !self.mark_device_as_verified().await? {
|
if done {
|
||||||
return Ok(self.cancel());
|
// TODO move the logic that marks and stores the device into the
|
||||||
|
// else branch and only after the identity was verified as well. We
|
||||||
|
// dont' want to verify one without the other.
|
||||||
|
if !self.mark_device_as_verified().await? {
|
||||||
|
return Ok(self.cancel());
|
||||||
|
} else {
|
||||||
|
self.mark_identity_as_verified().await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(content.map(|c| {
|
Ok(content.map(|c| {
|
||||||
|
@ -199,6 +206,61 @@ impl Sas {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn mark_identity_as_verified(&self) -> Result<bool, CryptoStoreError> {
|
||||||
|
// If there wasn't an identity available during the verification flow
|
||||||
|
// return early as there's nothing to do.
|
||||||
|
if self.other_identity.is_none() {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
let identity = self.store.get_user_identity(self.other_user_id()).await?;
|
||||||
|
|
||||||
|
if let Some(identity) = identity {
|
||||||
|
if identity.master_key() == self.other_identity.as_ref().unwrap().master_key() {
|
||||||
|
if self
|
||||||
|
.verified_identities()
|
||||||
|
.map_or(false, |i| i.contains(&identity))
|
||||||
|
{
|
||||||
|
trace!(
|
||||||
|
"Marking user identity of {} as verified.",
|
||||||
|
identity.user_id(),
|
||||||
|
);
|
||||||
|
|
||||||
|
match &identity {
|
||||||
|
UserIdentities::Own(i) => {
|
||||||
|
i.mark_as_verified();
|
||||||
|
self.store.save_user_identities(&[identity]).await?;
|
||||||
|
}
|
||||||
|
// TODO if we have the private part of the user signing
|
||||||
|
// key we should sign and upload a signature for this
|
||||||
|
// identity.
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
info!(
|
||||||
|
"The interactive verification process didn't contain a \
|
||||||
|
MAC for the user identity of {} {:?}",
|
||||||
|
identity.user_id(),
|
||||||
|
self.verified_identities(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!(
|
||||||
|
"The identity for {} was deleted while an interactive \
|
||||||
|
verification was going on.",
|
||||||
|
self.other_user_id(),
|
||||||
|
);
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn mark_device_as_verified(&self) -> Result<bool, CryptoStoreError> {
|
pub(crate) async fn mark_device_as_verified(&self) -> Result<bool, CryptoStoreError> {
|
||||||
let device = self
|
let device = self
|
||||||
.store
|
.store
|
||||||
|
@ -335,7 +397,6 @@ impl Sas {
|
||||||
self.inner.lock().unwrap().verified_devices()
|
self.inner.lock().unwrap().verified_devices()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) fn verified_identities(&self) -> Option<Arc<Vec<UserIdentities>>> {
|
pub(crate) fn verified_identities(&self) -> Option<Arc<Vec<UserIdentities>>> {
|
||||||
self.inner.lock().unwrap().verified_identities()
|
self.inner.lock().unwrap().verified_identities()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue