Skip to content

Commit

Permalink
Don't enable *ring*'s alloc feature by default; Require alloc for…
Browse files Browse the repository at this point in the history
… 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.
  • Loading branch information
briansmith committed Jan 7, 2021
1 parent 2deeb79 commit 28951a0
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 20 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
83 changes: 68 additions & 15 deletions src/signed_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,27 +221,39 @@ 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,
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
};

/// 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,
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
};

/// 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,
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
};

/// 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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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")),
};
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down
9 changes: 7 additions & 2 deletions src/webpki.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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/")]
Expand Down Expand Up @@ -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,
};
Expand Down
7 changes: 6 additions & 1 deletion tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 28951a0

Please sign in to comment.