revert(auth): remove RSA support from authentication and related components
Some checks failed
ci/woodpecker/pr/server-audit Pipeline was successful
ci/woodpecker/pr/server-vet Pipeline failed
ci/woodpecker/pr/server-lint Pipeline failed
ci/woodpecker/pr/server-test Pipeline was successful

This commit is contained in:
2026-03-14 13:23:06 +01:00
parent d29bca853b
commit 42760bbd79
11 changed files with 9 additions and 153 deletions

View File

@@ -43,9 +43,6 @@ restructed = "0.2.2"
strum = { version = "0.27.2", features = ["derive"] }
pem = "3.0.6"
k256.workspace = true
rsa.workspace = true
sha2.workspace = true
spki.workspace = true
alloy.workspace = true
arbiter-tokens-registry.path = "../arbiter-tokens-registry"

View File

@@ -6,7 +6,8 @@ use tracing::error;
use crate::actors::user_agent::{
UserAgentConnection,
auth::state::{AuthContext, AuthPublicKey, AuthStateMachine}, session::UserAgentSession,
auth::state::{AuthContext, AuthPublicKey, AuthStateMachine},
session::UserAgentSession,
};
#[derive(thiserror::Error, Debug, PartialEq)]
@@ -51,12 +52,6 @@ fn parse_pubkey(key_type: ProtoKeyType, pubkey: Vec<u8>) -> Result<AuthPublicKey
.map_err(|_| Error::InvalidAuthPubkeyEncoding)?;
Ok(AuthPublicKey::EcdsaSecp256k1(key))
}
ProtoKeyType::Rsa => {
use rsa::pkcs8::DecodePublicKey as _;
let key = rsa::RsaPublicKey::from_public_key_der(&pubkey)
.map_err(|_| Error::InvalidAuthPubkeyEncoding)?;
Ok(AuthPublicKey::Rsa(key))
}
}
}
@@ -131,7 +126,9 @@ pub async fn authenticate(props: &mut UserAgentConnection) -> Result<AuthPublicK
}
}
pub async fn authenticate_and_create(mut props: UserAgentConnection) -> Result<UserAgentSession, Error> {
pub async fn authenticate_and_create(
mut props: UserAgentConnection,
) -> Result<UserAgentSession, Error> {
let _key = authenticate(&mut props).await?;
let session = UserAgentSession::new(props);
Ok(session)

View File

@@ -11,30 +11,22 @@ use crate::{
db::{models::KeyType, schema},
};
/// Abstraction over Ed25519 / ECDSA-secp256k1 / RSA public keys used during the auth handshake.
/// Abstraction over Ed25519 / ECDSA-secp256k1 public keys used during the auth handshake.
#[derive(Clone)]
pub enum AuthPublicKey {
Ed25519(ed25519_dalek::VerifyingKey),
/// Compressed SEC1 public key; signature bytes are raw 64-byte (r||s).
EcdsaSecp256k1(k256::ecdsa::VerifyingKey),
/// RSA-2048+ public key; signature bytes are PSS+SHA-256.
Rsa(rsa::RsaPublicKey),
}
impl AuthPublicKey {
/// Canonical bytes stored in DB and echoed back in the challenge.
/// Ed25519: raw 32 bytes. ECDSA: SEC1 compressed 33 bytes. RSA: DER-encoded SPKI.
/// Ed25519: raw 32 bytes. ECDSA: SEC1 compressed 33 bytes.
pub fn to_stored_bytes(&self) -> Vec<u8> {
match self {
AuthPublicKey::Ed25519(k) => k.to_bytes().to_vec(),
// SEC1 compressed (33 bytes) is the natural compact format for secp256k1
AuthPublicKey::EcdsaSecp256k1(k) => k.to_encoded_point(true).as_bytes().to_vec(),
AuthPublicKey::Rsa(k) => {
use rsa::pkcs8::EncodePublicKey as _;
k.to_public_key_der()
.expect("rsa SPKI encoding is infallible")
.to_vec()
}
}
}
@@ -42,7 +34,6 @@ impl AuthPublicKey {
match self {
AuthPublicKey::Ed25519(_) => KeyType::Ed25519,
AuthPublicKey::EcdsaSecp256k1(_) => KeyType::EcdsaSecp256k1,
AuthPublicKey::Rsa(_) => KeyType::Rsa,
}
}
}
@@ -170,15 +161,6 @@ impl AuthStateMachineContext for AuthContext<'_> {
})?;
vk.verify(&formatted, &sig).is_ok()
}
AuthPublicKey::Rsa(pk) => {
use rsa::signature::Verifier as _;
let verifying_key = rsa::pss::VerifyingKey::<sha2::Sha256>::new(pk.clone());
let sig = rsa::pss::Signature::try_from(solution.as_slice()).map_err(|_| {
error!(?solution, "Invalid RSA signature bytes");
Error::InvalidChallengeSolution
})?;
verifying_key.verify(&formatted, &sig).is_ok()
}
};
Ok(valid)
@@ -284,13 +266,6 @@ impl AuthStateMachineContext for AuthContext<'_> {
.expect("ecdsa key was already validated in parse_auth_event"),
)
}
crate::db::models::KeyType::Rsa => {
use rsa::pkcs8::DecodePublicKey as _;
AuthPublicKey::Rsa(
rsa::RsaPublicKey::from_public_key_der(&bytes)
.expect("rsa key was already validated in parse_auth_event"),
)
}
};
Ok(rebuilt)
}

View File

@@ -81,7 +81,6 @@ pub mod types {
pub enum KeyType {
Ed25519 = 1,
EcdsaSecp256k1 = 2,
Rsa = 3,
}
impl ToSql<Integer, Sqlite> for KeyType {
@@ -104,7 +103,6 @@ pub mod types {
match bytes.read_long() {
1 => Ok(KeyType::Ed25519),
2 => Ok(KeyType::EcdsaSecp256k1),
3 => Ok(KeyType::Rsa),
other => Err(format!("Unknown KeyType discriminant: {other}").into()),
}
}