diff --git a/keyserver/addons/opaque-ke-node/src/lib.rs b/keyserver/addons/opaque-ke-node/src/lib.rs index be27d0ca7..9e5436a7f 100644 --- a/keyserver/addons/opaque-ke-node/src/lib.rs +++ b/keyserver/addons/opaque-ke-node/src/lib.rs @@ -1,146 +1,202 @@ use argon2::Argon2; use digest::generic_array::GenericArray; use digest::Digest; use neon::prelude::*; use neon::types::buffer::TypedArray; use opaque_ke::ciphersuite::CipherSuite; use opaque_ke::errors::InternalPakeError; use opaque_ke::hash::Hash; use opaque_ke::slow_hash::SlowHash; use opaque_ke::{ - ClientRegistration, ClientRegistrationFinishParameters, RegistrationRequest, + ClientLogin, ClientLoginStartParameters, ClientRegistration, + ClientRegistrationFinishParameters, CredentialRequest, RegistrationRequest, RegistrationResponse, RegistrationUpload, }; use rand::rngs::OsRng; struct Cipher; impl CipherSuite for Cipher { type Group = curve25519_dalek::ristretto::RistrettoPoint; type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH; type Hash = sha2::Sha512; type SlowHash = ArgonWrapper; } struct ArgonWrapper(Argon2<'static>); impl SlowHash for ArgonWrapper { fn hash( input: GenericArray::OutputSize>, ) -> Result, InternalPakeError> { let params = Argon2::default(); let mut output = vec![0u8; ::output_size()]; params .hash_password_into(&input, &[0; argon2::MIN_SALT_LEN], &mut output) .map_err(|_| InternalPakeError::SlowHashError)?; Ok(output) } } struct ClientRegistrationStartResult { message: RegistrationRequest, state: ClientRegistration, } impl Finalize for ClientRegistrationStartResult {} struct ClientRegistrationFinishResult { message: RegistrationUpload, } impl Finalize for ClientRegistrationFinishResult {} +struct ClientLoginStartResult { + message: CredentialRequest, + state: ClientLogin, +} + +impl Finalize for ClientLoginStartResult {} + fn client_register_start( mut cx: FunctionContext, ) -> JsResult> { let password = cx.argument::(0)?; let mut client_rng = OsRng; let client_registration_start_result = ClientRegistration::::start( &mut client_rng, password.value(&mut cx).as_bytes(), ) .or_else(|err| cx.throw_error(err.to_string()))?; Ok(cx.boxed(ClientRegistrationStartResult { message: client_registration_start_result.message, state: client_registration_start_result.state, })) } fn get_registration_start_message_array( mut cx: FunctionContext, ) -> JsResult { let client_registration_start_result = cx.argument::>(0)?; Ok(JsArrayBuffer::external( &mut cx, client_registration_start_result.message.serialize(), )) } fn get_registration_start_state_array( mut cx: FunctionContext, ) -> JsResult { let client_registration_start_result = cx.argument::>(0)?; Ok(JsArrayBuffer::external( &mut cx, client_registration_start_result.state.serialize(), )) } fn client_register_finish( mut cx: FunctionContext, ) -> JsResult> { let client_register_state = cx.argument::>(0)?; let server_message = cx.argument::>(1)?; let client_registration = ClientRegistration::::deserialize( client_register_state.as_slice(&cx), ) .or_else(|err| cx.throw_error(err.to_string()))?; let registration_response = RegistrationResponse::::deserialize(server_message.as_slice(&cx)) .or_else(|err| cx.throw_error(err.to_string()))?; let mut client_rng = OsRng; let client_registration_finish_result = ClientRegistrationFinishResult { message: client_registration .finish( &mut client_rng, registration_response, ClientRegistrationFinishParameters::Default, ) .or_else(|err| cx.throw_error(err.to_string()))? .message, }; Ok(cx.boxed(client_registration_finish_result)) } fn get_registration_finish_message_array( mut cx: FunctionContext, ) -> JsResult { let client_registration_finish_result = cx.argument::>(0)?; Ok(JsArrayBuffer::external( &mut cx, client_registration_finish_result.message.serialize(), )) } +fn client_login_start( + mut cx: FunctionContext, +) -> JsResult> { + let password = cx.argument::(0)?; + let mut client_rng = OsRng; + let client_login = ClientLogin::::start( + &mut client_rng, + password.value(&mut cx).as_bytes(), + ClientLoginStartParameters::default(), + ) + .or_else(|err| cx.throw_error(err.to_string()))?; + Ok(cx.boxed(ClientLoginStartResult { + message: client_login.message, + state: client_login.state, + })) +} + +fn get_login_start_message_array( + mut cx: FunctionContext, +) -> JsResult { + let client_login_start_result = + cx.argument::>(0)?; + let login_start_message_vec = + client_login_start_result + .message + .serialize() + .or_else(|err| cx.throw_error(err.to_string()))?; + Ok(JsArrayBuffer::external(&mut cx, login_start_message_vec)) +} + +fn get_login_start_state_array( + mut cx: FunctionContext, +) -> JsResult { + let client_login_start_result = + cx.argument::>(0)?; + let login_start_message_vec = client_login_start_result + .state + .serialize() + .or_else(|err| cx.throw_error(err.to_string()))?; + Ok(JsArrayBuffer::external(&mut cx, login_start_message_vec)) +} + #[neon::main] fn main(mut cx: ModuleContext) -> NeonResult<()> { cx.export_function("clientRegisterStart", client_register_start)?; cx.export_function( "getRegistrationStartMessageArray", get_registration_start_message_array, )?; cx.export_function( "getRegistrationStartStateArray", get_registration_start_state_array, )?; cx.export_function("clientRegisterFinish", client_register_finish)?; cx.export_function( "getRegistrationFinishMessageArray", get_registration_finish_message_array, )?; + cx.export_function("clientLoginStart", client_login_start)?; + cx.export_function( + "getLoginStartMessageArray", + get_login_start_message_array, + )?; + cx.export_function("getLoginStartStateArray", get_login_start_state_array)?; Ok(()) }