From dd79e0538a501213a685b0290ff657466b8299f3 Mon Sep 17 00:00:00 2001 From: pinkforest <36498018+pinkforest@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:37:47 +1100 Subject: [PATCH] Try validation workspace approach --- validation/README.md | 15 +++++ validation/consumer-no_std/Cargo.toml | 10 +++ validation/consumer-no_std/README.md | 3 + validation/consumer-no_std/src/fakes.rs | 2 + .../src/fakes/fake_cert_verifier.rs | 61 ++++++++++++++++++ .../src/fakes/fake_time_provider.rs | 14 +++++ validation/consumer-no_std/src/lib.rs | 62 +++++++++++++++++++ 7 files changed, 167 insertions(+) create mode 100644 validation/README.md create mode 100644 validation/consumer-no_std/Cargo.toml create mode 100644 validation/consumer-no_std/README.md create mode 100644 validation/consumer-no_std/src/fakes.rs create mode 100644 validation/consumer-no_std/src/fakes/fake_cert_verifier.rs create mode 100644 validation/consumer-no_std/src/fakes/fake_time_provider.rs create mode 100644 validation/consumer-no_std/src/lib.rs diff --git a/validation/README.md b/validation/README.md new file mode 100644 index 0000000..4670c20 --- /dev/null +++ b/validation/README.md @@ -0,0 +1,15 @@ +# rustls-rustcrypto Validation + +These are collection of crates that can be used to validate integration +between rustls and rustcrypto-rustcrypto provider under different targets. + +| Crate | Description | +| :--- | :--- | +| consumer-no_std | Basic consumer library aiming no_std environment | + +These live in the workspace due to different dependency requirements between +tests where development-deps may pollute the integration under test. + +This is aimed for internal validation without requiring further upstream +dependencies which are may or may not be in lock-step with current version of +rustls the provider targets in any given time. diff --git a/validation/consumer-no_std/Cargo.toml b/validation/consumer-no_std/Cargo.toml new file mode 100644 index 0000000..8944cc0 --- /dev/null +++ b/validation/consumer-no_std/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "consumer-no_std" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.orxg/cargo/reference/manifest.html + +[dependencies] +rustls-rustcrypto = { path = "../../" } +rustls = { version = "0.23", default-features = false } \ No newline at end of file diff --git a/validation/consumer-no_std/README.md b/validation/consumer-no_std/README.md new file mode 100644 index 0000000..16c05a3 --- /dev/null +++ b/validation/consumer-no_std/README.md @@ -0,0 +1,3 @@ +# no_std Consumer build + +Simple self-tester to validate no_std build with a given rustls version. diff --git a/validation/consumer-no_std/src/fakes.rs b/validation/consumer-no_std/src/fakes.rs new file mode 100644 index 0000000..bdfe633 --- /dev/null +++ b/validation/consumer-no_std/src/fakes.rs @@ -0,0 +1,2 @@ +pub(crate) mod fake_cert_verifier; +pub(crate) mod fake_time_provider; diff --git a/validation/consumer-no_std/src/fakes/fake_cert_verifier.rs b/validation/consumer-no_std/src/fakes/fake_cert_verifier.rs new file mode 100644 index 0000000..3e3e962 --- /dev/null +++ b/validation/consumer-no_std/src/fakes/fake_cert_verifier.rs @@ -0,0 +1,61 @@ +use rustls::client::danger::HandshakeSignatureValid; +use rustls::client::danger::ServerCertVerified; +use rustls::client::danger::ServerCertVerifier; +use rustls::pki_types::CertificateDer; +use rustls::pki_types::ServerName; +use rustls::pki_types::UnixTime; +use rustls::DigitallySignedStruct; +use rustls::Error; +use rustls::SignatureScheme; + +use alloc::vec::Vec; + +#[derive(Debug)] +pub(crate) struct FakeServerCertVerifier; + +impl ServerCertVerifier for FakeServerCertVerifier { + fn verify_server_cert( + &self, + _end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _server_name: &ServerName<'_>, + _ocsp_response: &[u8], + _now: UnixTime, + ) -> Result { + Ok(ServerCertVerified::assertion()) + } + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + fn supported_verify_schemes(&self) -> Vec { + alloc::vec![ + SignatureScheme::RSA_PKCS1_SHA1, + SignatureScheme::ECDSA_SHA1_Legacy, + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::ECDSA_NISTP256_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::ECDSA_NISTP384_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::ECDSA_NISTP521_SHA512, + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA512, + SignatureScheme::ED25519, + SignatureScheme::ED448, + //SignatureScheme::Unknown(u16), + ] + } +} diff --git a/validation/consumer-no_std/src/fakes/fake_time_provider.rs b/validation/consumer-no_std/src/fakes/fake_time_provider.rs new file mode 100644 index 0000000..6c32199 --- /dev/null +++ b/validation/consumer-no_std/src/fakes/fake_time_provider.rs @@ -0,0 +1,14 @@ +use rustls::time_provider::TimeProvider; +//use core::time::Duration; +use rustls::pki_types::UnixTime; + +// Required for no_std +#[derive(Debug)] +pub(crate) struct FakeTime; + +// TODO: Figure how to handle time +impl TimeProvider for FakeTime { + fn current_time(&self) -> Option { + None + } +} diff --git a/validation/consumer-no_std/src/lib.rs b/validation/consumer-no_std/src/lib.rs new file mode 100644 index 0000000..221cf0e --- /dev/null +++ b/validation/consumer-no_std/src/lib.rs @@ -0,0 +1,62 @@ +#![no_std] +#![forbid(unsafe_code)] +#![warn( + clippy::unwrap_used, + //missing_docs, + rust_2018_idioms, + unused_lifetimes, + unused_qualifications +)] +#![doc = include_str!("../README.md")] +#![allow(dead_code)] // HEAVY TODO + +//! RusTLS RustCrypto ValidationProvider +//! This crate is used to internally minimally validate the provider in CI +//! Obviously - don't use in prod ;-) + +// I hope in future there is an API without Arc for providers +extern crate alloc; +use alloc::sync::Arc; + +use rustls::client::ClientConfig as RusTlsClientConfig; + +use rustls_rustcrypto::provider as rustcrypto_provider; + +// TODO: rustcrypto tls PKI verifier provider missing +// We are not testing webpki / rustls itself which typically handle certificates +// Perhaps a separate crate for PKI operations e.g. cert verifying and then test that ? +mod fakes; +use crate::fakes::fake_cert_verifier::FakeServerCertVerifier; +use crate::fakes::fake_time_provider::FakeTime; + +pub struct ProviderValidatorClient { + pub(crate) rustls_client_config: RusTlsClientConfig, +} + +impl ProviderValidatorClient { + pub fn builder() -> Self { + let provider = rustcrypto_provider(); + let time_provider = FakeTime {}; + + let fake_server_cert_verifier = FakeServerCertVerifier {}; + + let builder_init = + RusTlsClientConfig::builder_with_details(Arc::new(provider), Arc::new(time_provider)); + + let builder_default_versions = builder_init + .with_safe_default_protocol_versions() + .expect("Default protocol versions error?"); + + // TODO - test with different verifiers + let dangerous_verifier = builder_default_versions + .dangerous() + .with_custom_certificate_verifier(Arc::new(fake_server_cert_verifier)); + + // Out of scope + let rustls_client_config = dangerous_verifier.with_no_client_auth(); + + Self { + rustls_client_config, + } + } +}