Skip to content

Commit 6958cd0

Browse files
committed
feat: add signer impl
- Add crate `rustls-mbedtls-provider-utils` - Add signer impl
1 parent 528fda2 commit 6958cd0

File tree

17 files changed

+471
-164
lines changed

17 files changed

+471
-164
lines changed

Cargo.lock

Lines changed: 11 additions & 0 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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
[workspace]
2-
members = ["examples","rustls-mbedcrypto-provider", "rustls-mbedpki-provider"]
2+
members = [
3+
"examples",
4+
"rustls-mbedcrypto-provider",
5+
"rustls-mbedpki-provider",
6+
"rustls-mbedtls-provider-utils",
7+
]
38
default-members = ["rustls-mbedcrypto-provider", "rustls-mbedpki-provider"]
49
resolver = "2"

rustls-mbedcrypto-provider/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ mbedtls = { version = "0.12.0-alpha.2", default-features = false, features = [
1717
"std",
1818
] }
1919
log = { version = "0.4.4", optional = true }
20+
pki-types = { package = "rustls-pki-types", version = "0.2.1", features = [
21+
"std",
22+
] }
23+
utils = { package = "rustls-mbedtls-provider-utils", path = "../rustls-mbedtls-provider-utils", version = "0.1.0-alpha.1" }
2024

2125
[target.'cfg(target_env = "msvc")'.dependencies]
2226
# mbedtls need feature `time` to build when targeting msvc
@@ -33,7 +37,6 @@ webpki = { package = "rustls-webpki", version = "0.102.0-alpha.1", default-featu
3337
"alloc",
3438
"std",
3539
] }
36-
pki-types = { package = "rustls-pki-types", version = "0.2.0" }
3740
webpki-roots = "0.26.0-alpha.1"
3841
rustls-pemfile = "2.0.0-alpha.1"
3942
env_logger = "0.10"

rustls-mbedcrypto-provider/src/kx.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use super::agreement;
99
use crate::error::mbedtls_err_to_rustls_general_error;
1010

11-
use crate::log::error;
1211
use alloc::boxed::Box;
1312
use alloc::fmt;
1413
use alloc::format;
@@ -42,15 +41,12 @@ impl fmt::Debug for KxGroup {
4241
}
4342

4443
impl SupportedKxGroup for KxGroup {
45-
fn start(&self) -> Result<Box<dyn crypto::ActiveKeyExchange>, rustls::crypto::GetRandomFailed> {
44+
fn start(&self) -> Result<Box<dyn crypto::ActiveKeyExchange>, Error> {
4645
let mut pk = PkMbed::generate_ec(
4746
&mut super::rng::rng_new().ok_or(rustls::crypto::GetRandomFailed)?,
4847
self.agreement_algorithm.group_id,
4948
)
50-
.map_err(|_err| {
51-
error!("Encountered error when generating ec key, mbedtls error: {}", _err);
52-
rustls::crypto::GetRandomFailed
53-
})?;
49+
.map_err(|err| rustls::Error::General(format!("Encountered error when generating ec key, mbedtls error: {}", err)))?;
5450

5551
fn get_key_pair(pk: &mut PkMbed, kx_group: &KxGroup) -> Result<KeyExchange, mbedtls::Error> {
5652
let group = EcGroup::new(kx_group.agreement_algorithm.group_id)?;
@@ -68,10 +64,7 @@ impl SupportedKxGroup for KxGroup {
6864

6965
match get_key_pair(&mut pk, self) {
7066
Ok(group) => Ok(Box::new(group)),
71-
Err(_err) => {
72-
error!("Unexpected mbedtls error: {}", _err);
73-
Err(rustls::crypto::GetRandomFailed)
74-
}
67+
Err(err) => Err(rustls::Error::General(format!("Unexpected mbedtls error: {}", err))),
7568
}
7669
}
7770

rustls-mbedcrypto-provider/src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ pub(crate) mod hash;
8080
pub(crate) mod hmac;
8181
pub(crate) mod kx;
8282

83+
/// Message signing interfaces.
84+
pub mod signer;
8385
/// TLS1.2 ciphersuites implementation.
8486
#[cfg(feature = "tls12")]
8587
pub mod tls12;
@@ -137,6 +139,17 @@ impl rustls::crypto::CryptoProvider for Mbedtls {
137139
fn default_kx_groups(&self) -> &'static [&'static dyn rustls::crypto::SupportedKxGroup] {
138140
ALL_KX_GROUPS
139141
}
142+
143+
fn load_private_key(
144+
&self,
145+
_key_der: pki_types::PrivateKeyDer<'static>,
146+
) -> Result<alloc::sync::Arc<dyn rustls::sign::SigningKey>, rustls::Error> {
147+
todo!()
148+
}
149+
150+
fn signature_verification_algorithms(&self) -> rustls::WebPkiSupportedAlgorithms {
151+
todo!()
152+
}
140153
}
141154

142155
/// The cipher suite configuration that an application should use by default.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use alloc::vec;
2+
use alloc::{boxed::Box, sync::Arc, vec::Vec};
3+
use core::fmt::Debug;
4+
use mbedtls::pk::ECDSA_MAX_LEN;
5+
use std::sync::Mutex;
6+
use utils::error::mbedtls_err_into_rustls_err;
7+
use utils::hash::{buffer_for_hash_type, rustls_signature_scheme_to_mbedtls_hash_type};
8+
use utils::pk::{rustls_signature_scheme_to_mbedtls_pk_options, rustls_signature_scheme_to_mbedtls_pk_type};
9+
10+
///
11+
struct MbedTlsSigner(Arc<Mutex<mbedtls::pk::Pk>>, rustls::SignatureScheme);
12+
13+
impl Debug for MbedTlsSigner {
14+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15+
f.debug_tuple("MbedTlsSigner")
16+
.field(&"Arc<Mutex<mbedtls::pk::Pk>>")
17+
.field(&self.1)
18+
.finish()
19+
}
20+
}
21+
22+
impl rustls::sign::Signer for MbedTlsSigner {
23+
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, rustls::Error> {
24+
let hash_type = rustls_signature_scheme_to_mbedtls_hash_type(self.1);
25+
let mut hash = buffer_for_hash_type(hash_type).ok_or_else(|| rustls::Error::General("unexpected hash type".into()))?;
26+
let hash_size = mbedtls::hash::Md::hash(hash_type, message, &mut hash).map_err(mbedtls_err_into_rustls_err)?;
27+
28+
let mut pk = self
29+
.0
30+
.lock()
31+
.expect("poisoned PK lock!");
32+
if let Some(opts) = rustls_signature_scheme_to_mbedtls_pk_options(self.1) {
33+
pk.set_options(opts);
34+
}
35+
36+
fn sig_len_for_pk(pk: &mbedtls::pk::Pk) -> usize {
37+
match pk.pk_type() {
38+
mbedtls::pk::Type::Eckey | mbedtls::pk::Type::EckeyDh | mbedtls::pk::Type::Ecdsa => ECDSA_MAX_LEN,
39+
_ => pk.len() / 8,
40+
}
41+
}
42+
let mut sig = vec![0; sig_len_for_pk(&pk)];
43+
let sig_len = pk
44+
.sign(
45+
hash_type,
46+
&hash[..hash_size],
47+
&mut sig,
48+
&mut crate::rng::rng_new().ok_or(rustls::Error::FailedToGetRandomBytes)?,
49+
)
50+
.map_err(mbedtls_err_into_rustls_err)?;
51+
sig.truncate(sig_len);
52+
Ok(sig)
53+
}
54+
55+
fn scheme(&self) -> rustls::SignatureScheme {
56+
self.1
57+
}
58+
}
59+
60+
/// A [`SigningKey`] implemented by using [`mbedtls`]
61+
///
62+
/// [`SigningKey`]: rustls::sign::SigningKey
63+
pub struct MbedTlsPkSigningKey(pub Arc<Mutex<mbedtls::pk::Pk>>);
64+
65+
impl Debug for MbedTlsPkSigningKey {
66+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
67+
f.debug_tuple("MbedTlsPkSigningKey")
68+
.field(&"Arc<Mutex<mbedtls::pk::Pk>>")
69+
.finish()
70+
}
71+
}
72+
73+
impl rustls::sign::SigningKey for MbedTlsPkSigningKey {
74+
fn choose_scheme(&self, offered: &[rustls::SignatureScheme]) -> Option<Box<dyn rustls::sign::Signer>> {
75+
for scheme in offered {
76+
let scheme_type = rustls_signature_scheme_to_mbedtls_pk_type(scheme);
77+
if let Some(scheme_type) = scheme_type {
78+
if scheme_type
79+
== self
80+
.0
81+
.lock()
82+
.expect("poisoned pk lock")
83+
.pk_type()
84+
{
85+
let signer = MbedTlsSigner(self.0.clone(), *scheme);
86+
return Some(Box::new(signer));
87+
}
88+
}
89+
}
90+
None
91+
}
92+
93+
fn algorithm(&self) -> rustls::SignatureAlgorithm {
94+
use rustls::SignatureAlgorithm;
95+
match self
96+
.0
97+
.lock()
98+
.expect("poisoned pk lock")
99+
.pk_type()
100+
{
101+
mbedtls::pk::Type::Rsa => SignatureAlgorithm::RSA,
102+
mbedtls::pk::Type::Ecdsa => SignatureAlgorithm::ECDSA,
103+
mbedtls::pk::Type::RsassaPss => SignatureAlgorithm::RSA,
104+
mbedtls::pk::Type::Eckey => SignatureAlgorithm::ECDSA,
105+
mbedtls::pk::Type::RsaAlt => SignatureAlgorithm::DSA,
106+
mbedtls::pk::Type::EckeyDh => SignatureAlgorithm::Anonymous,
107+
mbedtls::pk::Type::Custom => SignatureAlgorithm::Anonymous,
108+
mbedtls::pk::Type::None => SignatureAlgorithm::Anonymous,
109+
}
110+
}
111+
}

rustls-mbedcrypto-provider/src/tls12.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use alloc::boxed::Box;
1010
use alloc::vec::Vec;
1111
use mbedtls::cipher::raw::{CipherId, CipherMode, CipherType};
1212
use mbedtls::cipher::{Authenticated, Cipher, Decryption, Encryption, Fresh};
13-
use rustls::cipher_suite::CipherSuiteCommon;
1413
use rustls::crypto::cipher::{
1514
make_tls12_aad, AeadKey, BorrowedPlainMessage, Iv, KeyBlockShape, MessageDecrypter, MessageEncrypter, Nonce, OpaqueMessage,
1615
PlainMessage, Tls12AeadAlgorithm, UnsupportedOperationError, NONCE_LEN,
@@ -20,7 +19,9 @@ use rustls::crypto::KeyExchangeAlgorithm;
2019

2120
use super::aead::{self, Algorithm, AES128_GCM, AES256_GCM};
2221
use alloc::string::String;
23-
use rustls::{CipherSuite, ConnectionTrafficSecrets, Error, SignatureScheme, SupportedCipherSuite, Tls12CipherSuite};
22+
use rustls::{
23+
CipherSuite, CipherSuiteCommon, ConnectionTrafficSecrets, Error, SignatureScheme, SupportedCipherSuite, Tls12CipherSuite,
24+
};
2425

2526
pub(crate) const GCM_FIXED_IV_LEN: usize = 4;
2627
pub(crate) const GCM_EXPLICIT_NONCE_LEN: usize = 8;

rustls-mbedcrypto-provider/src/tls13.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ use alloc::string::String;
1212
use alloc::vec::Vec;
1313
use mbedtls::cipher::raw::CipherType;
1414
use mbedtls::cipher::{Authenticated, Cipher, Decryption, Encryption, Fresh};
15-
use rustls::cipher_suite::CipherSuiteCommon;
1615
use rustls::crypto::cipher::{
1716
make_tls13_aad, AeadKey, BorrowedPlainMessage, Iv, MessageDecrypter, MessageEncrypter, Nonce, OpaqueMessage, PlainMessage,
1817
Tls13AeadAlgorithm, UnsupportedOperationError,
1918
};
2019
use rustls::crypto::tls13::HkdfUsingHmac;
2120
use rustls::internal::msgs::codec::Codec;
2221
use rustls::{
23-
CipherSuite, ConnectionTrafficSecrets, ContentType, Error, ProtocolVersion, SupportedCipherSuite, Tls13CipherSuite,
22+
CipherSuite, CipherSuiteCommon, ConnectionTrafficSecrets, ContentType, Error, ProtocolVersion, SupportedCipherSuite,
23+
Tls13CipherSuite,
2424
};
2525

2626
/// The TLS1.3 ciphersuite TLS_CHACHA20_POLY1305_SHA256

rustls-mbedpki-provider/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ chrono = "0.4"
2323
pki-types = { package = "rustls-pki-types", version = "0.2.1", features = [
2424
"std",
2525
] }
26+
utils = { package = "rustls-mbedtls-provider-utils", path = "../rustls-mbedtls-provider-utils", version = "0.1.0-alpha.1" }
2627

2728
[target.'cfg(target_env = "msvc")'.dependencies]
2829
# mbedtls need feature `time` to build when targeting msvc

rustls-mbedpki-provider/src/client_cert_verifier.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@
55
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
66
*/
77

8-
use std::sync::Arc;
9-
8+
use alloc::string::String;
9+
use alloc::sync::Arc;
10+
use alloc::vec;
11+
use alloc::vec::Vec;
1012
use chrono::NaiveDateTime;
1113
use pki_types::{CertificateDer, UnixTime};
1214
use rustls::{
1315
server::danger::{ClientCertVerified, ClientCertVerifier},
1416
DistinguishedName,
1517
};
18+
use utils::error::mbedtls_err_into_rustls_err_with_error_msg;
1619

1720
use crate::{
18-
mbedtls_err_into_rustls_err, mbedtls_err_into_rustls_err_with_error_msg, rustls_cert_to_mbedtls_cert,
19-
verify_certificates_active, verify_tls_signature, CertActiveCheck,
21+
mbedtls_err_into_rustls_err, rustls_cert_to_mbedtls_cert, verify_certificates_active, verify_tls_signature, CertActiveCheck,
2022
};
2123

2224
/// A [`rustls`] [`ClientCertVerifier`] implemented using the PKI functionality of
@@ -29,6 +31,17 @@ pub struct MbedTlsClientCertVerifier {
2931
cert_active_check: CertActiveCheck,
3032
}
3133

34+
impl std::fmt::Debug for MbedTlsClientCertVerifier {
35+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36+
f.debug_struct("MbedTlsClientCertVerifier")
37+
.field("trusted_cas", &"..")
38+
.field("root_subjects", &self.root_subjects)
39+
.field("verify_callback", &"..")
40+
.field("cert_active_check", &self.cert_active_check)
41+
.finish()
42+
}
43+
}
44+
3245
impl MbedTlsClientCertVerifier {
3346
/// Constructs a new [`MbedTlsClientCertVerifier`] object given the provided trusted certificate authority
3447
/// certificates.

0 commit comments

Comments
 (0)