refactor(server): migrated auth to ml-dsa

This commit is contained in:
hdbg
2026-04-07 11:43:21 +02:00
parent 1497884ce6
commit 0d424f3afc
25 changed files with 457 additions and 414 deletions

View File

@@ -4,18 +4,31 @@ use arbiter_server::{
GlobalActors,
bootstrap::GetToken,
keyholder::Bootstrap,
user_agent::{AuthPublicKey, UserAgentConnection, UserAgentCredentials, auth},
user_agent::{UserAgentConnection, UserAgentCredentials, auth},
},
crypto::authn,
crypto::integrity,
db::{self, schema},
safe_cell::{SafeCell, SafeCellHandle as _},
};
use diesel::{ExpressionMethods as _, QueryDsl, insert_into};
use diesel_async::RunQueryDsl;
use ed25519_dalek::Signer as _;
use ml_dsa::{KeyGen, MlDsa87, SigningKey, signature::Keypair as _};
use super::common::ChannelTransport;
fn sign_useragent_challenge(
key: &SigningKey<MlDsa87>,
nonce: i32,
pubkey_bytes: &[u8],
) -> authn::Signature {
let challenge = arbiter_proto::format_challenge(nonce, pubkey_bytes);
key.signing_key()
.sign_deterministic(&challenge, arbiter_proto::USERAGENT_CONTEXT)
.unwrap()
.into()
}
#[tokio::test]
#[test_log::test]
pub async fn test_bootstrap_token_auth() {
@@ -37,10 +50,10 @@ pub async fn test_bootstrap_token_auth() {
auth::authenticate(&mut props, server_transport).await
});
let new_key = ed25519_dalek::SigningKey::generate(&mut rand::rng());
let new_key = MlDsa87::key_gen(&mut rand::rng());
test_transport
.send(auth::Inbound::AuthChallengeRequest {
pubkey: AuthPublicKey::Ed25519(new_key.verifying_key()),
pubkey: new_key.verifying_key().into(),
bootstrap_token: Some(token),
})
.await
@@ -63,7 +76,7 @@ pub async fn test_bootstrap_token_auth() {
.first::<Vec<u8>>(&mut conn)
.await
.unwrap();
assert_eq!(stored_pubkey, new_key.verifying_key().to_bytes().to_vec());
assert_eq!(stored_pubkey, new_key.verifying_key().encode().to_vec());
}
#[tokio::test]
@@ -79,10 +92,10 @@ pub async fn test_bootstrap_invalid_token_auth() {
auth::authenticate(&mut props, server_transport).await
});
let new_key = ed25519_dalek::SigningKey::generate(&mut rand::rng());
let new_key = MlDsa87::key_gen(&mut rand::rng());
test_transport
.send(auth::Inbound::AuthChallengeRequest {
pubkey: AuthPublicKey::Ed25519(new_key.verifying_key()),
pubkey: new_key.verifying_key().into(),
bootstrap_token: Some("invalid_token".to_string()),
})
.await
@@ -115,8 +128,8 @@ pub async fn test_challenge_auth() {
.await
.unwrap();
let new_key = ed25519_dalek::SigningKey::generate(&mut rand::rng());
let pubkey_bytes = new_key.verifying_key().to_bytes().to_vec();
let new_key = MlDsa87::key_gen(&mut rand::rng());
let pubkey_bytes = new_key.verifying_key().encode().to_vec();
{
let mut conn = db.get().await.unwrap();
@@ -133,7 +146,7 @@ pub async fn test_challenge_auth() {
&mut conn,
&actors.key_holder,
&UserAgentCredentials {
pubkey: AuthPublicKey::Ed25519(new_key.verifying_key()),
pubkey: new_key.verifying_key().into(),
nonce: 1,
},
id,
@@ -151,7 +164,7 @@ pub async fn test_challenge_auth() {
test_transport
.send(auth::Inbound::AuthChallengeRequest {
pubkey: AuthPublicKey::Ed25519(new_key.verifying_key()),
pubkey: new_key.verifying_key().into(),
bootstrap_token: None,
})
.await
@@ -169,12 +182,11 @@ pub async fn test_challenge_auth() {
Err(err) => panic!("Expected Ok response, got Err({err:?})"),
};
let formatted_challenge = arbiter_proto::format_challenge(challenge, &pubkey_bytes);
let signature = new_key.sign(&formatted_challenge);
let signature = sign_useragent_challenge(&new_key, challenge, &pubkey_bytes);
test_transport
.send(auth::Inbound::AuthChallengeSolution {
signature: signature.to_bytes().to_vec(),
signature: signature.to_bytes(),
})
.await
.unwrap();
@@ -205,8 +217,8 @@ pub async fn test_challenge_auth_rejects_integrity_tag_mismatch_when_unsealed()
.await
.unwrap();
let new_key = ed25519_dalek::SigningKey::generate(&mut rand::rng());
let pubkey_bytes = new_key.verifying_key().to_bytes().to_vec();
let new_key = MlDsa87::key_gen(&mut rand::rng());
let pubkey_bytes = new_key.verifying_key().encode().to_vec();
{
let mut conn = db.get().await.unwrap();
@@ -229,7 +241,7 @@ pub async fn test_challenge_auth_rejects_integrity_tag_mismatch_when_unsealed()
test_transport
.send(auth::Inbound::AuthChallengeRequest {
pubkey: AuthPublicKey::Ed25519(new_key.verifying_key()),
pubkey: new_key.verifying_key().into(),
bootstrap_token: None,
})
.await
@@ -254,8 +266,8 @@ pub async fn test_challenge_auth_rejects_invalid_signature() {
.await
.unwrap();
let new_key = ed25519_dalek::SigningKey::generate(&mut rand::rng());
let pubkey_bytes = new_key.verifying_key().to_bytes().to_vec();
let new_key = MlDsa87::key_gen(&mut rand::rng());
let pubkey_bytes = new_key.verifying_key().encode().to_vec();
{
let mut conn = db.get().await.unwrap();
@@ -272,7 +284,7 @@ pub async fn test_challenge_auth_rejects_invalid_signature() {
&mut conn,
&actors.key_holder,
&UserAgentCredentials {
pubkey: AuthPublicKey::Ed25519(new_key.verifying_key()),
pubkey: new_key.verifying_key().into(),
nonce: 1,
},
id,
@@ -290,7 +302,7 @@ pub async fn test_challenge_auth_rejects_invalid_signature() {
test_transport
.send(auth::Inbound::AuthChallengeRequest {
pubkey: AuthPublicKey::Ed25519(new_key.verifying_key()),
pubkey: new_key.verifying_key().into(),
bootstrap_token: None,
})
.await
@@ -308,12 +320,11 @@ pub async fn test_challenge_auth_rejects_invalid_signature() {
Err(err) => panic!("Expected Ok response, got Err({err:?})"),
};
let wrong_challenge = arbiter_proto::format_challenge(challenge + 1, &pubkey_bytes);
let signature = new_key.sign(&wrong_challenge);
let signature = sign_useragent_challenge(&new_key, challenge + 1, &pubkey_bytes);
test_transport
.send(auth::Inbound::AuthChallengeSolution {
signature: signature.to_bytes().to_vec(),
signature: signature.to_bytes(),
})
.await
.unwrap();