crypto: Test the full key share flow.
parent
84066d4a76
commit
8fe1eda169
|
@ -1653,7 +1653,10 @@ impl Client {
|
||||||
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
||||||
/// # let client = Client::new(homeserver).unwrap();
|
/// # let client = Client::new(homeserver).unwrap();
|
||||||
/// # block_on(async {
|
/// # block_on(async {
|
||||||
/// let device = client.get_device(&alice, "DEVICEID".into()).await.unwrap();
|
/// let device = client.get_device(&alice, "DEVICEID".into())
|
||||||
|
/// .await
|
||||||
|
/// .unwrap()
|
||||||
|
/// .unwrap();
|
||||||
///
|
///
|
||||||
/// println!("{:?}", device.is_trusted());
|
/// println!("{:?}", device.is_trusted());
|
||||||
///
|
///
|
||||||
|
|
|
@ -55,7 +55,10 @@ impl Device {
|
||||||
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
||||||
/// # let client = Client::new(homeserver).unwrap();
|
/// # let client = Client::new(homeserver).unwrap();
|
||||||
/// # block_on(async {
|
/// # block_on(async {
|
||||||
/// let device = client.get_device(&alice, "DEVICEID".into()).await.unwrap();
|
/// let device = client.get_device(&alice, "DEVICEID".into())
|
||||||
|
/// .await
|
||||||
|
/// .unwrap()
|
||||||
|
/// .unwrap();
|
||||||
///
|
///
|
||||||
/// let verification = device.start_verification().await.unwrap();
|
/// let verification = device.start_verification().await.unwrap();
|
||||||
/// # });
|
/// # });
|
||||||
|
|
|
@ -1819,8 +1819,7 @@ impl BaseClient {
|
||||||
if let Some(olm) = olm.as_ref() {
|
if let Some(olm) = olm.as_ref() {
|
||||||
olm.get_device(user_id, device_id).await
|
olm.get_device(user_id, device_id).await
|
||||||
} else {
|
} else {
|
||||||
// TODO remove this panic.
|
Ok(None)
|
||||||
panic!("The client hasn't been logged in")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,6 @@
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
//
|
//
|
||||||
// Incoming key requests:
|
|
||||||
// First handle the easy case, if we trust the device and have a session, queue
|
|
||||||
// up a to-device request.
|
|
||||||
//
|
|
||||||
// If we don't have a session, queue up a key claim request, once we get a
|
// If we don't have a session, queue up a key claim request, once we get a
|
||||||
// session send out the key if we trust the device.
|
// session send out the key if we trust the device.
|
||||||
//
|
//
|
||||||
|
@ -31,7 +27,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{value::to_raw_value, Value};
|
use serde_json::{value::to_raw_value, Value};
|
||||||
use std::{collections::BTreeMap, convert::TryInto, ops::Deref, sync::Arc};
|
use std::{collections::BTreeMap, convert::TryInto, ops::Deref, sync::Arc};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::{info, instrument, trace, warn};
|
use tracing::{error, info, instrument, trace, warn};
|
||||||
|
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
api::r0::to_device::DeviceIdOrAllDevices,
|
api::r0::to_device::DeviceIdOrAllDevices,
|
||||||
|
@ -62,12 +58,37 @@ struct Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device {
|
impl Device {
|
||||||
|
/// Encrypt the given inbound group session as a forwarded room key for this
|
||||||
|
/// device.
|
||||||
|
pub async fn encrypt_session(
|
||||||
|
&self,
|
||||||
|
session: InboundGroupSession,
|
||||||
|
) -> OlmResult<EncryptedEventContent> {
|
||||||
|
let export = session.export().await;
|
||||||
|
|
||||||
|
let content: ForwardedRoomKeyEventContent = if let Ok(c) = export.try_into() {
|
||||||
|
c
|
||||||
|
} else {
|
||||||
|
// TODO remove this panic.
|
||||||
|
panic!(
|
||||||
|
"Can't share session {} with device {} {}, key export can't \
|
||||||
|
be converted to a forwarded room key content",
|
||||||
|
session.session_id(),
|
||||||
|
self.user_id(),
|
||||||
|
self.device_id()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = serde_json::to_value(content)?;
|
||||||
|
self.encrypt(EventType::ForwardedRoomKey, content).await
|
||||||
|
}
|
||||||
|
|
||||||
fn trust_state(&self) -> bool {
|
fn trust_state(&self) -> bool {
|
||||||
self.inner
|
self.inner
|
||||||
.trust_state(&self.own_identity, &self.device_owner_identity)
|
.trust_state(&self.own_identity, &self.device_owner_identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn encrypt(
|
async fn encrypt(
|
||||||
&self,
|
&self,
|
||||||
event_type: EventType,
|
event_type: EventType,
|
||||||
content: Value,
|
content: Value,
|
||||||
|
@ -208,7 +229,7 @@ impl KeyRequestMachine {
|
||||||
|
|
||||||
/// Handle all the incoming key requests that are queued up and empty our
|
/// Handle all the incoming key requests that are queued up and empty our
|
||||||
/// key request queue.
|
/// key request queue.
|
||||||
pub async fn collect_incoming_key_requests(&self) -> Result<(), CryptoStoreError> {
|
pub async fn collect_incoming_key_requests(&self) -> OlmResult<()> {
|
||||||
for item in self.incoming_key_requests.iter() {
|
for item in self.incoming_key_requests.iter() {
|
||||||
let event = item.value();
|
let event = item.value();
|
||||||
self.handle_key_request(event).await?;
|
self.handle_key_request(event).await?;
|
||||||
|
@ -224,7 +245,7 @@ impl KeyRequestMachine {
|
||||||
async fn handle_key_request(
|
async fn handle_key_request(
|
||||||
&self,
|
&self,
|
||||||
event: &ToDeviceEvent<RoomKeyRequestEventContent>,
|
event: &ToDeviceEvent<RoomKeyRequestEventContent>,
|
||||||
) -> Result<(), CryptoStoreError> {
|
) -> OlmResult<()> {
|
||||||
let key_info = match event.content.action {
|
let key_info = match event.content.action {
|
||||||
Action::Request => {
|
Action::Request => {
|
||||||
if let Some(info) = &event.content.body {
|
if let Some(info) = &event.content.body {
|
||||||
|
@ -273,7 +294,6 @@ impl KeyRequestMachine {
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(device) = device {
|
if let Some(device) = device {
|
||||||
// TODO get the matching outbound session.
|
|
||||||
if let Err(e) = self.should_share_session(
|
if let Err(e) = self.should_share_session(
|
||||||
&device,
|
&device,
|
||||||
self.outbound_group_sessions
|
self.outbound_group_sessions
|
||||||
|
@ -294,7 +314,8 @@ impl KeyRequestMachine {
|
||||||
device.device_id()
|
device.device_id()
|
||||||
);
|
);
|
||||||
|
|
||||||
self.share_session(session, device).await;
|
// TODO the missing session error here.
|
||||||
|
self.share_session(session, device).await?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!(
|
||||||
|
@ -307,17 +328,10 @@ impl KeyRequestMachine {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn share_session(&self, session: InboundGroupSession, device: Device) {
|
async fn share_session(&self, session: InboundGroupSession, device: Device) -> OlmResult<()> {
|
||||||
let export = session.export().await;
|
let content = device.encrypt_session(session).await?;
|
||||||
let content: ForwardedRoomKeyEventContent = export.try_into().unwrap();
|
|
||||||
let content = serde_json::to_value(content).unwrap();
|
|
||||||
let content = device
|
|
||||||
.encrypt(EventType::ForwardedRoomKey, content)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let id = Uuid::new_v4();
|
let id = Uuid::new_v4();
|
||||||
|
|
||||||
let mut messages = BTreeMap::new();
|
let mut messages = BTreeMap::new();
|
||||||
|
|
||||||
messages
|
messages
|
||||||
|
@ -325,7 +339,7 @@ impl KeyRequestMachine {
|
||||||
.or_insert_with(BTreeMap::new)
|
.or_insert_with(BTreeMap::new)
|
||||||
.insert(
|
.insert(
|
||||||
DeviceIdOrAllDevices::DeviceId(device.device_id().into()),
|
DeviceIdOrAllDevices::DeviceId(device.device_id().into()),
|
||||||
to_raw_value(&content).unwrap(),
|
to_raw_value(&content)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
let request = OutgoingRequest {
|
let request = OutgoingRequest {
|
||||||
|
@ -341,6 +355,8 @@ impl KeyRequestMachine {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.outgoing_to_device_requests.insert(id, request);
|
self.outgoing_to_device_requests.insert(id, request);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if it's ok to share a session with the given device.
|
/// Check if it's ok to share a session with the given device.
|
||||||
|
@ -590,7 +606,7 @@ mod test {
|
||||||
events::{
|
events::{
|
||||||
forwarded_room_key::ForwardedRoomKeyEventContent,
|
forwarded_room_key::ForwardedRoomKeyEventContent,
|
||||||
room::encrypted::EncryptedEventContent, room_key_request::RoomKeyRequestEventContent,
|
room::encrypted::EncryptedEventContent, room_key_request::RoomKeyRequestEventContent,
|
||||||
ToDeviceEvent,
|
AnyToDeviceEvent, ToDeviceEvent,
|
||||||
},
|
},
|
||||||
identifiers::{room_id, user_id, DeviceIdBox, RoomId, UserId},
|
identifiers::{room_id, user_id, DeviceIdBox, RoomId, UserId},
|
||||||
};
|
};
|
||||||
|
@ -599,7 +615,7 @@ mod test {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
identities::{LocalTrust, ReadOnlyDevice},
|
identities::{LocalTrust, ReadOnlyDevice},
|
||||||
olm::ReadOnlyAccount,
|
olm::{Account, ReadOnlyAccount},
|
||||||
store::{MemoryStore, Store},
|
store::{MemoryStore, Store},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -905,7 +921,10 @@ mod test {
|
||||||
#[async_test]
|
#[async_test]
|
||||||
async fn key_share_cycle() {
|
async fn key_share_cycle() {
|
||||||
let alice_machine = get_machine();
|
let alice_machine = get_machine();
|
||||||
let alice_account = account();
|
let alice_account = Account {
|
||||||
|
inner: account(),
|
||||||
|
store: alice_machine.store.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
let bob_machine = bob_machine();
|
let bob_machine = bob_machine();
|
||||||
let bob_account = bob_account();
|
let bob_account = bob_account();
|
||||||
|
@ -964,7 +983,7 @@ mod test {
|
||||||
// Put the outbound session into bobs store.
|
// Put the outbound session into bobs store.
|
||||||
bob_machine
|
bob_machine
|
||||||
.outbound_group_sessions
|
.outbound_group_sessions
|
||||||
.insert(room_id(), group_session);
|
.insert(room_id(), group_session.clone());
|
||||||
|
|
||||||
// Get the request and convert it into a event.
|
// Get the request and convert it into a event.
|
||||||
let request = alice_machine
|
let request = alice_machine
|
||||||
|
@ -1029,12 +1048,45 @@ mod test {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let _event = ToDeviceEvent {
|
let mut event = ToDeviceEvent {
|
||||||
sender: bob_id(),
|
sender: bob_id(),
|
||||||
content,
|
content,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO test that alice can receive, decrypt and add the requested key
|
// Check that alice doesn't have the session.
|
||||||
// to the store.
|
assert!(alice_machine
|
||||||
|
.store
|
||||||
|
.get_inbound_group_session(
|
||||||
|
&room_id(),
|
||||||
|
&bob_account.identity_keys().curve25519(),
|
||||||
|
group_session.session_id()
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.is_none());
|
||||||
|
|
||||||
|
let (decrypted, sender_key, _) = alice_account
|
||||||
|
.decrypt_to_device_event(&mut event)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if let AnyToDeviceEvent::ForwardedRoomKey(mut e) = decrypted.deserialize().unwrap() {
|
||||||
|
alice_machine
|
||||||
|
.receive_forwarded_room_key(&sender_key, &mut e)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
panic!("Invalid decrypted event type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that alice now does have the session.
|
||||||
|
let session = alice_machine
|
||||||
|
.store
|
||||||
|
.get_inbound_group_session(&room_id(), &sender_key, group_session.session_id())
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(session.session_id(), group_session.session_id())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#[cfg(feature = "sqlite_cryptostore")]
|
#[cfg(feature = "sqlite_cryptostore")]
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::{collections::BTreeMap, convert::TryInto, mem, sync::Arc, time::Duration};
|
use std::{collections::BTreeMap, mem, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use tracing::{debug, error, info, instrument, trace, warn};
|
use tracing::{debug, error, info, instrument, trace, warn};
|
||||||
|
@ -51,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, ReadOnlyAccount,
|
InboundGroupSession, OutboundGroupSession, ReadOnlyAccount,
|
||||||
},
|
},
|
||||||
requests::{IncomingResponse, OutgoingRequest, ToDeviceRequest},
|
requests::{IncomingResponse, OutgoingRequest, ToDeviceRequest},
|
||||||
store::{CryptoStore, MemoryStore, Result as StoreResult, Store},
|
store::{CryptoStore, MemoryStore, Result as StoreResult, Store},
|
||||||
|
@ -513,47 +513,12 @@ impl OlmMachine {
|
||||||
&self,
|
&self,
|
||||||
event: &ToDeviceEvent<EncryptedEventContent>,
|
event: &ToDeviceEvent<EncryptedEventContent>,
|
||||||
) -> OlmResult<Raw<AnyToDeviceEvent>> {
|
) -> OlmResult<Raw<AnyToDeviceEvent>> {
|
||||||
info!("Decrypting to-device event");
|
let (decrypted_event, sender_key, signing_key) =
|
||||||
|
self.account.decrypt_to_device_event(event).await?;
|
||||||
let content = if let EncryptedEventContent::OlmV1Curve25519AesSha2(c) = &event.content {
|
|
||||||
c
|
|
||||||
} else {
|
|
||||||
warn!("Error, unsupported encryption algorithm");
|
|
||||||
return Err(EventError::UnsupportedAlgorithm.into());
|
|
||||||
};
|
|
||||||
|
|
||||||
let identity_keys = self.account.identity_keys();
|
|
||||||
let own_key = identity_keys.curve25519();
|
|
||||||
let own_ciphertext = content.ciphertext.get(own_key);
|
|
||||||
|
|
||||||
// Try to find a ciphertext that was meant for our device.
|
|
||||||
if let Some(ciphertext) = own_ciphertext {
|
|
||||||
let message_type: u8 = ciphertext
|
|
||||||
.message_type
|
|
||||||
.try_into()
|
|
||||||
.map_err(|_| EventError::UnsupportedOlmType)?;
|
|
||||||
|
|
||||||
// Create a OlmMessage from the ciphertext and the type.
|
|
||||||
let message =
|
|
||||||
OlmMessage::from_type_and_ciphertext(message_type.into(), ciphertext.body.clone())
|
|
||||||
.map_err(|_| EventError::UnsupportedOlmType)?;
|
|
||||||
|
|
||||||
// Decrypt the OlmMessage and get a Ruma event out of it.
|
|
||||||
let (decrypted_event, signing_key) = self
|
|
||||||
.account
|
|
||||||
.decrypt_olm_message(&event.sender, &content.sender_key, message)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
debug!("Decrypted a to-device event {:?}", decrypted_event);
|
|
||||||
|
|
||||||
// Handle the decrypted event, e.g. fetch out Megolm sessions out of
|
// Handle the decrypted event, e.g. fetch out Megolm sessions out of
|
||||||
// the event.
|
// the event.
|
||||||
if let Some(event) = self
|
if let Some(event) = self
|
||||||
.handle_decrypted_to_device_event(
|
.handle_decrypted_to_device_event(&sender_key, &signing_key, &decrypted_event)
|
||||||
&content.sender_key,
|
|
||||||
&signing_key,
|
|
||||||
&decrypted_event,
|
|
||||||
)
|
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
// Some events may have sensitive data e.g. private keys, while we
|
// Some events may have sensitive data e.g. private keys, while we
|
||||||
|
@ -565,10 +530,6 @@ impl OlmMachine {
|
||||||
} else {
|
} else {
|
||||||
Ok(decrypted_event)
|
Ok(decrypted_event)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
warn!("Olm event doesn't contain a ciphertext for our key");
|
|
||||||
Err(EventError::MissingCiphertext.into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a group session from a room key and add it to our crypto store.
|
/// Create a group session from a room key and add it to our crypto store.
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// 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.
|
||||||
|
|
||||||
|
use matrix_sdk_common::events::ToDeviceEvent;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -27,11 +28,11 @@ use std::{
|
||||||
use tracing::{debug, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use matrix_sdk_common::events::{room::encrypted::EncryptedEventContent, EventType};
|
use matrix_sdk_common::events::EventType;
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
api::r0::keys::{upload_keys, OneTimeKey, SignedKey},
|
api::r0::keys::{upload_keys, OneTimeKey, SignedKey},
|
||||||
encryption::DeviceKeys,
|
encryption::DeviceKeys,
|
||||||
events::AnyToDeviceEvent,
|
events::{room::encrypted::EncryptedEventContent, AnyToDeviceEvent},
|
||||||
identifiers::{
|
identifiers::{
|
||||||
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, RoomId,
|
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, RoomId,
|
||||||
UserId,
|
UserId,
|
||||||
|
@ -72,6 +73,48 @@ impl Deref for Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Account {
|
impl Account {
|
||||||
|
pub async fn decrypt_to_device_event(
|
||||||
|
&self,
|
||||||
|
event: &ToDeviceEvent<EncryptedEventContent>,
|
||||||
|
) -> OlmResult<(Raw<AnyToDeviceEvent>, String, String)> {
|
||||||
|
debug!("Decrypting to-device event");
|
||||||
|
|
||||||
|
let content = if let EncryptedEventContent::OlmV1Curve25519AesSha2(c) = &event.content {
|
||||||
|
c
|
||||||
|
} else {
|
||||||
|
warn!("Error, unsupported encryption algorithm");
|
||||||
|
return Err(EventError::UnsupportedAlgorithm.into());
|
||||||
|
};
|
||||||
|
|
||||||
|
let identity_keys = self.inner.identity_keys();
|
||||||
|
let own_key = identity_keys.curve25519();
|
||||||
|
let own_ciphertext = content.ciphertext.get(own_key);
|
||||||
|
|
||||||
|
// Try to find a ciphertext that was meant for our device.
|
||||||
|
if let Some(ciphertext) = own_ciphertext {
|
||||||
|
let message_type: u8 = ciphertext
|
||||||
|
.message_type
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| EventError::UnsupportedOlmType)?;
|
||||||
|
|
||||||
|
// Create a OlmMessage from the ciphertext and the type.
|
||||||
|
let message =
|
||||||
|
OlmMessage::from_type_and_ciphertext(message_type.into(), ciphertext.body.clone())
|
||||||
|
.map_err(|_| EventError::UnsupportedOlmType)?;
|
||||||
|
|
||||||
|
// Decrypt the OlmMessage and get a Ruma event out of it.
|
||||||
|
let (decrypted_event, signing_key) = self
|
||||||
|
.decrypt_olm_message(&event.sender, &content.sender_key, message)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
debug!("Decrypted a to-device event {:?}", decrypted_event);
|
||||||
|
Ok((decrypted_event, content.sender_key.clone(), signing_key))
|
||||||
|
} else {
|
||||||
|
warn!("Olm event doesn't contain a ciphertext for our key");
|
||||||
|
Err(EventError::MissingCiphertext.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_uploaded_key_count(
|
pub async fn update_uploaded_key_count(
|
||||||
&self,
|
&self,
|
||||||
key_count: &BTreeMap<DeviceKeyAlgorithm, UInt>,
|
key_count: &BTreeMap<DeviceKeyAlgorithm, UInt>,
|
||||||
|
@ -146,24 +189,27 @@ impl Account {
|
||||||
|
|
||||||
let ret = session.decrypt(message.clone()).await;
|
let ret = session.decrypt(message.clone()).await;
|
||||||
|
|
||||||
if let Ok(p) = ret {
|
match ret {
|
||||||
|
Ok(p) => {
|
||||||
plaintext = Some(p);
|
plaintext = Some(p);
|
||||||
session_to_save = Some(session.clone());
|
session_to_save = Some(session.clone());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
Err(e) => {
|
||||||
// Decryption failed with a matching session, the session is
|
// Decryption failed with a matching session, the session is
|
||||||
// likely wedged and needs to be rotated.
|
// likely wedged and needs to be rotated.
|
||||||
if matches {
|
if matches {
|
||||||
warn!(
|
warn!(
|
||||||
"Found a matching Olm session yet decryption failed
|
"Found a matching Olm session yet decryption failed
|
||||||
for sender {} and sender_key {}",
|
for sender {} and sender_key {} {:?}",
|
||||||
sender, sender_key
|
sender, sender_key, e
|
||||||
);
|
);
|
||||||
return Err(OlmError::SessionWedged);
|
return Err(OlmError::SessionWedged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(session) = session_to_save {
|
if let Some(session) = session_to_save {
|
||||||
// Decryption was successful, save the new ratchet state of the
|
// Decryption was successful, save the new ratchet state of the
|
||||||
|
@ -176,7 +222,7 @@ impl Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt an Olm message, creating a new Olm session if possible.
|
/// Decrypt an Olm message, creating a new Olm session if possible.
|
||||||
pub async fn decrypt_olm_message(
|
async fn decrypt_olm_message(
|
||||||
&self,
|
&self,
|
||||||
sender: &UserId,
|
sender: &UserId,
|
||||||
sender_key: &str,
|
sender_key: &str,
|
||||||
|
@ -882,6 +928,8 @@ impl ReadOnlyAccount {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
other.mark_keys_as_published().await;
|
||||||
|
|
||||||
let message = our_session
|
let message = our_session
|
||||||
.encrypt(&device, EventType::Dummy, json!({}))
|
.encrypt(&device, EventType::Dummy, json!({}))
|
||||||
.await
|
.await
|
||||||
|
@ -901,14 +949,14 @@ impl ReadOnlyAccount {
|
||||||
let message =
|
let message =
|
||||||
OlmMessage::from_type_and_ciphertext(message_type.into(), own_ciphertext.body.clone())
|
OlmMessage::from_type_and_ciphertext(message_type.into(), own_ciphertext.body.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let message = if let OlmMessage::PreKey(m) = message {
|
let prekey = if let OlmMessage::PreKey(m) = message.clone() {
|
||||||
m
|
m
|
||||||
} else {
|
} else {
|
||||||
panic!("Wrong Olm message type");
|
panic!("Wrong Olm message type");
|
||||||
};
|
};
|
||||||
|
|
||||||
let our_device = ReadOnlyDevice::from_account(self).await;
|
let our_device = ReadOnlyDevice::from_account(self).await;
|
||||||
let other_session = other
|
let mut other_session = other
|
||||||
.create_inbound_session(
|
.create_inbound_session(
|
||||||
our_device
|
our_device
|
||||||
.keys()
|
.keys()
|
||||||
|
@ -917,11 +965,13 @@ impl ReadOnlyAccount {
|
||||||
our_device.device_id(),
|
our_device.device_id(),
|
||||||
))
|
))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
message,
|
prekey,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
other_session.decrypt(message).await.unwrap();
|
||||||
|
|
||||||
(our_session, other_session)
|
(our_session, other_session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ pub use group_sessions::{
|
||||||
};
|
};
|
||||||
pub(crate) use group_sessions::{GroupSessionKey, OutboundGroupSession};
|
pub(crate) use group_sessions::{GroupSessionKey, OutboundGroupSession};
|
||||||
pub use olm_rs::{account::IdentityKeys, PicklingMode};
|
pub use olm_rs::{account::IdentityKeys, PicklingMode};
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue