diff --git a/native/cpp/CommonCpp/CryptoTools/opaque-ke-cxx/src/lib.rs b/native/cpp/CommonCpp/CryptoTools/opaque-ke-cxx/src/lib.rs --- a/native/cpp/CommonCpp/CryptoTools/opaque-ke-cxx/src/lib.rs +++ b/native/cpp/CommonCpp/CryptoTools/opaque-ke-cxx/src/lib.rs @@ -4,15 +4,17 @@ use opaque_ke::ciphersuite::CipherSuite; use opaque_ke::errors::{InternalPakeError, ProtocolError}; use opaque_ke::hash::Hash; +use opaque_ke::keypair::Key; use opaque_ke::slow_hash::SlowHash; use opaque_ke::{ ClientLogin, ClientLoginFinishParameters, ClientLoginFinishResult, ClientLoginStartParameters, ClientLoginStartResult, ClientRegistration, ClientRegistrationFinishParameters, - ClientRegistrationFinishResult, ClientRegistrationStartResult, CredentialResponse, - RegistrationResponse, + ClientRegistrationFinishResult, ClientRegistrationStartResult, CredentialFinalization, + CredentialRequest, CredentialResponse, RegistrationRequest, RegistrationResponse, + RegistrationUpload, ServerLogin, ServerLoginFinishResult, ServerLoginStartParameters, + ServerLoginStartResult, ServerRegistration, ServerRegistrationStartResult, }; use rand::rngs::OsRng; -use std::ops::Deref; struct Cipher; @@ -57,6 +59,14 @@ private: Vec, } + struct PasswordFile { + file: Vec, + } + + struct SessionKey { + key: Vec, + } + extern "Rust" { fn client_register_cxx(password: String) -> Result; fn client_register_finish_cxx( @@ -69,6 +79,23 @@ server_message: Vec, ) -> Result; fn server_kp() -> ServerKeyPair; + fn server_register_cxx( + registration_request: Vec, + server_public_key: Vec, + ) -> Result; + fn server_register_finish_cxx( + server_register_state: Vec, + client_message: Vec, + ) -> Result; + fn server_login_cxx( + password_file: Vec, + server_private_key: Vec, + login_request: Vec, + ) -> Result; + fn server_login_finish_cxx( + server_login_state: Vec, + client_message: Vec, + ) -> Result; } } @@ -165,14 +192,117 @@ fn server_kp() -> ffi::ServerKeyPair { let mut rng = OsRng; let keypair = Cipher::generate_random_keypair(&mut rng); - let public_key = keypair.public().deref().to_vec(); - let private_key = keypair.private().deref().to_vec(); + let public_key = keypair.public().to_vec(); + let private_key = keypair.private().to_vec(); ffi::ServerKeyPair { public: public_key, private: private_key, } } +fn server_register_cxx( + registration_request: Vec, + server_public_key: Vec, +) -> Result { + let registration_request = RegistrationRequest::::deserialize(®istration_request)?; + let server_public_key = Key::from_bytes(&server_public_key)?; + + let s = server_register(registration_request, &server_public_key)?; + + let message_bytes = s.message.serialize(); + let state_bytes = s.state.serialize(); + + Ok(ffi::MessageState { + message: message_bytes, + state: state_bytes, + }) +} + +fn server_register_finish_cxx( + server_register_state: Vec, + client_message: Vec, +) -> Result { + let server_register_state = ServerRegistration::::deserialize(&server_register_state)?; + let client_message = RegistrationUpload::::deserialize(&client_message)?; + + let s = server_register_finish(server_register_state, client_message)?; + + let password_file_bytes = s.serialize(); + + Ok(ffi::PasswordFile { + file: password_file_bytes, + }) +} + +fn server_login_cxx( + password_file: Vec, + server_private_key: Vec, + login_request: Vec, +) -> Result { + let password_file = ServerRegistration::::deserialize(&password_file)?; + let server_private_key = Key::from_bytes(&server_private_key)?; + let login_request = CredentialRequest::::deserialize(&login_request)?; + + let s = server_login(password_file, &server_private_key, login_request)?; + + let message_bytes = s.message.serialize()?; + let state_bytes = s.state.serialize()?; + + Ok(ffi::MessageState { + message: message_bytes, + state: state_bytes, + }) +} + +fn server_login_finish_cxx( + server_login_state: Vec, + client_message: Vec, +) -> Result { + let server_login_state = ServerLogin::::deserialize(&server_login_state)?; + let client_message = CredentialFinalization::::deserialize(&client_message)?; + + let s = server_login_finish(server_login_state, client_message)?; + + Ok(ffi::SessionKey { key: s.session_key }) +} + +fn server_register( + registration_request: RegistrationRequest, + server_public_key: &Key, +) -> Result, ProtocolError> { + let mut server_rng = OsRng; + ServerRegistration::::start(&mut server_rng, registration_request, server_public_key) +} + +fn server_register_finish( + server_register_state: ServerRegistration, + client_message: RegistrationUpload, +) -> Result, ProtocolError> { + server_register_state.finish(client_message) +} + +fn server_login( + password_file: ServerRegistration, + server_private_key: &Key, + login_request: CredentialRequest, +) -> Result, ProtocolError> { + let mut server_rng = OsRng; + ServerLogin::start( + &mut server_rng, + password_file, + server_private_key, + login_request, + ServerLoginStartParameters::default(), + ) +} + +fn server_login_finish( + server_login_state: ServerLogin, + client_message: CredentialFinalization, +) -> Result, ProtocolError> { + server_login_state.finish(client_message) +} + #[cfg(test)] mod tests { use super::*; @@ -389,4 +519,388 @@ assert_eq!(keys.public.len(), 32); assert_eq!(keys.private.len(), 32); } + + #[test] + fn test_server_register_cxx_ok() { + let password = "hunter2"; + let mut client_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, password.as_bytes()).unwrap(); + let mut rng = OsRng; + let server_kp = Cipher::generate_random_keypair(&mut rng); + assert!(server_register_cxx( + client_registration_start_result.message.serialize(), + server_kp.public().to_vec() + ) + .is_ok()) + } + + #[test] + fn test_server_register_cxx_err_request_deserialization_failed() { + let mut rng = OsRng; + let server_kp = Cipher::generate_random_keypair(&mut rng); + assert!(server_register_cxx(vec![], server_kp.public().to_vec()).is_err()) + } + + #[test] + fn test_server_register_cxx_err_key_deserialization_failed() { + let password = "hunter2"; + let mut client_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, password.as_bytes()).unwrap(); + assert!( + server_register_cxx(client_registration_start_result.message.serialize(), vec![]).is_err() + ) + } + + #[test] + fn test_server_register_finish_cxx_ok() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + let client_registration_finish_result = client_registration_start_result + .state + .finish( + &mut client_rng, + server_registration_start_result.message, + ClientRegistrationFinishParameters::default(), + ) + .unwrap(); + assert!(server_register_finish_cxx( + server_registration_start_result.state.serialize(), + client_registration_finish_result.message.serialize() + ) + .is_ok()); + } + + #[test] + fn test_server_register_finish_cxx_err_state_deserialization_failed() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + let client_registration_finish_result = client_registration_start_result + .state + .finish( + &mut client_rng, + server_registration_start_result.message, + ClientRegistrationFinishParameters::default(), + ) + .unwrap(); + assert!(server_register_finish_cxx( + vec![], + client_registration_finish_result.message.serialize() + ) + .is_err()); + } + + #[test] + fn test_server_register_finish_cxx_err_message_deserialization_failed() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + assert!( + server_register_finish_cxx(server_registration_start_result.state.serialize(), vec![]) + .is_err() + ); + } + + #[test] + fn test_server_login_cxx_ok() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + let client_registration_finish_result = client_registration_start_result + .state + .finish( + &mut client_rng, + server_registration_start_result.message, + ClientRegistrationFinishParameters::default(), + ) + .unwrap(); + let p_file = server_registration_start_result + .state + .finish(client_registration_finish_result.message) + .unwrap(); + let client_login_start_result = ClientLogin::::start( + &mut client_rng, + b"hunter2", + ClientLoginStartParameters::default(), + ) + .unwrap(); + assert!(server_login_cxx( + p_file.serialize(), + server_kp.private().to_vec(), + client_login_start_result.message.serialize().unwrap() + ) + .is_ok()); + } + + #[test] + fn test_server_login_cxx_err_password_file_deserialization_failed() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let client_login_start_result = ClientLogin::::start( + &mut client_rng, + b"hunter2", + ClientLoginStartParameters::default(), + ) + .unwrap(); + assert!(server_login_cxx( + vec![], + server_kp.private().to_vec(), + client_login_start_result.message.serialize().unwrap() + ) + .is_err()); + } + + #[test] + fn test_server_login_cxx_err_private_key_deserialization_failed() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + let client_registration_finish_result = client_registration_start_result + .state + .finish( + &mut client_rng, + server_registration_start_result.message, + ClientRegistrationFinishParameters::default(), + ) + .unwrap(); + let p_file = server_registration_start_result + .state + .finish(client_registration_finish_result.message) + .unwrap(); + let client_login_start_result = ClientLogin::::start( + &mut client_rng, + b"hunter2", + ClientLoginStartParameters::default(), + ) + .unwrap(); + assert!(server_login_cxx( + p_file.serialize(), + vec![], + client_login_start_result.message.serialize().unwrap() + ) + .is_err()); + } + + #[test] + fn test_server_login_cxx_err_login_request_deserialization_failed() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + let client_registration_finish_result = client_registration_start_result + .state + .finish( + &mut client_rng, + server_registration_start_result.message, + ClientRegistrationFinishParameters::default(), + ) + .unwrap(); + let p_file = server_registration_start_result + .state + .finish(client_registration_finish_result.message) + .unwrap(); + assert!(server_login_cxx(p_file.serialize(), server_kp.private().to_vec(), vec![]).is_err()); + } + + #[test] + fn test_server_login_finish_cxx_ok() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + let client_registration_finish_result = client_registration_start_result + .state + .finish( + &mut client_rng, + server_registration_start_result.message, + ClientRegistrationFinishParameters::default(), + ) + .unwrap(); + let p_file = server_registration_start_result + .state + .finish(client_registration_finish_result.message) + .unwrap(); + let client_login_start_result = ClientLogin::::start( + &mut client_rng, + b"hunter2", + ClientLoginStartParameters::default(), + ) + .unwrap(); + let server_login_start_result = ServerLogin::start( + &mut server_rng, + p_file, + &server_kp.private(), + client_login_start_result.message, + ServerLoginStartParameters::default(), + ) + .unwrap(); + let client_login_finish_result = client_login_start_result + .state + .finish( + server_login_start_result.message, + ClientLoginFinishParameters::default(), + ) + .unwrap(); + assert!(server_login_finish_cxx( + server_login_start_result.state.serialize().unwrap(), + client_login_finish_result.message.serialize().unwrap() + ) + .is_ok()); + } + + #[test] + fn test_server_login_finish_cxx_err_state_deserialization_failed() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + let client_registration_finish_result = client_registration_start_result + .state + .finish( + &mut client_rng, + server_registration_start_result.message, + ClientRegistrationFinishParameters::default(), + ) + .unwrap(); + let p_file = server_registration_start_result + .state + .finish(client_registration_finish_result.message) + .unwrap(); + let client_login_start_result = ClientLogin::::start( + &mut client_rng, + b"hunter2", + ClientLoginStartParameters::default(), + ) + .unwrap(); + let server_login_start_result = ServerLogin::start( + &mut server_rng, + p_file, + &server_kp.private(), + client_login_start_result.message, + ServerLoginStartParameters::default(), + ) + .unwrap(); + let client_login_finish_result = client_login_start_result + .state + .finish( + server_login_start_result.message, + ClientLoginFinishParameters::default(), + ) + .unwrap(); + assert!(server_login_finish_cxx( + vec![], + client_login_finish_result.message.serialize().unwrap() + ) + .is_err()); + } + + #[test] + fn test_server_login_finish_cxx_err_message_deserialization_failed() { + let mut client_rng = OsRng; + let mut server_rng = OsRng; + let client_registration_start_result = + ClientRegistration::::start(&mut client_rng, b"hunter2").unwrap(); + let server_kp = Cipher::generate_random_keypair(&mut server_rng); + let server_registration_start_result = ServerRegistration::::start( + &mut server_rng, + client_registration_start_result.message, + server_kp.public(), + ) + .unwrap(); + let client_registration_finish_result = client_registration_start_result + .state + .finish( + &mut client_rng, + server_registration_start_result.message, + ClientRegistrationFinishParameters::default(), + ) + .unwrap(); + let p_file = server_registration_start_result + .state + .finish(client_registration_finish_result.message) + .unwrap(); + let client_login_start_result = ClientLogin::::start( + &mut client_rng, + b"hunter2", + ClientLoginStartParameters::default(), + ) + .unwrap(); + let server_login_start_result = ServerLogin::start( + &mut server_rng, + p_file, + &server_kp.private(), + client_login_start_result.message, + ServerLoginStartParameters::default(), + ) + .unwrap(); + assert!( + server_login_finish_cxx(server_login_start_result.state.serialize().unwrap(), vec![]) + .is_err() + ); + } }