implement in-memory server
This commit is contained in:
@@ -1,28 +1,28 @@
|
||||
use std::marker::PhantomData;
|
||||
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::opaque::{OpaqueLoginSession, UserSecretKey};
|
||||
use crate::shared::models::opaque::{UserSecretKey};
|
||||
use anyhow::Result;
|
||||
use nkode_rs::nkode_core::nkode_cipher::NKodeCipher;
|
||||
use nkode_rs::from_bytes::FromBytes;
|
||||
use nkode_rs::nkode_core::chacha20prng::Nonce;
|
||||
use async_trait::async_trait;
|
||||
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;
|
||||
pub struct Register;
|
||||
struct Login;
|
||||
struct Register;
|
||||
|
||||
|
||||
pub struct ClientAppKey<State, S: OpaqueAPI> {
|
||||
pub struct ClientAppKey<State, S: AuthAPI> {
|
||||
api: S,
|
||||
email: Email,
|
||||
user_secret_key: UserSecretKey,
|
||||
_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> {
|
||||
self.api.register_key(&self.email, &self.user_secret_key).await?;
|
||||
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> {
|
||||
let key_login = self.api.login_key(&self.email, &self.user_secret_key).await?;
|
||||
Ok(ClientAppKeyLoggedIn{
|
||||
@@ -46,14 +46,14 @@ impl <S: OpaqueAPI> ClientAppKey<Login,S> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientAppKeyLoggedIn<S: OpaqueAPI> {
|
||||
pub struct ClientAppKeyLoggedIn<S: AuthAPI> {
|
||||
api: S,
|
||||
email: Email,
|
||||
user_secret_key: UserSecretKey,
|
||||
key_login: KeyLoggedInSession,
|
||||
}
|
||||
|
||||
impl <S: OpaqueAPI + AuthAPI> ClientAppKeyLoggedIn<S> {
|
||||
impl <S: AuthAPI> ClientAppKeyLoggedIn<S> {
|
||||
pub async fn register_code(self) -> Result<ClientAppCodeRegister<S>, String> {
|
||||
let icon_nonce = Nonce::new();
|
||||
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,
|
||||
email: Email,
|
||||
user_secret_key: UserSecretKey,
|
||||
@@ -110,7 +110,7 @@ pub struct ClientAppCodeRegister<S: OpaqueAPI> {
|
||||
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> {
|
||||
let policy = self.api.get_policy().await?;
|
||||
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,
|
||||
email: Email,
|
||||
mask: Vec<u64>,
|
||||
@@ -148,7 +148,7 @@ pub struct ClientAppCodeLogin<S: OpaqueAPI> {
|
||||
cipher: NKodeCipher
|
||||
}
|
||||
|
||||
impl <S: OpaqueAPI>ClientAppCodeLogin<S> {
|
||||
impl <S: AuthAPI>ClientAppCodeLogin<S> {
|
||||
pub fn sort_icons(&self) -> Vec<Icon> {
|
||||
nkode_rs::tensor::reorder(
|
||||
&self.icons,
|
||||
@@ -162,23 +162,22 @@ impl <S: OpaqueAPI>ClientAppCodeLogin<S> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientAuth<
|
||||
R: ServerConnectionRegister + Clone,
|
||||
L: ServerConnectionLogin + Clone,
|
||||
pub struct ClientAuth<'a, R, K>
|
||||
where
|
||||
R: ServerConnectionRegister + ServerConnectionLogin + Clone,
|
||||
K: AuthAPI
|
||||
> {
|
||||
opaque_key_register: OpaqueAuthRegister<R>,
|
||||
opaque_key_login: OpaqueAuthLogin<L>,
|
||||
opaque_code_register: OpaqueAuthRegister<R>,
|
||||
opaque_code_login: OpaqueAuthLogin<L>,
|
||||
{
|
||||
opaque_key_register: OpaqueAuth<'a, R>,
|
||||
opaque_key_login: OpaqueAuth<'a, R>,
|
||||
opaque_code_register: OpaqueAuth<'a, R>,
|
||||
opaque_code_login: OpaqueAuth<'a, R>,
|
||||
nkode_api: K,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<R, L, K> OpaqueAPI for ClientAuth<R, L,K>
|
||||
impl<'a, R, K> AuthAPI for ClientAuth<'a, R, K>
|
||||
where
|
||||
R: ServerConnectionRegister + Clone + Sync + Send,
|
||||
L: ServerConnectionLogin + Clone + Sync + Send,
|
||||
R: ServerConnectionRegister + ServerConnectionLogin + Clone + Sync + Send,
|
||||
K: AuthAPI + Sync + Send,
|
||||
{
|
||||
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> {
|
||||
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))?;
|
||||
todo!()
|
||||
// Ok(KeyLoggedInSession(
|
||||
// LoggedInSession {
|
||||
// email: email.clone(),
|
||||
// session_key
|
||||
// }
|
||||
// ))
|
||||
let session = self.opaque_key_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
||||
Ok(KeyLoggedInSession(session))
|
||||
}
|
||||
|
||||
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoggedInSession, String> {
|
||||
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))?;
|
||||
todo!()
|
||||
// Ok(CodeLoggedInSession(
|
||||
// LoggedInSession {
|
||||
// email: email.clone(),
|
||||
// session_key
|
||||
// }
|
||||
// ))
|
||||
let session = self.opaque_code_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
||||
Ok(CodeLoggedInSession(session))
|
||||
}
|
||||
}
|
||||
|
||||
#[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(
|
||||
&self,
|
||||
key_login_session: &KeyLoggedInSession,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::fmt;
|
||||
use async_trait::async_trait;
|
||||
use nkode_rs::from_bytes::FromBytes;
|
||||
use uuid::Uuid;
|
||||
use opaque_ke::rand::rngs::OsRng;
|
||||
use opaque_ke::{
|
||||
@@ -10,7 +9,7 @@ use opaque_ke::{
|
||||
RegistrationRequest,
|
||||
};
|
||||
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)]
|
||||
pub enum ClientAuthError {
|
||||
@@ -85,86 +84,61 @@ pub trait ServerConnectionLogin {
|
||||
) -> Result<LoggedInSession, ClientAuthError>;
|
||||
}
|
||||
|
||||
pub struct OpaqueAuth<'a, S>(&'a S);
|
||||
|
||||
|
||||
pub struct OpaqueAuthRegister<R: ServerConnectionRegister + Clone>(R);
|
||||
|
||||
impl <R: ServerConnectionRegister + Clone> OpaqueAuthRegister<R> {
|
||||
pub fn new(server: R) -> Self {
|
||||
impl<'a, S> OpaqueAuth<'a, S> {
|
||||
pub fn new(server: &'a S) -> Self {
|
||||
Self(server)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OpaqueAuthLogin<L: ServerConnectionLogin + Clone>(L);
|
||||
|
||||
impl <L: ServerConnectionLogin + Clone> OpaqueAuthLogin<L> {
|
||||
pub fn new(server: L) -> Self {
|
||||
Self(server)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl <R: ServerConnectionRegister + Clone>OpaqueAuthRegister<R> {
|
||||
pub async fn register(
|
||||
&self,
|
||||
auth: &AuthenticationData,
|
||||
) -> Result<(), ClientAuthError> {
|
||||
impl<S> OpaqueAuth<'_, S>
|
||||
where
|
||||
S: ServerConnectionRegister + ServerConnectionLogin,
|
||||
{
|
||||
pub async fn register(&self, auth: &AuthenticationData) -> Result<(), ClientAuthError> {
|
||||
let mut rng = OsRng;
|
||||
let start = ClientRegistration::<NKodeCipherSuite>::start(&mut rng, &auth.secret)
|
||||
.map_err(|e| ClientAuthError::Opaque(format!("client reg start: {e:?}")))?;
|
||||
let server_start = self.0
|
||||
.start(&auth.identifier, &start.message)
|
||||
let server_start = <S as ServerConnectionRegister>::start(&self.0, &auth.identifier, &start.message)
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(format!("server reg start: {e:?}")))?;
|
||||
let server_msg = server_start.response;
|
||||
let finish = start
|
||||
.state
|
||||
.finish(
|
||||
&mut rng,
|
||||
&auth.secret,
|
||||
server_msg,
|
||||
server_start.response,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
.map_err(|e| ClientAuthError::Opaque(format!("client reg finish: {e:?}")))?;
|
||||
let password_file: PasswordFile = finish.message.serialize();
|
||||
self.0
|
||||
.finish(&server_start.session_id, password_file)
|
||||
<S as ServerConnectionRegister>::finish(&self.0, &server_start.session_id, password_file)
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(format!("server reg finish: {e:?}")))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl <L: ServerConnectionLogin + Clone>OpaqueAuthLogin<L> {
|
||||
pub async fn login(
|
||||
&self,
|
||||
auth: &AuthenticationData,
|
||||
) -> Result<OpaqueSessionKey, ClientAuthError> {
|
||||
pub async fn login(&self, auth: &AuthenticationData) -> Result<LoggedInSession, ClientAuthError> {
|
||||
let mut rng = OsRng;
|
||||
let start = ClientLogin::<NKodeCipherSuite>::start(&mut rng, &auth.secret)
|
||||
.map_err(|e| ClientAuthError::Opaque(format!("client login start: {e:?}")))?;
|
||||
let server_start = self.0
|
||||
.start(&auth.identifier, &start.message)
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(format!("server login start: {e:?}")))?;
|
||||
let server_msg = server_start.response.clone();
|
||||
let server_start =
|
||||
<S as ServerConnectionLogin>::start(&self.0, &auth.identifier, &start.message)
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(format!("server login start: {e:?}")))?;
|
||||
let finish = start
|
||||
.state
|
||||
.finish(
|
||||
&mut rng,
|
||||
&auth.secret,
|
||||
server_msg,
|
||||
server_start.response,
|
||||
ClientLoginFinishParameters::default(),
|
||||
)
|
||||
.map_err(|e| ClientAuthError::Opaque(format!("client login finish: {e:?}")))?;
|
||||
self.0
|
||||
.finish(&server_start.session_id, &finish.message)
|
||||
let session = <S as ServerConnectionLogin>::finish(&self.0, &server_start.session_id, &finish.message)
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(format!("server login finish: {e:?}")))?;
|
||||
Ok(
|
||||
OpaqueSessionKey::from_bytes(finish.session_key.as_slice())
|
||||
.map_err(|e| ClientAuthError::Opaque(format!("from bytes error {e:?}")))?
|
||||
)
|
||||
Ok(session)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedIn
|
||||
use crate::shared::models::email::Email;
|
||||
use crate::shared::models::opaque::{NKodeCipherSuite, NKodeServerSetup, OpaqueLoginSession, OpaqueRegisterSession, OpaqueSessionKey, PasswordFile};
|
||||
|
||||
|
||||
pub struct ServerApp<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> {
|
||||
server_setup: NKodeServerSetup,
|
||||
opaque_db: R,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use opaque_ke::ServerLogin;
|
||||
|
||||
@@ -2,7 +2,7 @@ use async_trait::async_trait;
|
||||
use std::marker::PhantomData;
|
||||
use uuid::Uuid;
|
||||
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::server::app::{Code, Key};
|
||||
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::shared::models::app::LoggedInSession;
|
||||
|
||||
pub struct InMemoryServer<K: CredKind> {
|
||||
auth_db: ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>,
|
||||
pub type InMemoryKeyServer<'a> = InMemoryServer<'a, Key>;
|
||||
pub type InMemoryCodeServer<'a> = InMemoryServer<'a, Code>;
|
||||
|
||||
pub struct InMemoryServer<'a, K: CredKind> {
|
||||
auth_db: &'a ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>,
|
||||
_kind: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<K: CredKind> InMemoryServer<K> {
|
||||
pub fn new(server_setup: NKodeServerSetup) -> Self {
|
||||
impl<'a, K: CredKind> InMemoryServer<'a, K> {
|
||||
pub fn new(server_app: &'a ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>) -> Self {
|
||||
Self {
|
||||
auth_db: ServerApp::new(
|
||||
server_setup,
|
||||
InMemoryOpaqueDB::new(),
|
||||
InMemoryOpaqueSession::new(),
|
||||
InMemoryUserDB::new()
|
||||
),
|
||||
auth_db: server_app,
|
||||
_kind: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type InMemoryKeyServer = InMemoryServer<Key>;
|
||||
pub type InMemoryCodeServer = InMemoryServer<Code>;
|
||||
|
||||
#[async_trait]
|
||||
impl<K> ServerConnectionRegister for InMemoryServer<K>
|
||||
impl<'a, K> ServerConnectionRegister for InMemoryServer<'a, K>
|
||||
where
|
||||
K: CredKind + Sync,
|
||||
{
|
||||
@@ -64,7 +59,7 @@ where
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<K> ServerConnectionLogin for InMemoryServer<K>
|
||||
impl<'a, K> ServerConnectionLogin for InMemoryServer<'a,K>
|
||||
where
|
||||
K: CredKind + Send + Sync,
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
pub mod in_memory_opaque_db;
|
||||
pub mod in_memory_transport;
|
||||
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]
|
||||
pub trait OpaqueAPI {
|
||||
pub trait AuthAPI {
|
||||
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 login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoggedInSession, 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_login_data(&self, key_login_session: &KeyLoggedInSession) -> Result<CodeLoginData, String>;
|
||||
async fn is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result<bool, String>;
|
||||
|
||||
Reference in New Issue
Block a user