Skip to content

Commit aacd268

Browse files
committed
kex/sign
1 parent 992778d commit aacd268

File tree

7 files changed

+126
-31
lines changed

7 files changed

+126
-31
lines changed

Cargo.toml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@ crypto-common = { version = "0.1.6", default-features = false }
2525
der = { version = "0.7.9", default-features = false }
2626
digest = { version = "0.10.7", default-features = false }
2727
ecdsa = { version = "0.16.8", default-features = false, features = ["alloc"] }
28-
ed25519-dalek = { version = "2", default-features = false, features = ["pkcs8"] }
28+
ed25519-dalek = { version = "2", default-features = false, features = ["pkcs8"], optional = true }
2929
hmac = { version = "0.12.1", default-features = false }
30-
p256 = { version = "0.13.2", default-features = false, features = ["pem", "ecdsa", "ecdh"] }
31-
p384 = { version = "0.13.0", default-features = false, features = ["pem", "ecdsa", "ecdh"] }
30+
p256 = { version = "0.13.2", default-features = false, features = ["pem", "ecdsa", "ecdh"], optional = true }
31+
p384 = { version = "0.13.0", default-features = false, features = ["pem", "ecdsa", "ecdh"], optional = true }
3232
paste = { version = "1.0.15", default-features = false }
3333
pkcs8 = { version = "0.10.2", default-features = false, features = ["pem", "pkcs5"] }
3434
pki-types = { package = "rustls-pki-types", version = "1.0.1", default-features = false }
3535
rand_core = { version = "0.6.4", default-features = false, features = ["getrandom"] }
36-
rsa = { version = "0.9.2", default-features = false, features = ["sha2"] }
36+
rsa = { version = "0.9.2", default-features = false, features = ["sha2"], optional = true }
3737
rustls = { version = "0.23.12", default-features = false }
3838
sec1 = { version = "0.7.3", default-features = false, features = ["pkcs8", "pem"] }
3939
sha2 = { version = "0.10.7", default-features = false }
4040
signature = { version = "2.1.0", default-features = false }
4141
webpki = { package = "rustls-webpki", version = "0.102.0", default-features = false }
42-
x25519-dalek = { version = "2", default-features = false }
42+
x25519-dalek = { version = "2", default-features = false, optional = true }
4343

4444
[dev-dependencies]
4545
getrandom = { version = "0.2", features = ["custom"] } # workaround to build on no_std targets
@@ -53,7 +53,9 @@ tls12 = ["rustls/tls12"]
5353
# zeroize is another typical that can be turned off
5454

5555
# TODO: go through all of these that what gets exposed re: std error type
56-
std = ["alloc", "webpki/std", "pki-types/std", "rustls/std", "ed25519-dalek/std"]
56+
std = ["alloc", "webpki/std", "pki-types/std", "rustls/std"]
5757
# TODO: go through all of these to ensure to_vec etc. impls are exposed
58-
alloc = ["webpki/alloc", "pki-types/alloc", "aead/alloc", "ed25519-dalek/alloc"]
58+
alloc = ["webpki/alloc", "pki-types/alloc", "aead/alloc"]
5959
zeroize = ["ed25519-dalek/zeroize", "x25519-dalek/zeroize"]
60+
x25519 = ["dep:x25519-dalek"]
61+
ed25519 = ["dep:ed25519-dalek", "ed25519-dalek/alloc", "ed25519-dalek/std", "alloc"]

src/kx.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
#[cfg(feature = "alloc")]
2-
use alloc::boxed::Box;
3-
4-
use crypto::{SharedSecret, SupportedKxGroup};
5-
use paste::paste;
6-
use rustls::crypto;
7-
1+
#[cfg(feature = "x25519")]
82
#[derive(Debug)]
93
pub struct X25519;
104

