Page MenuHomePhabricator

D11959.id39981.diff
No OneTemporary

D11959.id39981.diff

diff --git a/services/identity/src/database/device_list.rs b/services/identity/src/database/device_list.rs
--- a/services/identity/src/database/device_list.rs
+++ b/services/identity/src/database/device_list.rs
@@ -83,6 +83,8 @@
/// Last primary device signature, in case the primary device has changed
/// since last device list update.
pub last_primary_signature: Option<String>,
+ /// Raw update payload to verify signatures
+ pub raw_payload: String,
}
impl DeviceRow {
@@ -934,6 +936,11 @@
let new_list = update.devices.clone();
self
.transact_update_devicelist(user_id, |current_list, _| {
+ crate::device_list::verify_device_list_signatures(
+ current_list.first(),
+ &update,
+ )?;
+
let previous_device_ids: Vec<&str> =
current_list.iter().map(AsRef::as_ref).collect();
let new_device_ids: Vec<&str> =
diff --git a/services/identity/src/device_list.rs b/services/identity/src/device_list.rs
--- a/services/identity/src/device_list.rs
+++ b/services/identity/src/device_list.rs
@@ -1,6 +1,6 @@
use chrono::{DateTime, Duration, Utc};
use std::collections::HashSet;
-use tracing::{error, warn};
+use tracing::{debug, error, warn};
use crate::{
constants::{error_types, DEVICE_LIST_TIMESTAMP_VALID_FOR},
@@ -115,6 +115,7 @@
timestamp,
current_primary_signature: signed_list.cur_primary_signature,
last_primary_signature: signed_list.last_primary_signature,
+ raw_payload: signed_list.raw_device_list,
})
}
}
@@ -164,6 +165,46 @@
Ok(())
}
+pub fn verify_device_list_signatures(
+ previous_primary_device_id: Option<&String>,
+ new_device_list: &DeviceListUpdate,
+) -> Result<(), DeviceListError> {
+ let Some(primary_device_id) = new_device_list.devices.first() else {
+ return Ok(());
+ };
+
+ // verify current signature
+ if let Some(signature) = &new_device_list.current_primary_signature {
+ crate::grpc_utils::ed25519_verify(
+ primary_device_id,
+ &new_device_list.raw_payload,
+ signature,
+ )
+ .map_err(|err| {
+ debug!("curPrimarySignature verification failed: {err}");
+ DeviceListError::InvalidSignature
+ })?;
+ }
+
+ // verify last signature if primary device changed
+ if let (Some(previous_primary_id), Some(last_signature)) = (
+ previous_primary_device_id.filter(|prev| *prev != primary_device_id),
+ &new_device_list.last_primary_signature,
+ ) {
+ crate::grpc_utils::ed25519_verify(
+ previous_primary_id,
+ &new_device_list.raw_payload,
+ last_signature,
+ )
+ .map_err(|err| {
+ debug!("lastPrimarySignature verification failed: {err}");
+ DeviceListError::InvalidSignature
+ })?;
+ }
+
+ Ok(())
+}
+
pub mod validation {
use super::*;
/// Returns `true` if `new_device_list` contains exactly one more new device
diff --git a/services/identity/src/error.rs b/services/identity/src/error.rs
--- a/services/identity/src/error.rs
+++ b/services/identity/src/error.rs
@@ -40,6 +40,7 @@
DeviceNotFound,
ConcurrentUpdateError,
InvalidDeviceListUpdate,
+ InvalidSignature,
}
pub fn consume_error<T>(result: Result<T, Error>) {

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 18, 11:01 AM (21 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2534836
Default Alt Text
D11959.id39981.diff (3 KB)

Event Timeline