Skip to content

Commit 68a2020

Browse files
committed
fix(crypto): Check if the device we get from the server matches our own
1 parent 13db642 commit 68a2020

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

crates/matrix-sdk-crypto/src/identities/manager.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use crate::{
3535
olm::PrivateCrossSigningIdentity,
3636
requests::KeysQueryRequest,
3737
store::{Changes, DeviceChanges, IdentityChanges, Result as StoreResult, Store},
38+
LocalTrust,
3839
};
3940

4041
enum DeviceChange {
@@ -153,14 +154,37 @@ impl IdentityManager {
153154
} else {
154155
match ReadOnlyDevice::try_from(&device_keys) {
155156
Ok(d) => {
156-
trace!(
157-
user_id = d.user_id().as_str(),
158-
device_id = d.device_id().as_str(),
159-
keys =? d.keys(),
160-
"Adding a new device to the device store",
161-
);
157+
// If this is our own device, check that the server isn't
158+
// lying about our keys, also mark the device as locally
159+
// trusted.
160+
if d.user_id() == store.user_id() && d.device_id() == store.device_id() {
161+
let local_device_keys = store.account().unsigned_device_keys();
162+
163+
if d.keys() == &local_device_keys.keys {
164+
d.set_trust_state(LocalTrust::Verified);
165+
166+
trace!(
167+
user_id = d.user_id().as_str(),
168+
device_id = d.device_id().as_str(),
169+
keys =? d.keys(),
170+
"Adding our own device to the device store, \
171+
marking it as locally verified",
172+
);
173+
174+
Ok(DeviceChange::New(d))
175+
} else {
176+
Ok(DeviceChange::None)
177+
}
178+
} else {
179+
trace!(
180+
user_id = d.user_id().as_str(),
181+
device_id = d.device_id().as_str(),
182+
keys =? d.keys(),
183+
"Adding a new device to the device store",
184+
);
162185

163-
Ok(DeviceChange::New(d))
186+
Ok(DeviceChange::New(d))
187+
}
164188
}
165189
Err(e) => {
166190
warn!(

crates/matrix-sdk-crypto/src/store/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ impl Store {
247247
self.verification_machine.own_device_id()
248248
}
249249

250+
pub fn account(&self) -> &ReadOnlyAccount {
251+
&self.verification_machine.store.account
252+
}
253+
250254
#[cfg(test)]
251255
pub async fn reset_cross_signing_identity(&self) {
252256
self.identity.lock().await.reset().await;

crates/matrix-sdk-crypto/src/store/sled.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ use crate::{
5050
/// This needs to be 32 bytes long since AES-GCM requires it, otherwise we will
5151
/// panic once we try to pickle a Signing object.
5252
const DEFAULT_PICKLE: &str = "DEFAULT_PICKLE_PASSPHRASE_123456";
53-
const DATABASE_VERSION: u8 = 2;
53+
const DATABASE_VERSION: u8 = 3;
5454

5555
trait EncodeKey {
5656
const SEPARATOR: u8 = 0xff;
@@ -322,6 +322,20 @@ impl SledStore {
322322
})?;
323323
}
324324

325+
if version <= 2 {
326+
// We're treating our own device now differently, we're checking if
327+
// the keys match to what we have locally, remove the unchecked
328+
// device and mark our own user as dirty.
329+
if let Some(pickle) = self.account.get("account".encode())? {
330+
let pickle = serde_json::from_slice(&pickle)?;
331+
let account = ReadOnlyAccount::from_pickle(pickle, self.get_pickle_mode())?;
332+
333+
self.devices
334+
.remove((account.user_id().as_str(), account.device_id.as_str()).encode())?;
335+
self.tracked_users.insert(account.user_id().as_str(), &[true as u8])?;
336+
}
337+
}
338+
325339
self.inner.insert("store_version", DATABASE_VERSION.to_be_bytes().as_ref())?;
326340
self.inner.flush()?;
327341

0 commit comments

Comments
 (0)