From 7d92be0154d0d4b1abeba7c514dbd059ac6f6492 Mon Sep 17 00:00:00 2001 From: jgreeer Date: Fri, 11 Sep 2026 15:02:31 +0000 Subject: [PATCH] add RSA key size to SignatureAlgorithm --- rcgen/src/key_pair.rs | 14 ++++++- rcgen/src/lib.rs | 25 ++++++++++-- rcgen/src/sign_algo.rs | 88 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/rcgen/src/key_pair.rs b/rcgen/src/key_pair.rs index a88ea05f..1f48dd2e 100644 --- a/rcgen/src/key_pair.rs +++ b/rcgen/src/key_pair.rs @@ -130,7 +130,15 @@ impl KeyPair { )) }, #[cfg(feature = "aws_lc_rs")] - SignAlgo::Rsa(sign_alg) => Self::generate_rsa_inner(alg, sign_alg, KeySize::Rsa2048), + SignAlgo::Rsa(sign_alg) => Self::generate_rsa_inner( + alg, + sign_alg, + match alg.rsa_key_size { + Some(RsaKeySize::_3072) => KeySize::Rsa3072, + Some(RsaKeySize::_4096) => KeySize::Rsa4096, + _ => KeySize::Rsa2048, + }, + ), // Ring doesn't have RSA key generation yet: // https://github.com/briansmith/ring/issues/219 // https://github.com/briansmith/ring/pull/733 @@ -144,6 +152,9 @@ impl KeyPair { /// If passed a signature algorithm that is not RSA, it will return /// [`Error::KeyGenerationUnavailable`]. #[cfg(all(feature = "crypto", feature = "aws_lc_rs"))] + #[deprecated( + note = "pass a key-size-specific algorithm such as `PKCS_RSA_SHA256_4096` to `generate_for` instead" + )] pub fn generate_rsa_for( alg: &'static SignatureAlgorithm, key_size: RsaKeySize, @@ -573,7 +584,6 @@ impl TryFrom<&PrivateKeyDer<'_>> for KeyPair { } /// The key size used for RSA key generation -#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum RsaKeySize { diff --git a/rcgen/src/lib.rs b/rcgen/src/lib.rs index 7834641f..839afb2f 100644 --- a/rcgen/src/lib.rs +++ b/rcgen/src/lib.rs @@ -77,9 +77,7 @@ mod key_pair; pub use key_pair::serialize_private_key_pem; #[cfg(feature = "crypto")] pub use key_pair::KeyPair; -#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))] -pub use key_pair::RsaKeySize; -pub use key_pair::{PublicKeyData, SigningKey, SubjectPublicKeyInfo}; +pub use key_pair::{PublicKeyData, RsaKeySize, SigningKey, SubjectPublicKeyInfo}; mod sign_algo; pub use sign_algo::algo::*; @@ -663,6 +661,27 @@ mod tests { } } + #[cfg(feature = "aws_lc_rs")] + #[test] + fn rsa_key_size_algorithms_generate_expected_key_sizes() { + use crate::{ + KeyPair, SigningKey, PKCS_RSA_SHA256, PKCS_RSA_SHA256_3072, PKCS_RSA_SHA256_4096, + }; + + // Key size does not affect signature-algorithm identity. + assert_eq!(PKCS_RSA_SHA256, PKCS_RSA_SHA256_3072); + assert_eq!(PKCS_RSA_SHA256, PKCS_RSA_SHA256_4096); + + for (alg, sig_len) in [ + (&PKCS_RSA_SHA256, 256usize), + (&PKCS_RSA_SHA256_3072, 384), + (&PKCS_RSA_SHA256_4096, 512), + ] { + let (key, _) = KeyPair::generate_for(alg).unwrap(); + assert_eq!(key.sign(b"message").unwrap().len(), sig_len); + } + } + #[test] fn signature_algos_different() { // TODO unify this with test_key_params_mismatch. diff --git a/rcgen/src/sign_algo.rs b/rcgen/src/sign_algo.rs index a7fe1c7c..09d8c7ae 100644 --- a/rcgen/src/sign_algo.rs +++ b/rcgen/src/sign_algo.rs @@ -8,6 +8,7 @@ use aws_lc_rs::signature::{ use yasna::models::ObjectIdentifier; use yasna::DERWriter; +use crate::key_pair::RsaKeySize; #[cfg(feature = "crypto")] use crate::ring_like::signature::{self, EcdsaSigningAlgorithm, EdDSAParameters, RsaEncoding}; use crate::Error; @@ -38,6 +39,9 @@ pub struct SignatureAlgorithm { pub(crate) sign_alg: SignAlgo, oid_components: &'static [u64], params: SignatureAlgorithmParams, + // Only read under `aws_lc_rs`. Not part of identity. + #[allow(dead_code)] + pub(crate) rsa_key_size: Option, } impl fmt::Debug for SignatureAlgorithm { @@ -125,7 +129,7 @@ pub(crate) mod algo { use super::*; use crate::oid::*; - /// RSA signing with PKCS#1 1.5 padding and SHA-256 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055) + /// RSA signing with PKCS#1 1.5 padding and SHA-256 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 2048-bit key pub static PKCS_RSA_SHA256: SignatureAlgorithm = SignatureAlgorithm { oids_sign_alg: &[RSA_ENCRYPTION], #[cfg(feature = "crypto")] @@ -133,9 +137,32 @@ pub(crate) mod algo { // sha256WithRSAEncryption in RFC 4055 oid_components: &[1, 2, 840, 113549, 1, 1, 11], params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_2048), }; - /// RSA signing with PKCS#1 1.5 padding and SHA-384 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055) + /// RSA signing with PKCS#1 1.5 padding and SHA-256 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 3072-bit key + pub static PKCS_RSA_SHA256_3072: SignatureAlgorithm = SignatureAlgorithm { + oids_sign_alg: &[RSA_ENCRYPTION], + #[cfg(feature = "crypto")] + sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA256), + // sha256WithRSAEncryption in RFC 4055 + oid_components: &[1, 2, 840, 113549, 1, 1, 11], + params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_3072), + }; + + /// RSA signing with PKCS#1 1.5 padding and SHA-256 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 4096-bit key + pub static PKCS_RSA_SHA256_4096: SignatureAlgorithm = SignatureAlgorithm { + oids_sign_alg: &[RSA_ENCRYPTION], + #[cfg(feature = "crypto")] + sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA256), + // sha256WithRSAEncryption in RFC 4055 + oid_components: &[1, 2, 840, 113549, 1, 1, 11], + params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_4096), + }; + + /// RSA signing with PKCS#1 1.5 padding and SHA-384 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 2048-bit key pub static PKCS_RSA_SHA384: SignatureAlgorithm = SignatureAlgorithm { oids_sign_alg: &[RSA_ENCRYPTION], #[cfg(feature = "crypto")] @@ -143,9 +170,32 @@ pub(crate) mod algo { // sha384WithRSAEncryption in RFC 4055 oid_components: &[1, 2, 840, 113549, 1, 1, 12], params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_2048), + }; + + /// RSA signing with PKCS#1 1.5 padding and SHA-384 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 3072-bit key + pub static PKCS_RSA_SHA384_3072: SignatureAlgorithm = SignatureAlgorithm { + oids_sign_alg: &[RSA_ENCRYPTION], + #[cfg(feature = "crypto")] + sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA384), + // sha384WithRSAEncryption in RFC 4055 + oid_components: &[1, 2, 840, 113549, 1, 1, 12], + params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_3072), }; - /// RSA signing with PKCS#1 1.5 padding and SHA-512 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055) + /// RSA signing with PKCS#1 1.5 padding and SHA-384 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 4096-bit key + pub static PKCS_RSA_SHA384_4096: SignatureAlgorithm = SignatureAlgorithm { + oids_sign_alg: &[RSA_ENCRYPTION], + #[cfg(feature = "crypto")] + sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA384), + // sha384WithRSAEncryption in RFC 4055 + oid_components: &[1, 2, 840, 113549, 1, 1, 12], + params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_4096), + }; + + /// RSA signing with PKCS#1 1.5 padding and SHA-512 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 2048-bit key pub static PKCS_RSA_SHA512: SignatureAlgorithm = SignatureAlgorithm { oids_sign_alg: &[RSA_ENCRYPTION], #[cfg(feature = "crypto")] @@ -153,6 +203,29 @@ pub(crate) mod algo { // sha512WithRSAEncryption in RFC 4055 oid_components: &[1, 2, 840, 113549, 1, 1, 13], params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_2048), + }; + + /// RSA signing with PKCS#1 1.5 padding and SHA-512 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 3072-bit key + pub static PKCS_RSA_SHA512_3072: SignatureAlgorithm = SignatureAlgorithm { + oids_sign_alg: &[RSA_ENCRYPTION], + #[cfg(feature = "crypto")] + sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA512), + // sha512WithRSAEncryption in RFC 4055 + oid_components: &[1, 2, 840, 113549, 1, 1, 13], + params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_3072), + }; + + /// RSA signing with PKCS#1 1.5 padding and SHA-512 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055), generating a 4096-bit key + pub static PKCS_RSA_SHA512_4096: SignatureAlgorithm = SignatureAlgorithm { + oids_sign_alg: &[RSA_ENCRYPTION], + #[cfg(feature = "crypto")] + sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA512), + // sha512WithRSAEncryption in RFC 4055 + oid_components: &[1, 2, 840, 113549, 1, 1, 13], + params: SignatureAlgorithmParams::Null, + rsa_key_size: Some(RsaKeySize::_4096), }; /// ECDSA signing using the P-256 curves and SHA-256 hashing as per [RFC 5758](https://tools.ietf.org/html/rfc5758#section-3.2) @@ -163,6 +236,7 @@ pub(crate) mod algo { // ecdsa-with-SHA256 in RFC 5758 oid_components: &[1, 2, 840, 10045, 4, 3, 2], params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; /// ECDSA signing using the P-384 curves and SHA-384 hashing as per [RFC 5758](https://tools.ietf.org/html/rfc5758#section-3.2) @@ -173,6 +247,7 @@ pub(crate) mod algo { // ecdsa-with-SHA384 in RFC 5758 oid_components: &[1, 2, 840, 10045, 4, 3, 3], params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; /// ECDSA signing using the P-521 curves and SHA-256 hashing as per [RFC 5758](https://tools.ietf.org/html/rfc5758#section-3.2) @@ -188,6 +263,7 @@ pub(crate) mod algo { // ecdsa-with-SHA256 in RFC 5758 oid_components: &[1, 2, 840, 10045, 4, 3, 2], params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; /// ECDSA signing using the P-521 curves and SHA-384 hashing as per [RFC 5758](https://tools.ietf.org/html/rfc5758#section-3.2) @@ -203,6 +279,7 @@ pub(crate) mod algo { // ecdsa-with-SHA384 in RFC 5758 oid_components: &[1, 2, 840, 10045, 4, 3, 3], params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; /// ECDSA signing using the P-521 curves and SHA-512 hashing as per [RFC 5758](https://tools.ietf.org/html/rfc5758#section-3.2) @@ -216,6 +293,7 @@ pub(crate) mod algo { // ecdsa-with-SHA512 in RFC 5758 oid_components: &[1, 2, 840, 10045, 4, 3, 4], params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; /// ED25519 curve signing as per [RFC 8410](https://tools.ietf.org/html/rfc8410) @@ -227,6 +305,7 @@ pub(crate) mod algo { // id-Ed25519 in RFC 8410 oid_components: &[1, 3, 101, 112], params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; /// ML-DSA-44 signing as per . @@ -237,6 +316,7 @@ pub(crate) mod algo { sign_alg: SignAlgo::PqDsa(&ML_DSA_44_SIGNING), oid_components: ML_DSA_44, params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; /// ML-DSA-65 signing as per . @@ -247,6 +327,7 @@ pub(crate) mod algo { sign_alg: SignAlgo::PqDsa(&ML_DSA_65_SIGNING), oid_components: ML_DSA_65, params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; /// ML-DSA-87 signing as per . @@ -257,6 +338,7 @@ pub(crate) mod algo { sign_alg: SignAlgo::PqDsa(&ML_DSA_87_SIGNING), oid_components: ML_DSA_87, params: SignatureAlgorithmParams::None, + rsa_key_size: None, }; } // Signature algorithm IDs as per https://tools.ietf.org/html/rfc4055