implement in-memory server
This commit is contained in:
@@ -1,28 +1,28 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use nkode_rs::nkode_core::keypad::Keypad;
|
use nkode_rs::nkode_core::keypad::Keypad;
|
||||||
use crate::shared::models::app::{OpaqueAPI, AuthAPI, CodeLoginData, CodeLoggedInSession, Icon, IconID, KeyLoggedInSession, ICON_ID_SIZE, LoggedInSession};
|
use crate::shared::models::app::{AuthAPI, CodeLoginData, CodeLoggedInSession, Icon, IconID, KeyLoggedInSession, ICON_ID_SIZE};
|
||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
use crate::shared::models::opaque::{OpaqueLoginSession, UserSecretKey};
|
use crate::shared::models::opaque::{UserSecretKey};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use nkode_rs::nkode_core::nkode_cipher::NKodeCipher;
|
use nkode_rs::nkode_core::nkode_cipher::NKodeCipher;
|
||||||
use nkode_rs::from_bytes::FromBytes;
|
use nkode_rs::from_bytes::FromBytes;
|
||||||
use nkode_rs::nkode_core::chacha20prng::Nonce;
|
use nkode_rs::nkode_core::chacha20prng::Nonce;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use nkode_rs::nkode_core::policy::{NKodePolicy, DEFAULT_POLICY};
|
use nkode_rs::nkode_core::policy::{NKodePolicy, DEFAULT_POLICY};
|
||||||
use crate::client::opaque::{AuthenticationData, OpaqueAuthLogin, OpaqueAuthRegister, ServerConnectionLogin, ServerConnectionRegister};
|
use crate::client::opaque::{AuthenticationData, OpaqueAuth, ServerConnectionLogin, ServerConnectionRegister};
|
||||||
|
|
||||||
pub struct Login;
|
struct Login;
|
||||||
pub struct Register;
|
struct Register;
|
||||||
|
|
||||||
|
|
||||||
pub struct ClientAppKey<State, S: OpaqueAPI> {
|
pub struct ClientAppKey<State, S: AuthAPI> {
|
||||||
api: S,
|
api: S,
|
||||||
email: Email,
|
email: Email,
|
||||||
user_secret_key: UserSecretKey,
|
user_secret_key: UserSecretKey,
|
||||||
_state: PhantomData<State>
|
_state: PhantomData<State>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: OpaqueAPI> ClientAppKey<Register,S> {
|
impl <S: AuthAPI> ClientAppKey<Register,S> {
|
||||||
pub async fn register(self) -> Result<ClientAppKey<Login, S>, String> {
|
pub async fn register(self) -> Result<ClientAppKey<Login, S>, String> {
|
||||||
self.api.register_key(&self.email, &self.user_secret_key).await?;
|
self.api.register_key(&self.email, &self.user_secret_key).await?;
|
||||||
Ok(ClientAppKey {
|
Ok(ClientAppKey {
|
||||||
@@ -34,7 +34,7 @@ impl <S: OpaqueAPI> ClientAppKey<Register,S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: OpaqueAPI> ClientAppKey<Login,S> {
|
impl <S: AuthAPI> ClientAppKey<Login,S> {
|
||||||
pub async fn login(self) -> Result<ClientAppKeyLoggedIn<S>,String> {
|
pub async fn login(self) -> Result<ClientAppKeyLoggedIn<S>,String> {
|
||||||
let key_login = self.api.login_key(&self.email, &self.user_secret_key).await?;
|
let key_login = self.api.login_key(&self.email, &self.user_secret_key).await?;
|
||||||
Ok(ClientAppKeyLoggedIn{
|
Ok(ClientAppKeyLoggedIn{
|
||||||
@@ -46,14 +46,14 @@ impl <S: OpaqueAPI> ClientAppKey<Login,S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClientAppKeyLoggedIn<S: OpaqueAPI> {
|
pub struct ClientAppKeyLoggedIn<S: AuthAPI> {
|
||||||
api: S,
|
api: S,
|
||||||
email: Email,
|
email: Email,
|
||||||
user_secret_key: UserSecretKey,
|
user_secret_key: UserSecretKey,
|
||||||
key_login: KeyLoggedInSession,
|
key_login: KeyLoggedInSession,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: OpaqueAPI + AuthAPI> ClientAppKeyLoggedIn<S> {
|
impl <S: AuthAPI> ClientAppKeyLoggedIn<S> {
|
||||||
pub async fn register_code(self) -> Result<ClientAppCodeRegister<S>, String> {
|
pub async fn register_code(self) -> Result<ClientAppCodeRegister<S>, String> {
|
||||||
let icon_nonce = Nonce::new();
|
let icon_nonce = Nonce::new();
|
||||||
let icons = self.get_icons(&icon_nonce).await?;
|
let icons = self.get_icons(&icon_nonce).await?;
|
||||||
@@ -100,7 +100,7 @@ impl <S: OpaqueAPI + AuthAPI> ClientAppKeyLoggedIn<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClientAppCodeRegister<S: OpaqueAPI> {
|
pub struct ClientAppCodeRegister<S: AuthAPI> {
|
||||||
api: S,
|
api: S,
|
||||||
email: Email,
|
email: Email,
|
||||||
user_secret_key: UserSecretKey,
|
user_secret_key: UserSecretKey,
|
||||||
@@ -110,7 +110,7 @@ pub struct ClientAppCodeRegister<S: OpaqueAPI> {
|
|||||||
keypad: Keypad,
|
keypad: Keypad,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: OpaqueAPI + AuthAPI>ClientAppCodeRegister<S> {
|
impl <S: AuthAPI>ClientAppCodeRegister<S> {
|
||||||
pub async fn register(self, selected_icons: Vec<IconID>) -> Result<ClientAppCodeLogin<S>, String> {
|
pub async fn register(self, selected_icons: Vec<IconID>) -> Result<ClientAppCodeLogin<S>, String> {
|
||||||
let policy = self.api.get_policy().await?;
|
let policy = self.api.get_policy().await?;
|
||||||
let keypad = Keypad::new(policy.clone());
|
let keypad = Keypad::new(policy.clone());
|
||||||
@@ -139,7 +139,7 @@ impl <S: OpaqueAPI + AuthAPI>ClientAppCodeRegister<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClientAppCodeLogin<S: OpaqueAPI> {
|
pub struct ClientAppCodeLogin<S: AuthAPI> {
|
||||||
api: S,
|
api: S,
|
||||||
email: Email,
|
email: Email,
|
||||||
mask: Vec<u64>,
|
mask: Vec<u64>,
|
||||||
@@ -148,7 +148,7 @@ pub struct ClientAppCodeLogin<S: OpaqueAPI> {
|
|||||||
cipher: NKodeCipher
|
cipher: NKodeCipher
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: OpaqueAPI>ClientAppCodeLogin<S> {
|
impl <S: AuthAPI>ClientAppCodeLogin<S> {
|
||||||
pub fn sort_icons(&self) -> Vec<Icon> {
|
pub fn sort_icons(&self) -> Vec<Icon> {
|
||||||
nkode_rs::tensor::reorder(
|
nkode_rs::tensor::reorder(
|
||||||
&self.icons,
|
&self.icons,
|
||||||
@@ -162,23 +162,22 @@ impl <S: OpaqueAPI>ClientAppCodeLogin<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClientAuth<
|
pub struct ClientAuth<'a, R, K>
|
||||||
R: ServerConnectionRegister + Clone,
|
where
|
||||||
L: ServerConnectionLogin + Clone,
|
R: ServerConnectionRegister + ServerConnectionLogin + Clone,
|
||||||
K: AuthAPI
|
K: AuthAPI
|
||||||
> {
|
{
|
||||||
opaque_key_register: OpaqueAuthRegister<R>,
|
opaque_key_register: OpaqueAuth<'a, R>,
|
||||||
opaque_key_login: OpaqueAuthLogin<L>,
|
opaque_key_login: OpaqueAuth<'a, R>,
|
||||||
opaque_code_register: OpaqueAuthRegister<R>,
|
opaque_code_register: OpaqueAuth<'a, R>,
|
||||||
opaque_code_login: OpaqueAuthLogin<L>,
|
opaque_code_login: OpaqueAuth<'a, R>,
|
||||||
nkode_api: K,
|
nkode_api: K,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<R, L, K> OpaqueAPI for ClientAuth<R, L,K>
|
impl<'a, R, K> AuthAPI for ClientAuth<'a, R, K>
|
||||||
where
|
where
|
||||||
R: ServerConnectionRegister + Clone + Sync + Send,
|
R: ServerConnectionRegister + ServerConnectionLogin + Clone + Sync + Send,
|
||||||
L: ServerConnectionLogin + Clone + Sync + Send,
|
|
||||||
K: AuthAPI + Sync + Send,
|
K: AuthAPI + Sync + Send,
|
||||||
{
|
{
|
||||||
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String> {
|
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String> {
|
||||||
@@ -193,36 +192,16 @@ where
|
|||||||
|
|
||||||
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoggedInSession, String> {
|
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoggedInSession, String> {
|
||||||
let auth_data = AuthenticationData::from_secret_key(&email.as_str(), secret_key.as_slice());
|
let auth_data = AuthenticationData::from_secret_key(&email.as_str(), secret_key.as_slice());
|
||||||
let session_key = self.opaque_key_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
let session = self.opaque_key_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
||||||
todo!()
|
Ok(KeyLoggedInSession(session))
|
||||||
// Ok(KeyLoggedInSession(
|
|
||||||
// LoggedInSession {
|
|
||||||
// email: email.clone(),
|
|
||||||
// session_key
|
|
||||||
// }
|
|
||||||
// ))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoggedInSession, String> {
|
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoggedInSession, String> {
|
||||||
let auth_data = AuthenticationData::from_code(email.as_str(), passcode);
|
let auth_data = AuthenticationData::from_code(email.as_str(), passcode);
|
||||||
let session_key = self.opaque_code_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
let session = self.opaque_code_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
||||||
todo!()
|
Ok(CodeLoggedInSession(session))
|
||||||
// Ok(CodeLoggedInSession(
|
|
||||||
// LoggedInSession {
|
|
||||||
// email: email.clone(),
|
|
||||||
// session_key
|
|
||||||
// }
|
|
||||||
// ))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<R, L, K> AuthAPI for ClientAuth<R, L, K>
|
|
||||||
where
|
|
||||||
R: ServerConnectionRegister + Clone + Sync + Send,
|
|
||||||
L: ServerConnectionLogin + Clone + Sync + Send,
|
|
||||||
K: AuthAPI + Sync + Send,
|
|
||||||
{
|
|
||||||
async fn get_new_icons(
|
async fn get_new_icons(
|
||||||
&self,
|
&self,
|
||||||
key_login_session: &KeyLoggedInSession,
|
key_login_session: &KeyLoggedInSession,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use nkode_rs::from_bytes::FromBytes;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use opaque_ke::rand::rngs::OsRng;
|
use opaque_ke::rand::rngs::OsRng;
|
||||||
use opaque_ke::{
|
use opaque_ke::{
|
||||||
@@ -10,7 +9,7 @@ use opaque_ke::{
|
|||||||
RegistrationRequest,
|
RegistrationRequest,
|
||||||
};
|
};
|
||||||
use crate::shared::models::app::LoggedInSession;
|
use crate::shared::models::app::LoggedInSession;
|
||||||
use crate::shared::models::opaque::{OpaqueRegisterSession, OpaqueLoginSession, NKodeCipherSuite, PasswordFile, OpaqueSessionKey};
|
use crate::shared::models::opaque::{OpaqueRegisterSession, OpaqueLoginSession, NKodeCipherSuite, PasswordFile};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ClientAuthError {
|
pub enum ClientAuthError {
|
||||||
@@ -85,86 +84,61 @@ pub trait ServerConnectionLogin {
|
|||||||
) -> Result<LoggedInSession, ClientAuthError>;
|
) -> Result<LoggedInSession, ClientAuthError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct OpaqueAuth<'a, S>(&'a S);
|
||||||
|
|
||||||
|
impl<'a, S> OpaqueAuth<'a, S> {
|
||||||
pub struct OpaqueAuthRegister<R: ServerConnectionRegister + Clone>(R);
|
pub fn new(server: &'a S) -> Self {
|
||||||
|
|
||||||
impl <R: ServerConnectionRegister + Clone> OpaqueAuthRegister<R> {
|
|
||||||
pub fn new(server: R) -> Self {
|
|
||||||
Self(server)
|
Self(server)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OpaqueAuthLogin<L: ServerConnectionLogin + Clone>(L);
|
impl<S> OpaqueAuth<'_, S>
|
||||||
|
where
|
||||||
impl <L: ServerConnectionLogin + Clone> OpaqueAuthLogin<L> {
|
S: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
pub fn new(server: L) -> Self {
|
{
|
||||||
Self(server)
|
pub async fn register(&self, auth: &AuthenticationData) -> Result<(), ClientAuthError> {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl <R: ServerConnectionRegister + Clone>OpaqueAuthRegister<R> {
|
|
||||||
pub async fn register(
|
|
||||||
&self,
|
|
||||||
auth: &AuthenticationData,
|
|
||||||
) -> Result<(), ClientAuthError> {
|
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let start = ClientRegistration::<NKodeCipherSuite>::start(&mut rng, &auth.secret)
|
let start = ClientRegistration::<NKodeCipherSuite>::start(&mut rng, &auth.secret)
|
||||||
.map_err(|e| ClientAuthError::Opaque(format!("client reg start: {e:?}")))?;
|
.map_err(|e| ClientAuthError::Opaque(format!("client reg start: {e:?}")))?;
|
||||||
let server_start = self.0
|
let server_start = <S as ServerConnectionRegister>::start(&self.0, &auth.identifier, &start.message)
|
||||||
.start(&auth.identifier, &start.message)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientAuthError::Transport(format!("server reg start: {e:?}")))?;
|
.map_err(|e| ClientAuthError::Transport(format!("server reg start: {e:?}")))?;
|
||||||
let server_msg = server_start.response;
|
|
||||||
let finish = start
|
let finish = start
|
||||||
.state
|
.state
|
||||||
.finish(
|
.finish(
|
||||||
&mut rng,
|
&mut rng,
|
||||||
&auth.secret,
|
&auth.secret,
|
||||||
server_msg,
|
server_start.response,
|
||||||
ClientRegistrationFinishParameters::default(),
|
ClientRegistrationFinishParameters::default(),
|
||||||
)
|
)
|
||||||
.map_err(|e| ClientAuthError::Opaque(format!("client reg finish: {e:?}")))?;
|
.map_err(|e| ClientAuthError::Opaque(format!("client reg finish: {e:?}")))?;
|
||||||
let password_file: PasswordFile = finish.message.serialize();
|
let password_file: PasswordFile = finish.message.serialize();
|
||||||
self.0
|
<S as ServerConnectionRegister>::finish(&self.0, &server_start.session_id, password_file)
|
||||||
.finish(&server_start.session_id, password_file)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientAuthError::Transport(format!("server reg finish: {e:?}")))?;
|
.map_err(|e| ClientAuthError::Transport(format!("server reg finish: {e:?}")))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl <L: ServerConnectionLogin + Clone>OpaqueAuthLogin<L> {
|
pub async fn login(&self, auth: &AuthenticationData) -> Result<LoggedInSession, ClientAuthError> {
|
||||||
pub async fn login(
|
|
||||||
&self,
|
|
||||||
auth: &AuthenticationData,
|
|
||||||
) -> Result<OpaqueSessionKey, ClientAuthError> {
|
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let start = ClientLogin::<NKodeCipherSuite>::start(&mut rng, &auth.secret)
|
let start = ClientLogin::<NKodeCipherSuite>::start(&mut rng, &auth.secret)
|
||||||
.map_err(|e| ClientAuthError::Opaque(format!("client login start: {e:?}")))?;
|
.map_err(|e| ClientAuthError::Opaque(format!("client login start: {e:?}")))?;
|
||||||
let server_start = self.0
|
let server_start =
|
||||||
.start(&auth.identifier, &start.message)
|
<S as ServerConnectionLogin>::start(&self.0, &auth.identifier, &start.message)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientAuthError::Transport(format!("server login start: {e:?}")))?;
|
.map_err(|e| ClientAuthError::Transport(format!("server login start: {e:?}")))?;
|
||||||
let server_msg = server_start.response.clone();
|
|
||||||
let finish = start
|
let finish = start
|
||||||
.state
|
.state
|
||||||
.finish(
|
.finish(
|
||||||
&mut rng,
|
&mut rng,
|
||||||
&auth.secret,
|
&auth.secret,
|
||||||
server_msg,
|
server_start.response,
|
||||||
ClientLoginFinishParameters::default(),
|
ClientLoginFinishParameters::default(),
|
||||||
)
|
)
|
||||||
.map_err(|e| ClientAuthError::Opaque(format!("client login finish: {e:?}")))?;
|
.map_err(|e| ClientAuthError::Opaque(format!("client login finish: {e:?}")))?;
|
||||||
self.0
|
let session = <S as ServerConnectionLogin>::finish(&self.0, &server_start.session_id, &finish.message)
|
||||||
.finish(&server_start.session_id, &finish.message)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientAuthError::Transport(format!("server login finish: {e:?}")))?;
|
.map_err(|e| ClientAuthError::Transport(format!("server login finish: {e:?}")))?;
|
||||||
Ok(
|
Ok(session)
|
||||||
OpaqueSessionKey::from_bytes(finish.session_key.as_slice())
|
|
||||||
.map_err(|e| ClientAuthError::Opaque(format!("from bytes error {e:?}")))?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedIn
|
|||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
use crate::shared::models::opaque::{NKodeCipherSuite, NKodeServerSetup, OpaqueLoginSession, OpaqueRegisterSession, OpaqueSessionKey, PasswordFile};
|
use crate::shared::models::opaque::{NKodeCipherSuite, NKodeServerSetup, OpaqueLoginSession, OpaqueRegisterSession, OpaqueSessionKey, PasswordFile};
|
||||||
|
|
||||||
|
|
||||||
pub struct ServerApp<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> {
|
pub struct ServerApp<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> {
|
||||||
server_setup: NKodeServerSetup,
|
server_setup: NKodeServerSetup,
|
||||||
opaque_db: R,
|
opaque_db: R,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use opaque_ke::ServerLogin;
|
use opaque_ke::ServerLogin;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use async_trait::async_trait;
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest};
|
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest};
|
||||||
use crate::shared::models::opaque::{NKodeCipherSuite, NKodeServerSetup, OpaqueLoginSession, OpaqueRegisterSession, PasswordFile};
|
use crate::shared::models::opaque::{NKodeCipherSuite, OpaqueLoginSession, OpaqueRegisterSession, PasswordFile};
|
||||||
use crate::client::opaque::{ClientAuthError, ServerConnectionLogin, ServerConnectionRegister};
|
use crate::client::opaque::{ClientAuthError, ServerConnectionLogin, ServerConnectionRegister};
|
||||||
use crate::server::app::{Code, Key};
|
use crate::server::app::{Code, Key};
|
||||||
use crate::server::app::ServerApp;
|
use crate::server::app::ServerApp;
|
||||||
@@ -12,30 +12,25 @@ use crate::server::repository::in_memory::in_memory_opaque_session::InMemoryOpaq
|
|||||||
use crate::server::repository::in_memory::in_memory_user_db::InMemoryUserDB;
|
use crate::server::repository::in_memory::in_memory_user_db::InMemoryUserDB;
|
||||||
use crate::shared::models::app::LoggedInSession;
|
use crate::shared::models::app::LoggedInSession;
|
||||||
|
|
||||||
pub struct InMemoryServer<K: CredKind> {
|
pub type InMemoryKeyServer<'a> = InMemoryServer<'a, Key>;
|
||||||
auth_db: ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>,
|
pub type InMemoryCodeServer<'a> = InMemoryServer<'a, Code>;
|
||||||
|
|
||||||
|
pub struct InMemoryServer<'a, K: CredKind> {
|
||||||
|
auth_db: &'a ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>,
|
||||||
_kind: PhantomData<K>,
|
_kind: PhantomData<K>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: CredKind> InMemoryServer<K> {
|
impl<'a, K: CredKind> InMemoryServer<'a, K> {
|
||||||
pub fn new(server_setup: NKodeServerSetup) -> Self {
|
pub fn new(server_app: &'a ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
auth_db: ServerApp::new(
|
auth_db: server_app,
|
||||||
server_setup,
|
|
||||||
InMemoryOpaqueDB::new(),
|
|
||||||
InMemoryOpaqueSession::new(),
|
|
||||||
InMemoryUserDB::new()
|
|
||||||
),
|
|
||||||
_kind: PhantomData,
|
_kind: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type InMemoryKeyServer = InMemoryServer<Key>;
|
|
||||||
pub type InMemoryCodeServer = InMemoryServer<Code>;
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<K> ServerConnectionRegister for InMemoryServer<K>
|
impl<'a, K> ServerConnectionRegister for InMemoryServer<'a, K>
|
||||||
where
|
where
|
||||||
K: CredKind + Sync,
|
K: CredKind + Sync,
|
||||||
{
|
{
|
||||||
@@ -64,7 +59,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<K> ServerConnectionLogin for InMemoryServer<K>
|
impl<'a, K> ServerConnectionLogin for InMemoryServer<'a,K>
|
||||||
where
|
where
|
||||||
K: CredKind + Send + Sync,
|
K: CredKind + Send + Sync,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
pub mod in_memory_opaque_db;
|
pub mod in_memory_opaque_db;
|
||||||
pub mod in_memory_transport;
|
pub mod in_memory_transport;
|
||||||
pub mod in_memory_opaque_session;
|
pub mod in_memory_opaque_session;
|
||||||
mod in_memory_user_db;
|
pub mod in_memory_user_db;
|
||||||
|
|||||||
@@ -58,15 +58,12 @@ pub struct CodeLoginData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait OpaqueAPI {
|
pub trait AuthAPI {
|
||||||
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String>;
|
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String>;
|
||||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, data: &CodeLoginData) -> Result<(), String>;
|
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, data: &CodeLoginData) -> Result<(), String>;
|
||||||
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoggedInSession, String>;
|
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoggedInSession, String>;
|
||||||
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoggedInSession, String>;
|
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoggedInSession, String>;
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
pub trait AuthAPI {
|
|
||||||
async fn get_new_icons(&self, key_login_session: &KeyLoggedInSession) -> Result<Vec<Icon>, String>;
|
async fn get_new_icons(&self, key_login_session: &KeyLoggedInSession) -> Result<Vec<Icon>, String>;
|
||||||
async fn get_login_data(&self, key_login_session: &KeyLoggedInSession) -> Result<CodeLoginData, String>;
|
async fn get_login_data(&self, key_login_session: &KeyLoggedInSession) -> Result<CodeLoginData, String>;
|
||||||
async fn is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result<bool, String>;
|
async fn is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result<bool, String>;
|
||||||
|
|||||||
@@ -1,30 +1,44 @@
|
|||||||
use opaque_ke::rand::rngs::OsRng;
|
use opaque_ke::rand::rngs::OsRng;
|
||||||
use nkode_protocol::client::opaque::{AuthenticationData, ClientAuthError, OpaqueAuthLogin, OpaqueAuthRegister};
|
use nkode_protocol::client::opaque::{AuthenticationData, ClientAuthError, OpaqueAuth};
|
||||||
|
use nkode_protocol::server::app::{Key, ServerApp};
|
||||||
|
use nkode_protocol::server::repository::in_memory::in_memory_opaque_db::InMemoryOpaqueDB;
|
||||||
|
use nkode_protocol::server::repository::in_memory::in_memory_opaque_session::InMemoryOpaqueSession;
|
||||||
use nkode_protocol::shared::models::opaque::NKodeServerSetup;
|
use nkode_protocol::shared::models::opaque::NKodeServerSetup;
|
||||||
use nkode_protocol::server::repository::in_memory::in_memory_transport::{InMemoryCodeServer, InMemoryKeyServer};
|
use nkode_protocol::server::repository::in_memory::in_memory_transport::{InMemoryCodeServer, InMemoryKeyServer, InMemoryServer};
|
||||||
|
use nkode_protocol::server::repository::in_memory::in_memory_user_db::InMemoryUserDB;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn opaque_key_registration_and_login_roundtrip() {
|
async fn opaque_key_registration_and_login_roundtrip() {
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let server_setup = NKodeServerSetup::new(&mut rng);
|
let server_setup = NKodeServerSetup::new(&mut rng);
|
||||||
let server = InMemoryKeyServer::new(server_setup);
|
let server = ServerApp::new(
|
||||||
let auth_reg = OpaqueAuthRegister::new(server);
|
server_setup,
|
||||||
|
InMemoryOpaqueDB::new(),
|
||||||
|
InMemoryOpaqueSession::new(),
|
||||||
|
InMemoryUserDB::new()
|
||||||
|
);
|
||||||
|
let key_server: InMemoryKeyServer = InMemoryServer::new(&server);
|
||||||
|
let auth = OpaqueAuth::new(&key_server);
|
||||||
let auth_data = AuthenticationData::from_secret_key("a@b.com", b"supersecret16bytes");
|
let auth_data = AuthenticationData::from_secret_key("a@b.com", b"supersecret16bytes");
|
||||||
auth_reg.register(&auth_data).await.expect("registration should succeed");
|
auth.register(&auth_data).await.expect("registration should succeed");
|
||||||
let login_reg = OpaqueAuthLogin::new(server);
|
let _ =auth.login(&auth_data)
|
||||||
let _ =login_reg.login(&auth_data)
|
|
||||||
.await
|
.await
|
||||||
.expect("login should succeed");
|
.expect("login should succeed");
|
||||||
// assert!(!session_key.is_empty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn opaque_login_fails_if_not_registered() {
|
async fn opaque_login_fails_if_not_registered() {
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let server_setup = NKodeServerSetup::new(&mut rng);
|
let server_setup = NKodeServerSetup::new(&mut rng);
|
||||||
let server = InMemoryKeyServer::new(server_setup);
|
let server = ServerApp::new(
|
||||||
|
server_setup,
|
||||||
|
InMemoryOpaqueDB::new(),
|
||||||
|
InMemoryOpaqueSession::new(),
|
||||||
|
InMemoryUserDB::new()
|
||||||
|
);
|
||||||
|
let key_server = InMemoryKeyServer::new(&server);
|
||||||
let auth = AuthenticationData::from_secret_key("nope@nope.com", b"supersecret16bytes");
|
let auth = AuthenticationData::from_secret_key("nope@nope.com", b"supersecret16bytes");
|
||||||
let login_reg = OpaqueAuthLogin::new(server);
|
let login_reg = OpaqueAuth::new(&key_server);
|
||||||
let err = login_reg.login(&auth)
|
let err = login_reg.login(&auth)
|
||||||
.await
|
.await
|
||||||
.expect_err("login should fail if user not registered");
|
.expect_err("login should fail if user not registered");
|
||||||
@@ -38,10 +52,16 @@ async fn opaque_login_fails_if_not_registered() {
|
|||||||
async fn cannot_register_code_before_key() {
|
async fn cannot_register_code_before_key() {
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let server_setup = NKodeServerSetup::new(&mut rng);
|
let server_setup = NKodeServerSetup::new(&mut rng);
|
||||||
let server = InMemoryCodeServer::new(server_setup);
|
let server = ServerApp::new(
|
||||||
let auth_reg = OpaqueAuthRegister::new(server.clone());
|
server_setup,
|
||||||
let auth = AuthenticationData::from_code("x@y.com", &[1u64,2,3,4]);
|
InMemoryOpaqueDB::new(),
|
||||||
let err = auth_reg.register(&auth)
|
InMemoryOpaqueSession::new(),
|
||||||
|
InMemoryUserDB::new()
|
||||||
|
);
|
||||||
|
let key_server: InMemoryCodeServer = InMemoryServer::new(&server);
|
||||||
|
let auth = OpaqueAuth::new(&key_server);
|
||||||
|
let auth_data = AuthenticationData::from_code("x@y.com", &[1u64,2,3,4]);
|
||||||
|
let err = auth.register(&auth_data)
|
||||||
.await
|
.await
|
||||||
.expect_err("should fail because key is not registered");
|
.expect_err("should fail because key is not registered");
|
||||||
match err {
|
match err {
|
||||||
|
|||||||
Reference in New Issue
Block a user