implement server app
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest, ServerLogin, ServerLoginParameters, ServerRegistration};
|
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest, ServerLogin, ServerLoginParameters, ServerRegistration};
|
||||||
use opaque_ke::argon2::password_hash::rand_core::OsRng;
|
use opaque_ke::argon2::password_hash::rand_core::OsRng;
|
||||||
@@ -26,7 +27,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
request: RegistrationRequest<NKodeCipherSuite>,
|
request: RegistrationRequest<NKodeCipherSuite>,
|
||||||
) -> Result<OpaqueRegisterSession, String> {
|
) -> Result<OpaqueRegisterSession, String> {
|
||||||
K::prereq_for_register(&self.opaque_db, identifier)
|
K::prereq_for_register(&self.opaque_db, identifier).await
|
||||||
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
||||||
let start = ServerRegistration::<NKodeCipherSuite>::start(
|
let start = ServerRegistration::<NKodeCipherSuite>::start(
|
||||||
&self.server_setup,
|
&self.server_setup,
|
||||||
@@ -34,7 +35,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
identifier,
|
identifier,
|
||||||
).map_err(|e| format!("opaque reg start: {e:?}"))?;
|
).map_err(|e| format!("opaque reg start: {e:?}"))?;
|
||||||
let cache = self.opaque_sess
|
let cache = self.opaque_sess
|
||||||
.new_reg_session(identifier)
|
.new_reg_session(identifier).await
|
||||||
.map_err(|e| format!("reg cache: {e}"))?;
|
.map_err(|e| format!("reg cache: {e}"))?;
|
||||||
|
|
||||||
Ok(OpaqueRegisterSession { session_id: cache.session_id, response: start.message })
|
Ok(OpaqueRegisterSession { session_id: cache.session_id, response: start.message })
|
||||||
@@ -46,14 +47,14 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
password_file: PasswordFile,
|
password_file: PasswordFile,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let sess = self.opaque_sess
|
let sess = self.opaque_sess
|
||||||
.get_reg_session(session_id)
|
.get_reg_session(session_id).await
|
||||||
.map_err(|e| format!("get reg session: {e}"))?;
|
.map_err(|e| format!("get reg session: {e}"))?;
|
||||||
K::prereq_for_register(&self.opaque_db, sess.identifier.as_slice())
|
K::prereq_for_register(&self.opaque_db, sess.identifier.as_slice()).await
|
||||||
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
||||||
K::set_password_file(&mut self.opaque_db, sess.identifier.as_slice(), password_file)
|
K::set_password_file(&mut self.opaque_db, sess.identifier.as_slice(), password_file).await
|
||||||
.map_err(|e| format!("repo write: {e:?}"))?;
|
.map_err(|e| format!("repo write: {e:?}"))?;
|
||||||
self.opaque_sess
|
self.opaque_sess
|
||||||
.clear_reg_session(session_id)
|
.clear_reg_session(session_id).await
|
||||||
.map_err(|e| format!("clear reg session: {e}"))
|
.map_err(|e| format!("clear reg session: {e}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
request: CredentialRequest<NKodeCipherSuite>,
|
request: CredentialRequest<NKodeCipherSuite>,
|
||||||
) -> Result<OpaqueLoginSession, String> {
|
) -> Result<OpaqueLoginSession, String> {
|
||||||
let password_file = K::get_password_file(&self.opaque_db, identifier)
|
let password_file = K::get_password_file(&self.opaque_db, identifier).await
|
||||||
.map_err(|e| format!("repo read: {e:?}"))?;
|
.map_err(|e| format!("repo read: {e:?}"))?;
|
||||||
|
|
||||||
let password_file =
|
let password_file =
|
||||||
@@ -78,7 +79,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
ServerLoginParameters::default(),
|
ServerLoginParameters::default(),
|
||||||
).map_err(|e| format!("opaque login start: {e:?}"))?;
|
).map_err(|e| format!("opaque login start: {e:?}"))?;
|
||||||
let cache = self.opaque_sess
|
let cache = self.opaque_sess
|
||||||
.new_login_session(identifier, start.state)
|
.new_login_session(identifier, start.state).await
|
||||||
.map_err(|e| format!("login cache: {e}"))?;
|
.map_err(|e| format!("login cache: {e}"))?;
|
||||||
Ok(OpaqueLoginSession { session_id: cache.session_id, response: start.message })
|
Ok(OpaqueLoginSession { session_id: cache.session_id, response: start.message })
|
||||||
}
|
}
|
||||||
@@ -89,15 +90,14 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
finalize: CredentialFinalization<NKodeCipherSuite>,
|
finalize: CredentialFinalization<NKodeCipherSuite>,
|
||||||
) -> Result<LoggedInSession, String> {
|
) -> Result<LoggedInSession, String> {
|
||||||
let cache = self.opaque_sess
|
let cache = self.opaque_sess
|
||||||
.get_login_session(session_id)
|
.get_login_session(session_id).await
|
||||||
.map_err(|e| format!("get login session: {e}"))?;
|
.map_err(|e| format!("get login session: {e}"))?;
|
||||||
|
|
||||||
let finish = cache.server_login
|
let finish = cache.server_login
|
||||||
.finish(finalize, ServerLoginParameters::default())
|
.finish(finalize, ServerLoginParameters::default())
|
||||||
.map_err(|e| format!("opaque login finish: {e:?}"))?;
|
.map_err(|e| format!("opaque login finish: {e:?}"))?;
|
||||||
|
|
||||||
self.opaque_sess
|
self.opaque_sess
|
||||||
.clear_login_session(session_id)
|
.clear_login_session(session_id).await
|
||||||
.map_err(|e| format!("clear login session: {e}"))?;
|
.map_err(|e| format!("clear login session: {e}"))?;
|
||||||
let session_key = OpaqueSessionKey::from_bytes(&finish.session_key.to_vec()).unwrap();
|
let session_key = OpaqueSessionKey::from_bytes(&finish.session_key.to_vec()).unwrap();
|
||||||
Ok(LoggedInSession{
|
Ok(LoggedInSession{
|
||||||
@@ -144,36 +144,38 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Debug,Clone )]
|
||||||
pub struct Key;
|
pub struct Key;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Debug,Clone)]
|
||||||
pub struct Code;
|
pub struct Code;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl CredKind for Key {
|
impl CredKind for Key {
|
||||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool {
|
async fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool {
|
||||||
repo.has_key(id)
|
repo.has_key(id).await
|
||||||
}
|
}
|
||||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
async fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||||
repo.get_key_passcode_file(id)
|
repo.get_key_passcode_file(id).await
|
||||||
}
|
}
|
||||||
fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
async fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
||||||
repo.new_key(id, pf)
|
repo.new_key(id, pf).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl CredKind for Code {
|
impl CredKind for Code {
|
||||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool {
|
async fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool {
|
||||||
repo.has_code(id)
|
repo.has_code(id).await
|
||||||
}
|
}
|
||||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
async fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||||
repo.get_code_passcode_file(id)
|
repo.get_code_passcode_file(id).await
|
||||||
}
|
}
|
||||||
fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
async fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
||||||
repo.new_code(id, pf)
|
repo.new_code(id, pf).await
|
||||||
}
|
}
|
||||||
fn prereq_for_register<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<(), AuthRepoError> {
|
async fn prereq_for_register<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<(), AuthRepoError> {
|
||||||
if repo.has_key(id) {
|
if repo.has_key(id).await {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(AuthRepoError::KeyNotRegistered)
|
Err(AuthRepoError::KeyNotRegistered)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use opaque_ke::ServerLogin;
|
use opaque_ke::ServerLogin;
|
||||||
use crate::server::repository::opaque_repo::{AuthRepoError, OpaqueDatabaseRepo};
|
use crate::server::repository::opaque_repo::{AuthRepoError, OpaqueDatabaseRepo};
|
||||||
@@ -14,11 +15,12 @@ pub struct LoginCache {
|
|||||||
pub server_login: ServerLogin<NKodeCipherSuite>,
|
pub server_login: ServerLogin<NKodeCipherSuite>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
pub trait CredKind {
|
pub trait CredKind {
|
||||||
fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool;
|
async fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool;
|
||||||
fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
async 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>;
|
async 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> {
|
async fn prereq_for_register<R: OpaqueDatabaseRepo>(_repo: &R, _id: &[u8]) -> Result<(), AuthRepoError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::shared::models::opaque::PasswordFile;
|
use crate::shared::models::opaque::PasswordFile;
|
||||||
use crate::server::repository::opaque_repo::{OpaqueDatabaseRepo, AuthRepoError};
|
use crate::server::repository::opaque_repo::{OpaqueDatabaseRepo, AuthRepoError};
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct InMemoryOpaqueDB {
|
pub struct InMemoryOpaqueDB {
|
||||||
key_entries: HashMap<KeyID, PasswordFile>,
|
key_entries: Arc<Mutex<HashMap<KeyID, PasswordFile>>>,
|
||||||
code_entries: HashMap<CodeID, PasswordFile>,
|
code_entries: Arc<Mutex<HashMap<CodeID, PasswordFile>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
@@ -19,66 +22,67 @@ impl InMemoryOpaqueDB {
|
|||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn code_exists(&self, identifier: &CodeID) -> bool {
|
async fn code_exists(&self, identifier: &CodeID) -> bool {
|
||||||
self.code_entries.contains_key(identifier)
|
self.code_entries.lock().await.contains_key(identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_exists(&self, identifier: &KeyID) -> bool {
|
async fn key_exists(&self, identifier: &KeyID) -> bool {
|
||||||
self.key_entries.contains_key(identifier)
|
self.key_entries.lock().await.contains_key(identifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl OpaqueDatabaseRepo for InMemoryOpaqueDB {
|
impl OpaqueDatabaseRepo for InMemoryOpaqueDB {
|
||||||
fn new_key(
|
async fn new_key(
|
||||||
&mut self,
|
&self,
|
||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
password_file: PasswordFile,
|
password_file: PasswordFile,
|
||||||
) -> Result<(), AuthRepoError> {
|
) -> Result<(), AuthRepoError> {
|
||||||
if self.key_exists(&KeyID(identifier.to_vec())) {
|
if self.key_exists(&KeyID(identifier.to_vec())).await {
|
||||||
return Err(AuthRepoError::UserExists);
|
return Err(AuthRepoError::UserExists);
|
||||||
}
|
}
|
||||||
|
self.key_entries.lock().await
|
||||||
self.key_entries
|
|
||||||
.insert(KeyID(identifier.to_vec()), password_file);
|
.insert(KeyID(identifier.to_vec()), password_file);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_code(
|
async fn new_code(
|
||||||
&mut self,
|
&self,
|
||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
password_file: PasswordFile,
|
password_file: PasswordFile,
|
||||||
) -> Result<(), AuthRepoError> {
|
) -> Result<(), AuthRepoError> {
|
||||||
if !self.has_key(identifier) {
|
if !self.has_key(identifier).await {
|
||||||
return Err(AuthRepoError::KeyNotRegistered);
|
return Err(AuthRepoError::KeyNotRegistered);
|
||||||
}
|
}
|
||||||
if self.code_exists(&CodeID(identifier.to_vec())) {
|
if self.code_exists(&CodeID(identifier.to_vec())).await {
|
||||||
return Err(AuthRepoError::UserExists);
|
return Err(AuthRepoError::UserExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.code_entries
|
self.code_entries.lock().await
|
||||||
.insert(CodeID(identifier.to_vec()), password_file);
|
.insert(CodeID(identifier.to_vec()), password_file);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_code(&self, identifier: &[u8]) -> bool {
|
async fn has_code(&self, identifier: &[u8]) -> bool {
|
||||||
self.code_entries
|
self.code_entries.lock().await
|
||||||
.contains_key(&CodeID(identifier.to_vec()))
|
.contains_key(&CodeID(identifier.to_vec()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_key(&self, identifier: &[u8]) -> bool {
|
async fn has_key(&self, identifier: &[u8]) -> bool {
|
||||||
self.key_entries
|
self.key_entries.lock().await
|
||||||
.contains_key(&KeyID(identifier.to_vec()))
|
.contains_key(&KeyID(identifier.to_vec()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_key_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
async fn get_key_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||||
self.key_entries
|
self.key_entries.lock().await
|
||||||
.get(&KeyID(identifier.to_vec()))
|
.get(&KeyID(identifier.to_vec()))
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or(AuthRepoError::KeyNotRegistered)
|
.ok_or(AuthRepoError::KeyNotRegistered)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_code_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
async fn get_code_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||||
self.code_entries
|
self.code_entries.lock().await
|
||||||
.get(&CodeID(identifier.to_vec()))
|
.get(&CodeID(identifier.to_vec()))
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or(AuthRepoError::CodeNotRegistered)
|
.ok_or(AuthRepoError::CodeNotRegistered)
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use async_trait::async_trait;
|
||||||
use opaque_ke::ServerLogin;
|
use opaque_ke::ServerLogin;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::server::models::{LoginCache, RegCache};
|
use crate::server::models::{LoginCache, RegCache};
|
||||||
use crate::shared::models::opaque::NKodeCipherSuite;
|
use crate::shared::models::opaque::NKodeCipherSuite;
|
||||||
@@ -7,8 +11,8 @@ use crate::server::repository::opaque_repo::OpaqueSessionRepo;
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct InMemoryOpaqueSession {
|
pub struct InMemoryOpaqueSession {
|
||||||
reg_sessions: HashMap<Uuid, RegCache>,
|
reg_sessions: Arc<Mutex<HashMap<Uuid, RegCache>>>,
|
||||||
login_sessions: HashMap<Uuid, LoginCache>,
|
login_sessions: Arc<Mutex<HashMap<Uuid, LoginCache>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InMemoryOpaqueSession {
|
impl InMemoryOpaqueSession {
|
||||||
@@ -17,28 +21,27 @@ impl InMemoryOpaqueSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
||||||
fn new_reg_session(&mut self, identifier: &[u8]) -> Result<RegCache, String> {
|
async fn new_reg_session(&self, identifier: &[u8]) -> Result<RegCache, String> {
|
||||||
let cache = RegCache {
|
let cache = RegCache {
|
||||||
session_id: Uuid::new_v4(),
|
session_id: Uuid::new_v4(),
|
||||||
identifier: identifier.to_vec(),
|
identifier: identifier.to_vec(),
|
||||||
};
|
};
|
||||||
|
if self.reg_sessions.lock().await.contains_key(&cache.session_id) {
|
||||||
// Extremely unlikely collision, but keep the invariant anyway.
|
|
||||||
if self.reg_sessions.contains_key(&cache.session_id) {
|
|
||||||
return Err("session_id collision".to_string());
|
return Err("session_id collision".to_string());
|
||||||
}
|
}
|
||||||
|
self.reg_sessions.lock().await.insert(cache.session_id, RegCache {
|
||||||
self.reg_sessions.insert(cache.session_id, RegCache {
|
|
||||||
session_id: cache.session_id,
|
session_id: cache.session_id,
|
||||||
identifier: cache.identifier.clone(),
|
identifier: cache.identifier.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(cache)
|
Ok(cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_reg_session(&self, session_id: &Uuid) -> Result<RegCache, String> {
|
async fn get_reg_session(&self, session_id: &Uuid) -> Result<RegCache, String> {
|
||||||
self.reg_sessions
|
self.reg_sessions
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
.get(session_id)
|
.get(session_id)
|
||||||
.map(|c| RegCache {
|
.map(|c| RegCache {
|
||||||
session_id: c.session_id,
|
session_id: c.session_id,
|
||||||
@@ -47,15 +50,17 @@ impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
|||||||
.ok_or_else(|| "registration session not found".to_string())
|
.ok_or_else(|| "registration session not found".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_reg_session(&mut self, session_id: &Uuid) -> Result<(), String> {
|
async fn clear_reg_session(&self, session_id: &Uuid) -> Result<(), String> {
|
||||||
self.reg_sessions
|
self.reg_sessions
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
.remove(session_id)
|
.remove(session_id)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.ok_or_else(|| "registration session not found".to_string())
|
.ok_or_else(|| "registration session not found".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_login_session(
|
async fn new_login_session(
|
||||||
&mut self,
|
&self,
|
||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
server_login: ServerLogin<NKodeCipherSuite>,
|
server_login: ServerLogin<NKodeCipherSuite>,
|
||||||
) -> Result<LoginCache, String> {
|
) -> Result<LoginCache, String> {
|
||||||
@@ -64,12 +69,10 @@ impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
|||||||
identifiers: identifier.to_vec(),
|
identifiers: identifier.to_vec(),
|
||||||
server_login,
|
server_login,
|
||||||
};
|
};
|
||||||
|
if self.login_sessions.lock().await.contains_key(&cache.session_id) {
|
||||||
if self.login_sessions.contains_key(&cache.session_id) {
|
|
||||||
return Err("session_id collision".to_string());
|
return Err("session_id collision".to_string());
|
||||||
}
|
}
|
||||||
|
self.login_sessions.lock().await.insert(
|
||||||
self.login_sessions.insert(
|
|
||||||
cache.session_id,
|
cache.session_id,
|
||||||
LoginCache {
|
LoginCache {
|
||||||
session_id: cache.session_id,
|
session_id: cache.session_id,
|
||||||
@@ -78,12 +81,11 @@ impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
|||||||
server_login: cache.server_login.clone(),
|
server_login: cache.server_login.clone(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(cache)
|
Ok(cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_login_session(&self, session_id: &Uuid) -> Result<LoginCache, String> {
|
async fn get_login_session(&self, session_id: &Uuid) -> Result<LoginCache, String> {
|
||||||
self.login_sessions
|
self.login_sessions.lock().await
|
||||||
.get(session_id)
|
.get(session_id)
|
||||||
.map(|c| LoginCache {
|
.map(|c| LoginCache {
|
||||||
session_id: c.session_id,
|
session_id: c.session_id,
|
||||||
@@ -93,8 +95,8 @@ impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
|||||||
.ok_or_else(|| "login session not found".to_string())
|
.ok_or_else(|| "login session not found".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_login_session(&mut self, session_id: &Uuid) -> Result<(), String> {
|
async fn clear_login_session(&self, session_id: &Uuid) -> Result<(), String> {
|
||||||
self.login_sessions
|
self.login_sessions.lock().await
|
||||||
.remove(session_id)
|
.remove(session_id)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.ok_or_else(|| "login session not found".to_string())
|
.ok_or_else(|| "login session not found".to_string())
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use opaque_ke::ServerLogin;
|
use opaque_ke::ServerLogin;
|
||||||
use crate::server::models::{LoginCache, RegCache};
|
use crate::server::models::{LoginCache, RegCache};
|
||||||
@@ -9,27 +10,29 @@ pub enum AuthRepoError {
|
|||||||
CodeNotRegistered,
|
CodeNotRegistered,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait OpaqueDatabaseRepo {
|
#[async_trait]
|
||||||
fn new_key(&mut self, identifier: &[u8], password_file: PasswordFile) -> Result<(), AuthRepoError>;
|
pub trait OpaqueDatabaseRepo: Send + Sync {
|
||||||
fn new_code(&mut self, identifier: &[u8], password_file: PasswordFile) -> Result<(), AuthRepoError>;
|
async fn new_key(&self, identifier: &[u8], password_file: PasswordFile) -> Result<(), AuthRepoError>;
|
||||||
|
async fn new_code(&self, identifier: &[u8], password_file: PasswordFile) -> Result<(), AuthRepoError>;
|
||||||
|
|
||||||
fn has_code(&self, identifier: &[u8]) -> bool;
|
async fn has_code(&self, identifier: &[u8]) -> bool;
|
||||||
fn has_key(&self, identifier: &[u8]) -> bool;
|
async fn has_key(&self, identifier: &[u8]) -> bool;
|
||||||
|
|
||||||
fn get_key_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
async fn get_key_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||||
fn get_code_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
async fn get_code_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
pub trait OpaqueSessionRepo {
|
pub trait OpaqueSessionRepo {
|
||||||
fn new_reg_session(&mut self, identifier: &[u8]) -> Result<RegCache, String>;
|
async fn new_reg_session(&self, identifier: &[u8]) -> Result<RegCache, String>;
|
||||||
fn get_reg_session(&self, session_id: &Uuid) -> Result<RegCache, String>;
|
async fn get_reg_session(&self, session_id: &Uuid) -> Result<RegCache, String>;
|
||||||
fn clear_reg_session(&mut self, session_id: &Uuid) -> Result<(), String>;
|
async fn clear_reg_session(&self, session_id: &Uuid) -> Result<(), String>;
|
||||||
|
|
||||||
fn new_login_session(
|
async fn new_login_session(
|
||||||
&mut self,
|
&self,
|
||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
server_login: ServerLogin<NKodeCipherSuite>,
|
server_login: ServerLogin<NKodeCipherSuite>,
|
||||||
) -> Result<LoginCache, String>;
|
) -> Result<LoginCache, String>;
|
||||||
fn get_login_session(&self, session_id: &Uuid) -> Result<LoginCache, String>;
|
async fn get_login_session(&self, session_id: &Uuid) -> Result<LoginCache, String>;
|
||||||
fn clear_login_session(&mut self, session_id: &Uuid) -> Result<(), String>;
|
async fn clear_login_session(&self, session_id: &Uuid) -> Result<(), String>;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user