From fbab2494ebc4c2e55057bdad3c51b0d967077101 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sat, 10 Feb 2024 11:37:38 +0000 Subject: [PATCH] Add ServerPadlockGenerator, UserServerKeyGenerator prototypes --- src/auth.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/auth.rs b/src/auth.rs index fd2c405..9982ef4 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,13 +1,18 @@ use std::sync::Arc; +use base64::{prelude::BASE64_STANDARD, Engine}; +use hmac::{Hmac, Mac}; +use md5::Md5; use rand::{seq::IteratorRandom, thread_rng}; +use secrecy::{ExposeSecret, SecretVec}; use thiserror::Error; +use time::{macros::format_description, OffsetDateTime}; use tokio::sync::Mutex; use tracing::{event, instrument, Level}; use crate::{ db::{/* Database, */ Database, SqliteDatabase}, - secrets::{Password, UserToken}, + secrets::{Password, ServerHash, ServerPadlock, UserServerKey, UserToken}, }; #[derive(Debug, Error)] @@ -67,3 +72,57 @@ impl Authenticator { Ok(()) } } + +pub struct ServerPadlockGenerator { + secret: SecretVec, +} + +impl ServerPadlockGenerator { + pub fn new(/* secret */) -> Self { + todo!() + } + + pub fn generate_padlock(&self, server_hash: &ServerHash) -> ServerPadlock { + todo!() + } +} + +pub struct UserServerKeyGenerator { + user_authenticator: Arc, + padlock_generator: Arc, +} + +impl UserServerKeyGenerator { + pub fn new(/* Authenticator, ServerPadlockGenerator? */) -> Self { + todo!() + } + + pub async fn generate_user_server_key( + &self, + username: &str, + token: &UserToken, + server_hash: &ServerHash, + ) -> Result<(UserServerKey, String), AuthenticationError> { + self.user_authenticator + .verify_user_token(username, token) + .await?; + + let padlock = self.padlock_generator.generate_padlock(server_hash); + + let timestamp = OffsetDateTime::now_utc() + .format(format_description!( + "[year repr:last_two][month][day][hour repr:24][minute][second]" + )) + .expect("timestamp format should be validated at compile-time"); + + event!(Level::DEBUG, timestamp, "Generating user_server_key"); + + let mut mac: Hmac = Hmac::new_from_slice(padlock.0.expose_secret().as_bytes()) + .map_err(|_e| AuthenticationError::InvalidServerHash)?; + mac.update(format!("{}_{}_{}", username, padlock.0.expose_secret(), timestamp).as_bytes()); + let user_server_key = + UserServerKey(BASE64_STANDARD.encode(mac.finalize().into_bytes()).into()); + + Ok((user_server_key, timestamp)) + } +}