crypto: Split out the Account into a read only portion and one with effects.

master
Damir Jelić 2020-09-29 12:03:41 +02:00
parent e1c220e2f7
commit 84066d4a76
15 changed files with 357 additions and 317 deletions

View File

@ -34,7 +34,7 @@ use serde_json::{json, Value};
use tracing::warn; use tracing::warn;
#[cfg(test)] #[cfg(test)]
use crate::{Account, OlmMachine}; use crate::{OlmMachine, ReadOnlyAccount};
use crate::{ use crate::{
error::{EventError, OlmError, OlmResult, SignatureError}, error::{EventError, OlmError, OlmResult, SignatureError},
@ -419,7 +419,7 @@ impl ReadOnlyDevice {
} }
#[cfg(test)] #[cfg(test)]
pub async fn from_account(account: &Account) -> ReadOnlyDevice { pub async fn from_account(account: &ReadOnlyAccount) -> ReadOnlyDevice {
let device_keys = account.device_keys().await; let device_keys = account.device_keys().await;
ReadOnlyDevice::try_from(&device_keys).unwrap() ReadOnlyDevice::try_from(&device_keys).unwrap()
} }

View File

@ -666,7 +666,7 @@ pub(crate) mod test {
manager::test::{other_key_query, own_key_query}, manager::test::{other_key_query, own_key_query},
Device, ReadOnlyDevice, Device, ReadOnlyDevice,
}, },
olm::Account, olm::ReadOnlyAccount,
store::{MemoryStore, Store}, store::{MemoryStore, Store},
verification::VerificationMachine, verification::VerificationMachine,
}; };
@ -735,7 +735,7 @@ pub(crate) mod test {
assert!(identity.is_device_signed(&second).is_ok()); assert!(identity.is_device_signed(&second).is_ok());
let verification_machine = VerificationMachine::new( let verification_machine = VerificationMachine::new(
Account::new(second.user_id(), second.device_id()), ReadOnlyAccount::new(second.user_id(), second.device_id()),
Store::new( Store::new(
Arc::new(second.user_id().clone()), Arc::new(second.user_id().clone()),
Box::new(MemoryStore::new()), Box::new(MemoryStore::new()),

View File

@ -599,7 +599,7 @@ mod test {
use crate::{ use crate::{
identities::{LocalTrust, ReadOnlyDevice}, identities::{LocalTrust, ReadOnlyDevice},
olm::Account, olm::ReadOnlyAccount,
store::{MemoryStore, Store}, store::{MemoryStore, Store},
}; };
@ -625,12 +625,12 @@ mod test {
room_id!("!test:example.org") room_id!("!test:example.org")
} }
fn account() -> Account { fn account() -> ReadOnlyAccount {
Account::new(&alice_id(), &alice_device_id()) ReadOnlyAccount::new(&alice_id(), &alice_device_id())
} }
fn bob_account() -> Account { fn bob_account() -> ReadOnlyAccount {
Account::new(&bob_id(), &bob_device_id()) ReadOnlyAccount::new(&bob_id(), &bob_device_id())
} }
fn bob_machine() -> KeyRequestMachine { fn bob_machine() -> KeyRequestMachine {

View File

@ -46,8 +46,8 @@ pub use identities::{
Device, LocalTrust, OwnUserIdentity, ReadOnlyDevice, UserDevices, UserIdentities, UserIdentity, Device, LocalTrust, OwnUserIdentity, ReadOnlyDevice, UserDevices, UserIdentities, UserIdentity,
}; };
pub use machine::OlmMachine; pub use machine::OlmMachine;
pub(crate) use olm::Account;
pub use olm::EncryptionSettings; pub use olm::EncryptionSettings;
pub(crate) use olm::ReadOnlyAccount;
pub use requests::{ pub use requests::{
IncomingResponse, KeysQueryRequest, OutgoingRequest, OutgoingRequests, ToDeviceRequest, IncomingResponse, KeysQueryRequest, OutgoingRequest, OutgoingRequests, ToDeviceRequest,
}; };

View File

@ -17,7 +17,6 @@ use std::path::Path;
use std::{collections::BTreeMap, convert::TryInto, mem, sync::Arc, time::Duration}; use std::{collections::BTreeMap, convert::TryInto, mem, sync::Arc, time::Duration};
use dashmap::DashMap; use dashmap::DashMap;
use serde_json::Value;
use tracing::{debug, error, info, instrument, trace, warn}; use tracing::{debug, error, info, instrument, trace, warn};
use matrix_sdk_common::{ use matrix_sdk_common::{
@ -52,7 +51,7 @@ use super::{
key_request::KeyRequestMachine, key_request::KeyRequestMachine,
olm::{ olm::{
Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys, Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys,
InboundGroupSession, OlmMessage, OutboundGroupSession, InboundGroupSession, OlmMessage, OutboundGroupSession, ReadOnlyAccount,
}, },
requests::{IncomingResponse, OutgoingRequest, ToDeviceRequest}, requests::{IncomingResponse, OutgoingRequest, ToDeviceRequest},
store::{CryptoStore, MemoryStore, Result as StoreResult, Store}, store::{CryptoStore, MemoryStore, Result as StoreResult, Store},
@ -113,7 +112,7 @@ impl OlmMachine {
pub fn new(user_id: &UserId, device_id: &DeviceId) -> Self { pub fn new(user_id: &UserId, device_id: &DeviceId) -> Self {
let store: Box<dyn CryptoStore> = Box::new(MemoryStore::new()); let store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let device_id: DeviceIdBox = device_id.into(); let device_id: DeviceIdBox = device_id.into();
let account = Account::new(&user_id, &device_id); let account = ReadOnlyAccount::new(&user_id, &device_id);
OlmMachine::new_helper(user_id, device_id, store, account) OlmMachine::new_helper(user_id, device_id, store, account)
} }
@ -122,7 +121,7 @@ impl OlmMachine {
user_id: &UserId, user_id: &UserId,
device_id: DeviceIdBox, device_id: DeviceIdBox,
store: Box<dyn CryptoStore>, store: Box<dyn CryptoStore>,
account: Account, account: ReadOnlyAccount,
) -> Self { ) -> Self {
let user_id = Arc::new(user_id.clone()); let user_id = Arc::new(user_id.clone());
@ -142,7 +141,10 @@ impl OlmMachine {
OlmMachine { OlmMachine {
user_id, user_id,
device_id, device_id,
account, account: Account {
inner: account,
store: store.clone(),
},
store, store,
outbound_group_sessions, outbound_group_sessions,
verification_machine, verification_machine,
@ -182,7 +184,7 @@ impl OlmMachine {
} }
None => { None => {
debug!("Creating a new account"); debug!("Creating a new account");
Account::new(&user_id, &device_id) ReadOnlyAccount::new(&user_id, &device_id)
} }
}; };
@ -326,7 +328,7 @@ impl OlmMachine {
/// Get the underlying Olm account of the machine. /// Get the underlying Olm account of the machine.
#[cfg(test)] #[cfg(test)]
pub(crate) fn account(&self) -> &Account { pub(crate) fn account(&self) -> &ReadOnlyAccount {
&self.account &self.account
} }
@ -341,26 +343,7 @@ impl OlmMachine {
&self, &self,
response: &upload_keys::Response, response: &upload_keys::Response,
) -> OlmResult<()> { ) -> OlmResult<()> {
if !self.account.shared() { self.account.receive_keys_upload_response(response).await
debug!("Marking account as shared");
}
self.account.mark_as_shared();
let one_time_key_count = response
.one_time_key_counts
.get(&DeviceKeyAlgorithm::SignedCurve25519);
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
debug!(
"Updated uploaded one-time key count {} -> {}, marking keys as published",
self.account.uploaded_key_count(),
count
);
self.account.update_uploaded_key_count(count);
self.account.mark_keys_as_published().await;
self.store.save_account(self.account.clone()).await?;
Ok(())
} }
/// Get the a key claiming request for the user/device pairs that we are /// Get the a key claiming request for the user/device pairs that we are
@ -518,197 +501,6 @@ impl OlmMachine {
Some(assign!(upload_keys::Request::new(), { device_keys, one_time_keys })) Some(assign!(upload_keys::Request::new(), { device_keys, one_time_keys }))
} }
/// Try to decrypt an Olm message.
///
/// This try to decrypt an Olm message using all the sessions we share
/// have with the given sender.
async fn try_decrypt_olm_message(
&self,
sender: &UserId,
sender_key: &str,
message: &OlmMessage,
) -> OlmResult<Option<String>> {
let s = self.store.get_sessions(sender_key).await?;
// We don't have any existing sessions, return early.
let sessions = if let Some(s) = s {
s
} else {
return Ok(None);
};
let mut session_to_save = None;
let mut plaintext = None;
for session in &mut *sessions.lock().await {
let mut matches = false;
// If this is a pre-key message check if it was encrypted for our
// session, if it wasn't decryption will fail so no need to try.
if let OlmMessage::PreKey(m) = &message {
matches = session.matches(sender_key, m.clone()).await?;
if !matches {
continue;
}
}
let ret = session.decrypt(message.clone()).await;
if let Ok(p) = ret {
plaintext = Some(p);
session_to_save = Some(session.clone());
break;
} else {
// Decryption failed with a matching session, the session is
// likely wedged and needs to be rotated.
if matches {
warn!(
"Found a matching Olm session yet decryption failed
for sender {} and sender_key {}",
sender, sender_key
);
return Err(OlmError::SessionWedged);
}
}
}
if let Some(session) = session_to_save {
// Decryption was successful, save the new ratchet state of the
// session that was used to decrypt the message.
trace!("Saved the new session state for {}", sender);
self.store.save_sessions(&[session]).await?;
}
Ok(plaintext)
}
/// Decrypt an Olm message, creating a new Olm session if possible.
async fn decrypt_olm_message(
&self,
sender: &UserId,
sender_key: &str,
message: OlmMessage,
) -> OlmResult<(Raw<AnyToDeviceEvent>, String)> {
// First try to decrypt using an existing session.
let plaintext = if let Some(p) = self
.try_decrypt_olm_message(sender, sender_key, &message)
.await?
{
// Decryption succeeded, de-structure the plaintext out of the
// Option.
p
} else {
// Decryption failed with every known session, let's try to create a
// new session.
let mut session = match &message {
// A new session can only be created using a pre-key message,
// return with an error if it isn't one.
OlmMessage::Message(_) => {
warn!(
"Failed to decrypt a non-pre-key message with all
available sessions {} {}",
sender, sender_key
);
return Err(OlmError::SessionWedged);
}
OlmMessage::PreKey(m) => {
// Create the new session.
let session = match self
.account
.create_inbound_session(sender_key, m.clone())
.await
{
Ok(s) => s,
Err(e) => {
warn!(
"Failed to create a new Olm session for {} {}
from a prekey message: {}",
sender, sender_key, e
);
return Err(OlmError::SessionWedged);
}
};
// Save the account since we remove the one-time key that
// was used to create this session.
self.store.save_account(self.account.clone()).await?;
session
}
};
// Decrypt our message, this shouldn't fail since we're using a
// newly created Session.
let plaintext = session.decrypt(message).await?;
// Save the new ratcheted state of the session.
self.store.save_sessions(&[session]).await?;
plaintext
};
trace!("Successfully decrypted a Olm message: {}", plaintext);
self.parse_decrypted_to_device_event(sender, &plaintext)
}
/// Parse a decrypted Olm message, check that the plaintext and encrypted
/// senders match and that the message was meant for us.
fn parse_decrypted_to_device_event(
&self,
sender: &UserId,
plaintext: &str,
) -> OlmResult<(Raw<AnyToDeviceEvent>, String)> {
// TODO make the errors a bit more specific.
let decrypted_json: Value = serde_json::from_str(&plaintext)?;
let encrytped_sender = decrypted_json
.get("sender")
.cloned()
.ok_or_else(|| EventError::MissingField("sender".to_string()))?;
let encrytped_sender: UserId = serde_json::from_value(encrytped_sender)?;
let recipient = decrypted_json
.get("recipient")
.cloned()
.ok_or_else(|| EventError::MissingField("recipient".to_string()))?;
let recipient: UserId = serde_json::from_value(recipient)?;
let recipient_keys: BTreeMap<DeviceKeyAlgorithm, String> = serde_json::from_value(
decrypted_json
.get("recipient_keys")
.cloned()
.ok_or_else(|| EventError::MissingField("recipient_keys".to_string()))?,
)?;
let keys: BTreeMap<DeviceKeyAlgorithm, String> = serde_json::from_value(
decrypted_json
.get("keys")
.cloned()
.ok_or_else(|| EventError::MissingField("keys".to_string()))?,
)?;
if &recipient != self.user_id() || sender != &encrytped_sender {
return Err(EventError::MissmatchedSender.into());
}
if self.account.identity_keys().ed25519()
!= recipient_keys
.get(&DeviceKeyAlgorithm::Ed25519)
.ok_or(EventError::MissingSigningKey)?
{
return Err(EventError::MissmatchedKeys.into());
}
let signing_key = keys
.get(&DeviceKeyAlgorithm::Ed25519)
.ok_or(EventError::MissingSigningKey)?;
Ok((
Raw::from(serde_json::from_value::<AnyToDeviceEvent>(decrypted_json)?),
signing_key.to_owned(),
))
}
/// Decrypt a to-device event. /// Decrypt a to-device event.
/// ///
/// Returns a decrypted `ToDeviceEvent` if the decryption was successful, /// Returns a decrypted `ToDeviceEvent` if the decryption was successful,
@ -748,6 +540,7 @@ impl OlmMachine {
// Decrypt the OlmMessage and get a Ruma event out of it. // Decrypt the OlmMessage and get a Ruma event out of it.
let (decrypted_event, signing_key) = self let (decrypted_event, signing_key) = self
.account
.decrypt_olm_message(&event.sender, &content.sender_key, message) .decrypt_olm_message(&event.sender, &content.sender_key, message)
.await?; .await?;
@ -1070,11 +863,7 @@ impl OlmMachine {
&self, &self,
key_count: &BTreeMap<DeviceKeyAlgorithm, UInt>, key_count: &BTreeMap<DeviceKeyAlgorithm, UInt>,
) -> StoreResult<()> { ) -> StoreResult<()> {
let one_time_key_count = key_count.get(&DeviceKeyAlgorithm::SignedCurve25519); self.account.update_uploaded_key_count(key_count).await
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
self.account.update_uploaded_key_count(count);
self.store.save_account(self.account.clone()).await
} }
/// Handle a sync response and update the internal state of the Olm machine. /// Handle a sync response and update the internal state of the Olm machine.
@ -1496,7 +1285,7 @@ pub(crate) mod test {
pub(crate) async fn get_prepared_machine() -> (OlmMachine, OneTimeKeys) { pub(crate) async fn get_prepared_machine() -> (OlmMachine, OneTimeKeys) {
let machine = OlmMachine::new(&user_id(), &alice_device_id()); let machine = OlmMachine::new(&user_id(), &alice_device_id());
machine.account.update_uploaded_key_count(0); machine.account.inner.update_uploaded_key_count(0);
let request = machine let request = machine
.keys_for_upload() .keys_for_upload()
.await .await
@ -1699,7 +1488,7 @@ pub(crate) mod test {
#[tokio::test] #[tokio::test]
async fn test_one_time_key_signing() { async fn test_one_time_key_signing() {
let machine = OlmMachine::new(&user_id(), &alice_device_id()); let machine = OlmMachine::new(&user_id(), &alice_device_id());
machine.account.update_uploaded_key_count(49); machine.account.inner.update_uploaded_key_count(49);
let mut one_time_keys = machine.account.signed_one_time_keys().await.unwrap(); let mut one_time_keys = machine.account.signed_one_time_keys().await.unwrap();
let identity_keys = machine.account.identity_keys(); let identity_keys = machine.account.identity_keys();
@ -1720,7 +1509,7 @@ pub(crate) mod test {
#[tokio::test] #[tokio::test]
async fn test_keys_for_upload() { async fn test_keys_for_upload() {
let machine = OlmMachine::new(&user_id(), &alice_device_id()); let machine = OlmMachine::new(&user_id(), &alice_device_id());
machine.account.update_uploaded_key_count(0); machine.account.inner.update_uploaded_key_count(0);
let identity_keys = machine.account.identity_keys(); let identity_keys = machine.account.identity_keys();
let ed25519_key = identity_keys.ed25519(); let ed25519_key = identity_keys.ed25519();

View File

@ -12,51 +12,301 @@
// 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.
#[cfg(test)] use serde::{Deserialize, Serialize};
use matrix_sdk_common::events::{room::encrypted::EncryptedEventContent, EventType}; use serde_json::{json, Value};
use std::{ use std::{
collections::BTreeMap, collections::BTreeMap,
convert::{TryFrom, TryInto}, convert::{TryFrom, TryInto},
fmt, fmt,
ops::Deref,
sync::{ sync::{
atomic::{AtomicBool, AtomicI64, Ordering}, atomic::{AtomicBool, AtomicI64, Ordering},
Arc, Arc,
}, },
}; };
use tracing::{debug, trace, warn};
#[cfg(test)]
use matrix_sdk_common::events::{room::encrypted::EncryptedEventContent, EventType};
use matrix_sdk_common::{ use matrix_sdk_common::{
api::r0::keys::{OneTimeKey, SignedKey}, api::r0::keys::{upload_keys, OneTimeKey, SignedKey},
encryption::DeviceKeys, encryption::DeviceKeys,
events::AnyToDeviceEvent,
identifiers::{ identifiers::{
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, RoomId, DeviceId, DeviceIdBox, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, RoomId,
UserId, UserId,
}, },
instant::Instant, instant::Instant,
js_int::UInt,
locks::Mutex, locks::Mutex,
Raw,
}; };
use olm_rs::{ use olm_rs::{
account::{OlmAccount, OneTimeKeys}, account::{IdentityKeys, OlmAccount, OneTimeKeys},
errors::{OlmAccountError, OlmSessionError}, errors::{OlmAccountError, OlmSessionError},
session::{OlmMessage, PreKeyMessage},
PicklingMode, PicklingMode,
}; };
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
pub use olm_rs::{ use crate::{
account::IdentityKeys, error::{EventError, OlmResult, SessionCreationError},
session::{OlmMessage, PreKeyMessage}, identities::ReadOnlyDevice,
utility::OlmUtility, store::{Result as StoreResult, Store},
OlmError,
}; };
use super::{EncryptionSettings, InboundGroupSession, OutboundGroupSession, Session}; use super::{EncryptionSettings, InboundGroupSession, OutboundGroupSession, Session};
use crate::{error::SessionCreationError, identities::ReadOnlyDevice};
#[derive(Clone)]
pub struct Account {
pub(crate) inner: ReadOnlyAccount,
pub(crate) store: Store,
}
impl Deref for Account {
type Target = ReadOnlyAccount;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Account {
pub async fn update_uploaded_key_count(
&self,
key_count: &BTreeMap<DeviceKeyAlgorithm, UInt>,
) -> StoreResult<()> {
let one_time_key_count = key_count.get(&DeviceKeyAlgorithm::SignedCurve25519);
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
self.inner.update_uploaded_key_count(count);
self.store.save_account(self.inner.clone()).await
}
pub async fn receive_keys_upload_response(
&self,
response: &upload_keys::Response,
) -> OlmResult<()> {
if !self.inner.shared() {
debug!("Marking account as shared");
}
self.inner.mark_as_shared();
let one_time_key_count = response
.one_time_key_counts
.get(&DeviceKeyAlgorithm::SignedCurve25519);
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
debug!(
"Updated uploaded one-time key count {} -> {}, marking keys as published",
self.inner.uploaded_key_count(),
count
);
self.inner.update_uploaded_key_count(count);
self.inner.mark_keys_as_published().await;
self.store.save_account(self.inner.clone()).await?;
Ok(())
}
/// Try to decrypt an Olm message.
///
/// This try to decrypt an Olm message using all the sessions we share
/// have with the given sender.
async fn try_decrypt_olm_message(
&self,
sender: &UserId,
sender_key: &str,
message: &OlmMessage,
) -> OlmResult<Option<String>> {
let s = self.store.get_sessions(sender_key).await?;
// We don't have any existing sessions, return early.
let sessions = if let Some(s) = s {
s
} else {
return Ok(None);
};
let mut session_to_save = None;
let mut plaintext = None;
for session in &mut *sessions.lock().await {
let mut matches = false;
// If this is a pre-key message check if it was encrypted for our
// session, if it wasn't decryption will fail so no need to try.
if let OlmMessage::PreKey(m) = &message {
matches = session.matches(sender_key, m.clone()).await?;
if !matches {
continue;
}
}
let ret = session.decrypt(message.clone()).await;
if let Ok(p) = ret {
plaintext = Some(p);
session_to_save = Some(session.clone());
break;
} else {
// Decryption failed with a matching session, the session is
// likely wedged and needs to be rotated.
if matches {
warn!(
"Found a matching Olm session yet decryption failed
for sender {} and sender_key {}",
sender, sender_key
);
return Err(OlmError::SessionWedged);
}
}
}
if let Some(session) = session_to_save {
// Decryption was successful, save the new ratchet state of the
// session that was used to decrypt the message.
trace!("Saved the new session state for {}", sender);
self.store.save_sessions(&[session]).await?;
}
Ok(plaintext)
}
/// Decrypt an Olm message, creating a new Olm session if possible.
pub async fn decrypt_olm_message(
&self,
sender: &UserId,
sender_key: &str,
message: OlmMessage,
) -> OlmResult<(Raw<AnyToDeviceEvent>, String)> {
// First try to decrypt using an existing session.
let plaintext = if let Some(p) = self
.try_decrypt_olm_message(sender, sender_key, &message)
.await?
{
// Decryption succeeded, de-structure the plaintext out of the
// Option.
p
} else {
// Decryption failed with every known session, let's try to create a
// new session.
let mut session = match &message {
// A new session can only be created using a pre-key message,
// return with an error if it isn't one.
OlmMessage::Message(_) => {
warn!(
"Failed to decrypt a non-pre-key message with all
available sessions {} {}",
sender, sender_key
);
return Err(OlmError::SessionWedged);
}
OlmMessage::PreKey(m) => {
// Create the new session.
let session = match self
.inner
.create_inbound_session(sender_key, m.clone())
.await
{
Ok(s) => s,
Err(e) => {
warn!(
"Failed to create a new Olm session for {} {}
from a prekey message: {}",
sender, sender_key, e
);
return Err(OlmError::SessionWedged);
}
};
// Save the account since we remove the one-time key that
// was used to create this session.
self.store.save_account(self.inner.clone()).await?;
session
}
};
// Decrypt our message, this shouldn't fail since we're using a
// newly created Session.
let plaintext = session.decrypt(message).await?;
// Save the new ratcheted state of the session.
self.store.save_sessions(&[session]).await?;
plaintext
};
trace!("Successfully decrypted a Olm message: {}", plaintext);
self.parse_decrypted_to_device_event(sender, &plaintext)
}
/// Parse a decrypted Olm message, check that the plaintext and encrypted
/// senders match and that the message was meant for us.
fn parse_decrypted_to_device_event(
&self,
sender: &UserId,
plaintext: &str,
) -> OlmResult<(Raw<AnyToDeviceEvent>, String)> {
// TODO make the errors a bit more specific.
let decrypted_json: Value = serde_json::from_str(&plaintext)?;
let encrytped_sender = decrypted_json
.get("sender")
.cloned()
.ok_or_else(|| EventError::MissingField("sender".to_string()))?;
let encrytped_sender: UserId = serde_json::from_value(encrytped_sender)?;
let recipient = decrypted_json
.get("recipient")
.cloned()
.ok_or_else(|| EventError::MissingField("recipient".to_string()))?;
let recipient: UserId = serde_json::from_value(recipient)?;
let recipient_keys: BTreeMap<DeviceKeyAlgorithm, String> = serde_json::from_value(
decrypted_json
.get("recipient_keys")
.cloned()
.ok_or_else(|| EventError::MissingField("recipient_keys".to_string()))?,
)?;
let keys: BTreeMap<DeviceKeyAlgorithm, String> = serde_json::from_value(
decrypted_json
.get("keys")
.cloned()
.ok_or_else(|| EventError::MissingField("keys".to_string()))?,
)?;
if &recipient != self.user_id() || sender != &encrytped_sender {
return Err(EventError::MissmatchedSender.into());
}
if self.inner.identity_keys().ed25519()
!= recipient_keys
.get(&DeviceKeyAlgorithm::Ed25519)
.ok_or(EventError::MissingSigningKey)?
{
return Err(EventError::MissmatchedKeys.into());
}
let signing_key = keys
.get(&DeviceKeyAlgorithm::Ed25519)
.ok_or(EventError::MissingSigningKey)?;
Ok((
Raw::from(serde_json::from_value::<AnyToDeviceEvent>(decrypted_json)?),
signing_key.to_owned(),
))
}
}
/// Account holding identity keys for which sessions can be created. /// Account holding identity keys for which sessions can be created.
/// ///
/// An account is the central identity for encrypted communication between two /// An account is the central identity for encrypted communication between two
/// devices. /// devices.
#[derive(Clone)] #[derive(Clone)]
pub struct Account { pub struct ReadOnlyAccount {
pub(crate) user_id: Arc<UserId>, pub(crate) user_id: Arc<UserId>,
pub(crate) device_id: Arc<Box<DeviceId>>, pub(crate) device_id: Arc<Box<DeviceId>>,
inner: Arc<Mutex<OlmAccount>>, inner: Arc<Mutex<OlmAccount>>,
@ -106,7 +356,7 @@ pub struct PickledAccount {
} }
#[cfg(not(tarpaulin_include))] #[cfg(not(tarpaulin_include))]
impl fmt::Debug for Account { impl fmt::Debug for ReadOnlyAccount {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Account") f.debug_struct("Account")
.field("identity_keys", self.identity_keys()) .field("identity_keys", self.identity_keys())
@ -115,7 +365,7 @@ impl fmt::Debug for Account {
} }
} }
impl Account { impl ReadOnlyAccount {
const ALGORITHMS: &'static [&'static EventEncryptionAlgorithm] = &[ const ALGORITHMS: &'static [&'static EventEncryptionAlgorithm] = &[
&EventEncryptionAlgorithm::OlmV1Curve25519AesSha2, &EventEncryptionAlgorithm::OlmV1Curve25519AesSha2,
&EventEncryptionAlgorithm::MegolmV1AesSha2, &EventEncryptionAlgorithm::MegolmV1AesSha2,
@ -127,7 +377,7 @@ impl Account {
let account = OlmAccount::new(); let account = OlmAccount::new();
let identity_keys = account.parsed_identity_keys(); let identity_keys = account.parsed_identity_keys();
Account { Self {
user_id: Arc::new(user_id.to_owned()), user_id: Arc::new(user_id.to_owned()),
device_id: Arc::new(device_id.into()), device_id: Arc::new(device_id.into()),
inner: Arc::new(Mutex::new(account)), inner: Arc::new(Mutex::new(account)),
@ -307,7 +557,7 @@ impl Account {
let account = OlmAccount::unpickle(pickle.pickle.0, pickle_mode)?; let account = OlmAccount::unpickle(pickle.pickle.0, pickle_mode)?;
let identity_keys = account.parsed_identity_keys(); let identity_keys = account.parsed_identity_keys();
Ok(Account { Ok(Self {
user_id: Arc::new(pickle.user_id), user_id: Arc::new(pickle.user_id),
device_id: Arc::new(pickle.device_id), device_id: Arc::new(pickle.device_id),
inner: Arc::new(Mutex::new(account)), inner: Arc::new(Mutex::new(account)),
@ -336,7 +586,7 @@ impl Account {
let device_keys = json!({ let device_keys = json!({
"user_id": (*self.user_id).clone(), "user_id": (*self.user_id).clone(),
"device_id": (*self.device_id).clone(), "device_id": (*self.device_id).clone(),
"algorithms": Account::ALGORITHMS, "algorithms": Self::ALGORITHMS,
"keys": keys, "keys": keys,
}); });
@ -621,7 +871,7 @@ impl Account {
} }
#[cfg(test)] #[cfg(test)]
pub(crate) async fn create_session_for(&self, other: &Account) -> (Session, Session) { pub(crate) async fn create_session_for(&self, other: &ReadOnlyAccount) -> (Session, Session) {
other.generate_one_time_keys_helper(1).await; other.generate_one_time_keys_helper(1).await;
let one_time = other.signed_one_time_keys().await.unwrap(); let one_time = other.signed_one_time_keys().await.unwrap();
@ -676,7 +926,7 @@ impl Account {
} }
} }
impl PartialEq for Account { impl PartialEq for ReadOnlyAccount {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.identity_keys() == other.identity_keys() && self.shared() == other.shared() self.identity_keys() == other.identity_keys() && self.shared() == other.shared()
} }

View File

@ -135,7 +135,7 @@ mod test {
}; };
use super::EncryptionSettings; use super::EncryptionSettings;
use crate::Account; use crate::ReadOnlyAccount;
#[tokio::test] #[tokio::test]
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
@ -145,7 +145,7 @@ mod test {
..Default::default() ..Default::default()
}; };
let account = Account::new(&user_id!("@alice:example.org"), "DEVICEID".into()); let account = ReadOnlyAccount::new(&user_id!("@alice:example.org"), "DEVICEID".into());
let (session, _) = account let (session, _) = account
.create_group_session_pair(&room_id!("!test_room:example.org"), settings, [].iter()) .create_group_session_pair(&room_id!("!test_room:example.org"), settings, [].iter())
.await .await

View File

@ -22,20 +22,21 @@ mod group_sessions;
mod session; mod session;
mod utility; mod utility;
pub use account::{Account, AccountPickle, IdentityKeys, PickledAccount}; pub(crate) use account::Account;
pub use account::{AccountPickle, PickledAccount, ReadOnlyAccount};
pub use group_sessions::{ pub use group_sessions::{
EncryptionSettings, ExportedRoomKey, InboundGroupSession, InboundGroupSessionPickle, EncryptionSettings, ExportedRoomKey, InboundGroupSession, InboundGroupSessionPickle,
PickledInboundGroupSession, PickledInboundGroupSession,
}; };
pub(crate) use group_sessions::{GroupSessionKey, OutboundGroupSession}; pub(crate) use group_sessions::{GroupSessionKey, OutboundGroupSession};
pub use olm_rs::PicklingMode; pub use olm_rs::{account::IdentityKeys, PicklingMode};
pub(crate) use session::OlmMessage; pub(crate) use session::OlmMessage;
pub use session::{PickledSession, Session, SessionPickle}; pub use session::{PickledSession, Session, SessionPickle};
pub(crate) use utility::Utility; pub(crate) use utility::Utility;
#[cfg(test)] #[cfg(test)]
pub(crate) mod test { pub(crate) mod test {
use crate::olm::{Account, InboundGroupSession, Session}; use crate::olm::{InboundGroupSession, ReadOnlyAccount, Session};
use matrix_sdk_common::{ use matrix_sdk_common::{
api::r0::keys::SignedKey, api::r0::keys::SignedKey,
events::forwarded_room_key::ForwardedRoomKeyEventContent, events::forwarded_room_key::ForwardedRoomKeyEventContent,
@ -60,9 +61,9 @@ pub(crate) mod test {
"BOBDEVICE".into() "BOBDEVICE".into()
} }
pub(crate) async fn get_account_and_session() -> (Account, Session) { pub(crate) async fn get_account_and_session() -> (ReadOnlyAccount, Session) {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let bob = Account::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
bob.generate_one_time_keys_helper(1).await; bob.generate_one_time_keys_helper(1).await;
let one_time_key = bob let one_time_key = bob
@ -89,7 +90,7 @@ pub(crate) mod test {
#[test] #[test]
fn account_creation() { fn account_creation() {
let account = Account::new(&alice_id(), &alice_device_id()); let account = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let identyty_keys = account.identity_keys(); let identyty_keys = account.identity_keys();
assert!(!account.shared()); assert!(!account.shared());
@ -110,7 +111,7 @@ pub(crate) mod test {
#[tokio::test] #[tokio::test]
async fn one_time_keys_creation() { async fn one_time_keys_creation() {
let account = Account::new(&alice_id(), &alice_device_id()); let account = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let one_time_keys = account.one_time_keys().await; let one_time_keys = account.one_time_keys().await;
assert!(one_time_keys.curve25519().is_empty()); assert!(one_time_keys.curve25519().is_empty());
@ -137,8 +138,8 @@ pub(crate) mod test {
#[tokio::test] #[tokio::test]
async fn session_creation() { async fn session_creation() {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let bob = Account::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let alice_keys = alice.identity_keys(); let alice_keys = alice.identity_keys();
alice.generate_one_time_keys_helper(1).await; alice.generate_one_time_keys_helper(1).await;
let one_time_keys = alice.one_time_keys().await; let one_time_keys = alice.one_time_keys().await;
@ -190,7 +191,7 @@ pub(crate) mod test {
#[tokio::test] #[tokio::test]
async fn group_session_creation() { async fn group_session_creation() {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let room_id = room_id!("!test:localhost"); let room_id = room_id!("!test:localhost");
let (outbound, _) = alice let (outbound, _) = alice
@ -226,7 +227,7 @@ pub(crate) mod test {
#[tokio::test] #[tokio::test]
async fn group_session_export() { async fn group_session_export() {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let room_id = room_id!("!test:localhost"); let room_id = room_id!("!test:localhost");
let (_, inbound) = alice let (_, inbound) = alice

View File

@ -23,7 +23,7 @@ use matrix_sdk_common_macros::async_trait;
use super::{ use super::{
caches::{DeviceStore, GroupSessionStore, ReadOnlyUserDevices, SessionStore}, caches::{DeviceStore, GroupSessionStore, ReadOnlyUserDevices, SessionStore},
Account, CryptoStore, InboundGroupSession, Result, Session, CryptoStore, InboundGroupSession, ReadOnlyAccount, Result, Session,
}; };
use crate::identities::{ReadOnlyDevice, UserIdentities}; use crate::identities::{ReadOnlyDevice, UserIdentities};
@ -62,11 +62,11 @@ impl MemoryStore {
#[async_trait] #[async_trait]
impl CryptoStore for MemoryStore { impl CryptoStore for MemoryStore {
async fn load_account(&self) -> Result<Option<Account>> { async fn load_account(&self) -> Result<Option<ReadOnlyAccount>> {
Ok(None) Ok(None)
} }
async fn save_account(&self, _: Account) -> Result<()> { async fn save_account(&self, _: ReadOnlyAccount) -> Result<()> {
Ok(()) Ok(())
} }

View File

@ -72,7 +72,7 @@ use matrix_sdk_common_macros::send_sync;
use super::{ use super::{
identities::{OwnUserIdentity, ReadOnlyDevice, UserIdentities}, identities::{OwnUserIdentity, ReadOnlyDevice, UserIdentities},
olm::{Account, InboundGroupSession, Session}, olm::{InboundGroupSession, ReadOnlyAccount, Session},
}; };
use crate::error::SessionUnpicklingError; use crate::error::SessionUnpicklingError;
@ -216,14 +216,14 @@ pub enum CryptoStoreError {
#[cfg_attr(not(target_arch = "wasm32"), send_sync)] #[cfg_attr(not(target_arch = "wasm32"), send_sync)]
pub trait CryptoStore: Debug { pub trait CryptoStore: Debug {
/// Load an account that was previously stored. /// Load an account that was previously stored.
async fn load_account(&self) -> Result<Option<Account>>; async fn load_account(&self) -> Result<Option<ReadOnlyAccount>>;
/// Save the given account in the store. /// Save the given account in the store.
/// ///
/// # Arguments /// # Arguments
/// ///
/// * `account` - The account that should be stored. /// * `account` - The account that should be stored.
async fn save_account(&self, account: Account) -> Result<()>; async fn save_account(&self, account: ReadOnlyAccount) -> Result<()>;
/// Save the given sessions in the store. /// Save the given sessions in the store.
/// ///

View File

@ -41,9 +41,9 @@ use super::{
use crate::{ use crate::{
identities::{LocalTrust, OwnUserIdentity, ReadOnlyDevice, UserIdentities, UserIdentity}, identities::{LocalTrust, OwnUserIdentity, ReadOnlyDevice, UserIdentities, UserIdentity},
olm::{ olm::{
Account, AccountPickle, IdentityKeys, InboundGroupSession, InboundGroupSessionPickle, AccountPickle, IdentityKeys, InboundGroupSession, InboundGroupSessionPickle,
PickledAccount, PickledInboundGroupSession, PickledSession, PicklingMode, Session, PickledAccount, PickledInboundGroupSession, PickledSession, PicklingMode, ReadOnlyAccount,
SessionPickle, Session, SessionPickle,
}, },
}; };
@ -1167,7 +1167,7 @@ impl SqliteStore {
#[async_trait] #[async_trait]
impl CryptoStore for SqliteStore { impl CryptoStore for SqliteStore {
async fn load_account(&self) -> Result<Option<Account>> { async fn load_account(&self) -> Result<Option<ReadOnlyAccount>> {
let mut connection = self.connection.lock().await; let mut connection = self.connection.lock().await;
let row: Option<(i64, String, bool, i64)> = query_as( let row: Option<(i64, String, bool, i64)> = query_as(
@ -1188,7 +1188,7 @@ impl CryptoStore for SqliteStore {
uploaded_signed_key_count: uploaded_key_count, uploaded_signed_key_count: uploaded_key_count,
}; };
let account = Account::from_pickle(pickle, self.get_pickle_mode())?; let account = ReadOnlyAccount::from_pickle(pickle, self.get_pickle_mode())?;
*self.account_info.lock().unwrap() = Some(AccountInfo { *self.account_info.lock().unwrap() = Some(AccountInfo {
account_id: id, account_id: id,
@ -1209,7 +1209,7 @@ impl CryptoStore for SqliteStore {
Ok(result) Ok(result)
} }
async fn save_account(&self, account: Account) -> Result<()> { async fn save_account(&self, account: ReadOnlyAccount) -> Result<()> {
let pickle = account.pickle(self.get_pickle_mode()).await; let pickle = account.pickle(self.get_pickle_mode()).await;
let mut connection = self.connection.lock().await; let mut connection = self.connection.lock().await;
@ -1456,7 +1456,7 @@ mod test {
device::test::get_device, device::test::get_device,
user::test::{get_other_identity, get_own_identity}, user::test::{get_other_identity, get_own_identity},
}, },
olm::{Account, GroupSessionKey, InboundGroupSession, Session}, olm::{GroupSessionKey, InboundGroupSession, ReadOnlyAccount, Session},
}; };
use matrix_sdk_common::{ use matrix_sdk_common::{
api::r0::keys::SignedKey, api::r0::keys::SignedKey,
@ -1506,7 +1506,7 @@ mod test {
(store, tmpdir) (store, tmpdir)
} }
async fn get_loaded_store() -> (Account, SqliteStore, tempfile::TempDir) { async fn get_loaded_store() -> (ReadOnlyAccount, SqliteStore, tempfile::TempDir) {
let (store, dir) = get_store(None).await; let (store, dir) = get_store(None).await;
let account = get_account(); let account = get_account();
store store
@ -1517,13 +1517,13 @@ mod test {
(account, store, dir) (account, store, dir)
} }
fn get_account() -> Account { fn get_account() -> ReadOnlyAccount {
Account::new(&alice_id(), &alice_device_id()) ReadOnlyAccount::new(&alice_id(), &alice_device_id())
} }
async fn get_account_and_session() -> (Account, Session) { async fn get_account_and_session() -> (ReadOnlyAccount, Session) {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let bob = Account::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
bob.generate_one_time_keys_helper(1).await; bob.generate_one_time_keys_helper(1).await;
let one_time_key = bob let one_time_key = bob
@ -1870,7 +1870,7 @@ mod test {
.await .await
.expect("Can't create store"); .expect("Can't create store");
let account = Account::new(&user_id, &device_id); let account = ReadOnlyAccount::new(&user_id, &device_id);
store store
.save_account(account.clone()) .save_account(account.clone())

View File

@ -28,19 +28,19 @@ use super::sas::{content_to_request, Sas};
use crate::{ use crate::{
requests::{OutgoingRequest, ToDeviceRequest}, requests::{OutgoingRequest, ToDeviceRequest},
store::{CryptoStoreError, Store}, store::{CryptoStoreError, Store},
Account, ReadOnlyDevice, ReadOnlyAccount, ReadOnlyDevice,
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct VerificationMachine { pub struct VerificationMachine {
account: Account, account: ReadOnlyAccount,
pub(crate) store: Store, pub(crate) store: Store,
verifications: Arc<DashMap<String, Sas>>, verifications: Arc<DashMap<String, Sas>>,
outgoing_to_device_messages: Arc<DashMap<Uuid, OutgoingRequest>>, outgoing_to_device_messages: Arc<DashMap<Uuid, OutgoingRequest>>,
} }
impl VerificationMachine { impl VerificationMachine {
pub(crate) fn new(account: Account, store: Store) -> Self { pub(crate) fn new(account: ReadOnlyAccount, store: Store) -> Self {
Self { Self {
account, account,
store, store,
@ -235,7 +235,7 @@ mod test {
requests::OutgoingRequests, requests::OutgoingRequests,
store::{CryptoStore, MemoryStore, Store}, store::{CryptoStore, MemoryStore, Store},
verification::test::{get_content_from_request, wrap_any_to_device_content}, verification::test::{get_content_from_request, wrap_any_to_device_content},
Account, ReadOnlyDevice, ReadOnlyAccount, ReadOnlyDevice,
}; };
fn alice_id() -> UserId { fn alice_id() -> UserId {
@ -255,8 +255,8 @@ mod test {
} }
async fn setup_verification_machine() -> (VerificationMachine, Sas) { async fn setup_verification_machine() -> (VerificationMachine, Sas) {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let bob = Account::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let store = MemoryStore::new(); let store = MemoryStore::new();
let bob_store = Store::new(Arc::new(bob_id()), Box::new(MemoryStore::new())); let bob_store = Store::new(Arc::new(bob_id()), Box::new(MemoryStore::new()));
@ -285,7 +285,7 @@ mod test {
#[test] #[test]
fn create() { fn create() {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let user_id = Arc::new(alice_id()); let user_id = Arc::new(alice_id());
let store = MemoryStore::new(); let store = MemoryStore::new();
let _ = VerificationMachine::new(alice, Store::new(user_id, Box::new(store))); let _ = VerificationMachine::new(alice, Store::new(user_id, Box::new(store)));

View File

@ -30,12 +30,12 @@ use matrix_sdk_common::{
use crate::{ use crate::{
identities::{ReadOnlyDevice, UserIdentities}, identities::{ReadOnlyDevice, UserIdentities},
Account, ToDeviceRequest, ReadOnlyAccount, ToDeviceRequest,
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SasIds { pub struct SasIds {
pub account: Account, pub account: ReadOnlyAccount,
pub other_device: ReadOnlyDevice, pub other_device: ReadOnlyDevice,
pub other_identity: Option<UserIdentities>, pub other_identity: Option<UserIdentities>,
} }

View File

@ -35,7 +35,7 @@ use matrix_sdk_common::{
use crate::{ use crate::{
identities::{LocalTrust, ReadOnlyDevice, UserIdentities}, identities::{LocalTrust, ReadOnlyDevice, UserIdentities},
store::{CryptoStoreError, Store}, store::{CryptoStoreError, Store},
Account, ToDeviceRequest, ReadOnlyAccount, ToDeviceRequest,
}; };
pub use helpers::content_to_request; pub use helpers::content_to_request;
@ -48,7 +48,7 @@ use sas_state::{
pub struct Sas { pub struct Sas {
inner: Arc<Mutex<InnerSas>>, inner: Arc<Mutex<InnerSas>>,
store: Store, store: Store,
account: Account, account: ReadOnlyAccount,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
other_identity: Option<UserIdentities>, other_identity: Option<UserIdentities>,
flow_id: Arc<String>, flow_id: Arc<String>,
@ -102,7 +102,7 @@ impl Sas {
/// Returns the new `Sas` object and a `StartEventContent` that needs to be /// Returns the new `Sas` object and a `StartEventContent` that needs to be
/// sent out through the server to the other device. /// sent out through the server to the other device.
pub(crate) fn start( pub(crate) fn start(
account: Account, account: ReadOnlyAccount,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
store: Store, store: Store,
other_identity: Option<UserIdentities>, other_identity: Option<UserIdentities>,
@ -137,7 +137,7 @@ impl Sas {
/// * `event` - The m.key.verification.start event that was sent to us by /// * `event` - The m.key.verification.start event that was sent to us by
/// the other side. /// the other side.
pub(crate) fn from_start_event( pub(crate) fn from_start_event(
account: Account, account: ReadOnlyAccount,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
store: Store, store: Store,
event: &ToDeviceEvent<StartEventContent>, event: &ToDeviceEvent<StartEventContent>,
@ -426,7 +426,7 @@ enum InnerSas {
impl InnerSas { impl InnerSas {
fn start( fn start(
account: Account, account: ReadOnlyAccount,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
other_identity: Option<UserIdentities>, other_identity: Option<UserIdentities>,
) -> (InnerSas, StartEventContent) { ) -> (InnerSas, StartEventContent) {
@ -436,7 +436,7 @@ impl InnerSas {
} }
fn from_start_event( fn from_start_event(
account: Account, account: ReadOnlyAccount,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
event: &ToDeviceEvent<StartEventContent>, event: &ToDeviceEvent<StartEventContent>,
other_identity: Option<UserIdentities>, other_identity: Option<UserIdentities>,
@ -656,7 +656,7 @@ mod test {
use crate::{ use crate::{
store::{MemoryStore, Store}, store::{MemoryStore, Store},
verification::test::{get_content_from_request, wrap_any_to_device_content}, verification::test::{get_content_from_request, wrap_any_to_device_content},
Account, ReadOnlyDevice, ReadOnlyAccount, ReadOnlyDevice,
}; };
use super::{Accepted, Created, Sas, SasState, Started}; use super::{Accepted, Created, Sas, SasState, Started};
@ -685,10 +685,10 @@ mod test {
} }
async fn get_sas_pair() -> (SasState<Created>, SasState<Started>) { async fn get_sas_pair() -> (SasState<Created>, SasState<Started>) {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let alice_device = ReadOnlyDevice::from_account(&alice).await; let alice_device = ReadOnlyDevice::from_account(&alice).await;
let bob = Account::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let bob_device = ReadOnlyDevice::from_account(&bob).await; let bob_device = ReadOnlyDevice::from_account(&bob).await;
let alice_sas = SasState::<Created>::new(alice.clone(), bob_device, None); let alice_sas = SasState::<Created>::new(alice.clone(), bob_device, None);
@ -770,10 +770,10 @@ mod test {
#[tokio::test] #[tokio::test]
async fn sas_wrapper_full() { async fn sas_wrapper_full() {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let alice_device = ReadOnlyDevice::from_account(&alice).await; let alice_device = ReadOnlyDevice::from_account(&alice).await;
let bob = Account::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let bob_device = ReadOnlyDevice::from_account(&bob).await; let bob_device = ReadOnlyDevice::from_account(&bob).await;
let alice_store = Store::new(Arc::new(alice_id()), Box::new(MemoryStore::new())); let alice_store = Store::new(Arc::new(alice_id()), Box::new(MemoryStore::new()));

View File

@ -45,7 +45,7 @@ use super::helpers::{get_decimal, get_emoji, get_mac_content, receive_mac_event,
use crate::{ use crate::{
identities::{ReadOnlyDevice, UserIdentities}, identities::{ReadOnlyDevice, UserIdentities},
Account, ReadOnlyAccount,
}; };
const KEY_AGREEMENT_PROTOCOLS: &[KeyAgreementProtocol] = const KEY_AGREEMENT_PROTOCOLS: &[KeyAgreementProtocol] =
@ -290,7 +290,7 @@ impl SasState<Created> {
/// ///
/// * `other_device` - The other device which we are going to verify. /// * `other_device` - The other device which we are going to verify.
pub fn new( pub fn new(
account: Account, account: ReadOnlyAccount,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
other_identity: Option<UserIdentities>, other_identity: Option<UserIdentities>,
) -> SasState<Created> { ) -> SasState<Created> {
@ -387,7 +387,7 @@ impl SasState<Started> {
/// * `event` - The m.key.verification.start event that was sent to us by /// * `event` - The m.key.verification.start event that was sent to us by
/// the other side. /// the other side.
pub fn from_start_event( pub fn from_start_event(
account: Account, account: ReadOnlyAccount,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
event: &ToDeviceEvent<StartEventContent>, event: &ToDeviceEvent<StartEventContent>,
other_identity: Option<UserIdentities>, other_identity: Option<UserIdentities>,
@ -843,7 +843,7 @@ impl SasState<Canceled> {
mod test { mod test {
use std::convert::TryFrom; use std::convert::TryFrom;
use crate::{Account, ReadOnlyDevice}; use crate::{ReadOnlyAccount, ReadOnlyDevice};
use matrix_sdk_common::{ use matrix_sdk_common::{
events::{ events::{
key::verification::{ key::verification::{
@ -881,10 +881,10 @@ mod test {
} }
async fn get_sas_pair() -> (SasState<Created>, SasState<Started>) { async fn get_sas_pair() -> (SasState<Created>, SasState<Started>) {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let alice_device = ReadOnlyDevice::from_account(&alice).await; let alice_device = ReadOnlyDevice::from_account(&alice).await;
let bob = Account::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let bob_device = ReadOnlyDevice::from_account(&bob).await; let bob_device = ReadOnlyDevice::from_account(&bob).await;
let alice_sas = SasState::<Created>::new(alice.clone(), bob_device, None); let alice_sas = SasState::<Created>::new(alice.clone(), bob_device, None);
@ -1038,10 +1038,10 @@ mod test {
#[tokio::test] #[tokio::test]
async fn sas_from_start_unknown_method() { async fn sas_from_start_unknown_method() {
let alice = Account::new(&alice_id(), &alice_device_id()); let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());
let alice_device = ReadOnlyDevice::from_account(&alice).await; let alice_device = ReadOnlyDevice::from_account(&alice).await;
let bob = Account::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let bob_device = ReadOnlyDevice::from_account(&bob).await; let bob_device = ReadOnlyDevice::from_account(&bob).await;
let alice_sas = SasState::<Created>::new(alice.clone(), bob_device, None); let alice_sas = SasState::<Created>::new(alice.clone(), bob_device, None);