diff --git a/services/identity/src/constants.rs b/services/identity/src/constants.rs --- a/services/identity/src/constants.rs +++ b/services/identity/src/constants.rs @@ -200,6 +200,7 @@ pub const WALLET_ADDRESS_MISMATCH: &str = "wallet_address_mismatch"; pub const DEVICE_ID_ALREADY_EXISTS: &str = "device_id_already_exists"; pub const USER_NOT_FOUND: &str = "user_not_found"; + pub const DEVICE_NOT_FOUND: &str = "device_not_found"; pub const INVALID_NONCE: &str = "invalid_nonce"; pub const NONCE_EXPIRED: &str = "nonce_expired"; pub const FID_TAKEN: &str = "fid_taken"; diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs --- a/services/identity/src/database.rs +++ b/services/identity/src/database.rs @@ -65,11 +65,9 @@ mod token; mod workflows; pub use device_list::{ - DeviceListRow, DeviceListUpdate, DeviceRow, PlatformDetails, + DeviceListRow, DeviceListUpdate, DeviceRow, PlatformDetails, Prekey, }; -use self::device_list::Prekey; - #[derive(Serialize, Deserialize)] pub struct OlmKeys { pub curve25519: String, 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 @@ -82,6 +82,13 @@ pub key_payload_signature: String, } +impl IdentityKeyInfo { + pub fn key_payload(&self) -> Result<super::KeyPayload, crate::error::Error> { + let payload = self.key_payload.parse::<super::KeyPayload>()?; + Ok(payload) + } +} + #[derive(Clone, Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Prekey { @@ -90,14 +97,14 @@ } impl Prekey { - fn new(prekey: String, prekey_signature: String) -> Self { + pub fn new(prekey: String, prekey_signature: String) -> Self { Self { prekey, prekey_signature, } } /// ED25519-verifies if prekey is signed correctly - fn verify(&self, signing_public_key: &str) -> Result<(), Error> { + pub fn verify(&self, signing_public_key: &str) -> Result<(), Error> { use crate::constants::tonic_status_messages; use base64::engine::{ general_purpose::STANDARD_NO_PAD as BASE64, Engine as _, diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs --- a/services/identity/src/grpc_services/authenticated.rs +++ b/services/identity/src/grpc_services/authenticated.rs @@ -3,7 +3,9 @@ use crate::comm_service::{backup, blob, tunnelbroker}; use crate::config::CONFIG; use crate::constants::staff::AUTHORITATIVE_KEYSERVER_OWNER_USER_ID; -use crate::database::{DeviceListRow, DeviceListUpdate, PlatformDetails}; +use crate::database::{ + DeviceListRow, DeviceListUpdate, PlatformDetails, Prekey, +}; use crate::device_list::validation::DeviceListValidator; use crate::device_list::SignedDeviceList; use crate::error::consume_error; @@ -142,14 +144,45 @@ Status::invalid_argument(tonic_status_messages::MISSING_NOTIF_KEYS) })?; + let device_info = self + .db_client + .get_device_data(&user_id, &device_id) + .await? + .ok_or_else(|| { + Status::invalid_argument(tonic_status_messages::DEVICE_NOT_FOUND) + })?; + let notif_signing_pub_key = device_info + .device_key_info + .key_payload()? + .notification_identity_public_keys + .ed25519; + + use crate::database::Prekey as DBPrekey; + let content_prekey = DBPrekey::from(content_key); + let notif_prekey = DBPrekey::from(notif_key); + + if let Err(err) = content_prekey.verify(&device_id) { + error!( + errorType = error_types::GRPC_SERVICES_LOG, + "Content prekey verification failed: {err}" + ); + return Err(Status::invalid_argument( + tonic_status_messages::MALFORMED_KEY, + )); + } + if let Err(err) = notif_prekey.verify(¬if_signing_pub_key) { + error!( + errorType = error_types::GRPC_SERVICES_LOG, + "Notif prekey verification failed: {err}" + ); + return Err(Status::invalid_argument( + tonic_status_messages::MALFORMED_KEY, + )); + } + self .db_client - .update_device_prekeys( - user_id, - device_id, - content_key.into(), - notif_key.into(), - ) + .update_device_prekeys(user_id, device_id, content_prekey, notif_prekey) .await?; let response = Response::new(Empty {});