idk what i did
This commit is contained in:
@@ -1,75 +1,43 @@
|
|||||||
use crate::shared::models::app::{AuthAPI, CodeLoggedInSession, CodeLoginData, Icon, KeyLoggedInSession};
|
use async_trait::async_trait;
|
||||||
|
use crate::shared::models::app::AuthAPI;
|
||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
use crate::shared::models::opaque::UserSecretKey;
|
use crate::shared::models::opaque::UserSecretKey;
|
||||||
use anyhow::Result;
|
//https://chatgpt.com/c/69441737-c990-8333-9737-7ac75232da1d
|
||||||
use async_trait::async_trait;
|
|
||||||
use nkode_rs::nkode_core::policy::{NKodePolicy, DEFAULT_POLICY};
|
|
||||||
use crate::client::opaque::{AuthenticationData, OpaqueAuth, ServerConnectionLogin, ServerConnectionRegister};
|
|
||||||
|
|
||||||
|
struct ClientApp<K, C>
|
||||||
pub struct ClientAuth<'a, R, K>
|
|
||||||
where
|
where
|
||||||
R: ServerConnectionRegister + ServerConnectionLogin + Clone,
|
K: AuthAPI,
|
||||||
K: AuthAPI
|
C: ClientRepo
|
||||||
{
|
{
|
||||||
opaque_key_register: OpaqueAuth<'a, R>,
|
auth_api: K,
|
||||||
opaque_key_login: OpaqueAuth<'a, R>,
|
client_repo: C,
|
||||||
opaque_code_register: OpaqueAuth<'a, R>,
|
}
|
||||||
opaque_code_login: OpaqueAuth<'a, R>,
|
|
||||||
nkode_api: K,
|
impl <K, C>ClientApp<K, C>
|
||||||
|
where
|
||||||
|
K: AuthAPI,
|
||||||
|
C: ClientRepo
|
||||||
|
{
|
||||||
|
fn new(auth_api: K, client_repo: C) -> Self {
|
||||||
|
Self {
|
||||||
|
auth_api,
|
||||||
|
client_repo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn new_user(&self, email: Email) -> Result<UserSecretKey, String> {
|
||||||
|
let secret_key = UserSecretKey::new();
|
||||||
|
self.client_repo.add_secret_key(email.clone(), secret_key.clone()).await?;
|
||||||
|
if let Err(_) = self.auth_api.register_key(&email, &secret_key).await {
|
||||||
|
self.client_repo.remove_secret_key(&email).await.expect("couldn't delete");
|
||||||
|
}
|
||||||
|
Ok(secret_key)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<'a, R, K> AuthAPI for ClientAuth<'a, R, K>
|
trait ClientRepo {
|
||||||
where
|
async fn add_secret_key(&self, email: Email, user_secret_key: UserSecretKey) -> Result<(), String>;
|
||||||
R: ServerConnectionRegister + ServerConnectionLogin + Clone + Sync + Send,
|
async fn remove_secret_key(&self, email: &Email) -> Result<(), String>;
|
||||||
K: AuthAPI + Sync + Send,
|
|
||||||
{
|
|
||||||
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String> {
|
|
||||||
let auth_data = AuthenticationData::from_secret_key(email.as_str(), secret_key.as_slice());
|
|
||||||
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: &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<KeyLoggedInSession, String> {
|
|
||||||
let auth_data = AuthenticationData::from_secret_key(&email.as_str(), secret_key.as_slice());
|
|
||||||
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 = self.opaque_code_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
|
||||||
Ok(CodeLoggedInSession(session))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_new_icons(
|
|
||||||
&self,
|
|
||||||
key_login_session: &KeyLoggedInSession,
|
|
||||||
) -> Result<Vec<Icon>, String> {
|
|
||||||
self.nkode_api
|
|
||||||
.get_new_icons(key_login_session)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_login_data(
|
|
||||||
&self,
|
|
||||||
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: &KeyLoggedInSession) -> Result<bool, String> {
|
|
||||||
self.nkode_api.is_code_registered(key_login_session).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_policy(&self) -> Result<NKodePolicy, String> {
|
|
||||||
Ok(DEFAULT_POLICY)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
79
src/client/client_auth_api.rs
Normal file
79
src/client/client_auth_api.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use crate::shared::models::app::{AuthAPI, CodeLoggedInSession, CodeLoginData, Icon, KeyLoggedInSession};
|
||||||
|
use crate::shared::models::email::Email;
|
||||||
|
use crate::shared::models::opaque::UserSecretKey;
|
||||||
|
use anyhow::Result;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use nkode_rs::nkode_core::policy::{NKodePolicy, DEFAULT_POLICY};
|
||||||
|
use crate::client::opaque::{OpaqueAuthData, OpaqueAuth, ServerConnectionLogin, ServerConnectionRegister};
|
||||||
|
use crate::shared::models::store::UserAuthStore;
|
||||||
|
|
||||||
|
pub struct ClientAuth<'a, R, U>
|
||||||
|
where
|
||||||
|
R: ServerConnectionRegister + ServerConnectionLogin + Clone,
|
||||||
|
U: UserAuthStore
|
||||||
|
{
|
||||||
|
opaque_key_register: OpaqueAuth<'a, R>,
|
||||||
|
opaque_key_login: OpaqueAuth<'a, R>,
|
||||||
|
opaque_code_register: OpaqueAuth<'a, R>,
|
||||||
|
opaque_code_login: OpaqueAuth<'a, R>,
|
||||||
|
user_store: U
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<'a, R, U> AuthAPI for ClientAuth<'a, R, U>
|
||||||
|
where
|
||||||
|
R: ServerConnectionRegister + ServerConnectionLogin + Clone + Sync + Send,
|
||||||
|
U: UserAuthStore + Sync + Send,
|
||||||
|
{
|
||||||
|
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String> {
|
||||||
|
let auth_data = OpaqueAuthData::from_secret_key(email.as_str(), secret_key.as_slice());
|
||||||
|
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: &KeyLoggedInSession, data: &CodeLoginData) -> Result<(), String> {
|
||||||
|
let auth_data = OpaqueAuthData::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<KeyLoggedInSession, String> {
|
||||||
|
let auth_data = OpaqueAuthData::from_secret_key(&email.as_str(), secret_key.as_slice());
|
||||||
|
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 = OpaqueAuthData::from_code(email.as_str(), passcode);
|
||||||
|
let session = self.opaque_code_login.login(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
||||||
|
Ok(CodeLoggedInSession(session))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_new_icons(
|
||||||
|
&self,
|
||||||
|
key_login_session: &KeyLoggedInSession,
|
||||||
|
) -> Result<Vec<Icon>, String> {
|
||||||
|
// self.nkode_api
|
||||||
|
// .get_new_icons(key_login_session)
|
||||||
|
// .await
|
||||||
|
//
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_login_data(
|
||||||
|
&self,
|
||||||
|
key_login_session: &KeyLoggedInSession,
|
||||||
|
) -> Result<CodeLoginData, String> {
|
||||||
|
// self.nkode_api
|
||||||
|
// .get_login_data(key_login_session)
|
||||||
|
// .await
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result<bool, String> {
|
||||||
|
// self.nkode_api.is_code_registered(key_login_session).await
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_policy(&self) -> Result<NKodePolicy, String> {
|
||||||
|
Ok(DEFAULT_POLICY)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
mod app;
|
mod client_auth_api;
|
||||||
pub mod opaque;
|
pub mod opaque;
|
||||||
mod states;
|
mod states;
|
||||||
|
mod app;
|
||||||
@@ -28,12 +28,12 @@ impl fmt::Display for ClientAuthError {
|
|||||||
|
|
||||||
impl std::error::Error for ClientAuthError {}
|
impl std::error::Error for ClientAuthError {}
|
||||||
|
|
||||||
pub struct AuthenticationData {
|
pub struct OpaqueAuthData {
|
||||||
pub identifier: Vec<u8>,
|
pub identifier: Vec<u8>,
|
||||||
pub secret: Vec<u8>,
|
pub secret: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuthenticationData {
|
impl OpaqueAuthData {
|
||||||
pub fn from_secret_key(email: &str, secret_key: &[u8]) -> Self {
|
pub fn from_secret_key(email: &str, secret_key: &[u8]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
identifier: email.as_bytes().to_vec(),
|
identifier: email.as_bytes().to_vec(),
|
||||||
@@ -96,7 +96,7 @@ impl<S> OpaqueAuth<'_, S>
|
|||||||
where
|
where
|
||||||
S: ServerConnectionRegister + ServerConnectionLogin,
|
S: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
{
|
{
|
||||||
pub async fn register(&self, auth: &AuthenticationData) -> Result<(), ClientAuthError> {
|
pub async fn register(&self, auth: &OpaqueAuthData) -> 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:?}")))?;
|
||||||
@@ -119,7 +119,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login(&self, auth: &AuthenticationData) -> Result<LoggedInSession, ClientAuthError> {
|
pub async fn login(&self, auth: &OpaqueAuthData) -> Result<LoggedInSession, 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:?}")))?;
|
||||||
|
|||||||
@@ -7,30 +7,9 @@ use crate::shared::models::app::{AuthAPI, CodeLoggedInSession, CodeLoginData, Ic
|
|||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
use crate::shared::models::opaque::UserSecretKey;
|
use crate::shared::models::opaque::UserSecretKey;
|
||||||
|
|
||||||
struct KeyRegister;
|
|
||||||
struct KeyLogin;
|
struct KeyLogin;
|
||||||
struct KeyLoggedIn;
|
|
||||||
struct CodeRegister;
|
|
||||||
struct CodeLogIn;
|
|
||||||
struct CodeLoggedIn;
|
|
||||||
|
|
||||||
|
struct KeyRegister;
|
||||||
pub struct UserState<State, S: AuthAPI> {
|
|
||||||
api: S,
|
|
||||||
email: Email,
|
|
||||||
user_secret_key: UserSecretKey,
|
|
||||||
key_login: Option<KeyLoggedInSession>,
|
|
||||||
icon_nonce: Option<Nonce>,
|
|
||||||
icons: Option<Vec<Icon>>,
|
|
||||||
keypad: Option<Keypad>,
|
|
||||||
mask: Option<Vec<u64>>,
|
|
||||||
cipher: Option<NKodeCipher>,
|
|
||||||
_state: PhantomData<State>
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Login;
|
|
||||||
|
|
||||||
struct Register;
|
|
||||||
|
|
||||||
pub struct UserStateKey<State, S: AuthAPI> {
|
pub struct UserStateKey<State, S: AuthAPI> {
|
||||||
api: S,
|
api: S,
|
||||||
@@ -39,20 +18,20 @@ pub struct UserStateKey<State, S: AuthAPI> {
|
|||||||
_state: PhantomData<State>
|
_state: PhantomData<State>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: AuthAPI> UserStateKey<Register,S> {
|
impl <S: AuthAPI> UserStateKey<KeyRegister,S> {
|
||||||
pub async fn register(self) -> anyhow::Result<UserStateKey<Login, S>, String> {
|
pub async fn register(self) -> Result<UserStateKey<KeyLogin, 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(UserStateKey {
|
Ok(UserStateKey {
|
||||||
api: self.api,
|
api: self.api,
|
||||||
email: self.email,
|
email: self.email,
|
||||||
user_secret_key: self.user_secret_key,
|
user_secret_key: self.user_secret_key,
|
||||||
_state: PhantomData::<Login>,
|
_state: PhantomData::<KeyLogin>,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: AuthAPI> UserStateKey<Login,S> {
|
impl <S: AuthAPI> UserStateKey<KeyLogin,S> {
|
||||||
pub async fn login(self) -> anyhow::Result<UserStateKeyLoggedIn<S>,String> {
|
pub async fn login(self) -> Result<UserStateKeyLoggedIn<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(UserStateKeyLoggedIn {
|
Ok(UserStateKeyLoggedIn {
|
||||||
api: self.api,
|
api: self.api,
|
||||||
@@ -71,7 +50,7 @@ pub struct UserStateKeyLoggedIn<S: AuthAPI> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl <S: AuthAPI> UserStateKeyLoggedIn<S> {
|
impl <S: AuthAPI> UserStateKeyLoggedIn<S> {
|
||||||
pub async fn register_code(self) -> anyhow::Result<UserStateCodeRegister<S>, String> {
|
pub async fn register_code(self) -> Result<UserStateCodeRegister<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?;
|
||||||
let policy = self.api.get_policy().await?;
|
let policy = self.api.get_policy().await?;
|
||||||
@@ -86,7 +65,7 @@ impl <S: AuthAPI> UserStateKeyLoggedIn<S> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_icons(&self, icon_nonce: &Nonce) -> anyhow::Result<Vec<Icon>, String> {
|
async fn get_icons(&self, icon_nonce: &Nonce) -> Result<Vec<Icon>, String> {
|
||||||
let chacha20_key = self.user_secret_key.chacha20_secret_key();
|
let chacha20_key = self.user_secret_key.chacha20_secret_key();
|
||||||
let mut chacha_cipher = nkode_rs::nkode_core::chacha20prng::ChaCha20PRNG::new(&chacha20_key, icon_nonce);
|
let mut chacha_cipher = nkode_rs::nkode_core::chacha20prng::ChaCha20PRNG::new(&chacha20_key, icon_nonce);
|
||||||
let mut icons = self.api.get_new_icons(&self.key_login).await?;
|
let mut icons = self.api.get_new_icons(&self.key_login).await?;
|
||||||
@@ -98,7 +77,7 @@ impl <S: AuthAPI> UserStateKeyLoggedIn<S> {
|
|||||||
Ok(icons)
|
Ok(icons)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login_code(self) -> anyhow::Result<UserStateCodeLogin<S>, String> {
|
pub async fn login_code(self) -> Result<UserStateCodeLogin<S>, String> {
|
||||||
let login_data = self.api.get_login_data(&self.key_login).await?;
|
let login_data = self.api.get_login_data(&self.key_login).await?;
|
||||||
let icons = self.get_icons(&login_data.icon_nonce()).await?;
|
let icons = self.get_icons(&login_data.icon_nonce()).await?;
|
||||||
let policy = self.api.get_policy().await?;
|
let policy = self.api.get_policy().await?;
|
||||||
@@ -128,7 +107,7 @@ pub struct UserStateCodeRegister<S: AuthAPI> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl <S: AuthAPI> UserStateCodeRegister<S> {
|
impl <S: AuthAPI> UserStateCodeRegister<S> {
|
||||||
pub async fn register(self, selected_icons: Vec<IconID>) -> anyhow::Result<UserStateCodeLogin<S>, String> {
|
pub async fn register(self, selected_icons: Vec<IconID>) -> Result<UserStateCodeLogin<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());
|
||||||
let secret_key = self.user_secret_key.chacha20_secret_key();
|
let secret_key = self.user_secret_key.chacha20_secret_key();
|
||||||
@@ -173,7 +152,7 @@ impl <S: AuthAPI> UserStateCodeLogin<S> {
|
|||||||
).unwrap().to_vec()
|
).unwrap().to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login(&self, selected_keys: &Vec<usize>) -> anyhow::Result<CodeLoggedInSession, 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}"))?;
|
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
|
self.api.login_code(&self.email, &passcode).await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,20 +5,20 @@ use opaque_ke::argon2::password_hash::rand_core::OsRng;
|
|||||||
use nkode_rs::from_bytes::FromBytes;
|
use nkode_rs::from_bytes::FromBytes;
|
||||||
use crate::server::models::CredKind;
|
use crate::server::models::CredKind;
|
||||||
use crate::server::repository::opaque_repo::{AuthRepoError, OpaqueDatabaseRepo, OpaqueSessionRepo};
|
use crate::server::repository::opaque_repo::{AuthRepoError, OpaqueDatabaseRepo, OpaqueSessionRepo};
|
||||||
use crate::server::repository::user_repo::UserRepo;
|
use crate::shared::models::store::UserAuthStore;
|
||||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession, LoggedInSession};
|
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession, LoggedInSession};
|
||||||
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: UserAuthStore> {
|
||||||
server_setup: NKodeServerSetup,
|
server_setup: NKodeServerSetup,
|
||||||
opaque_db: R,
|
opaque_db: R,
|
||||||
opaque_sess: S,
|
opaque_sess: S,
|
||||||
user_db: U,
|
user_db: U,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U> {
|
impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserAuthStore> ServerApp<R, S, U> {
|
||||||
pub fn new(server_setup: NKodeServerSetup, opaque_db: R, opaque_sess: S, user_db: U) -> Self {
|
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}
|
Self { server_setup, opaque_db, opaque_sess, user_db}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::server::repository::user_repo::UserRepo;
|
use crate::shared::models::store::UserAuthStore;
|
||||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession};
|
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession};
|
||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ impl Default for InMemoryUserDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UserRepo for InMemoryUserDB {
|
impl UserAuthStore for InMemoryUserDB {
|
||||||
async fn get_key_session(&self, session_id: &Uuid) -> Result<KeyLoggedInSession, String> {
|
async fn get_key_session(&self, session_id: &Uuid) -> Result<KeyLoggedInSession, String> {
|
||||||
self.key_session.lock().await
|
self.key_session.lock().await
|
||||||
.get(&session_id)
|
.get(&session_id)
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
pub mod in_memory;
|
pub mod in_memory;
|
||||||
pub mod opaque_repo;
|
pub mod opaque_repo;
|
||||||
pub mod user_repo;
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod opaque;
|
pub mod opaque;
|
||||||
pub mod app;
|
pub mod app;
|
||||||
pub mod email;
|
pub mod email;
|
||||||
|
pub mod store;
|
||||||
@@ -8,6 +8,8 @@ use uuid::Uuid;
|
|||||||
use nkode_rs::nkode_core::chacha20prng::SecretKey;
|
use nkode_rs::nkode_core::chacha20prng::SecretKey;
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
use nkode_rs::from_bytes::FromBytes;
|
use nkode_rs::from_bytes::FromBytes;
|
||||||
|
use rand::RngCore;
|
||||||
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
const USER_KEY_SIZE: usize = 16;
|
const USER_KEY_SIZE: usize = 16;
|
||||||
|
|
||||||
@@ -15,6 +17,14 @@ const USER_KEY_SIZE: usize = 16;
|
|||||||
pub struct UserSecretKey(Zeroizing<[u8; USER_KEY_SIZE]>);
|
pub struct UserSecretKey(Zeroizing<[u8; USER_KEY_SIZE]>);
|
||||||
|
|
||||||
impl UserSecretKey {
|
impl UserSecretKey {
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let mut rng = OsRng;
|
||||||
|
let mut secret_key = [0u8; USER_KEY_SIZE];
|
||||||
|
rng.fill_bytes(&mut secret_key);
|
||||||
|
Self(Zeroizing::new(secret_key))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn chacha20_secret_key(&self) -> SecretKey {
|
pub fn chacha20_secret_key(&self) -> SecretKey {
|
||||||
let out = blake3::derive_key("your-app chacha20 secret key v1", &self.0.as_slice());
|
let out = blake3::derive_key("your-app chacha20 secret key v1", &self.0.as_slice());
|
||||||
SecretKey::from_bytes(&out).unwrap()
|
SecretKey::from_bytes(&out).unwrap()
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedIn
|
|||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait UserRepo {
|
pub trait UserAuthStore {
|
||||||
async fn get_key_session(&self, session_id: &Uuid) -> Result<KeyLoggedInSession, String>;
|
async fn get_key_session(&self, session_id: &Uuid) -> Result<KeyLoggedInSession, String>;
|
||||||
async fn get_code_session(&self, session_id: &Uuid) -> Result<CodeLoggedInSession, String>;
|
async fn get_code_session(&self, session_id: &Uuid) -> Result<CodeLoggedInSession, String>;
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use opaque_ke::rand::rngs::OsRng;
|
use opaque_ke::rand::rngs::OsRng;
|
||||||
use nkode_protocol::client::opaque::{AuthenticationData, ClientAuthError, OpaqueAuth};
|
use nkode_protocol::client::opaque::{OpaqueAuthData, ClientAuthError, OpaqueAuth};
|
||||||
use nkode_protocol::server::app::{Key, ServerApp};
|
use nkode_protocol::server::app::{ServerApp};
|
||||||
use nkode_protocol::server::repository::in_memory::in_memory_opaque_db::InMemoryOpaqueDB;
|
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::server::repository::in_memory::in_memory_opaque_session::InMemoryOpaqueSession;
|
||||||
use nkode_protocol::shared::models::opaque::NKodeServerSetup;
|
use nkode_protocol::shared::models::opaque::NKodeServerSetup;
|
||||||
@@ -19,7 +19,7 @@ async fn opaque_key_registration_and_login_roundtrip() {
|
|||||||
);
|
);
|
||||||
let key_server: InMemoryKeyServer = InMemoryServer::new(&server);
|
let key_server: InMemoryKeyServer = InMemoryServer::new(&server);
|
||||||
let auth = OpaqueAuth::new(&key_server);
|
let auth = OpaqueAuth::new(&key_server);
|
||||||
let auth_data = AuthenticationData::from_secret_key("a@b.com", b"supersecret16bytes");
|
let auth_data = OpaqueAuthData::from_secret_key("a@b.com", b"supersecret16bytes");
|
||||||
auth.register(&auth_data).await.expect("registration should succeed");
|
auth.register(&auth_data).await.expect("registration should succeed");
|
||||||
let _ =auth.login(&auth_data)
|
let _ =auth.login(&auth_data)
|
||||||
.await
|
.await
|
||||||
@@ -37,7 +37,7 @@ async fn opaque_login_fails_if_not_registered() {
|
|||||||
InMemoryUserDB::new()
|
InMemoryUserDB::new()
|
||||||
);
|
);
|
||||||
let key_server = InMemoryKeyServer::new(&server);
|
let key_server = InMemoryKeyServer::new(&server);
|
||||||
let auth = AuthenticationData::from_secret_key("nope@nope.com", b"supersecret16bytes");
|
let auth = OpaqueAuthData::from_secret_key("nope@nope.com", b"supersecret16bytes");
|
||||||
let login_reg = OpaqueAuth::new(&key_server);
|
let login_reg = OpaqueAuth::new(&key_server);
|
||||||
let err = login_reg.login(&auth)
|
let err = login_reg.login(&auth)
|
||||||
.await
|
.await
|
||||||
@@ -60,7 +60,7 @@ async fn cannot_register_code_before_key() {
|
|||||||
);
|
);
|
||||||
let key_server: InMemoryCodeServer = InMemoryServer::new(&server);
|
let key_server: InMemoryCodeServer = InMemoryServer::new(&server);
|
||||||
let auth = OpaqueAuth::new(&key_server);
|
let auth = OpaqueAuth::new(&key_server);
|
||||||
let auth_data = AuthenticationData::from_code("x@y.com", &[1u64,2,3,4]);
|
let auth_data = OpaqueAuthData::from_code("x@y.com", &[1u64,2,3,4]);
|
||||||
let err = auth.register(&auth_data)
|
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");
|
||||||
|
|||||||
Reference in New Issue
Block a user