Skip to content

Commit

Permalink
Fix tls config for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Oct 29, 2024
1 parent 791e740 commit 0cf5f3a
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ http = "1"
chrono = "0.4.38"
env_logger = "0.11.3"
rustainers = "0.12.0"
rustls = { version = "0.22.4" }
rustls = { version = "0.23" }
tokio = { version = "1.37.0", features = ["rt", "macros"] }
ureq = "=3.0.0-rc2"
2 changes: 1 addition & 1 deletion generator/src/main/resources/crust/Cargo.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ http = "1"
chrono = "0.4.38"
env_logger = "0.11.3"
rustainers = "0.12.0"
rustls = { version = "0.22.4" }
rustls = { version = "0.23.4" }
tokio = { version = "1.37.0", features = ["rt", "macros"] }
ureq = "=3.0.0-rc2"
188 changes: 174 additions & 14 deletions tests/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
// Author: David Runge <[email protected]>
// License: Apache-2.0 OR MIT

use std::sync::Arc;
use std::{
fmt::Debug,
io::{Read, Write},
sync::Arc,
};

use nethsm_sdk_rs::apis::configuration::Configuration;
use rustainers::{
Expand All @@ -12,15 +16,174 @@ use rustainers::{
WaitStrategy,
};
use rustls::{
client::{
danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
ClientConfig,
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
crypto::{
self, verify_tls12_signature, verify_tls13_signature, CryptoProvider,
WebPkiSupportedAlgorithms,
},
crypto::{self, WebPkiSupportedAlgorithms},
pki_types::{CertificateDer, ServerName, UnixTime},
DigitallySignedStruct, SignatureScheme,
ClientConnection, DigitallySignedStruct, SignatureScheme, StreamOwned,
};
use ureq::{
resolver::DefaultResolver,
transport::{
Buffers, ChainedConnector, ConnectionDetails, Connector, LazyBuffers, NextTimeout,
TcpConnector, Transport, TransportAdapter,
},
};

#[derive(Debug)]
struct TlsConnectorAcceptAll;

impl Connector for TlsConnectorAcceptAll {
fn connect(
&self,
details: &ConnectionDetails,
chained: Option<Box<dyn Transport>>,
) -> Result<Option<Box<dyn Transport>>, ureq::Error> {
let Some(transport) = chained else {
panic!("Chained connector is required");
};

if !details.needs_tls() || transport.is_tls() {
return Ok(Some(transport));
}

let name_borrowed: ServerName<'_> = details
.uri
.authority()
.expect("uri authority for tls")
.host()
.try_into()
.map_err(|_e| ureq::Error::Tls("Rustls invalid dns name error"))?;

let name = name_borrowed.to_owned();
let config = rustls_accept_all_config();
let conn = ClientConnection::new(config, name)?;

let stream = StreamOwned {
conn,
sock: TransportAdapter::new(transport),
};

// FIXME: use details.config.(input/output)_buffer_size,
let buffers = LazyBuffers::new(512 * 1024, 512 * 1024);

let transport = Box::new(CertIgnoredTransport { buffers, stream });
Ok(Some(transport))
}
}

struct CertIgnoredTransport {
stream: StreamOwned<ClientConnection, TransportAdapter>,
buffers: LazyBuffers,
}

impl Debug for CertIgnoredTransport {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CertIgnoredTransport")
.finish_non_exhaustive()
}
}

impl Transport for CertIgnoredTransport {
fn buffers(&mut self) -> &mut dyn Buffers {
&mut self.buffers
}

fn transmit_output(&mut self, amount: usize, timeout: NextTimeout) -> Result<(), ureq::Error> {
self.stream.get_mut().set_timeout(timeout);

let output = &self.buffers.output()[..amount];
self.stream.write_all(output)?;

Ok(())
}

fn await_input(&mut self, timeout: NextTimeout) -> Result<bool, ureq::Error> {
if self.buffers.can_use_input() {
return Ok(true);
}

self.stream.get_mut().set_timeout(timeout);

let input = self.buffers.input_append_buf();
let amount = self.stream.read(input)?;
self.buffers.input_appended(amount);

Ok(amount > 0)
}

fn is_open(&mut self) -> bool {
self.stream.get_mut().get_mut().is_open()
}

fn is_tls(&self) -> bool {
true
}
}

fn rustls_accept_all_config() -> Arc<rustls::ClientConfig> {
let provider = Arc::new(rustls::crypto::ring::default_provider());

let config = rustls::ClientConfig::builder_with_provider(provider.clone())
.with_protocol_versions(rustls::ALL_VERSIONS)
.unwrap()
.dangerous()
.with_custom_certificate_verifier(Arc::new(DisabledVerifier(provider.clone())))
.with_no_client_auth();

Arc::new(config)
}

#[derive(Debug)]
struct DisabledVerifier(Arc<CryptoProvider>);

impl ServerCertVerifier for DisabledVerifier {
fn verify_server_cert(
&self,
_end_entity: &CertificateDer<'_>,
_intermediates: &[CertificateDer<'_>],
_server_name: &ServerName<'_>,
_ocsp_response: &[u8],
_now: UnixTime,
) -> Result<ServerCertVerified, rustls::Error> {
Ok(rustls::client::danger::ServerCertVerified::assertion())
}

fn verify_tls12_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
verify_tls12_signature(
message,
cert,
dss,
&self.0.signature_verification_algorithms,
)
}

fn verify_tls13_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
verify_tls13_signature(
message,
cert,
dss,
&self.0.signature_verification_algorithms,
)
}

fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
self.0.signature_verification_algorithms.supported_schemes()
}
}

pub async fn with_container<F: FnOnce(Configuration) -> T, T>(f: F) -> T {
let _ = env_logger::builder().is_test(true).try_init();

Expand All @@ -33,14 +196,11 @@ pub async fn with_container<F: FnOnce(Configuration) -> T, T>(f: F) -> T {

let config = Configuration {
base_path: container.api().await,
client: ureq::Agent::config_builder()
.tls_config(
ureq::tls::TlsConfig::builder()
.disable_verification(true)
.build(),
)
.build()
.new_agent(),
client: ureq::Agent::with_parts(
ureq::Agent::config_builder().build(),
ChainedConnector::new([Box::new(TlsConnectorAcceptAll)]),
DefaultResolver::default(),
),
..Default::default()
};

Expand Down

0 comments on commit 0cf5f3a

Please sign in to comment.