From 42760bbd79187f491799d4bf52724a3ac4a5aa20 Mon Sep 17 00:00:00 2001 From: CleverWild Date: Sat, 14 Mar 2026 13:23:06 +0100 Subject: [PATCH] revert(auth): remove RSA support from authentication and related components --- protobufs/user_agent.proto | 1 - server/Cargo.lock | 84 ------------------- server/Cargo.toml | 3 - server/crates/arbiter-proto/src/transport.rs | 1 - server/crates/arbiter-proto/src/url.rs | 2 +- server/crates/arbiter-server/Cargo.toml | 3 - .../src/actors/user_agent/auth.rs | 13 ++- .../src/actors/user_agent/auth/state.rs | 29 +------ server/crates/arbiter-server/src/db/models.rs | 2 - server/crates/arbiter-useragent/Cargo.toml | 3 - server/crates/arbiter-useragent/src/lib.rs | 21 +---- 11 files changed, 9 insertions(+), 153 deletions(-) diff --git a/protobufs/user_agent.proto b/protobufs/user_agent.proto index fcf508d..55b18fc 100644 --- a/protobufs/user_agent.proto +++ b/protobufs/user_agent.proto @@ -9,7 +9,6 @@ enum KeyType { KEY_TYPE_UNSPECIFIED = 0; KEY_TYPE_ED25519 = 1; KEY_TYPE_ECDSA_SECP256K1 = 2; - KEY_TYPE_RSA = 3; } message AuthChallengeRequest { diff --git a/server/Cargo.lock b/server/Cargo.lock index 1586320..9645220 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -731,12 +731,9 @@ dependencies = [ "rand 0.10.0", "rcgen", "restructed", - "rsa", "rustls", "secrecy", - "sha2 0.10.9", "smlang", - "spki", "strum", "test-log", "thiserror", @@ -767,11 +764,8 @@ dependencies = [ "k256", "kameo", "rand 0.10.0", - "rsa", "rustls-webpki", - "sha2 0.10.9", "smlang", - "spki", "thiserror", "tokio", "tokio-stream", @@ -1739,7 +1733,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", - "pem-rfc7468", "zeroize", ] @@ -2920,9 +2913,6 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] [[package]] name = "leb128fmt" @@ -3156,22 +3146,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint-dig" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" -dependencies = [ - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - [[package]] name = "num-conv" version = "0.2.0" @@ -3187,17 +3161,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -3367,15 +3330,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - [[package]] name = "percent-encoding" version = "2.3.2" @@ -3435,17 +3389,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - [[package]] name = "pkcs8" version = "0.10.2" @@ -4093,27 +4036,6 @@ dependencies = [ "rustc-hex", ] -[[package]] -name = "rsa" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" -dependencies = [ - "const-oid", - "digest 0.10.7", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "sha2 0.10.9", - "signature 2.2.0", - "spki", - "subtle", - "zeroize", -] - [[package]] name = "rsqlite-vfs" version = "0.1.0" @@ -4661,12 +4583,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "spki" version = "0.7.3" diff --git a/server/Cargo.toml b/server/Cargo.toml index 03ffbbe..bbb9eb9 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -37,6 +37,3 @@ rcgen = { version = "0.14.7", features = [ "zeroize", ], default-features = false } k256 = { version = "0.13.4", features = ["ecdsa", "pkcs8"] } -rsa = { version = "0.9", features = ["sha2"] } -sha2 = "0.10" -spki = "0.7" diff --git a/server/crates/arbiter-proto/src/transport.rs b/server/crates/arbiter-proto/src/transport.rs index f5acaf9..6f89b80 100644 --- a/server/crates/arbiter-proto/src/transport.rs +++ b/server/crates/arbiter-proto/src/transport.rs @@ -203,7 +203,6 @@ pub mod grpc { /// [`Bi`] adapter backed by a tonic gRPC bidirectional stream. /// - /// Tonic receive errors are logged and treated as stream closure (`None`). /// The receive converter is only invoked for successful inbound transport /// items. diff --git a/server/crates/arbiter-proto/src/url.rs b/server/crates/arbiter-proto/src/url.rs index adfd45d..c961680 100644 --- a/server/crates/arbiter-proto/src/url.rs +++ b/server/crates/arbiter-proto/src/url.rs @@ -20,7 +20,7 @@ impl Display for ArbiterUrl { "{ARBITER_URL_SCHEME}://{}:{}?{CERT_QUERY_KEY}={}", self.host, self.port, - BASE64_URL_SAFE.encode(self.ca_cert.to_vec()) + BASE64_URL_SAFE.encode(&self.ca_cert) ); if let Some(token) = &self.bootstrap_token { base.push_str(&format!("&{BOOTSTRAP_TOKEN_QUERY_KEY}={}", token)); diff --git a/server/crates/arbiter-server/Cargo.toml b/server/crates/arbiter-server/Cargo.toml index 4fcb05e..b93c02e 100644 --- a/server/crates/arbiter-server/Cargo.toml +++ b/server/crates/arbiter-server/Cargo.toml @@ -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" diff --git a/server/crates/arbiter-server/src/actors/user_agent/auth.rs b/server/crates/arbiter-server/src/actors/user_agent/auth.rs index 3da8291..de5f20f 100644 --- a/server/crates/arbiter-server/src/actors/user_agent/auth.rs +++ b/server/crates/arbiter-server/src/actors/user_agent/auth.rs @@ -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) -> Result { - 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 Result { +pub async fn authenticate_and_create( + mut props: UserAgentConnection, +) -> Result { let _key = authenticate(&mut props).await?; let session = UserAgentSession::new(props); Ok(session) diff --git a/server/crates/arbiter-server/src/actors/user_agent/auth/state.rs b/server/crates/arbiter-server/src/actors/user_agent/auth/state.rs index 2acd45b..04e6d57 100644 --- a/server/crates/arbiter-server/src/actors/user_agent/auth/state.rs +++ b/server/crates/arbiter-server/src/actors/user_agent/auth/state.rs @@ -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 { 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::::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) } diff --git a/server/crates/arbiter-server/src/db/models.rs b/server/crates/arbiter-server/src/db/models.rs index 92c6d85..3f0de44 100644 --- a/server/crates/arbiter-server/src/db/models.rs +++ b/server/crates/arbiter-server/src/db/models.rs @@ -81,7 +81,6 @@ pub mod types { pub enum KeyType { Ed25519 = 1, EcdsaSecp256k1 = 2, - Rsa = 3, } impl ToSql 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()), } } diff --git a/server/crates/arbiter-useragent/Cargo.toml b/server/crates/arbiter-useragent/Cargo.toml index 7b08cbf..a2042eb 100644 --- a/server/crates/arbiter-useragent/Cargo.toml +++ b/server/crates/arbiter-useragent/Cargo.toml @@ -15,9 +15,6 @@ ed25519-dalek.workspace = true smlang.workspace = true x25519-dalek.workspace = true k256.workspace = true -rsa.workspace = true -sha2.workspace = true -spki.workspace = true rand.workspace = true thiserror.workspace = true tokio-stream.workspace = true diff --git a/server/crates/arbiter-useragent/src/lib.rs b/server/crates/arbiter-useragent/src/lib.rs index b2f3ee3..1be9f3a 100644 --- a/server/crates/arbiter-useragent/src/lib.rs +++ b/server/crates/arbiter-useragent/src/lib.rs @@ -16,10 +16,8 @@ use tracing::{error, info}; /// Signing key variants supported by the user-agent auth protocol. pub enum SigningKeyEnum { Ed25519(ed25519_dalek::SigningKey), - /// secp256k1 ECDSA; public key is sent as DER SPKI; signature is raw 64-byte (r||s). + /// secp256k1 ECDSA; public key is sent as SEC1 compressed 33 bytes; signature is raw 64-byte (r||s). EcdsaSecp256k1(k256::ecdsa::SigningKey), - /// RSA; public key is sent as DER SPKI; signature is PSS+SHA-256. - Rsa(rsa::RsaPrivateKey), } impl SigningKeyEnum { @@ -31,13 +29,6 @@ impl SigningKeyEnum { SigningKeyEnum::EcdsaSecp256k1(k) => { k.verifying_key().to_encoded_point(true).as_bytes().to_vec() } - SigningKeyEnum::Rsa(k) => { - use rsa::pkcs8::EncodePublicKey as _; - k.to_public_key() - .to_public_key_der() - .expect("rsa SPKI encoding is infallible") - .to_vec() - } } } @@ -46,7 +37,6 @@ impl SigningKeyEnum { match self { SigningKeyEnum::Ed25519(_) => ProtoKeyType::Ed25519, SigningKeyEnum::EcdsaSecp256k1(_) => ProtoKeyType::EcdsaSecp256k1, - SigningKeyEnum::Rsa(_) => ProtoKeyType::Rsa, } } @@ -62,15 +52,6 @@ impl SigningKeyEnum { let sig: k256::ecdsa::Signature = k.sign(msg); sig.to_bytes().to_vec() } - SigningKeyEnum::Rsa(k) => { - use rsa::signature::RandomizedSigner as _; - let signing_key = rsa::pss::BlindedSigningKey::::new(k.clone()); - // Use rand_core OsRng from the rsa crate's re-exported rand_core (0.6.x), - // which is the version rsa's signature API expects. - let sig = signing_key.sign_with_rng(&mut rsa::rand_core::OsRng, msg); - use rsa::signature::SignatureEncoding as _; - sig.to_vec() - } } } }