diff --git a/services/commtest/src/identity/olm_account_infos.rs b/services/commtest/src/identity/olm_account_infos.rs --- a/services/commtest/src/identity/olm_account_infos.rs +++ b/services/commtest/src/identity/olm_account_infos.rs @@ -1,4 +1,5 @@ use lazy_static::lazy_static; +use rand::{distributions::Alphanumeric, Rng}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, Clone)] @@ -46,3 +47,11 @@ }, }; } + +pub fn get_random_otk() -> String { + rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(43) + .map(char::from) + .collect() +} diff --git a/services/commtest/tests/identity_keyserver_tests.rs b/services/commtest/tests/identity_keyserver_tests.rs --- a/services/commtest/tests/identity_keyserver_tests.rs +++ b/services/commtest/tests/identity_keyserver_tests.rs @@ -1,6 +1,7 @@ use commtest::identity::device::{ register_user_device, DEVICE_TYPE, PLACEHOLDER_CODE_VERSION, }; +use commtest::identity::olm_account_infos::get_random_otk; use commtest::service_addr; use grpc_clients::identity::{ get_auth_client, @@ -25,9 +26,12 @@ .await .expect("Couldn't connect to identity service"); + let content_one_time_prekey = get_random_otk(); + let notif_one_time_prekey = get_random_otk(); + let upload_request = UploadOneTimeKeysRequest { - content_one_time_prekeys: vec!["content1".to_string()], - notif_one_time_prekeys: vec!["notif1".to_string()], + content_one_time_prekeys: vec![content_one_time_prekey.clone()], + notif_one_time_prekeys: vec![notif_one_time_prekey.clone()], }; client @@ -44,18 +48,18 @@ let first_reponse = client .get_keyserver_keys(keyserver_request.clone()) .await - .expect("Second keyserver keys request failed") + .expect("First keyserver keys request failed") .into_inner() .keyserver_info .unwrap(); assert_eq!( first_reponse.one_time_content_prekey, - Some("content1".to_string()) + Some(content_one_time_prekey) ); assert_eq!( first_reponse.one_time_notif_prekey, - Some("notif1".to_string()) + Some(notif_one_time_prekey) ); let second_reponse = client diff --git a/services/commtest/tests/identity_one_time_key_tests.rs b/services/commtest/tests/identity_one_time_key_tests.rs --- a/services/commtest/tests/identity_one_time_key_tests.rs +++ b/services/commtest/tests/identity_one_time_key_tests.rs @@ -1,6 +1,7 @@ use commtest::identity::device::{ register_user_device, DEVICE_TYPE, PLACEHOLDER_CODE_VERSION, }; +use commtest::identity::olm_account_infos::get_random_otk; use commtest::service_addr; use grpc_clients::identity::{ get_auth_client, protos::authenticated::UploadOneTimeKeysRequest, @@ -22,11 +23,8 @@ .expect("Couldn't connect to identity service"); let upload_request = UploadOneTimeKeysRequest { - content_one_time_prekeys: vec![ - "content1".to_string(), - "content2".to_string(), - ], - notif_one_time_prekeys: vec!["notif1".to_string(), "notif2".to_string()], + content_one_time_prekeys: vec![get_random_otk(), get_random_otk()], + notif_one_time_prekeys: vec![get_random_otk(), get_random_otk()], }; identity_client diff --git a/services/commtest/tests/identity_tunnelbroker_tests.rs b/services/commtest/tests/identity_tunnelbroker_tests.rs --- a/services/commtest/tests/identity_tunnelbroker_tests.rs +++ b/services/commtest/tests/identity_tunnelbroker_tests.rs @@ -1,6 +1,7 @@ use commtest::identity::device::{ register_user_device, DEVICE_TYPE, PLACEHOLDER_CODE_VERSION, }; +use commtest::identity::olm_account_infos::get_random_otk; use commtest::service_addr; use commtest::tunnelbroker::socket::{create_socket, receive_message}; use futures_util::StreamExt; @@ -47,9 +48,11 @@ .await .expect("Couldn't connect to identity service"); + let content_one_time_prekeys = vec![get_random_otk()]; + let notif_one_time_prekeys = vec![get_random_otk()]; let upload_request = UploadOneTimeKeysRequest { - content_one_time_prekeys: vec!["content1".to_string()], - notif_one_time_prekeys: vec!["notif1".to_string()], + content_one_time_prekeys, + notif_one_time_prekeys, }; client.upload_one_time_keys(upload_request).await.unwrap(); 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 @@ -245,3 +245,4 @@ // One-time keys pub const ONE_TIME_KEY_UPLOAD_LIMIT_PER_ACCOUNT: usize = 49; +pub const ONE_TIME_KEY_SIZE: usize = 43; // as defined in olm 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 @@ -27,6 +27,7 @@ pub use crate::database::device_list::DeviceIDAttribute; use crate::ddb_utils::into_one_time_update_requests; +use crate::olm::is_valid_olm_key; use crate::{ constants::USERS_TABLE_SOCIAL_PROOF_ATTRIBUTE_NAME, ddb_utils::EthereumIdentity, reserved_users::UserDetail, @@ -608,6 +609,15 @@ return Err(Error::OneTimeKeyUploadLimitExceeded); } + if content_one_time_keys + .iter() + .any(|otk| !is_valid_olm_key(otk)) + || notif_one_time_keys.iter().any(|otk| !is_valid_olm_key(otk)) + { + debug!("Invalid one-time key format"); + return Err(Error::InvalidFormat); + } + let current_time = chrono::Utc::now(); let content_otk_requests = into_one_time_put_requests( 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 @@ -28,6 +28,8 @@ OneTimeKeyUploadLimitExceeded, #[display(...)] MaxRetriesExceeded, + #[display(...)] + InvalidFormat, } #[derive(Debug, derive_more::Display, derive_more::Error)] diff --git a/services/identity/src/main.rs b/services/identity/src/main.rs --- a/services/identity/src/main.rs +++ b/services/identity/src/main.rs @@ -16,6 +16,7 @@ mod id; mod keygen; mod nonce; +mod olm; mod regex; mod reserved_users; mod siwe; diff --git a/services/identity/src/olm.rs b/services/identity/src/olm.rs new file mode 100644 --- /dev/null +++ b/services/identity/src/olm.rs @@ -0,0 +1,9 @@ +use crate::constants::ONE_TIME_KEY_SIZE; + +pub fn is_valid_olm_key(input: &str) -> bool { + let is_json = input.starts_with('{') && input.ends_with('}'); + + let is_correct_length = input.len() == ONE_TIME_KEY_SIZE; + + !is_json && is_correct_length +}