5+
#[cfg(feature = "x25519")]
116
impl crypto::SupportedKxGroup for X25519 {
127
fn name(&self) -> rustls::NamedGroup {
138
rustls::NamedGroup::X25519
@@ -20,13 +15,15 @@ impl crypto::SupportedKxGroup for X25519 {
2015
}
2116
}
2217

18+
#[cfg(feature = "x25519")]
2319
pub struct X25519KeyExchange {
2420
priv_key: x25519_dalek::EphemeralSecret,
2521
pub_key: x25519_dalek::PublicKey,
2622
}
2723

24+
#[cfg(feature = "x25519")]
2825
impl crypto::ActiveKeyExchange for X25519KeyExchange {
29-
fn complete(self: Box<X25519KeyExchange>, peer: &[u8]) -> Result<SharedSecret, rustls::Error> {
26+
fn complete(self: Box<X25519KeyExchange>, peer: &[u8]) -> Result<crypto::SharedSecret, rustls::Error> {
3027
let peer_array: [u8; 32] = peer
3128
.try_into()
3229
.map_err(|_| rustls::Error::from(rustls::PeerMisbehaved::InvalidKeyShare))?;
@@ -48,7 +45,7 @@ impl crypto::ActiveKeyExchange for X25519KeyExchange {
4845

4946
macro_rules! impl_kx {
5047
($name:ident, $kx_name:ty, $secret:ty, $public_key:ty) => {
51-
paste! {
48+
paste::paste! {
5249

5350
#[derive(Debug)]
5451
#[allow(non_camel_case_types)]
@@ -79,7 +76,7 @@ macro_rules! impl_kx {
7976
fn complete(
8077
self: Box<[<$name KeyExchange>]>,
8178
peer: &[u8],
82-
) -> Result<SharedSecret, rustls::Error> {
79+
) -> Result<crypto::SharedSecret, rustls::Error> {
8380
let their_pub = $public_key::from_sec1_bytes(peer)
8481
.map_err(|_| rustls::Error::from(rustls::PeerMisbehaved::InvalidKeyShare))?;
8582
Ok(self
@@ -102,7 +99,8 @@ macro_rules! impl_kx {
10299
};
103100
}
104101

102+
#[cfg(feature = "p256")]
105103
impl_kx! {SecP256R1, rustls::NamedGroup::secp256r1, p256::ecdh::EphemeralSecret, p256::PublicKey}
104+
#[cfg(feature = "p384")]
106105
impl_kx! {SecP384R1, rustls::NamedGroup::secp384r1, p384::ecdh::EphemeralSecret, p384::PublicKey}
107106

108-
pub const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[&X25519, &SecP256R1, &SecP384R1];

src/lib.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use alloc::sync::Arc;
4444
use rustls::crypto::{
4545
CipherSuiteCommon, CryptoProvider, GetRandomFailed, KeyProvider, SecureRandom,
4646
};
47-
use rustls::{CipherSuite, SupportedCipherSuite, Tls13CipherSuite};
47+
use rustls::{crypto, CipherSuite, SupportedCipherSuite, Tls13CipherSuite};
4848

4949
#[cfg(feature = "tls12")]
5050
use rustls::SignatureScheme;
@@ -55,7 +55,7 @@ pub struct Provider;
5555
pub fn provider() -> CryptoProvider {
5656
CryptoProvider {
5757
cipher_suites: ALL_CIPHER_SUITES.to_vec(),
58-
kx_groups: kx::ALL_KX_GROUPS.to_vec(),
58+
kx_groups: ALL_KX_GROUPS.to_vec(),
5959
signature_verification_algorithms: verify::ALGORITHMS,
6060
secure_random: &Provider,
6161
key_provider: &Provider,
@@ -261,9 +261,31 @@ static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = misc::const_concat_slices!(
261261
TLS13_SUITES,
262262
);
263263

264+
#[cfg(feature = "p256")]
265+
pub use verify::ecdsa::{ECDSA_P256_SHA256, ECDSA_P256_SHA384};
266+
#[cfg(feature = "p384")]
267+
pub use verify::ecdsa::{ECDSA_P384_SHA256, ECDSA_P384_SHA384};
268+
269+
#[cfg(feature = "ed25519")]
270+
pub use verify::eddsa::ED25519;
271+
272+
#[cfg(feature = "rsa")]
273+
pub use verify::rsa::{RSA_PKCS1_SHA256, RSA_PKCS1_SHA384, RSA_PKCS1_SHA512, RSA_PSS_SHA256, RSA_PSS_SHA384, RSA_PSS_SHA512};
274+
275+
const ALL_KX_GROUPS: &[&dyn crypto::SupportedKxGroup] = &[
276+
#[cfg(feature = "x25519")]
277+
&X25519,
278+
#[cfg(feature = "p256")]
279+
&SecP256R1,
280+
#[cfg(feature = "p384")]
281+
&SecP384R1
282+
];
283+
264284
mod aead;
265285
mod hash;
266286
mod hmac;
287+
288+
#[cfg(any(feature = "x25519", feature = "p256", feature = "p384"))]
267289
mod kx;
268290
mod misc;
269291
pub mod quic;

src/sign.rs

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
use alloc::{sync::Arc, vec::Vec};
33
use core::marker::PhantomData;
44

5-
use self::ecdsa::{EcdsaSigningKeyP256, EcdsaSigningKeyP384};
5+
#[cfg(feature = "p256")]
6+
use self::ecdsa::EcdsaSigningKeyP256;
7+
#[cfg(feature = "p384")]
8+
use self::ecdsa::EcdsaSigningKeyP384;
9+
#[cfg(feature = "ed25519")]
610
use self::eddsa::Ed25519SigningKey;
11+
#[cfg(feature = "rsa")]
712
use self::rsa::RsaSigningKey;
813

914
use pki_types::PrivateKeyDer;
@@ -72,24 +77,47 @@ where
7277
/// # Errors
7378
///
7479
/// Returns an error if the key couldn't be decoded.
80+
#[allow(unused_variables, reason = "the argument is unused if all features are disabled")]
7581
pub fn any_supported_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, rustls::Error> {
76-
RsaSigningKey::try_from(der)
77-
.map(|x| Arc::new(x) as _)
78-
.or_else(|_| any_ecdsa_type(der))
79-
.or_else(|_| any_eddsa_type(der))
82+
#[cfg(feature = "rsa")]
83+
if let Ok(key) = RsaSigningKey::try_from(der) {
84+
return Ok(Arc::new(key));
85+
}
86+
87+
#[cfg(any(feature = "p256", feature = "p384"))]
88+
if let Ok(key) = any_ecdsa_type(der) {
89+
return Ok(key);
90+
}
91+
92+
#[cfg(feature = "ed25519")]
93+
if let Ok(key) = any_eddsa_type(der) {
94+
return Ok(key);
95+
}
96+
97+
Err(rustls::Error::General("unsupported private key format".into()))
8098
}
8199

100+
#[cfg(any(feature = "p256", feature = "p384"))]
82101
/// Extract any supported ECDSA key from the given DER input.
83102
///
84103
/// # Errors
85104
///
86105
/// Returns an error if the key couldn't be decoded.
87106
pub fn any_ecdsa_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, rustls::Error> {
88-
let p256 = |_| EcdsaSigningKeyP256::try_from(der).map(|x| Arc::new(x) as _);
89-
let p384 = |_| EcdsaSigningKeyP384::try_from(der).map(|x| Arc::new(x) as _);
90-
p256(()).or_else(p384)
107+
#[cfg(feature = "p256")]
108+
if let Ok(key) = EcdsaSigningKeyP256::try_from(der) {
109+
return Ok(Arc::new(key));
110+
}
111+
112+
#[cfg(feature = "p384")]
113+
if let Ok(key) = EcdsaSigningKeyP384::try_from(der) {
114+
return Ok(Arc::new(key));
115+
}
116+
117+
Err(rustls::Error::General("unsupported private key format".into()))
91118
}
92119

120+
#[cfg(feature = "ed25519")]
93121
/// Extract any supported EDDSA key from the given DER input.
94122
///
95123
/// # Errors
@@ -100,6 +128,9 @@ pub fn any_eddsa_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, ru
100128
Ed25519SigningKey::try_from(der).map(|x| Arc::new(x) as _)
101129
}
102130

131+
#[cfg(any(feature = "p256", feature = "p384"))]
103132
pub mod ecdsa;
133+
#[cfg(feature = "ed25519")]
104134
pub mod eddsa;
135+
#[cfg(feature = "rsa")]
105136
pub mod rsa;

src/sign/ecdsa.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,7 @@ macro_rules! impl_ecdsa {
6262
};
6363
}
6464

65+
#[cfg(feature = "p256")]
6566
impl_ecdsa! {P256, SignatureScheme::ECDSA_NISTP256_SHA256, p256::ecdsa::SigningKey, p256::ecdsa::DerSignature}
67+
#[cfg(feature = "p384")]
6668
impl_ecdsa! {P384, SignatureScheme::ECDSA_NISTP384_SHA384, p384::ecdsa::SigningKey, p384::ecdsa::DerSignature}

src/verify.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,82 @@
11
use rustls::crypto::WebPkiSupportedAlgorithms;
22
use rustls::SignatureScheme;
33

4-
use self::ecdsa::{ECDSA_P256_SHA256, ECDSA_P256_SHA384, ECDSA_P384_SHA256, ECDSA_P384_SHA384};
4+
#[cfg(feature = "p256")]
5+
use self::ecdsa::{ECDSA_P256_SHA256, ECDSA_P256_SHA384};
6+
#[cfg(feature = "p384")]
7+
use self::ecdsa::{ECDSA_P384_SHA256, ECDSA_P384_SHA384};
8+
#[cfg(feature = "ed25519")]
59
use self::eddsa::ED25519;
10+
#[cfg(feature = "rsa")]
611
use self::rsa::{
712
RSA_PKCS1_SHA256, RSA_PKCS1_SHA384, RSA_PKCS1_SHA512, RSA_PSS_SHA256, RSA_PSS_SHA384,
813
RSA_PSS_SHA512,
914
};
1015

1116
pub static ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
1217
all: &[
18+
#[cfg(feature = "p256")]
1319
ECDSA_P256_SHA256,
20+
#[cfg(feature = "p256")]
1421
ECDSA_P256_SHA384,
22+
#[cfg(feature = "p384")]
1523
ECDSA_P384_SHA256,
24+
#[cfg(feature = "p384")]
1625
ECDSA_P384_SHA384,
26+
#[cfg(feature = "ed25519")]
1727
ED25519,
28+
#[cfg(feature = "rsa")]
1829
RSA_PKCS1_SHA256,
30+
#[cfg(feature = "rsa")]
1931
RSA_PKCS1_SHA384,
32+
#[cfg(feature = "rsa")]
2033
RSA_PKCS1_SHA512,
34+
#[cfg(feature = "rsa")]
2135
RSA_PSS_SHA256,
36+
#[cfg(feature = "rsa")]
2237
RSA_PSS_SHA384,
38+
#[cfg(feature = "rsa")]
2339
RSA_PSS_SHA512,
2440
],
2541
mapping: &[
2642
(
2743
SignatureScheme::ECDSA_NISTP384_SHA384,
28-
&[ECDSA_P384_SHA384, ECDSA_P256_SHA384],
44+
&[
45+
#[cfg(feature = "p384")]
46+
ECDSA_P384_SHA384,
47+
#[cfg(feature = "p256")]
48+
ECDSA_P256_SHA384
49+
],
2950
),
3051
(
3152
SignatureScheme::ECDSA_NISTP256_SHA256,
32-
&[ECDSA_P256_SHA256, ECDSA_P384_SHA256],
53+
&[
54+
#[cfg(feature = "p256")]
55+
ECDSA_P256_SHA256,
56+
#[cfg(feature = "p384")]
57+
ECDSA_P384_SHA256
58+
],
3359
),
60+
#[cfg(feature = "ed25519")]
3461
(SignatureScheme::ED25519, &[ED25519]),
62+
#[cfg(feature = "rsa")]
3563
(SignatureScheme::RSA_PKCS1_SHA256, &[RSA_PKCS1_SHA256]),
64+
#[cfg(feature = "rsa")]
3665
(SignatureScheme::RSA_PKCS1_SHA384, &[RSA_PKCS1_SHA384]),
66+
#[cfg(feature = "rsa")]
3767
(SignatureScheme::RSA_PKCS1_SHA512, &[RSA_PKCS1_SHA512]),
68+
#[cfg(feature = "rsa")]
3869
(SignatureScheme::RSA_PSS_SHA256, &[RSA_PSS_SHA256]),
70+
#[cfg(feature = "rsa")]
3971
(SignatureScheme::RSA_PSS_SHA384, &[RSA_PSS_SHA384]),
72+
#[cfg(feature = "rsa")]
4073
(SignatureScheme::RSA_PSS_SHA512, &[RSA_PSS_SHA512]),
4174
],
4275
};
4376

77+
#[cfg(any(feature = "p256", feature = "p384"))]
4478
pub mod ecdsa;
79+
#[cfg(feature = "ed25519")]
4580
pub mod eddsa;
81+
#[cfg(feature = "rsa")]
4682
pub mod rsa;

src/verify/ecdsa.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ macro_rules! impl_generic_ecdsa_verifer {
4848
};
4949
}
5050

51+
#[cfg(feature = "p256")]
5152
impl_generic_ecdsa_verifer! {ECDSA_P256_SHA256, alg_id::ECDSA_P256, alg_id::ECDSA_SHA256, p256::ecdsa::VerifyingKey, p256::ecdsa::DerSignature, sha2::Sha256}
53+
#[cfg(feature = "p256")]
5254
impl_generic_ecdsa_verifer! {ECDSA_P256_SHA384, alg_id::ECDSA_P256, alg_id::ECDSA_SHA384, p256::ecdsa::VerifyingKey, p256::ecdsa::DerSignature, sha2::Sha384}
55+
#[cfg(feature = "p384")]
5356
impl_generic_ecdsa_verifer! {ECDSA_P384_SHA256, alg_id::ECDSA_P384, alg_id::ECDSA_SHA256, p384::ecdsa::VerifyingKey, p384::ecdsa::DerSignature, sha2::Sha256}
57+
#[cfg(feature = "p384")]
5458
impl_generic_ecdsa_verifer! {ECDSA_P384_SHA384, alg_id::ECDSA_P384, alg_id::ECDSA_SHA384, p384::ecdsa::VerifyingKey, p384::ecdsa::DerSignature, sha2::Sha384}

0 commit comments

Comments
 (0)