From 528fda250464e997f5355d7f01a1461f46c2b29c Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Tue, 14 Nov 2023 14:10:14 -0800 Subject: [PATCH 01/14] build: upgrade to use rustls 0.22.0-alpha.4 --- Cargo.lock | 3 ++- examples/Cargo.toml | 4 +--- rustls-mbedcrypto-provider/Cargo.toml | 11 +++++------ rustls-mbedpki-provider/Cargo.toml | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a9d937..588ec30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -655,7 +655,8 @@ dependencies = [ [[package]] name = "rustls" version = "0.22.0-alpha.4" -source = "git+https://github.com/rustls/rustls?rev=b776a5778ad333653670c34ff9125d8ae59b6047#b776a5778ad333653670c34ff9125d8ae59b6047" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c23376606de66c7b9249d091b59ee55b52df72063e1cae7bb44e0691c9e5150" dependencies = [ "log", "ring", diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 0402e39..5e54756 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -10,7 +10,5 @@ publish = false rustls-mbedcrypto-provider = { path = "../rustls-mbedcrypto-provider" } rustls-mbedpki-provider = { path = "../rustls-mbedpki-provider" } env_logger = "0.10" -# TODO: upgrade to use formal 0.22.0 or 0.22.0-* versions when availabe -rustls = { git = "https://github.com/rustls/rustls", rev = "b776a5778ad333653670c34ff9125d8ae59b6047", version = "0.22.0-alpha.4", default-features = false } +rustls = { version = "0.22.0-alpha.4", default-features = false } rustls-native-certs = "0.6.3" - diff --git a/rustls-mbedcrypto-provider/Cargo.toml b/rustls-mbedcrypto-provider/Cargo.toml index 22848cc..fbca6a7 100644 --- a/rustls-mbedcrypto-provider/Cargo.toml +++ b/rustls-mbedcrypto-provider/Cargo.toml @@ -12,12 +12,11 @@ categories = ["network-programming", "cryptography"] resolver = "2" [dependencies] -# TODO: upgrade to use formal 0.22.0 or 0.22.0-* versions when availabe -rustls = { git = "https://github.com/rustls/rustls", rev = "b776a5778ad333653670c34ff9125d8ae59b6047", version = "0.22.0-alpha.4", default-features = false } +rustls = { version = "0.22.0-alpha.4", default-features = false } mbedtls = { version = "0.12.0-alpha.2", default-features = false, features = [ "std", ] } -log = { version = "0.4.20", optional = true } +log = { version = "0.4.4", optional = true } [target.'cfg(target_env = "msvc")'.dependencies] # mbedtls need feature `time` to build when targeting msvc @@ -27,7 +26,7 @@ mbedtls = { version = "0.12.0-alpha.2", default-features = false, features = [ ] } [dev-dependencies] -rustls = { git = "https://github.com/rustls/rustls", rev = "b776a5778ad333653670c34ff9125d8ae59b6047", version = "0.22.0-alpha.4", default-features = false, features = [ +rustls = { version = "0.22.0-alpha.4", default-features = false, features = [ "ring", ] } webpki = { package = "rustls-webpki", version = "0.102.0-alpha.1", default-features = false, features = [ @@ -36,9 +35,9 @@ webpki = { package = "rustls-webpki", version = "0.102.0-alpha.1", default-featu ] } pki-types = { package = "rustls-pki-types", version = "0.2.0" } webpki-roots = "0.26.0-alpha.1" -rustls-pemfile = "=2.0.0-alpha.1" +rustls-pemfile = "2.0.0-alpha.1" env_logger = "0.10" -log = { version = "0.4.20" } +log = { version = "0.4.4" } [features] default = ["logging", "tls12"] diff --git a/rustls-mbedpki-provider/Cargo.toml b/rustls-mbedpki-provider/Cargo.toml index 4b66e99..ffe9e67 100644 --- a/rustls-mbedpki-provider/Cargo.toml +++ b/rustls-mbedpki-provider/Cargo.toml @@ -11,7 +11,7 @@ categories = ["network-programming", "cryptography"] resolver = "2" [dependencies] -rustls = { git = "https://github.com/rustls/rustls", rev = "b776a5778ad333653670c34ff9125d8ae59b6047", version = "0.22.0-alpha.4", default_features = false } +rustls = { version = "0.22.0-alpha.4", default_features = false } mbedtls = { version = "0.12.0-alpha.2", features = [ "x509", "chrono", @@ -35,4 +35,4 @@ mbedtls = { version = "0.12.0-alpha.2", default-features = false, features = [ [dev-dependencies] rustls-pemfile = "1.0" -rustls = { git = "https://github.com/rustls/rustls", rev = "b776a5778ad333653670c34ff9125d8ae59b6047", version = "0.22.0-alpha.4" } +rustls = { version = "0.22.0-alpha.4" } From 6958cd0757450ff706ef4c9b127de2752f25b393 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Tue, 14 Nov 2023 16:08:08 -0800 Subject: [PATCH 02/14] feat: add signer impl - Add crate `rustls-mbedtls-provider-utils` - Add signer impl --- Cargo.lock | 11 ++ Cargo.toml | 7 +- rustls-mbedcrypto-provider/Cargo.toml | 5 +- rustls-mbedcrypto-provider/src/kx.rs | 13 +- rustls-mbedcrypto-provider/src/lib.rs | 13 ++ rustls-mbedcrypto-provider/src/signer.rs | 111 ++++++++++++ rustls-mbedcrypto-provider/src/tls12.rs | 5 +- rustls-mbedcrypto-provider/src/tls13.rs | 4 +- rustls-mbedpki-provider/Cargo.toml | 1 + .../src/client_cert_verifier.rs | 21 ++- rustls-mbedpki-provider/src/lib.rs | 163 +++--------------- .../src/server_cert_verifier.rs | 21 ++- rustls-mbedtls-provider-utils/Cargo.toml | 28 +++ rustls-mbedtls-provider-utils/src/error.rs | 39 +++++ rustls-mbedtls-provider-utils/src/hash.rs | 47 +++++ rustls-mbedtls-provider-utils/src/lib.rs | 40 +++++ rustls-mbedtls-provider-utils/src/pk.rs | 106 ++++++++++++ 17 files changed, 471 insertions(+), 164 deletions(-) create mode 100644 rustls-mbedcrypto-provider/src/signer.rs create mode 100644 rustls-mbedtls-provider-utils/Cargo.toml create mode 100644 rustls-mbedtls-provider-utils/src/error.rs create mode 100644 rustls-mbedtls-provider-utils/src/hash.rs create mode 100644 rustls-mbedtls-provider-utils/src/lib.rs create mode 100644 rustls-mbedtls-provider-utils/src/pk.rs diff --git a/Cargo.lock b/Cargo.lock index 588ec30..bebee03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,6 +674,7 @@ dependencies = [ "log", "mbedtls", "rustls", + "rustls-mbedtls-provider-utils", "rustls-pemfile 2.0.0-alpha.1", "rustls-pki-types", "rustls-webpki", @@ -687,6 +688,7 @@ dependencies = [ "chrono", "mbedtls", "rustls", + "rustls-mbedtls-provider-utils", "rustls-pemfile 1.0.3", "rustls-pki-types", "x509-parser", @@ -703,6 +705,15 @@ dependencies = [ "rustls-native-certs", ] +[[package]] +name = "rustls-mbedtls-provider-utils" +version = "0.1.0-alpha.1" +dependencies = [ + "mbedtls", + "rustls", + "rustls-pki-types", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" diff --git a/Cargo.toml b/Cargo.toml index 7a370c8..4311ad7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,9 @@ [workspace] -members = ["examples","rustls-mbedcrypto-provider", "rustls-mbedpki-provider"] +members = [ + "examples", + "rustls-mbedcrypto-provider", + "rustls-mbedpki-provider", + "rustls-mbedtls-provider-utils", +] default-members = ["rustls-mbedcrypto-provider", "rustls-mbedpki-provider"] resolver = "2" diff --git a/rustls-mbedcrypto-provider/Cargo.toml b/rustls-mbedcrypto-provider/Cargo.toml index fbca6a7..bf6913d 100644 --- a/rustls-mbedcrypto-provider/Cargo.toml +++ b/rustls-mbedcrypto-provider/Cargo.toml @@ -17,6 +17,10 @@ mbedtls = { version = "0.12.0-alpha.2", default-features = false, features = [ "std", ] } log = { version = "0.4.4", optional = true } +pki-types = { package = "rustls-pki-types", version = "0.2.1", features = [ + "std", +] } +utils = { package = "rustls-mbedtls-provider-utils", path = "../rustls-mbedtls-provider-utils", version = "0.1.0-alpha.1" } [target.'cfg(target_env = "msvc")'.dependencies] # 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 "alloc", "std", ] } -pki-types = { package = "rustls-pki-types", version = "0.2.0" } webpki-roots = "0.26.0-alpha.1" rustls-pemfile = "2.0.0-alpha.1" env_logger = "0.10" diff --git a/rustls-mbedcrypto-provider/src/kx.rs b/rustls-mbedcrypto-provider/src/kx.rs index 6d34fea..dbcd47f 100644 --- a/rustls-mbedcrypto-provider/src/kx.rs +++ b/rustls-mbedcrypto-provider/src/kx.rs @@ -8,7 +8,6 @@ use super::agreement; use crate::error::mbedtls_err_to_rustls_general_error; -use crate::log::error; use alloc::boxed::Box; use alloc::fmt; use alloc::format; @@ -42,15 +41,12 @@ impl fmt::Debug for KxGroup { } impl SupportedKxGroup for KxGroup { - fn start(&self) -> Result, rustls::crypto::GetRandomFailed> { + fn start(&self) -> Result, Error> { let mut pk = PkMbed::generate_ec( &mut super::rng::rng_new().ok_or(rustls::crypto::GetRandomFailed)?, self.agreement_algorithm.group_id, ) - .map_err(|_err| { - error!("Encountered error when generating ec key, mbedtls error: {}", _err); - rustls::crypto::GetRandomFailed - })?; + .map_err(|err| rustls::Error::General(format!("Encountered error when generating ec key, mbedtls error: {}", err)))?; fn get_key_pair(pk: &mut PkMbed, kx_group: &KxGroup) -> Result { let group = EcGroup::new(kx_group.agreement_algorithm.group_id)?; @@ -68,10 +64,7 @@ impl SupportedKxGroup for KxGroup { match get_key_pair(&mut pk, self) { Ok(group) => Ok(Box::new(group)), - Err(_err) => { - error!("Unexpected mbedtls error: {}", _err); - Err(rustls::crypto::GetRandomFailed) - } + Err(err) => Err(rustls::Error::General(format!("Unexpected mbedtls error: {}", err))), } } diff --git a/rustls-mbedcrypto-provider/src/lib.rs b/rustls-mbedcrypto-provider/src/lib.rs index 65733f9..8182f78 100644 --- a/rustls-mbedcrypto-provider/src/lib.rs +++ b/rustls-mbedcrypto-provider/src/lib.rs @@ -80,6 +80,8 @@ pub(crate) mod hash; pub(crate) mod hmac; pub(crate) mod kx; +/// Message signing interfaces. +pub mod signer; /// TLS1.2 ciphersuites implementation. #[cfg(feature = "tls12")] pub mod tls12; @@ -137,6 +139,17 @@ impl rustls::crypto::CryptoProvider for Mbedtls { fn default_kx_groups(&self) -> &'static [&'static dyn rustls::crypto::SupportedKxGroup] { ALL_KX_GROUPS } + + fn load_private_key( + &self, + _key_der: pki_types::PrivateKeyDer<'static>, + ) -> Result, rustls::Error> { + todo!() + } + + fn signature_verification_algorithms(&self) -> rustls::WebPkiSupportedAlgorithms { + todo!() + } } /// The cipher suite configuration that an application should use by default. diff --git a/rustls-mbedcrypto-provider/src/signer.rs b/rustls-mbedcrypto-provider/src/signer.rs new file mode 100644 index 0000000..407c520 --- /dev/null +++ b/rustls-mbedcrypto-provider/src/signer.rs @@ -0,0 +1,111 @@ +use alloc::vec; +use alloc::{boxed::Box, sync::Arc, vec::Vec}; +use core::fmt::Debug; +use mbedtls::pk::ECDSA_MAX_LEN; +use std::sync::Mutex; +use utils::error::mbedtls_err_into_rustls_err; +use utils::hash::{buffer_for_hash_type, rustls_signature_scheme_to_mbedtls_hash_type}; +use utils::pk::{rustls_signature_scheme_to_mbedtls_pk_options, rustls_signature_scheme_to_mbedtls_pk_type}; + +/// +struct MbedTlsSigner(Arc>, rustls::SignatureScheme); + +impl Debug for MbedTlsSigner { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_tuple("MbedTlsSigner") + .field(&"Arc>") + .field(&self.1) + .finish() + } +} + +impl rustls::sign::Signer for MbedTlsSigner { + fn sign(&self, message: &[u8]) -> Result, rustls::Error> { + let hash_type = rustls_signature_scheme_to_mbedtls_hash_type(self.1); + let mut hash = buffer_for_hash_type(hash_type).ok_or_else(|| rustls::Error::General("unexpected hash type".into()))?; + let hash_size = mbedtls::hash::Md::hash(hash_type, message, &mut hash).map_err(mbedtls_err_into_rustls_err)?; + + let mut pk = self + .0 + .lock() + .expect("poisoned PK lock!"); + if let Some(opts) = rustls_signature_scheme_to_mbedtls_pk_options(self.1) { + pk.set_options(opts); + } + + fn sig_len_for_pk(pk: &mbedtls::pk::Pk) -> usize { + match pk.pk_type() { + mbedtls::pk::Type::Eckey | mbedtls::pk::Type::EckeyDh | mbedtls::pk::Type::Ecdsa => ECDSA_MAX_LEN, + _ => pk.len() / 8, + } + } + let mut sig = vec![0; sig_len_for_pk(&pk)]; + let sig_len = pk + .sign( + hash_type, + &hash[..hash_size], + &mut sig, + &mut crate::rng::rng_new().ok_or(rustls::Error::FailedToGetRandomBytes)?, + ) + .map_err(mbedtls_err_into_rustls_err)?; + sig.truncate(sig_len); + Ok(sig) + } + + fn scheme(&self) -> rustls::SignatureScheme { + self.1 + } +} + +/// A [`SigningKey`] implemented by using [`mbedtls`] +/// +/// [`SigningKey`]: rustls::sign::SigningKey +pub struct MbedTlsPkSigningKey(pub Arc>); + +impl Debug for MbedTlsPkSigningKey { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_tuple("MbedTlsPkSigningKey") + .field(&"Arc>") + .finish() + } +} + +impl rustls::sign::SigningKey for MbedTlsPkSigningKey { + fn choose_scheme(&self, offered: &[rustls::SignatureScheme]) -> Option> { + for scheme in offered { + let scheme_type = rustls_signature_scheme_to_mbedtls_pk_type(scheme); + if let Some(scheme_type) = scheme_type { + if scheme_type + == self + .0 + .lock() + .expect("poisoned pk lock") + .pk_type() + { + let signer = MbedTlsSigner(self.0.clone(), *scheme); + return Some(Box::new(signer)); + } + } + } + None + } + + fn algorithm(&self) -> rustls::SignatureAlgorithm { + use rustls::SignatureAlgorithm; + match self + .0 + .lock() + .expect("poisoned pk lock") + .pk_type() + { + mbedtls::pk::Type::Rsa => SignatureAlgorithm::RSA, + mbedtls::pk::Type::Ecdsa => SignatureAlgorithm::ECDSA, + mbedtls::pk::Type::RsassaPss => SignatureAlgorithm::RSA, + mbedtls::pk::Type::Eckey => SignatureAlgorithm::ECDSA, + mbedtls::pk::Type::RsaAlt => SignatureAlgorithm::DSA, + mbedtls::pk::Type::EckeyDh => SignatureAlgorithm::Anonymous, + mbedtls::pk::Type::Custom => SignatureAlgorithm::Anonymous, + mbedtls::pk::Type::None => SignatureAlgorithm::Anonymous, + } + } +} diff --git a/rustls-mbedcrypto-provider/src/tls12.rs b/rustls-mbedcrypto-provider/src/tls12.rs index 8980e95..781c699 100644 --- a/rustls-mbedcrypto-provider/src/tls12.rs +++ b/rustls-mbedcrypto-provider/src/tls12.rs @@ -10,7 +10,6 @@ use alloc::boxed::Box; use alloc::vec::Vec; use mbedtls::cipher::raw::{CipherId, CipherMode, CipherType}; use mbedtls::cipher::{Authenticated, Cipher, Decryption, Encryption, Fresh}; -use rustls::cipher_suite::CipherSuiteCommon; use rustls::crypto::cipher::{ make_tls12_aad, AeadKey, BorrowedPlainMessage, Iv, KeyBlockShape, MessageDecrypter, MessageEncrypter, Nonce, OpaqueMessage, PlainMessage, Tls12AeadAlgorithm, UnsupportedOperationError, NONCE_LEN, @@ -20,7 +19,9 @@ use rustls::crypto::KeyExchangeAlgorithm; use super::aead::{self, Algorithm, AES128_GCM, AES256_GCM}; use alloc::string::String; -use rustls::{CipherSuite, ConnectionTrafficSecrets, Error, SignatureScheme, SupportedCipherSuite, Tls12CipherSuite}; +use rustls::{ + CipherSuite, CipherSuiteCommon, ConnectionTrafficSecrets, Error, SignatureScheme, SupportedCipherSuite, Tls12CipherSuite, +}; pub(crate) const GCM_FIXED_IV_LEN: usize = 4; pub(crate) const GCM_EXPLICIT_NONCE_LEN: usize = 8; diff --git a/rustls-mbedcrypto-provider/src/tls13.rs b/rustls-mbedcrypto-provider/src/tls13.rs index 23137c1..a008f85 100644 --- a/rustls-mbedcrypto-provider/src/tls13.rs +++ b/rustls-mbedcrypto-provider/src/tls13.rs @@ -12,7 +12,6 @@ use alloc::string::String; use alloc::vec::Vec; use mbedtls::cipher::raw::CipherType; use mbedtls::cipher::{Authenticated, Cipher, Decryption, Encryption, Fresh}; -use rustls::cipher_suite::CipherSuiteCommon; use rustls::crypto::cipher::{ make_tls13_aad, AeadKey, BorrowedPlainMessage, Iv, MessageDecrypter, MessageEncrypter, Nonce, OpaqueMessage, PlainMessage, Tls13AeadAlgorithm, UnsupportedOperationError, @@ -20,7 +19,8 @@ use rustls::crypto::cipher::{ use rustls::crypto::tls13::HkdfUsingHmac; use rustls::internal::msgs::codec::Codec; use rustls::{ - CipherSuite, ConnectionTrafficSecrets, ContentType, Error, ProtocolVersion, SupportedCipherSuite, Tls13CipherSuite, + CipherSuite, CipherSuiteCommon, ConnectionTrafficSecrets, ContentType, Error, ProtocolVersion, SupportedCipherSuite, + Tls13CipherSuite, }; /// The TLS1.3 ciphersuite TLS_CHACHA20_POLY1305_SHA256 diff --git a/rustls-mbedpki-provider/Cargo.toml b/rustls-mbedpki-provider/Cargo.toml index ffe9e67..aa7f6a1 100644 --- a/rustls-mbedpki-provider/Cargo.toml +++ b/rustls-mbedpki-provider/Cargo.toml @@ -23,6 +23,7 @@ chrono = "0.4" pki-types = { package = "rustls-pki-types", version = "0.2.1", features = [ "std", ] } +utils = { package = "rustls-mbedtls-provider-utils", path = "../rustls-mbedtls-provider-utils", version = "0.1.0-alpha.1" } [target.'cfg(target_env = "msvc")'.dependencies] # mbedtls need feature `time` to build when targeting msvc diff --git a/rustls-mbedpki-provider/src/client_cert_verifier.rs b/rustls-mbedpki-provider/src/client_cert_verifier.rs index 10ae1ab..d1ba8aa 100644 --- a/rustls-mbedpki-provider/src/client_cert_verifier.rs +++ b/rustls-mbedpki-provider/src/client_cert_verifier.rs @@ -5,18 +5,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::sync::Arc; - +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec; +use alloc::vec::Vec; use chrono::NaiveDateTime; use pki_types::{CertificateDer, UnixTime}; use rustls::{ server::danger::{ClientCertVerified, ClientCertVerifier}, DistinguishedName, }; +use utils::error::mbedtls_err_into_rustls_err_with_error_msg; use crate::{ - mbedtls_err_into_rustls_err, mbedtls_err_into_rustls_err_with_error_msg, rustls_cert_to_mbedtls_cert, - verify_certificates_active, verify_tls_signature, CertActiveCheck, + mbedtls_err_into_rustls_err, rustls_cert_to_mbedtls_cert, verify_certificates_active, verify_tls_signature, CertActiveCheck, }; /// A [`rustls`] [`ClientCertVerifier`] implemented using the PKI functionality of @@ -29,6 +31,17 @@ pub struct MbedTlsClientCertVerifier { cert_active_check: CertActiveCheck, } +impl std::fmt::Debug for MbedTlsClientCertVerifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MbedTlsClientCertVerifier") + .field("trusted_cas", &"..") + .field("root_subjects", &self.root_subjects) + .field("verify_callback", &"..") + .field("cert_active_check", &self.cert_active_check) + .finish() + } +} + impl MbedTlsClientCertVerifier { /// Constructs a new [`MbedTlsClientCertVerifier`] object given the provided trusted certificate authority /// certificates. diff --git a/rustls-mbedpki-provider/src/lib.rs b/rustls-mbedpki-provider/src/lib.rs index d2af9b6..4f769db 100644 --- a/rustls-mbedpki-provider/src/lib.rs +++ b/rustls-mbedpki-provider/src/lib.rs @@ -31,12 +31,21 @@ // Enable documentation for all features on docs.rs #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(bench, feature(test))] +#![cfg_attr(not(test), no_std)] + +extern crate alloc; + +// This `extern crate` plus the `#![no_std]` attribute changes the default prelude from +// `std::prelude` to `core::prelude`. That forces one to _explicitly_ import (`use`) everything that +// is in `std::prelude` but not in `core::prelude`. This helps maintain no-std support as even +// developers that are not interested in, or aware of, no-std support and / or that never run +// `cargo build --no-default-features` locally will get errors when they rely on `std::prelude` API. +#[cfg(not(test))] +extern crate std; use chrono::NaiveDateTime; -use mbedtls::hash::Type; use pki_types::CertificateDer; use rustls::SignatureScheme; -use std::sync::Arc; #[cfg(test)] mod tests_common; @@ -52,6 +61,7 @@ pub mod server_cert_verifier; pub use client_cert_verifier::MbedTlsClientCertVerifier; pub use server_cert_verifier::MbedTlsServerCertVerifier; +use utils::error::mbedtls_err_into_rustls_err; /// A config about whether to check certificate validity period #[derive(Debug, PartialEq, Eq, Clone, Default)] @@ -62,17 +72,6 @@ pub struct CertActiveCheck { pub ignore_not_active_yet: bool, } -/// Helper function to convert a [`CertificateDer`] to [`mbedtls::x509::Certificate`] -pub fn rustls_cert_to_mbedtls_cert(cert: &CertificateDer) -> mbedtls::Result> { - let cert = mbedtls::x509::Certificate::from_der(cert)?; - Ok(cert) -} - -/// Converts an `mbedtls::Error` into a `rustls::Error` -pub fn mbedtls_err_into_rustls_err(err: mbedtls::Error) -> rustls::Error { - mbedtls_err_into_rustls_err_with_error_msg(err, "") -} - /// All supported signature schemas pub const SUPPORTED_SIGNATURE_SCHEMA: [SignatureScheme; 9] = [ rustls::SignatureScheme::RSA_PSS_SHA512, @@ -86,129 +85,6 @@ pub const SUPPORTED_SIGNATURE_SCHEMA: [SignatureScheme; 9] = [ rustls::SignatureScheme::RSA_PSS_SHA256, ]; -/// Converts an `mbedtls::Error` into a `rustls::Error`; may include the provided `msg` in the -/// returned error (e.g., if returning a `rustls::Error::General` error). -pub fn mbedtls_err_into_rustls_err_with_error_msg(err: mbedtls::Error, msg: &str) -> rustls::Error { - match err { - mbedtls::Error::X509InvalidSignature | - mbedtls::Error::RsaVerifyFailed => rustls::Error::InvalidCertificate(rustls::CertificateError::BadSignature), - - mbedtls::Error::X509CertUnknownFormat | - mbedtls::Error::X509BadInputData => rustls::Error::InvalidCertificate(rustls::CertificateError::BadEncoding), - - // mbedtls::Error::X509AllocFailed | - mbedtls::Error::X509BufferTooSmall | - mbedtls::Error::X509CertVerifyFailed | - mbedtls::Error::X509FatalError | - mbedtls::Error::X509FeatureUnavailable | - // mbedtls::Error::X509FileIoError | - mbedtls::Error::X509InvalidAlg | - mbedtls::Error::X509InvalidDate | - mbedtls::Error::X509InvalidExtensions | - mbedtls::Error::X509InvalidFormat | - mbedtls::Error::X509InvalidSerial | - mbedtls::Error::X509InvalidVersion | - mbedtls::Error::X509SigMismatch | - mbedtls::Error::X509UnknownOid | - mbedtls::Error::X509UnknownSigAlg | - mbedtls::Error::X509UnknownVersion => rustls::Error::InvalidCertificate(rustls::CertificateError::Other(Arc::new(err))), - - mbedtls::Error::X509InvalidName => rustls::Error::InvalidCertificate(rustls::CertificateError::NotValidForName), - - _ => rustls::Error::General(format!("{err}{sep}{msg}", sep = if msg.is_empty() {""} else {"\n"})), - } -} - -/// Helper function to convert rustls [`SignatureScheme`] to mbedtls [`Type`] -pub fn rustls_signature_scheme_to_mbedtls_hash_type(signature_scheme: SignatureScheme) -> Type { - match signature_scheme { - SignatureScheme::RSA_PKCS1_SHA1 => Type::Sha1, - SignatureScheme::ECDSA_SHA1_Legacy => Type::Sha1, - SignatureScheme::RSA_PKCS1_SHA256 => Type::Sha256, - SignatureScheme::ECDSA_NISTP256_SHA256 => Type::Sha256, - SignatureScheme::RSA_PKCS1_SHA384 => Type::Sha384, - SignatureScheme::ECDSA_NISTP384_SHA384 => Type::Sha384, - SignatureScheme::RSA_PKCS1_SHA512 => Type::Sha512, - SignatureScheme::ECDSA_NISTP521_SHA512 => Type::Sha512, - SignatureScheme::RSA_PSS_SHA256 => Type::Sha256, - SignatureScheme::RSA_PSS_SHA384 => Type::Sha384, - SignatureScheme::RSA_PSS_SHA512 => Type::Sha512, - SignatureScheme::ED25519 => Type::None, - SignatureScheme::ED448 => Type::None, - SignatureScheme::Unknown(_) => Type::None, - _ => Type::None, - } -} - -/// Helper function to convert rustls [`SignatureScheme`] to mbedtls [`mbedtls::pk::Options`] -pub fn rustls_signature_scheme_to_mbedtls_pk_options(signature_scheme: SignatureScheme) -> Option { - use mbedtls::pk::Options; - use mbedtls::pk::RsaPadding; - // reference: https://www.rfc-editor.org/rfc/rfc8446.html#section-4.2.3 - match signature_scheme { - SignatureScheme::RSA_PKCS1_SHA1 => None, - SignatureScheme::ECDSA_SHA1_Legacy => None, - SignatureScheme::ECDSA_NISTP256_SHA256 => None, - SignatureScheme::ECDSA_NISTP384_SHA384 => None, - SignatureScheme::ECDSA_NISTP521_SHA512 => None, - SignatureScheme::RSA_PKCS1_SHA256 | SignatureScheme::RSA_PKCS1_SHA384 | SignatureScheme::RSA_PKCS1_SHA512 => { - Some(Options::Rsa { padding: RsaPadding::Pkcs1V15 }) - } - SignatureScheme::RSA_PSS_SHA256 => Some(Options::Rsa { padding: RsaPadding::Pkcs1V21 { mgf: Type::Sha256 } }), - SignatureScheme::RSA_PSS_SHA384 => Some(Options::Rsa { padding: RsaPadding::Pkcs1V21 { mgf: Type::Sha384 } }), - SignatureScheme::RSA_PSS_SHA512 => Some(Options::Rsa { padding: RsaPadding::Pkcs1V21 { mgf: Type::Sha512 } }), - SignatureScheme::ED25519 => None, - SignatureScheme::ED448 => None, - SignatureScheme::Unknown(_) => None, - _ => None, - } -} - -/// Helper function to convert rustls [`SignatureScheme`] to mbedtls [`mbedtls::pk::EcGroupId`] -pub fn rustls_signature_scheme_to_mbedtls_curve_id(signature_scheme: SignatureScheme) -> mbedtls::pk::EcGroupId { - // reference: https://www.rfc-editor.org/rfc/rfc8446.html#section-4.2.3 - use mbedtls::pk::EcGroupId; - match signature_scheme { - SignatureScheme::ECDSA_NISTP256_SHA256 => EcGroupId::SecP256R1, - SignatureScheme::ECDSA_NISTP384_SHA384 => EcGroupId::SecP384R1, - SignatureScheme::ECDSA_NISTP521_SHA512 => EcGroupId::SecP521R1, - SignatureScheme::ECDSA_SHA1_Legacy => EcGroupId::None, - SignatureScheme::RSA_PKCS1_SHA1 => EcGroupId::None, - SignatureScheme::RSA_PKCS1_SHA256 => EcGroupId::None, - SignatureScheme::RSA_PKCS1_SHA384 => EcGroupId::None, - SignatureScheme::RSA_PKCS1_SHA512 => EcGroupId::None, - SignatureScheme::RSA_PSS_SHA256 => EcGroupId::None, - SignatureScheme::RSA_PSS_SHA384 => EcGroupId::None, - SignatureScheme::RSA_PSS_SHA512 => EcGroupId::None, - SignatureScheme::ED25519 => EcGroupId::None, - SignatureScheme::ED448 => EcGroupId::None, - SignatureScheme::Unknown(_) => EcGroupId::None, - _ => EcGroupId::None, - } -} - -/// Returns the size of the message digest given the hash type. -fn hash_size_bytes(hash_type: Type) -> Option { - match hash_type { - mbedtls::hash::Type::None => None, - mbedtls::hash::Type::Md2 => Some(16), - mbedtls::hash::Type::Md4 => Some(16), - mbedtls::hash::Type::Md5 => Some(16), - mbedtls::hash::Type::Sha1 => Some(20), - mbedtls::hash::Type::Sha224 => Some(28), - mbedtls::hash::Type::Sha256 => Some(32), - mbedtls::hash::Type::Sha384 => Some(48), - mbedtls::hash::Type::Sha512 => Some(64), - mbedtls::hash::Type::Ripemd => Some(20), // this is MD_RIPEMD160 - } -} - -/// Returns the a ready to use empty [`Vec`] for the message digest with given hash type. -pub fn buffer_for_hash_type(hash_type: Type) -> Option> { - let size = hash_size_bytes(hash_type)?; - Some(vec![0; size]) -} - /// Verifies that certificates are active, i.e., `now` is between not_before and not_after for /// each certificate fn verify_certificates_active<'a>( @@ -259,11 +135,11 @@ fn verify_tls_signature( ) -> Result { let mut cert = rustls_cert_to_mbedtls_cert(cert).map_err(mbedtls_err_into_rustls_err)?; let pk = cert.public_key_mut(); - let hash_type = rustls_signature_scheme_to_mbedtls_hash_type(dss.scheme); + let hash_type = utils::hash::rustls_signature_scheme_to_mbedtls_hash_type(dss.scheme); // for tls 1.3, we need to verify the advertised curve in signaure scheme matches the public key if is_tls13 { - let signature_curve = rustls_signature_scheme_to_mbedtls_curve_id(dss.scheme); + let signature_curve = utils::pk::rustls_signature_scheme_to_mbedtls_curve_id(dss.scheme); match signature_curve { mbedtls::pk::EcGroupId::None => (), _ => { @@ -279,14 +155,21 @@ fn verify_tls_signature( } } - if let Some(opts) = rustls_signature_scheme_to_mbedtls_pk_options(dss.scheme) { + if let Some(opts) = utils::pk::rustls_signature_scheme_to_mbedtls_pk_options(dss.scheme) { pk.set_options(opts); } - let mut hash = buffer_for_hash_type(hash_type).ok_or_else(|| rustls::Error::General("unexpected hash type".into()))?; + let mut hash = + utils::hash::buffer_for_hash_type(hash_type).ok_or_else(|| rustls::Error::General("unexpected hash type".into()))?; let hash_size = mbedtls::hash::Md::hash(hash_type, message, &mut hash).map_err(mbedtls_err_into_rustls_err)?; pk.verify(hash_type, &hash[..hash_size], dss.signature()) .map_err(mbedtls_err_into_rustls_err)?; Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) } + +/// Helper function to convert a [`CertificateDer`] to [`mbedtls::x509::Certificate`] +pub fn rustls_cert_to_mbedtls_cert(cert: &CertificateDer) -> mbedtls::Result> { + let cert = mbedtls::x509::Certificate::from_der(cert)?; + Ok(cert) +} diff --git a/rustls-mbedpki-provider/src/server_cert_verifier.rs b/rustls-mbedpki-provider/src/server_cert_verifier.rs index 8d23718..b90b8fd 100644 --- a/rustls-mbedpki-provider/src/server_cert_verifier.rs +++ b/rustls-mbedpki-provider/src/server_cert_verifier.rs @@ -5,18 +5,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::sync::Arc; - +use alloc::string::String; +use alloc::string::ToString; +use alloc::sync::Arc; +use alloc::vec; +use alloc::vec::Vec; use chrono::NaiveDateTime; use pki_types::{CertificateDer, UnixTime}; use rustls::{ client::danger::{ServerCertVerified, ServerCertVerifier}, ServerName, }; +use utils::error::mbedtls_err_into_rustls_err_with_error_msg; use crate::{ - mbedtls_err_into_rustls_err, mbedtls_err_into_rustls_err_with_error_msg, rustls_cert_to_mbedtls_cert, - verify_certificates_active, verify_tls_signature, CertActiveCheck, + mbedtls_err_into_rustls_err, rustls_cert_to_mbedtls_cert, verify_certificates_active, verify_tls_signature, CertActiveCheck, }; /// A [`rustls`] [`ServerCertVerifier`] implemented using the PKI functionality of @@ -27,6 +30,16 @@ pub struct MbedTlsServerCertVerifier { cert_active_check: CertActiveCheck, } +impl std::fmt::Debug for MbedTlsServerCertVerifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MbedTlsServerCertVerifier") + .field("trusted_cas", &"..") + .field("verify_callback", &"..") + .field("cert_active_check", &self.cert_active_check) + .finish() + } +} + impl MbedTlsServerCertVerifier { /// Constructs a new [`MbedTlsServerCertVerifier`] object given the provided trusted certificate authority /// certificates. diff --git a/rustls-mbedtls-provider-utils/Cargo.toml b/rustls-mbedtls-provider-utils/Cargo.toml new file mode 100644 index 0000000..5d1033f --- /dev/null +++ b/rustls-mbedtls-provider-utils/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "rustls-mbedtls-provider-utils" +version = "0.1.0-alpha.1" +edition = "2021" +license = "MPL-2.0" +description = "Utility code used in mbedtls based provider for rustls." +homepage = "https://github.com/fortanix/rustls-mbedtls-provider" +repository = "https://github.com/fortanix/rustls-mbedtls-provider" +readme = "../README.md" +authors = ["Fortanix Inc."] +categories = ["network-programming", "cryptography"] +resolver = "2" + +[dependencies] +rustls = { version = "0.22.0-alpha.4", default-features = false } +mbedtls = { version = "0.12.0-alpha.2", default-features = false, features = [ + "std", +] } +pki-types = { package = "rustls-pki-types", version = "0.2.1", features = [ + "std", +] } + +[target.'cfg(target_env = "msvc")'.dependencies] +# mbedtls need feature `time` to build when targeting msvc +mbedtls = { version = "0.12.0-alpha.2", default-features = false, features = [ + "std", + "time", +] } diff --git a/rustls-mbedtls-provider-utils/src/error.rs b/rustls-mbedtls-provider-utils/src/error.rs new file mode 100644 index 0000000..e9a8a21 --- /dev/null +++ b/rustls-mbedtls-provider-utils/src/error.rs @@ -0,0 +1,39 @@ +use alloc::{format, sync::Arc}; + +/// Converts an `mbedtls::Error` into a `rustls::Error` +pub fn mbedtls_err_into_rustls_err(err: mbedtls::Error) -> rustls::Error { + mbedtls_err_into_rustls_err_with_error_msg(err, "") +} + +/// Converts an `mbedtls::Error` into a `rustls::Error`; may include the provided `msg` in the +/// returned error (e.g., if returning a `rustls::Error::General` error). +pub fn mbedtls_err_into_rustls_err_with_error_msg(err: mbedtls::Error, msg: &str) -> rustls::Error { + match err { + mbedtls::Error::X509InvalidSignature | + mbedtls::Error::RsaVerifyFailed => rustls::Error::InvalidCertificate(rustls::CertificateError::BadSignature), + + mbedtls::Error::X509CertUnknownFormat | + mbedtls::Error::X509BadInputData => rustls::Error::InvalidCertificate(rustls::CertificateError::BadEncoding), + + // mbedtls::Error::X509AllocFailed | + mbedtls::Error::X509BufferTooSmall | + mbedtls::Error::X509CertVerifyFailed | + mbedtls::Error::X509FatalError | + mbedtls::Error::X509FeatureUnavailable | + // mbedtls::Error::X509FileIoError | + mbedtls::Error::X509InvalidAlg | + mbedtls::Error::X509InvalidDate | + mbedtls::Error::X509InvalidExtensions | + mbedtls::Error::X509InvalidFormat | + mbedtls::Error::X509InvalidSerial | + mbedtls::Error::X509InvalidVersion | + mbedtls::Error::X509SigMismatch | + mbedtls::Error::X509UnknownOid | + mbedtls::Error::X509UnknownSigAlg | + mbedtls::Error::X509UnknownVersion => rustls::Error::InvalidCertificate(rustls::CertificateError::Other(Arc::new(err))), + + mbedtls::Error::X509InvalidName => rustls::Error::InvalidCertificate(rustls::CertificateError::NotValidForName), + + _ => rustls::Error::General(format!("{err}{sep}{msg}", sep = if msg.is_empty() {""} else {"\n"})), + } +} diff --git a/rustls-mbedtls-provider-utils/src/hash.rs b/rustls-mbedtls-provider-utils/src/hash.rs new file mode 100644 index 0000000..5ee68d3 --- /dev/null +++ b/rustls-mbedtls-provider-utils/src/hash.rs @@ -0,0 +1,47 @@ +use alloc::vec; +use alloc::vec::Vec; +use mbedtls::hash::Type; +use rustls::SignatureScheme; + +/// Returns the size of the message digest given the hash type. +fn hash_size_bytes(hash_type: Type) -> Option { + match hash_type { + Type::None => None, + Type::Md2 => Some(16), + Type::Md4 => Some(16), + Type::Md5 => Some(16), + Type::Sha1 => Some(20), + Type::Sha224 => Some(28), + Type::Sha256 => Some(32), + Type::Sha384 => Some(48), + Type::Sha512 => Some(64), + Type::Ripemd => Some(20), // this is MD_RIPEMD160 + } +} + +/// Returns the a ready to use empty [`Vec`] for the message digest with given hash type. +pub fn buffer_for_hash_type(hash_type: Type) -> Option> { + let size = hash_size_bytes(hash_type)?; + Some(vec![0; size]) +} + +/// Helper function to convert rustls [`SignatureScheme`] to mbedtls [`Type`] +pub fn rustls_signature_scheme_to_mbedtls_hash_type(signature_scheme: SignatureScheme) -> Type { + match signature_scheme { + SignatureScheme::RSA_PKCS1_SHA1 => Type::Sha1, + SignatureScheme::ECDSA_SHA1_Legacy => Type::Sha1, + SignatureScheme::RSA_PKCS1_SHA256 => Type::Sha256, + SignatureScheme::ECDSA_NISTP256_SHA256 => Type::Sha256, + SignatureScheme::RSA_PKCS1_SHA384 => Type::Sha384, + SignatureScheme::ECDSA_NISTP384_SHA384 => Type::Sha384, + SignatureScheme::RSA_PKCS1_SHA512 => Type::Sha512, + SignatureScheme::ECDSA_NISTP521_SHA512 => Type::Sha512, + SignatureScheme::RSA_PSS_SHA256 => Type::Sha256, + SignatureScheme::RSA_PSS_SHA384 => Type::Sha384, + SignatureScheme::RSA_PSS_SHA512 => Type::Sha512, + SignatureScheme::ED25519 => Type::None, + SignatureScheme::ED448 => Type::None, + SignatureScheme::Unknown(_) => Type::None, + _ => Type::None, + } +} diff --git a/rustls-mbedtls-provider-utils/src/lib.rs b/rustls-mbedtls-provider-utils/src/lib.rs new file mode 100644 index 0000000..0075274 --- /dev/null +++ b/rustls-mbedtls-provider-utils/src/lib.rs @@ -0,0 +1,40 @@ +//! This crate provides common util code used in `rustls-mbedcrypto-provider` and `rustls-mbedpki-provider` + +// Require docs for public APIs, deny unsafe code, etc. +#![forbid(unsafe_code, unused_must_use)] +#![cfg_attr(not(bench), forbid(unstable_features))] +#![deny( + clippy::alloc_instead_of_core, + clippy::clone_on_ref_ptr, + clippy::std_instead_of_core, + clippy::use_self, + clippy::upper_case_acronyms, + trivial_casts, + trivial_numeric_casts, + missing_docs, + unreachable_pub, + unused_import_braces, + unused_extern_crates, + unused_qualifications +)] +// Enable documentation for all features on docs.rs +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(bench, feature(test))] +#![cfg_attr(not(test), no_std)] + +extern crate alloc; + +// This `extern crate` plus the `#![no_std]` attribute changes the default prelude from +// `std::prelude` to `core::prelude`. That forces one to _explicitly_ import (`use`) everything that +// is in `std::prelude` but not in `core::prelude`. This helps maintain no-std support as even +// developers that are not interested in, or aware of, no-std support and / or that never run +// `cargo build --no-default-features` locally will get errors when they rely on `std::prelude` API. +#[cfg(not(test))] +extern crate std; + +/// Utility code related to error types in [`mbedtls::error`] and [`rustls::error`] +pub mod error; +/// Utility code related to [`mbedtls::hash`] types +pub mod hash; +/// Utility code related to [`mbedtls::pk`] types +pub mod pk; diff --git a/rustls-mbedtls-provider-utils/src/pk.rs b/rustls-mbedtls-provider-utils/src/pk.rs new file mode 100644 index 0000000..41be1e7 --- /dev/null +++ b/rustls-mbedtls-provider-utils/src/pk.rs @@ -0,0 +1,106 @@ +use mbedtls::pk::Type; +use rustls::SignatureScheme; + +/// Helper function to convert [`SignatureScheme`] to [`Type`] +pub fn rustls_signature_scheme_to_mbedtls_pk_type(scheme: &SignatureScheme) -> Option { + match scheme { + SignatureScheme::RSA_PKCS1_SHA1 + | SignatureScheme::RSA_PKCS1_SHA256 + | SignatureScheme::RSA_PKCS1_SHA384 + | SignatureScheme::RSA_PKCS1_SHA512 + | SignatureScheme::RSA_PSS_SHA384 + | SignatureScheme::RSA_PSS_SHA256 + | SignatureScheme::RSA_PSS_SHA512 => Some(Type::Rsa), + SignatureScheme::ECDSA_SHA1_Legacy + | SignatureScheme::ECDSA_NISTP256_SHA256 + | SignatureScheme::ECDSA_NISTP384_SHA384 + | SignatureScheme::ECDSA_NISTP521_SHA512 => Some(Type::Ecdsa), + SignatureScheme::ED25519 => None, + SignatureScheme::ED448 => None, + SignatureScheme::Unknown(_) => None, + _ => None, + } +} + +/// Helper function to get mbedtls supported [`SignatureScheme`] from given [`SignatureScheme`] slice based on given [`Type`] +pub fn get_pk_supported_scheme(pk_type: &Type, offered: &[SignatureScheme]) -> Option { + for scheme in offered { + let scheme_type = rustls_signature_scheme_to_mbedtls_pk_type(scheme); + if let Some(scheme_type) = scheme_type { + if scheme_type == *pk_type { + return Some(*scheme); + } + } + } + return None; +} + +/// Helper function to get the corresponding [`rustls::SignatureAlgorithm`] of given [`mbedtls::pk::Pk`] +pub fn get_signature_algo_from_pk(pk: &mbedtls::pk::Pk) -> rustls::SignatureAlgorithm { + let pk_type = pk.pk_type(); + match pk_type { + Type::Rsa | Type::RsaAlt | Type::RsassaPss => rustls::SignatureAlgorithm::RSA, + Type::Ecdsa => rustls::SignatureAlgorithm::ECDSA, + Type::Eckey | Type::EckeyDh => match pk.curve().expect("validated") { + // TODO: ED25519 maybe not supported yet or not supported by mbedtls + mbedtls::pk::EcGroupId::Curve25519 => rustls::SignatureAlgorithm::ED25519, + // TODO: ED448 maybe not supported yet or not supported by mbedtls + mbedtls::pk::EcGroupId::Curve448 => rustls::SignatureAlgorithm::ED448, + _ => rustls::SignatureAlgorithm::Unknown(u8::MAX), + }, + _ => rustls::SignatureAlgorithm::Unknown(u8::MAX), + } +} + +/// Helper function to convert rustls [`SignatureScheme`] to mbedtls [`mbedtls::pk::Options`] +pub fn rustls_signature_scheme_to_mbedtls_pk_options(signature_scheme: SignatureScheme) -> Option { + use mbedtls::pk::Options; + use mbedtls::pk::RsaPadding; + // reference: https://www.rfc-editor.org/rfc/rfc8446.html#section-4.2.3 + match signature_scheme { + SignatureScheme::RSA_PKCS1_SHA1 => None, + SignatureScheme::ECDSA_SHA1_Legacy => None, + SignatureScheme::ECDSA_NISTP256_SHA256 => None, + SignatureScheme::ECDSA_NISTP384_SHA384 => None, + SignatureScheme::ECDSA_NISTP521_SHA512 => None, + SignatureScheme::RSA_PKCS1_SHA256 | SignatureScheme::RSA_PKCS1_SHA384 | SignatureScheme::RSA_PKCS1_SHA512 => { + Some(Options::Rsa { padding: RsaPadding::Pkcs1V15 }) + } + SignatureScheme::RSA_PSS_SHA256 => { + Some(Options::Rsa { padding: RsaPadding::Pkcs1V21 { mgf: mbedtls::hash::Type::Sha256 } }) + } + SignatureScheme::RSA_PSS_SHA384 => { + Some(Options::Rsa { padding: RsaPadding::Pkcs1V21 { mgf: mbedtls::hash::Type::Sha384 } }) + } + SignatureScheme::RSA_PSS_SHA512 => { + Some(Options::Rsa { padding: RsaPadding::Pkcs1V21 { mgf: mbedtls::hash::Type::Sha512 } }) + } + SignatureScheme::ED25519 => None, + SignatureScheme::ED448 => None, + SignatureScheme::Unknown(_) => None, + _ => None, + } +} + +/// Helper function to convert rustls [`SignatureScheme`] to mbedtls [`mbedtls::pk::EcGroupId`] +pub fn rustls_signature_scheme_to_mbedtls_curve_id(signature_scheme: SignatureScheme) -> mbedtls::pk::EcGroupId { + // reference: https://www.rfc-editor.org/rfc/rfc8446.html#section-4.2.3 + use mbedtls::pk::EcGroupId; + match signature_scheme { + SignatureScheme::ECDSA_NISTP256_SHA256 => EcGroupId::SecP256R1, + SignatureScheme::ECDSA_NISTP384_SHA384 => EcGroupId::SecP384R1, + SignatureScheme::ECDSA_NISTP521_SHA512 => EcGroupId::SecP521R1, + SignatureScheme::ECDSA_SHA1_Legacy => EcGroupId::None, + SignatureScheme::RSA_PKCS1_SHA1 => EcGroupId::None, + SignatureScheme::RSA_PKCS1_SHA256 => EcGroupId::None, + SignatureScheme::RSA_PKCS1_SHA384 => EcGroupId::None, + SignatureScheme::RSA_PKCS1_SHA512 => EcGroupId::None, + SignatureScheme::RSA_PSS_SHA256 => EcGroupId::None, + SignatureScheme::RSA_PSS_SHA384 => EcGroupId::None, + SignatureScheme::RSA_PSS_SHA512 => EcGroupId::None, + SignatureScheme::ED25519 => EcGroupId::None, + SignatureScheme::ED448 => EcGroupId::None, + SignatureScheme::Unknown(_) => EcGroupId::None, + _ => EcGroupId::None, + } +} From 2857b5f3e9036b7df56b7e2181f46e631c5513a2 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Tue, 14 Nov 2023 17:23:34 -0800 Subject: [PATCH 03/14] feat: add SignatureVerificationAlgorithm --- rustls-mbedcrypto-provider/Cargo.toml | 1 + rustls-mbedcrypto-provider/src/hash.rs | 9 ++ rustls-mbedcrypto-provider/src/lib.rs | 50 +++++++- .../src/{signer.rs => sign.rs} | 1 - .../src/signature_verify_algo.rs | 114 ++++++++++++++++++ rustls-mbedpki-provider/src/lib.rs | 2 +- 6 files changed, 169 insertions(+), 8 deletions(-) rename rustls-mbedcrypto-provider/src/{signer.rs => sign.rs} (99%) create mode 100644 rustls-mbedcrypto-provider/src/signature_verify_algo.rs diff --git a/rustls-mbedcrypto-provider/Cargo.toml b/rustls-mbedcrypto-provider/Cargo.toml index bf6913d..adc0691 100644 --- a/rustls-mbedcrypto-provider/Cargo.toml +++ b/rustls-mbedcrypto-provider/Cargo.toml @@ -20,6 +20,7 @@ log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "0.2.1", features = [ "std", ] } +webpki = { package = "rustls-webpki", version = "0.102.0-alpha.6", features = ["alloc", "std"], default-features = false } utils = { package = "rustls-mbedtls-provider-utils", path = "../rustls-mbedtls-provider-utils", version = "0.1.0-alpha.1" } [target.'cfg(target_env = "msvc")'.dependencies] diff --git a/rustls-mbedcrypto-provider/src/hash.rs b/rustls-mbedcrypto-provider/src/hash.rs index 4b74042..25c15d5 100644 --- a/rustls-mbedcrypto-provider/src/hash.rs +++ b/rustls-mbedcrypto-provider/src/hash.rs @@ -43,6 +43,15 @@ pub(crate) static MBED_SHA_384: Algorithm = Algorithm { output_len: 384 / 8, }; +/// SHA-512 as specified in [FIPS 180-4]. +/// +/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf +pub(crate) static MBED_SHA_512: Algorithm = Algorithm { + hash_algorithm: HashAlgorithm::SHA512, + hash_type: mbedtls::hash::Type::Sha512, + output_len: 512 / 8, +}; + impl hash::Hash for Hash { fn start(&self) -> Box { Box::new(HashContext(MbedHashContext::new(self.0))) diff --git a/rustls-mbedcrypto-provider/src/lib.rs b/rustls-mbedcrypto-provider/src/lib.rs index 8182f78..fcee18e 100644 --- a/rustls-mbedcrypto-provider/src/lib.rs +++ b/rustls-mbedcrypto-provider/src/lib.rs @@ -81,7 +81,9 @@ pub(crate) mod hmac; pub(crate) mod kx; /// Message signing interfaces. -pub mod signer; +pub mod sign; +/// Supported signature verify algorithms +pub mod signature_verify_algo; /// TLS1.2 ciphersuites implementation. #[cfg(feature = "tls12")] pub mod tls12; @@ -89,7 +91,7 @@ pub mod tls12; pub mod tls13; use mbedtls::rng::Random; -use rustls::SupportedCipherSuite; +use rustls::{SignatureScheme, SupportedCipherSuite, WebPkiSupportedAlgorithms}; /// RNG supported by *mbedtls* pub mod rng { @@ -142,13 +144,17 @@ impl rustls::crypto::CryptoProvider for Mbedtls { fn load_private_key( &self, - _key_der: pki_types::PrivateKeyDer<'static>, + key_der: pki_types::PrivateKeyDer<'static>, ) -> Result, rustls::Error> { - todo!() + let pk = mbedtls::pk::Pk::from_private_key(key_der.secret_der(), None) + .map_err(|err| rustls::Error::Other(rustls::OtherError(alloc::sync::Arc::new(err))))?; + Ok(alloc::sync::Arc::new(MbedTlsPkSigningKey(alloc::sync::Arc::new( + std::sync::Mutex::new(pk), + )))) } - fn signature_verification_algorithms(&self) -> rustls::WebPkiSupportedAlgorithms { - todo!() + fn signature_verification_algorithms(&self) -> WebPkiSupportedAlgorithms { + SUPPORTED_SIG_ALGS } } @@ -179,6 +185,37 @@ pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[ tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, ]; +/// A `WebPkiSupportedAlgorithms` value that reflects pki's capabilities when +/// compiled against *mbedtls*. +static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms { + all: &[ + signature_verify_algo::ECDSA_P256_SHA256, + signature_verify_algo::ECDSA_P384_SHA384, + signature_verify_algo::RSA_PKCS1_SHA256, + signature_verify_algo::RSA_PKCS1_SHA384, + signature_verify_algo::RSA_PKCS1_SHA512, + signature_verify_algo::RSA_PSS_SHA256, + signature_verify_algo::RSA_PSS_SHA384, + signature_verify_algo::RSA_PSS_SHA512, + ], + mapping: &[ + ( + SignatureScheme::ECDSA_NISTP384_SHA384, + &[signature_verify_algo::ECDSA_P384_SHA384], + ), + ( + SignatureScheme::ECDSA_NISTP256_SHA256, + &[signature_verify_algo::ECDSA_P256_SHA256], + ), + (SignatureScheme::RSA_PSS_SHA512, &[signature_verify_algo::RSA_PKCS1_SHA512]), + (SignatureScheme::RSA_PSS_SHA384, &[signature_verify_algo::RSA_PKCS1_SHA384]), + (SignatureScheme::RSA_PSS_SHA256, &[signature_verify_algo::RSA_PKCS1_SHA256]), + (SignatureScheme::RSA_PKCS1_SHA512, &[signature_verify_algo::RSA_PSS_SHA512]), + (SignatureScheme::RSA_PKCS1_SHA384, &[signature_verify_algo::RSA_PSS_SHA384]), + (SignatureScheme::RSA_PKCS1_SHA256, &[signature_verify_algo::RSA_PSS_SHA256]), + ], +}; + /// All defined key exchange groups supported by *mbedtls* appear in this module. /// /// [`ALL_KX_GROUPS`] is provided as an array of all of these values. @@ -190,3 +227,4 @@ pub mod kx_group { } pub use kx::ALL_KX_GROUPS; +use sign::MbedTlsPkSigningKey; diff --git a/rustls-mbedcrypto-provider/src/signer.rs b/rustls-mbedcrypto-provider/src/sign.rs similarity index 99% rename from rustls-mbedcrypto-provider/src/signer.rs rename to rustls-mbedcrypto-provider/src/sign.rs index 407c520..8930707 100644 --- a/rustls-mbedcrypto-provider/src/signer.rs +++ b/rustls-mbedcrypto-provider/src/sign.rs @@ -7,7 +7,6 @@ use utils::error::mbedtls_err_into_rustls_err; use utils::hash::{buffer_for_hash_type, rustls_signature_scheme_to_mbedtls_hash_type}; use utils::pk::{rustls_signature_scheme_to_mbedtls_pk_options, rustls_signature_scheme_to_mbedtls_pk_type}; -/// struct MbedTlsSigner(Arc>, rustls::SignatureScheme); impl Debug for MbedTlsSigner { diff --git a/rustls-mbedcrypto-provider/src/signature_verify_algo.rs b/rustls-mbedcrypto-provider/src/signature_verify_algo.rs new file mode 100644 index 0000000..548b4bf --- /dev/null +++ b/rustls-mbedcrypto-provider/src/signature_verify_algo.rs @@ -0,0 +1,114 @@ +use super::hash::Algorithm as HashAlgorithm; +use alloc::vec; +use mbedtls::pk::Pk; +use pki_types::{AlgorithmIdentifier, InvalidSignature, SignatureVerificationAlgorithm}; +use rustls::SignatureScheme; +use webpki::alg_id; + +/// ECDSA signatures using the P-256 curve and SHA-256. +pub static ECDSA_P256_SHA256: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::ECDSA_NISTP256_SHA256, + hash_algo: &super::hash::MBED_SHA_256, + public_key_alg_id: alg_id::ECDSA_P256, + signature_alg_id: alg_id::ECDSA_SHA256, +}; +/// ECDSA signatures using the P-384 curve and SHA-384. +pub static ECDSA_P384_SHA384: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::ECDSA_NISTP384_SHA384, + hash_algo: &super::hash::MBED_SHA_384, + public_key_alg_id: alg_id::ECDSA_P384, + signature_alg_id: alg_id::ECDSA_SHA384, +}; +/// RSA PKCS#1 1.5 signatures using SHA-256. +pub static RSA_PKCS1_SHA256: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::RSA_PKCS1_SHA256, + hash_algo: &super::hash::MBED_SHA_256, + public_key_alg_id: alg_id::RSA_ENCRYPTION, + signature_alg_id: alg_id::RSA_PKCS1_SHA256, +}; +/// RSA PKCS#1 1.5 signatures using SHA-384. +pub static RSA_PKCS1_SHA384: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::RSA_PKCS1_SHA384, + hash_algo: &super::hash::MBED_SHA_384, + public_key_alg_id: alg_id::RSA_ENCRYPTION, + signature_alg_id: alg_id::RSA_PKCS1_SHA384, +}; +/// RSA PKCS#1 1.5 signatures using SHA-512. +pub static RSA_PKCS1_SHA512: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::RSA_PKCS1_SHA512, + hash_algo: &super::hash::MBED_SHA_512, + public_key_alg_id: alg_id::RSA_ENCRYPTION, + signature_alg_id: alg_id::RSA_PKCS1_SHA512, +}; +/// RSA PSS signatures using SHA-256 and of +/// type rsaEncryption; see [RFC 4055 Section 1.2]. +/// +/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2 +pub static RSA_PSS_SHA256: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::RSA_PSS_SHA256, + hash_algo: &super::hash::MBED_SHA_256, + public_key_alg_id: alg_id::RSA_ENCRYPTION, + signature_alg_id: alg_id::RSA_PSS_SHA256, +}; +/// RSA PSS signatures using SHA-384 and of +/// type rsaEncryption; see [RFC 4055 Section 1.2]. +/// +/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2 +pub static RSA_PSS_SHA384: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::RSA_PSS_SHA384, + hash_algo: &super::hash::MBED_SHA_384, + public_key_alg_id: alg_id::RSA_ENCRYPTION, + signature_alg_id: alg_id::RSA_PSS_SHA384, +}; +/// RSA PSS signatures using SHA-512 and of +/// type rsaEncryption; see [RFC 4055 Section 1.2]. +/// +/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2 +pub static RSA_PSS_SHA512: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::RSA_PSS_SHA512, + hash_algo: &super::hash::MBED_SHA_512, + public_key_alg_id: alg_id::RSA_ENCRYPTION, + signature_alg_id: alg_id::RSA_PSS_SHA512, +}; + +/// A signature verify algorithm type +#[derive(Clone, Debug, PartialEq)] +pub struct Algorithm { + signature_scheme: SignatureScheme, + hash_algo: &'static HashAlgorithm, + public_key_alg_id: AlgorithmIdentifier, + signature_alg_id: AlgorithmIdentifier, +} + +impl SignatureVerificationAlgorithm for Algorithm { + fn verify_signature(&self, public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<(), InvalidSignature> { + let mut pk = Pk::from_public_key(public_key).map_err(|_| InvalidSignature)?; + let signature_curve = utils::pk::rustls_signature_scheme_to_mbedtls_curve_id(self.signature_scheme); + match signature_curve { + mbedtls::pk::EcGroupId::None => (), + _ => { + let curves_match = pk + .curve() + .is_ok_and(|pk_curve| pk_curve == signature_curve); + if !curves_match { + return Err(InvalidSignature); + } + } + } + if let Some(opts) = utils::pk::rustls_signature_scheme_to_mbedtls_pk_options(self.signature_scheme) { + pk.set_options(opts); + } + let mut hash = vec![0u8; self.hash_algo.output_len]; + mbedtls::hash::Md::hash(self.hash_algo.hash_type, message, &mut hash).map_err(|_| InvalidSignature)?; + pk.verify(self.hash_algo.hash_type, &hash, signature) + .map_err(|_| InvalidSignature) + } + + fn public_key_alg_id(&self) -> AlgorithmIdentifier { + self.public_key_alg_id + } + + fn signature_alg_id(&self) -> AlgorithmIdentifier { + self.signature_alg_id + } +} diff --git a/rustls-mbedpki-provider/src/lib.rs b/rustls-mbedpki-provider/src/lib.rs index 4f769db..42841bd 100644 --- a/rustls-mbedpki-provider/src/lib.rs +++ b/rustls-mbedpki-provider/src/lib.rs @@ -137,7 +137,7 @@ fn verify_tls_signature( let pk = cert.public_key_mut(); let hash_type = utils::hash::rustls_signature_scheme_to_mbedtls_hash_type(dss.scheme); - // for tls 1.3, we need to verify the advertised curve in signaure scheme matches the public key + // for tls 1.3, we need to verify the advertised curve in signature scheme matches the public key if is_tls13 { let signature_curve = utils::pk::rustls_signature_scheme_to_mbedtls_curve_id(dss.scheme); match signature_curve { From 3400887bce200f3575fc6b5aa5e462216bb593dd Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Wed, 15 Nov 2023 13:49:04 -0800 Subject: [PATCH 04/14] fix: fix tests --- .../examples/internal/bench.rs | 34 +-- rustls-mbedcrypto-provider/src/lib.rs | 33 +- rustls-mbedcrypto-provider/src/sign.rs | 41 ++- .../src/signature_verify_algo.rs | 15 +- rustls-mbedcrypto-provider/tests/api.rs | 289 +++++++++++------- .../tests/common/mod.rs | 98 ++++-- rustls-mbedpki-provider/src/tests_common.rs | 14 +- rustls-mbedtls-provider-utils/src/hash.rs | 8 +- 8 files changed, 347 insertions(+), 185 deletions(-) diff --git a/rustls-mbedcrypto-provider/examples/internal/bench.rs b/rustls-mbedcrypto-provider/examples/internal/bench.rs index cd0fde1..02b4164 100644 --- a/rustls-mbedcrypto-provider/examples/internal/bench.rs +++ b/rustls-mbedcrypto-provider/examples/internal/bench.rs @@ -21,7 +21,7 @@ use std::time::{Duration, Instant}; use pki_types::{CertificateDer, PrivateKeyDer}; use rustls::client::Resumption; -use rustls::crypto::ring::Ticketer; +use rustls::crypto::ring::{cipher_suite, Ticketer}; use rustls::server::{NoServerSessionStorage, ServerSessionMemoryCache, WebPkiClientVerifier}; use rustls::RootCertStore; use rustls::{ClientConfig, ClientConnection}; @@ -178,68 +178,60 @@ static ALL_BENCHMARKS: &[BenchmarkParam] = &[ #[cfg(feature = "tls12")] BenchmarkParam::new( KeyType::Rsa, - rustls::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, &rustls::version::TLS12, ), #[cfg(feature = "tls12")] BenchmarkParam::new( KeyType::Ecdsa, - rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, &rustls::version::TLS12, ), #[cfg(feature = "tls12")] BenchmarkParam::new( KeyType::Rsa, - rustls::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, &rustls::version::TLS12, ), #[cfg(feature = "tls12")] BenchmarkParam::new( KeyType::Rsa, - rustls::cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, &rustls::version::TLS12, ), #[cfg(feature = "tls12")] BenchmarkParam::new( KeyType::Rsa, - rustls::cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, &rustls::version::TLS12, ), #[cfg(feature = "tls12")] BenchmarkParam::new( KeyType::Ecdsa, - rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, &rustls::version::TLS12, ), #[cfg(feature = "tls12")] BenchmarkParam::new( KeyType::Ecdsa, - rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, &rustls::version::TLS12, ), BenchmarkParam::new( KeyType::Rsa, - rustls::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256, - &rustls::version::TLS13, - ), - BenchmarkParam::new( - KeyType::Rsa, - rustls::cipher_suite::TLS13_AES_256_GCM_SHA384, - &rustls::version::TLS13, - ), - BenchmarkParam::new( - KeyType::Rsa, - rustls::cipher_suite::TLS13_AES_128_GCM_SHA256, + cipher_suite::TLS13_CHACHA20_POLY1305_SHA256, &rustls::version::TLS13, ), + BenchmarkParam::new(KeyType::Rsa, cipher_suite::TLS13_AES_256_GCM_SHA384, &rustls::version::TLS13), + BenchmarkParam::new(KeyType::Rsa, cipher_suite::TLS13_AES_128_GCM_SHA256, &rustls::version::TLS13), BenchmarkParam::new( KeyType::Ecdsa, - rustls::cipher_suite::TLS13_AES_128_GCM_SHA256, + cipher_suite::TLS13_AES_128_GCM_SHA256, &rustls::version::TLS13, ), BenchmarkParam::new( KeyType::Ed25519, - rustls::cipher_suite::TLS13_AES_128_GCM_SHA256, + cipher_suite::TLS13_AES_128_GCM_SHA256, &rustls::version::TLS13, ), ]; diff --git a/rustls-mbedcrypto-provider/src/lib.rs b/rustls-mbedcrypto-provider/src/lib.rs index fcee18e..3ef0f5c 100644 --- a/rustls-mbedcrypto-provider/src/lib.rs +++ b/rustls-mbedcrypto-provider/src/lib.rs @@ -86,9 +86,9 @@ pub mod sign; pub mod signature_verify_algo; /// TLS1.2 ciphersuites implementation. #[cfg(feature = "tls12")] -pub mod tls12; +pub(crate) mod tls12; /// TLS1.3 ciphersuites implementation. -pub mod tls13; +pub(crate) mod tls13; use mbedtls::rng::Random; use rustls::{SignatureScheme, SupportedCipherSuite, WebPkiSupportedAlgorithms}; @@ -146,11 +146,7 @@ impl rustls::crypto::CryptoProvider for Mbedtls { &self, key_der: pki_types::PrivateKeyDer<'static>, ) -> Result, rustls::Error> { - let pk = mbedtls::pk::Pk::from_private_key(key_der.secret_der(), None) - .map_err(|err| rustls::Error::Other(rustls::OtherError(alloc::sync::Arc::new(err))))?; - Ok(alloc::sync::Arc::new(MbedTlsPkSigningKey(alloc::sync::Arc::new( - std::sync::Mutex::new(pk), - )))) + Ok(alloc::sync::Arc::new(MbedTlsPkSigningKey::new(&key_der)?)) } fn signature_verification_algorithms(&self) -> WebPkiSupportedAlgorithms { @@ -185,6 +181,17 @@ pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[ tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, ]; +/// All defined cipher suites supported by *mbedtls* appear in this module. +pub mod cipher_suite { + #[cfg(feature = "tls12")] + pub use super::tls12::{ + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }; + pub use super::tls13::{TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256}; +} + /// A `WebPkiSupportedAlgorithms` value that reflects pki's capabilities when /// compiled against *mbedtls*. static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms { @@ -207,12 +214,12 @@ static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms SignatureScheme::ECDSA_NISTP256_SHA256, &[signature_verify_algo::ECDSA_P256_SHA256], ), - (SignatureScheme::RSA_PSS_SHA512, &[signature_verify_algo::RSA_PKCS1_SHA512]), - (SignatureScheme::RSA_PSS_SHA384, &[signature_verify_algo::RSA_PKCS1_SHA384]), - (SignatureScheme::RSA_PSS_SHA256, &[signature_verify_algo::RSA_PKCS1_SHA256]), - (SignatureScheme::RSA_PKCS1_SHA512, &[signature_verify_algo::RSA_PSS_SHA512]), - (SignatureScheme::RSA_PKCS1_SHA384, &[signature_verify_algo::RSA_PSS_SHA384]), - (SignatureScheme::RSA_PKCS1_SHA256, &[signature_verify_algo::RSA_PSS_SHA256]), + (SignatureScheme::RSA_PKCS1_SHA512, &[signature_verify_algo::RSA_PKCS1_SHA512]), + (SignatureScheme::RSA_PKCS1_SHA384, &[signature_verify_algo::RSA_PKCS1_SHA384]), + (SignatureScheme::RSA_PKCS1_SHA256, &[signature_verify_algo::RSA_PKCS1_SHA256]), + (SignatureScheme::RSA_PSS_SHA512, &[signature_verify_algo::RSA_PSS_SHA512]), + (SignatureScheme::RSA_PSS_SHA384, &[signature_verify_algo::RSA_PSS_SHA384]), + (SignatureScheme::RSA_PSS_SHA256, &[signature_verify_algo::RSA_PSS_SHA256]), ], }; diff --git a/rustls-mbedcrypto-provider/src/sign.rs b/rustls-mbedcrypto-provider/src/sign.rs index 8930707..8c74090 100644 --- a/rustls-mbedcrypto-provider/src/sign.rs +++ b/rustls-mbedcrypto-provider/src/sign.rs @@ -5,7 +5,7 @@ use mbedtls::pk::ECDSA_MAX_LEN; use std::sync::Mutex; use utils::error::mbedtls_err_into_rustls_err; use utils::hash::{buffer_for_hash_type, rustls_signature_scheme_to_mbedtls_hash_type}; -use utils::pk::{rustls_signature_scheme_to_mbedtls_pk_options, rustls_signature_scheme_to_mbedtls_pk_type}; +use utils::pk::rustls_signature_scheme_to_mbedtls_pk_options; struct MbedTlsSigner(Arc>, rustls::SignatureScheme); @@ -69,18 +69,31 @@ impl Debug for MbedTlsPkSigningKey { } } +impl MbedTlsPkSigningKey { + /// Make a new `MbedTlsPkSigningKey` from a DER encoding. + pub fn new(der: &pki_types::PrivateKeyDer<'_>) -> Result { + let pk = mbedtls::pk::Pk::from_private_key(der.secret_der(), None) + .map_err(|err| rustls::Error::Other(rustls::OtherError(alloc::sync::Arc::new(err))))?; + + Ok(Self(alloc::sync::Arc::new(std::sync::Mutex::new(pk)))) + } +} + impl rustls::sign::SigningKey for MbedTlsPkSigningKey { fn choose_scheme(&self, offered: &[rustls::SignatureScheme]) -> Option> { + let pk_type = self + .0 + .lock() + .expect("poisoned pk lock") + .pk_type(); for scheme in offered { - let scheme_type = rustls_signature_scheme_to_mbedtls_pk_type(scheme); - if let Some(scheme_type) = scheme_type { - if scheme_type - == self - .0 - .lock() - .expect("poisoned pk lock") - .pk_type() - { + let scheme_type = utils::pk::rustls_signature_scheme_to_mbedtls_pk_type(scheme); + if let Some(mut scheme_type) = scheme_type { + // TODO: better handling logic here. + if scheme_type == mbedtls::pk::Type::Ecdsa { + scheme_type = mbedtls::pk::Type::Eckey; + } + if scheme_type == pk_type { let signer = MbedTlsSigner(self.0.clone(), *scheme); return Some(Box::new(signer)); } @@ -100,11 +113,11 @@ impl rustls::sign::SigningKey for MbedTlsPkSigningKey { mbedtls::pk::Type::Rsa => SignatureAlgorithm::RSA, mbedtls::pk::Type::Ecdsa => SignatureAlgorithm::ECDSA, mbedtls::pk::Type::RsassaPss => SignatureAlgorithm::RSA, + mbedtls::pk::Type::RsaAlt => SignatureAlgorithm::RSA, mbedtls::pk::Type::Eckey => SignatureAlgorithm::ECDSA, - mbedtls::pk::Type::RsaAlt => SignatureAlgorithm::DSA, - mbedtls::pk::Type::EckeyDh => SignatureAlgorithm::Anonymous, - mbedtls::pk::Type::Custom => SignatureAlgorithm::Anonymous, - mbedtls::pk::Type::None => SignatureAlgorithm::Anonymous, + mbedtls::pk::Type::EckeyDh => SignatureAlgorithm::Unknown(255), + mbedtls::pk::Type::Custom => SignatureAlgorithm::Unknown(255), + mbedtls::pk::Type::None => SignatureAlgorithm::Unknown(255), } } } diff --git a/rustls-mbedcrypto-provider/src/signature_verify_algo.rs b/rustls-mbedcrypto-provider/src/signature_verify_algo.rs index 548b4bf..20c3412 100644 --- a/rustls-mbedcrypto-provider/src/signature_verify_algo.rs +++ b/rustls-mbedcrypto-provider/src/signature_verify_algo.rs @@ -82,7 +82,10 @@ pub struct Algorithm { impl SignatureVerificationAlgorithm for Algorithm { fn verify_signature(&self, public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<(), InvalidSignature> { - let mut pk = Pk::from_public_key(public_key).map_err(|_| InvalidSignature)?; + let mut pk = Pk::from_public_key(public_key).map_err(|e| { + crate::log::error!("{e}"); + InvalidSignature + })?; let signature_curve = utils::pk::rustls_signature_scheme_to_mbedtls_curve_id(self.signature_scheme); match signature_curve { mbedtls::pk::EcGroupId::None => (), @@ -99,9 +102,15 @@ impl SignatureVerificationAlgorithm for Algorithm { pk.set_options(opts); } let mut hash = vec![0u8; self.hash_algo.output_len]; - mbedtls::hash::Md::hash(self.hash_algo.hash_type, message, &mut hash).map_err(|_| InvalidSignature)?; + mbedtls::hash::Md::hash(self.hash_algo.hash_type, message, &mut hash).map_err(|e| { + crate::log::error!("{e}"); + InvalidSignature + })?; pk.verify(self.hash_algo.hash_type, &hash, signature) - .map_err(|_| InvalidSignature) + .map_err(|e| { + crate::log::error!("{e}"); + InvalidSignature + }) } fn public_key_alg_id(&self) -> AlgorithmIdentifier { diff --git a/rustls-mbedcrypto-provider/tests/api.rs b/rustls-mbedcrypto-provider/tests/api.rs index 58c7c89..aec31da 100644 --- a/rustls-mbedcrypto-provider/tests/api.rs +++ b/rustls-mbedcrypto-provider/tests/api.rs @@ -5,9 +5,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#![cfg_attr(read_buf, feature(read_buf))] +#![cfg_attr(read_buf, feature(core_io_borrowed_buf))] //! Assorted public API tests. use std::cell::RefCell; use std::fmt; +use std::fmt::Debug; use std::io::{self, IoSlice, Read, Write}; use std::mem; use std::ops::{Deref, DerefMut}; @@ -15,22 +18,26 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use std::sync::Mutex; -use pki_types::{CertificateDer, UnixTime}; -use rustls::client::{verify_server_cert_signed_by_trust_anchor, ResolvesClientCert, Resumption, WebPkiServerVerifier}; -use rustls::internal::msgs::{ - base::Payload, - codec::Codec, - enums::AlertLevel, - handshake::{ClientExtension, HandshakePayload}, - message::{Message, MessagePayload, PlainMessage}, -}; -use rustls::server::{ClientHello, ParsedCertificate, ResolvesServerCert, WebPkiClientVerifier}; +use pki_types::{CertificateDer, PrivateKeyDer, UnixTime}; +use primary_provider::cipher_suite; +use primary_provider::sign::MbedTlsPkSigningKey as RsaSigningKey; +use rustls::client::{verify_server_cert_signed_by_trust_anchor, ResolvesClientCert, Resumption}; +use rustls::internal::msgs::base::Payload; +use rustls::internal::msgs::codec::Codec; +use rustls::internal::msgs::enums::AlertLevel; +use rustls::internal::msgs::handshake::{ClientExtension, HandshakePayload}; +use rustls::internal::msgs::message::{Message, MessagePayload, PlainMessage}; +use rustls::server::{ClientHello, ParsedCertificate, ResolvesServerCert}; +use rustls::SupportedCipherSuite; use rustls::{ - sign, AlertDescription, CertificateError, CipherSuite, ClientConfig, ClientConnection, ConnectionCommon, ContentType, - DistinguishedName, Error, KeyLog, PeerIncompatible, PeerMisbehaved, ProtocolVersion, ServerConfig, ServerConnection, - SideData, SignatureScheme, Stream, StreamOwned, SupportedCipherSuite, + sign, AlertDescription, CertificateError, ConnectionCommon, ContentType, Error, KeyLog, PeerIncompatible, PeerMisbehaved, + SideData, }; -use rustls_mbedcrypto_provider::ALL_CIPHER_SUITES; +use rustls::{CipherSuite, ProtocolVersion, SignatureScheme}; +use rustls::{ClientConfig, ClientConnection}; +use rustls::{ConnectionTrafficSecrets, DistinguishedName}; +use rustls::{ServerConfig, ServerConnection}; +use rustls::{Stream, StreamOwned}; mod common; use crate::common::*; @@ -187,7 +194,8 @@ fn check_read_err(reader: &mut dyn io::Read, err_kind: io::ErrorKind) { #[cfg(read_buf)] fn check_read_buf(reader: &mut dyn io::Read, bytes: &[u8]) { - use std::{io::BorrowedBuf, mem::MaybeUninit}; + use core::io::BorrowedBuf; + use std::mem::MaybeUninit; let mut buf = [MaybeUninit::::uninit(); 128]; let mut buf: BorrowedBuf<'_> = buf.as_mut_slice().into(); @@ -197,7 +205,8 @@ fn check_read_buf(reader: &mut dyn io::Read, bytes: &[u8]) { #[cfg(read_buf)] fn check_read_buf_err(reader: &mut dyn io::Read, err_kind: io::ErrorKind) { - use std::{io::BorrowedBuf, mem::MaybeUninit}; + use core::io::BorrowedBuf; + use std::mem::MaybeUninit; let mut buf = [MaybeUninit::::uninit(); 1]; let mut buf: BorrowedBuf<'_> = buf.as_mut_slice().into(); @@ -210,7 +219,7 @@ fn check_read_buf_err(reader: &mut dyn io::Read, err_kind: io::ErrorKind) { #[test] fn config_builder_for_client_rejects_empty_kx_groups() { assert_eq!( - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + client_config_builder() .with_safe_default_cipher_suites() .with_kx_groups(&[]) .with_safe_default_protocol_versions() @@ -222,7 +231,7 @@ fn config_builder_for_client_rejects_empty_kx_groups() { #[test] fn config_builder_for_client_rejects_empty_cipher_suites() { assert_eq!( - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + client_config_builder() .with_cipher_suites(&[]) .with_safe_default_kx_groups() .with_safe_default_protocol_versions() @@ -235,8 +244,8 @@ fn config_builder_for_client_rejects_empty_cipher_suites() { #[test] fn config_builder_for_client_rejects_incompatible_cipher_suites() { assert_eq!( - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) - .with_cipher_suites(&[rustls_mbedcrypto_provider::tls13::TLS13_AES_256_GCM_SHA384]) + client_config_builder() + .with_cipher_suites(&[cipher_suite::TLS13_AES_256_GCM_SHA384]) .with_safe_default_kx_groups() .with_protocol_versions(&[&rustls::version::TLS12]) .err(), @@ -247,7 +256,7 @@ fn config_builder_for_client_rejects_incompatible_cipher_suites() { #[test] fn config_builder_for_server_rejects_empty_kx_groups() { assert_eq!( - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_safe_default_cipher_suites() .with_kx_groups(&[]) .with_safe_default_protocol_versions() @@ -259,7 +268,7 @@ fn config_builder_for_server_rejects_empty_kx_groups() { #[test] fn config_builder_for_server_rejects_empty_cipher_suites() { assert_eq!( - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_cipher_suites(&[]) .with_safe_default_kx_groups() .with_safe_default_protocol_versions() @@ -272,8 +281,8 @@ fn config_builder_for_server_rejects_empty_cipher_suites() { #[test] fn config_builder_for_server_rejects_incompatible_cipher_suites() { assert_eq!( - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) - .with_cipher_suites(&[rustls_mbedcrypto_provider::tls13::TLS13_AES_256_GCM_SHA384]) + server_config_builder() + .with_cipher_suites(&[cipher_suite::TLS13_AES_256_GCM_SHA384]) .with_safe_default_kx_groups() .with_protocol_versions(&[&rustls::version::TLS12]) .err(), @@ -424,15 +433,48 @@ fn server_can_get_client_cert_after_resumption() { } #[test] +#[cfg(feature = "ring")] fn test_config_builders_debug() { - let b = ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS); + let b = server_config_builder(); + assert_eq!( + "ConfigBuilder { state: WantsCipherSuites(Ring) }", + format!("{:?}", b) + ); + let b = b.with_cipher_suites(&[cipher_suite::TLS13_CHACHA20_POLY1305_SHA256]); + assert_eq!("ConfigBuilder { state: WantsKxGroups { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], provider: Ring } }", format!("{:?}", b)); + let b = b.with_kx_groups(&[primary_provider::kx_group::X25519]); + assert_eq!("ConfigBuilder { state: WantsVersions { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Ring } }", format!("{:?}", b)); + let b = b + .with_protocol_versions(&[&rustls::version::TLS13]) + .unwrap(); + let b = b.with_no_client_auth(); + assert_eq!("ConfigBuilder { state: WantsServerCert { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Ring, versions: [TLSv1_3], verifier: NoClientAuth } }", format!("{:?}", b)); + + let b = client_config_builder(); + assert_eq!( + "ConfigBuilder { state: WantsCipherSuites(Ring) }", + format!("{:?}", b) + ); + let b = b.with_cipher_suites(&[cipher_suite::TLS13_CHACHA20_POLY1305_SHA256]); + assert_eq!("ConfigBuilder { state: WantsKxGroups { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], provider: Ring } }", format!("{:?}", b)); + let b = b.with_kx_groups(&[primary_provider::kx_group::X25519]); + assert_eq!("ConfigBuilder { state: WantsVersions { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Ring } }", format!("{:?}", b)); + let b = b + .with_protocol_versions(&[&rustls::version::TLS13]) + .unwrap(); + assert_eq!("ConfigBuilder { state: WantsVerifier { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Ring, versions: [TLSv1_3] } }", format!("{:?}", b)); +} + +#[test] +fn test_config_builders_debug_mbedtls() { + let b = server_config_builder(); assert_eq!( "ConfigBuilder { state: WantsCipherSuites(Mbedtls) }", format!("{:?}", b) ); - let b = b.with_cipher_suites(&[rustls_mbedcrypto_provider::tls13::TLS13_CHACHA20_POLY1305_SHA256]); + let b = b.with_cipher_suites(&[cipher_suite::TLS13_CHACHA20_POLY1305_SHA256]); assert_eq!("ConfigBuilder { state: WantsKxGroups { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], provider: Mbedtls } }", format!("{:?}", b)); - let b = b.with_kx_groups(&[rustls_mbedcrypto_provider::kx_group::X25519]); + let b = b.with_kx_groups(&[primary_provider::kx_group::X25519]); assert_eq!("ConfigBuilder { state: WantsVersions { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Mbedtls } }", format!("{:?}", b)); let b = b .with_protocol_versions(&[&rustls::version::TLS13]) @@ -440,14 +482,14 @@ fn test_config_builders_debug() { let b = b.with_no_client_auth(); assert_eq!("ConfigBuilder { state: WantsServerCert { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Mbedtls, versions: [TLSv1_3], verifier: dyn ClientCertVerifier } }", format!("{:?}", b)); - let b = ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS); + let b = client_config_builder(); assert_eq!( "ConfigBuilder { state: WantsCipherSuites(Mbedtls) }", format!("{:?}", b) ); - let b = b.with_cipher_suites(&[rustls_mbedcrypto_provider::tls13::TLS13_CHACHA20_POLY1305_SHA256]); + let b = b.with_cipher_suites(&[cipher_suite::TLS13_CHACHA20_POLY1305_SHA256]); assert_eq!("ConfigBuilder { state: WantsKxGroups { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], provider: Mbedtls } }", format!("{:?}", b)); - let b = b.with_kx_groups(&[rustls_mbedcrypto_provider::kx_group::X25519]); + let b = b.with_kx_groups(&[primary_provider::kx_group::X25519]); assert_eq!("ConfigBuilder { state: WantsVersions { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Mbedtls } }", format!("{:?}", b)); let b = b .with_protocol_versions(&[&rustls::version::TLS13]) @@ -464,12 +506,12 @@ fn server_allow_any_anonymous_or_authenticated_client() { let kt = KeyType::Rsa; for client_cert_chain in [None, Some(kt.get_client_chain())].iter() { let client_auth_roots = get_client_root_store(kt); - let client_auth = WebPkiClientVerifier::builder(client_auth_roots.clone()) + let client_auth = webpki_client_verifier_builder(client_auth_roots.clone()) .allow_unauthenticated() .build() .unwrap(); - let server_config = ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + let server_config = server_config_builder() .with_safe_defaults() .with_client_cert_verifier(client_auth) .with_single_cert(kt.get_chain(), kt.get_key()) @@ -730,7 +772,7 @@ fn test_tls13_late_plaintext_alert() { assert_eq!(server.process_new_packets(), Err(Error::DecryptError)); } -#[derive(Default)] +#[derive(Default, Debug)] struct ServerCheckCertResolve { expected_sni: Option, expected_sigalgs: Option>, @@ -848,7 +890,7 @@ fn client_trims_terminating_dot() { fn check_sigalgs_reduced_by_ciphersuite(kt: KeyType, suite: CipherSuite, expected_sigalgs: Vec) { let client_config = finish_client_config( kt, - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + client_config_builder() .with_cipher_suites(&[find_suite(suite)]) .with_safe_default_kx_groups() .with_safe_default_protocol_versions() @@ -901,6 +943,7 @@ fn server_cert_resolve_reduces_sigalgs_for_ecdsa_ciphersuite() { ); } +#[derive(Debug)] struct ServerCheckNoSni {} impl ResolvesServerCert for ServerCheckNoSni { @@ -1008,7 +1051,7 @@ fn client_check_server_certificate_ee_revoked() { // Setup a server verifier that will check the EE certificate's revocation status. let crls = vec![kt.end_entity_crl()]; - let builder = WebPkiServerVerifier::builder(get_client_root_store(*kt)) + let builder = webpki_server_verifier_builder(get_client_root_store(*kt)) .with_crls(crls) .only_check_end_entity_revocation(); @@ -1036,12 +1079,12 @@ fn client_check_server_certificate_ee_unknown_revocation() { // allow unknown revocation status (the default). We'll provide CRLs that are not relevant // to the EE cert to ensure its status is unknown. let unrelated_crls = vec![kt.intermediate_crl()]; - let forbid_unknown_verifier = WebPkiServerVerifier::builder(get_client_root_store(*kt)) + let forbid_unknown_verifier = webpki_server_verifier_builder(get_client_root_store(*kt)) .with_crls(unrelated_crls.clone()) .only_check_end_entity_revocation(); // Also set up a verifier builder that will allow unknown revocation status. - let allow_unknown_verifier = WebPkiServerVerifier::builder(get_client_root_store(*kt)) + let allow_unknown_verifier = webpki_server_verifier_builder(get_client_root_store(*kt)) .with_crls(unrelated_crls) .only_check_end_entity_revocation() .allow_unknown_revocation_status(); @@ -1080,13 +1123,13 @@ fn client_check_server_certificate_intermediate_revoked() { // that marks the intermediate certificate as revoked. We allow unknown revocation status // so the EE cert's unknown status doesn't cause an error. let crls = vec![kt.intermediate_crl()]; - let full_chain_verifier_builder = WebPkiServerVerifier::builder(get_client_root_store(*kt)) + let full_chain_verifier_builder = webpki_server_verifier_builder(get_client_root_store(*kt)) .with_crls(crls.clone()) .allow_unknown_revocation_status(); // Also set up a verifier builder that will use the same CRL, but only check the EE certificate // revocation status. - let ee_verifier_builder = WebPkiServerVerifier::builder(get_client_root_store(*kt)) + let ee_verifier_builder = webpki_server_verifier_builder(get_client_root_store(*kt)) .with_crls(crls.clone()) .only_check_end_entity_revocation() .allow_unknown_revocation_status(); @@ -1151,6 +1194,7 @@ fn client_check_server_certificate_helper_api() { } } +#[derive(Debug)] struct ClientCheckCertResolve { query_count: AtomicUsize, expect_queries: usize, @@ -1267,7 +1311,7 @@ fn client_cert_resolve_server_no_hints() { // arguments. for key_type in ALL_KEY_TYPES.into_iter() { // Build a verifier with no hint subjects. - let verifier = WebPkiClientVerifier::builder(get_client_root_store(key_type)).clear_root_hint_subjects(); + let verifier = webpki_client_verifier_builder(get_client_root_store(key_type)).clear_root_hint_subjects(); let server_config = make_server_config_with_client_verifier(key_type, verifier); let expected_root_hint_subjects = Vec::default(); // no hints expected. test_client_cert_resolve(key_type, server_config.into(), expected_root_hint_subjects); @@ -1291,7 +1335,7 @@ fn client_cert_resolve_server_added_hint() { ]; // Create a verifier that adds the extra_name as a hint subject in addition to the ones // from the root cert store. - let verifier = WebPkiClientVerifier::builder(get_client_root_store(key_type)) + let verifier = webpki_client_verifier_builder(get_client_root_store(key_type)) .add_root_hint_subjects([DistinguishedName::from(extra_name.clone())].into_iter()); let server_config = make_server_config_with_client_verifier(key_type, verifier); test_client_cert_resolve(key_type, server_config.into(), expected_hint_subjects); @@ -1319,7 +1363,7 @@ fn client_mandatory_auth_client_revocation_works() { let relevant_crls = vec![kt.client_crl()]; // Only check the EE certificate status. See client_mandatory_auth_intermediate_revocation_works // for testing revocation status of the whole chain. - let ee_verifier_builder = WebPkiClientVerifier::builder(get_client_root_store(*kt)) + let ee_verifier_builder = webpki_client_verifier_builder(get_client_root_store(*kt)) .with_crls(relevant_crls) .only_check_end_entity_revocation(); let revoked_server_config = Arc::new(make_server_config_with_client_verifier(*kt, ee_verifier_builder)); @@ -1327,14 +1371,14 @@ fn client_mandatory_auth_client_revocation_works() { // Create a server configuration that includes a CRL that doesn't cover the client certificate, // and uses the default behaviour of treating unknown revocation status as an error. let unrelated_crls = vec![kt.intermediate_crl()]; - let ee_verifier_builder = WebPkiClientVerifier::builder(get_client_root_store(*kt)) + let ee_verifier_builder = webpki_client_verifier_builder(get_client_root_store(*kt)) .with_crls(unrelated_crls.clone()) .only_check_end_entity_revocation(); let missing_client_crl_server_config = Arc::new(make_server_config_with_client_verifier(*kt, ee_verifier_builder)); // Create a server configuration that includes a CRL that doesn't cover the client certificate, // but change the builder to allow unknown revocation status. - let ee_verifier_builder = WebPkiClientVerifier::builder(get_client_root_store(*kt)) + let ee_verifier_builder = webpki_client_verifier_builder(get_client_root_store(*kt)) .with_crls(unrelated_crls.clone()) .only_check_end_entity_revocation() .allow_unknown_revocation_status(); @@ -1377,14 +1421,14 @@ fn client_mandatory_auth_intermediate_revocation_works() { // is revoked. We check the full chain for revocation status (default), and allow unknown // revocation status so the EE's unknown revocation status isn't an error. let crls = vec![kt.intermediate_crl()]; - let full_chain_verifier_builder = WebPkiClientVerifier::builder(get_client_root_store(*kt)) + let full_chain_verifier_builder = webpki_client_verifier_builder(get_client_root_store(*kt)) .with_crls(crls.clone()) .allow_unknown_revocation_status(); let full_chain_server_config = Arc::new(make_server_config_with_client_verifier(*kt, full_chain_verifier_builder)); // Also create a server configuration that uses the same CRL, but that only checks the EE // cert revocation status. - let ee_only_verifier_builder = WebPkiClientVerifier::builder(get_client_root_store(*kt)) + let ee_only_verifier_builder = webpki_client_verifier_builder(get_client_root_store(*kt)) .with_crls(crls) .only_check_end_entity_revocation() .allow_unknown_revocation_status(); @@ -2171,8 +2215,8 @@ fn make_disjoint_suite_configs() -> (ClientConfig, ServerConfig) { let kt = KeyType::Rsa; let server_config = finish_server_config( kt, - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) - .with_cipher_suites(&[rustls_mbedcrypto_provider::tls13::TLS13_CHACHA20_POLY1305_SHA256]) + server_config_builder() + .with_cipher_suites(&[cipher_suite::TLS13_CHACHA20_POLY1305_SHA256]) .with_safe_default_kx_groups() .with_safe_default_protocol_versions() .unwrap(), @@ -2180,8 +2224,8 @@ fn make_disjoint_suite_configs() -> (ClientConfig, ServerConfig) { let client_config = finish_client_config( kt, - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) - .with_cipher_suites(&[rustls_mbedcrypto_provider::tls13::TLS13_AES_256_GCM_SHA384]) + client_config_builder() + .with_cipher_suites(&[cipher_suite::TLS13_AES_256_GCM_SHA384]) .with_safe_default_kx_groups() .with_safe_default_protocol_versions() .unwrap(), @@ -2377,7 +2421,7 @@ fn server_exposes_offered_sni_even_if_resolver_fails() { fn sni_resolver_works() { let kt = KeyType::Rsa; let mut resolver = rustls::server::ResolvesServerCertUsingSni::new(); - let signing_key = sign::RsaSigningKey::new(&kt.get_key()).unwrap(); + let signing_key = RsaSigningKey::new(&kt.get_key()).unwrap(); let signing_key: Arc = Arc::new(signing_key); resolver .add("localhost", sign::CertifiedKey::new(kt.get_chain(), signing_key.clone())) @@ -2407,7 +2451,7 @@ fn sni_resolver_works() { fn sni_resolver_rejects_wrong_names() { let kt = KeyType::Rsa; let mut resolver = rustls::server::ResolvesServerCertUsingSni::new(); - let signing_key = sign::RsaSigningKey::new(&kt.get_key()).unwrap(); + let signing_key = RsaSigningKey::new(&kt.get_key()).unwrap(); let signing_key: Arc = Arc::new(signing_key); assert_eq!( @@ -2428,7 +2472,7 @@ fn sni_resolver_rejects_wrong_names() { fn sni_resolver_lower_cases_configured_names() { let kt = KeyType::Rsa; let mut resolver = rustls::server::ResolvesServerCertUsingSni::new(); - let signing_key = sign::RsaSigningKey::new(&kt.get_key()).unwrap(); + let signing_key = RsaSigningKey::new(&kt.get_key()).unwrap(); let signing_key: Arc = Arc::new(signing_key); assert_eq!( @@ -2451,7 +2495,7 @@ fn sni_resolver_lower_cases_queried_names() { // actually, the handshake parser does this, but the effect is the same. let kt = KeyType::Rsa; let mut resolver = rustls::server::ResolvesServerCertUsingSni::new(); - let signing_key = sign::RsaSigningKey::new(&kt.get_key()).unwrap(); + let signing_key = RsaSigningKey::new(&kt.get_key()).unwrap(); let signing_key: Arc = Arc::new(signing_key); assert_eq!( @@ -2473,7 +2517,7 @@ fn sni_resolver_lower_cases_queried_names() { fn sni_resolver_rejects_bad_certs() { let kt = KeyType::Rsa; let mut resolver = rustls::server::ResolvesServerCertUsingSni::new(); - let signing_key = sign::RsaSigningKey::new(&kt.get_key()).unwrap(); + let signing_key = RsaSigningKey::new(&kt.get_key()).unwrap(); let signing_key: Arc = Arc::new(signing_key); assert_eq!( @@ -2628,7 +2672,10 @@ fn do_suite_test( } fn find_suite(suite: CipherSuite) -> SupportedCipherSuite { - for scs in ALL_CIPHER_SUITES.iter().copied() { + for scs in primary_provider::ALL_CIPHER_SUITES + .iter() + .copied() + { if scs.suite() == suite { return scs; } @@ -2697,7 +2744,7 @@ fn negotiated_ciphersuite_default() { #[test] fn all_suites_covered() { - assert_eq!(ALL_CIPHER_SUITES.len(), TEST_CIPHERSUITES.len()); + assert_eq!(primary_provider::ALL_CIPHER_SUITES.len(), TEST_CIPHERSUITES.len()); } #[test] @@ -2707,7 +2754,7 @@ fn negotiated_ciphersuite_client() { let scs = find_suite(suite); let client_config = finish_client_config( kt, - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + client_config_builder() .with_cipher_suites(&[scs]) .with_safe_default_kx_groups() .with_protocol_versions(&[version]) @@ -2725,7 +2772,7 @@ fn negotiated_ciphersuite_server() { let scs = find_suite(suite); let server_config = finish_server_config( kt, - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_cipher_suites(&[scs]) .with_safe_default_kx_groups() .with_protocol_versions(&[version]) @@ -2743,6 +2790,7 @@ struct KeyLogItem { secret: Vec, } +#[derive(Debug)] struct KeyLogToVec { label: &'static str, items: Mutex>, @@ -3307,6 +3355,7 @@ fn tls13_stateless_resumption() { let client_config = Arc::new(client_config); let mut server_config = make_server_config(kt); + // TODO: add mbedtls based Ticketer server_config.ticketer = rustls::crypto::ring::Ticketer::new().unwrap(); let storage = Arc::new(ServerStorage::new()); server_config.session_storage = storage.clone(); @@ -3355,6 +3404,7 @@ fn tls13_stateless_resumption() { Some(3) ); } + #[test] fn early_data_not_available() { let (mut client, _) = make_pair(KeyType::Rsa); @@ -3496,16 +3546,16 @@ fn test_client_does_not_offer_sha1() { #[test] fn test_client_config_keyshare() { - let client_config = make_client_config_with_kx_groups(KeyType::Rsa, &[rustls_mbedcrypto_provider::kx_group::SECP384R1]); - let server_config = make_server_config_with_kx_groups(KeyType::Rsa, &[rustls_mbedcrypto_provider::kx_group::SECP384R1]); + let client_config = make_client_config_with_kx_groups(KeyType::Rsa, &[primary_provider::kx_group::SECP384R1]); + let server_config = make_server_config_with_kx_groups(KeyType::Rsa, &[primary_provider::kx_group::SECP384R1]); let (mut client, mut server) = make_pair_for_configs(client_config, server_config); do_handshake_until_error(&mut client, &mut server).unwrap(); } #[test] fn test_client_config_keyshare_mismatch() { - let client_config = make_client_config_with_kx_groups(KeyType::Rsa, &[rustls_mbedcrypto_provider::kx_group::SECP384R1]); - let server_config = make_server_config_with_kx_groups(KeyType::Rsa, &[rustls_mbedcrypto_provider::kx_group::X25519]); + let client_config = make_client_config_with_kx_groups(KeyType::Rsa, &[primary_provider::kx_group::SECP384R1]); + let server_config = make_server_config_with_kx_groups(KeyType::Rsa, &[primary_provider::kx_group::X25519]); let (mut client, mut server) = make_pair_for_configs(client_config, server_config); assert!(do_handshake_until_error(&mut client, &mut server).is_err()); } @@ -3516,17 +3566,14 @@ fn test_client_sends_helloretryrequest() { // client sends a secp384r1 key share let mut client_config = make_client_config_with_kx_groups( KeyType::Rsa, - &[ - rustls_mbedcrypto_provider::kx_group::SECP384R1, - rustls_mbedcrypto_provider::kx_group::X25519, - ], + &[primary_provider::kx_group::SECP384R1, primary_provider::kx_group::X25519], ); let storage = Arc::new(ClientStorage::new()); client_config.resumption = Resumption::store(storage.clone()); // but server only accepts x25519, so a HRR is required - let server_config = make_server_config_with_kx_groups(KeyType::Rsa, &[rustls_mbedcrypto_provider::kx_group::X25519]); + let server_config = make_server_config_with_kx_groups(KeyType::Rsa, &[primary_provider::kx_group::X25519]); let (mut client, mut server) = make_pair_for_configs(client_config, server_config); @@ -3589,8 +3636,7 @@ fn test_client_sends_helloretryrequest() { #[test] fn test_client_rejects_hrr_with_varied_session_id() { use rustls::internal::msgs::handshake::SessionId; - use rustls_mbedcrypto_provider::MBEDTLS; - let different_session_id = SessionId::random(MBEDTLS).unwrap(); + let different_session_id = SessionId::random(PROVIDER).unwrap(); let assert_client_sends_hello_with_secp384 = |msg: &mut Message| -> Altered { if let MessagePayload::Handshake { parsed, encoded } = &mut msg.payload { @@ -3623,13 +3669,10 @@ fn test_client_rejects_hrr_with_varied_session_id() { // client prefers a secp384r1 key share, server only accepts x25519 let client_config = make_client_config_with_kx_groups( KeyType::Rsa, - &[ - rustls_mbedcrypto_provider::kx_group::SECP384R1, - rustls_mbedcrypto_provider::kx_group::X25519, - ], + &[primary_provider::kx_group::SECP384R1, primary_provider::kx_group::X25519], ); - let server_config = make_server_config_with_kx_groups(KeyType::Rsa, &[rustls_mbedcrypto_provider::kx_group::X25519]); + let server_config = make_server_config_with_kx_groups(KeyType::Rsa, &[primary_provider::kx_group::X25519]); let (client, server) = make_pair_for_configs(client_config, server_config); let (mut client, mut server) = (client.into(), server.into()); @@ -3647,19 +3690,17 @@ fn test_client_rejects_hrr_with_varied_session_id() { #[cfg(feature = "tls12")] #[test] fn test_client_attempts_to_use_unsupported_kx_group() { - use rustls_mbedcrypto_provider::kx_group::{SECP384R1, X25519}; - // common to both client configs let shared_storage = Arc::new(ClientStorage::new()); // first, client sends a x25519 and server agrees. x25519 is inserted // into kx group cache. - let mut client_config_1 = make_client_config_with_kx_groups(KeyType::Rsa, &[X25519]); + let mut client_config_1 = make_client_config_with_kx_groups(KeyType::Rsa, &[primary_provider::kx_group::X25519]); client_config_1.resumption = Resumption::store(shared_storage.clone()); // second, client only supports secp-384 and so kx group cache // contains an unusable value. - let mut client_config_2 = make_client_config_with_kx_groups(KeyType::Rsa, &[SECP384R1]); + let mut client_config_2 = make_client_config_with_kx_groups(KeyType::Rsa, &[primary_provider::kx_group::SECP384R1]); client_config_2.resumption = Resumption::store(shared_storage.clone()); let server_config = make_server_config(KeyType::Rsa); @@ -3850,6 +3891,39 @@ fn bad_client_max_fragment_sizes() { assert_eq!(check_client_max_fragment_size(0xffff), Some(Error::BadMaxFragmentSize)); } +#[test] +fn handshakes_complete_and_data_flows_with_gratuitious_max_fragment_sizes() { + // general exercising of msgs::fragmenter and msgs::deframer + for kt in ALL_KEY_TYPES.iter() { + for version in rustls::ALL_VERSIONS { + // no hidden significance to these numbers + for frag_size in [37, 61, 101, 257] { + println!("test kt={kt:?} version={version:?} frag={frag_size:?}"); + let mut client_config = make_client_config_with_versions(*kt, &[version]); + client_config.max_fragment_size = Some(frag_size); + let mut server_config = make_server_config(*kt); + server_config.max_fragment_size = Some(frag_size); + + let (mut client, mut server) = make_pair_for_configs(client_config, server_config); + do_handshake(&mut client, &mut server); + + // check server -> client data flow + let pattern = (0x00..=0xffu8).collect::>(); + assert_eq!(pattern.len(), server.writer().write(&pattern).unwrap()); + transfer(&mut server, &mut client); + client.process_new_packets().unwrap(); + check_read(&mut client.reader(), &pattern); + + // and client -> server + assert_eq!(pattern.len(), client.writer().write(&pattern).unwrap()); + transfer(&mut client, &mut server); + server.process_new_packets().unwrap(); + check_read(&mut server.reader(), &pattern); + } + } + } +} + fn assert_lt(left: usize, right: usize) { if left >= right { panic!("expected {} < {}", left, right); @@ -3979,7 +4053,7 @@ fn test_client_tls12_no_resume_after_server_downgrade() { let server_config_1 = Arc::new(common::finish_server_config( KeyType::Ed25519, - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() .with_protocol_versions(&[&rustls::version::TLS13]) @@ -3988,7 +4062,7 @@ fn test_client_tls12_no_resume_after_server_downgrade() { let mut server_config_2 = common::finish_server_config( KeyType::Ed25519, - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() .with_protocol_versions(&[&rustls::version::TLS12]) @@ -4186,7 +4260,6 @@ fn test_no_warning_logging_during_successful_sessions() { #[cfg(feature = "tls12")] #[test] fn test_secret_extraction_enabled() { - use rustls::ConnectionTrafficSecrets; // Normally, secret extraction would be used to configure kTLS (TLS offload // to the kernel). We want this test to run on any platform, though, so // instead we just compare secrets for equality. @@ -4197,18 +4270,18 @@ fn test_secret_extraction_enabled() { // Chacha20Poly1305), so that's 2*3 = 6 combinations to test. let kt = KeyType::Rsa; for suite in [ - rustls_mbedcrypto_provider::tls13::TLS13_AES_128_GCM_SHA256, - rustls_mbedcrypto_provider::tls13::TLS13_AES_256_GCM_SHA384, - rustls_mbedcrypto_provider::tls13::TLS13_CHACHA20_POLY1305_SHA256, - rustls_mbedcrypto_provider::tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - rustls_mbedcrypto_provider::tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - rustls_mbedcrypto_provider::tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + cipher_suite::TLS13_AES_128_GCM_SHA256, + cipher_suite::TLS13_AES_256_GCM_SHA384, + cipher_suite::TLS13_CHACHA20_POLY1305_SHA256, + cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, ] { let version = suite.version(); println!("Testing suite {:?}", suite.suite().as_str()); // Only offer the cipher suite (and protocol version) that we're testing - let mut server_config = ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + let mut server_config = server_config_builder() .with_cipher_suites(&[suite]) .with_safe_default_kx_groups() .with_protocol_versions(&[version]) @@ -4265,11 +4338,11 @@ fn test_secret_extraction_enabled() { #[cfg(feature = "tls12")] #[test] fn test_secret_extraction_disabled_or_too_early() { - let suite = rustls_mbedcrypto_provider::tls13::TLS13_AES_128_GCM_SHA256; + let suite = cipher_suite::TLS13_AES_128_GCM_SHA256; let kt = KeyType::Rsa; for (server_enable, client_enable) in [(true, false), (false, true)] { - let mut server_config = ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + let mut server_config = server_config_builder() .with_cipher_suites(&[suite]) .with_safe_default_kx_groups() .with_safe_default_protocol_versions() @@ -4321,11 +4394,11 @@ fn test_secret_extraction_disabled_or_too_early() { #[test] fn test_received_plaintext_backpressure() { - let suite = rustls_mbedcrypto_provider::tls13::TLS13_AES_128_GCM_SHA256; + let suite = cipher_suite::TLS13_AES_128_GCM_SHA256; let kt = KeyType::Rsa; let server_config = Arc::new( - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_cipher_suites(&[suite]) .with_safe_default_kx_groups() .with_safe_default_protocol_versions() @@ -4411,7 +4484,7 @@ fn test_debug_server_name_from_string() { fn test_explicit_provider_selection() { let client_config = finish_client_config( KeyType::Rsa, - rustls::ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS).with_safe_defaults(), + rustls::ClientConfig::builder_with_provider(rustls::crypto::ring::RING).with_safe_defaults(), ); let server_config = finish_server_config( KeyType::Rsa, @@ -4453,16 +4526,24 @@ impl rustls::crypto::CryptoProvider for FaultyRandomProvider { fn default_kx_groups(&self) -> &'static [&'static (dyn rustls::crypto::SupportedKxGroup)] { self.parent.default_kx_groups() } + + fn load_private_key(&self, key_der: PrivateKeyDer<'static>) -> Result, Error> { + self.parent.load_private_key(key_der) + } + + fn signature_verification_algorithms(&self) -> rustls::WebPkiSupportedAlgorithms { + self.parent + .signature_verification_algorithms() + } } #[test] fn test_client_construction_fails_if_random_source_fails_in_first_request() { - static PROVIDER: FaultyRandomProvider = - FaultyRandomProvider { parent: rustls_mbedcrypto_provider::MBEDTLS, rand_queue: Mutex::new(b"") }; + static TEST_PROVIDER: FaultyRandomProvider = FaultyRandomProvider { parent: PROVIDER, rand_queue: Mutex::new(b"") }; let client_config = finish_client_config( KeyType::Rsa, - rustls::ClientConfig::builder_with_provider(&PROVIDER).with_safe_defaults(), + rustls::ClientConfig::builder_with_provider(&TEST_PROVIDER).with_safe_defaults(), ); assert_eq!( @@ -4473,14 +4554,12 @@ fn test_client_construction_fails_if_random_source_fails_in_first_request() { #[test] fn test_client_construction_fails_if_random_source_fails_in_second_request() { - static PROVIDER: FaultyRandomProvider = FaultyRandomProvider { - parent: rustls_mbedcrypto_provider::MBEDTLS, - rand_queue: Mutex::new(b"nice random number generator huh"), - }; + static TEST_PROVIDER: FaultyRandomProvider = + FaultyRandomProvider { parent: PROVIDER, rand_queue: Mutex::new(b"nice random number generator huh") }; let client_config = finish_client_config( KeyType::Rsa, - rustls::ClientConfig::builder_with_provider(&PROVIDER).with_safe_defaults(), + rustls::ClientConfig::builder_with_provider(&TEST_PROVIDER).with_safe_defaults(), ); assert_eq!( @@ -4491,8 +4570,8 @@ fn test_client_construction_fails_if_random_source_fails_in_second_request() { #[test] fn test_client_construction_requires_64_bytes_of_random_material() { - static PROVIDER: FaultyRandomProvider = FaultyRandomProvider { - parent: rustls_mbedcrypto_provider::MBEDTLS, + static TEST_PROVIDER: FaultyRandomProvider = FaultyRandomProvider { + parent: PROVIDER, rand_queue: Mutex::new( b"nice random number generator !!!\ it's really not very good is it?", @@ -4501,7 +4580,7 @@ fn test_client_construction_requires_64_bytes_of_random_material() { let client_config = finish_client_config( KeyType::Rsa, - rustls::ClientConfig::builder_with_provider(&PROVIDER).with_safe_defaults(), + rustls::ClientConfig::builder_with_provider(&TEST_PROVIDER).with_safe_defaults(), ); ClientConnection::new(Arc::new(client_config), server_name("localhost")) diff --git a/rustls-mbedcrypto-provider/tests/common/mod.rs b/rustls-mbedcrypto-provider/tests/common/mod.rs index 4d7b7b8..bb79190 100644 --- a/rustls-mbedcrypto-provider/tests/common/mod.rs +++ b/rustls-mbedcrypto-provider/tests/common/mod.rs @@ -14,7 +14,7 @@ use std::sync::Arc; use pki_types::{CertificateDer, CertificateRevocationListDer, PrivateKeyDer}; use webpki::extract_trust_anchor; -use rustls::client::ServerCertVerifierBuilder; +use rustls::client::{ServerCertVerifierBuilder, WebPkiServerVerifier}; use rustls::internal::msgs::codec::Reader; use rustls::internal::msgs::message::{Message, OpaqueMessage, PlainMessage}; use rustls::server::{ClientCertVerifierBuilder, WebPkiClientVerifier}; @@ -24,6 +24,9 @@ use rustls::RootCertStore; use rustls::{ClientConfig, ClientConnection}; use rustls::{ConnectionCommon, ServerConfig, ServerConnection, SideData}; +pub use rustls_mbedcrypto_provider as primary_provider; +pub use rustls_mbedcrypto_provider::MBEDTLS as PROVIDER; + macro_rules! embed_files { ( $( @@ -202,7 +205,12 @@ pub enum KeyType { Ed25519, } -pub static ALL_KEY_TYPES: [KeyType; 3] = [KeyType::Rsa, KeyType::Ecdsa, KeyType::Ed25519]; +pub static ALL_KEY_TYPES: [KeyType; 2] = [ + KeyType::Rsa, + KeyType::Ecdsa, + // ! Ed25519 is not supported by mbedtls + // KeyType::Ed25519, +]; impl KeyType { fn bytes_for(&self, part: &str) -> &'static [u8] { @@ -263,6 +271,33 @@ impl KeyType { } } +pub fn server_config_builder() -> rustls::ConfigBuilder { + // ensure `ServerConfig::builder()` is covered, even though it is + // equivalent to `builder_with_provider(PROVIDER)`. + #[cfg(feature = "ring")] + { + rustls::ServerConfig::builder() + } + #[cfg(not(feature = "ring"))] + { + rustls::ServerConfig::builder_with_provider(PROVIDER) + } +} + +pub fn client_config_builder() -> rustls::ConfigBuilder { + // ensure `ClientConfig::builder()` is covered, even though it is + // equivalent to `builder_with_provider(PROVIDER)`. + #[cfg(feature = "ring")] + { + rustls::ClientConfig::builder() + } + + #[cfg(not(feature = "ring"))] + { + rustls::ClientConfig::builder_with_provider(PROVIDER) + } +} + pub fn finish_server_config(kt: KeyType, conf: rustls::ConfigBuilder) -> ServerConfig { conf.with_no_client_auth() .with_single_cert(kt.get_chain(), kt.get_key()) @@ -270,16 +305,13 @@ pub fn finish_server_config(kt: KeyType, conf: rustls::ConfigBuilder ServerConfig { - finish_server_config( - kt, - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS).with_safe_defaults(), - ) + finish_server_config(kt, server_config_builder().with_safe_defaults()) } pub fn make_server_config_with_versions(kt: KeyType, versions: &[&'static rustls::SupportedProtocolVersion]) -> ServerConfig { finish_server_config( kt, - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() .with_protocol_versions(versions) @@ -293,7 +325,7 @@ pub fn make_server_config_with_kx_groups( ) -> ServerConfig { finish_server_config( kt, - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_safe_default_cipher_suites() .with_kx_groups(kx_groups) .with_safe_default_protocol_versions() @@ -318,11 +350,11 @@ pub fn make_server_config_with_mandatory_client_auth_crls( kt: KeyType, crls: Vec>, ) -> ServerConfig { - make_server_config_with_client_verifier(kt, WebPkiClientVerifier::builder(get_client_root_store(kt)).with_crls(crls)) + make_server_config_with_client_verifier(kt, webpki_client_verifier_builder(get_client_root_store(kt)).with_crls(crls)) } pub fn make_server_config_with_mandatory_client_auth(kt: KeyType) -> ServerConfig { - make_server_config_with_client_verifier(kt, WebPkiClientVerifier::builder(get_client_root_store(kt))) + make_server_config_with_client_verifier(kt, webpki_client_verifier_builder(get_client_root_store(kt))) } pub fn make_server_config_with_optional_client_auth( @@ -331,7 +363,7 @@ pub fn make_server_config_with_optional_client_auth( ) -> ServerConfig { make_server_config_with_client_verifier( kt, - WebPkiClientVerifier::builder(get_client_root_store(kt)) + webpki_client_verifier_builder(get_client_root_store(kt)) .with_crls(crls) .allow_unknown_revocation_status() .allow_unauthenticated(), @@ -339,7 +371,7 @@ pub fn make_server_config_with_optional_client_auth( } pub fn make_server_config_with_client_verifier(kt: KeyType, verifier_builder: ClientCertVerifierBuilder) -> ServerConfig { - ServerConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + server_config_builder() .with_safe_defaults() .with_client_cert_verifier(verifier_builder.build().unwrap()) .with_single_cert(kt.get_chain(), kt.get_key()) @@ -372,17 +404,14 @@ pub fn finish_client_config_with_creds( } pub fn make_client_config(kt: KeyType) -> ClientConfig { - finish_client_config( - kt, - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS).with_safe_defaults(), - ) + finish_client_config(kt, client_config_builder().with_safe_defaults()) } pub fn make_client_config_with_kx_groups( kt: KeyType, kx_groups: &[&'static dyn rustls::crypto::SupportedKxGroup], ) -> ClientConfig { - let builder = ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + let builder = client_config_builder() .with_safe_default_cipher_suites() .with_kx_groups(kx_groups) .with_safe_default_protocol_versions() @@ -391,7 +420,7 @@ pub fn make_client_config_with_kx_groups( } pub fn make_client_config_with_versions(kt: KeyType, versions: &[&'static rustls::SupportedProtocolVersion]) -> ClientConfig { - let builder = ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + let builder = client_config_builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() .with_protocol_versions(versions) @@ -400,17 +429,14 @@ pub fn make_client_config_with_versions(kt: KeyType, versions: &[&'static rustls } pub fn make_client_config_with_auth(kt: KeyType) -> ClientConfig { - finish_client_config_with_creds( - kt, - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS).with_safe_defaults(), - ) + finish_client_config_with_creds(kt, client_config_builder().with_safe_defaults()) } pub fn make_client_config_with_versions_with_auth( kt: KeyType, versions: &[&'static rustls::SupportedProtocolVersion], ) -> ClientConfig { - let builder = ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + let builder = client_config_builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() .with_protocol_versions(versions) @@ -422,7 +448,7 @@ pub fn make_client_config_with_verifier( versions: &[&'static rustls::SupportedProtocolVersion], verifier_builder: ServerCertVerifierBuilder, ) -> ClientConfig { - ClientConfig::builder_with_provider(rustls_mbedcrypto_provider::MBEDTLS) + client_config_builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() .with_protocol_versions(versions) @@ -432,6 +458,30 @@ pub fn make_client_config_with_verifier( .with_no_client_auth() } +pub fn webpki_client_verifier_builder(roots: Arc) -> ClientCertVerifierBuilder { + #[cfg(feature = "ring")] + { + WebPkiClientVerifier::builder(roots) + } + + #[cfg(not(feature = "ring"))] + { + WebPkiClientVerifier::builder_with_provider(roots, PROVIDER) + } +} + +pub fn webpki_server_verifier_builder(roots: Arc) -> ServerCertVerifierBuilder { + #[cfg(feature = "ring")] + { + WebPkiServerVerifier::builder(roots) + } + + #[cfg(not(feature = "ring"))] + { + WebPkiServerVerifier::builder_with_provider(roots, PROVIDER) + } +} + pub fn make_pair(kt: KeyType) -> (ClientConnection, ServerConnection) { make_pair_for_configs(make_client_config(kt), make_server_config(kt)) } diff --git a/rustls-mbedpki-provider/src/tests_common.rs b/rustls-mbedpki-provider/src/tests_common.rs index eea0459..945d5c3 100644 --- a/rustls-mbedpki-provider/src/tests_common.rs +++ b/rustls-mbedpki-provider/src/tests_common.rs @@ -7,7 +7,10 @@ use std::io; -use core::ops::{Deref, DerefMut}; +use core::{ + fmt::Debug, + ops::{Deref, DerefMut}, +}; use pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer, UnixTime}; use rustls::{client::danger::ServerCertVerifier, ClientConnection, ConnectionCommon, ServerConnection, SideData}; @@ -81,6 +84,15 @@ pub(crate) struct VerifierWithSupportedVerifySchemes { pub(crate) supported_verify_schemes: Vec, } +impl Debug for VerifierWithSupportedVerifySchemes { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("VerifierWithSupportedVerifySchemes") + .field("verifier", &"..") + .field("supported_verify_schemes", &self.supported_verify_schemes) + .finish() + } +} + impl ServerCertVerifier for VerifierWithSupportedVerifySchemes { fn verify_server_cert( &self, diff --git a/rustls-mbedtls-provider-utils/src/hash.rs b/rustls-mbedtls-provider-utils/src/hash.rs index 5ee68d3..fc37e52 100644 --- a/rustls-mbedtls-provider-utils/src/hash.rs +++ b/rustls-mbedtls-provider-utils/src/hash.rs @@ -11,10 +11,10 @@ fn hash_size_bytes(hash_type: Type) -> Option { Type::Md4 => Some(16), Type::Md5 => Some(16), Type::Sha1 => Some(20), - Type::Sha224 => Some(28), - Type::Sha256 => Some(32), - Type::Sha384 => Some(48), - Type::Sha512 => Some(64), + Type::Sha224 => Some(224 / 8), + Type::Sha256 => Some(256 / 8), + Type::Sha384 => Some(384 / 8), + Type::Sha512 => Some(512 / 8), Type::Ripemd => Some(20), // this is MD_RIPEMD160 } } From 1000ff4da136ae30f2ff0c9257c5a6a676424fde Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Thu, 16 Nov 2023 17:27:55 -0800 Subject: [PATCH 05/14] test: update test code to fit with mbedtls --- rustls-mbedcrypto-provider/tests/api.rs | 27 ++++++++++--------- .../tests/common/mod.rs | 4 +-- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/rustls-mbedcrypto-provider/tests/api.rs b/rustls-mbedcrypto-provider/tests/api.rs index aec31da..b62deed 100644 --- a/rustls-mbedcrypto-provider/tests/api.rs +++ b/rustls-mbedcrypto-provider/tests/api.rs @@ -480,7 +480,7 @@ fn test_config_builders_debug_mbedtls() { .with_protocol_versions(&[&rustls::version::TLS13]) .unwrap(); let b = b.with_no_client_auth(); - assert_eq!("ConfigBuilder { state: WantsServerCert { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Mbedtls, versions: [TLSv1_3], verifier: dyn ClientCertVerifier } }", format!("{:?}", b)); + assert_eq!("ConfigBuilder { state: WantsServerCert { cipher_suites: [TLS13_CHACHA20_POLY1305_SHA256], kx_groups: [X25519], provider: Mbedtls, versions: [TLSv1_3], verifier: NoClientAuth } }", format!("{:?}", b)); let b = client_config_builder(); assert_eq!( @@ -938,7 +938,8 @@ fn server_cert_resolve_reduces_sigalgs_for_ecdsa_ciphersuite() { vec![ SignatureScheme::ECDSA_NISTP384_SHA384, SignatureScheme::ECDSA_NISTP256_SHA256, - SignatureScheme::ED25519, + // mbedtls does not support ED25519 + // SignatureScheme::ED25519, ], ); } @@ -1248,7 +1249,8 @@ fn test_client_cert_resolve(key_type: KeyType, server_config: Arc, ProtocolVersion::TLSv1_2 => vec![ SignatureScheme::ECDSA_NISTP384_SHA384, SignatureScheme::ECDSA_NISTP256_SHA256, - SignatureScheme::ED25519, + // mbedtls does not support ED25519 + // SignatureScheme::ED25519, SignatureScheme::RSA_PSS_SHA512, SignatureScheme::RSA_PSS_SHA384, SignatureScheme::RSA_PSS_SHA256, @@ -1259,7 +1261,8 @@ fn test_client_cert_resolve(key_type: KeyType, server_config: Arc, ProtocolVersion::TLSv1_3 => vec![ SignatureScheme::ECDSA_NISTP384_SHA384, SignatureScheme::ECDSA_NISTP256_SHA256, - SignatureScheme::ED25519, + // mbedtls does not support ED25519 + // SignatureScheme::ED25519, SignatureScheme::RSA_PSS_SHA512, SignatureScheme::RSA_PSS_SHA384, SignatureScheme::RSA_PSS_SHA256, @@ -1297,7 +1300,7 @@ fn client_cert_resolve_default() { let expected_root_hint_subjects = vec![match key_type { KeyType::Rsa => &b"0\x1a1\x180\x16\x06\x03U\x04\x03\x0c\x0fponytown RSA CA"[..], KeyType::Ecdsa => &b"0\x1c1\x1a0\x18\x06\x03U\x04\x03\x0c\x11ponytown ECDSA CA"[..], - KeyType::Ed25519 => &b"0\x1c1\x1a0\x18\x06\x03U\x04\x03\x0c\x11ponytown EdDSA CA"[..], + // KeyType::Ed25519 => &b"0\x1c1\x1a0\x18\x06\x03U\x04\x03\x0c\x11ponytown EdDSA CA"[..], } .to_vec()]; @@ -1328,7 +1331,7 @@ fn client_cert_resolve_server_added_hint() { match key_type { KeyType::Rsa => &b"0\x1a1\x180\x16\x06\x03U\x04\x03\x0c\x0fponytown RSA CA"[..], KeyType::Ecdsa => &b"0\x1c1\x1a0\x18\x06\x03U\x04\x03\x0c\x11ponytown ECDSA CA"[..], - KeyType::Ed25519 => &b"0\x1c1\x1a0\x18\x06\x03U\x04\x03\x0c\x11ponytown EdDSA CA"[..], + // KeyType::Ed25519 => &b"0\x1c1\x1a0\x18\x06\x03U\x04\x03\x0c\x11ponytown EdDSA CA"[..], } .to_vec(), extra_name.clone(), @@ -3874,7 +3877,7 @@ fn test_server_mtu_reduction() { } fn check_client_max_fragment_size(size: usize) -> Option { - let mut client_config = make_client_config(KeyType::Ed25519); + let mut client_config = make_client_config(KeyType::Rsa); client_config.max_fragment_size = Some(size); ClientConnection::new(Arc::new(client_config), server_name("localhost")).err() } @@ -4046,13 +4049,13 @@ fn test_client_rejects_illegal_tls13_ccs() { #[cfg(feature = "tls12")] #[test] fn test_client_tls12_no_resume_after_server_downgrade() { - let mut client_config = common::make_client_config(KeyType::Ed25519); + let mut client_config = common::make_client_config(KeyType::Rsa); let client_storage = Arc::new(ClientStorage::new()); client_config.resumption = Resumption::store(client_storage.clone()); let client_config = Arc::new(client_config); let server_config_1 = Arc::new(common::finish_server_config( - KeyType::Ed25519, + KeyType::Rsa, server_config_builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() @@ -4061,7 +4064,7 @@ fn test_client_tls12_no_resume_after_server_downgrade() { )); let mut server_config_2 = common::finish_server_config( - KeyType::Ed25519, + KeyType::Rsa, server_config_builder() .with_safe_default_cipher_suites() .with_safe_default_kx_groups() @@ -4099,12 +4102,12 @@ fn test_client_tls12_no_resume_after_server_downgrade() { fn test_acceptor() { use rustls::server::Acceptor; - let client_config = Arc::new(make_client_config(KeyType::Ed25519)); + let client_config = Arc::new(make_client_config(KeyType::Rsa)); let mut client = ClientConnection::new(client_config, server_name("localhost")).unwrap(); let mut buf = Vec::new(); client.write_tls(&mut buf).unwrap(); - let server_config = Arc::new(make_server_config(KeyType::Ed25519)); + let server_config = Arc::new(make_server_config(KeyType::Rsa)); let mut acceptor = Acceptor::default(); acceptor .read_tls(&mut buf.as_slice()) diff --git a/rustls-mbedcrypto-provider/tests/common/mod.rs b/rustls-mbedcrypto-provider/tests/common/mod.rs index bb79190..ef85ae7 100644 --- a/rustls-mbedcrypto-provider/tests/common/mod.rs +++ b/rustls-mbedcrypto-provider/tests/common/mod.rs @@ -202,7 +202,7 @@ where pub enum KeyType { Rsa, Ecdsa, - Ed25519, + // Ed25519, } pub static ALL_KEY_TYPES: [KeyType; 2] = [ @@ -217,7 +217,7 @@ impl KeyType { match self { Self::Rsa => bytes_for("rsa", part), Self::Ecdsa => bytes_for("ecdsa", part), - Self::Ed25519 => bytes_for("eddsa", part), + // Self::Ed25519 => bytes_for("eddsa", part), } } From a2faaa8f583eaaead4bb1f192ef573ef7f6d1277 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Thu, 16 Nov 2023 17:43:12 -0800 Subject: [PATCH 06/14] fix implementation --- Cargo.lock | 21 ++- rustls-mbedcrypto-provider/Cargo.toml | 15 ++- rustls-mbedcrypto-provider/src/lib.rs | 27 ++-- rustls-mbedcrypto-provider/src/sign.rs | 125 ++++++++++++------ .../src/signature_verify_algo.rs | 70 +++++++--- 5 files changed, 179 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bebee03..6f4b765 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,6 +106,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -416,7 +422,7 @@ dependencies = [ "rs-libc", "serde", "serde_derive", - "yasna", + "yasna 0.2.2", ] [[package]] @@ -670,6 +676,7 @@ dependencies = [ name = "rustls-mbedcrypto-provider" version = "0.0.1-alpha.1" dependencies = [ + "bit-vec 0.6.3", "env_logger", "log", "mbedtls", @@ -679,6 +686,7 @@ dependencies = [ "rustls-pki-types", "rustls-webpki", "webpki-roots", + "yasna 0.3.2", ] [[package]] @@ -1152,10 +1160,19 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79af3189e6b0484c9fd54208f8eeb8818cadee00ec81438b67a64c8e6f2f3694" dependencies = [ - "bit-vec", + "bit-vec 0.5.1", "num-bigint 0.2.6", ] +[[package]] +name = "yasna" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de7bff972b4f2a06c85f6d8454b09df153af7e3a4ec2aac81db1b105b684ddb" +dependencies = [ + "bit-vec 0.6.3", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/rustls-mbedcrypto-provider/Cargo.toml b/rustls-mbedcrypto-provider/Cargo.toml index adc0691..9109690 100644 --- a/rustls-mbedcrypto-provider/Cargo.toml +++ b/rustls-mbedcrypto-provider/Cargo.toml @@ -20,8 +20,13 @@ log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "0.2.1", features = [ "std", ] } -webpki = { package = "rustls-webpki", version = "0.102.0-alpha.6", features = ["alloc", "std"], default-features = false } +webpki = { package = "rustls-webpki", version = "0.102.0-alpha.6", features = [ + "alloc", + "std", +], default-features = false } utils = { package = "rustls-mbedtls-provider-utils", path = "../rustls-mbedtls-provider-utils", version = "0.1.0-alpha.1" } +yasna = { version = "0.3", default-features = false, features = ["bit-vec"] } +bit-vec = "0.6.3" [target.'cfg(target_env = "msvc")'.dependencies] # mbedtls need feature `time` to build when targeting msvc @@ -34,12 +39,8 @@ mbedtls = { version = "0.12.0-alpha.2", default-features = false, features = [ rustls = { version = "0.22.0-alpha.4", default-features = false, features = [ "ring", ] } -webpki = { package = "rustls-webpki", version = "0.102.0-alpha.1", default-features = false, features = [ - "alloc", - "std", -] } -webpki-roots = "0.26.0-alpha.1" -rustls-pemfile = "2.0.0-alpha.1" +webpki-roots = "=0.26.0-alpha.1" +rustls-pemfile = "=2.0.0-alpha.1" env_logger = "0.10" log = { version = "0.4.4" } diff --git a/rustls-mbedcrypto-provider/src/lib.rs b/rustls-mbedcrypto-provider/src/lib.rs index 3ef0f5c..b491c9f 100644 --- a/rustls-mbedcrypto-provider/src/lib.rs +++ b/rustls-mbedcrypto-provider/src/lib.rs @@ -146,7 +146,7 @@ impl rustls::crypto::CryptoProvider for Mbedtls { &self, key_der: pki_types::PrivateKeyDer<'static>, ) -> Result, rustls::Error> { - Ok(alloc::sync::Arc::new(MbedTlsPkSigningKey::new(&key_der)?)) + Ok(alloc::sync::Arc::new(sign::MbedTlsPkSigningKey::new(&key_der)?)) } fn signature_verification_algorithms(&self) -> WebPkiSupportedAlgorithms { @@ -197,29 +197,37 @@ pub mod cipher_suite { static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms { all: &[ signature_verify_algo::ECDSA_P256_SHA256, + signature_verify_algo::ECDSA_P256_SHA384, + signature_verify_algo::ECDSA_P384_SHA256, signature_verify_algo::ECDSA_P384_SHA384, - signature_verify_algo::RSA_PKCS1_SHA256, - signature_verify_algo::RSA_PKCS1_SHA384, - signature_verify_algo::RSA_PKCS1_SHA512, signature_verify_algo::RSA_PSS_SHA256, signature_verify_algo::RSA_PSS_SHA384, signature_verify_algo::RSA_PSS_SHA512, + signature_verify_algo::RSA_PKCS1_SHA256, + signature_verify_algo::RSA_PKCS1_SHA384, + signature_verify_algo::RSA_PKCS1_SHA512, ], mapping: &[ ( SignatureScheme::ECDSA_NISTP384_SHA384, - &[signature_verify_algo::ECDSA_P384_SHA384], + &[ + signature_verify_algo::ECDSA_P384_SHA384, + signature_verify_algo::ECDSA_P256_SHA384, + ], ), ( SignatureScheme::ECDSA_NISTP256_SHA256, - &[signature_verify_algo::ECDSA_P256_SHA256], + &[ + signature_verify_algo::ECDSA_P256_SHA256, + signature_verify_algo::ECDSA_P384_SHA256, + ], ), - (SignatureScheme::RSA_PKCS1_SHA512, &[signature_verify_algo::RSA_PKCS1_SHA512]), - (SignatureScheme::RSA_PKCS1_SHA384, &[signature_verify_algo::RSA_PKCS1_SHA384]), - (SignatureScheme::RSA_PKCS1_SHA256, &[signature_verify_algo::RSA_PKCS1_SHA256]), (SignatureScheme::RSA_PSS_SHA512, &[signature_verify_algo::RSA_PSS_SHA512]), (SignatureScheme::RSA_PSS_SHA384, &[signature_verify_algo::RSA_PSS_SHA384]), (SignatureScheme::RSA_PSS_SHA256, &[signature_verify_algo::RSA_PSS_SHA256]), + (SignatureScheme::RSA_PKCS1_SHA512, &[signature_verify_algo::RSA_PKCS1_SHA512]), + (SignatureScheme::RSA_PKCS1_SHA384, &[signature_verify_algo::RSA_PKCS1_SHA384]), + (SignatureScheme::RSA_PKCS1_SHA256, &[signature_verify_algo::RSA_PKCS1_SHA256]), ], }; @@ -234,4 +242,3 @@ pub mod kx_group { } pub use kx::ALL_KX_GROUPS; -use sign::MbedTlsPkSigningKey; diff --git a/rustls-mbedcrypto-provider/src/sign.rs b/rustls-mbedcrypto-provider/src/sign.rs index 8c74090..7ea1dd7 100644 --- a/rustls-mbedcrypto-provider/src/sign.rs +++ b/rustls-mbedcrypto-provider/src/sign.rs @@ -1,13 +1,15 @@ +use alloc::string::String; use alloc::vec; use alloc::{boxed::Box, sync::Arc, vec::Vec}; use core::fmt::Debug; -use mbedtls::pk::ECDSA_MAX_LEN; +use mbedtls::pk::{EcGroupId, ECDSA_MAX_LEN}; +use rustls::SignatureScheme; use std::sync::Mutex; use utils::error::mbedtls_err_into_rustls_err; use utils::hash::{buffer_for_hash_type, rustls_signature_scheme_to_mbedtls_hash_type}; use utils::pk::rustls_signature_scheme_to_mbedtls_pk_options; -struct MbedTlsSigner(Arc>, rustls::SignatureScheme); +struct MbedTlsSigner(Arc>, SignatureScheme); impl Debug for MbedTlsSigner { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { @@ -51,7 +53,7 @@ impl rustls::sign::Signer for MbedTlsSigner { Ok(sig) } - fn scheme(&self) -> rustls::SignatureScheme { + fn scheme(&self) -> SignatureScheme { self.1 } } @@ -59,12 +61,20 @@ impl rustls::sign::Signer for MbedTlsSigner { /// A [`SigningKey`] implemented by using [`mbedtls`] /// /// [`SigningKey`]: rustls::sign::SigningKey -pub struct MbedTlsPkSigningKey(pub Arc>); +pub struct MbedTlsPkSigningKey { + pk: Arc>, + pk_type: mbedtls::pk::Type, + signature_algorithm: rustls::SignatureAlgorithm, + ec_signature_scheme: Option, +} impl Debug for MbedTlsPkSigningKey { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_tuple("MbedTlsPkSigningKey") - .field(&"Arc>") + f.debug_struct("MbedTlsPkSigningKey") + .field("pk", &"Arc>") + .field("pk_type", &self.pk_type) + .field("signature_algorithm", &self.signature_algorithm) + .field("ec_signature_scheme", &self.ec_signature_scheme) .finish() } } @@ -74,50 +84,87 @@ impl MbedTlsPkSigningKey { pub fn new(der: &pki_types::PrivateKeyDer<'_>) -> Result { let pk = mbedtls::pk::Pk::from_private_key(der.secret_der(), None) .map_err(|err| rustls::Error::Other(rustls::OtherError(alloc::sync::Arc::new(err))))?; - - Ok(Self(alloc::sync::Arc::new(std::sync::Mutex::new(pk)))) + let pk_type = pk.pk_type(); + let signature_algorithm = pk_type_to_signature_algo(pk_type); + let ec_signature_scheme = if signature_algorithm == rustls::SignatureAlgorithm::ECDSA { + Some( + match pk + .curve() + .map_err(|err| rustls::Error::Other(rustls::OtherError(alloc::sync::Arc::new(err))))? + { + EcGroupId::SecP256R1 => SignatureScheme::ECDSA_NISTP256_SHA256, + EcGroupId::SecP384R1 => SignatureScheme::ECDSA_NISTP384_SHA384, + EcGroupId::SecP521R1 => SignatureScheme::ECDSA_NISTP521_SHA512, + _ => { + return Err(rustls::Error::General(String::from( + "MbedTlsPkSigningKey: unsupported ec curve", + ))) + } + }, + ) + } else { + None + }; + Ok(Self { + pk: alloc::sync::Arc::new(std::sync::Mutex::new(pk)), + pk_type, + signature_algorithm, + ec_signature_scheme, + }) } } +const RSA_SIGNATURE_SCHEME_PREFER_LIST: &[SignatureScheme] = &[ + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA512, + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, +]; + impl rustls::sign::SigningKey for MbedTlsPkSigningKey { - fn choose_scheme(&self, offered: &[rustls::SignatureScheme]) -> Option> { - let pk_type = self - .0 - .lock() - .expect("poisoned pk lock") - .pk_type(); - for scheme in offered { - let scheme_type = utils::pk::rustls_signature_scheme_to_mbedtls_pk_type(scheme); - if let Some(mut scheme_type) = scheme_type { - // TODO: better handling logic here. - if scheme_type == mbedtls::pk::Type::Ecdsa { - scheme_type = mbedtls::pk::Type::Eckey; + fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option> { + match self.pk_type { + mbedtls::pk::Type::Rsa | mbedtls::pk::Type::RsaAlt | mbedtls::pk::Type::RsassaPss => { + // choose a rsa schema + for scheme in RSA_SIGNATURE_SCHEME_PREFER_LIST { + if offered.contains(scheme) { + let signer = MbedTlsSigner(self.pk.clone(), *scheme); + return Some(Box::new(signer)); + } } - if scheme_type == pk_type { - let signer = MbedTlsSigner(self.0.clone(), *scheme); + None + } + mbedtls::pk::Type::Eckey | mbedtls::pk::Type::EckeyDh | mbedtls::pk::Type::Ecdsa => { + let scheme = self + .ec_signature_scheme + .expect("validated"); + if offered.contains(&scheme) { + let signer = MbedTlsSigner(self.pk.clone(), scheme); return Some(Box::new(signer)); } + None } + _ => None, } - None } fn algorithm(&self) -> rustls::SignatureAlgorithm { - use rustls::SignatureAlgorithm; - match self - .0 - .lock() - .expect("poisoned pk lock") - .pk_type() - { - mbedtls::pk::Type::Rsa => SignatureAlgorithm::RSA, - mbedtls::pk::Type::Ecdsa => SignatureAlgorithm::ECDSA, - mbedtls::pk::Type::RsassaPss => SignatureAlgorithm::RSA, - mbedtls::pk::Type::RsaAlt => SignatureAlgorithm::RSA, - mbedtls::pk::Type::Eckey => SignatureAlgorithm::ECDSA, - mbedtls::pk::Type::EckeyDh => SignatureAlgorithm::Unknown(255), - mbedtls::pk::Type::Custom => SignatureAlgorithm::Unknown(255), - mbedtls::pk::Type::None => SignatureAlgorithm::Unknown(255), - } + self.signature_algorithm + } +} + +fn pk_type_to_signature_algo(pk_type: mbedtls::pk::Type) -> rustls::SignatureAlgorithm { + use rustls::SignatureAlgorithm; + match pk_type { + mbedtls::pk::Type::Rsa => SignatureAlgorithm::RSA, + mbedtls::pk::Type::Ecdsa => SignatureAlgorithm::ECDSA, + mbedtls::pk::Type::RsassaPss => SignatureAlgorithm::RSA, + mbedtls::pk::Type::RsaAlt => SignatureAlgorithm::RSA, + mbedtls::pk::Type::Eckey => SignatureAlgorithm::ECDSA, + mbedtls::pk::Type::EckeyDh => SignatureAlgorithm::Unknown(255), + mbedtls::pk::Type::Custom => SignatureAlgorithm::Unknown(255), + mbedtls::pk::Type::None => SignatureAlgorithm::Unknown(255), } } diff --git a/rustls-mbedcrypto-provider/src/signature_verify_algo.rs b/rustls-mbedcrypto-provider/src/signature_verify_algo.rs index 20c3412..c7f5922 100644 --- a/rustls-mbedcrypto-provider/src/signature_verify_algo.rs +++ b/rustls-mbedcrypto-provider/src/signature_verify_algo.rs @@ -1,6 +1,6 @@ use super::hash::Algorithm as HashAlgorithm; use alloc::vec; -use mbedtls::pk::Pk; +use mbedtls::pk::{EcGroupId, Pk}; use pki_types::{AlgorithmIdentifier, InvalidSignature, SignatureVerificationAlgorithm}; use rustls::SignatureScheme; use webpki::alg_id; @@ -10,6 +10,15 @@ pub static ECDSA_P256_SHA256: &Algorithm = &Algorithm { signature_scheme: SignatureScheme::ECDSA_NISTP256_SHA256, hash_algo: &super::hash::MBED_SHA_256, public_key_alg_id: alg_id::ECDSA_P256, + ec_group_id: Some(EcGroupId::SecP256R1), + signature_alg_id: alg_id::ECDSA_SHA256, +}; +/// ECDSA signatures using the P-384 curve and SHA-256. +pub static ECDSA_P384_SHA256: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::ECDSA_NISTP256_SHA256, + hash_algo: &super::hash::MBED_SHA_256, + public_key_alg_id: alg_id::ECDSA_P384, + ec_group_id: Some(EcGroupId::SecP384R1), signature_alg_id: alg_id::ECDSA_SHA256, }; /// ECDSA signatures using the P-384 curve and SHA-384. @@ -17,6 +26,15 @@ pub static ECDSA_P384_SHA384: &Algorithm = &Algorithm { signature_scheme: SignatureScheme::ECDSA_NISTP384_SHA384, hash_algo: &super::hash::MBED_SHA_384, public_key_alg_id: alg_id::ECDSA_P384, + ec_group_id: Some(EcGroupId::SecP384R1), + signature_alg_id: alg_id::ECDSA_SHA384, +}; +/// ECDSA signatures using the P-256 curve and SHA-384. +pub static ECDSA_P256_SHA384: &Algorithm = &Algorithm { + signature_scheme: SignatureScheme::ECDSA_NISTP384_SHA384, + hash_algo: &super::hash::MBED_SHA_384, + public_key_alg_id: alg_id::ECDSA_P256, + ec_group_id: Some(EcGroupId::SecP256R1), signature_alg_id: alg_id::ECDSA_SHA384, }; /// RSA PKCS#1 1.5 signatures using SHA-256. @@ -24,6 +42,7 @@ pub static RSA_PKCS1_SHA256: &Algorithm = &Algorithm { signature_scheme: SignatureScheme::RSA_PKCS1_SHA256, hash_algo: &super::hash::MBED_SHA_256, public_key_alg_id: alg_id::RSA_ENCRYPTION, + ec_group_id: None, signature_alg_id: alg_id::RSA_PKCS1_SHA256, }; /// RSA PKCS#1 1.5 signatures using SHA-384. @@ -31,6 +50,7 @@ pub static RSA_PKCS1_SHA384: &Algorithm = &Algorithm { signature_scheme: SignatureScheme::RSA_PKCS1_SHA384, hash_algo: &super::hash::MBED_SHA_384, public_key_alg_id: alg_id::RSA_ENCRYPTION, + ec_group_id: None, signature_alg_id: alg_id::RSA_PKCS1_SHA384, }; /// RSA PKCS#1 1.5 signatures using SHA-512. @@ -38,6 +58,7 @@ pub static RSA_PKCS1_SHA512: &Algorithm = &Algorithm { signature_scheme: SignatureScheme::RSA_PKCS1_SHA512, hash_algo: &super::hash::MBED_SHA_512, public_key_alg_id: alg_id::RSA_ENCRYPTION, + ec_group_id: None, signature_alg_id: alg_id::RSA_PKCS1_SHA512, }; /// RSA PSS signatures using SHA-256 and of @@ -48,6 +69,7 @@ pub static RSA_PSS_SHA256: &Algorithm = &Algorithm { signature_scheme: SignatureScheme::RSA_PSS_SHA256, hash_algo: &super::hash::MBED_SHA_256, public_key_alg_id: alg_id::RSA_ENCRYPTION, + ec_group_id: None, signature_alg_id: alg_id::RSA_PSS_SHA256, }; /// RSA PSS signatures using SHA-384 and of @@ -58,6 +80,7 @@ pub static RSA_PSS_SHA384: &Algorithm = &Algorithm { signature_scheme: SignatureScheme::RSA_PSS_SHA384, hash_algo: &super::hash::MBED_SHA_384, public_key_alg_id: alg_id::RSA_ENCRYPTION, + ec_group_id: None, signature_alg_id: alg_id::RSA_PSS_SHA384, }; /// RSA PSS signatures using SHA-512 and of @@ -68,6 +91,7 @@ pub static RSA_PSS_SHA512: &Algorithm = &Algorithm { signature_scheme: SignatureScheme::RSA_PSS_SHA512, hash_algo: &super::hash::MBED_SHA_512, public_key_alg_id: alg_id::RSA_ENCRYPTION, + ec_group_id: None, signature_alg_id: alg_id::RSA_PSS_SHA512, }; @@ -77,40 +101,44 @@ pub struct Algorithm { signature_scheme: SignatureScheme, hash_algo: &'static HashAlgorithm, public_key_alg_id: AlgorithmIdentifier, + ec_group_id: Option, signature_alg_id: AlgorithmIdentifier, } impl SignatureVerificationAlgorithm for Algorithm { fn verify_signature(&self, public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<(), InvalidSignature> { - let mut pk = Pk::from_public_key(public_key).map_err(|e| { - crate::log::error!("{e}"); - InvalidSignature - })?; - let signature_curve = utils::pk::rustls_signature_scheme_to_mbedtls_curve_id(self.signature_scheme); - match signature_curve { - mbedtls::pk::EcGroupId::None => (), - _ => { - let curves_match = pk + let mut pk = match self.ec_group_id { + None => Pk::from_public_key(public_key).map_err(|_| InvalidSignature)?, + Some(ec_group_id) => { + let spki = yasna::construct_der(|writer| { + writer.write_sequence(|writer| { + writer.next().write_sequence(|w| { + w.next() + .write_der(&self.public_key_alg_id) + }); + writer + .next() + .write_bitvec(&bit_vec::BitVec::from_bytes(public_key)); + }) + }); + let ec_pk = Pk::from_public_key(&spki).map_err(|_| InvalidSignature)?; + let curves_match = ec_pk .curve() - .is_ok_and(|pk_curve| pk_curve == signature_curve); + .is_ok_and(|pk_curve| pk_curve == ec_group_id); if !curves_match { return Err(InvalidSignature); - } + }; + ec_pk } - } + }; + if let Some(opts) = utils::pk::rustls_signature_scheme_to_mbedtls_pk_options(self.signature_scheme) { pk.set_options(opts); } let mut hash = vec![0u8; self.hash_algo.output_len]; - mbedtls::hash::Md::hash(self.hash_algo.hash_type, message, &mut hash).map_err(|e| { - crate::log::error!("{e}"); - InvalidSignature - })?; + mbedtls::hash::Md::hash(self.hash_algo.hash_type, message, &mut hash).map_err(|_| InvalidSignature)?; pk.verify(self.hash_algo.hash_type, &hash, signature) - .map_err(|e| { - crate::log::error!("{e}"); - InvalidSignature - }) + .map_err(|_| InvalidSignature) } fn public_key_alg_id(&self) -> AlgorithmIdentifier { From e273d530f5320d111b2596b8c5e6f1b7eb8f75bc Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Thu, 16 Nov 2023 23:18:42 -0800 Subject: [PATCH 07/14] fix clippy --- .gitignore | 1 + rustls-mbedcrypto-provider/src/sign.rs | 4 ++-- rustls-mbedcrypto-provider/tests/api.rs | 7 ++++--- rustls-mbedpki-provider/src/client_cert_verifier.rs | 4 ++-- rustls-mbedpki-provider/src/server_cert_verifier.rs | 4 ++-- rustls-mbedtls-provider-utils/src/pk.rs | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index d26870e..b5e07eb 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ admin/rustfmt **/._.DS_Store /.idea /default.profraw +.cargo/ diff --git a/rustls-mbedcrypto-provider/src/sign.rs b/rustls-mbedcrypto-provider/src/sign.rs index 7ea1dd7..d949f66 100644 --- a/rustls-mbedcrypto-provider/src/sign.rs +++ b/rustls-mbedcrypto-provider/src/sign.rs @@ -130,7 +130,7 @@ impl rustls::sign::SigningKey for MbedTlsPkSigningKey { // choose a rsa schema for scheme in RSA_SIGNATURE_SCHEME_PREFER_LIST { if offered.contains(scheme) { - let signer = MbedTlsSigner(self.pk.clone(), *scheme); + let signer = MbedTlsSigner(Arc::clone(&self.pk), *scheme); return Some(Box::new(signer)); } } @@ -141,7 +141,7 @@ impl rustls::sign::SigningKey for MbedTlsPkSigningKey { .ec_signature_scheme .expect("validated"); if offered.contains(&scheme) { - let signer = MbedTlsSigner(self.pk.clone(), scheme); + let signer = MbedTlsSigner(Arc::clone(&self.pk), scheme); return Some(Box::new(signer)); } None diff --git a/rustls-mbedcrypto-provider/tests/api.rs b/rustls-mbedcrypto-provider/tests/api.rs index b62deed..8946a31 100644 --- a/rustls-mbedcrypto-provider/tests/api.rs +++ b/rustls-mbedcrypto-provider/tests/api.rs @@ -9,8 +9,8 @@ #![cfg_attr(read_buf, feature(core_io_borrowed_buf))] //! Assorted public API tests. use std::cell::RefCell; -use std::fmt; -use std::fmt::Debug; +use core::fmt; +use core::fmt::Debug; use std::io::{self, IoSlice, Read, Write}; use std::mem; use std::ops::{Deref, DerefMut}; @@ -35,7 +35,7 @@ use rustls::{ }; use rustls::{CipherSuite, ProtocolVersion, SignatureScheme}; use rustls::{ClientConfig, ClientConnection}; -use rustls::{ConnectionTrafficSecrets, DistinguishedName}; +use rustls::DistinguishedName; use rustls::{ServerConfig, ServerConnection}; use rustls::{Stream, StreamOwned}; @@ -4263,6 +4263,7 @@ fn test_no_warning_logging_during_successful_sessions() { #[cfg(feature = "tls12")] #[test] fn test_secret_extraction_enabled() { + use rustls::ConnectionTrafficSecrets; // Normally, secret extraction would be used to configure kTLS (TLS offload // to the kernel). We want this test to run on any platform, though, so // instead we just compare secrets for equality. diff --git a/rustls-mbedpki-provider/src/client_cert_verifier.rs b/rustls-mbedpki-provider/src/client_cert_verifier.rs index d1ba8aa..e99c328 100644 --- a/rustls-mbedpki-provider/src/client_cert_verifier.rs +++ b/rustls-mbedpki-provider/src/client_cert_verifier.rs @@ -31,8 +31,8 @@ pub struct MbedTlsClientCertVerifier { cert_active_check: CertActiveCheck, } -impl std::fmt::Debug for MbedTlsClientCertVerifier { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for MbedTlsClientCertVerifier { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("MbedTlsClientCertVerifier") .field("trusted_cas", &"..") .field("root_subjects", &self.root_subjects) diff --git a/rustls-mbedpki-provider/src/server_cert_verifier.rs b/rustls-mbedpki-provider/src/server_cert_verifier.rs index b90b8fd..ef4d265 100644 --- a/rustls-mbedpki-provider/src/server_cert_verifier.rs +++ b/rustls-mbedpki-provider/src/server_cert_verifier.rs @@ -30,8 +30,8 @@ pub struct MbedTlsServerCertVerifier { cert_active_check: CertActiveCheck, } -impl std::fmt::Debug for MbedTlsServerCertVerifier { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for MbedTlsServerCertVerifier { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("MbedTlsServerCertVerifier") .field("trusted_cas", &"..") .field("verify_callback", &"..") diff --git a/rustls-mbedtls-provider-utils/src/pk.rs b/rustls-mbedtls-provider-utils/src/pk.rs index 41be1e7..cea9183 100644 --- a/rustls-mbedtls-provider-utils/src/pk.rs +++ b/rustls-mbedtls-provider-utils/src/pk.rs @@ -32,7 +32,7 @@ pub fn get_pk_supported_scheme(pk_type: &Type, offered: &[SignatureScheme]) -> O } } } - return None; + None } /// Helper function to get the corresponding [`rustls::SignatureAlgorithm`] of given [`mbedtls::pk::Pk`] From a10633d1c9525674a245f34bf69150661e88c700 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Nov 2023 00:38:21 -0800 Subject: [PATCH 08/14] test: add more unit tests --- rustls-mbedcrypto-provider/tests/api.rs | 4 +- .../src/client_cert_verifier.rs | 10 ++ .../src/server_cert_verifier.rs | 10 ++ rustls-mbedpki-provider/src/tests_common.rs | 18 ++++ rustls-mbedtls-provider-utils/src/error.rs | 58 ++++++++++ rustls-mbedtls-provider-utils/src/hash.rs | 100 +++++++++++++++++- rustls-mbedtls-provider-utils/src/pk.rs | 67 +++++++++--- 7 files changed, 250 insertions(+), 17 deletions(-) diff --git a/rustls-mbedcrypto-provider/tests/api.rs b/rustls-mbedcrypto-provider/tests/api.rs index 8946a31..84074ee 100644 --- a/rustls-mbedcrypto-provider/tests/api.rs +++ b/rustls-mbedcrypto-provider/tests/api.rs @@ -8,9 +8,9 @@ #![cfg_attr(read_buf, feature(read_buf))] #![cfg_attr(read_buf, feature(core_io_borrowed_buf))] //! Assorted public API tests. -use std::cell::RefCell; use core::fmt; use core::fmt::Debug; +use std::cell::RefCell; use std::io::{self, IoSlice, Read, Write}; use std::mem; use std::ops::{Deref, DerefMut}; @@ -28,6 +28,7 @@ use rustls::internal::msgs::enums::AlertLevel; use rustls::internal::msgs::handshake::{ClientExtension, HandshakePayload}; use rustls::internal::msgs::message::{Message, MessagePayload, PlainMessage}; use rustls::server::{ClientHello, ParsedCertificate, ResolvesServerCert}; +use rustls::DistinguishedName; use rustls::SupportedCipherSuite; use rustls::{ sign, AlertDescription, CertificateError, ConnectionCommon, ContentType, Error, KeyLog, PeerIncompatible, PeerMisbehaved, @@ -35,7 +36,6 @@ use rustls::{ }; use rustls::{CipherSuite, ProtocolVersion, SignatureScheme}; use rustls::{ClientConfig, ClientConnection}; -use rustls::DistinguishedName; use rustls::{ServerConfig, ServerConnection}; use rustls::{Stream, StreamOwned}; diff --git a/rustls-mbedpki-provider/src/client_cert_verifier.rs b/rustls-mbedpki-provider/src/client_cert_verifier.rs index e99c328..a3f7f2d 100644 --- a/rustls-mbedpki-provider/src/client_cert_verifier.rs +++ b/rustls-mbedpki-provider/src/client_cert_verifier.rs @@ -211,6 +211,16 @@ mod tests { .unwrap() } + #[test] + fn client_cert_verifier_debug() { + let root_ca = CertificateDer::from(include_bytes!("../test-data/rsa/ca.der").to_vec()); + let client_cert_verifier = MbedTlsClientCertVerifier::new([&root_ca]).unwrap(); + assert_eq!( + r#"MbedTlsClientCertVerifier { trusted_cas: "..", root_subjects: [DistinguishedName(301a3118301606035504030c0f706f6e79746f776e20525341204341)], verify_callback: "..", cert_active_check: CertActiveCheck { ignore_expired: false, ignore_not_active_yet: false } }"#, + format!("{:?}", client_cert_verifier) + ); + } + #[test] fn connection_client_cert_verifier() { let client_config = ClientConfig::builder().with_safe_defaults(); diff --git a/rustls-mbedpki-provider/src/server_cert_verifier.rs b/rustls-mbedpki-provider/src/server_cert_verifier.rs index ef4d265..ac4ee17 100644 --- a/rustls-mbedpki-provider/src/server_cert_verifier.rs +++ b/rustls-mbedpki-provider/src/server_cert_verifier.rs @@ -223,6 +223,16 @@ mod tests { .with_no_client_auth() } + #[test] + fn server_cert_verifier_debug() { + let root_ca = CertificateDer::from(include_bytes!("../test-data/rsa/ca.der").to_vec()); + let server_cert_verifier = MbedTlsServerCertVerifier::new([&root_ca]).unwrap(); + assert_eq!( + "MbedTlsServerCertVerifier { trusted_cas: \"..\", verify_callback: \"..\", cert_active_check: CertActiveCheck { ignore_expired: false, ignore_not_active_yet: false } }", + format!("{:?}", server_cert_verifier) + ); + } + fn test_connection_server_cert_verifier_with_invalid_certs( invalid_cert_chain: Vec>, ) -> rustls::Error { diff --git a/rustls-mbedpki-provider/src/tests_common.rs b/rustls-mbedpki-provider/src/tests_common.rs index 945d5c3..950f934 100644 --- a/rustls-mbedpki-provider/src/tests_common.rs +++ b/rustls-mbedpki-provider/src/tests_common.rs @@ -130,3 +130,21 @@ impl ServerCertVerifier for VerifierWithSupportedVerifySc self.supported_verify_schemes.clone() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn verifier_with_supported_verify_schemes_debug() { + let verifier = VerifierWithSupportedVerifySchemes { + verifier: "Sample Verifier".to_string(), + supported_verify_schemes: vec![ + rustls::SignatureScheme::RSA_PKCS1_SHA1, + rustls::SignatureScheme::ECDSA_NISTP521_SHA512, + ], + }; + + assert_eq!("VerifierWithSupportedVerifySchemes { verifier: \"..\", supported_verify_schemes: [RSA_PKCS1_SHA1, ECDSA_NISTP521_SHA512] }",format!("{:?}", verifier)); + } +} diff --git a/rustls-mbedtls-provider-utils/src/error.rs b/rustls-mbedtls-provider-utils/src/error.rs index e9a8a21..03d310f 100644 --- a/rustls-mbedtls-provider-utils/src/error.rs +++ b/rustls-mbedtls-provider-utils/src/error.rs @@ -37,3 +37,61 @@ pub fn mbedtls_err_into_rustls_err_with_error_msg(err: mbedtls::Error, msg: &str _ => rustls::Error::General(format!("{err}{sep}{msg}", sep = if msg.is_empty() {""} else {"\n"})), } } + +#[cfg(test)] +mod tests { + use super::*; + use rustls::CertificateError; + + #[test] + fn test_mbedtls_err_into_rustls_err() { + assert_eq!( + mbedtls_err_into_rustls_err(mbedtls::Error::X509InvalidSignature), + rustls::Error::InvalidCertificate(CertificateError::BadSignature) + ); + assert_eq!( + mbedtls_err_into_rustls_err(mbedtls::Error::X509BadInputData), + rustls::Error::InvalidCertificate(CertificateError::BadEncoding) + ); + assert_eq!( + mbedtls_err_into_rustls_err(mbedtls::Error::X509InvalidName), + rustls::Error::InvalidCertificate(CertificateError::NotValidForName) + ); + } + + #[test] + fn test_mbedtls_err_into_rustls_err_with_error_msg() { + assert_eq!( + mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509InvalidSignature, ""), + rustls::Error::InvalidCertificate(CertificateError::BadSignature) + ); + assert_eq!( + mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::RsaVerifyFailed, ""), + rustls::Error::InvalidCertificate(CertificateError::BadSignature) + ); + assert_eq!( + mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509InvalidName, ""), + rustls::Error::InvalidCertificate(CertificateError::NotValidForName) + ); + assert_eq!( + format!( + "{:?}", + mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509UnknownVersion, "") + ), + format!( + "{:?}", + rustls::Error::InvalidCertificate(CertificateError::Other(Arc::new(mbedtls::Error::X509UnknownVersion))) + ) + ); + assert_eq!( + format!( + "{:?}", + mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509InvalidSerial, "Invalid serial number") + ), + format!( + "{:?}", + rustls::Error::InvalidCertificate(CertificateError::Other(Arc::new(mbedtls::Error::X509InvalidSerial))) + ) + ); + } +} diff --git a/rustls-mbedtls-provider-utils/src/hash.rs b/rustls-mbedtls-provider-utils/src/hash.rs index fc37e52..32423c2 100644 --- a/rustls-mbedtls-provider-utils/src/hash.rs +++ b/rustls-mbedtls-provider-utils/src/hash.rs @@ -10,12 +10,12 @@ fn hash_size_bytes(hash_type: Type) -> Option { Type::Md2 => Some(16), Type::Md4 => Some(16), Type::Md5 => Some(16), - Type::Sha1 => Some(20), + Type::Sha1 => Some(160 / 8), Type::Sha224 => Some(224 / 8), Type::Sha256 => Some(256 / 8), Type::Sha384 => Some(384 / 8), Type::Sha512 => Some(512 / 8), - Type::Ripemd => Some(20), // this is MD_RIPEMD160 + Type::Ripemd => Some(160 / 8), // this is MD_RIPEMD160 } } @@ -45,3 +45,99 @@ pub fn rustls_signature_scheme_to_mbedtls_hash_type(signature_scheme: SignatureS _ => Type::None, } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_hash_size_bytes() { + assert_eq!(hash_size_bytes(Type::None), None); + assert_eq!(hash_size_bytes(Type::Md2), Some(16)); + assert_eq!(hash_size_bytes(Type::Md4), Some(16)); + assert_eq!(hash_size_bytes(Type::Md5), Some(16)); + assert_eq!(hash_size_bytes(Type::Sha1), Some(20)); + assert_eq!(hash_size_bytes(Type::Sha224), Some(224 / 8)); + assert_eq!(hash_size_bytes(Type::Sha256), Some(256 / 8)); + assert_eq!(hash_size_bytes(Type::Sha384), Some(384 / 8)); + assert_eq!(hash_size_bytes(Type::Sha512), Some(512 / 8)); + assert_eq!(hash_size_bytes(Type::Ripemd), Some(20)); + // Add more test cases if needed + } + + #[test] + fn test_buffer_for_hash_type() { + assert_eq!(buffer_for_hash_type(Type::None), None); + assert_eq!(buffer_for_hash_type(Type::Md2), Some(vec![0; 16])); + assert_eq!(buffer_for_hash_type(Type::Md4), Some(vec![0; 16])); + assert_eq!(buffer_for_hash_type(Type::Md5), Some(vec![0; 16])); + assert_eq!(buffer_for_hash_type(Type::Sha1), Some(vec![0; 20])); + assert_eq!(buffer_for_hash_type(Type::Sha224), Some(vec![0; 28])); + assert_eq!(buffer_for_hash_type(Type::Sha256), Some(vec![0; 32])); + assert_eq!(buffer_for_hash_type(Type::Sha384), Some(vec![0; 48])); + assert_eq!(buffer_for_hash_type(Type::Sha512), Some(vec![0; 64])); + assert_eq!(buffer_for_hash_type(Type::Ripemd), Some(vec![0; 20])); + // Add more test cases if needed + } + + #[test] + fn test_rustls_signature_scheme_to_mbedtls_hash_type() { + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::RSA_PKCS1_SHA1), + Type::Sha1 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::ECDSA_SHA1_Legacy), + Type::Sha1 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::RSA_PKCS1_SHA256), + Type::Sha256 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::ECDSA_NISTP256_SHA256), + Type::Sha256 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::RSA_PKCS1_SHA384), + Type::Sha384 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::ECDSA_NISTP384_SHA384), + Type::Sha384 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::RSA_PKCS1_SHA512), + Type::Sha512 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::ECDSA_NISTP521_SHA512), + Type::Sha512 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::RSA_PSS_SHA256), + Type::Sha256 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::RSA_PSS_SHA384), + Type::Sha384 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::RSA_PSS_SHA512), + Type::Sha512 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::ED25519), + Type::None + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::ED448), + Type::None + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_hash_type(SignatureScheme::Unknown(100)), + Type::None + ); + // Add more test cases if needed + } +} diff --git a/rustls-mbedtls-provider-utils/src/pk.rs b/rustls-mbedtls-provider-utils/src/pk.rs index cea9183..b8ccc9a 100644 --- a/rustls-mbedtls-provider-utils/src/pk.rs +++ b/rustls-mbedtls-provider-utils/src/pk.rs @@ -22,19 +22,6 @@ pub fn rustls_signature_scheme_to_mbedtls_pk_type(scheme: &SignatureScheme) -> O } } -/// Helper function to get mbedtls supported [`SignatureScheme`] from given [`SignatureScheme`] slice based on given [`Type`] -pub fn get_pk_supported_scheme(pk_type: &Type, offered: &[SignatureScheme]) -> Option { - for scheme in offered { - let scheme_type = rustls_signature_scheme_to_mbedtls_pk_type(scheme); - if let Some(scheme_type) = scheme_type { - if scheme_type == *pk_type { - return Some(*scheme); - } - } - } - None -} - /// Helper function to get the corresponding [`rustls::SignatureAlgorithm`] of given [`mbedtls::pk::Pk`] pub fn get_signature_algo_from_pk(pk: &mbedtls::pk::Pk) -> rustls::SignatureAlgorithm { let pk_type = pk.pk_type(); @@ -104,3 +91,57 @@ pub fn rustls_signature_scheme_to_mbedtls_curve_id(signature_scheme: SignatureSc _ => EcGroupId::None, } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_rustls_signature_scheme_to_mbedtls_pk_type() { + assert_eq!( + rustls_signature_scheme_to_mbedtls_pk_type(&SignatureScheme::RSA_PKCS1_SHA1), + Some(Type::Rsa) + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_pk_type(&SignatureScheme::ECDSA_NISTP256_SHA256), + Some(Type::Ecdsa) + ); + assert_eq!(rustls_signature_scheme_to_mbedtls_pk_type(&SignatureScheme::ED25519), None); + assert_eq!( + rustls_signature_scheme_to_mbedtls_pk_type(&SignatureScheme::Unknown(100)), + None + ); + } + + #[test] + fn test_rustls_signature_scheme_to_mbedtls_curve_id() { + assert_eq!( + rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::ECDSA_NISTP256_SHA256), + mbedtls::pk::EcGroupId::SecP256R1 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::ECDSA_NISTP384_SHA384), + mbedtls::pk::EcGroupId::SecP384R1 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::ECDSA_NISTP521_SHA512), + mbedtls::pk::EcGroupId::SecP521R1 + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::ECDSA_SHA1_Legacy), + mbedtls::pk::EcGroupId::None + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::RSA_PKCS1_SHA1), + mbedtls::pk::EcGroupId::None + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::ED25519), + mbedtls::pk::EcGroupId::None + ); + assert_eq!( + rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::Unknown(100)), + mbedtls::pk::EcGroupId::None + ); + } +} From 1f364d5cf9b0916fc140a6a02902ffcad39a7451 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Nov 2023 01:25:13 -0800 Subject: [PATCH 09/14] test: add more unit tests --- rustls-mbedcrypto-provider/src/sign.rs | 33 ++++++++ rustls-mbedtls-provider-utils/src/error.rs | 12 +++ rustls-mbedtls-provider-utils/src/pk.rs | 98 ++++++++++++---------- 3 files changed, 97 insertions(+), 46 deletions(-) diff --git a/rustls-mbedcrypto-provider/src/sign.rs b/rustls-mbedcrypto-provider/src/sign.rs index d949f66..d835181 100644 --- a/rustls-mbedcrypto-provider/src/sign.rs +++ b/rustls-mbedcrypto-provider/src/sign.rs @@ -168,3 +168,36 @@ fn pk_type_to_signature_algo(pk_type: mbedtls::pk::Type) -> rustls::SignatureAlg mbedtls::pk::Type::None => SignatureAlgorithm::Unknown(255), } } + +#[cfg(test)] +mod tests { + use super::*; + use rustls::{SignatureAlgorithm, sign::SigningKey}; + + #[test] + fn test_signing_key() { + let ec_key_pem = include_str!("../../test-ca/ecdsa/end.key"); + let der: pki_types::PrivateKeyDer<'static> = rustls_pemfile::pkcs8_private_keys(&mut std::io::BufReader::new(ec_key_pem.as_bytes())).next() + .unwrap() + .unwrap() + .into(); + let key = MbedTlsPkSigningKey::new(&der).unwrap(); + assert_eq!("MbedTlsPkSigningKey { pk: \"Arc>\", pk_type: Eckey, signature_algorithm: ECDSA, ec_signature_scheme: Some(ECDSA_NISTP256_SHA256) }", format!("{:?}", key)); + assert!(key.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA1]).is_none()); + let res = key.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256]); + assert!(res.is_some()); + assert_eq!("Some(MbedTlsSigner(\"Arc>\", ECDSA_NISTP256_SHA256))", format!("{:?}", res)); + } + + #[test] + fn test_pk_type_to_signature_algo() { + assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::Rsa), SignatureAlgorithm::RSA); + assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::Ecdsa), SignatureAlgorithm::ECDSA); + assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::RsassaPss), SignatureAlgorithm::RSA); + assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::RsaAlt), SignatureAlgorithm::RSA); + assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::Eckey), SignatureAlgorithm::ECDSA); + assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::EckeyDh), SignatureAlgorithm::Unknown(255)); + assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::Custom), SignatureAlgorithm::Unknown(255)); + assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::None), SignatureAlgorithm::Unknown(255)); + } +} diff --git a/rustls-mbedtls-provider-utils/src/error.rs b/rustls-mbedtls-provider-utils/src/error.rs index 03d310f..06b1861 100644 --- a/rustls-mbedtls-provider-utils/src/error.rs +++ b/rustls-mbedtls-provider-utils/src/error.rs @@ -49,10 +49,18 @@ mod tests { mbedtls_err_into_rustls_err(mbedtls::Error::X509InvalidSignature), rustls::Error::InvalidCertificate(CertificateError::BadSignature) ); + assert_eq!( + mbedtls_err_into_rustls_err(mbedtls::Error::RsaVerifyFailed), + rustls::Error::InvalidCertificate(CertificateError::BadSignature) + ); assert_eq!( mbedtls_err_into_rustls_err(mbedtls::Error::X509BadInputData), rustls::Error::InvalidCertificate(CertificateError::BadEncoding) ); + assert_eq!( + mbedtls_err_into_rustls_err(mbedtls::Error::X509CertUnknownFormat), + rustls::Error::InvalidCertificate(CertificateError::BadEncoding) + ); assert_eq!( mbedtls_err_into_rustls_err(mbedtls::Error::X509InvalidName), rustls::Error::InvalidCertificate(CertificateError::NotValidForName) @@ -65,6 +73,10 @@ mod tests { mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509InvalidSignature, ""), rustls::Error::InvalidCertificate(CertificateError::BadSignature) ); + assert_eq!( + mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::CipherAuthFailed, ""), + rustls::Error::General(String::from("mbedTLS error CipherAuthFailed")) + ); assert_eq!( mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::RsaVerifyFailed, ""), rustls::Error::InvalidCertificate(CertificateError::BadSignature) diff --git a/rustls-mbedtls-provider-utils/src/pk.rs b/rustls-mbedtls-provider-utils/src/pk.rs index b8ccc9a..e6aa073 100644 --- a/rustls-mbedtls-provider-utils/src/pk.rs +++ b/rustls-mbedtls-provider-utils/src/pk.rs @@ -22,23 +22,6 @@ pub fn rustls_signature_scheme_to_mbedtls_pk_type(scheme: &SignatureScheme) -> O } } -/// Helper function to get the corresponding [`rustls::SignatureAlgorithm`] of given [`mbedtls::pk::Pk`] -pub fn get_signature_algo_from_pk(pk: &mbedtls::pk::Pk) -> rustls::SignatureAlgorithm { - let pk_type = pk.pk_type(); - match pk_type { - Type::Rsa | Type::RsaAlt | Type::RsassaPss => rustls::SignatureAlgorithm::RSA, - Type::Ecdsa => rustls::SignatureAlgorithm::ECDSA, - Type::Eckey | Type::EckeyDh => match pk.curve().expect("validated") { - // TODO: ED25519 maybe not supported yet or not supported by mbedtls - mbedtls::pk::EcGroupId::Curve25519 => rustls::SignatureAlgorithm::ED25519, - // TODO: ED448 maybe not supported yet or not supported by mbedtls - mbedtls::pk::EcGroupId::Curve448 => rustls::SignatureAlgorithm::ED448, - _ => rustls::SignatureAlgorithm::Unknown(u8::MAX), - }, - _ => rustls::SignatureAlgorithm::Unknown(u8::MAX), - } -} - /// Helper function to convert rustls [`SignatureScheme`] to mbedtls [`mbedtls::pk::Options`] pub fn rustls_signature_scheme_to_mbedtls_pk_options(signature_scheme: SignatureScheme) -> Option { use mbedtls::pk::Options; @@ -98,19 +81,43 @@ mod tests { #[test] fn test_rustls_signature_scheme_to_mbedtls_pk_type() { - assert_eq!( - rustls_signature_scheme_to_mbedtls_pk_type(&SignatureScheme::RSA_PKCS1_SHA1), - Some(Type::Rsa) - ); - assert_eq!( - rustls_signature_scheme_to_mbedtls_pk_type(&SignatureScheme::ECDSA_NISTP256_SHA256), - Some(Type::Ecdsa) - ); - assert_eq!(rustls_signature_scheme_to_mbedtls_pk_type(&SignatureScheme::ED25519), None); - assert_eq!( - rustls_signature_scheme_to_mbedtls_pk_type(&SignatureScheme::Unknown(100)), - None - ); + let test_data = [ + ( + Some(Type::Rsa), + vec![ + SignatureScheme::RSA_PKCS1_SHA1, + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA512, + ], + ), + ( + Some(Type::Ecdsa), + vec![ + SignatureScheme::ECDSA_SHA1_Legacy, + SignatureScheme::ECDSA_NISTP256_SHA256, + SignatureScheme::ECDSA_NISTP384_SHA384, + SignatureScheme::ECDSA_NISTP521_SHA512, + ], + ), + ( + None, + vec![ + SignatureScheme::ED25519, + SignatureScheme::ED448, + SignatureScheme::Unknown(100), + ], + ), + ]; + + for pair in &test_data { + for scheme in &pair.1 { + assert_eq!(pair.0, rustls_signature_scheme_to_mbedtls_pk_type(scheme)); + } + } } #[test] @@ -127,21 +134,20 @@ mod tests { rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::ECDSA_NISTP521_SHA512), mbedtls::pk::EcGroupId::SecP521R1 ); - assert_eq!( - rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::ECDSA_SHA1_Legacy), - mbedtls::pk::EcGroupId::None - ); - assert_eq!( - rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::RSA_PKCS1_SHA1), - mbedtls::pk::EcGroupId::None - ); - assert_eq!( - rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::ED25519), - mbedtls::pk::EcGroupId::None - ); - assert_eq!( - rustls_signature_scheme_to_mbedtls_curve_id(SignatureScheme::Unknown(100)), - mbedtls::pk::EcGroupId::None - ); + for scheme in [ + SignatureScheme::ECDSA_SHA1_Legacy, + SignatureScheme::RSA_PKCS1_SHA1, + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA512, + SignatureScheme::ED25519, + SignatureScheme::ED448, + SignatureScheme::Unknown(123), + ] { + assert_eq!(rustls_signature_scheme_to_mbedtls_curve_id(scheme), mbedtls::pk::EcGroupId::None); + } } } From 2ca377457d6bb33bf6fc3c007817dc8a4e5dc505 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Nov 2023 01:26:08 -0800 Subject: [PATCH 10/14] ci: turn of CARGO_INCREMENTAL Turn off CARGO_INCREMENTAL to ensure cache & test coverage works correctly. --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fed2782..310e179 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,6 +17,7 @@ on: env: CARGO_TERM_COLOR: always CARGO_NET_RETRY: 10 + CARGO_INCREMENTAL: 0 jobs: build: From f7c43756c97f8163a4cf138b54e86e44635ff808 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Nov 2023 01:28:25 -0800 Subject: [PATCH 11/14] style: fmt --- rustls-mbedcrypto-provider/src/sign.rs | 41 ++++++++++++++++++------- rustls-mbedtls-provider-utils/src/pk.rs | 5 ++- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/rustls-mbedcrypto-provider/src/sign.rs b/rustls-mbedcrypto-provider/src/sign.rs index d835181..c10fb00 100644 --- a/rustls-mbedcrypto-provider/src/sign.rs +++ b/rustls-mbedcrypto-provider/src/sign.rs @@ -172,32 +172,51 @@ fn pk_type_to_signature_algo(pk_type: mbedtls::pk::Type) -> rustls::SignatureAlg #[cfg(test)] mod tests { use super::*; - use rustls::{SignatureAlgorithm, sign::SigningKey}; + use rustls::{sign::SigningKey, SignatureAlgorithm}; #[test] fn test_signing_key() { let ec_key_pem = include_str!("../../test-ca/ecdsa/end.key"); - let der: pki_types::PrivateKeyDer<'static> = rustls_pemfile::pkcs8_private_keys(&mut std::io::BufReader::new(ec_key_pem.as_bytes())).next() - .unwrap() - .unwrap() - .into(); + let der: pki_types::PrivateKeyDer<'static> = + rustls_pemfile::pkcs8_private_keys(&mut std::io::BufReader::new(ec_key_pem.as_bytes())) + .next() + .unwrap() + .unwrap() + .into(); let key = MbedTlsPkSigningKey::new(&der).unwrap(); assert_eq!("MbedTlsPkSigningKey { pk: \"Arc>\", pk_type: Eckey, signature_algorithm: ECDSA, ec_signature_scheme: Some(ECDSA_NISTP256_SHA256) }", format!("{:?}", key)); - assert!(key.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA1]).is_none()); + assert!(key + .choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA1]) + .is_none()); let res = key.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256]); assert!(res.is_some()); - assert_eq!("Some(MbedTlsSigner(\"Arc>\", ECDSA_NISTP256_SHA256))", format!("{:?}", res)); + assert_eq!( + "Some(MbedTlsSigner(\"Arc>\", ECDSA_NISTP256_SHA256))", + format!("{:?}", res) + ); } #[test] fn test_pk_type_to_signature_algo() { assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::Rsa), SignatureAlgorithm::RSA); assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::Ecdsa), SignatureAlgorithm::ECDSA); - assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::RsassaPss), SignatureAlgorithm::RSA); + assert_eq!( + pk_type_to_signature_algo(mbedtls::pk::Type::RsassaPss), + SignatureAlgorithm::RSA + ); assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::RsaAlt), SignatureAlgorithm::RSA); assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::Eckey), SignatureAlgorithm::ECDSA); - assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::EckeyDh), SignatureAlgorithm::Unknown(255)); - assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::Custom), SignatureAlgorithm::Unknown(255)); - assert_eq!(pk_type_to_signature_algo(mbedtls::pk::Type::None), SignatureAlgorithm::Unknown(255)); + assert_eq!( + pk_type_to_signature_algo(mbedtls::pk::Type::EckeyDh), + SignatureAlgorithm::Unknown(255) + ); + assert_eq!( + pk_type_to_signature_algo(mbedtls::pk::Type::Custom), + SignatureAlgorithm::Unknown(255) + ); + assert_eq!( + pk_type_to_signature_algo(mbedtls::pk::Type::None), + SignatureAlgorithm::Unknown(255) + ); } } diff --git a/rustls-mbedtls-provider-utils/src/pk.rs b/rustls-mbedtls-provider-utils/src/pk.rs index e6aa073..cbf9b62 100644 --- a/rustls-mbedtls-provider-utils/src/pk.rs +++ b/rustls-mbedtls-provider-utils/src/pk.rs @@ -147,7 +147,10 @@ mod tests { SignatureScheme::ED448, SignatureScheme::Unknown(123), ] { - assert_eq!(rustls_signature_scheme_to_mbedtls_curve_id(scheme), mbedtls::pk::EcGroupId::None); + assert_eq!( + rustls_signature_scheme_to_mbedtls_curve_id(scheme), + mbedtls::pk::EcGroupId::None + ); } } } From 92ab97df5fcc7b0ff317ea15990132d69dce63c1 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Nov 2023 01:31:33 -0800 Subject: [PATCH 12/14] build: update ws default-members Add rustls-mbedtls-provider-utils to default-members --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4311ad7..fd64931 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,5 +5,5 @@ members = [ "rustls-mbedpki-provider", "rustls-mbedtls-provider-utils", ] -default-members = ["rustls-mbedcrypto-provider", "rustls-mbedpki-provider"] +default-members = ["rustls-mbedcrypto-provider", "rustls-mbedpki-provider", "rustls-mbedtls-provider-utils"] resolver = "2" From 1dcadd5f5a65906871a8cf5497e9828ec5fbe068 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Nov 2023 01:35:20 -0800 Subject: [PATCH 13/14] docs: fix rustdoc --- rustls-mbedtls-provider-utils/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rustls-mbedtls-provider-utils/src/lib.rs b/rustls-mbedtls-provider-utils/src/lib.rs index 0075274..a30ad5a 100644 --- a/rustls-mbedtls-provider-utils/src/lib.rs +++ b/rustls-mbedtls-provider-utils/src/lib.rs @@ -32,7 +32,7 @@ extern crate alloc; #[cfg(not(test))] extern crate std; -/// Utility code related to error types in [`mbedtls::error`] and [`rustls::error`] +/// Utility code related to error types: [`mbedtls::Error`] and [`rustls::Error`] pub mod error; /// Utility code related to [`mbedtls::hash`] types pub mod hash; From f62e3734ca01e8248bd25dbf9a2886e4d4f4614c Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Mon, 27 Nov 2023 13:12:51 -0800 Subject: [PATCH 14/14] refactor: better prefer order Update `RSA_SIGNATURE_SCHEME_PREFER_LIST` to have a better order. --- rustls-mbedcrypto-provider/src/sign.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rustls-mbedcrypto-provider/src/sign.rs b/rustls-mbedcrypto-provider/src/sign.rs index c10fb00..467be2e 100644 --- a/rustls-mbedcrypto-provider/src/sign.rs +++ b/rustls-mbedcrypto-provider/src/sign.rs @@ -115,12 +115,12 @@ impl MbedTlsPkSigningKey { } const RSA_SIGNATURE_SCHEME_PREFER_LIST: &[SignatureScheme] = &[ - SignatureScheme::RSA_PSS_SHA256, - SignatureScheme::RSA_PSS_SHA384, SignatureScheme::RSA_PSS_SHA512, - SignatureScheme::RSA_PKCS1_SHA256, - SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA256, SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::RSA_PKCS1_SHA256, ]; impl rustls::sign::SigningKey for MbedTlsPkSigningKey {