diff --git a/rcgen/src/key_pair.rs b/rcgen/src/key_pair.rs index 102cd4df..e81066eb 100644 --- a/rcgen/src/key_pair.rs +++ b/rcgen/src/key_pair.rs @@ -259,12 +259,18 @@ impl KeyPair { } else if alg == &PKCS_RSA_SHA512 { let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?; KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA512) - } else if alg == &PKCS_RSA_PSS_SHA256 { - let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?; - KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA256) } else { #[cfg(feature = "aws_lc_rs")] - if alg == &PKCS_ECDSA_P521_SHA256 { + if alg == &PKCS_RSA_PSS_SHA256 { + let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?; + KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA256) + } else if alg == &PKCS_RSA_PSS_SHA384 { + let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?; + KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA384) + } else if alg == &PKCS_RSA_PSS_SHA512 { + let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?; + KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA512) + } else if alg == &PKCS_ECDSA_P521_SHA256 { KeyPairKind::Ec(ecdsa_from_pkcs8( &signature::ECDSA_P521_SHA256_ASN1_SIGNING, &serialized_der, diff --git a/rcgen/src/oid.rs b/rcgen/src/oid.rs index 3b1c0eb9..ee35b257 100644 --- a/rcgen/src/oid.rs +++ b/rcgen/src/oid.rs @@ -35,6 +35,7 @@ pub(crate) const ML_DSA_87: &[u64] = &[2, 16, 840, 1, 101, 3, 4, 3, 19]; /// rsaEncryption in [RFC 4055](https://www.rfc-editor.org/rfc/rfc4055#section-6) pub(crate) const RSA_ENCRYPTION: &[u64] = &[1, 2, 840, 113549, 1, 1, 1]; +#[cfg(feature = "aws_lc_rs")] /// id-RSASSA-PSS in [RFC 4055](https://www.rfc-editor.org/rfc/rfc4055#section-6) pub(crate) const RSASSA_PSS: &[u64] = &[1, 2, 840, 113549, 1, 1, 10]; diff --git a/rcgen/src/sign_algo.rs b/rcgen/src/sign_algo.rs index 9e6916cb..e4582e88 100644 --- a/rcgen/src/sign_algo.rs +++ b/rcgen/src/sign_algo.rs @@ -29,6 +29,7 @@ pub(crate) enum SignatureAlgorithmParams { /// Write null parameters Null, /// RSASSA-PSS-params as per RFC 4055 + #[allow(unused)] // RsaPss only used by feature `aws_lc_rs` RsaPss { hash_algorithm: &'static [u64], salt_length: u64, @@ -54,8 +55,6 @@ impl fmt::Debug for SignatureAlgorithm { write!(f, "PKCS_RSA_SHA384") } else if self == &PKCS_RSA_SHA512 { write!(f, "PKCS_RSA_SHA512") - } else if self == &PKCS_RSA_PSS_SHA256 { - write!(f, "PKCS_RSA_PSS_SHA256") } else if self == &PKCS_ECDSA_P256_SHA256 { write!(f, "PKCS_ECDSA_P256_SHA256") } else if self == &PKCS_ECDSA_P384_SHA384 { @@ -63,6 +62,18 @@ impl fmt::Debug for SignatureAlgorithm { } else if self == &PKCS_ED25519 { write!(f, "PKCS_ED25519") } else { + #[cfg(feature = "aws_lc_rs")] + if self == &PKCS_RSA_PSS_SHA256 { + return write!(f, "PKCS_RSA_PSS_SHA256"); + } + #[cfg(feature = "aws_lc_rs")] + if self == &PKCS_RSA_PSS_SHA384 { + return write!(f, "PKCS_RSA_PSS_SHA384"); + } + #[cfg(feature = "aws_lc_rs")] + if self == &PKCS_RSA_PSS_SHA512 { + return write!(f, "PKCS_RSA_PSS_SHA512"); + } #[cfg(feature = "aws_lc_rs")] if self == &PKCS_ECDSA_P521_SHA256 { return write!(f, "PKCS_ECDSA_P521_SHA256"); @@ -83,6 +94,21 @@ impl fmt::Debug for SignatureAlgorithm { impl PartialEq for SignatureAlgorithm { fn eq(&self, other: &Self) -> bool { + // RSA-PSS algs all have the same OID with different `params` fields + if let SignatureAlgorithmParams::RsaPss { + hash_algorithm: selfhash, + .. + } = self.params + { + if let SignatureAlgorithmParams::RsaPss { + hash_algorithm: otherhash, + .. + } = other.params + { + return (self.oids_sign_alg, self.oid_components, selfhash) + == (other.oids_sign_alg, other.oid_components, otherhash); + } + } (self.oids_sign_alg, self.oid_components) == (other.oids_sign_alg, other.oid_components) } } @@ -103,7 +129,12 @@ impl SignatureAlgorithm { &PKCS_RSA_SHA256, &PKCS_RSA_SHA384, &PKCS_RSA_SHA512, - //&PKCS_RSA_PSS_SHA256, + #[cfg(feature = "aws_lc_rs")] + &PKCS_RSA_PSS_SHA256, + #[cfg(feature = "aws_lc_rs")] + &PKCS_RSA_PSS_SHA384, + #[cfg(feature = "aws_lc_rs")] + &PKCS_RSA_PSS_SHA512, &PKCS_ECDSA_P256_SHA256, &PKCS_ECDSA_P384_SHA384, #[cfg(feature = "aws_lc_rs")] @@ -163,24 +194,52 @@ pub(crate) mod algo { params: SignatureAlgorithmParams::Null, }; - // TODO: not really sure whether the certs we generate actually work. - // Both openssl and webpki reject them. It *might* be possible that openssl - // accepts the certificate if the key is a proper RSA-PSS key, but ring doesn't - // support those: https://github.com/briansmith/ring/issues/1353 - // + #[cfg(feature = "aws_lc_rs")] /// RSA signing with PKCS#1 2.1 RSASSA-PSS padding and SHA-256 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055) - pub(crate) static PKCS_RSA_PSS_SHA256: SignatureAlgorithm = SignatureAlgorithm { + pub static PKCS_RSA_PSS_SHA256: SignatureAlgorithm = SignatureAlgorithm { // We could also use RSA_ENCRYPTION here, but it's recommended // to use ID-RSASSA-PSS if possible. oids_sign_alg: &[RSASSA_PSS], #[cfg(feature = "crypto")] sign_alg: SignAlgo::Rsa(&signature::RSA_PSS_SHA256), + // rSASSA-PSS-SHA256-Identifier oid_components: RSASSA_PSS, //&[1, 2, 840, 113549, 1, 1, 13], // rSASSA-PSS-SHA256-Params in RFC 4055 params: SignatureAlgorithmParams::RsaPss { // id-sha256 in https://datatracker.ietf.org/doc/html/rfc4055#section-2.1 hash_algorithm: &[2, 16, 840, 1, 101, 3, 4, 2, 1], - salt_length: 20, + // Salt length = hash octets (RFC 4055, pg. 9) + salt_length: 32, + }, + }; + + #[cfg(feature = "aws_lc_rs")] + /// RSA signing with PKCS#1 2.1 RSASSA-PSS padding and SHA-384 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055) + pub static PKCS_RSA_PSS_SHA384: SignatureAlgorithm = SignatureAlgorithm { + oids_sign_alg: &[RSASSA_PSS], + #[cfg(feature = "crypto")] + sign_alg: SignAlgo::Rsa(&signature::RSA_PSS_SHA384), + oid_components: RSASSA_PSS, //&[1, 2, 840, 113549, 1, 1, 13], + params: SignatureAlgorithmParams::RsaPss { + // id-sha256 in https://datatracker.ietf.org/doc/html/rfc4055#section-2.1 + hash_algorithm: &[2, 16, 840, 1, 101, 3, 4, 2, 2], + // Salt length = hash octets (RFC 4055, pg. 9) + salt_length: 48, + }, + }; + + #[cfg(feature = "aws_lc_rs")] + /// RSA signing with PKCS#1 2.1 RSASSA-PSS padding and SHA-512 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055) + pub static PKCS_RSA_PSS_SHA512: SignatureAlgorithm = SignatureAlgorithm { + oids_sign_alg: &[RSASSA_PSS], + #[cfg(feature = "crypto")] + sign_alg: SignAlgo::Rsa(&signature::RSA_PSS_SHA512), + oid_components: RSASSA_PSS, //&[1, 2, 840, 113549, 1, 1, 13], + params: SignatureAlgorithmParams::RsaPss { + // id-sha256 in https://datatracker.ietf.org/doc/html/rfc4055#section-2.1 + hash_algorithm: &[2, 16, 840, 1, 101, 3, 4, 2, 3], + // Salt length = hash octets (RFC 4055, pg. 9) + salt_length: 64, }, }; diff --git a/verify-tests/tests/openssl.rs b/verify-tests/tests/openssl.rs index a99cad49..1f030d52 100644 --- a/verify-tests/tests/openssl.rs +++ b/verify-tests/tests/openssl.rs @@ -187,6 +187,42 @@ fn test_request() { verify_csr(¶ms, &key_pair); } +#[cfg(feature = "aws_lc_rs")] +#[test] +fn test_openssl_rsa_pss_sha256() { + let (params, _) = util::default_params(); + let key_pair = KeyPair::generate_for(&rcgen::PKCS_RSA_PSS_SHA256).unwrap(); + let cert = params.self_signed(&key_pair).unwrap(); + + // Now verify the certificate. + verify_cert(&cert, &key_pair); + verify_csr(¶ms, &key_pair); +} + +#[cfg(feature = "aws_lc_rs")] +#[test] +fn test_openssl_rsa_pss_sha384() { + let (params, _) = util::default_params(); + let key_pair = KeyPair::generate_for(&rcgen::PKCS_RSA_PSS_SHA384).unwrap(); + let cert = params.self_signed(&key_pair).unwrap(); + + // Now verify the certificate. + verify_cert(&cert, &key_pair); + verify_csr(¶ms, &key_pair); +} + +#[cfg(feature = "aws_lc_rs")] +#[test] +fn test_openssl_rsa_pss_sha512() { + let (params, _) = util::default_params(); + let key_pair = KeyPair::generate_for(&rcgen::PKCS_RSA_PSS_SHA512).unwrap(); + let cert = params.self_signed(&key_pair).unwrap(); + + // Now verify the certificate. + verify_cert(&cert, &key_pair); + verify_csr(¶ms, &key_pair); +} + #[test] fn test_openssl_256() { let (params, _) = util::default_params();