diff --git a/Cargo.toml b/Cargo.toml index e8e5de0..13303e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,30 +20,34 @@ resolver = "1" # Hack to enable the `custom` feature of `getrandom` [dependencies] aead = { version = "0.6", default-features = false } aes-gcm = { version = "0.11", default-features = false, features = ["aes", "alloc"] } -chacha20poly1305 = { version = "0.11", default-features = false } +chacha20poly1305 = { version = "0.11", default-features = false, optional = true } crypto-common = { version = "0.2", default-features = false } der = { version = "0.8", default-features = false } digest = { version = "0.11", default-features = false } -ecdsa = { version = "0.17", default-features = false, features = ["alloc"] } +ecdsa = { version = "0.17", default-features = false, features = ["alloc"], optional = true } ed25519-dalek = { version = "3", default-features = false, features = ["pkcs8"] } getrandom = { version = "0.4", default-features = false, features = ["sys_rng"] } hmac = { version = "0.13", default-features = false } -p256 = { version = "0.14", default-features = false, features = ["pem", "ecdsa", "ecdh"] } -p384 = { version = "0.14", default-features = false, features = ["pem", "ecdsa", "ecdh"] } +p256 = { version = "0.14", default-features = false, features = ["pem", "ecdsa", "ecdh"], optional = true } +p384 = { version = "0.14", default-features = false, features = ["pem", "ecdsa", "ecdh"], optional = true } paste = { version = "1", default-features = false } pkcs8 = { version = "0.11", default-features = false } pki-types = { package = "rustls-pki-types", version = "1", default-features = false } -rsa = { version = "0.10.0-rc.18", default-features = false, features = ["sha2", "encoding"] } +rsa = { version = "0.10.0-rc.18", default-features = false, features = ["sha2", "encoding"], optional = true } rustls = { version = "0.23", default-features = false } -sec1 = { version = "0.8", default-features = false } +sec1 = { version = "0.8", default-features = false, optional = true } sha2 = { version = "0.11", default-features = false } signature = { version = "3", default-features = false } x25519-dalek = { version = "3", default-features = false } [features] -default = ["std", "tls12", "zeroize"] +default = ["std", "tls12", "zeroize", "chacha20poly1305", "p256", "p384", "rsa"] logging = ["rustls/logging"] tls12 = ["rustls/tls12"] +chacha20poly1305 = ["dep:chacha20poly1305"] +p256 = ["dep:p256", "dep:ecdsa", "dep:sec1"] +p384 = ["dep:p384", "dep:ecdsa", "dep:sec1"] +rsa = ["dep:rsa"] # Only enable feature in upstream if there is an overall effect e.g. aead/alloc in-place # zeroize is another typical that can be turned off diff --git a/src/aead.rs b/src/aead.rs index 6ff57b7..1b42417 100644 --- a/src/aead.rs +++ b/src/aead.rs @@ -1,6 +1,7 @@ use aead::Buffer; use rustls::crypto::cipher::{BorrowedPayload, PrefixedPayload}; +#[cfg(feature = "chacha20poly1305")] pub mod chacha20; pub mod gcm; diff --git a/src/kx.rs b/src/kx.rs index 3f8a4dd..33c43b4 100644 --- a/src/kx.rs +++ b/src/kx.rs @@ -2,8 +2,10 @@ use alloc::boxed::Box; use crypto::{SharedSecret, SupportedKxGroup}; +#[cfg(any(feature = "p256", feature = "p384"))] use crypto_common::Generate; use getrandom::rand_core::UnwrapErr; +#[cfg(any(feature = "p256", feature = "p384"))] use paste::paste; use rustls::crypto; @@ -49,6 +51,7 @@ impl crypto::ActiveKeyExchange for X25519KeyExchange { } } +#[cfg(any(feature = "p256", feature = "p384"))] macro_rules! impl_kx { ($name:ident, $kx_name:ty, $secret:ty, $public_key:ty) => { paste! { @@ -106,7 +109,15 @@ macro_rules! impl_kx { }; } +#[cfg(feature = "p256")] impl_kx! {SecP256R1, rustls::NamedGroup::secp256r1, p256::ecdh::EphemeralSecret, p256::PublicKey} +#[cfg(feature = "p384")] impl_kx! {SecP384R1, rustls::NamedGroup::secp384r1, p384::ecdh::EphemeralSecret, p384::PublicKey} -pub const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[&X25519, &SecP256R1, &SecP384R1]; +pub const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[ + &X25519, + #[cfg(feature = "p256")] + &SecP256R1, + #[cfg(feature = "p384")] + &SecP384R1, +]; diff --git a/src/lib.rs b/src/lib.rs index 6332bca..dcd6757 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -125,7 +125,7 @@ pub const TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite = aead_alg: &aead::gcm::Tls12Aes256Gcm, }); -#[cfg(feature = "tls12")] +#[cfg(all(feature = "tls12", feature = "chacha20poly1305"))] pub const TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite = SupportedCipherSuite::Tls12(&rustls::Tls12CipherSuite { common: CipherSuiteCommon { @@ -143,6 +143,7 @@ pub const TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite = const TLS_ECDHE_ECDSA_SUITES: &[SupportedCipherSuite] = &[ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + #[cfg(feature = "chacha20poly1305")] TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, ]; @@ -174,7 +175,7 @@ pub const TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite = aead_alg: &aead::gcm::Tls12Aes256Gcm, }); -#[cfg(feature = "tls12")] +#[cfg(all(feature = "tls12", feature = "chacha20poly1305"))] pub const TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite = SupportedCipherSuite::Tls12(&rustls::Tls12CipherSuite { common: CipherSuiteCommon { @@ -192,6 +193,7 @@ pub const TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite = const TLS_ECDHE_RSA_SUITES: &[SupportedCipherSuite] = &[ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + #[cfg(feature = "chacha20poly1305")] TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, ]; @@ -232,6 +234,7 @@ pub const TLS13_AES_256_GCM_SHA384: SupportedCipherSuite = const TLS13_AES_SUITES: &[SupportedCipherSuite] = &[TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384]; +#[cfg(feature = "chacha20poly1305")] pub const TLS13_CHACHA20_POLY1305_SHA256: SupportedCipherSuite = SupportedCipherSuite::Tls13(&Tls13CipherSuite { common: CipherSuiteCommon { @@ -244,12 +247,16 @@ pub const TLS13_CHACHA20_POLY1305_SHA256: SupportedCipherSuite = quic: None, }); +#[cfg(feature = "chacha20poly1305")] const TLS13_SUITES: &[SupportedCipherSuite] = misc::const_concat_slices!( SupportedCipherSuite, TLS13_AES_SUITES, &[TLS13_CHACHA20_POLY1305_SHA256] ); +#[cfg(not(feature = "chacha20poly1305"))] +const TLS13_SUITES: &[SupportedCipherSuite] = TLS13_AES_SUITES; + static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = misc::const_concat_slices!( SupportedCipherSuite, if cfg!(feature = "tls12") { @@ -265,6 +272,7 @@ mod hash; mod hmac; mod kx; mod misc; +#[cfg(feature = "chacha20poly1305")] pub mod quic; pub mod sign; mod verify; diff --git a/src/sign.rs b/src/sign.rs index cf30cc5..1f680d9 100644 --- a/src/sign.rs +++ b/src/sign.rs @@ -2,16 +2,25 @@ use alloc::{sync::Arc, vec::Vec}; use core::marker::PhantomData; -use self::ecdsa::{EcdsaSigningKeyP256, EcdsaSigningKeyP384}; +#[cfg(feature = "p256")] +use self::ecdsa::EcdsaSigningKeyP256; +#[cfg(feature = "p384")] +use self::ecdsa::EcdsaSigningKeyP384; use self::eddsa::Ed25519SigningKey; +#[cfg(feature = "rsa")] use self::rsa::RsaSigningKey; +#[cfg(any(feature = "p256", feature = "p384", feature = "rsa"))] use getrandom::rand_core::UnwrapErr; use pki_types::PrivateKeyDer; use rustls::sign::{Signer, SigningKey}; use rustls::{Error, SignatureScheme}; -use signature::{RandomizedSigner, SignatureEncoding}; +use signature::SignatureEncoding; +#[cfg(any(feature = "p256", feature = "p384", feature = "rsa"))] +use signature::RandomizedSigner; + +#[cfg(any(feature = "p256", feature = "p384", feature = "rsa"))] #[derive(Debug)] pub struct GenericRandomizedSigner where @@ -23,6 +32,7 @@ where scheme: SignatureScheme, } +#[cfg(any(feature = "p256", feature = "p384", feature = "rsa"))] impl Signer for GenericRandomizedSigner where S: SignatureEncoding + Send + Sync + core::fmt::Debug, @@ -75,10 +85,15 @@ where /// /// Returns an error if the key couldn't be decoded. pub fn any_supported_type(der: &PrivateKeyDer<'_>) -> Result, rustls::Error> { - RsaSigningKey::try_from(der) - .map(|x| Arc::new(x) as _) - .or_else(|_| any_ecdsa_type(der)) - .or_else(|_| any_eddsa_type(der)) + #[cfg(feature = "rsa")] + if let Ok(key) = RsaSigningKey::try_from(der) { + return Ok(Arc::new(key) as _); + } + #[cfg(any(feature = "p256", feature = "p384"))] + if let Ok(key) = any_ecdsa_type(der) { + return Ok(key); + } + any_eddsa_type(der) } /// Extract any supported ECDSA key from the given DER input. @@ -86,10 +101,25 @@ pub fn any_supported_type(der: &PrivateKeyDer<'_>) -> Result /// # Errors /// /// Returns an error if the key couldn't be decoded. +#[cfg(any(feature = "p256", feature = "p384"))] pub fn any_ecdsa_type(der: &PrivateKeyDer<'_>) -> Result, rustls::Error> { + #[cfg(feature = "p256")] let p256 = |_| EcdsaSigningKeyP256::try_from(der).map(|x| Arc::new(x) as _); + #[cfg(feature = "p384")] let p384 = |_| EcdsaSigningKeyP384::try_from(der).map(|x| Arc::new(x) as _); - p256(()).or_else(p384) + + #[cfg(all(feature = "p256", feature = "p384"))] + { + p256(()).or_else(p384) + } + #[cfg(all(feature = "p256", not(feature = "p384")))] + { + p256(()) + } + #[cfg(all(not(feature = "p256"), feature = "p384"))] + { + p384(()) + } } /// Extract any supported EDDSA key from the given DER input. @@ -102,6 +132,8 @@ pub fn any_eddsa_type(der: &PrivateKeyDer<'_>) -> Result, ru Ed25519SigningKey::try_from(der).map(|x| Arc::new(x) as _) } +#[cfg(any(feature = "p256", feature = "p384"))] pub mod ecdsa; pub mod eddsa; +#[cfg(feature = "rsa")] pub mod rsa; diff --git a/src/sign/ecdsa.rs b/src/sign/ecdsa.rs index 347bc25..88c458a 100644 --- a/src/sign/ecdsa.rs +++ b/src/sign/ecdsa.rs @@ -67,5 +67,7 @@ macro_rules! impl_ecdsa { }; } +#[cfg(feature = "p256")] impl_ecdsa! {P256, SignatureScheme::ECDSA_NISTP256_SHA256, p256::ecdsa::SigningKey, p256::ecdsa::DerSignature} +#[cfg(feature = "p384")] impl_ecdsa! {P384, SignatureScheme::ECDSA_NISTP384_SHA384, p384::ecdsa::SigningKey, p384::ecdsa::DerSignature} diff --git a/src/verify.rs b/src/verify.rs index 2043b64..9cf9edd 100644 --- a/src/verify.rs +++ b/src/verify.rs @@ -1,46 +1,73 @@ use rustls::crypto::WebPkiSupportedAlgorithms; use rustls::SignatureScheme; -use self::ecdsa::{ECDSA_P256_SHA256, ECDSA_P256_SHA384, ECDSA_P384_SHA256, ECDSA_P384_SHA384}; +#[cfg(any(feature = "p256", feature = "p384"))] +use self::ecdsa::*; use self::eddsa::ED25519; -use self::rsa::{ - RSA_PKCS1_SHA256, RSA_PKCS1_SHA384, RSA_PKCS1_SHA512, RSA_PSS_SHA256, RSA_PSS_SHA384, - RSA_PSS_SHA512, -}; +#[cfg(feature = "rsa")] +use self::rsa::*; pub static ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms { all: &[ + #[cfg(feature = "p256")] ECDSA_P256_SHA256, + #[cfg(feature = "p256")] ECDSA_P256_SHA384, + #[cfg(feature = "p384")] ECDSA_P384_SHA256, + #[cfg(feature = "p384")] ECDSA_P384_SHA384, ED25519, + #[cfg(feature = "rsa")] RSA_PKCS1_SHA256, + #[cfg(feature = "rsa")] RSA_PKCS1_SHA384, + #[cfg(feature = "rsa")] RSA_PKCS1_SHA512, + #[cfg(feature = "rsa")] RSA_PSS_SHA256, + #[cfg(feature = "rsa")] RSA_PSS_SHA384, + #[cfg(feature = "rsa")] RSA_PSS_SHA512, ], mapping: &[ + #[cfg(feature = "p384")] ( SignatureScheme::ECDSA_NISTP384_SHA384, - &[ECDSA_P384_SHA384, ECDSA_P256_SHA384], + &[ + ECDSA_P384_SHA384, + #[cfg(feature = "p256")] + ECDSA_P256_SHA384, + ], ), + #[cfg(feature = "p256")] ( SignatureScheme::ECDSA_NISTP256_SHA256, - &[ECDSA_P256_SHA256, ECDSA_P384_SHA256], + &[ + ECDSA_P256_SHA256, + #[cfg(feature = "p384")] + ECDSA_P384_SHA256, + ], ), (SignatureScheme::ED25519, &[ED25519]), + #[cfg(feature = "rsa")] (SignatureScheme::RSA_PKCS1_SHA256, &[RSA_PKCS1_SHA256]), + #[cfg(feature = "rsa")] (SignatureScheme::RSA_PKCS1_SHA384, &[RSA_PKCS1_SHA384]), + #[cfg(feature = "rsa")] (SignatureScheme::RSA_PKCS1_SHA512, &[RSA_PKCS1_SHA512]), + #[cfg(feature = "rsa")] (SignatureScheme::RSA_PSS_SHA256, &[RSA_PSS_SHA256]), + #[cfg(feature = "rsa")] (SignatureScheme::RSA_PSS_SHA384, &[RSA_PSS_SHA384]), + #[cfg(feature = "rsa")] (SignatureScheme::RSA_PSS_SHA512, &[RSA_PSS_SHA512]), ], }; +#[cfg(any(feature = "p256", feature = "p384"))] pub mod ecdsa; pub mod eddsa; +#[cfg(feature = "rsa")] pub mod rsa; diff --git a/src/verify/ecdsa.rs b/src/verify/ecdsa.rs index 743a6c5..ae8c861 100644 --- a/src/verify/ecdsa.rs +++ b/src/verify/ecdsa.rs @@ -47,7 +47,11 @@ macro_rules! impl_generic_ecdsa_verifer { }; } +#[cfg(feature = "p256")] impl_generic_ecdsa_verifer! {ECDSA_P256_SHA256, alg_id::ECDSA_P256, alg_id::ECDSA_SHA256, p256::ecdsa::VerifyingKey, p256::ecdsa::DerSignature, sha2::Sha256} +#[cfg(feature = "p256")] impl_generic_ecdsa_verifer! {ECDSA_P256_SHA384, alg_id::ECDSA_P256, alg_id::ECDSA_SHA384, p256::ecdsa::VerifyingKey, p256::ecdsa::DerSignature, sha2::Sha384} +#[cfg(feature = "p384")] impl_generic_ecdsa_verifer! {ECDSA_P384_SHA256, alg_id::ECDSA_P384, alg_id::ECDSA_SHA256, p384::ecdsa::VerifyingKey, p384::ecdsa::DerSignature, sha2::Sha256} +#[cfg(feature = "p384")] impl_generic_ecdsa_verifer! {ECDSA_P384_SHA384, alg_id::ECDSA_P384, alg_id::ECDSA_SHA384, p384::ecdsa::VerifyingKey, p384::ecdsa::DerSignature, sha2::Sha384}