Skip to content

Commit 72311f3

Browse files
Refactor dependencies and update cryptographic implementations
- Updated dependencies in Cargo.toml, replacing `rsa` with `rsa_098` and `signature` with `signature_220`. - Enhanced error handling in HMAC and key exchange implementations to provide clearer error messages. - Removed deprecated SecP521R1 key exchange implementation and replaced it with a feature-gated version. - Adjusted X448 key exchange to improve random byte generation and error handling. - Refactored signing logic to improve clarity and maintainability, including changes to the GenericSigner struct. - Updated ECDSA signing key extraction to streamline the process and improve error handling. - Modified AEAD implementations for TLS 1.2 and TLS 1.3 to ensure proper nonce and tag handling. - Updated test files to reflect changes in dependencies and ensure compatibility with new signing and key exchange implementations.
1 parent fe2150c commit 72311f3

File tree

11 files changed

+550
-277
lines changed

11 files changed

+550
-277
lines changed

Cargo.lock

Lines changed: 365 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,15 @@ paste = "1.0.15"
6262
[dev-dependencies]
6363
bytes = { version = "1.10.1", default-features = false }
6464
itertools = { version = "0.14.0", default-features = false }
65-
rsa = { version = "0.10.0-rc.6", default-features = false, features = ["sha2"] }
65+
rsa_098 = { package = "rsa", version = "0.9.8", features = ["sha2"] }
66+
signature_220 = { package = "signature", version = "2.2.0" }
6667
rustls = { version = "0.23.31", default-features = false, features = ["std"] }
6768
spki = { version = "0.8.0-rc.4", default-features = false, features = ["alloc"] }
6869
x509-cert = { version = "0.2.5", default-features = false, features = [
69-
"builder", "hazmat"
70+
"builder"
7071
] }
72+
rand_core_064 = { package = "rand_core", version = "0.6.4" }
73+
p256_0132 = { package = "p256", version = "0.13.2" }
7174

7275
[features]
7376
default = ["std", "tls12", "zeroize", "full", "fast"]
@@ -223,7 +226,7 @@ aes-ccm = ["aes", "ccm"]
223226
aes-gcm = ["dep:aes-gcm", "aes", "gcm"]
224227
ccm = ["dep:ccm"]
225228
chacha20poly1305 = ["dep:chacha20poly1305"]
226-
elliptic-curve = ["dep:elliptic-curve"]
229+
elliptic-curve = ["dep:elliptic-curve", "elliptic-curve/ecdh", "elliptic-curve/sec1"]
227230
gcm = []
228231
rand = ["dep:rand_core", "signature?/rand_core", "x25519-dalek?/os_rng"]
229232
signature = ["dep:signature"]

src/hmac.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ macro_rules! impl_hmac {
2121
impl Hmac for #hmac_type_name {
2222
fn with_key(&self, key: &[u8]) -> Box<dyn Key> {
2323
Box::new(#hmac_key_type_name(
24-
::hmac::Hmac::<$ty>::new_from_slice(key).unwrap(),
24+
::hmac::Hmac::<$ty>::new_from_slice(key).expect("Invalid key length for HMAC"),
2525
))
2626
}
2727

src/kx/nist.rs

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ macro_rules! impl_kx {
2626
}
2727

