From 28951a0d466894166ba5bed9703794caf537241d Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Wed, 6 Jan 2021 14:49:07 -0800 Subject: [PATCH] Don't enable *ring*'s `alloc` feature by default; Require `alloc` for RSA. Only use *ring*'s `alloc` feature if webpki's `alloc` feature is enabled. This disables RSA by default. Adjust some tests that return different results depending on whether RSA is available. --- Cargo.toml | 4 +-- src/signed_data.rs | 83 ++++++++++++++++++++++++++++++++++++-------- src/webpki.rs | 9 +++-- tests/integration.rs | 7 +++- 4 files changed, 83 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 05957249..98bdd949 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,11 +64,11 @@ name = "webpki" path = "src/webpki.rs" [features] -alloc = [] +alloc = ["ring/alloc"] std = ["alloc"] [dependencies] -ring = { version = "0.16.19", default-features = false, features = ["alloc"] } +ring = { version = "0.16.19", default-features = false } untrusted = "0.7.1" [dev-dependencies] diff --git a/src/signed_data.rs b/src/signed_data.rs index 14fc76db..092d0574 100644 --- a/src/signed_data.rs +++ b/src/signed_data.rs @@ -221,6 +221,9 @@ pub static ECDSA_P384_SHA384: SignatureAlgorithm = SignatureAlgorithm { }; /// RSA PKCS#1 1.5 signatures using SHA-256 for keys of 2048-8192 bits. +/// +/// Requires the `alloc` feature. +#[cfg(feature = "alloc")] pub static RSA_PKCS1_2048_8192_SHA256: SignatureAlgorithm = SignatureAlgorithm { public_key_alg_id: RSA_ENCRYPTION, signature_alg_id: RSA_PKCS1_SHA256, @@ -228,6 +231,9 @@ pub static RSA_PKCS1_2048_8192_SHA256: SignatureAlgorithm = SignatureAlgorithm { }; /// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 2048-8192 bits. +/// +/// Requires the `alloc` feature. +#[cfg(feature = "alloc")] pub static RSA_PKCS1_2048_8192_SHA384: SignatureAlgorithm = SignatureAlgorithm { public_key_alg_id: RSA_ENCRYPTION, signature_alg_id: RSA_PKCS1_SHA384, @@ -235,6 +241,9 @@ pub static RSA_PKCS1_2048_8192_SHA384: SignatureAlgorithm = SignatureAlgorithm { }; /// RSA PKCS#1 1.5 signatures using SHA-512 for keys of 2048-8192 bits. +/// +/// Requires the `alloc` feature. +#[cfg(feature = "alloc")] pub static RSA_PKCS1_2048_8192_SHA512: SignatureAlgorithm = SignatureAlgorithm { public_key_alg_id: RSA_ENCRYPTION, signature_alg_id: RSA_PKCS1_SHA512, @@ -242,6 +251,9 @@ pub static RSA_PKCS1_2048_8192_SHA512: SignatureAlgorithm = SignatureAlgorithm { }; /// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 3072-8192 bits. +/// +/// Requires the `alloc` feature. +#[cfg(feature = "alloc")] pub static RSA_PKCS1_3072_8192_SHA384: SignatureAlgorithm = SignatureAlgorithm { public_key_alg_id: RSA_ENCRYPTION, signature_alg_id: RSA_PKCS1_SHA384, @@ -252,6 +264,9 @@ pub static RSA_PKCS1_3072_8192_SHA384: SignatureAlgorithm = SignatureAlgorithm { /// type rsaEncryption; see [RFC 4055 Section 1.2]. /// /// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2 +/// +/// Requires the `alloc` feature. +#[cfg(feature = "alloc")] pub static RSA_PSS_2048_8192_SHA256_LEGACY_KEY: SignatureAlgorithm = SignatureAlgorithm { public_key_alg_id: RSA_ENCRYPTION, signature_alg_id: RSA_PSS_SHA256, @@ -262,6 +277,9 @@ pub static RSA_PSS_2048_8192_SHA256_LEGACY_KEY: SignatureAlgorithm = SignatureAl /// type rsaEncryption; see [RFC 4055 Section 1.2]. /// /// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2 +/// +/// Requires the `alloc` feature. +#[cfg(feature = "alloc")] pub static RSA_PSS_2048_8192_SHA384_LEGACY_KEY: SignatureAlgorithm = SignatureAlgorithm { public_key_alg_id: RSA_ENCRYPTION, signature_alg_id: RSA_PSS_SHA384, @@ -272,6 +290,9 @@ pub static RSA_PSS_2048_8192_SHA384_LEGACY_KEY: SignatureAlgorithm = SignatureAl /// type rsaEncryption; see [RFC 4055 Section 1.2]. /// /// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2 +/// +/// Requires the `alloc` feature. +#[cfg(feature = "alloc")] pub static RSA_PSS_2048_8192_SHA512_LEGACY_KEY: SignatureAlgorithm = SignatureAlgorithm { public_key_alg_id: RSA_ENCRYPTION, signature_alg_id: RSA_PSS_SHA512, @@ -313,30 +334,37 @@ const ECDSA_SHA384: AlgorithmIdentifier = AlgorithmIdentifier { asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-ecdsa-sha384.der")), }; +#[cfg(feature = "alloc")] const RSA_ENCRYPTION: AlgorithmIdentifier = AlgorithmIdentifier { asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-encryption.der")), }; +#[cfg(feature = "alloc")] const RSA_PKCS1_SHA256: AlgorithmIdentifier = AlgorithmIdentifier { asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pkcs1-sha256.der")), }; +#[cfg(feature = "alloc")] const RSA_PKCS1_SHA384: AlgorithmIdentifier = AlgorithmIdentifier { asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pkcs1-sha384.der")), }; +#[cfg(feature = "alloc")] const RSA_PKCS1_SHA512: AlgorithmIdentifier = AlgorithmIdentifier { asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pkcs1-sha512.der")), }; +#[cfg(feature = "alloc")] const RSA_PSS_SHA256: AlgorithmIdentifier = AlgorithmIdentifier { asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pss-sha256.der")), }; +#[cfg(feature = "alloc")] const RSA_PSS_SHA384: AlgorithmIdentifier = AlgorithmIdentifier { asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pss-sha384.der")), }; +#[cfg(feature = "alloc")] const RSA_PSS_SHA512: AlgorithmIdentifier = AlgorithmIdentifier { asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pss-sha512.der")), }; @@ -449,6 +477,24 @@ mod tests { ); } + const UNSUPPORTED_SIGNATURE_ALGORITHM_FOR_RSA_KEY: Error = if cfg!(feature = "alloc") { + Error::UnsupportedSignatureAlgorithmForPublicKey + } else { + Error::UnsupportedSignatureAlgorithm + }; + + const INVALID_SIGNATURE_FOR_RSA_KEY: Error = if cfg!(feature = "alloc") { + Error::InvalidSignatureForPublicKey + } else { + Error::UnsupportedSignatureAlgorithm + }; + + const OK_IF_RSA_AVAILABLE: Result<(), Error> = if cfg!(feature = "alloc") { + Ok(()) + } else { + Err(Error::UnsupportedSignatureAlgorithm) + }; + // XXX: Some of the BadDER tests should have better error codes, maybe? // XXX: We should have a variant of this test with a SHA-256 digest that gives @@ -480,7 +526,7 @@ mod tests { test_verify_signed_data!( test_ecdsa_prime256v1_sha512_using_rsa_algorithm, "ecdsa-prime256v1-sha512-using-rsa-algorithm.pem", - Err(Error::UnsupportedSignatureAlgorithmForPublicKey) + Err(UNSUPPORTED_SIGNATURE_ALGORITHM_FOR_RSA_KEY) ); // XXX: We should have a variant of this test with a SHA-256 digest that gives // `Error::InvalidSignatureForPublicKey`. @@ -534,7 +580,7 @@ mod tests { test_verify_signed_data!( test_rsa_pkcs1_sha1_wrong_algorithm, "rsa-pkcs1-sha1-wrong-algorithm.pem", - Err(Error::InvalidSignatureForPublicKey) + Err(INVALID_SIGNATURE_FOR_RSA_KEY) ); test_verify_signed_data!( test_rsa_pkcs1_sha1, @@ -548,7 +594,7 @@ mod tests { test_verify_signed_data!( test_rsa_pkcs1_sha256, "rsa-pkcs1-sha256.pem", - Err(Error::InvalidSignatureForPublicKey) + Err(INVALID_SIGNATURE_FOR_RSA_KEY) ); test_parse_spki_bad_outer!( test_rsa_pkcs1_sha256_key_encoded_ber, @@ -558,7 +604,7 @@ mod tests { test_verify_signed_data!( test_rsa_pkcs1_sha256_spki_non_null_params, "rsa-pkcs1-sha256-spki-non-null-params.pem", - Err(Error::UnsupportedSignatureAlgorithmForPublicKey) + Err(UNSUPPORTED_SIGNATURE_ALGORITHM_FOR_RSA_KEY) ); test_verify_signed_data!( test_rsa_pkcs1_sha256_using_ecdsa_algorithm, @@ -568,7 +614,7 @@ mod tests { test_verify_signed_data!( test_rsa_pkcs1_sha256_using_id_ea_rsa, "rsa-pkcs1-sha256-using-id-ea-rsa.pem", - Err(Error::UnsupportedSignatureAlgorithmForPublicKey) + Err(UNSUPPORTED_SIGNATURE_ALGORITHM_FOR_RSA_KEY) ); // Chromium's PSS test are for parameter combinations we don't support. @@ -617,43 +663,43 @@ mod tests { test_verify_signed_data!( test_rsa_pss_sha256_salt32, "ours/rsa-pss-sha256-salt32.pem", - Ok(()) + OK_IF_RSA_AVAILABLE ); test_verify_signed_data!( test_rsa_pss_sha384_salt48, "ours/rsa-pss-sha384-salt48.pem", - Ok(()) + OK_IF_RSA_AVAILABLE ); test_verify_signed_data!( test_rsa_pss_sha512_salt64, "ours/rsa-pss-sha512-salt64.pem", - Ok(()) + OK_IF_RSA_AVAILABLE ); test_verify_signed_data!( test_rsa_pss_sha256_salt32_corrupted_data, "ours/rsa-pss-sha256-salt32-corrupted-data.pem", - Err(Error::InvalidSignatureForPublicKey) + Err(INVALID_SIGNATURE_FOR_RSA_KEY) ); test_verify_signed_data!( test_rsa_pss_sha384_salt48_corrupted_data, "ours/rsa-pss-sha384-salt48-corrupted-data.pem", - Err(Error::InvalidSignatureForPublicKey) + Err(INVALID_SIGNATURE_FOR_RSA_KEY) ); test_verify_signed_data!( test_rsa_pss_sha512_salt64_corrupted_data, "ours/rsa-pss-sha512-salt64-corrupted-data.pem", - Err(Error::InvalidSignatureForPublicKey) + Err(INVALID_SIGNATURE_FOR_RSA_KEY) ); test_verify_signed_data!( test_rsa_using_ec_key, "rsa-using-ec-key.pem", - Err(Error::UnsupportedSignatureAlgorithmForPublicKey) + Err(UNSUPPORTED_SIGNATURE_ALGORITHM_FOR_RSA_KEY) ); test_verify_signed_data!( test_rsa2048_pkcs1_sha512, "rsa2048-pkcs1-sha512.pem", - Ok(()) + OK_IF_RSA_AVAILABLE ); struct TestSignedData { @@ -710,16 +756,23 @@ mod tests { static SUPPORTED_ALGORITHMS_IN_TESTS: &[&signed_data::SignatureAlgorithm] = &[ // Reasonable algorithms. - &signed_data::RSA_PKCS1_2048_8192_SHA256, &signed_data::ECDSA_P256_SHA256, &signed_data::ECDSA_P384_SHA384, + &signed_data::ED25519, + #[cfg(feature = "alloc")] + &signed_data::RSA_PKCS1_2048_8192_SHA256, + #[cfg(feature = "alloc")] &signed_data::RSA_PKCS1_2048_8192_SHA384, + #[cfg(feature = "alloc")] &signed_data::RSA_PKCS1_2048_8192_SHA512, + #[cfg(feature = "alloc")] &signed_data::RSA_PKCS1_3072_8192_SHA384, + #[cfg(feature = "alloc")] &signed_data::RSA_PSS_2048_8192_SHA256_LEGACY_KEY, + #[cfg(feature = "alloc")] &signed_data::RSA_PSS_2048_8192_SHA384_LEGACY_KEY, + #[cfg(feature = "alloc")] &signed_data::RSA_PSS_2048_8192_SHA512_LEGACY_KEY, - &signed_data::ED25519, // Algorithms deprecated because they are annoying (P-521) or because // they are nonsensical combinations. &signed_data::ECDSA_P256_SHA384, // Truncates digest. diff --git a/src/webpki.rs b/src/webpki.rs index a5c171e0..a5613152 100644 --- a/src/webpki.rs +++ b/src/webpki.rs @@ -21,7 +21,7 @@ //! //! | Feature | Description | //! | ------- | ----------- | -//! | `alloc` | Enable features that require use of the heap. | +//! | `alloc` | Enable features that require use of the heap. Currently all RSA signature algorithms require this feature. | //! | `std` | Enable features that require libstd. Implies `alloc`. | #![doc(html_root_url = "https://briansmith.org/rustdoc/")] @@ -57,7 +57,12 @@ pub use name::DnsName; pub use signed_data::{ SignatureAlgorithm, ECDSA_P256_SHA256, ECDSA_P256_SHA384, ECDSA_P384_SHA256, ECDSA_P384_SHA384, - ED25519, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512, + ED25519, +}; + +#[cfg(feature = "alloc")] +pub use signed_data::{ + RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512, RSA_PKCS1_3072_8192_SHA384, RSA_PSS_2048_8192_SHA256_LEGACY_KEY, RSA_PSS_2048_8192_SHA384_LEGACY_KEY, RSA_PSS_2048_8192_SHA512_LEGACY_KEY, }; diff --git a/tests/integration.rs b/tests/integration.rs index 8c738f85..8e7abddc 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -19,15 +19,20 @@ static ALL_SIGALGS: &[&webpki::SignatureAlgorithm] = &[ &webpki::ECDSA_P256_SHA384, &webpki::ECDSA_P384_SHA256, &webpki::ECDSA_P384_SHA384, + &webpki::ED25519, + #[cfg(feature = "alloc")] &webpki::RSA_PKCS1_2048_8192_SHA256, + #[cfg(feature = "alloc")] &webpki::RSA_PKCS1_2048_8192_SHA384, + #[cfg(feature = "alloc")] &webpki::RSA_PKCS1_2048_8192_SHA512, + #[cfg(feature = "alloc")] &webpki::RSA_PKCS1_3072_8192_SHA384, - &webpki::ED25519, ]; /* Checks we can verify netflix's cert chain. This is notable * because they're rooted at a Verisign v1 root. */ +#[cfg(feature = "alloc")] #[test] pub fn netflix() { let ee = include_bytes!("netflix/ee.der");