crypto: Add methods to request verification from users
parent
db0843a47a
commit
c5df7c5356
|
@ -39,11 +39,11 @@ use tracing::warn;
|
||||||
use super::{atomic_bool_deserializer, atomic_bool_serializer};
|
use super::{atomic_bool_deserializer, atomic_bool_serializer};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{EventError, OlmError, OlmResult, SignatureError},
|
error::{EventError, OlmError, OlmResult, SignatureError},
|
||||||
identities::{OwnUserIdentity, UserIdentities},
|
identities::{ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities},
|
||||||
olm::{InboundGroupSession, PrivateCrossSigningIdentity, Session, Utility},
|
olm::{InboundGroupSession, PrivateCrossSigningIdentity, Session, Utility},
|
||||||
store::{Changes, CryptoStore, DeviceChanges, Result as StoreResult},
|
store::{Changes, CryptoStore, DeviceChanges, Result as StoreResult},
|
||||||
verification::VerificationMachine,
|
verification::VerificationMachine,
|
||||||
OutgoingVerificationRequest, Sas, ToDeviceRequest,
|
OutgoingVerificationRequest, Sas, ToDeviceRequest, VerificationRequest,
|
||||||
};
|
};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::{OlmMachine, ReadOnlyAccount};
|
use crate::{OlmMachine, ReadOnlyAccount};
|
||||||
|
@ -104,8 +104,8 @@ pub struct Device {
|
||||||
pub(crate) inner: ReadOnlyDevice,
|
pub(crate) inner: ReadOnlyDevice,
|
||||||
pub(crate) private_identity: Arc<Mutex<PrivateCrossSigningIdentity>>,
|
pub(crate) private_identity: Arc<Mutex<PrivateCrossSigningIdentity>>,
|
||||||
pub(crate) verification_machine: VerificationMachine,
|
pub(crate) verification_machine: VerificationMachine,
|
||||||
pub(crate) own_identity: Option<OwnUserIdentity>,
|
pub(crate) own_identity: Option<ReadOnlyOwnUserIdentity>,
|
||||||
pub(crate) device_owner_identity: Option<UserIdentities>,
|
pub(crate) device_owner_identity: Option<ReadOnlyUserIdentities>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Device {
|
impl std::fmt::Debug for Device {
|
||||||
|
@ -228,8 +228,8 @@ pub struct UserDevices {
|
||||||
pub(crate) inner: HashMap<DeviceIdBox, ReadOnlyDevice>,
|
pub(crate) inner: HashMap<DeviceIdBox, ReadOnlyDevice>,
|
||||||
pub(crate) private_identity: Arc<Mutex<PrivateCrossSigningIdentity>>,
|
pub(crate) private_identity: Arc<Mutex<PrivateCrossSigningIdentity>>,
|
||||||
pub(crate) verification_machine: VerificationMachine,
|
pub(crate) verification_machine: VerificationMachine,
|
||||||
pub(crate) own_identity: Option<OwnUserIdentity>,
|
pub(crate) own_identity: Option<ReadOnlyOwnUserIdentity>,
|
||||||
pub(crate) device_owner_identity: Option<UserIdentities>,
|
pub(crate) device_owner_identity: Option<ReadOnlyUserIdentities>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserDevices {
|
impl UserDevices {
|
||||||
|
@ -382,16 +382,16 @@ impl ReadOnlyDevice {
|
||||||
|
|
||||||
pub(crate) fn verified(
|
pub(crate) fn verified(
|
||||||
&self,
|
&self,
|
||||||
own_identity: &Option<OwnUserIdentity>,
|
own_identity: &Option<ReadOnlyOwnUserIdentity>,
|
||||||
device_owner: &Option<UserIdentities>,
|
device_owner: &Option<ReadOnlyUserIdentities>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.is_locally_trusted() || self.is_cross_signing_trusted(own_identity, device_owner)
|
self.is_locally_trusted() || self.is_cross_signing_trusted(own_identity, device_owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_cross_signing_trusted(
|
pub(crate) fn is_cross_signing_trusted(
|
||||||
&self,
|
&self,
|
||||||
own_identity: &Option<OwnUserIdentity>,
|
own_identity: &Option<ReadOnlyOwnUserIdentity>,
|
||||||
device_owner: &Option<UserIdentities>,
|
device_owner: &Option<ReadOnlyUserIdentities>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
own_identity.as_ref().map_or(false, |own_identity| {
|
own_identity.as_ref().map_or(false, |own_identity| {
|
||||||
// Our own identity needs to be marked as verified.
|
// Our own identity needs to be marked as verified.
|
||||||
|
@ -401,14 +401,14 @@ impl ReadOnlyDevice {
|
||||||
.map(|device_identity| match device_identity {
|
.map(|device_identity| match device_identity {
|
||||||
// If it's one of our own devices, just check that
|
// If it's one of our own devices, just check that
|
||||||
// we signed the device.
|
// we signed the device.
|
||||||
UserIdentities::Own(_) => {
|
ReadOnlyUserIdentities::Own(_) => {
|
||||||
own_identity.is_device_signed(self).map_or(false, |_| true)
|
own_identity.is_device_signed(self).map_or(false, |_| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's a device from someone else, first check
|
// If it's a device from someone else, first check
|
||||||
// that our user has signed the other user and then
|
// that our user has signed the other user and then
|
||||||
// check if the other user has signed this device.
|
// check if the other user has signed this device.
|
||||||
UserIdentities::Other(device_identity) => {
|
ReadOnlyUserIdentities::Other(device_identity) => {
|
||||||
own_identity.is_identity_signed(device_identity).map_or(false, |_| true)
|
own_identity.is_identity_signed(device_identity).map_or(false, |_| true)
|
||||||
&& device_identity.is_device_signed(self).map_or(false, |_| true)
|
&& device_identity.is_device_signed(self).map_or(false, |_| true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ use tracing::{trace, warn};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::OlmResult,
|
error::OlmResult,
|
||||||
identities::{
|
identities::{
|
||||||
MasterPubkey, OwnUserIdentity, ReadOnlyDevice, SelfSigningPubkey, UserIdentities,
|
MasterPubkey, ReadOnlyDevice, ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities,
|
||||||
UserIdentity, UserSigningPubkey,
|
ReadOnlyUserIdentity, SelfSigningPubkey, UserSigningPubkey,
|
||||||
},
|
},
|
||||||
requests::KeysQueryRequest,
|
requests::KeysQueryRequest,
|
||||||
store::{Changes, DeviceChanges, IdentityChanges, Result as StoreResult, Store},
|
store::{Changes, DeviceChanges, IdentityChanges, Result as StoreResult, Store},
|
||||||
|
@ -246,7 +246,7 @@ impl IdentityManager {
|
||||||
|
|
||||||
let result = if let Some(mut i) = self.store.get_user_identity(user_id).await? {
|
let result = if let Some(mut i) = self.store.get_user_identity(user_id).await? {
|
||||||
match &mut i {
|
match &mut i {
|
||||||
UserIdentities::Own(ref mut identity) => {
|
ReadOnlyUserIdentities::Own(ref mut identity) => {
|
||||||
let user_signing = if let Some(s) = response.user_signing_keys.get(user_id)
|
let user_signing = if let Some(s) = response.user_signing_keys.get(user_id)
|
||||||
{
|
{
|
||||||
UserSigningPubkey::from(s)
|
UserSigningPubkey::from(s)
|
||||||
|
@ -261,7 +261,7 @@ impl IdentityManager {
|
||||||
|
|
||||||
identity.update(master_key, self_signing, user_signing).map(|_| (i, false))
|
identity.update(master_key, self_signing, user_signing).map(|_| (i, false))
|
||||||
}
|
}
|
||||||
UserIdentities::Other(ref mut identity) => {
|
ReadOnlyUserIdentities::Other(ref mut identity) => {
|
||||||
identity.update(master_key, self_signing).map(|_| (i, false))
|
identity.update(master_key, self_signing).map(|_| (i, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,8 +280,8 @@ impl IdentityManager {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnUserIdentity::new(master_key, self_signing, user_signing)
|
ReadOnlyOwnUserIdentity::new(master_key, self_signing, user_signing)
|
||||||
.map(|i| (UserIdentities::Own(i), true))
|
.map(|i| (ReadOnlyUserIdentities::Own(i), true))
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!(
|
||||||
"User identity for our own user {} didn't contain a \
|
"User identity for our own user {} didn't contain a \
|
||||||
|
@ -294,8 +294,8 @@ impl IdentityManager {
|
||||||
warn!("User id mismatch in one of the cross signing keys for user {}", user_id);
|
warn!("User id mismatch in one of the cross signing keys for user {}", user_id);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
UserIdentity::new(master_key, self_signing)
|
ReadOnlyUserIdentity::new(master_key, self_signing)
|
||||||
.map(|i| (UserIdentities::Other(i), true))
|
.map(|i| (ReadOnlyUserIdentities::Other(i), true))
|
||||||
};
|
};
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -53,8 +53,8 @@ pub use device::{Device, LocalTrust, ReadOnlyDevice, UserDevices};
|
||||||
pub(crate) use manager::IdentityManager;
|
pub(crate) use manager::IdentityManager;
|
||||||
use serde::{Deserialize, Deserializer, Serializer};
|
use serde::{Deserialize, Deserializer, Serializer};
|
||||||
pub use user::{
|
pub use user::{
|
||||||
MasterPubkey, OwnUserIdentity, SelfSigningPubkey, UserIdentities, UserIdentity,
|
MasterPubkey, OwnUserIdentity, ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities,
|
||||||
UserSigningPubkey,
|
ReadOnlyUserIdentity, SelfSigningPubkey, UserIdentities, UserIdentity, UserSigningPubkey,
|
||||||
};
|
};
|
||||||
|
|
||||||
// These methods are only here because Serialize and Deserialize don't seem to
|
// These methods are only here because Serialize and Deserialize don't seem to
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::{btree_map::Iter, BTreeMap},
|
collections::{btree_map::Iter, BTreeMap},
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
|
ops::Deref,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
Arc,
|
Arc,
|
||||||
|
@ -23,7 +24,10 @@ use std::{
|
||||||
|
|
||||||
use ruma::{
|
use ruma::{
|
||||||
encryption::{CrossSigningKey, KeyUsage},
|
encryption::{CrossSigningKey, KeyUsage},
|
||||||
DeviceKeyId, UserId,
|
events::{
|
||||||
|
key::verification::VerificationMethod, room::message::KeyVerificationRequestEventContent,
|
||||||
|
},
|
||||||
|
DeviceKeyId, EventId, RoomId, UserId,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::to_value;
|
use serde_json::to_value;
|
||||||
|
@ -31,7 +35,153 @@ use serde_json::to_value;
|
||||||
use super::{atomic_bool_deserializer, atomic_bool_serializer};
|
use super::{atomic_bool_deserializer, atomic_bool_serializer};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::olm::PrivateCrossSigningIdentity;
|
use crate::olm::PrivateCrossSigningIdentity;
|
||||||
use crate::{error::SignatureError, olm::Utility, ReadOnlyDevice};
|
use crate::{
|
||||||
|
error::SignatureError, olm::Utility, verification::VerificationMachine, CryptoStoreError,
|
||||||
|
OutgoingVerificationRequest, ReadOnlyDevice, VerificationRequest,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Enum over the different user identity types we can have.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum UserIdentities {
|
||||||
|
/// Our own user identity.
|
||||||
|
Own(OwnUserIdentity),
|
||||||
|
/// An identity belonging to another user.
|
||||||
|
Other(UserIdentity),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserIdentities {
|
||||||
|
/// Destructure the enum into an `OwnUserIdentity` if it's of the correct
|
||||||
|
/// type.
|
||||||
|
pub fn own(self) -> Option<OwnUserIdentity> {
|
||||||
|
match self {
|
||||||
|
Self::Own(i) => Some(i),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Destructure the enum into an `UserIdentity` if it's of the correct
|
||||||
|
/// type.
|
||||||
|
pub fn other(self) -> Option<UserIdentity> {
|
||||||
|
match self {
|
||||||
|
Self::Other(i) => Some(i),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OwnUserIdentity> for UserIdentities {
|
||||||
|
fn from(i: OwnUserIdentity) -> Self {
|
||||||
|
Self::Own(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<UserIdentity> for UserIdentities {
|
||||||
|
fn from(i: UserIdentity) -> Self {
|
||||||
|
Self::Other(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Struct representing a cross signing identity of a user.
|
||||||
|
///
|
||||||
|
/// This is the user identity of a user that isn't our own. Other users will
|
||||||
|
/// only contain a master key and a self signing key, meaning that only device
|
||||||
|
/// signatures can be checked with this identity.
|
||||||
|
///
|
||||||
|
/// This struct wraps a read-only version of the struct and allows verifications
|
||||||
|
/// to be requested to verify our own device with the user identity.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct OwnUserIdentity {
|
||||||
|
pub(crate) inner: ReadOnlyOwnUserIdentity,
|
||||||
|
pub(crate) verification_machine: VerificationMachine,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for OwnUserIdentity {
|
||||||
|
type Target = ReadOnlyOwnUserIdentity;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OwnUserIdentity {
|
||||||
|
/// Send a verification request to our other devices.
|
||||||
|
pub async fn request_verification(
|
||||||
|
&self,
|
||||||
|
) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> {
|
||||||
|
self.verification_machine.request_self_verification(&self.inner, None).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a verification request to our other devices while specifying our
|
||||||
|
/// supported methods.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `methods` - The verification methods that we're supporting.
|
||||||
|
pub async fn request_verification_with_methods(
|
||||||
|
&self,
|
||||||
|
methods: Vec<VerificationMethod>,
|
||||||
|
) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> {
|
||||||
|
self.verification_machine.request_self_verification(&self.inner, Some(methods)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Struct representing a cross signing identity of a user.
|
||||||
|
///
|
||||||
|
/// This is the user identity of a user that isn't our own. Other users will
|
||||||
|
/// only contain a master key and a self signing key, meaning that only device
|
||||||
|
/// signatures can be checked with this identity.
|
||||||
|
///
|
||||||
|
/// This struct wraps a read-only version of the struct and allows verifications
|
||||||
|
/// to be requested to verify our own device with the user identity.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct UserIdentity {
|
||||||
|
pub(crate) inner: ReadOnlyUserIdentity,
|
||||||
|
pub(crate) verification_machine: VerificationMachine,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for UserIdentity {
|
||||||
|
type Target = ReadOnlyUserIdentity;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserIdentity {
|
||||||
|
/// Create a `VerificationRequest` object after the verification request
|
||||||
|
/// content has been sent out.
|
||||||
|
pub async fn request_verification(
|
||||||
|
&self,
|
||||||
|
room_id: &RoomId,
|
||||||
|
request_event_id: &EventId,
|
||||||
|
methods: Option<Vec<VerificationMethod>>,
|
||||||
|
) -> VerificationRequest {
|
||||||
|
self.verification_machine
|
||||||
|
.request_verification(&self.inner, room_id, request_event_id, methods)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a verification request to the given user.
|
||||||
|
///
|
||||||
|
/// The returned content needs to be sent out into a DM room with the given
|
||||||
|
/// user.
|
||||||
|
///
|
||||||
|
/// After the content has been sent out a `VerificationRequest` can be
|
||||||
|
/// started with the [`request_verification`] method.
|
||||||
|
///
|
||||||
|
/// [`request_verification()`]: #method.request_verification
|
||||||
|
pub async fn verification_request_content(
|
||||||
|
&self,
|
||||||
|
methods: Option<Vec<VerificationMethod>>,
|
||||||
|
) -> KeyVerificationRequestEventContent {
|
||||||
|
VerificationRequest::request(
|
||||||
|
self.verification_machine.own_user_id(),
|
||||||
|
self.verification_machine.own_device_id(),
|
||||||
|
self.user_id(),
|
||||||
|
methods,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Wrapper for a cross signing key marking it as the master key.
|
/// Wrapper for a cross signing key marking it as the master key.
|
||||||
///
|
///
|
||||||
|
@ -358,47 +508,47 @@ impl<'a> IntoIterator for &'a SelfSigningPubkey {
|
||||||
|
|
||||||
/// Enum over the different user identity types we can have.
|
/// Enum over the different user identity types we can have.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum UserIdentities {
|
pub enum ReadOnlyUserIdentities {
|
||||||
/// Our own user identity.
|
/// Our own user identity.
|
||||||
Own(OwnUserIdentity),
|
Own(ReadOnlyOwnUserIdentity),
|
||||||
/// Identities of other users.
|
/// Identities of other users.
|
||||||
Other(UserIdentity),
|
Other(ReadOnlyUserIdentity),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OwnUserIdentity> for UserIdentities {
|
impl From<ReadOnlyOwnUserIdentity> for ReadOnlyUserIdentities {
|
||||||
fn from(identity: OwnUserIdentity) -> Self {
|
fn from(identity: ReadOnlyOwnUserIdentity) -> Self {
|
||||||
UserIdentities::Own(identity)
|
ReadOnlyUserIdentities::Own(identity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<UserIdentity> for UserIdentities {
|
impl From<ReadOnlyUserIdentity> for ReadOnlyUserIdentities {
|
||||||
fn from(identity: UserIdentity) -> Self {
|
fn from(identity: ReadOnlyUserIdentity) -> Self {
|
||||||
UserIdentities::Other(identity)
|
ReadOnlyUserIdentities::Other(identity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserIdentities {
|
impl ReadOnlyUserIdentities {
|
||||||
/// The unique user id of this identity.
|
/// The unique user id of this identity.
|
||||||
pub fn user_id(&self) -> &UserId {
|
pub fn user_id(&self) -> &UserId {
|
||||||
match self {
|
match self {
|
||||||
UserIdentities::Own(i) => i.user_id(),
|
ReadOnlyUserIdentities::Own(i) => i.user_id(),
|
||||||
UserIdentities::Other(i) => i.user_id(),
|
ReadOnlyUserIdentities::Other(i) => i.user_id(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the master key of the identity.
|
/// Get the master key of the identity.
|
||||||
pub fn master_key(&self) -> &MasterPubkey {
|
pub fn master_key(&self) -> &MasterPubkey {
|
||||||
match self {
|
match self {
|
||||||
UserIdentities::Own(i) => i.master_key(),
|
ReadOnlyUserIdentities::Own(i) => i.master_key(),
|
||||||
UserIdentities::Other(i) => i.master_key(),
|
ReadOnlyUserIdentities::Other(i) => i.master_key(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the self-signing key of the identity.
|
/// Get the self-signing key of the identity.
|
||||||
pub fn self_signing_key(&self) -> &SelfSigningPubkey {
|
pub fn self_signing_key(&self) -> &SelfSigningPubkey {
|
||||||
match self {
|
match self {
|
||||||
UserIdentities::Own(i) => &i.self_signing_key,
|
ReadOnlyUserIdentities::Own(i) => &i.self_signing_key,
|
||||||
UserIdentities::Other(i) => &i.self_signing_key,
|
ReadOnlyUserIdentities::Other(i) => &i.self_signing_key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,32 +556,32 @@ impl UserIdentities {
|
||||||
/// own user identity..
|
/// own user identity..
|
||||||
pub fn user_signing_key(&self) -> Option<&UserSigningPubkey> {
|
pub fn user_signing_key(&self) -> Option<&UserSigningPubkey> {
|
||||||
match self {
|
match self {
|
||||||
UserIdentities::Own(i) => Some(&i.user_signing_key),
|
ReadOnlyUserIdentities::Own(i) => Some(&i.user_signing_key),
|
||||||
UserIdentities::Other(_) => None,
|
ReadOnlyUserIdentities::Other(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructure the enum into an `OwnUserIdentity` if it's of the correct
|
/// Destructure the enum into an `ReadOnlyOwnUserIdentity` if it's of the
|
||||||
/// type.
|
/// correct type.
|
||||||
pub fn own(&self) -> Option<&OwnUserIdentity> {
|
pub fn own(&self) -> Option<&ReadOnlyOwnUserIdentity> {
|
||||||
match self {
|
match self {
|
||||||
UserIdentities::Own(i) => Some(i),
|
ReadOnlyUserIdentities::Own(i) => Some(i),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructure the enum into an `UserIdentity` if it's of the correct
|
/// Destructure the enum into an `UserIdentity` if it's of the correct
|
||||||
/// type.
|
/// type.
|
||||||
pub fn other(&self) -> Option<&UserIdentity> {
|
pub fn other(&self) -> Option<&ReadOnlyUserIdentity> {
|
||||||
match self {
|
match self {
|
||||||
UserIdentities::Other(i) => Some(i),
|
ReadOnlyUserIdentities::Other(i) => Some(i),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for UserIdentities {
|
impl PartialEq for ReadOnlyUserIdentities {
|
||||||
fn eq(&self, other: &UserIdentities) -> bool {
|
fn eq(&self, other: &ReadOnlyUserIdentities) -> bool {
|
||||||
self.user_id() == other.user_id()
|
self.user_id() == other.user_id()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,13 +592,13 @@ impl PartialEq for UserIdentities {
|
||||||
/// only contain a master key and a self signing key, meaning that only device
|
/// only contain a master key and a self signing key, meaning that only device
|
||||||
/// signatures can be checked with this identity.
|
/// signatures can be checked with this identity.
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct UserIdentity {
|
pub struct ReadOnlyUserIdentity {
|
||||||
user_id: Arc<UserId>,
|
user_id: Arc<UserId>,
|
||||||
pub(crate) master_key: MasterPubkey,
|
pub(crate) master_key: MasterPubkey,
|
||||||
self_signing_key: SelfSigningPubkey,
|
self_signing_key: SelfSigningPubkey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserIdentity {
|
impl ReadOnlyUserIdentity {
|
||||||
/// Create a new user identity with the given master and self signing key.
|
/// Create a new user identity with the given master and self signing key.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -543,7 +693,7 @@ impl UserIdentity {
|
||||||
/// This identity can verify other identities as well as devices belonging to
|
/// This identity can verify other identities as well as devices belonging to
|
||||||
/// the identity.
|
/// the identity.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct OwnUserIdentity {
|
pub struct ReadOnlyOwnUserIdentity {
|
||||||
user_id: Arc<UserId>,
|
user_id: Arc<UserId>,
|
||||||
master_key: MasterPubkey,
|
master_key: MasterPubkey,
|
||||||
self_signing_key: SelfSigningPubkey,
|
self_signing_key: SelfSigningPubkey,
|
||||||
|
@ -555,7 +705,7 @@ pub struct OwnUserIdentity {
|
||||||
verified: Arc<AtomicBool>,
|
verified: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnUserIdentity {
|
impl ReadOnlyOwnUserIdentity {
|
||||||
/// Create a new own user identity with the given master, self signing, and
|
/// Create a new own user identity with the given master, self signing, and
|
||||||
/// user signing key.
|
/// user signing key.
|
||||||
///
|
///
|
||||||
|
@ -615,7 +765,10 @@ impl OwnUserIdentity {
|
||||||
///
|
///
|
||||||
/// Returns an empty result if the signature check succeeded, otherwise a
|
/// Returns an empty result if the signature check succeeded, otherwise a
|
||||||
/// SignatureError indicating why the check failed.
|
/// SignatureError indicating why the check failed.
|
||||||
pub fn is_identity_signed(&self, identity: &UserIdentity) -> Result<(), SignatureError> {
|
pub fn is_identity_signed(
|
||||||
|
&self,
|
||||||
|
identity: &ReadOnlyUserIdentity,
|
||||||
|
) -> Result<(), SignatureError> {
|
||||||
self.user_signing_key.verify_master_key(&identity.master_key)
|
self.user_signing_key.verify_master_key(&identity.master_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,7 +845,7 @@ pub(crate) mod test {
|
||||||
use matrix_sdk_test::async_test;
|
use matrix_sdk_test::async_test;
|
||||||
use ruma::{api::client::r0::keys::get_keys::Response as KeyQueryResponse, user_id};
|
use ruma::{api::client::r0::keys::get_keys::Response as KeyQueryResponse, user_id};
|
||||||
|
|
||||||
use super::{OwnUserIdentity, UserIdentities, UserIdentity};
|
use super::{ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities, ReadOnlyUserIdentity};
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{
|
identities::{
|
||||||
manager::test::{other_key_query, own_key_query},
|
manager::test::{other_key_query, own_key_query},
|
||||||
|
@ -710,28 +863,29 @@ pub(crate) mod test {
|
||||||
(first, second)
|
(first, second)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn own_identity(response: &KeyQueryResponse) -> OwnUserIdentity {
|
fn own_identity(response: &KeyQueryResponse) -> ReadOnlyOwnUserIdentity {
|
||||||
let user_id = user_id!("@example:localhost");
|
let user_id = user_id!("@example:localhost");
|
||||||
|
|
||||||
let master_key = response.master_keys.get(&user_id).unwrap();
|
let master_key = response.master_keys.get(&user_id).unwrap();
|
||||||
let user_signing = response.user_signing_keys.get(&user_id).unwrap();
|
let user_signing = response.user_signing_keys.get(&user_id).unwrap();
|
||||||
let self_signing = response.self_signing_keys.get(&user_id).unwrap();
|
let self_signing = response.self_signing_keys.get(&user_id).unwrap();
|
||||||
|
|
||||||
OwnUserIdentity::new(master_key.into(), self_signing.into(), user_signing.into()).unwrap()
|
ReadOnlyOwnUserIdentity::new(master_key.into(), self_signing.into(), user_signing.into())
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_own_identity() -> OwnUserIdentity {
|
pub(crate) fn get_own_identity() -> ReadOnlyOwnUserIdentity {
|
||||||
own_identity(&own_key_query())
|
own_identity(&own_key_query())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_other_identity() -> UserIdentity {
|
pub(crate) fn get_other_identity() -> ReadOnlyUserIdentity {
|
||||||
let user_id = user_id!("@example2:localhost");
|
let user_id = user_id!("@example2:localhost");
|
||||||
let response = other_key_query();
|
let response = other_key_query();
|
||||||
|
|
||||||
let master_key = response.master_keys.get(&user_id).unwrap();
|
let master_key = response.master_keys.get(&user_id).unwrap();
|
||||||
let self_signing = response.self_signing_keys.get(&user_id).unwrap();
|
let self_signing = response.self_signing_keys.get(&user_id).unwrap();
|
||||||
|
|
||||||
UserIdentity::new(master_key.into(), self_signing.into()).unwrap()
|
ReadOnlyUserIdentity::new(master_key.into(), self_signing.into()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -743,7 +897,8 @@ pub(crate) mod test {
|
||||||
let user_signing = response.user_signing_keys.get(&user_id).unwrap();
|
let user_signing = response.user_signing_keys.get(&user_id).unwrap();
|
||||||
let self_signing = response.self_signing_keys.get(&user_id).unwrap();
|
let self_signing = response.self_signing_keys.get(&user_id).unwrap();
|
||||||
|
|
||||||
OwnUserIdentity::new(master_key.into(), self_signing.into(), user_signing.into()).unwrap();
|
ReadOnlyOwnUserIdentity::new(master_key.into(), self_signing.into(), user_signing.into())
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -773,7 +928,7 @@ pub(crate) mod test {
|
||||||
verification_machine: verification_machine.clone(),
|
verification_machine: verification_machine.clone(),
|
||||||
private_identity: private_identity.clone(),
|
private_identity: private_identity.clone(),
|
||||||
own_identity: Some(identity.clone()),
|
own_identity: Some(identity.clone()),
|
||||||
device_owner_identity: Some(UserIdentities::Own(identity.clone())),
|
device_owner_identity: Some(ReadOnlyUserIdentities::Own(identity.clone())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let second = Device {
|
let second = Device {
|
||||||
|
@ -781,7 +936,7 @@ pub(crate) mod test {
|
||||||
verification_machine,
|
verification_machine,
|
||||||
private_identity,
|
private_identity,
|
||||||
own_identity: Some(identity.clone()),
|
own_identity: Some(identity.clone()),
|
||||||
device_owner_identity: Some(UserIdentities::Own(identity.clone())),
|
device_owner_identity: Some(ReadOnlyUserIdentities::Own(identity.clone())),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(!second.is_locally_trusted());
|
assert!(!second.is_locally_trusted());
|
||||||
|
|
|
@ -45,7 +45,8 @@ pub use file_encryption::{
|
||||||
DecryptorError, EncryptionInfo, KeyExportError,
|
DecryptorError, EncryptionInfo, KeyExportError,
|
||||||
};
|
};
|
||||||
pub use identities::{
|
pub use identities::{
|
||||||
Device, LocalTrust, OwnUserIdentity, ReadOnlyDevice, UserDevices, UserIdentities, UserIdentity,
|
Device, LocalTrust, OwnUserIdentity, ReadOnlyDevice, ReadOnlyOwnUserIdentity,
|
||||||
|
ReadOnlyUserIdentities, ReadOnlyUserIdentity, UserDevices, UserIdentities, UserIdentity,
|
||||||
};
|
};
|
||||||
pub use machine::OlmMachine;
|
pub use machine::OlmMachine;
|
||||||
pub use matrix_qrcode;
|
pub use matrix_qrcode;
|
||||||
|
|
|
@ -46,7 +46,7 @@ use tracing::{debug, error, info, trace, warn};
|
||||||
use crate::store::sled::SledStore;
|
use crate::store::sled::SledStore;
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{EventError, MegolmError, MegolmResult, OlmError, OlmResult},
|
error::{EventError, MegolmError, MegolmResult, OlmError, OlmResult},
|
||||||
identities::{Device, IdentityManager, UserDevices},
|
identities::{user::UserIdentities, Device, IdentityManager, UserDevices},
|
||||||
key_request::KeyRequestMachine,
|
key_request::KeyRequestMachine,
|
||||||
olm::{
|
olm::{
|
||||||
Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys,
|
Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys,
|
||||||
|
@ -1052,6 +1052,18 @@ impl OlmMachine {
|
||||||
self.store.get_device(user_id, device_id).await
|
self.store.get_device(user_id, device_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the cross signing user identity of a user.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `user_id` - The unique id of the user that the identity belongs to
|
||||||
|
///
|
||||||
|
/// Returns a `UserIdentities` enum if one is found and the crypto store
|
||||||
|
/// didn't throw an error.
|
||||||
|
pub async fn get_identity(&self, user_id: &UserId) -> StoreResult<Option<UserIdentities>> {
|
||||||
|
self.store.get_identity(user_id).await
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a map holding all the devices of an user.
|
/// Get a map holding all the devices of an user.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|
|
@ -34,7 +34,7 @@ use serde_json::Error as JsonError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::SignatureError, identities::MasterPubkey, requests::UploadSigningKeysRequest,
|
error::SignatureError, identities::MasterPubkey, requests::UploadSigningKeysRequest,
|
||||||
OwnUserIdentity, ReadOnlyAccount, ReadOnlyDevice, UserIdentity,
|
ReadOnlyAccount, ReadOnlyDevice, ReadOnlyOwnUserIdentity, ReadOnlyUserIdentity,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Private cross signing identity.
|
/// Private cross signing identity.
|
||||||
|
@ -117,7 +117,9 @@ impl PrivateCrossSigningIdentity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn to_public_identity(&self) -> Result<OwnUserIdentity, SignatureError> {
|
pub(crate) async fn to_public_identity(
|
||||||
|
&self,
|
||||||
|
) -> Result<ReadOnlyOwnUserIdentity, SignatureError> {
|
||||||
let master = self
|
let master = self
|
||||||
.master_key
|
.master_key
|
||||||
.lock()
|
.lock()
|
||||||
|
@ -142,7 +144,7 @@ impl PrivateCrossSigningIdentity {
|
||||||
.ok_or(SignatureError::MissingSigningKey)?
|
.ok_or(SignatureError::MissingSigningKey)?
|
||||||
.public_key
|
.public_key
|
||||||
.clone();
|
.clone();
|
||||||
let identity = OwnUserIdentity::new(master, self_signing, user_signing)?;
|
let identity = ReadOnlyOwnUserIdentity::new(master, self_signing, user_signing)?;
|
||||||
identity.mark_as_verified();
|
identity.mark_as_verified();
|
||||||
|
|
||||||
Ok(identity)
|
Ok(identity)
|
||||||
|
@ -151,7 +153,7 @@ impl PrivateCrossSigningIdentity {
|
||||||
/// Sign the given public user identity with this private identity.
|
/// Sign the given public user identity with this private identity.
|
||||||
pub(crate) async fn sign_user(
|
pub(crate) async fn sign_user(
|
||||||
&self,
|
&self,
|
||||||
user_identity: &UserIdentity,
|
user_identity: &ReadOnlyUserIdentity,
|
||||||
) -> Result<SignatureUploadRequest, SignatureError> {
|
) -> Result<SignatureUploadRequest, SignatureError> {
|
||||||
let signed_keys = self
|
let signed_keys = self
|
||||||
.user_signing_key
|
.user_signing_key
|
||||||
|
@ -407,7 +409,7 @@ mod test {
|
||||||
|
|
||||||
use super::{PrivateCrossSigningIdentity, Signing};
|
use super::{PrivateCrossSigningIdentity, Signing};
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{ReadOnlyDevice, UserIdentity},
|
identities::{ReadOnlyDevice, ReadOnlyUserIdentity},
|
||||||
olm::ReadOnlyAccount,
|
olm::ReadOnlyAccount,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -518,7 +520,7 @@ mod test {
|
||||||
|
|
||||||
let bob_account = ReadOnlyAccount::new(&user_id!("@bob:localhost"), "DEVICEID".into());
|
let bob_account = ReadOnlyAccount::new(&user_id!("@bob:localhost"), "DEVICEID".into());
|
||||||
let (bob_private, _, _) = PrivateCrossSigningIdentity::new_with_account(&bob_account).await;
|
let (bob_private, _, _) = PrivateCrossSigningIdentity::new_with_account(&bob_account).await;
|
||||||
let mut bob_public = UserIdentity::from_private(&bob_private).await;
|
let mut bob_public = ReadOnlyUserIdentity::from_private(&bob_private).await;
|
||||||
|
|
||||||
let user_signing = identity.user_signing_key.lock().await;
|
let user_signing = identity.user_signing_key.lock().await;
|
||||||
let user_signing = user_signing.as_ref().unwrap();
|
let user_signing = user_signing.as_ref().unwrap();
|
||||||
|
|
|
@ -37,7 +37,7 @@ use crate::{
|
||||||
error::SignatureError,
|
error::SignatureError,
|
||||||
identities::{MasterPubkey, SelfSigningPubkey, UserSigningPubkey},
|
identities::{MasterPubkey, SelfSigningPubkey, UserSigningPubkey},
|
||||||
utilities::{decode_url_safe as decode, encode_url_safe as encode, DecodeError},
|
utilities::{decode_url_safe as decode, encode_url_safe as encode, DecodeError},
|
||||||
UserIdentity,
|
ReadOnlyUserIdentity,
|
||||||
};
|
};
|
||||||
|
|
||||||
const NONCE_SIZE: usize = 12;
|
const NONCE_SIZE: usize = 12;
|
||||||
|
@ -186,7 +186,7 @@ impl UserSigning {
|
||||||
|
|
||||||
pub async fn sign_user(
|
pub async fn sign_user(
|
||||||
&self,
|
&self,
|
||||||
user: &UserIdentity,
|
user: &ReadOnlyUserIdentity,
|
||||||
) -> Result<BTreeMap<UserId, BTreeMap<String, Value>>, SignatureError> {
|
) -> Result<BTreeMap<UserId, BTreeMap<String, Value>>, SignatureError> {
|
||||||
let user_master: &CrossSigningKey = user.master_key().as_ref();
|
let user_master: &CrossSigningKey = user.master_key().as_ref();
|
||||||
let signature = self.inner.sign_json(serde_json::to_value(user_master)?).await?;
|
let signature = self.inner.sign_json(serde_json::to_value(user_master)?).await?;
|
||||||
|
|
|
@ -26,7 +26,7 @@ use super::{
|
||||||
Changes, CryptoStore, InboundGroupSession, ReadOnlyAccount, Result, Session,
|
Changes, CryptoStore, InboundGroupSession, ReadOnlyAccount, Result, Session,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{ReadOnlyDevice, UserIdentities},
|
identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
|
||||||
key_request::OutgoingKeyRequest,
|
key_request::OutgoingKeyRequest,
|
||||||
olm::{OutboundGroupSession, PrivateCrossSigningIdentity},
|
olm::{OutboundGroupSession, PrivateCrossSigningIdentity},
|
||||||
};
|
};
|
||||||
|
@ -44,7 +44,7 @@ pub struct MemoryStore {
|
||||||
users_for_key_query: Arc<DashSet<UserId>>,
|
users_for_key_query: Arc<DashSet<UserId>>,
|
||||||
olm_hashes: Arc<DashMap<String, DashSet<String>>>,
|
olm_hashes: Arc<DashMap<String, DashSet<String>>>,
|
||||||
devices: DeviceStore,
|
devices: DeviceStore,
|
||||||
identities: Arc<DashMap<UserId, UserIdentities>>,
|
identities: Arc<DashMap<UserId, ReadOnlyUserIdentities>>,
|
||||||
outgoing_key_requests: Arc<DashMap<Uuid, OutgoingKeyRequest>>,
|
outgoing_key_requests: Arc<DashMap<Uuid, OutgoingKeyRequest>>,
|
||||||
key_requests_by_info: Arc<DashMap<String, Uuid>>,
|
key_requests_by_info: Arc<DashMap<String, Uuid>>,
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ impl CryptoStore for MemoryStore {
|
||||||
Ok(self.devices.user_devices(user_id))
|
Ok(self.devices.user_devices(user_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_user_identity(&self, user_id: &UserId) -> Result<Option<UserIdentities>> {
|
async fn get_user_identity(&self, user_id: &UserId) -> Result<Option<ReadOnlyUserIdentities>> {
|
||||||
#[allow(clippy::map_clone)]
|
#[allow(clippy::map_clone)]
|
||||||
Ok(self.identities.get(user_id).map(|i| i.clone()))
|
Ok(self.identities.get(user_id).map(|i| i.clone()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,10 @@ use thiserror::Error;
|
||||||
pub use self::sled::SledStore;
|
pub use self::sled::SledStore;
|
||||||
use crate::{
|
use crate::{
|
||||||
error::SessionUnpicklingError,
|
error::SessionUnpicklingError,
|
||||||
identities::{Device, ReadOnlyDevice, UserDevices, UserIdentities},
|
identities::{
|
||||||
|
user::{OwnUserIdentity, UserIdentities, UserIdentity},
|
||||||
|
Device, ReadOnlyDevice, ReadOnlyUserIdentities, UserDevices,
|
||||||
|
},
|
||||||
key_request::OutgoingKeyRequest,
|
key_request::OutgoingKeyRequest,
|
||||||
olm::{
|
olm::{
|
||||||
InboundGroupSession, OlmMessageHash, OutboundGroupSession, PrivateCrossSigningIdentity,
|
InboundGroupSession, OlmMessageHash, OutboundGroupSession, PrivateCrossSigningIdentity,
|
||||||
|
@ -109,8 +112,8 @@ pub struct Changes {
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub struct IdentityChanges {
|
pub struct IdentityChanges {
|
||||||
pub new: Vec<UserIdentities>,
|
pub new: Vec<ReadOnlyUserIdentities>,
|
||||||
pub changed: Vec<UserIdentities>,
|
pub changed: Vec<ReadOnlyUserIdentities>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
@ -215,8 +218,8 @@ impl Store {
|
||||||
device_id: &DeviceId,
|
device_id: &DeviceId,
|
||||||
) -> Result<Option<Device>> {
|
) -> Result<Option<Device>> {
|
||||||
let own_identity =
|
let own_identity =
|
||||||
self.get_user_identity(&self.user_id).await?.map(|i| i.own().cloned()).flatten();
|
self.inner.get_user_identity(&self.user_id).await?.map(|i| i.own().cloned()).flatten();
|
||||||
let device_owner_identity = self.get_user_identity(user_id).await?;
|
let device_owner_identity = self.inner.get_user_identity(user_id).await?;
|
||||||
|
|
||||||
Ok(self.inner.get_device(user_id, device_id).await?.map(|d| Device {
|
Ok(self.inner.get_device(user_id, device_id).await?.map(|d| Device {
|
||||||
inner: d,
|
inner: d,
|
||||||
|
@ -226,6 +229,20 @@ impl Store {
|
||||||
device_owner_identity,
|
device_owner_identity,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_identity(&self, user_id: &UserId) -> Result<Option<UserIdentities>> {
|
||||||
|
Ok(self.inner.get_user_identity(user_id).await?.map(|i| match i {
|
||||||
|
ReadOnlyUserIdentities::Own(i) => OwnUserIdentity {
|
||||||
|
inner: i,
|
||||||
|
verification_machine: self.verification_machine.clone(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
ReadOnlyUserIdentities::Other(i) => {
|
||||||
|
UserIdentity { inner: i, verification_machine: self.verification_machine.clone() }
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Store {
|
impl Deref for Store {
|
||||||
|
@ -388,7 +405,7 @@ pub trait CryptoStore: AsyncTraitDeps {
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `user_id` - The user for which we should get the identity.
|
/// * `user_id` - The user for which we should get the identity.
|
||||||
async fn get_user_identity(&self, user_id: &UserId) -> Result<Option<UserIdentities>>;
|
async fn get_user_identity(&self, user_id: &UserId) -> Result<Option<ReadOnlyUserIdentities>>;
|
||||||
|
|
||||||
/// Check if a hash for an Olm message stored in the database.
|
/// Check if a hash for an Olm message stored in the database.
|
||||||
async fn is_message_known(&self, message_hash: &OlmMessageHash) -> Result<bool>;
|
async fn is_message_known(&self, message_hash: &OlmMessageHash) -> Result<bool>;
|
||||||
|
|
|
@ -35,7 +35,7 @@ use super::{
|
||||||
ReadOnlyAccount, Result, Session,
|
ReadOnlyAccount, Result, Session,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{ReadOnlyDevice, UserIdentities},
|
identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
|
||||||
key_request::OutgoingKeyRequest,
|
key_request::OutgoingKeyRequest,
|
||||||
olm::{OutboundGroupSession, PickledInboundGroupSession, PrivateCrossSigningIdentity},
|
olm::{OutboundGroupSession, PickledInboundGroupSession, PrivateCrossSigningIdentity},
|
||||||
};
|
};
|
||||||
|
@ -669,7 +669,7 @@ impl CryptoStore for SledStore {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_user_identity(&self, user_id: &UserId) -> Result<Option<UserIdentities>> {
|
async fn get_user_identity(&self, user_id: &UserId) -> Result<Option<ReadOnlyUserIdentities>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.identities
|
.identities
|
||||||
.get(user_id.encode())?
|
.get(user_id.encode())?
|
||||||
|
|
|
@ -20,9 +20,13 @@ use std::{
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use matrix_sdk_common::{locks::Mutex, uuid::Uuid};
|
use matrix_sdk_common::{locks::Mutex, uuid::Uuid};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
events::{AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent},
|
events::{
|
||||||
|
key::verification::VerificationMethod, AnyToDeviceEvent, AnyToDeviceEventContent,
|
||||||
|
ToDeviceEvent,
|
||||||
|
},
|
||||||
serde::Raw,
|
serde::Raw,
|
||||||
DeviceId, MilliSecondsSinceUnixEpoch, UserId,
|
to_device::DeviceIdOrAllDevices,
|
||||||
|
DeviceId, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId,
|
||||||
};
|
};
|
||||||
use tracing::{info, trace, warn};
|
use tracing::{info, trace, warn};
|
||||||
|
|
||||||
|
@ -37,8 +41,8 @@ use crate::{
|
||||||
olm::PrivateCrossSigningIdentity,
|
olm::PrivateCrossSigningIdentity,
|
||||||
requests::OutgoingRequest,
|
requests::OutgoingRequest,
|
||||||
store::{CryptoStore, CryptoStoreError},
|
store::{CryptoStore, CryptoStoreError},
|
||||||
OutgoingVerificationRequest, ReadOnlyAccount, ReadOnlyDevice, RoomMessageRequest,
|
OutgoingVerificationRequest, ReadOnlyAccount, ReadOnlyDevice, ReadOnlyOwnUserIdentity,
|
||||||
ToDeviceRequest,
|
ReadOnlyUserIdentity, RoomMessageRequest, ToDeviceRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -65,6 +69,69 @@ impl VerificationMachine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn own_user_id(&self) -> &UserId {
|
||||||
|
self.account.user_id()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn own_device_id(&self) -> &DeviceId {
|
||||||
|
self.account.device_id()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn request_self_verification(
|
||||||
|
&self,
|
||||||
|
identity: &ReadOnlyOwnUserIdentity,
|
||||||
|
methods: Option<Vec<VerificationMethod>>,
|
||||||
|
) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> {
|
||||||
|
let flow_id = FlowId::from(Uuid::new_v4().to_string());
|
||||||
|
|
||||||
|
let verification = VerificationRequest::new(
|
||||||
|
self.verifications.clone(),
|
||||||
|
self.account.clone(),
|
||||||
|
self.private_identity.lock().await.clone(),
|
||||||
|
self.store.clone(),
|
||||||
|
flow_id,
|
||||||
|
identity.user_id(),
|
||||||
|
methods,
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO get all the device ids of the user instead of using AllDevices
|
||||||
|
// make sure to remember this so we can cancel once someone picks up
|
||||||
|
let request: OutgoingVerificationRequest = ToDeviceRequest::new(
|
||||||
|
identity.user_id(),
|
||||||
|
DeviceIdOrAllDevices::AllDevices,
|
||||||
|
AnyToDeviceEventContent::KeyVerificationRequest(verification.request_to_device()),
|
||||||
|
)
|
||||||
|
.into();
|
||||||
|
|
||||||
|
self.insert_request(verification.clone());
|
||||||
|
|
||||||
|
Ok((verification, request))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn request_verification(
|
||||||
|
&self,
|
||||||
|
identity: &ReadOnlyUserIdentity,
|
||||||
|
room_id: &RoomId,
|
||||||
|
request_event_id: &EventId,
|
||||||
|
methods: Option<Vec<VerificationMethod>>,
|
||||||
|
) -> VerificationRequest {
|
||||||
|
let flow_id = FlowId::InRoom(room_id.to_owned(), request_event_id.to_owned());
|
||||||
|
|
||||||
|
let request = VerificationRequest::new(
|
||||||
|
self.verifications.clone(),
|
||||||
|
self.account.clone(),
|
||||||
|
self.private_identity.lock().await.clone(),
|
||||||
|
self.store.clone(),
|
||||||
|
flow_id,
|
||||||
|
identity.user_id(),
|
||||||
|
methods,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.insert_request(request.clone());
|
||||||
|
|
||||||
|
request
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn start_sas(
|
pub async fn start_sas(
|
||||||
&self,
|
&self,
|
||||||
device: ReadOnlyDevice,
|
device: ReadOnlyDevice,
|
||||||
|
|
|
@ -44,7 +44,7 @@ use crate::{
|
||||||
error::SignatureError,
|
error::SignatureError,
|
||||||
olm::PrivateCrossSigningIdentity,
|
olm::PrivateCrossSigningIdentity,
|
||||||
store::{Changes, CryptoStore},
|
store::{Changes, CryptoStore},
|
||||||
CryptoStoreError, LocalTrust, ReadOnlyDevice, UserIdentities,
|
CryptoStoreError, LocalTrust, ReadOnlyDevice, ReadOnlyUserIdentities,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An enum over the different verification types the SDK supports.
|
/// An enum over the different verification types the SDK supports.
|
||||||
|
@ -144,7 +144,7 @@ impl From<QrVerification> for Verification {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Done {
|
pub struct Done {
|
||||||
verified_devices: Arc<[ReadOnlyDevice]>,
|
verified_devices: Arc<[ReadOnlyDevice]>,
|
||||||
verified_master_keys: Arc<[UserIdentities]>,
|
verified_master_keys: Arc<[ReadOnlyUserIdentities]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Done {
|
impl Done {
|
||||||
|
@ -277,7 +277,7 @@ pub struct IdentitiesBeingVerified {
|
||||||
private_identity: PrivateCrossSigningIdentity,
|
private_identity: PrivateCrossSigningIdentity,
|
||||||
store: Arc<dyn CryptoStore>,
|
store: Arc<dyn CryptoStore>,
|
||||||
device_being_verified: ReadOnlyDevice,
|
device_being_verified: ReadOnlyDevice,
|
||||||
identity_being_verified: Option<UserIdentities>,
|
identity_being_verified: Option<ReadOnlyUserIdentities>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IdentitiesBeingVerified {
|
impl IdentitiesBeingVerified {
|
||||||
|
@ -308,7 +308,7 @@ impl IdentitiesBeingVerified {
|
||||||
pub async fn mark_as_done(
|
pub async fn mark_as_done(
|
||||||
&self,
|
&self,
|
||||||
verified_devices: Option<&[ReadOnlyDevice]>,
|
verified_devices: Option<&[ReadOnlyDevice]>,
|
||||||
verified_identities: Option<&[UserIdentities]>,
|
verified_identities: Option<&[ReadOnlyUserIdentities]>,
|
||||||
) -> Result<VerificationResult, CryptoStoreError> {
|
) -> Result<VerificationResult, CryptoStoreError> {
|
||||||
let 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?;
|
||||||
|
@ -415,8 +415,8 @@ impl IdentitiesBeingVerified {
|
||||||
|
|
||||||
async fn mark_identity_as_verified(
|
async fn mark_identity_as_verified(
|
||||||
&self,
|
&self,
|
||||||
verified_identities: Option<&[UserIdentities]>,
|
verified_identities: Option<&[ReadOnlyUserIdentities]>,
|
||||||
) -> Result<Option<UserIdentities>, CryptoStoreError> {
|
) -> Result<Option<ReadOnlyUserIdentities>, CryptoStoreError> {
|
||||||
// If there wasn't an identity available during the verification flow
|
// If there wasn't an identity available during the verification flow
|
||||||
// return early as there's nothing to do.
|
// return early as there's nothing to do.
|
||||||
if self.identity_being_verified.is_none() {
|
if self.identity_being_verified.is_none() {
|
||||||
|
@ -437,7 +437,7 @@ impl IdentitiesBeingVerified {
|
||||||
"Marking the user identity of as verified."
|
"Marking the user identity of as verified."
|
||||||
);
|
);
|
||||||
|
|
||||||
if let UserIdentities::Own(i) = &identity {
|
if let ReadOnlyUserIdentities::Own(i) = &identity {
|
||||||
i.mark_as_verified();
|
i.mark_as_verified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,8 @@ use super::{
|
||||||
use crate::{
|
use crate::{
|
||||||
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount},
|
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount},
|
||||||
store::CryptoStore,
|
store::CryptoStore,
|
||||||
CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, RoomMessageRequest,
|
CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, ReadOnlyUserIdentities,
|
||||||
ToDeviceRequest, UserIdentities,
|
RoomMessageRequest, ToDeviceRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SECRET_SIZE: usize = 16;
|
const SECRET_SIZE: usize = 16;
|
||||||
|
@ -518,7 +518,7 @@ impl QrVerification {
|
||||||
ScanError::MissingDeviceKeys(other_user_id.clone(), other_device_id.clone())
|
ScanError::MissingDeviceKeys(other_user_id.clone(), other_device_id.clone())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let check_master_key = |key, identity: &UserIdentities| {
|
let check_master_key = |key, identity: &ReadOnlyUserIdentities| {
|
||||||
let master_key = identity.master_key().get_first_key().ok_or_else(|| {
|
let master_key = identity.master_key().get_first_key().ok_or_else(|| {
|
||||||
ScanError::MissingCrossSigningIdentity(identity.user_id().clone())
|
ScanError::MissingCrossSigningIdentity(identity.user_id().clone())
|
||||||
})?;
|
})?;
|
||||||
|
@ -719,7 +719,7 @@ impl QrState<Done> {
|
||||||
self.state.as_content(flow_id)
|
self.state.as_content(flow_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verified_identities(&self) -> (Arc<[ReadOnlyDevice]>, Arc<[UserIdentities]>) {
|
fn verified_identities(&self) -> (Arc<[ReadOnlyDevice]>, Arc<[ReadOnlyUserIdentities]>) {
|
||||||
(self.state.verified_devices.clone(), self.state.verified_master_keys.clone())
|
(self.state.verified_devices.clone(), self.state.verified_master_keys.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -729,7 +729,7 @@ impl QrState<Confirmed> {
|
||||||
self,
|
self,
|
||||||
_: &DoneContent,
|
_: &DoneContent,
|
||||||
verified_device: Option<&ReadOnlyDevice>,
|
verified_device: Option<&ReadOnlyDevice>,
|
||||||
verified_identity: Option<&UserIdentities>,
|
verified_identity: Option<&ReadOnlyUserIdentities>,
|
||||||
) -> QrState<Done> {
|
) -> QrState<Done> {
|
||||||
let devices: Vec<_> = verified_device.into_iter().cloned().collect();
|
let devices: Vec<_> = verified_device.into_iter().cloned().collect();
|
||||||
let identities: Vec<_> = verified_identity.into_iter().cloned().collect();
|
let identities: Vec<_> = verified_identity.into_iter().cloned().collect();
|
||||||
|
@ -768,7 +768,7 @@ impl QrState<Reciprocated> {
|
||||||
self,
|
self,
|
||||||
_: &DoneContent,
|
_: &DoneContent,
|
||||||
verified_device: Option<&ReadOnlyDevice>,
|
verified_device: Option<&ReadOnlyDevice>,
|
||||||
verified_identity: Option<&UserIdentities>,
|
verified_identity: Option<&ReadOnlyUserIdentities>,
|
||||||
) -> QrState<Done> {
|
) -> QrState<Done> {
|
||||||
let devices: Vec<_> = verified_device.into_iter().cloned().collect();
|
let devices: Vec<_> = verified_device.into_iter().cloned().collect();
|
||||||
let identities: Vec<_> = verified_identity.into_iter().cloned().collect();
|
let identities: Vec<_> = verified_identity.into_iter().cloned().collect();
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use matrix_qrcode::QrVerificationData;
|
use matrix_qrcode::QrVerificationData;
|
||||||
|
@ -31,7 +29,7 @@ use ruma::{
|
||||||
AnyMessageEventContent, AnyToDeviceEventContent,
|
AnyMessageEventContent, AnyToDeviceEventContent,
|
||||||
},
|
},
|
||||||
to_device::DeviceIdOrAllDevices,
|
to_device::DeviceIdOrAllDevices,
|
||||||
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId,
|
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, MilliSecondsSinceUnixEpoch, RoomId, UserId,
|
||||||
};
|
};
|
||||||
use tracing::{info, trace, warn};
|
use tracing::{info, trace, warn};
|
||||||
|
|
||||||
|
@ -46,8 +44,8 @@ use super::{
|
||||||
use crate::{
|
use crate::{
|
||||||
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount},
|
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount},
|
||||||
store::CryptoStore,
|
store::CryptoStore,
|
||||||
CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, RoomMessageRequest, Sas,
|
CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, ReadOnlyUserIdentities,
|
||||||
ToDeviceRequest, UserIdentities,
|
RoomMessageRequest, Sas, ToDeviceRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SUPPORTED_METHODS: &[VerificationMethod] = &[
|
const SUPPORTED_METHODS: &[VerificationMethod] = &[
|
||||||
|
@ -79,41 +77,10 @@ impl VerificationRequest {
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
private_cross_signing_identity: PrivateCrossSigningIdentity,
|
private_cross_signing_identity: PrivateCrossSigningIdentity,
|
||||||
store: Arc<dyn CryptoStore>,
|
store: Arc<dyn CryptoStore>,
|
||||||
room_id: &RoomId,
|
flow_id: FlowId,
|
||||||
event_id: &EventId,
|
|
||||||
other_user: &UserId,
|
other_user: &UserId,
|
||||||
|
methods: Option<Vec<VerificationMethod>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let flow_id = (room_id.to_owned(), event_id.to_owned()).into();
|
|
||||||
|
|
||||||
let inner = Mutex::new(InnerRequest::Created(RequestState::new(
|
|
||||||
account.clone(),
|
|
||||||
private_cross_signing_identity,
|
|
||||||
cache.clone(),
|
|
||||||
store,
|
|
||||||
other_user,
|
|
||||||
&flow_id,
|
|
||||||
)))
|
|
||||||
.into();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
account,
|
|
||||||
verification_cache: cache,
|
|
||||||
flow_id: flow_id.into(),
|
|
||||||
inner,
|
|
||||||
other_user_id: other_user.to_owned().into(),
|
|
||||||
we_started: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn new_to_device(
|
|
||||||
cache: VerificationCache,
|
|
||||||
account: ReadOnlyAccount,
|
|
||||||
private_cross_signing_identity: PrivateCrossSigningIdentity,
|
|
||||||
store: Arc<dyn CryptoStore>,
|
|
||||||
other_user: &UserId,
|
|
||||||
) -> Self {
|
|
||||||
let flow_id = Uuid::new_v4().to_string().into();
|
|
||||||
|
|
||||||
let inner = Mutex::new(InnerRequest::Created(RequestState::new(
|
let inner = Mutex::new(InnerRequest::Created(RequestState::new(
|
||||||
account.clone(),
|
account.clone(),
|
||||||
private_cross_signing_identity,
|
private_cross_signing_identity,
|
||||||
|
@ -121,6 +88,7 @@ impl VerificationRequest {
|
||||||
store,
|
store,
|
||||||
other_user,
|
other_user,
|
||||||
&flow_id,
|
&flow_id,
|
||||||
|
methods,
|
||||||
)))
|
)))
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
|
@ -138,11 +106,19 @@ impl VerificationRequest {
|
||||||
/// verification from the other side. This should be used only for
|
/// verification from the other side. This should be used only for
|
||||||
/// self-verifications and it should be sent to the specific device that we
|
/// self-verifications and it should be sent to the specific device that we
|
||||||
/// want to verify.
|
/// want to verify.
|
||||||
pub fn request_to_device(&self) -> RequestToDeviceEventContent {
|
pub(crate) fn request_to_device(&self) -> RequestToDeviceEventContent {
|
||||||
|
let inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
|
let methods = if let InnerRequest::Created(c) = &*inner {
|
||||||
|
c.state.our_methods.clone()
|
||||||
|
} else {
|
||||||
|
SUPPORTED_METHODS.to_vec()
|
||||||
|
};
|
||||||
|
|
||||||
RequestToDeviceEventContent::new(
|
RequestToDeviceEventContent::new(
|
||||||
self.account.device_id().into(),
|
self.account.device_id().into(),
|
||||||
self.flow_id().as_str().to_string(),
|
self.flow_id().as_str().to_string(),
|
||||||
SUPPORTED_METHODS.to_vec(),
|
methods,
|
||||||
MilliSecondsSinceUnixEpoch::now(),
|
MilliSecondsSinceUnixEpoch::now(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -155,6 +131,7 @@ impl VerificationRequest {
|
||||||
own_user_id: &UserId,
|
own_user_id: &UserId,
|
||||||
own_device_id: &DeviceId,
|
own_device_id: &DeviceId,
|
||||||
other_user_id: &UserId,
|
other_user_id: &UserId,
|
||||||
|
methods: Option<Vec<VerificationMethod>>,
|
||||||
) -> KeyVerificationRequestEventContent {
|
) -> KeyVerificationRequestEventContent {
|
||||||
KeyVerificationRequestEventContent::new(
|
KeyVerificationRequestEventContent::new(
|
||||||
format!(
|
format!(
|
||||||
|
@ -163,7 +140,7 @@ impl VerificationRequest {
|
||||||
key verification to verify keys.",
|
key verification to verify keys.",
|
||||||
own_user_id
|
own_user_id
|
||||||
),
|
),
|
||||||
SUPPORTED_METHODS.to_vec(),
|
methods.unwrap_or_else(|| SUPPORTED_METHODS.to_vec()),
|
||||||
own_device_id.into(),
|
own_device_id.into(),
|
||||||
other_user_id.to_owned(),
|
other_user_id.to_owned(),
|
||||||
)
|
)
|
||||||
|
@ -376,6 +353,15 @@ impl VerificationRequest {
|
||||||
|
|
||||||
/// Cancel the verification request
|
/// Cancel the verification request
|
||||||
pub fn cancel(&self) -> Option<OutgoingVerificationRequest> {
|
pub fn cancel(&self) -> Option<OutgoingVerificationRequest> {
|
||||||
|
if let Some(verification) =
|
||||||
|
self.verification_cache.get(self.other_user(), self.flow_id().as_str())
|
||||||
|
{
|
||||||
|
match verification {
|
||||||
|
crate::Verification::SasV1(s) => s.cancel(),
|
||||||
|
crate::Verification::QrV1(q) => q.cancel(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let mut inner = self.inner.lock().unwrap();
|
let mut inner = self.inner.lock().unwrap();
|
||||||
inner.cancel(true, &CancelCode::User);
|
inner.cancel(true, &CancelCode::User);
|
||||||
|
|
||||||
|
@ -398,12 +384,20 @@ impl VerificationRequest {
|
||||||
pub(crate) fn receive_ready(&self, sender: &UserId, content: &ReadyContent) {
|
pub(crate) fn receive_ready(&self, sender: &UserId, content: &ReadyContent) {
|
||||||
let mut inner = self.inner.lock().unwrap();
|
let mut inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
if let InnerRequest::Created(s) = &*inner {
|
match &*inner {
|
||||||
if sender == self.own_user_id() && content.from_device() == self.account.device_id() {
|
InnerRequest::Created(s) => {
|
||||||
*inner = InnerRequest::Passive(s.clone().into_passive(content))
|
|
||||||
} else {
|
|
||||||
*inner = InnerRequest::Ready(s.clone().into_ready(sender, content));
|
*inner = InnerRequest::Ready(s.clone().into_ready(sender, content));
|
||||||
}
|
}
|
||||||
|
InnerRequest::Requested(s) => {
|
||||||
|
if sender == self.own_user_id() && content.from_device() != self.account.device_id()
|
||||||
|
{
|
||||||
|
*inner = InnerRequest::Passive(s.clone().into_passive(content))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InnerRequest::Ready(_)
|
||||||
|
| InnerRequest::Passive(_)
|
||||||
|
| InnerRequest::Done(_)
|
||||||
|
| InnerRequest::Cancelled(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,17 +506,6 @@ impl InnerRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn other_user_id(&self) -> &UserId {
|
|
||||||
match self {
|
|
||||||
InnerRequest::Created(s) => &s.other_user_id,
|
|
||||||
InnerRequest::Requested(s) => &s.other_user_id,
|
|
||||||
InnerRequest::Ready(s) => &s.other_user_id,
|
|
||||||
InnerRequest::Passive(s) => &s.other_user_id,
|
|
||||||
InnerRequest::Done(s) => &s.other_user_id,
|
|
||||||
InnerRequest::Cancelled(s) => &s.other_user_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn accept(&mut self, methods: Vec<VerificationMethod>) -> Option<OutgoingContent> {
|
fn accept(&mut self, methods: Vec<VerificationMethod>) -> Option<OutgoingContent> {
|
||||||
if let InnerRequest::Requested(s) = self {
|
if let InnerRequest::Requested(s) = self {
|
||||||
let (state, content) = s.clone().accept(methods);
|
let (state, content) = s.clone().accept(methods);
|
||||||
|
@ -569,20 +552,6 @@ impl InnerRequest {
|
||||||
InnerRequest::Cancelled(_) => Ok(None),
|
InnerRequest::Cancelled(_) => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_started_sas(
|
|
||||||
&self,
|
|
||||||
content: &StartContent,
|
|
||||||
other_device: ReadOnlyDevice,
|
|
||||||
other_identity: Option<UserIdentities>,
|
|
||||||
we_started: bool,
|
|
||||||
) -> Result<Option<Sas>, OutgoingContent> {
|
|
||||||
if let InnerRequest::Ready(s) = self {
|
|
||||||
Ok(Some(s.to_started_sas(content, other_device, other_identity, we_started)?))
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -638,30 +607,21 @@ impl RequestState<Created> {
|
||||||
store: Arc<dyn CryptoStore>,
|
store: Arc<dyn CryptoStore>,
|
||||||
other_user_id: &UserId,
|
other_user_id: &UserId,
|
||||||
flow_id: &FlowId,
|
flow_id: &FlowId,
|
||||||
|
methods: Option<Vec<VerificationMethod>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let our_methods = methods.unwrap_or_else(|| SUPPORTED_METHODS.to_vec());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
account,
|
account,
|
||||||
other_user_id: other_user_id.to_owned(),
|
other_user_id: other_user_id.to_owned(),
|
||||||
private_cross_signing_identity: private_identity,
|
private_cross_signing_identity: private_identity,
|
||||||
state: Created { our_methods: SUPPORTED_METHODS.to_vec() },
|
state: Created { our_methods },
|
||||||
verification_cache: cache,
|
verification_cache: cache,
|
||||||
store,
|
store,
|
||||||
flow_id: flow_id.to_owned().into(),
|
flow_id: flow_id.to_owned().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_passive(self, content: &ReadyContent) -> RequestState<Passive> {
|
|
||||||
RequestState {
|
|
||||||
account: self.account,
|
|
||||||
flow_id: self.flow_id,
|
|
||||||
verification_cache: self.verification_cache,
|
|
||||||
private_cross_signing_identity: self.private_cross_signing_identity,
|
|
||||||
store: self.store,
|
|
||||||
other_user_id: self.other_user_id,
|
|
||||||
state: Passive { other_device_id: content.from_device().to_owned() },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_ready(self, _sender: &UserId, content: &ReadyContent) -> RequestState<Ready> {
|
fn into_ready(self, _sender: &UserId, content: &ReadyContent) -> RequestState<Ready> {
|
||||||
// TODO check the flow id, and that the methods match what we suggested.
|
// TODO check the flow id, and that the methods match what we suggested.
|
||||||
RequestState {
|
RequestState {
|
||||||
|
@ -720,6 +680,18 @@ impl RequestState<Requested> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_passive(self, content: &ReadyContent) -> RequestState<Passive> {
|
||||||
|
RequestState {
|
||||||
|
account: self.account,
|
||||||
|
flow_id: self.flow_id,
|
||||||
|
verification_cache: self.verification_cache,
|
||||||
|
private_cross_signing_identity: self.private_cross_signing_identity,
|
||||||
|
store: self.store,
|
||||||
|
other_user_id: self.other_user_id,
|
||||||
|
state: Passive { other_device_id: content.from_device().to_owned() },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn accept(self, methods: Vec<VerificationMethod>) -> (RequestState<Ready>, OutgoingContent) {
|
fn accept(self, methods: Vec<VerificationMethod>) -> (RequestState<Ready>, OutgoingContent) {
|
||||||
let state = RequestState {
|
let state = RequestState {
|
||||||
account: self.account.clone(),
|
account: self.account.clone(),
|
||||||
|
@ -776,7 +748,7 @@ impl RequestState<Ready> {
|
||||||
&self,
|
&self,
|
||||||
content: &StartContent<'a>,
|
content: &StartContent<'a>,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
we_started: bool,
|
we_started: bool,
|
||||||
) -> Result<Sas, OutgoingContent> {
|
) -> Result<Sas, OutgoingContent> {
|
||||||
Sas::from_start_event(
|
Sas::from_start_event(
|
||||||
|
@ -827,7 +799,7 @@ impl RequestState<Ready> {
|
||||||
|
|
||||||
let verification = if let Some(identity) = &identites.identity_being_verified {
|
let verification = if let Some(identity) = &identites.identity_being_verified {
|
||||||
match &identity {
|
match &identity {
|
||||||
UserIdentities::Own(i) => {
|
ReadOnlyUserIdentities::Own(i) => {
|
||||||
if let Some(master_key) = i.master_key().get_first_key() {
|
if let Some(master_key) = i.master_key().get_first_key() {
|
||||||
if identites.can_sign_devices().await {
|
if identites.can_sign_devices().await {
|
||||||
if let Some(device_key) =
|
if let Some(device_key) =
|
||||||
|
@ -870,7 +842,7 @@ impl RequestState<Ready> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UserIdentities::Other(i) => {
|
ReadOnlyUserIdentities::Other(i) => {
|
||||||
if let Some(other_master) = i.master_key().get_first_key() {
|
if let Some(other_master) = i.master_key().get_first_key() {
|
||||||
// TODO we can get the master key from the public
|
// TODO we can get the master key from the public
|
||||||
// identity if we don't have the private one and we
|
// identity if we don't have the private one and we
|
||||||
|
@ -1117,20 +1089,21 @@ mod test {
|
||||||
let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
|
let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
|
||||||
let bob_identity = PrivateCrossSigningIdentity::empty(alice_id());
|
let bob_identity = PrivateCrossSigningIdentity::empty(alice_id());
|
||||||
|
|
||||||
let content = VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id());
|
let content =
|
||||||
|
VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id(), None);
|
||||||
|
|
||||||
|
let flow_id = FlowId::InRoom(room_id, event_id);
|
||||||
|
|
||||||
let bob_request = VerificationRequest::new(
|
let bob_request = VerificationRequest::new(
|
||||||
VerificationCache::new(),
|
VerificationCache::new(),
|
||||||
bob,
|
bob,
|
||||||
bob_identity,
|
bob_identity,
|
||||||
bob_store.into(),
|
bob_store.into(),
|
||||||
&room_id,
|
flow_id.clone(),
|
||||||
&event_id,
|
|
||||||
&alice_id(),
|
&alice_id(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let flow_id = FlowId::from((room_id, event_id));
|
|
||||||
|
|
||||||
let alice_request = VerificationRequest::from_request(
|
let alice_request = VerificationRequest::from_request(
|
||||||
VerificationCache::new(),
|
VerificationCache::new(),
|
||||||
alice,
|
alice,
|
||||||
|
@ -1174,20 +1147,20 @@ mod test {
|
||||||
changes.devices.new.push(alice_device.clone());
|
changes.devices.new.push(alice_device.clone());
|
||||||
bob_store.save_changes(changes).await.unwrap();
|
bob_store.save_changes(changes).await.unwrap();
|
||||||
|
|
||||||
let content = VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id());
|
let content =
|
||||||
|
VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id(), None);
|
||||||
|
let flow_id = FlowId::from((room_id, event_id));
|
||||||
|
|
||||||
let bob_request = VerificationRequest::new(
|
let bob_request = VerificationRequest::new(
|
||||||
VerificationCache::new(),
|
VerificationCache::new(),
|
||||||
bob,
|
bob,
|
||||||
bob_identity,
|
bob_identity,
|
||||||
bob_store.into(),
|
bob_store.into(),
|
||||||
&room_id,
|
flow_id.clone(),
|
||||||
&event_id,
|
|
||||||
&alice_id(),
|
&alice_id(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let flow_id = FlowId::from((room_id, event_id));
|
|
||||||
|
|
||||||
let alice_request = VerificationRequest::from_request(
|
let alice_request = VerificationRequest::from_request(
|
||||||
VerificationCache::new(),
|
VerificationCache::new(),
|
||||||
alice,
|
alice,
|
||||||
|
@ -1240,12 +1213,16 @@ mod test {
|
||||||
changes.devices.new.push(alice_device.clone());
|
changes.devices.new.push(alice_device.clone());
|
||||||
bob_store.save_changes(changes).await.unwrap();
|
bob_store.save_changes(changes).await.unwrap();
|
||||||
|
|
||||||
let bob_request = VerificationRequest::new_to_device(
|
let flow_id = FlowId::from("TEST_FLOW_ID".to_owned());
|
||||||
|
|
||||||
|
let bob_request = VerificationRequest::new(
|
||||||
VerificationCache::new(),
|
VerificationCache::new(),
|
||||||
bob,
|
bob,
|
||||||
bob_identity,
|
bob_identity,
|
||||||
bob_store.into(),
|
bob_store.into(),
|
||||||
|
flow_id,
|
||||||
&alice_id(),
|
&alice_id(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let content = bob_request.request_to_device();
|
let content = bob_request.request_to_device();
|
||||||
|
|
|
@ -31,7 +31,7 @@ use tracing::{trace, warn};
|
||||||
|
|
||||||
use super::{FlowId, OutgoingContent};
|
use super::{FlowId, OutgoingContent};
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{ReadOnlyDevice, UserIdentities},
|
identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
|
||||||
utilities::encode,
|
utilities::encode,
|
||||||
verification::event_enums::{MacContent, StartContent},
|
verification::event_enums::{MacContent, StartContent},
|
||||||
ReadOnlyAccount,
|
ReadOnlyAccount,
|
||||||
|
@ -41,7 +41,7 @@ use crate::{
|
||||||
pub struct SasIds {
|
pub struct SasIds {
|
||||||
pub account: ReadOnlyAccount,
|
pub account: ReadOnlyAccount,
|
||||||
pub other_device: ReadOnlyDevice,
|
pub other_device: ReadOnlyDevice,
|
||||||
pub other_identity: Option<UserIdentities>,
|
pub other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the commitment for a accept event from the public key and the
|
/// Calculate the commitment for a accept event from the public key and the
|
||||||
|
@ -182,7 +182,7 @@ pub fn receive_mac_event(
|
||||||
flow_id: &str,
|
flow_id: &str,
|
||||||
sender: &UserId,
|
sender: &UserId,
|
||||||
content: &MacContent,
|
content: &MacContent,
|
||||||
) -> Result<(Vec<ReadOnlyDevice>, Vec<UserIdentities>), CancelCode> {
|
) -> Result<(Vec<ReadOnlyDevice>, Vec<ReadOnlyUserIdentities>), CancelCode> {
|
||||||
let mut verified_devices = Vec::new();
|
let mut verified_devices = Vec::new();
|
||||||
let mut verified_identities = Vec::new();
|
let mut verified_identities = Vec::new();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ use super::{
|
||||||
FlowId,
|
FlowId,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{ReadOnlyDevice, UserIdentities},
|
identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
|
||||||
verification::{
|
verification::{
|
||||||
event_enums::{AnyVerificationContent, OutgoingContent, OwnedAcceptContent, StartContent},
|
event_enums::{AnyVerificationContent, OutgoingContent, OwnedAcceptContent, StartContent},
|
||||||
Cancelled, Done,
|
Cancelled, Done,
|
||||||
|
@ -55,7 +55,7 @@ impl InnerSas {
|
||||||
pub fn start(
|
pub fn start(
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
transaction_id: Option<String>,
|
transaction_id: Option<String>,
|
||||||
) -> (InnerSas, OutgoingContent) {
|
) -> (InnerSas, OutgoingContent) {
|
||||||
let sas = SasState::<Created>::new(account, other_device, other_identity, transaction_id);
|
let sas = SasState::<Created>::new(account, other_device, other_identity, transaction_id);
|
||||||
|
@ -131,7 +131,7 @@ impl InnerSas {
|
||||||
room_id: RoomId,
|
room_id: RoomId,
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
) -> (InnerSas, OutgoingContent) {
|
) -> (InnerSas, OutgoingContent) {
|
||||||
let sas = SasState::<Created>::new_in_room(
|
let sas = SasState::<Created>::new_in_room(
|
||||||
room_id,
|
room_id,
|
||||||
|
@ -149,7 +149,7 @@ impl InnerSas {
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
flow_id: FlowId,
|
flow_id: FlowId,
|
||||||
content: &StartContent,
|
content: &StartContent,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
started_from_request: bool,
|
started_from_request: bool,
|
||||||
) -> Result<InnerSas, OutgoingContent> {
|
) -> Result<InnerSas, OutgoingContent> {
|
||||||
match SasState::<Started>::from_start_event(
|
match SasState::<Started>::from_start_event(
|
||||||
|
@ -204,7 +204,9 @@ impl InnerSas {
|
||||||
InnerSas::WeAccepted(s) => s.cancel(cancelled_by_us, code),
|
InnerSas::WeAccepted(s) => s.cancel(cancelled_by_us, code),
|
||||||
InnerSas::KeyReceived(s) => s.cancel(cancelled_by_us, code),
|
InnerSas::KeyReceived(s) => s.cancel(cancelled_by_us, code),
|
||||||
InnerSas::MacReceived(s) => s.cancel(cancelled_by_us, code),
|
InnerSas::MacReceived(s) => s.cancel(cancelled_by_us, code),
|
||||||
_ => return (self, None),
|
InnerSas::Confirmed(s) => s.cancel(cancelled_by_us, code),
|
||||||
|
InnerSas::WaitingForDone(s) => s.cancel(cancelled_by_us, code),
|
||||||
|
InnerSas::Done(_) | InnerSas::Cancelled(_) => return (self, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let content = sas.as_content();
|
let content = sas.as_content();
|
||||||
|
@ -423,7 +425,7 @@ impl InnerSas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verified_identities(&self) -> Option<Arc<[UserIdentities]>> {
|
pub fn verified_identities(&self) -> Option<Arc<[ReadOnlyUserIdentities]>> {
|
||||||
if let InnerSas::Done(s) = self {
|
if let InnerSas::Done(s) = self {
|
||||||
Some(s.verified_identities())
|
Some(s.verified_identities())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -41,7 +41,7 @@ use super::{
|
||||||
FlowId, IdentitiesBeingVerified, VerificationResult,
|
FlowId, IdentitiesBeingVerified, VerificationResult,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{ReadOnlyDevice, UserIdentities},
|
identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
|
||||||
olm::PrivateCrossSigningIdentity,
|
olm::PrivateCrossSigningIdentity,
|
||||||
requests::{OutgoingVerificationRequest, RoomMessageRequest},
|
requests::{OutgoingVerificationRequest, RoomMessageRequest},
|
||||||
store::{CryptoStore, CryptoStoreError},
|
store::{CryptoStore, CryptoStoreError},
|
||||||
|
@ -151,7 +151,7 @@ impl Sas {
|
||||||
private_identity: PrivateCrossSigningIdentity,
|
private_identity: PrivateCrossSigningIdentity,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
store: Arc<dyn CryptoStore>,
|
store: Arc<dyn CryptoStore>,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
we_started: bool,
|
we_started: bool,
|
||||||
) -> Sas {
|
) -> Sas {
|
||||||
let flow_id = inner_sas.verification_flow_id();
|
let flow_id = inner_sas.verification_flow_id();
|
||||||
|
@ -187,7 +187,7 @@ impl Sas {
|
||||||
private_identity: PrivateCrossSigningIdentity,
|
private_identity: PrivateCrossSigningIdentity,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
store: Arc<dyn CryptoStore>,
|
store: Arc<dyn CryptoStore>,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
transaction_id: Option<String>,
|
transaction_id: Option<String>,
|
||||||
we_started: bool,
|
we_started: bool,
|
||||||
) -> (Sas, OutgoingContent) {
|
) -> (Sas, OutgoingContent) {
|
||||||
|
@ -230,7 +230,7 @@ impl Sas {
|
||||||
private_identity: PrivateCrossSigningIdentity,
|
private_identity: PrivateCrossSigningIdentity,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
store: Arc<dyn CryptoStore>,
|
store: Arc<dyn CryptoStore>,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
we_started: bool,
|
we_started: bool,
|
||||||
) -> (Sas, OutgoingContent) {
|
) -> (Sas, OutgoingContent) {
|
||||||
let (inner, content) = InnerSas::start_in_room(
|
let (inner, content) = InnerSas::start_in_room(
|
||||||
|
@ -273,7 +273,7 @@ impl Sas {
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
private_identity: PrivateCrossSigningIdentity,
|
private_identity: PrivateCrossSigningIdentity,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
started_from_request: bool,
|
started_from_request: bool,
|
||||||
we_started: bool,
|
we_started: bool,
|
||||||
) -> Result<Sas, OutgoingContent> {
|
) -> Result<Sas, OutgoingContent> {
|
||||||
|
@ -503,7 +503,7 @@ impl Sas {
|
||||||
self.inner.lock().unwrap().verified_devices()
|
self.inner.lock().unwrap().verified_devices()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn verified_identities(&self) -> Option<Arc<[UserIdentities]>> {
|
pub(crate) fn verified_identities(&self) -> Option<Arc<[ReadOnlyUserIdentities]>> {
|
||||||
self.inner.lock().unwrap().verified_identities()
|
self.inner.lock().unwrap().verified_identities()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ use super::{
|
||||||
OutgoingContent,
|
OutgoingContent,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{ReadOnlyDevice, UserIdentities},
|
identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
|
||||||
verification::{
|
verification::{
|
||||||
event_enums::{
|
event_enums::{
|
||||||
AcceptContent, DoneContent, KeyContent, MacContent, OwnedAcceptContent,
|
AcceptContent, DoneContent, KeyContent, MacContent, OwnedAcceptContent,
|
||||||
|
@ -277,7 +277,7 @@ pub struct MacReceived {
|
||||||
we_started: bool,
|
we_started: bool,
|
||||||
their_pubkey: String,
|
their_pubkey: String,
|
||||||
verified_devices: Arc<[ReadOnlyDevice]>,
|
verified_devices: Arc<[ReadOnlyDevice]>,
|
||||||
verified_master_keys: Arc<[UserIdentities]>,
|
verified_master_keys: Arc<[ReadOnlyUserIdentities]>,
|
||||||
pub accepted_protocols: Arc<AcceptedProtocols>,
|
pub accepted_protocols: Arc<AcceptedProtocols>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ pub struct MacReceived {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct WaitingForDone {
|
pub struct WaitingForDone {
|
||||||
verified_devices: Arc<[ReadOnlyDevice]>,
|
verified_devices: Arc<[ReadOnlyDevice]>,
|
||||||
verified_master_keys: Arc<[UserIdentities]>,
|
verified_master_keys: Arc<[ReadOnlyUserIdentities]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Clone> SasState<S> {
|
impl<S: Clone> SasState<S> {
|
||||||
|
@ -362,7 +362,7 @@ impl SasState<Created> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
transaction_id: Option<String>,
|
transaction_id: Option<String>,
|
||||||
) -> SasState<Created> {
|
) -> SasState<Created> {
|
||||||
let started_from_request = transaction_id.is_some();
|
let started_from_request = transaction_id.is_some();
|
||||||
|
@ -388,7 +388,7 @@ impl SasState<Created> {
|
||||||
event_id: EventId,
|
event_id: EventId,
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
) -> SasState<Created> {
|
) -> SasState<Created> {
|
||||||
let flow_id = FlowId::InRoom(room_id, event_id);
|
let flow_id = FlowId::InRoom(room_id, event_id);
|
||||||
Self::new_helper(flow_id, account, other_device, other_identity, false)
|
Self::new_helper(flow_id, account, other_device, other_identity, false)
|
||||||
|
@ -398,7 +398,7 @@ impl SasState<Created> {
|
||||||
flow_id: FlowId,
|
flow_id: FlowId,
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
started_from_request: bool,
|
started_from_request: bool,
|
||||||
) -> SasState<Created> {
|
) -> SasState<Created> {
|
||||||
SasState {
|
SasState {
|
||||||
|
@ -497,7 +497,7 @@ impl SasState<Started> {
|
||||||
pub fn from_start_event(
|
pub fn from_start_event(
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<ReadOnlyUserIdentities>,
|
||||||
flow_id: FlowId,
|
flow_id: FlowId,
|
||||||
content: &StartContent,
|
content: &StartContent,
|
||||||
started_from_request: bool,
|
started_from_request: bool,
|
||||||
|
@ -1096,7 +1096,7 @@ impl SasState<Done> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the list of verified identities.
|
/// Get the list of verified identities.
|
||||||
pub fn verified_identities(&self) -> Arc<[UserIdentities]> {
|
pub fn verified_identities(&self) -> Arc<[ReadOnlyUserIdentities]> {
|
||||||
self.state.verified_master_keys.clone()
|
self.state.verified_master_keys.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue