use std::sync::Arc; use opaque_ke::rand::rngs::OsRng; use tokio::sync::Mutex; use nkode_protocol::opaque::client::{AuthenticationData, OpaqueAuthentication, ClientAuthError}; use nkode_protocol::opaque::in_memory_auth_repo::InMemoryAuthRepo; use nkode_protocol::opaque::in_memory_auth_session::InMemoryAuthSession; use nkode_protocol::opaque::in_memory_transport::{InMemoryKeyServer, InMemoryCodeServer, SharedServer}; use nkode_protocol::opaque::models::NKodeServerSetup; use nkode_protocol::opaque::server::{Code, Key, OpaqueAuth}; #[tokio::test] async fn opaque_key_registration_and_login_roundtrip() { let mut rng = OsRng; let server_setup = NKodeServerSetup::new(&mut rng); let mut server = InMemoryKeyServer::new(server_setup); let auth = AuthenticationData::from_secret_key("a@b.com", b"supersecret16bytes"); OpaqueAuthentication::register(&auth, &mut server) .await .expect("registration should succeed"); let session_key = OpaqueAuthentication::login(&auth, &mut server) .await .expect("login should succeed"); assert!(!session_key.is_empty()); } #[tokio::test] async fn opaque_code_registration_and_login_roundtrip() { let mut rng = OsRng; let server_setup = NKodeServerSetup::new(&mut rng); let shared = Arc::new(Mutex::new(OpaqueAuth::new( server_setup, InMemoryAuthRepo::new(), InMemoryAuthSession::new(), ))); let mut key_server = SharedServer::::new(shared.clone()); let mut code_server = SharedServer::::new(shared.clone()); let email = "c@d.com"; let key_auth = AuthenticationData::from_secret_key(email, b"supersecret16bytes"); OpaqueAuthentication::register(&key_auth, &mut key_server) .await .expect("key registration should succeed"); let code = vec![1usize, 2, 3, 4, 5, 6]; let code_auth = AuthenticationData::from_code(email, &code); OpaqueAuthentication::register(&code_auth, &mut code_server) .await .expect("code registration should succeed after key exists"); let session_key = OpaqueAuthentication::login(&code_auth, &mut code_server) .await .expect("login should succeed"); assert!(!session_key.is_empty()); } #[tokio::test] async fn opaque_login_fails_if_not_registered() { let mut rng = OsRng; let server_setup = NKodeServerSetup::new(&mut rng); let mut server = InMemoryKeyServer::new(server_setup); let auth = AuthenticationData::from_secret_key("nope@nope.com", b"supersecret16bytes"); let err = OpaqueAuthentication::login(&auth, &mut server) .await .expect_err("login should fail if user not registered"); match err { ClientAuthError::Transport(_) => {} other => panic!("unexpected error: {other:?}"), } } #[tokio::test] async fn cannot_register_code_before_key() { let mut rng = OsRng; let server_setup = NKodeServerSetup::new(&mut rng); let mut server = InMemoryCodeServer::new(server_setup); let auth = AuthenticationData::from_code("x@y.com", &[1usize,2,3,4]); let err = OpaqueAuthentication::register(&auth, &mut server) .await .expect_err("should fail because key is not registered"); match err { ClientAuthError::Transport(msg) => { assert!(msg.contains("KeyNotRegistered"), "msg was: {msg}"); } other => panic!("unexpected error: {other:?}"), } }