Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 75 additions & 15 deletions examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
use bytes::{Buf, Bytes};
use futures::future;
use http3::error::{Code, ConnectionError, StreamError};
use rustls::pki_types::CertificateDer;
use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
use rustls::crypto::WebPkiSupportedAlgorithms;
use rustls::pki_types::{CertificateDer, ServerName, UnixTime};
use rustls::{DigitallySignedStruct, SignatureScheme};
use rustls_native_certs::CertificateResult;
use structopt::StructOpt;
use tracing::{Level, error, info};
Expand Down Expand Up @@ -46,6 +49,55 @@
help = "URI of the server to connect to"
)]
pub uri: String,

#[structopt(long, help = "Skip server certificate verification (insecure)")]
pub skip_verify: bool,
}

#[derive(Debug)]
struct SkipServerVerification(WebPkiSupportedAlgorithms);

impl SkipServerVerification {
fn new() -> Self {
let provider = rustls::crypto::CryptoProvider::get_default()
.expect("rustls default crypto provider not initialized");
Self(provider.signature_verification_algorithms)
}
}

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

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

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

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

#[tokio::main]
Expand Down Expand Up @@ -84,22 +136,24 @@

// create quinn client endpoint

// load CA certificates stored in the system
let mut roots = rustls::RootCertStore::empty();
let CertificateResult { certs, errors, .. } = rustls_native_certs::load_native_certs();
for cert in certs {
if let Err(e) = roots.add(cert) {
error!("failed to parse trust anchor: {}", e);
if !opt.skip_verify {
// load CA certificates stored in the system
let CertificateResult { certs, errors, .. } = rustls_native_certs::load_native_certs();
for cert in certs {
if let Err(e) = roots.add(cert) {
error!("failed to parse trust anchor: {}", e);
}
}
for e in errors {
error!("couldn't load default trust roots: {}", e);
}
}
for e in errors {
error!("couldn't load default trust roots: {}", e);
}

// load certificate of CA who issues the server certificate
// NOTE that this should be used for dev only
if let Err(e) = roots.add(CertificateDer::from(std::fs::read(opt.ca)?)) {
error!("failed to parse trust anchor: {}", e);
// load certificate of CA who issues the server certificate
// NOTE that this should be used for dev only
if let Err(e) = roots.add(CertificateDer::from(std::fs::read(opt.ca)?)) {
error!("failed to parse trust anchor: {}", e);
}
}

let mut tls_config = rustls::ClientConfig::builder()
Expand All @@ -113,12 +167,18 @@
if opt.key_log_file {
// Write all Keys to a file if SSLKEYLOGFILE is set
// WARNING, we enable this for the example, you should think carefully about enabling in
// your own code

Check warning on line 170 in examples/client.rs

View workflow job for this annotation

GitHub Actions / Check Style

Diff in /home/runner/work/http3/http3/examples/client.rs
tls_config.key_log = Arc::new(rustls::KeyLogFile::new());
}

if opt.skip_verify {
info!("TLS certificate verification is disabled for this run");
tls_config
.dangerous()
.set_certificate_verifier(Arc::new(SkipServerVerification::new()));
}

let mut client_endpoint = http3_quic::quic::Endpoint::client("[::]:0".parse().unwrap())?;

let client_config = quinn::ClientConfig::new(Arc::new(
quinn::crypto::rustls::QuicClientConfig::try_from(tls_config)?,
));
Expand Down
5 changes: 5 additions & 0 deletions examples/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ To start the example client you can run following command:
```bash
> cargo run --example client -- https://localhost:4433
```
or if you need to ignore certificate validation:

```bash
> cargo run --example client -- --skip-verify --requests 10 --qpack-blocked-streams 100 --qpack-max-table-capacity 65535 https://localhost:8181/api/all
```

This sends an HTTP request to the server.

Expand Down
Loading