diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs index 608602b41..10984ec3f 100644 --- a/services/identity/src/client_service.rs +++ b/services/identity/src/client_service.rs @@ -1,117 +1,126 @@ pub mod client_proto { tonic::include_proto!("identity.client"); } use crate::client_service::client_proto::{ - DeleteUserRequest, DeviceKeysForUserRequest, DeviceKeysForUserResponse, - Empty, GenerateNonceResponse, KeyserverKeysRequest, KeyserverKeysResponse, - OpaqueLoginFinishRequest, OpaqueLoginFinishResponse, OpaqueLoginStartRequest, - OpaqueLoginStartResponse, RefreshUserPreKeysRequest, - RegistrationFinishRequest, RegistrationFinishResponse, - RegistrationStartRequest, RegistrationStartResponse, - UpdateUserPasswordFinishRequest, UpdateUserPasswordFinishResponse, - UpdateUserPasswordStartRequest, UpdateUserPasswordStartResponse, - UploadOneTimeKeysRequest, WalletLoginRequest, WalletLoginResponse, + DeleteUserRequest, Empty, GenerateNonceResponse, KeyserverKeysRequest, + KeyserverKeysResponse, OpaqueLoginFinishRequest, OpaqueLoginFinishResponse, + OpaqueLoginStartRequest, OpaqueLoginStartResponse, + ReceiverKeysForUserRequest, ReceiverKeysForUserResponse, + RefreshUserPreKeysRequest, RegistrationFinishRequest, + RegistrationFinishResponse, RegistrationStartRequest, + RegistrationStartResponse, SenderKeysForUserRequest, + SenderKeysForUserResponse, UpdateUserPasswordFinishRequest, + UpdateUserPasswordFinishResponse, UpdateUserPasswordStartRequest, + UpdateUserPasswordStartResponse, UploadOneTimeKeysRequest, + WalletLoginRequest, WalletLoginResponse, }; pub use client_proto::identity_client_service_server::{ IdentityClientService, IdentityClientServiceServer, }; #[derive(derive_more::Constructor)] pub struct ClientService {} #[tonic::async_trait] impl IdentityClientService for ClientService { async fn register_password_user_start( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn register_password_user_finish( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn update_user_password_start( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn update_user_password_finish( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn login_password_user_start( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn login_password_user_finish( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn login_wallet_user( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn delete_user( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn generate_nonce( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } - async fn get_device_keys_for_user( + async fn get_receiver_keys_for_user( &self, - _request: tonic::Request, - ) -> Result, tonic::Status> { + _request: tonic::Request, + ) -> Result, tonic::Status> { + unimplemented!(); + } + + async fn get_sender_keys_for_user( + &self, + _request: tonic::Request, + ) -> Result, tonic::Status> { unimplemented!(); } async fn get_keyserver_keys( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn upload_one_time_keys( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } async fn refresh_user_pre_keys( &self, _request: tonic::Request, ) -> Result, tonic::Status> { unimplemented!(); } } diff --git a/shared/protos/identity_client.proto b/shared/protos/identity_client.proto index e7fffbc9e..467690af4 100644 --- a/shared/protos/identity_client.proto +++ b/shared/protos/identity_client.proto @@ -1,290 +1,302 @@ syntax = "proto3"; package identity.client; // RPCs from a client (iOS, Android, or web) to identity service service IdentityClientService { // Account actions // Called by user to register with the Identity Service (PAKE only) // Due to limitations of grpc-web, the Opaque challenge+response // needs to be split up over two unary requests // Start/Finish is used here to align with opaque protocol rpc RegisterPasswordUserStart(RegistrationStartRequest) returns ( RegistrationStartResponse) {} rpc RegisterPasswordUserFinish(RegistrationFinishRequest) returns ( RegistrationFinishResponse) {} // Called by user to update password and receive new access token rpc UpdateUserPasswordStart(UpdateUserPasswordStartRequest) returns (UpdateUserPasswordStartResponse) {} rpc UpdateUserPasswordFinish(UpdateUserPasswordFinishRequest) returns (UpdateUserPasswordFinishResponse) {} // Called by user to register device and get an access token rpc LoginPasswordUserStart(OpaqueLoginStartRequest) returns (OpaqueLoginStartResponse) {} rpc LoginPasswordUserFinish(OpaqueLoginFinishRequest) returns (OpaqueLoginFinishResponse) {} rpc LoginWalletUser(WalletLoginRequest) returns (WalletLoginResponse) {} // Called by a user to delete their own account rpc DeleteUser(DeleteUserRequest) returns (Empty) {} // Sign-In with Ethereum actions // Called by clients to get a nonce for a Sign-In with Ethereum message rpc GenerateNonce(Empty) returns (GenerateNonceResponse) {} // X3DH actions // Called by clients to get all device keys associated with a user in order - // to open a new channel of communication on any of their devices - rpc GetDeviceKeysForUser(DeviceKeysForUserRequest) returns - (DeviceKeysForUserResponse) {} + // to open a new channel of communication on any of their devices. + // Specially, this will return the following per device: + // - Identity keys + // - PreKey (including preKey signature) + // - One-time PreKey + rpc GetReceiverKeysForUser(ReceiverKeysForUserRequest) returns + (ReceiverKeysForUserResponse) {} + // Called by receivers of a communication request. The reponse will only + // return identity and prekeys per device, but will not contain one-time keys. + rpc GetSenderKeysForUser(SenderKeysForUserRequest) returns + (SenderKeysForUserResponse) {} // Called by clients to get required keys for opening a connection // to a keyserver rpc GetKeyserverKeys(KeyserverKeysRequest) returns (KeyserverKeysResponse) {} // Replenish one-time preKeys rpc UploadOneTimeKeys(UploadOneTimeKeysRequest) returns (Empty) {} // Rotate a devices preKey and preKey signature // Rotated for deniability of older messages rpc RefreshUserPreKeys(RefreshUserPreKeysRequest) returns (Empty) {} } // Helper types message Empty {} +message PreKey { + string preKey = 1; + string preKeySignature = 2; +} + // Key information needed for starting a X3DH session message IdentityKeyInfo { // JSON payload containing Olm Identity keys // Sessions for users will contain both IdentityKeys and NotifKeys // For keyservers, this will only contain IdentityKeys string payload = 1; // Payload signed with the signing ed25519 key string payloadSignature = 2; // Signed message used for SIWE (optional) // This correlates a given wallet with the identity of a device optional string socialProof = 3; } -// Ephemeral information provided to create initial message -// Prekeys are generally rotated periodically -// One-time Prekeys are "consumed" after first use -message PreKeyResponse { - // Rotating preKey, validated to be associatd with IdentityKeys - // through signature - string preKey = 4; - string preKeySignature = 5; - // One time key, removed from available list of one time keys after requested - // Client is also intended to remove OPKs after initial message - optional string onetimePrekey = 6; -} - -// Information needed when establishing communication to someone else's device -message RemoteDeviceInfo { - IdentityKeyInfo identityInfo = 1; - PreKeyResponse identityPrekeys = 2; - PreKeyResponse notifPrekeys = 3; -} - -// Information needed when establishing communication to a keyserver -message KeyserverSessionInfo { - IdentityKeyInfo identityInfo = 1; - PreKeyResponse identityPrekeys = 2; -} - // RegisterUser // Ephemeral information provided so others can create initial message // to this device // // Prekeys are generally rotated periodically // One-time Prekeys are "consumed" after first use, so many need to // be provide to avoid exhausting them. -message PreKeyRegistrationUpload { - // Rotating preKey, validated to be associatd with IdentityKeys - // through signature - string preKey = 1; - string preKeySignature = 2; - // One time keys - // Removed from available list after requested by another client - repeated string onetimePrekeys = 3; -} // Bundle of information needed for creating an initial message using X3DH message DeviceKeyUpload { IdentityKeyInfo deviceKeyInfo = 1; - PreKeyRegistrationUpload identityUpload = 2; - PreKeyRegistrationUpload notifUpload = 3; + PreKey identityUpload = 2; + PreKey notifUpload = 3; + repeated string onetimeIdentityPrekeys = 4; + repeated string onetimeNotifPrekeys = 5; } // Request for registering a new user message RegistrationStartRequest { // Message sent to initiate PAKE registration (step 1) bytes opaqueRegistrationRequest = 1; string username = 2; // Information needed to open a new channel to current user's device DeviceKeyUpload deviceKeyUpload = 3; } // Messages sent from a client to Identity Service message RegistrationFinishRequest { // Identifier to correlate RegisterStart session string sessionID = 1; // Final message in PAKE registration bytes opaqueRegistrationUpload = 2; } // Messages sent from Identity Service to client message RegistrationStartResponse { // Identifier used to correlate start request with finish request string sessionID = 1; // sent to the user upon reception of the PAKE registration attempt // (step 2) bytes opaqueRegistrationResponse = 2; } message RegistrationFinishResponse { // After successful unpacking of user credentials, return token string accessToken = 2; } // UpdateUserPassword // Request for updating a user, similar to registration but need a // access token to validate user before updating password message UpdateUserPasswordStartRequest { // Message sent to initiate PAKE registration (step 1) bytes opaqueRegistrationRequest = 1; // Used to validate user, before attempting to update password string accessToken = 3; } // Do a user registration, but overwrite the existing credentials // after validation of user message UpdateUserPasswordFinishRequest { // Identifier used to correlate start and finish request string sessionID = 1; // Opaque client registration upload (step 3) bytes opaqueRegistrationUpload = 2; } message UpdateUserPasswordStartResponse { // Identifier used to correlate start request with finish request string sessionID = 1; bytes opaqueRegistrationResponse = 2; } message UpdateUserPasswordFinishResponse { // After validating client reponse, mint a new token string accessToken = 2; } // LoginUser message OpaqueLoginStartRequest { string username = 1; // Message sent to initiate PAKE login (step 1) bytes opaqueLoginRequest = 2; // Information specific to a user's device needed to open a new channel of // communication with this user DeviceKeyUpload deviceKeyUpload = 3; } message OpaqueLoginFinishRequest { // Identifier used to correlate start request with finish request string sessionID = 1; // Message containing client's reponse to server challenge. // Used to verify that client holds password secret (Step 3) bytes opaqueLoginUpload = 2; } message OpaqueLoginStartResponse { // Identifier used to correlate start request with finish request string sessionID = 1; // Opaque challenge sent from server to client attempting to login (Step 2) bytes opaqueLoginResponse = 2; } message OpaqueLoginFinishResponse { // Mint and return a new key upon successful login string accessToken = 2; } message WalletLoginRequest { // ed25519 key for the given user's device string siweMessage = 1; string siweSignature = 2; // Information specific to a user's device needed to open a new channel of // communication with this user DeviceKeyUpload deviceKeyUpload = 3; } message WalletLoginResponse { string accessToken = 1; } // DeleteUser message DeleteUserRequest { string accessToken = 1; } // GenerateNonce message GenerateNonceResponse{ string nonce = 1; } -// GetDeviceKeysForUser +// GetReceiverKeysForUser + +// Information needed when establishing communication to someone else's device +message ReceiverKeyInfo { + IdentityKeyInfo identityInfo = 1; + PreKey identityPrekey = 2; + PreKey notifPrekey = 3; + optional string onetimeIdentityPrekey = 4; + optional string onetimeNotifPrekey = 5; +} -message DeviceKeysForUserRequest { +// Information needed by a device to establish communcation when responding +// to a request. +// The device receiving a request only needs the identity and prekeys. +message ReceiverKeysForUserRequest { oneof identifier { string username = 1; string walletAddress = 2; } } -message DeviceKeysForUserResponse { +message ReceiverKeysForUserResponse { // Map is keyed on devices' public ed25519 key used for signing - map devices = 1; + map devices = 1; +} + +// GetSenderKeysForUser + +message SenderKeyInfo { + IdentityKeyInfo identityInfo = 1; + PreKey identityPrekey = 2; + PreKey notifPrekey = 3; +} + +message SenderKeysForUserRequest { + oneof identifier { + string username = 1; + string walletAddress = 2; + } +} + +message SenderKeysForUserResponse { + // Map is keyed on devices' public ed25519 key used for signing + map devices = 1; } // GetKeyserverKeys +// Information needed when establishing communication to a keyserver +message KeyserverSessionInfo { + IdentityKeyInfo identityInfo = 1; + PreKey identityPrekeys = 2; + optional string onetimeIdentityPrekey = 5; +} + // All keyserver must be registered with an existing user. // Conversely, one or zero keyservers can registered to a user. message KeyserverKeysRequest { oneof identifier { string username = 1; string walletAddress = 2; } } message KeyserverKeysResponse { KeyserverSessionInfo keyserverInfo = 1; } // UploadOneTimeKeys // As OPKs get exhausted, they need to be refreshed message UploadOneTimeKeysRequest { // Use device associated with token to insert OPKs string accessToken = 1; repeated string oneTimePreKeys = 2; } // RefreshUserPreKeys -message PreKeyUpload { - // Rotating preKey, validated to be associatd with IdentityKeys - // through signature - string preKey = 1; - string preKeySignature = 2; -} - message RefreshUserPreKeysRequest { string accessToken = 1; - PreKeyUpload newPreKeys = 2; + PreKey newPreKeys = 2; }