use opaque_ke::ciphersuite::CipherSuite; use rand::{CryptoRng, RngCore}; #[derive(thiserror::Error, Debug)] pub enum AuthenticationError { #[error("Protocol error: `{0}`")] ProtocolError(#[from] opaque_ke::errors::ProtocolError), } pub type AuthenticationResult = std::result::Result; /// The ciphersuite trait allows to specify the underlying primitives /// that will be used in the OPAQUE protocol #[allow(dead_code)] pub struct DefaultSuite; impl CipherSuite for DefaultSuite { type Group = curve25519_dalek::ristretto::RistrettoPoint; type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH; type Hash = sha2::Sha512; type SlowHash = opaque_ke::slow_hash::NoOpHash; } /// Client-side code for OPAQUE protocol handling, to register a new user and login. All methods' /// results must be sent to the server using the serialized `.message`. Incoming messages can be /// deserialized using the type's `deserialize` method. #[cfg(feature = "opaque_client")] pub mod client { use super::*; /// Methods to register a new user, from the client side. pub mod registration { use super::*; use opaque_ke::{ ClientRegistration, ClientRegistrationFinishParameters, ClientRegistrationFinishResult, ClientRegistrationStartResult, RegistrationResponse, }; /// Initiate the registration negotiation. pub fn start_registration( password: &str, rng: &mut R, ) -> AuthenticationResult> { Ok(ClientRegistration::::start( rng, password.as_bytes(), )?) } /// Finalize the registration negotiation. pub fn finish_registration( registration_start: ClientRegistration, registration_response: RegistrationResponse, rng: &mut R, ) -> AuthenticationResult> { Ok(registration_start.finish( rng, registration_response, ClientRegistrationFinishParameters::default(), )?) } } /// Methods to login, from the client side. pub mod login { use super::*; use opaque_ke::{ ClientLogin, ClientLoginFinishParameters, ClientLoginFinishResult, ClientLoginStartParameters, ClientLoginStartResult, CredentialResponse, }; /// Initiate the login negotiation. pub fn start_login( password: &str, rng: &mut R, ) -> AuthenticationResult> { Ok(ClientLogin::::start( rng, password.as_bytes(), ClientLoginStartParameters::default(), )?) } /// Finalize the client login negotiation. pub fn finish_login( login_start: ClientLogin, login_response: CredentialResponse, ) -> AuthenticationResult> { Ok(login_start.finish(login_response, ClientLoginFinishParameters::default())?) } } } /// Server-side code for OPAQUE protocol handling, to register a new user and login. The /// intermediate results must be sent to the client using the serialized `.message`. #[cfg(feature = "opaque_server")] pub mod server { use super::*; use opaque_ke::{keypair::Key, ServerRegistration}; /// Methods to register a new user, from the server side. pub mod registration { use super::*; use opaque_ke::{RegistrationRequest, RegistrationUpload, ServerRegistrationStartResult}; /// Start a registration process, from a request sent by the client. /// /// The result must be kept for the next step. pub fn start_registration( rng: &mut R, registration_request: RegistrationRequest, server_public_key: &Key, ) -> AuthenticationResult> { Ok(ServerRegistration::::start( rng, registration_request, server_public_key, )?) } /// Finish to register a new user, and get the data to store in the database. pub fn get_password_file( registration_start: ServerRegistration, registration_upload: RegistrationUpload, ) -> AuthenticationResult> { Ok(registration_start.finish(registration_upload)?) } } /// Methods to handle user login, from the server-side. pub mod login { use super::*; use opaque_ke::{ CredentialFinalization, CredentialRequest, ServerLogin, ServerLoginFinishResult, ServerLoginStartParameters, ServerLoginStartResult, }; /// Start a login process, from a request sent by the client. /// /// The result must be kept for the next step. pub fn start_login( rng: &mut R, password_file: ServerRegistration, server_private_key: &Key, credential_request: CredentialRequest, ) -> AuthenticationResult> { Ok(ServerLogin::start( rng, password_file, server_private_key, credential_request, ServerLoginStartParameters::default(), )?) } /// Finish to authorize a new user, and get the session key to decrypt associated data. pub fn finalize_login( login_start: ServerLogin, credential_finalization: CredentialFinalization, ) -> AuthenticationResult { Ok(login_start.finish(credential_finalization)?) } } }