diff --git a/keyserver/addons/rust-node-addon/src/identity_client.rs b/keyserver/addons/rust-node-addon/src/identity_client.rs --- a/keyserver/addons/rust-node-addon/src/identity_client.rs +++ b/keyserver/addons/rust-node-addon/src/identity_client.rs @@ -11,6 +11,7 @@ PakeRegistrationRequestAndUserId as PakeRegistrationRequestAndUserIdStruct, PakeRegistrationUploadAndCredentialRequest as PakeRegistrationUploadAndCredentialRequestStruct, RegistrationRequest, RegistrationResponse as RegistrationResponseMessage, + SessionInitializationInfo, }; use crate::{AUTH_TOKEN, IDENTITY_SERVICE_SOCKET_ADDR}; use comm_opaque::Cipher; @@ -22,6 +23,7 @@ CredentialResponse, RegistrationResponse, RegistrationUpload, }; use rand::{rngs::OsRng, CryptoRng, Rng}; +use std::collections::HashMap; use tokio::sync::mpsc; use tokio_stream::wrappers::ReceiverStream; use tonic::{metadata::MetadataValue, transport::Channel, Request}; @@ -34,6 +36,7 @@ signing_public_key: String, username: String, password: String, + session_initialization_info: HashMap, ) -> Result { let channel = Channel::from_static(&IDENTITY_SERVICE_SOCKET_ADDR) .connect() @@ -70,6 +73,9 @@ signing_public_key, &password, username, + SessionInitializationInfo { + info: session_initialization_info, + }, )?; send_to_mpsc(tx.clone(), registration_request).await?; @@ -164,6 +170,7 @@ signing_public_key: String, password: &str, username: String, + session_initialization_info: SessionInitializationInfo, ) -> Result<(RegistrationRequest, ClientRegistration)> { let client_registration_start_result = ClientRegistration::::start(rng, password.as_bytes()).map_err( @@ -182,6 +189,7 @@ pake_registration_request, username, signing_public_key, + session_initialization_info: Some(session_initialization_info), }, )), }, diff --git a/native/native_rust_library/src/identity_client.rs b/native/native_rust_library/src/identity_client.rs --- a/native/native_rust_library/src/identity_client.rs +++ b/native/native_rust_library/src/identity_client.rs @@ -171,6 +171,8 @@ error!("Could not serialize credential request: {}", e); Status::failed_precondition("PAKE failure") })?, + // Todo: provide actual session initialization info + session_initialization_info: None, }, )), })), @@ -225,6 +227,8 @@ signing_public_key, siwe_message, siwe_signature, + // Todo: provide actual session initialization info + session_initialization_info: None, })), }; if let Err(e) = tx.send(login_request).await { @@ -261,6 +265,8 @@ signing_public_key, pake_registration_request, username, + // Todo: provide actual session initialization info + session_initialization_info: None, }, )), }, 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 @@ -102,6 +102,7 @@ signing_public_key: Option, registration: Option>, username: Option, + session_initialization_info: Option<&HashMap>, ) -> Result { let mut update_expression_parts = Vec::new(); let mut expression_attribute_names = HashMap::new(); @@ -129,8 +130,15 @@ format!("#{}", USERS_TABLE_DEVICES_MAP_ATTRIBUTE_NAME), public_key, ); + let device_info = match session_initialization_info { + Some(info) => info + .iter() + .map(|(k, v)| (k.to_string(), AttributeValue::S(v.to_string()))) + .collect(), + None => HashMap::new(), + }; expression_attribute_values - .insert(":k".to_string(), AttributeValue::M(HashMap::new())); + .insert(":k".to_string(), AttributeValue::M(device_info)); }; self @@ -164,7 +172,14 @@ registration: ServerRegistration, username: String, signing_public_key: String, + session_initialization_info: &HashMap, ) -> Result { + let device_info: HashMap = + session_initialization_info + .iter() + .map(|(k, v)| (k.to_string(), AttributeValue::S(v.to_string()))) + .collect(); + let item = HashMap::from([ ( USERS_TABLE_PARTITION_KEY.to_string(), @@ -182,7 +197,7 @@ USERS_TABLE_DEVICES_ATTRIBUTE.to_string(), AttributeValue::M(HashMap::from([( signing_public_key, - AttributeValue::M(HashMap::new()), + AttributeValue::M(device_info), )])), ), ]); diff --git a/services/identity/src/service.rs b/services/identity/src/service.rs --- a/services/identity/src/service.rs +++ b/services/identity/src/service.rs @@ -386,6 +386,12 @@ Some(wallet_login_request.signing_public_key.clone()), None, None, + Some( + &wallet_login_request + .session_initialization_info + .ok_or_else(|| Status::invalid_argument("Invalid message"))? + .info, + ), ) .await .map_err(handle_db_error)?; @@ -461,6 +467,7 @@ pake_credential_finalization: &[u8], rng: &mut (impl Rng + CryptoRng), pake_workflow: PakeWorkflow, + session_initialization_info: &HashMap, ) -> Result { if user_id.is_empty() || signing_public_key.is_empty() { error!( @@ -491,6 +498,7 @@ Some(signing_public_key.to_string()), None, None, + Some(session_initialization_info), ) .await .map_err(handle_db_error)?; @@ -545,6 +553,7 @@ server_registration: Option>, username: &str, signing_public_key: &str, + session_initialization_info: &HashMap, ) -> Result<(), Status> { if user_id.is_empty() { error!("Incomplete data: user ID not provided"); @@ -574,6 +583,7 @@ server_registration_finish_result, username.to_string(), signing_public_key.to_string(), + session_initialization_info, ) .await { diff --git a/services/identity/src/service/login.rs b/services/identity/src/service/login.rs --- a/services/identity/src/service/login.rs +++ b/services/identity/src/service/login.rs @@ -3,6 +3,7 @@ user_id: String, signing_public_key: String, pake_state: ServerLogin, + session_initialization_info: HashMap, } pub async fn handle_login_request( message: Option>, @@ -50,6 +51,10 @@ signing_public_key: pake_credential_request_and_user_id .signing_public_key, pake_state: response_and_state.pake_state, + session_initialization_info: pake_credential_request_and_user_id + .session_initialization_info + .ok_or_else(|| Status::invalid_argument("Invalid message"))? + .info, })) } Some(_) | None => Err(Status::aborted("failure")), @@ -77,6 +82,7 @@ &pake_credential_finalization, &mut OsRng, PakeWorkflow::Login, + &login_state.session_initialization_info, ) .await .map(|pake_login_response| LoginResponse { diff --git a/services/identity/src/service/registration.rs b/services/identity/src/service/registration.rs --- a/services/identity/src/service/registration.rs +++ b/services/identity/src/service/registration.rs @@ -4,6 +4,7 @@ username: String, signing_public_key: String, pub pake_state: Option>, + session_initialization_info: HashMap, } pub async fn handle_registration_request( @@ -51,6 +52,10 @@ signing_public_key: pake_registration_request_and_user_id .signing_public_key, pake_state: Some(response_and_state.pake_state), + session_initialization_info: pake_registration_request_and_user_id + .session_initialization_info + .ok_or_else(|| Status::invalid_argument("Invalid message"))? + .info, }) } None | Some(_) => Err(Status::aborted("failure")), @@ -79,6 +84,7 @@ Some(pake_state), ®istration_state.username, ®istration_state.signing_public_key, + ®istration_state.session_initialization_info, ) .await { @@ -130,6 +136,7 @@ &pake_credential_finalization, &mut OsRng, PakeWorkflow::Registration, + ®istration_state.session_initialization_info, ) .await .map(|pake_login_response| RegistrationResponse { diff --git a/shared/protos/identity.proto b/shared/protos/identity.proto --- a/shared/protos/identity.proto +++ b/shared/protos/identity.proto @@ -37,6 +37,9 @@ // Message sent to initiate PAKE registration (step 1) bytes pakeRegistrationRequest = 3; string username = 4; + // Information specific to a user's device needed to open a new channel of + // communication with this user + SessionInitializationInfo sessionInitializationInfo = 5; } message PakeCredentialRequestAndUserID { @@ -45,6 +48,9 @@ string signingPublicKey = 2; // Message sent to initiate PAKE login (step 1) bytes pakeCredentialRequest = 3; + // Information specific to a user's device needed to open a new channel of + // communication with this user + SessionInitializationInfo sessionInitializationInfo = 4; } message PakeLoginRequest { @@ -79,6 +85,9 @@ string signingPublicKey = 2; string siweMessage = 3; bytes siweSignature = 4; + // Information specific to a user's device needed to open a new channel of + // communication with this user + SessionInitializationInfo sessionInitializationInfo = 5; } message WalletLoginResponse {