refactor auth_repo to server_app
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::marker::PhantomData;
|
||||
use nkode_rs::nkode_core::keypad::Keypad;
|
||||
use crate::shared::models::app::{OpaqueAPI, AuthAPI, CodeLoginData, CodeLoginSession, Icon, IconID, KeyLoginSession, ICON_ID_SIZE, LoginSession};
|
||||
use crate::shared::models::app::{OpaqueAPI, AuthAPI, CodeLoginData, CodeLoggedInSession, Icon, IconID, KeyLoggedInSession, ICON_ID_SIZE, LoggedInSession};
|
||||
use crate::shared::models::email::Email;
|
||||
use crate::shared::models::opaque::{OpaqueLoginSession, UserSecretKey};
|
||||
use anyhow::Result;
|
||||
@@ -50,7 +50,7 @@ pub struct ClientAppKeyLoggedIn<S: OpaqueAPI> {
|
||||
api: S,
|
||||
email: Email,
|
||||
user_secret_key: UserSecretKey,
|
||||
key_login: KeyLoginSession,
|
||||
key_login: KeyLoggedInSession,
|
||||
}
|
||||
|
||||
impl <S: OpaqueAPI + AuthAPI> ClientAppKeyLoggedIn<S> {
|
||||
@@ -104,7 +104,7 @@ pub struct ClientAppCodeRegister<S: OpaqueAPI> {
|
||||
api: S,
|
||||
email: Email,
|
||||
user_secret_key: UserSecretKey,
|
||||
key_login: KeyLoginSession,
|
||||
key_login: KeyLoggedInSession,
|
||||
icon_nonce: Nonce,
|
||||
icons: Vec<Icon>,
|
||||
keypad: Keypad,
|
||||
@@ -156,7 +156,7 @@ impl <S: OpaqueAPI>ClientAppCodeLogin<S> {
|
||||
).unwrap().to_vec()
|
||||
}
|
||||
|
||||
pub async fn login(&self, selected_keys: &Vec<usize>) -> Result<CodeLoginSession, String> {
|
||||
pub async fn login(&self, selected_keys: &Vec<usize>) -> Result<CodeLoggedInSession, String> {
|
||||
let passcode = self.cipher.decipher(selected_keys, self.keypad.indices(), &self.mask).map_err(|e| format!("invalid keys: {e}"))?;
|
||||
self.api.login_code(&self.email, &passcode).await
|
||||
}
|
||||
@@ -186,31 +186,33 @@ where
|
||||
self.opaque_key_register.register(&auth_data).await.map_err(|e| format!("error: {}", e))
|
||||
}
|
||||
|
||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoginSession, data: &CodeLoginData) -> Result<(), String> {
|
||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, data: &CodeLoginData) -> Result<(), String> {
|
||||
let auth_data = AuthenticationData::from_code(email.as_str(), passcode);
|
||||
self.opaque_code_register.register(&auth_data).await.map_err(|e| format!("error: {}", e))
|
||||
}
|
||||
|
||||
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoginSession, 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 session_key = self.opaque_key_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
||||
Ok(KeyLoginSession(
|
||||
LoginSession {
|
||||
email: email.clone(),
|
||||
session_key
|
||||
}
|
||||
))
|
||||
todo!()
|
||||
// Ok(KeyLoggedInSession(
|
||||
// LoggedInSession {
|
||||
// email: email.clone(),
|
||||
// session_key
|
||||
// }
|
||||
// ))
|
||||
}
|
||||
|
||||
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoginSession, String> {
|
||||
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))?;
|
||||
Ok(CodeLoginSession(
|
||||
LoginSession {
|
||||
email: email.clone(),
|
||||
session_key
|
||||
}
|
||||
))
|
||||
todo!()
|
||||
// Ok(CodeLoggedInSession(
|
||||
// LoggedInSession {
|
||||
// email: email.clone(),
|
||||
// session_key
|
||||
// }
|
||||
// ))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +225,7 @@ where
|
||||
{
|
||||
async fn get_new_icons(
|
||||
&self,
|
||||
key_login_session: &KeyLoginSession,
|
||||
key_login_session: &KeyLoggedInSession,
|
||||
) -> Result<Vec<Icon>, String> {
|
||||
self.nkode_api
|
||||
.get_new_icons(key_login_session)
|
||||
@@ -232,14 +234,14 @@ where
|
||||
|
||||
async fn get_login_data(
|
||||
&self,
|
||||
key_login_session: &KeyLoginSession,
|
||||
key_login_session: &KeyLoggedInSession,
|
||||
) -> Result<CodeLoginData, String> {
|
||||
self.nkode_api
|
||||
.get_login_data(key_login_session)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn is_code_registered(&self, key_login_session: &KeyLoginSession) -> Result<bool, String> {
|
||||
async fn is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result<bool, String> {
|
||||
self.nkode_api.is_code_registered(key_login_session).await
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ use opaque_ke::{
|
||||
CredentialFinalization, CredentialRequest,
|
||||
RegistrationRequest,
|
||||
};
|
||||
use crate::shared::models::app::LoggedInSession;
|
||||
use crate::shared::models::opaque::{OpaqueRegisterSession, OpaqueLoginSession, NKodeCipherSuite, PasswordFile, OpaqueSessionKey};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -81,7 +82,7 @@ pub trait ServerConnectionLogin {
|
||||
&self,
|
||||
session_id: &Uuid,
|
||||
message: &CredentialFinalization<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueSessionKey, ClientAuthError>;
|
||||
) -> Result<LoggedInSession, ClientAuthError>;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
use uuid::Uuid;
|
||||
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest, ServerLogin, ServerLoginParameters, ServerRegistration};
|
||||
use opaque_ke::argon2::password_hash::rand_core::OsRng;
|
||||
use nkode_rs::from_bytes::FromBytes;
|
||||
use crate::server::models::CredKind;
|
||||
use crate::server::repository::opaque_repo::{AuthRepoError, OpaqueDatabaseRepo, OpaqueSessionRepo};
|
||||
use crate::server::repository::user_repo::UserRepo;
|
||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession, LoggedInSession};
|
||||
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,
|
||||
opaque_sess: S,
|
||||
user_db: U,
|
||||
}
|
||||
|
||||
impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U> {
|
||||
pub fn new(server_setup: NKodeServerSetup, opaque_db: R, opaque_sess: S, user_db: U) -> Self {
|
||||
Self { server_setup, opaque_db, opaque_sess, user_db}
|
||||
}
|
||||
|
||||
pub async fn reg_start<K: CredKind>(
|
||||
&mut self,
|
||||
identifier: &[u8],
|
||||
request: RegistrationRequest<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueRegisterSession, String> {
|
||||
K::prereq_for_register(&self.opaque_db, identifier)
|
||||
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
||||
let start = ServerRegistration::<NKodeCipherSuite>::start(
|
||||
&self.server_setup,
|
||||
request,
|
||||
identifier,
|
||||
).map_err(|e| format!("opaque reg start: {e:?}"))?;
|
||||
let cache = self.opaque_sess
|
||||
.new_reg_session(identifier)
|
||||
.map_err(|e| format!("reg cache: {e}"))?;
|
||||
|
||||
Ok(OpaqueRegisterSession { session_id: cache.session_id, response: start.message })
|
||||
}
|
||||
|
||||
pub async fn reg_finish<K: CredKind>(
|
||||
&mut self,
|
||||
session_id: &Uuid,
|
||||
password_file: PasswordFile,
|
||||
) -> Result<(), String> {
|
||||
let sess = self.opaque_sess
|
||||
.get_reg_session(session_id)
|
||||
.map_err(|e| format!("get reg session: {e}"))?;
|
||||
K::prereq_for_register(&self.opaque_db, sess.identifier.as_slice())
|
||||
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
||||
K::set_password_file(&mut self.opaque_db, sess.identifier.as_slice(), password_file)
|
||||
.map_err(|e| format!("repo write: {e:?}"))?;
|
||||
self.opaque_sess
|
||||
.clear_reg_session(session_id)
|
||||
.map_err(|e| format!("clear reg session: {e}"))
|
||||
}
|
||||
|
||||
pub async fn login_start<K: CredKind>(
|
||||
&mut self,
|
||||
identifier: &[u8],
|
||||
request: CredentialRequest<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueLoginSession, String> {
|
||||
let password_file = K::get_password_file(&self.opaque_db, identifier)
|
||||
.map_err(|e| format!("repo read: {e:?}"))?;
|
||||
|
||||
let password_file =
|
||||
ServerRegistration::<NKodeCipherSuite>::deserialize(password_file.as_slice())
|
||||
.map_err(|e| format!("pf deserialize: {e:?}"))?;
|
||||
let mut server_rng = OsRng;
|
||||
let start = ServerLogin::start(
|
||||
&mut server_rng,
|
||||
&self.server_setup,
|
||||
Some(password_file),
|
||||
request,
|
||||
identifier,
|
||||
ServerLoginParameters::default(),
|
||||
).map_err(|e| format!("opaque login start: {e:?}"))?;
|
||||
let cache = self.opaque_sess
|
||||
.new_login_session(identifier, start.state)
|
||||
.map_err(|e| format!("login cache: {e}"))?;
|
||||
Ok(OpaqueLoginSession { session_id: cache.session_id, response: start.message })
|
||||
}
|
||||
|
||||
pub async fn login_finish(
|
||||
&mut self,
|
||||
session_id: &Uuid,
|
||||
finalize: CredentialFinalization<NKodeCipherSuite>,
|
||||
) -> Result<LoggedInSession, String> {
|
||||
let cache = self.opaque_sess
|
||||
.get_login_session(session_id)
|
||||
.map_err(|e| format!("get login session: {e}"))?;
|
||||
|
||||
let finish = cache.server_login
|
||||
.finish(finalize, ServerLoginParameters::default())
|
||||
.map_err(|e| format!("opaque login finish: {e:?}"))?;
|
||||
|
||||
self.opaque_sess
|
||||
.clear_login_session(session_id)
|
||||
.map_err(|e| format!("clear login session: {e}"))?;
|
||||
let session_key = OpaqueSessionKey::from_bytes(&finish.session_key.to_vec()).unwrap();
|
||||
Ok(LoggedInSession{
|
||||
session_id: Uuid::new_v4(),
|
||||
email: Email::from_bytes(cache.identifiers.as_slice()).unwrap(),
|
||||
session_key
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn key_login_finish(
|
||||
&mut self,
|
||||
session_id: &Uuid,
|
||||
finalize: CredentialFinalization<NKodeCipherSuite>,
|
||||
) -> Result<KeyLoggedInSession, String> {
|
||||
let session = KeyLoggedInSession(self.login_finish(session_id, finalize).await?);
|
||||
self.user_db.set_key_session(session.clone())?;
|
||||
Ok(session)
|
||||
}
|
||||
|
||||
pub async fn code_login_finish(
|
||||
&mut self,
|
||||
session_id: &Uuid,
|
||||
finalize: CredentialFinalization<NKodeCipherSuite>,
|
||||
) -> Result<CodeLoggedInSession, String> {
|
||||
let session = CodeLoggedInSession(self.login_finish(session_id, finalize).await?);
|
||||
self.user_db.set_code_session(session.clone())?;
|
||||
Ok(session)
|
||||
}
|
||||
|
||||
pub async fn get_key_session(&mut self, session_id: &Uuid) -> Result<KeyLoggedInSession, String> {
|
||||
self.user_db.get_key_session(session_id)
|
||||
}
|
||||
|
||||
pub async fn get_code_session(&mut self, session_id: &Uuid) -> Result<CodeLoggedInSession, String> {
|
||||
self.user_db.get_code_session(session_id)
|
||||
}
|
||||
|
||||
pub async fn get_code_login_data(&mut self, email: &Email) -> Result<CodeLoginData, String> {
|
||||
self.user_db.get_code_login_data(email)
|
||||
}
|
||||
|
||||
pub async fn set_code_login_data(&mut self, email: Email, data: CodeLoginData) -> Result<(), String> {
|
||||
self.user_db.set_code_login_data(email, data)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Key;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Code;
|
||||
|
||||
impl CredKind for Key {
|
||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool {
|
||||
repo.has_key(id)
|
||||
}
|
||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||
repo.get_key_passcode_file(id)
|
||||
}
|
||||
fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
||||
repo.new_key(id, pf)
|
||||
}
|
||||
}
|
||||
|
||||
impl CredKind for Code {
|
||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool {
|
||||
repo.has_code(id)
|
||||
}
|
||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||
repo.get_code_passcode_file(id)
|
||||
}
|
||||
fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
||||
repo.new_code(id, pf)
|
||||
}
|
||||
fn prereq_for_register<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<(), AuthRepoError> {
|
||||
if repo.has_key(id) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(AuthRepoError::KeyNotRegistered)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
pub mod app;
|
||||
pub mod repository;
|
||||
pub mod opaque;
|
||||
mod models;
|
||||
|
||||
24
src/server/models.rs
Normal file
24
src/server/models.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use uuid::Uuid;
|
||||
use opaque_ke::ServerLogin;
|
||||
use crate::server::repository::opaque_repo::{AuthRepoError, OpaqueDatabaseRepo};
|
||||
use crate::shared::models::opaque::{NKodeCipherSuite, PasswordFile};
|
||||
|
||||
pub struct RegCache {
|
||||
pub session_id: Uuid,
|
||||
pub identifier: Vec<u8>,
|
||||
}
|
||||
|
||||
pub struct LoginCache {
|
||||
pub session_id: Uuid,
|
||||
pub identifiers: Vec<u8>,
|
||||
pub server_login: ServerLogin<NKodeCipherSuite>,
|
||||
}
|
||||
|
||||
pub trait CredKind {
|
||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool;
|
||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||
fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError>;
|
||||
fn prereq_for_register<R: OpaqueDatabaseRepo>(_repo: &R, _id: &[u8]) -> Result<(), AuthRepoError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
use nkode_rs::from_bytes::FromBytes;
|
||||
use opaque_ke::{
|
||||
rand::rngs::OsRng, CredentialFinalization, CredentialRequest,
|
||||
RegistrationRequest, ServerLogin, ServerLoginParameters,
|
||||
ServerRegistration,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
use crate::shared::models::opaque::{OpaqueLoginSession, NKodeCipherSuite, NKodeServerSetup, OpaqueSessionKey, PasswordFile, OpaqueRegisterSession};
|
||||
use crate::server::repository::opaque::repos::{OpaqueDatabaseRepo, AuthRepoError, OpaqueSessionRepo};
|
||||
|
||||
pub struct RegCache {
|
||||
pub session_id: Uuid,
|
||||
pub identifier: Vec<u8>,
|
||||
}
|
||||
|
||||
pub struct LoginCache {
|
||||
pub session_id: Uuid,
|
||||
pub identifiers: Vec<u8>,
|
||||
pub server_login: ServerLogin<NKodeCipherSuite>,
|
||||
}
|
||||
|
||||
pub trait CredKind {
|
||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool;
|
||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||
fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError>;
|
||||
fn prereq_for_register<R: OpaqueDatabaseRepo>(_repo: &R, _id: &[u8]) -> Result<(), AuthRepoError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Key;
|
||||
#[derive(Clone)]
|
||||
pub struct Code;
|
||||
|
||||
impl CredKind for Key {
|
||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool {
|
||||
repo.has_key(id)
|
||||
}
|
||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||
repo.get_key_passcode_file(id)
|
||||
}
|
||||
fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
||||
repo.new_key(id, pf)
|
||||
}
|
||||
}
|
||||
|
||||
impl CredKind for Code {
|
||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool {
|
||||
repo.has_code(id)
|
||||
}
|
||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||
repo.get_code_passcode_file(id)
|
||||
}
|
||||
fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
||||
repo.new_code(id, pf)
|
||||
}
|
||||
fn prereq_for_register<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<(), AuthRepoError> {
|
||||
if repo.has_key(id) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(AuthRepoError::KeyNotRegistered)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OpaqueAuth<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo> {
|
||||
server_setup: NKodeServerSetup,
|
||||
user_repo: R,
|
||||
session: S,
|
||||
}
|
||||
|
||||
impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo> OpaqueAuth<R, S> {
|
||||
pub fn new(server_setup: NKodeServerSetup, user_repo: R, session: S) -> Self {
|
||||
Self { server_setup, user_repo, session }
|
||||
}
|
||||
|
||||
pub async fn reg_start<K: CredKind>(
|
||||
&mut self,
|
||||
identifier: &[u8],
|
||||
request: RegistrationRequest<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueRegisterSession, String> {
|
||||
K::prereq_for_register(&self.user_repo, identifier)
|
||||
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
||||
let start = ServerRegistration::<NKodeCipherSuite>::start(
|
||||
&self.server_setup,
|
||||
request,
|
||||
identifier,
|
||||
).map_err(|e| format!("opaque reg start: {e:?}"))?;
|
||||
let cache = self.session
|
||||
.new_reg_session(identifier)
|
||||
.map_err(|e| format!("reg cache: {e}"))?;
|
||||
|
||||
Ok(OpaqueRegisterSession { session_id: cache.session_id, response: start.message })
|
||||
}
|
||||
|
||||
pub async fn reg_finish<K: CredKind>(
|
||||
&mut self,
|
||||
session_id: &Uuid,
|
||||
password_file: PasswordFile,
|
||||
) -> Result<(), String> {
|
||||
let sess = self.session
|
||||
.get_reg_session(session_id)
|
||||
.map_err(|e| format!("get reg session: {e}"))?;
|
||||
K::prereq_for_register(&self.user_repo, sess.identifier.as_slice())
|
||||
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
||||
K::set_password_file(&mut self.user_repo, sess.identifier.as_slice(), password_file)
|
||||
.map_err(|e| format!("repo write: {e:?}"))?;
|
||||
self.session
|
||||
.clear_reg_session(session_id)
|
||||
.map_err(|e| format!("clear reg session: {e}"))
|
||||
}
|
||||
|
||||
pub async fn login_start<K: CredKind>(
|
||||
&mut self,
|
||||
identifier: &[u8],
|
||||
request: CredentialRequest<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueLoginSession, String> {
|
||||
let password_file = K::get_password_file(&self.user_repo, identifier)
|
||||
.map_err(|e| format!("repo read: {e:?}"))?;
|
||||
|
||||
let password_file =
|
||||
ServerRegistration::<NKodeCipherSuite>::deserialize(password_file.as_slice())
|
||||
.map_err(|e| format!("pf deserialize: {e:?}"))?;
|
||||
let mut server_rng = OsRng;
|
||||
let start = ServerLogin::start(
|
||||
&mut server_rng,
|
||||
&self.server_setup,
|
||||
Some(password_file),
|
||||
request,
|
||||
identifier,
|
||||
ServerLoginParameters::default(),
|
||||
).map_err(|e| format!("opaque login start: {e:?}"))?;
|
||||
let cache = self.session
|
||||
.new_login_session(identifier, start.state)
|
||||
.map_err(|e| format!("login cache: {e}"))?;
|
||||
Ok(OpaqueLoginSession { session_id: cache.session_id, response: start.message })
|
||||
}
|
||||
|
||||
pub async fn login_finish<K: CredKind>(
|
||||
&mut self,
|
||||
session_id: &Uuid,
|
||||
finalize: CredentialFinalization<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueSessionKey, String> {
|
||||
let cache = self.session
|
||||
.get_login_session(session_id)
|
||||
.map_err(|e| format!("get login session: {e}"))?;
|
||||
|
||||
let finish = cache.server_login
|
||||
.finish(finalize, ServerLoginParameters::default())
|
||||
.map_err(|e| format!("opaque login finish: {e:?}"))?;
|
||||
|
||||
self.session
|
||||
.clear_login_session(session_id)
|
||||
.map_err(|e| format!("clear login session: {e}"))?;
|
||||
|
||||
Ok(OpaqueSessionKey::from_bytes(&finish.session_key.to_vec()).unwrap())
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::shared::models::opaque::PasswordFile;
|
||||
use crate::server::repository::opaque::repos::{OpaqueDatabaseRepo, AuthRepoError};
|
||||
use crate::server::repository::opaque_repo::{OpaqueDatabaseRepo, AuthRepoError};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct InMemoryAuthRepo {
|
||||
pub struct InMemoryOpaqueDB {
|
||||
key_entries: HashMap<KeyID, PasswordFile>,
|
||||
code_entries: HashMap<CodeID, PasswordFile>,
|
||||
}
|
||||
@@ -14,7 +14,7 @@ pub struct KeyID(Vec<u8>);
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct CodeID(Vec<u8>);
|
||||
|
||||
impl InMemoryAuthRepo {
|
||||
impl InMemoryOpaqueDB {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
@@ -28,7 +28,7 @@ impl InMemoryAuthRepo {
|
||||
}
|
||||
}
|
||||
|
||||
impl OpaqueDatabaseRepo for InMemoryAuthRepo {
|
||||
impl OpaqueDatabaseRepo for InMemoryOpaqueDB {
|
||||
fn new_key(
|
||||
&mut self,
|
||||
identifier: &[u8],
|
||||
@@ -1,23 +1,23 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::server::opaque::{LoginCache, RegCache};
|
||||
use opaque_ke::ServerLogin;
|
||||
use uuid::Uuid;
|
||||
use crate::server::models::{LoginCache, RegCache};
|
||||
use crate::shared::models::opaque::NKodeCipherSuite;
|
||||
use crate::server::repository::opaque::repos::OpaqueSessionRepo;
|
||||
use crate::server::repository::opaque_repo::OpaqueSessionRepo;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct InMemoryAuthSession {
|
||||
pub struct InMemoryOpaqueSession {
|
||||
reg_sessions: HashMap<Uuid, RegCache>,
|
||||
login_sessions: HashMap<Uuid, LoginCache>,
|
||||
}
|
||||
|
||||
impl InMemoryAuthSession {
|
||||
impl InMemoryOpaqueSession {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl OpaqueSessionRepo for InMemoryAuthSession {
|
||||
impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
||||
fn new_reg_session(&mut self, identifier: &[u8]) -> Result<RegCache, String> {
|
||||
let cache = RegCache {
|
||||
session_id: Uuid::new_v4(),
|
||||
100
src/server/repository/in_memory/in_memory_transport.rs
Normal file
100
src/server/repository/in_memory/in_memory_transport.rs
Normal file
@@ -0,0 +1,100 @@
|
||||
use async_trait::async_trait;
|
||||
use std::marker::PhantomData;
|
||||
use tokio::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest};
|
||||
use crate::shared::models::opaque::{NKodeCipherSuite, NKodeServerSetup, OpaqueLoginSession, OpaqueRegisterSession, PasswordFile};
|
||||
use crate::client::opaque::{ClientAuthError, ServerConnectionLogin, ServerConnectionRegister};
|
||||
use crate::server::app::{Code, Key};
|
||||
use crate::server::app::ServerApp;
|
||||
use crate::server::models::CredKind;
|
||||
use crate::server::repository::in_memory::in_memory_opaque_db::InMemoryOpaqueDB;
|
||||
use crate::server::repository::in_memory::in_memory_opaque_session::InMemoryOpaqueSession;
|
||||
use crate::server::repository::in_memory::in_memory_user_db::InMemoryUserDB;
|
||||
use crate::shared::models::app::LoggedInSession;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InMemoryServer<K: CredKind> {
|
||||
auth_db: Arc<Mutex<ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>>>,
|
||||
_kind: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<K: CredKind> InMemoryServer<K> {
|
||||
pub fn new(server_setup: NKodeServerSetup) -> Self {
|
||||
Self {
|
||||
auth_db: Arc::new(Mutex::new(
|
||||
ServerApp::new(
|
||||
server_setup,
|
||||
InMemoryOpaqueDB::new(),
|
||||
InMemoryOpaqueSession::new(),
|
||||
InMemoryUserDB::new()
|
||||
)
|
||||
)),
|
||||
_kind: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type InMemoryKeyServer = InMemoryServer<Key>;
|
||||
pub type InMemoryCodeServer = InMemoryServer<Code>;
|
||||
|
||||
#[async_trait]
|
||||
impl<K> ServerConnectionRegister for InMemoryServer<K>
|
||||
where
|
||||
K: CredKind + Sync,
|
||||
{
|
||||
async fn start(
|
||||
&self,
|
||||
identifier: &[u8],
|
||||
message: &RegistrationRequest<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueRegisterSession, ClientAuthError> {
|
||||
// Server API takes ownership; client trait gives us a reference.
|
||||
// opaque-ke request types are typically Clone; if not, you'll need to adjust signatures.
|
||||
self.auth_db.lock().await
|
||||
.reg_start::<K>(identifier, message.clone())
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(e))
|
||||
}
|
||||
|
||||
async fn finish(
|
||||
&self,
|
||||
session_id: &Uuid,
|
||||
password_file: PasswordFile,
|
||||
) -> Result<(), ClientAuthError> {
|
||||
self.auth_db.lock().await
|
||||
.reg_finish::<K>(session_id, password_file)
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(e))
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<K> ServerConnectionLogin for InMemoryServer<K>
|
||||
where
|
||||
K: CredKind + Send + Sync,
|
||||
{
|
||||
async fn start(
|
||||
&self,
|
||||
identifier: &[u8],
|
||||
request: &CredentialRequest<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueLoginSession, ClientAuthError> {
|
||||
self.auth_db.lock().await
|
||||
.login_start::<K>(identifier, request.clone())
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(e))
|
||||
}
|
||||
|
||||
async fn finish(
|
||||
&self,
|
||||
session_id: &Uuid,
|
||||
message: &CredentialFinalization<NKodeCipherSuite>,
|
||||
) -> Result<LoggedInSession, ClientAuthError> {
|
||||
Ok(self
|
||||
.auth_db.lock().await
|
||||
.login_finish(session_id, message.clone())
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(e))?
|
||||
)
|
||||
}
|
||||
}
|
||||
67
src/server/repository/in_memory/in_memory_user_db.rs
Normal file
67
src/server/repository/in_memory/in_memory_user_db.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
use std::collections::HashMap;
|
||||
use uuid::Uuid;
|
||||
use crate::server::repository::user_repo::UserRepo;
|
||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession};
|
||||
use crate::shared::models::email::Email;
|
||||
|
||||
pub struct InMemoryUserDB {
|
||||
key_session: HashMap<Uuid, KeyLoggedInSession>,
|
||||
code_session: HashMap<Uuid, CodeLoggedInSession>,
|
||||
code_data: HashMap<Email, CodeLoginData>,
|
||||
}
|
||||
|
||||
impl InMemoryUserDB {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
key_session: HashMap::new(),
|
||||
code_session: HashMap::new(),
|
||||
code_data: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for InMemoryUserDB {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl UserRepo for InMemoryUserDB {
|
||||
fn get_key_session(&mut self, session_id: &Uuid) -> Result<KeyLoggedInSession, String> {
|
||||
self.key_session
|
||||
.get(&session_id)
|
||||
.cloned()
|
||||
.ok_or_else(|| format!("key session not found for session_id={}", session_id))
|
||||
}
|
||||
|
||||
fn get_code_session(&mut self, session_id: &Uuid) -> Result<CodeLoggedInSession, String> {
|
||||
self.code_session
|
||||
.get(&session_id)
|
||||
.cloned()
|
||||
.ok_or_else(|| format!("code session not found for session_id={}", session_id))
|
||||
}
|
||||
|
||||
fn set_key_session(&mut self, session: KeyLoggedInSession) -> Result<(), String> {
|
||||
// Assumes KeyLoggedInSession has a session_id: Uuid field (common pattern)
|
||||
self.key_session.insert(session.0.session_id, session);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_code_session(&mut self, session: CodeLoggedInSession) -> Result<(), String> {
|
||||
// Assumes CodeLoggedInSession has a session_id: Uuid field (common pattern)
|
||||
self.code_session.insert(session.0.session_id, session);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_code_login_data(&mut self, email: Email, data: CodeLoginData) -> Result<(), String> {
|
||||
self.code_data.insert(email, data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_code_login_data(&mut self, email: &Email) -> Result<CodeLoginData, String> {
|
||||
self.code_data
|
||||
.get(email)
|
||||
.cloned()
|
||||
.ok_or_else(|| "code login data not found for email".to_string())
|
||||
}
|
||||
}
|
||||
4
src/server/repository/in_memory/mod.rs
Normal file
4
src/server/repository/in_memory/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod in_memory_opaque_db;
|
||||
pub mod in_memory_transport;
|
||||
pub mod in_memory_opaque_session;
|
||||
mod in_memory_user_db;
|
||||
@@ -1 +1,3 @@
|
||||
pub mod opaque;
|
||||
pub mod in_memory;
|
||||
pub mod opaque_repo;
|
||||
pub mod user_repo;
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
use async_trait::async_trait;
|
||||
use std::marker::PhantomData;
|
||||
use tokio::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest};
|
||||
use crate::shared::models::opaque::{OpaqueLoginSession, NKodeCipherSuite, NKodeServerSetup, OpaqueSessionKey, PasswordFile, OpaqueRegisterSession};
|
||||
use crate::client::opaque::{ClientAuthError, ServerConnectionLogin, ServerConnectionRegister};
|
||||
use crate::server::opaque::{OpaqueAuth, CredKind, Key, Code};
|
||||
use crate::server::repository::opaque::in_memory::in_memory_auth_repo::InMemoryAuthRepo;
|
||||
use crate::server::repository::opaque::in_memory::in_memory_auth_session::InMemoryAuthSession;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InMemoryServer<K: CredKind> {
|
||||
auth: Arc<Mutex<OpaqueAuth<InMemoryAuthRepo, InMemoryAuthSession>>>,
|
||||
_kind: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<K: CredKind> InMemoryServer<K> {
|
||||
pub fn new(server_setup: NKodeServerSetup) -> Self {
|
||||
Self {
|
||||
auth: Arc::new(Mutex::new(OpaqueAuth::new(server_setup, InMemoryAuthRepo::new(), InMemoryAuthSession::new()))),
|
||||
_kind: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type InMemoryKeyServer = InMemoryServer<Key>;
|
||||
pub type InMemoryCodeServer = InMemoryServer<Code>;
|
||||
|
||||
#[async_trait]
|
||||
impl<K> ServerConnectionRegister for InMemoryServer<K>
|
||||
where
|
||||
K: CredKind + Sync,
|
||||
{
|
||||
async fn start(
|
||||
&self,
|
||||
identifier: &[u8],
|
||||
message: &RegistrationRequest<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueRegisterSession, ClientAuthError> {
|
||||
// Server API takes ownership; client trait gives us a reference.
|
||||
// opaque-ke request types are typically Clone; if not, you'll need to adjust signatures.
|
||||
self.auth.lock().await
|
||||
.reg_start::<K>(identifier, message.clone())
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(e))
|
||||
}
|
||||
|
||||
async fn finish(
|
||||
&self,
|
||||
session_id: &Uuid,
|
||||
password_file: PasswordFile,
|
||||
) -> Result<(), ClientAuthError> {
|
||||
self.auth.lock().await
|
||||
.reg_finish::<K>(session_id, password_file)
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(e))
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<K> ServerConnectionLogin for InMemoryServer<K>
|
||||
where
|
||||
K: CredKind + Send + Sync,
|
||||
{
|
||||
async fn start(
|
||||
&self,
|
||||
identifier: &[u8],
|
||||
request: &CredentialRequest<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueLoginSession, ClientAuthError> {
|
||||
self.auth.lock().await
|
||||
.login_start::<K>(identifier, request.clone())
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(e))
|
||||
}
|
||||
|
||||
async fn finish(
|
||||
&self,
|
||||
session_id: &Uuid,
|
||||
message: &CredentialFinalization<NKodeCipherSuite>,
|
||||
) -> Result<OpaqueSessionKey, ClientAuthError> {
|
||||
// Server computes its own session key too; we just need it to validate and complete.
|
||||
let key = self
|
||||
.auth.lock().await
|
||||
.login_finish::<K>(session_id, message.clone())
|
||||
.await
|
||||
.map_err(|e| ClientAuthError::Transport(e))?;
|
||||
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
|
||||
// pub struct InMemSharedServer<K> {
|
||||
// inner: Arc<Mutex<OpaqueAuth<InMemoryAuthRepo, InMemoryAuthSession>>>,
|
||||
// _k: PhantomData<K>,
|
||||
// }
|
||||
//
|
||||
// impl<K> InMemSharedServer<K> {
|
||||
// pub fn new(inner: Arc<Mutex<OpaqueAuth<InMemoryAuthRepo, InMemoryAuthSession>>>) -> Self {
|
||||
// Self { inner, _k: PhantomData }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// #[async_trait::async_trait]
|
||||
// impl<K> ServerConnectionRegister for InMemSharedServer<K>
|
||||
// where
|
||||
// K: CredKind + Send + Sync,
|
||||
// {
|
||||
// async fn start(
|
||||
// &mut self,
|
||||
// identifier: &[u8],
|
||||
// message: &RegistrationRequest<NKodeCipherSuite>,
|
||||
// ) -> Result<RegisterSession, ClientAuthError> {
|
||||
// let mut guard = self.inner.lock().await;
|
||||
// guard
|
||||
// .reg_start::<K>(identifier, message.clone())
|
||||
// .await
|
||||
// .map_err(ClientAuthError::Transport)
|
||||
// }
|
||||
//
|
||||
// async fn finish(
|
||||
// &mut self,
|
||||
// session_id: &Uuid,
|
||||
// password_file: PasswordFile,
|
||||
// ) -> Result<(), ClientAuthError> {
|
||||
// let mut guard = self.inner.lock().await;
|
||||
// guard
|
||||
// .reg_finish::<K>(session_id, password_file)
|
||||
// .await
|
||||
// .map_err(ClientAuthError::Transport)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// #[async_trait::async_trait]
|
||||
// impl<K> ServerConnectionLogin for InMemSharedServer<K>
|
||||
// where
|
||||
// K: CredKind + Send + Sync,
|
||||
// {
|
||||
// async fn start(
|
||||
// &mut self,
|
||||
// identifier: &[u8],
|
||||
// request: &CredentialRequest<NKodeCipherSuite>,
|
||||
// ) -> Result<LoginSession, ClientAuthError> {
|
||||
// let mut guard = self.inner.lock().await;
|
||||
// guard
|
||||
// .login_start::<K>(identifier, request.clone())
|
||||
// .await
|
||||
// .map_err(ClientAuthError::Transport)
|
||||
// }
|
||||
//
|
||||
// async fn finish(
|
||||
// &mut self,
|
||||
// session_id: &Uuid,
|
||||
// message: &CredentialFinalization<NKodeCipherSuite>,
|
||||
// ) -> Result<OpaqueSessionKey, ClientAuthError> {
|
||||
// let mut guard = self.inner.lock().await;
|
||||
// let key = guard
|
||||
// .login_finish::<K>(session_id, message.clone())
|
||||
// .await
|
||||
// .map_err(ClientAuthError::Transport)?;
|
||||
// Ok(key)
|
||||
// }
|
||||
// }
|
||||
@@ -1,3 +0,0 @@
|
||||
pub mod in_memory_auth_repo;
|
||||
pub mod in_memory_transport;
|
||||
pub mod in_memory_auth_session;
|
||||
@@ -1,2 +0,0 @@
|
||||
pub mod in_memory;
|
||||
pub mod repos;
|
||||
@@ -1,8 +1,7 @@
|
||||
use uuid::Uuid;
|
||||
use opaque_ke::ServerLogin;
|
||||
use crate::server::models::{LoginCache, RegCache};
|
||||
use crate::shared::models::opaque::{NKodeCipherSuite, PasswordFile};
|
||||
use crate::server::opaque::{LoginCache, RegCache};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AuthRepoError {
|
||||
UserExists,
|
||||
14
src/server/repository/user_repo.rs
Normal file
14
src/server/repository/user_repo.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use uuid::Uuid;
|
||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession};
|
||||
use crate::shared::models::email::Email;
|
||||
|
||||
pub trait UserRepo {
|
||||
fn get_key_session(&mut self, session_id: &Uuid) -> Result<KeyLoggedInSession, String>;
|
||||
fn get_code_session(&mut self, session_id: &Uuid) -> Result<CodeLoggedInSession, String>;
|
||||
|
||||
fn set_key_session(&mut self, session: KeyLoggedInSession) -> Result<(), String>;
|
||||
fn set_code_session(&mut self, session: CodeLoggedInSession) -> Result<(), String>;
|
||||
|
||||
fn set_code_login_data(&mut self, email: Email, data: CodeLoginData) -> Result<(), String>;
|
||||
fn get_code_login_data(&mut self, email: &Email) -> Result<CodeLoginData, String>;
|
||||
}
|
||||
@@ -4,15 +4,23 @@ use serde::{Deserialize, Serialize};
|
||||
use getset::Getters;
|
||||
use nkode_rs::from_bytes::FromBytes;
|
||||
use nkode_rs::nkode_core::policy::NKodePolicy;
|
||||
use uuid::Uuid;
|
||||
use crate::shared::models::email::Email;
|
||||
use crate::shared::models::opaque::{OpaqueSessionKey, UserSecretKey};
|
||||
pub struct LoginSession {
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LoggedInSession {
|
||||
pub(crate) session_id: Uuid,
|
||||
pub(crate) email: Email,
|
||||
pub(crate) session_key: OpaqueSessionKey,
|
||||
}
|
||||
|
||||
pub struct KeyLoginSession(pub(crate) LoginSession);
|
||||
pub struct CodeLoginSession(pub(crate) LoginSession);
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KeyLoggedInSession(pub(crate) LoggedInSession);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CodeLoggedInSession(pub(crate) LoggedInSession);
|
||||
|
||||
pub const ICON_ID_SIZE: usize = 32;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -53,16 +61,16 @@ pub struct CodeLoginData {
|
||||
#[async_trait]
|
||||
pub trait OpaqueAPI {
|
||||
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String>;
|
||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoginSession, data: &CodeLoginData) -> Result<(), String>;
|
||||
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoginSession, String>;
|
||||
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoginSession, 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: &KeyLoginSession) -> Result<Vec<Icon>, String>;
|
||||
async fn get_login_data(&self, key_login_session: &KeyLoginSession) -> Result<CodeLoginData, String>;
|
||||
async fn is_code_registered(&self, key_login_session: &KeyLoginSession) -> Result<bool, 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 is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result<bool, String>;
|
||||
async fn get_policy(&self) -> Result<NKodePolicy, String>;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ impl FromBytes<USER_KEY_SIZE> for UserSecretKey {
|
||||
|
||||
const OPAQUE_SESSION_KEY_SIZE: usize = 64;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OpaqueSessionKey(Zeroizing<[u8; OPAQUE_SESSION_KEY_SIZE]>);
|
||||
|
||||
impl FromBytes<OPAQUE_SESSION_KEY_SIZE> for OpaqueSessionKey {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use opaque_ke::rand::rngs::OsRng;
|
||||
use nkode_protocol::client::opaque::{AuthenticationData, ClientAuthError, OpaqueAuthLogin, OpaqueAuthRegister};
|
||||
use nkode_protocol::shared::models::opaque::NKodeServerSetup;
|
||||
use nkode_protocol::server::repository::opaque::in_memory::in_memory_transport::{InMemoryCodeServer, InMemoryKeyServer};
|
||||
use nkode_protocol::server::repository::in_memory::in_memory_transport::{InMemoryCodeServer, InMemoryKeyServer};
|
||||
|
||||
#[tokio::test]
|
||||
async fn opaque_key_registration_and_login_roundtrip() {
|
||||
@@ -15,7 +15,6 @@ async fn opaque_key_registration_and_login_roundtrip() {
|
||||
let _ =login_reg.login(&auth_data)
|
||||
.await
|
||||
.expect("login should succeed");
|
||||
// assert!(!session_key.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user