refactor(server::{useragent::auth, client::auth}): use random based + timestamp nonce instead of monotonic counter in database

This commit is contained in:
Skipper
2026-04-17 16:14:45 +02:00
parent 51e6571d80
commit 0e09afda5d
24 changed files with 320 additions and 466 deletions

View File

@@ -24,3 +24,4 @@ http = "1.4.0"
rustls-webpki = { version = "0.103.10", features = ["aws-lc-rs"] }
async-trait.workspace = true
rand.workspace = true
chrono.workspace = true

View File

@@ -1,4 +1,4 @@
use arbiter_crypto::authn::{CLIENT_CONTEXT, SigningKey, format_challenge};
use arbiter_crypto::authn::{self, CLIENT_CONTEXT, SigningKey};
use arbiter_proto::{
ClientMetadata,
proto::{
@@ -15,6 +15,7 @@ use arbiter_proto::{
shared::ClientInfo as ProtoClientInfo,
},
};
use chrono::DateTime;
use crate::{
storage::StorageError,
@@ -23,6 +24,8 @@ use crate::{
#[derive(Debug, thiserror::Error)]
pub enum AuthError {
#[error("Server sent invalid auth challenge")]
InvalidChallenge,
#[error("Auth challenge was not returned by server")]
MissingAuthChallenge,
@@ -98,7 +101,15 @@ async fn send_auth_challenge_solution(
key: &SigningKey,
challenge: AuthChallenge,
) -> std::result::Result<(), AuthError> {
let challenge_payload = format_challenge(challenge.nonce, &challenge.pubkey);
let timestamp = DateTime::from_timestamp_nanos(challenge.timestamp_nanos as i64);
let challenge = authn::AuthChallenge {
nonce: *challenge
.random
.as_array()
.ok_or(AuthError::InvalidChallenge)?,
timestamp,
};
let challenge_payload: Vec<u8> = challenge.format();
let signature = key
.sign_message(&challenge_payload, CLIENT_CONTEXT)
.map_err(|_| AuthError::UnexpectedAuthResponse)?