Skip to content

Commit 2857b5f

Browse files
committed
feat: add SignatureVerificationAlgorithm
1 parent 6958cd0 commit 2857b5f

File tree

6 files changed

+169
-8
lines changed

6 files changed

+169
-8
lines changed

rustls-mbedcrypto-provider/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ log = { version = "0.4.4", optional = true }
2020
pki-types = { package = "rustls-pki-types", version = "0.2.1", features = [
2121
"std",
2222
] }
23+
webpki = { package = "rustls-webpki", version = "0.102.0-alpha.6", features = ["alloc", "std"], default-features = false }
2324
utils = { package = "rustls-mbedtls-provider-utils", path = "../rustls-mbedtls-provider-utils", version = "0.1.0-alpha.1" }
2425

2526
[target.'cfg(target_env = "msvc")'.dependencies]

rustls-mbedcrypto-provider/src/hash.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ pub(crate) static MBED_SHA_384: Algorithm = Algorithm {
4343
output_len: 384 / 8,
4444
};
4545

46+
/// SHA-512 as specified in [FIPS 180-4].
47+
///
48+
/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
49+
pub(crate) static MBED_SHA_512: Algorithm = Algorithm {
50+
hash_algorithm: HashAlgorithm::SHA512,
51+
hash_type: mbedtls::hash::Type::Sha512,
52+
output_len: 512 / 8,
53+
};
54+
4655
impl hash::Hash for Hash {
4756
fn start(&self) -> Box<dyn hash::Context> {
4857
Box::new(HashContext(MbedHashContext::new(self.0)))

rustls-mbedcrypto-provider/src/lib.rs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,17 @@ pub(crate) mod hmac;
8181
pub(crate) mod kx;
8282

8383
/// Message signing interfaces.
84-
pub mod signer;
84+
pub mod sign;
85+
/// Supported signature verify algorithms
86+
pub mod signature_verify_algo;
8587
/// TLS1.2 ciphersuites implementation.
8688
#[cfg(feature = "tls12")]
8789
pub mod tls12;
8890
/// TLS1.3 ciphersuites implementation.
8991
pub mod tls13;
9092

9193
use mbedtls::rng::Random;
92-
use rustls::SupportedCipherSuite;
94+
use rustls::{SignatureScheme, SupportedCipherSuite, WebPkiSupportedAlgorithms};
9395

9496
/// RNG supported by *mbedtls*
9597
pub mod rng {
@@ -142,13 +144,17 @@ impl rustls::crypto::CryptoProvider for Mbedtls {
142144

143145
fn load_private_key(
144146
&self,
145-
_key_der: pki_types::PrivateKeyDer<'static>,
147+
key_der: pki_types::PrivateKeyDer<'static>,
146148
) -> Result<alloc::sync::Arc<dyn rustls::sign::SigningKey>, rustls::Error> {
147-
todo!()
149+
let pk = mbedtls::pk::Pk::from_private_key(key_der.secret_der(), None)
150+
.map_err(|err| rustls::Error::Other(rustls::OtherError(alloc::sync::Arc::new(err))))?;
151+
Ok(alloc::sync::Arc::new(MbedTlsPkSigningKey(alloc::sync::Arc::new(
152+
std::sync::Mutex::new(pk),
153+
))))
148154
}
149155

150-
fn signature_verification_algorithms(&self) -> rustls::WebPkiSupportedAlgorithms {
151-
todo!()
156+
fn signature_verification_algorithms(&self) -> WebPkiSupportedAlgorithms {
157+
SUPPORTED_SIG_ALGS
152158
}
153159
}
154160

@@ -179,6 +185,37 @@ pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
179185
tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
180186
];
181187

188+
/// A `WebPkiSupportedAlgorithms` value that reflects pki's capabilities when
189+
/// compiled against *mbedtls*.
190+
static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
191+
all: &[
192+
signature_verify_algo::ECDSA_P256_SHA256,
193+
signature_verify_algo::ECDSA_P384_SHA384,
194+
signature_verify_algo::RSA_PKCS1_SHA256,
195+
signature_verify_algo::RSA_PKCS1_SHA384,
196+
signature_verify_algo::RSA_PKCS1_SHA512,
197+
signature_verify_algo::RSA_PSS_SHA256,
198+
signature_verify_algo::RSA_PSS_SHA384,
199+
signature_verify_algo::RSA_PSS_SHA512,
200+
],
201+
mapping: &[
202+
(
203+
SignatureScheme::ECDSA_NISTP384_SHA384,
204+
&[signature_verify_algo::ECDSA_P384_SHA384],
205+
),
206+
(
207+
SignatureScheme::ECDSA_NISTP256_SHA256,
208+
&[signature_verify_algo::ECDSA_P256_SHA256],
209+
),
210+
(SignatureScheme::RSA_PSS_SHA512, &[signature_verify_algo::RSA_PKCS1_SHA512]),
211+
(SignatureScheme::RSA_PSS_SHA384, &[signature_verify_algo::RSA_PKCS1_SHA384]),
212+
(SignatureScheme::RSA_PSS_SHA256, &[signature_verify_algo::RSA_PKCS1_SHA256]),
213+
(SignatureScheme::RSA_PKCS1_SHA512, &[signature_verify_algo::RSA_PSS_SHA512]),
214+
(SignatureScheme::RSA_PKCS1_SHA384, &[signature_verify_algo::RSA_PSS_SHA384]),
215+
(SignatureScheme::RSA_PKCS1_SHA256, &[signature_verify_algo::RSA_PSS_SHA256]),
216+
],
217+
};
218+
182219
/// All defined key exchange groups supported by *mbedtls* appear in this module.
183220
///
184221
/// [`ALL_KX_GROUPS`] is provided as an array of all of these values.
@@ -190,3 +227,4 @@ pub mod kx_group {
190227
}
191228

192229
pub use kx::ALL_KX_GROUPS;
230+
use sign::MbedTlsPkSigningKey;

rustls-mbedcrypto-provider/src/signer.rs renamed to rustls-mbedcrypto-provider/src/sign.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use utils::error::mbedtls_err_into_rustls_err;
77
use utils::hash::{buffer_for_hash_type, rustls_signature_scheme_to_mbedtls_hash_type};
88
use utils::pk::{rustls_signature_scheme_to_mbedtls_pk_options, rustls_signature_scheme_to_mbedtls_pk_type};
99

10-
///
1110
struct MbedTlsSigner(Arc<Mutex<mbedtls::pk::Pk>>, rustls::SignatureScheme);
1211

1312
impl Debug for MbedTlsSigner {
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use super::hash::Algorithm as HashAlgorithm;
2+
use alloc::vec;
3+
use mbedtls::pk::Pk;
4+
use pki_types::{AlgorithmIdentifier, InvalidSignature, SignatureVerificationAlgorithm};
5+
use rustls::SignatureScheme;
6+
use webpki::alg_id;
7+
8+
/// ECDSA signatures using the P-256 curve and SHA-256.
9+
pub static ECDSA_P256_SHA256: &Algorithm = &Algorithm {
10+
signature_scheme: SignatureScheme::ECDSA_NISTP256_SHA256,
11+
hash_algo: &super::hash::MBED_SHA_256,
12+
public_key_alg_id: alg_id::ECDSA_P256,
13+
signature_alg_id: alg_id::ECDSA_SHA256,
14+
};
15+
/// ECDSA signatures using the P-384 curve and SHA-384.
16+
pub static ECDSA_P384_SHA384: &Algorithm = &Algorithm {
17+
signature_scheme: SignatureScheme::ECDSA_NISTP384_SHA384,
18+
hash_algo: &super::hash::MBED_SHA_384,
19+
public_key_alg_id: alg_id::ECDSA_P384,
20+
signature_alg_id: alg_id::ECDSA_SHA384,
21+
};
22+
/// RSA PKCS#1 1.5 signatures using SHA-256.
23+
pub static RSA_PKCS1_SHA256: &Algorithm = &Algorithm {
24+
signature_scheme: SignatureScheme::RSA_PKCS1_SHA256,
25+
hash_algo: &super::hash::MBED_SHA_256,
26+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
27+
signature_alg_id: alg_id::RSA_PKCS1_SHA256,
28+
};
29+
/// RSA PKCS#1 1.5 signatures using SHA-384.
30+
pub static RSA_PKCS1_SHA384: &Algorithm = &Algorithm {
31+
signature_scheme: SignatureScheme::RSA_PKCS1_SHA384,
32+
hash_algo: &super::hash::MBED_SHA_384,
33+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
34+
signature_alg_id: alg_id::RSA_PKCS1_SHA384,
35+
};
36+
/// RSA PKCS#1 1.5 signatures using SHA-512.
37+
pub static RSA_PKCS1_SHA512: &Algorithm = &Algorithm {
38+
signature_scheme: SignatureScheme::RSA_PKCS1_SHA512,
39+
hash_algo: &super::hash::MBED_SHA_512,
40+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
41+
signature_alg_id: alg_id::RSA_PKCS1_SHA512,
42+
};
43+
/// RSA PSS signatures using SHA-256 and of
44+
/// type rsaEncryption; see [RFC 4055 Section 1.2].
45+
///
46+
/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
47+
pub static RSA_PSS_SHA256: &Algorithm = &Algorithm {
48+
signature_scheme: SignatureScheme::RSA_PSS_SHA256,
49+
hash_algo: &super::hash::MBED_SHA_256,
50+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
51+
signature_alg_id: alg_id::RSA_PSS_SHA256,
52+
};
53+
/// RSA PSS signatures using SHA-384 and of
54+
/// type rsaEncryption; see [RFC 4055 Section 1.2].
55+
///
56+
/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
57+
pub static RSA_PSS_SHA384: &Algorithm = &Algorithm {
58+
signature_scheme: SignatureScheme::RSA_PSS_SHA384,
59+
hash_algo: &super::hash::MBED_SHA_384,
60+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
61+
signature_alg_id: alg_id::RSA_PSS_SHA384,
62+
};
63+
/// RSA PSS signatures using SHA-512 and of
64+
/// type rsaEncryption; see [RFC 4055 Section 1.2].
65+
///
66+
/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
67+
pub static RSA_PSS_SHA512: &Algorithm = &Algorithm {
68+
signature_scheme: SignatureScheme::RSA_PSS_SHA512,
69+
hash_algo: &super::hash::MBED_SHA_512,
70+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
71+
signature_alg_id: alg_id::RSA_PSS_SHA512,
72+
};
73+
74+
/// A signature verify algorithm type
75+
#[derive(Clone, Debug, PartialEq)]
76+
pub struct Algorithm {
77+
signature_scheme: SignatureScheme,
78+
hash_algo: &'static HashAlgorithm,
79+
public_key_alg_id: AlgorithmIdentifier,
80+
signature_alg_id: AlgorithmIdentifier,
81+
}
82+
83+
impl SignatureVerificationAlgorithm for Algorithm {
84+
fn verify_signature(&self, public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<(), InvalidSignature> {
85+
let mut pk = Pk::from_public_key(public_key).map_err(|_| InvalidSignature)?;
86+
let signature_curve = utils::pk::rustls_signature_scheme_to_mbedtls_curve_id(self.signature_scheme);
87+
match signature_curve {
88+
mbedtls::pk::EcGroupId::None => (),
89+
_ => {
90+
let curves_match = pk
91+
.curve()
92+
.is_ok_and(|pk_curve| pk_curve == signature_curve);
93+
if !curves_match {
94+
return Err(InvalidSignature);
95+
}
96+
}
97+
}
98+
if let Some(opts) = utils::pk::rustls_signature_scheme_to_mbedtls_pk_options(self.signature_scheme) {
99+
pk.set_options(opts);
100+
}
101+
let mut hash = vec![0u8; self.hash_algo.output_len];
102+
mbedtls::hash::Md::hash(self.hash_algo.hash_type, message, &mut hash).map_err(|_| InvalidSignature)?;
103+
pk.verify(self.hash_algo.hash_type, &hash, signature)
104+
.map_err(|_| InvalidSignature)
105+
}
106+
107+
fn public_key_alg_id(&self) -> AlgorithmIdentifier {
108+
self.public_key_alg_id
109+
}
110+
111+
fn signature_alg_id(&self) -> AlgorithmIdentifier {
112+
self.signature_alg_id
113+
}
114+
}

rustls-mbedpki-provider/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ fn verify_tls_signature(
137137
let pk = cert.public_key_mut();
138138
let hash_type = utils::hash::rustls_signature_scheme_to_mbedtls_hash_type(dss.scheme);
139139

140-
// for tls 1.3, we need to verify the advertised curve in signaure scheme matches the public key
140+
// for tls 1.3, we need to verify the advertised curve in signature scheme matches the public key
141141
if is_tls13 {
142142
let signature_curve = utils::pk::rustls_signature_scheme_to_mbedtls_curve_id(dss.scheme);
143143
match signature_curve {

0 commit comments

Comments
 (0)