2828
fn start(&self) -> Result<Box<dyn crypto::ActiveKeyExchange>, rustls::Error> {
29-
let priv_key = $secret::try_from_rng(&mut rand_core::OsRng).unwrap();
29+
let priv_key = $secret::try_from_rng(&mut rand_core::OsRng).map_err(|_| rustls::Error::General("Failed to generate private key".into()))?;
3030
let pub_key: $public_key = (&priv_key).into();
3131
Ok(Box::new(#key_exchange {
3232
priv_key,
@@ -74,46 +74,5 @@ impl_kx! {SecP256R1, rustls::NamedGroup::secp256r1, ::p256::ecdh::EphemeralSecre
7474
#[cfg(feature = "kx-p384")]
7575
impl_kx! {SecP384R1, rustls::NamedGroup::secp384r1, ::p384::ecdh::EphemeralSecret, ::p384::PublicKey}
7676

77-
#[derive(Debug)]
78-
#[allow(non_camel_case_types)]
79-
pub struct SecP521R1;
80-
81-
impl crypto::SupportedKxGroup for SecP521R1 {
82-
fn name(&self) -> rustls::NamedGroup {
83-
rustls::NamedGroup::secp521r1
84-
}
85-
fn start(&self) -> Result<Box<dyn crypto::ActiveKeyExchange>, rustls::Error> {
86-
let priv_key = ::p521::ecdh::EphemeralSecret::try_from_rng(&mut rand_core::OsRng).unwrap();
87-
let pub_key: ::p521::PublicKey = (&priv_key).into();
88-
Ok(Box::new(SecP521R1KeyExchange {
89-
priv_key,
90-
pub_key: pub_key.to_sec1_bytes(),
91-
}))
92-
}
93-
}
94-
#[allow(non_camel_case_types)]
95-
pub struct SecP521R1KeyExchange {
96-
priv_key: ::p521::ecdh::EphemeralSecret,
97-
pub_key: Box<[u8]>,
98-
}
99-
impl crypto::ActiveKeyExchange for SecP521R1KeyExchange {
100-
fn complete(
101-
self: Box<SecP521R1KeyExchange>,
102-
peer: &[u8],
103-
) -> Result<SharedSecret, rustls::Error> {
104-
let their_pub = ::p521::PublicKey::from_sec1_bytes(peer)
105-
.map_err(|_| rustls::Error::from(rustls::PeerMisbehaved::InvalidKeyShare))?;
106-
Ok(self
107-
.priv_key
108-
.diffie_hellman(&their_pub)
109-
.raw_secret_bytes()
110-
.as_slice()
111-
.into())
112-
}
113-
fn pub_key(&self) -> &[u8] {
114-
&self.pub_key
115-
}
116-
fn group(&self) -> rustls::NamedGroup {
117-
SecP521R1.name()
118-
}
119-
}
77+
#[cfg(feature = "kx-p521")]
78+
impl_kx! {SecP521R1, rustls::NamedGroup::secp521r1, ::p521::ecdh::EphemeralSecret, ::p521::PublicKey}

src/kx/x448.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use alloc::boxed::Box;
33

44
use crypto::{SharedSecret, SupportedKxGroup};
5-
use rand_core::{RngCore, TryRngCore};
5+
use rand_core::TryRngCore;
66
use rustls::crypto::{self, ActiveKeyExchange};
77

88
#[derive(Debug)]
@@ -14,15 +14,13 @@ impl crypto::SupportedKxGroup for X448 {
1414
}
1515

1616
fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, rustls::Error> {
17-
18-
let priv_key = x448::Secret::from({
19-
let mut bytes = [0u8; 56];
20-
rand_core::OsRng.try_fill_bytes(&mut bytes).unwrap();
21-
bytes
22-
});
17+
let mut priv_key = [0u8; 56];
18+
rand_core::OsRng
19+
.try_fill_bytes(&mut priv_key)
20+
.map_err(|_| rustls::Error::FailedToGetRandomBytes)?;
21+
let priv_key: x448::Secret = priv_key.into();
2322
let pub_key = x448::PublicKey::from(&priv_key);
2423

25-
2624
Ok(Box::new(X448KeyExchange { priv_key, pub_key }))
2725
}
2826
}
@@ -34,14 +32,16 @@ pub struct X448KeyExchange {
3432

3533
impl ActiveKeyExchange for X448KeyExchange {
3634
fn complete(self: Box<X448KeyExchange>, peer: &[u8]) -> Result<SharedSecret, rustls::Error> {
37-
let pub_key = x448::PublicKey::from_bytes(peer).unwrap();
38-
39-
self.priv_key.as_diffie_hellman(&pub_key).unwrap();
40-
41-
// let peer_public: x448::PublicKey = peer
42-
// .try_into()
43-
// .map_err(|_| rustls::Error::from(rustls::PeerMisbehaved::InvalidKeyShare))?;
44-
Ok(self.priv_key.as_diffie_hellman(&pub_key).unwrap().as_bytes().as_ref().into())
35+
Ok(self
36+
.priv_key
37+
.as_diffie_hellman(
38+
&x448::PublicKey::from_bytes(peer)
39+
.ok_or(rustls::PeerMisbehaved::InvalidKeyShare)?,
40+
)
41+
.ok_or(rustls::PeerMisbehaved::InvalidKeyShare)?
42+
.as_bytes()
43+
.as_ref()
44+
.into())
4545
}
4646

4747
fn pub_key(&self) -> &[u8] {

src/sign.rs

Lines changed: 108 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,108 @@
1-
#[cfg(feature = "alloc")]
2-
use alloc::{sync::Arc, vec::Vec};
3-
use core::marker::PhantomData;
4-
5-
use pki_types::PrivateKeyDer;
6-
use rustls::sign::{Signer, SigningKey};
7-
use rustls::{Error, SignatureScheme};
8-
use signature::SignatureEncoding;
9-
10-
#[derive(Debug)]
11-
pub struct GenericSigner<S, T>
12-
where
13-
S: SignatureEncoding,
14-
T: signature::Signer<S>,
15-
{
16-
_marker: PhantomData<S>,
17-
key: Arc<T>,
18-
scheme: SignatureScheme,
19-
}
20-
21-
impl<S, T> Signer for GenericSigner<S, T>
22-
where
23-
S: SignatureEncoding + Send + Sync + core::fmt::Debug,
24-
T: signature::Signer<S> + Send + Sync + core::fmt::Debug,
25-
{
26-
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
27-
self.key
28-
.try_sign(message)
29-
.map_err(|_| rustls::Error::General("signing failed".into()))
30-
.map(|sig: S| sig.to_vec())
31-
}
32-
33-
fn scheme(&self) -> SignatureScheme {
34-
self.scheme
35-
}
36-
}
37-
38-
/// Extract any supported key from the given DER input.
39-
///
40-
/// # Errors
41-
///
42-
/// Returns an error if the key couldn't be decoded.
43-
#[allow(unused_variables)]
44-
pub fn any_supported_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, rustls::Error> {
45-
#[cfg(feature = "sign-rsa")]
46-
if let Ok(key) = rsa::RsaSigningKey::try_from(der) {
47-
return Ok(Arc::new(key) as _);
48-
}
49-
50-
#[cfg(feature = "sign-ecdsa-nist")]
51-
if let Ok(key) = any_ecdsa_type(der) {
52-
return Ok(key);
53-
}
54-
55-
#[cfg(feature = "sign-eddsa")]
56-
if let Ok(key) = any_eddsa_type(der) {
57-
return Ok(key);
58-
}
59-
60-
Err(rustls::Error::General("not supported".into()))
61-
}
62-
63-
/// Extract any supported ECDSA key from the given DER input.
64-
///
65-
/// # Errors
66-
///
67-
/// Returns an error if the key couldn't be decoded.
68-
#[allow(unused_variables)]
69-
#[cfg(feature = "sign-ecdsa-nist")]
70-
pub fn any_ecdsa_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, rustls::Error> {
71-
#[cfg(all(feature = "der", feature = "ecdsa-p256"))]
72-
if let Ok(key) = ecdsa::nist::EcdsaSigningKeyP256::try_from(der) {
73-
return Ok(Arc::new(key) as _);
74-
}
75-
#[cfg(all(feature = "der", feature = "ecdsa-p384"))]
76-
if let Ok(key) = ecdsa::nist::EcdsaSigningKeyP384::try_from(der) {
77-
return Ok(Arc::new(key) as _);
78-
}
79-
80-
Err(rustls::Error::General("not supported".into()))
81-
}
82-
83-
/// Extract any supported EDDSA key from the given DER input.
84-
///
85-
/// # Errors
86-
///
87-
/// Returns an error if the key couldn't be decoded.
88-
#[allow(unused_variables)]
89-
#[cfg(feature = "sign-eddsa")]
90-
pub fn any_eddsa_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, rustls::Error> {
91-
// TODO: Add support for Ed448
92-
#[cfg(all(feature = "der", feature = "eddsa-ed25519"))]
93-
if let Ok(key) = eddsa::ed25519::Ed25519SigningKey::try_from(der) {
94-
return Ok(Arc::new(key) as _);
95-
}
96-
97-
Err(rustls::Error::General("not supported".into()))
98-
}
99-
100-
#[cfg(feature = "ecdsa")]
101-
pub mod ecdsa;
102-
#[cfg(feature = "eddsa")]
103-
pub mod eddsa;
104-
#[cfg(feature = "rsa")]
105-
pub mod rsa;
106-
107-
#[cfg(feature = "rand")]
108-
pub mod rand;
1+
#[cfg(feature = "alloc")]
2+
use alloc::{sync::Arc, vec::Vec};
3+
use core::marker::PhantomData;
4+
5+
use pki_types::PrivateKeyDer;
6+
use rustls::sign::{Signer, SigningKey};
7+
use rustls::{Error, SignatureScheme};
8+
use signature::SignatureEncoding;
9+
10+
#[derive(Debug)]
11+
pub struct GenericSigner<S, T>
12+
where
13+
S: SignatureEncoding,
14+
T: signature::Signer<S>,
15+
{
16+
_marker: PhantomData<S>,
17+
key: Arc<T>,
18+
scheme: SignatureScheme,
19+
}
20+
21+
impl<S, T> Signer for GenericSigner<S, T>
22+
where
23+
S: SignatureEncoding + Send + Sync + core::fmt::Debug,
24+
T: signature::Signer<S> + Send + Sync + core::fmt::Debug,
25+
{
26+
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
27+
self.key
28+
.try_sign(message)
29+
.map_err(|_| rustls::Error::General("signing failed".into()))
30+
.map(|sig: S| sig.to_vec())
31+
}
32+
33+
fn scheme(&self) -> SignatureScheme {
34+
self.scheme
35+
}
36+
}
37+
38+
/// Extract any supported key from the given DER input.
39+
///
40+
/// # Errors
41+
///
42+
/// Returns an error if the key couldn't be decoded.
43+
#[allow(unused_variables)]
44+
pub fn any_supported_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, rustls::Error> {
45+
#[cfg(feature = "sign-rsa")]
46+
if let Ok(key) = rsa::RsaSigningKey::try_from(der) {
47+
return Ok(Arc::new(key) as _);
48+
}
49+
50+
#[cfg(feature = "sign-ecdsa-nist")]
51+
if let Ok(key) = any_ecdsa_type(der) {
52+
return Ok(key);
53+
}
54+
55+
#[cfg(feature = "sign-eddsa")]
56+
if let Ok(key) = any_eddsa_type(der) {
57+
return Ok(key);
58+
}
59+
60+
Err(rustls::Error::General("not supported".into()))
61+
}
62+
63+
/// Extract any supported ECDSA key from the given DER input.
64+
///
65+
/// # Errors
66+
///
67+
/// Returns an error if the key couldn't be decoded.
68+
#[allow(unused_variables)]
69+
#[cfg(feature = "sign-ecdsa-nist")]
70+
pub fn any_ecdsa_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, rustls::Error> {
71+
#[cfg(all(feature = "der", feature = "ecdsa-p256"))]
72+
if let Ok(key) = ecdsa::nist::EcdsaSigningKeyP256::try_from(der) {
73+
return Ok(Arc::new(key) as _);
74+
}
75+
#[cfg(all(feature = "der", feature = "ecdsa-p384"))]
76+
if let Ok(key) = ecdsa::nist::EcdsaSigningKeyP384::try_from(der) {
77+
return Ok(Arc::new(key) as _);
78+
}
79+
80+
Err(rustls::Error::General("not supported".into()))
81+
}
82+
83+
/// Extract any supported EDDSA key from the given DER input.
84+
///
85+
/// # Errors
86+
///
87+
/// Returns an error if the key couldn't be decoded.
88+
#[allow(unused_variables)]
89+
#[cfg(feature = "sign-eddsa")]
90+
pub fn any_eddsa_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, rustls::Error> {
91+
// TODO: Add support for Ed448
92+
#[cfg(all(feature = "der", feature = "eddsa-ed25519"))]
93+
if let Ok(key) = eddsa::ed25519::Ed25519SigningKey::try_from(der) {
94+
return Ok(Arc::new(key) as _);
95+
}
96+
97+
Err(rustls::Error::General("not supported".into()))
98+
}
99+
100+
#[cfg(feature = "ecdsa")]
101+
pub mod ecdsa;
102+
#[cfg(feature = "eddsa")]
103+
pub mod eddsa;
104+
#[cfg(feature = "rsa")]
105+
pub mod rsa;
106+
107+
#[cfg(feature = "rand")]
108+
pub mod rand;

0 commit comments

Comments
 (0)