Page MenuHomePhabricator

D7538.diff
No OneTemporary

D7538.diff

diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -29,6 +29,7 @@
pub use client_proto::identity_client_service_server::{
IdentityClientService, IdentityClientServiceServer,
};
+use comm_opaque2::grpc::protocol_error_to_grpc_status;
use moka::future::Cache;
use rand::rngs::OsRng;
use tonic::Response;
@@ -47,7 +48,10 @@
}
#[derive(Clone)]
-pub struct UserLoginInfo(FlattenedDeviceKeyUpload);
+pub struct UserLoginInfo {
+ pub flattened_device_key_upload: FlattenedDeviceKeyUpload,
+ pub opaque_server_login: comm_opaque2::server::Login,
+}
#[derive(Clone)]
pub struct FlattenedDeviceKeyUpload {
@@ -118,7 +122,7 @@
let server_registration = comm_opaque2::server::Registration::new();
let server_message = server_registration
.start(&CONFIG.server_setup, &register_message, username.as_bytes())
- .map_err(comm_opaque2::grpc::protocol_error_to_grpc_status)?;
+ .map_err(protocol_error_to_grpc_status)?;
let key_info = KeyPayload::from_str(&payload)
.map_err(|_| tonic::Status::invalid_argument("malformed payload"))?;
let registration_state = UserRegistrationInfo {
@@ -168,7 +172,7 @@
let server_registration = comm_opaque2::server::Registration::new();
let password_file = server_registration
.finish(&message.opaque_registration_upload)
- .map_err(comm_opaque2::grpc::protocol_error_to_grpc_status)?;
+ .map_err(protocol_error_to_grpc_status)?;
let device_id = state.flattened_device_key_upload.device_id_key.clone();
let user_id = self
@@ -221,9 +225,83 @@
async fn login_password_user_start(
&self,
- _request: tonic::Request<OpaqueLoginStartRequest>,
+ request: tonic::Request<OpaqueLoginStartRequest>,
) -> Result<tonic::Response<OpaqueLoginStartResponse>, tonic::Status> {
- unimplemented!();
+ let message = request.into_inner();
+
+ let password_file_bytes = self
+ .client
+ .get_password_file_from_username(&message.username)
+ .await
+ .map_err(handle_db_error)?
+ .ok_or(tonic::Status::not_found("user not found"))?;
+
+ if let client_proto::OpaqueLoginStartRequest {
+ opaque_login_request: login_message,
+ username,
+ device_key_upload:
+ Some(client_proto::DeviceKeyUpload {
+ device_key_info:
+ Some(client_proto::IdentityKeyInfo {
+ payload,
+ payload_signature,
+ social_proof: _social_proof,
+ }),
+ identity_upload:
+ Some(client_proto::PreKey {
+ pre_key: identity_prekey,
+ pre_key_signature: identity_prekey_signature,
+ }),
+ notif_upload:
+ Some(client_proto::PreKey {
+ pre_key: notif_prekey,
+ pre_key_signature: notif_prekey_signature,
+ }),
+ onetime_identity_prekeys,
+ onetime_notif_prekeys,
+ }),
+ } = message
+ {
+ let mut server_login = comm_opaque2::server::Login::new();
+ let server_response = server_login
+ .start(
+ &CONFIG.server_setup,
+ &password_file_bytes,
+ &login_message,
+ username.as_bytes(),
+ )
+ .map_err(protocol_error_to_grpc_status)?;
+
+ let key_info = KeyPayload::from_str(&payload)
+ .map_err(|_| tonic::Status::invalid_argument("malformed payload"))?;
+ let login_state = UserLoginInfo {
+ opaque_server_login: server_login,
+ flattened_device_key_upload: FlattenedDeviceKeyUpload {
+ device_id_key: key_info.primary_identity_public_keys.curve25519,
+ key_payload: payload,
+ key_payload_signature: payload_signature,
+ identity_prekey,
+ identity_prekey_signature,
+ identity_onetime_keys: onetime_identity_prekeys,
+ notif_prekey,
+ notif_prekey_signature,
+ notif_onetime_keys: onetime_notif_prekeys,
+ },
+ };
+ let session_id = generate_uuid();
+ self
+ .cache
+ .insert(session_id.clone(), WorkflowInProgress::Login(login_state))
+ .await;
+
+ let response = Response::new(OpaqueLoginStartResponse {
+ session_id,
+ opaque_login_response: server_response,
+ });
+ Ok(response)
+ } else {
+ Err(tonic::Status::invalid_argument("unexpected message data"))
+ }
}
async fn login_password_user_finish(
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
@@ -105,36 +105,6 @@
}
}
- pub async fn get_pake_registration(
- &self,
- user_id: String,
- ) -> Result<Option<ServerRegistration<Cipher>>, Error> {
- match self.get_item_from_users_table(&user_id).await {
- Ok(GetItemOutput {
- item: Some(mut item),
- ..
- }) => parse_registration_data_attribute(
- item.remove(USERS_TABLE_REGISTRATION_ATTRIBUTE),
- )
- .map(Some)
- .map_err(Error::Attribute),
- Ok(_) => {
- info!(
- "No item found for user {} in PAKE registration table",
- user_id
- );
- Ok(None)
- }
- Err(e) => {
- error!(
- "DynamoDB client failed to get registration data for user {}: {}",
- user_id, e
- );
- Err(e)
- }
- }
- }
-
pub async fn add_user_to_users_table(
&self,
registration_state: UserRegistrationInfo,
@@ -397,11 +367,11 @@
Ok(result.is_some())
}
- pub async fn get_user_id_from_user_info(
+ async fn get_user_from_user_info(
&self,
user_info: String,
auth_type: AuthType,
- ) -> Result<Option<String>, Error> {
+ ) -> Result<Option<HashMap<String, AttributeValue>>, Error> {
let (index, attribute_name) = match auth_type {
AuthType::Password => {
(USERS_TABLE_USERNAME_INDEX, USERS_TABLE_USERNAME_ATTRIBUTE)
@@ -422,8 +392,7 @@
.await
{
Ok(QueryOutput {
- items: Some(mut items),
- ..
+ items: Some(items), ..
}) => {
let num_items = items.len();
if num_items == 0 {
@@ -435,12 +404,8 @@
num_items, attribute_name, user_info, items
);
}
- parse_string_attribute(
- USERS_TABLE_PARTITION_KEY,
- items[0].remove(USERS_TABLE_PARTITION_KEY),
- )
- .map(Some)
- .map_err(Error::Attribute)
+ let first_item = items[0].clone();
+ Ok(Some(first_item))
}
Ok(_) => {
info!(
@@ -451,7 +416,7 @@
}
Err(e) => {
error!(
- "DynamoDB client failed to get user ID from {} {}: {}",
+ "DynamoDB client failed to get user from {} {}: {}",
attribute_name, user_info, e
);
Err(Error::AwsSdk(e.into()))
@@ -459,6 +424,56 @@
}
}
+ pub async fn get_user_id_from_user_info(
+ &self,
+ user_info: String,
+ auth_type: AuthType,
+ ) -> Result<Option<String>, Error> {
+ match self
+ .get_user_from_user_info(user_info.clone(), auth_type)
+ .await
+ {
+ Ok(Some(mut user)) => parse_string_attribute(
+ USERS_TABLE_PARTITION_KEY,
+ user.remove(USERS_TABLE_PARTITION_KEY),
+ )
+ .map(Some)
+ .map_err(Error::Attribute),
+ Ok(_) => Ok(None),
+ Err(e) => Err(e),
+ }
+ }
+
+ pub async fn get_password_file_from_username(
+ &self,
+ username: &str,
+ ) -> Result<Option<Vec<u8>>, Error> {
+ match self
+ .get_user_from_user_info(username.to_string(), AuthType::Password)
+ .await
+ {
+ Ok(Some(mut user)) => parse_registration_data_attribute(
+ user.remove(USERS_TABLE_REGISTRATION_ATTRIBUTE),
+ )
+ .map(Some)
+ .map_err(Error::Attribute),
+ Ok(_) => {
+ info!(
+ "No item found for user {} in PAKE registration table",
+ username
+ );
+ Ok(None)
+ }
+ Err(e) => {
+ error!(
+ "DynamoDB client failed to get registration data for user {}: {}",
+ username, e
+ );
+ Err(e)
+ }
+ }
+ }
+
pub async fn get_item_from_users_table(
&self,
user_id: &str,
@@ -673,19 +688,10 @@
fn parse_registration_data_attribute(
attribute: Option<AttributeValue>,
-) -> Result<ServerRegistration<Cipher>, DBItemError> {
- match &attribute {
+) -> Result<Vec<u8>, DBItemError> {
+ match attribute {
Some(AttributeValue::B(server_registration_bytes)) => {
- match ServerRegistration::<Cipher>::deserialize(
- server_registration_bytes.as_ref(),
- ) {
- Ok(server_registration) => Ok(server_registration),
- Err(e) => Err(DBItemError::new(
- USERS_TABLE_REGISTRATION_ATTRIBUTE,
- attribute,
- DBItemAttributeError::Pake(e),
- )),
- }
+ Ok(server_registration_bytes.into_inner())
}
Some(_) => Err(DBItemError::new(
USERS_TABLE_REGISTRATION_ATTRIBUTE,
diff --git a/shared/comm-opaque2/src/server/login.rs b/shared/comm-opaque2/src/server/login.rs
--- a/shared/comm-opaque2/src/server/login.rs
+++ b/shared/comm-opaque2/src/server/login.rs
@@ -7,6 +7,7 @@
use crate::Cipher;
+#[derive(Clone)]
pub struct Login {
state: Option<ServerLogin<Cipher>>,
rng: OsRng,

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 28, 1:10 PM (8 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2726747
Default Alt Text
D7538.diff (9 KB)

Event Timeline