From d7fa80318a96e356e4a41dd0964498cae340fa69 Mon Sep 17 00:00:00 2001 From: Richard Tweed Date: Sun, 29 Jan 2023 19:16:44 +0000 Subject: [PATCH 001/133] Adding steps to run the examples --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index aaabd9f..2cf9588 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,17 @@ hyper-rustls is distributed under the following three licenses: These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC respectively. You may use this software under the terms of any of these licenses, at your option. + +## Running examples + +### server + +```bash +cargo run --example server +``` + +### client + +```bash +cargo run --example client "https://docs.rs/hyper-rustls/latest/hyper_rustls/" +``` From 4bf725bd959cd9ea2ab987ec64ae88e3bb34dfd6 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 7 Mar 2023 11:36:34 -0500 Subject: [PATCH 002/133] fix: allow example server http/1.0 ALPN. Prior to this commit the `example/server.rs` code built a Rustls `ServerConfig` that configured the `alpn_protocols` to accept HTTP/2 and HTTP/1.1. Notably, the protocol list did **not** include HTTP/1.0. This should have been uncovered by the `tests/test.rs` integration tests explicitly providing `--http1.0` in the test `curl` invocations, but it was hidden by an upstream bug in curl! Prior to v7.88.0 curl would send the HTTP1.1 ALPN ID even when `--http1.0` was specified[0], and so our example server would work even without accepting HTTP1.0 ALPN. This commit updates the example server code to accept HTTP/1.0 ALPN, which in turn fixes the unit tests when run with Curl v7.88.0+. This should also help with other clients that didn't exhibit the same bug as curl did. [0]: https://github.com/curl/curl/commit/df856cb5c94665c9083dc8be5bb02392d841cc1e --- examples/server.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/server.rs b/examples/server.rs index 8e38132..69702d3 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -51,8 +51,8 @@ async fn run_server() -> Result<(), Box> { .with_no_client_auth() .with_single_cert(certs, key) .map_err(|e| error(format!("{}", e)))?; - // Configure ALPN to accept HTTP/2, HTTP/1.1 in that order. - cfg.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + // Configure ALPN to accept HTTP/2, HTTP/1.1, and HTTP/1.0 in that order. + cfg.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()]; sync::Arc::new(cfg) }; From f73f4e4d62e3581c71260e89cc16aa7a3a9a6ca8 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 7 Mar 2023 12:03:44 -0500 Subject: [PATCH 003/133] chore: avoid fixed sleep in integration tests. Prior to this commit the `tests/tests.rs` integration tests had an unconditional 1 second sleep waiting for a server to become available. This is slightly problematic: * Waiting a full second if the server becomes available sooner is unnecessarily slow. * Conversely, we can't be sure the server is available after the 1s sleep. This commit replaces the sleeps with a loop of up to 10 iterations that tries to connect to the server port. If any iteration succeeds we return immediately to avoid unnecessary waiting. If an iteration fails, we wait longer, increasing the duration each time we wait (up to a maximum of 10 iteration). --- tests/tests.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index f08b7cb..3d23783 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,4 +1,5 @@ use std::env; +use std::net::TcpStream; use std::path::PathBuf; use std::process::Command; use std::thread; @@ -21,6 +22,16 @@ fn client_command() -> Command { Command::new(examples_dir().join("client")) } +fn wait_for_server(addr: &str) { + for i in 0..10 { + if let Ok(_) = TcpStream::connect(addr) { + return; + } + thread::sleep(time::Duration::from_millis(i * 100)); + } + panic!("failed to connect to {:?} after 10 tries", addr); +} + #[test] fn client() { let rc = client_command() @@ -38,13 +49,14 @@ fn server() { .spawn() .expect("cannot run server example"); - thread::sleep(time::Duration::from_secs(1)); + let addr = "localhost:1337"; + wait_for_server(addr); let output = Command::new("curl") .arg("--insecure") .arg("--http1.0") .arg("--silent") - .arg("https://localhost:1337") + .arg(format!("https://{}", addr)) .output() .expect("cannot run curl"); @@ -61,10 +73,11 @@ fn custom_ca_store() { .spawn() .expect("cannot run server example"); - thread::sleep(time::Duration::from_secs(1)); + let addr = "localhost:1338"; + wait_for_server(addr); let rc = client_command() - .arg("https://localhost:1338") + .arg(format!("https://{}", addr)) .arg("examples/sample.pem") .output() .expect("cannot run client example"); From 520be4506df72a40540d9ef20ea92df37aea40b3 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 7 Mar 2023 12:12:24 -0500 Subject: [PATCH 004/133] fix: kill server before asserting on output. Prior to this commit the `server()` test would call `assert_eq!` to assert on client output matching expected _before_ calling `srv.kill()` on the `Child` spawned by `server_command()`. The upstream rustdocs for `std.process.Child` mention: > There is no implementation of Drop for child processes, so if you do > not ensure the Child has exited then it will continue to run, even > after the Child handle to the child process has gone out of scope. The net result is that if the assertion in `server()` fails, we leave a running server instance behind. This manifests as a port conflict when re-running the test without first killing the orphan. This commit moves the `srv.kill()` call to before the `assert_eq`. This avoids leaking the server process if the assertion fails. --- tests/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index 3d23783..dbee5bc 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -60,10 +60,10 @@ fn server() { .output() .expect("cannot run curl"); + srv.kill().unwrap(); + println!("client output: {:?}", output.stdout); assert_eq!(output.stdout, b"Try POST /echo\n"); - - srv.kill().unwrap(); } #[test] From c4dd4cad69017726cd1c547607617f1f163e6e79 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 7 Mar 2023 12:59:28 -0500 Subject: [PATCH 005/133] chore: improve server integration test output. This commit adds a few quality of life improvements to the server integration test: 1. The `--silent` curl arg is removed so that we can get diagnostic info from curl on stderr in the event of a failure. Our test only asserts on stdout content, which remains unaffected by this change. 2. If the `curl` command invocation status isn't success, we print the stderr content enabled by not using `--silent`. This will provide more diagnostic context to investigate the failure. 3. The `assert_eq` is changed to assert on a string value created from stdout instead of raw bytes. This is easier for humans to diff in the test output compared to a slice of byte values. Combined these changes should make it easier to diagnose future test failures without needing to iterate in CI. --- tests/tests.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index dbee5bc..4cc2ce2 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -55,15 +55,17 @@ fn server() { let output = Command::new("curl") .arg("--insecure") .arg("--http1.0") - .arg("--silent") .arg(format!("https://{}", addr)) .output() .expect("cannot run curl"); srv.kill().unwrap(); - println!("client output: {:?}", output.stdout); - assert_eq!(output.stdout, b"Try POST /echo\n"); + if !output.status.success() { + println!("curl stderr:\n{}", String::from_utf8_lossy(&output.stderr)); + } + + assert_eq!(String::from_utf8_lossy(&*output.stdout), "Try POST /echo\n"); } #[test] From aa1506a068c49ae449ee016eef1c1166bdf58b8e Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 7 Mar 2023 12:28:52 -0500 Subject: [PATCH 006/133] chore: output curl version in server test failure. In the event the `server()` integration test fails it's helpful to know the version of `curl` that was used. This commit includes this information when the `curl` client invocation returns a non-zero status code. --- tests/tests.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/tests.rs b/tests/tests.rs index 4cc2ce2..aa39880 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -62,6 +62,12 @@ fn server() { srv.kill().unwrap(); if !output.status.success() { + let version_stdout = Command::new("curl") + .arg("--version") + .output() + .expect("cannot run curl to collect --version") + .stdout; + println!("curl version: {}", String::from_utf8_lossy(&version_stdout)); println!("curl stderr:\n{}", String::from_utf8_lossy(&output.stderr)); } From cf50a4da5bd59e060acbbe36fd69cad40daba8ba Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 14 Mar 2023 16:47:01 -0400 Subject: [PATCH 007/133] CI: configure Dependabot to monitor GitHub actions. This commit updates the existing `.github/dependabot.yml` config that monitors Cargo dependencies to also monitor GitHub actions (on a weekly cadence). --- .github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5cde165..c7b634c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,3 +5,7 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly From 3a040dc35d9f91f33057b20c75a9df9d07558e0c Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 14 Mar 2023 16:47:55 -0400 Subject: [PATCH 008/133] CI: actions/checkout@v2 -> v3. --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 37ced22..f6610a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: rust: stable steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: persist-credentials: false @@ -74,7 +74,7 @@ jobs: runs-on: ubuntu-18.04 steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: persist-credentials: false @@ -95,7 +95,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: persist-credentials: false - name: Install rust toolchain @@ -116,7 +116,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: persist-credentials: false - name: Install rust toolchain From 468c788454ca0560b7e708922e15bb7eb0662baa Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 14 Mar 2023 16:50:43 -0400 Subject: [PATCH 009/133] CI: replace actions-rs w/ dtolnay/rust-toolchain. This commit replaces the `actions-rs/toolchain` action with `dtolnay/rust-toolchain`. The former is no longer maintained. Usages of `actions-rs/cargo` are replaced with direct invocation of the relevant tooling installed by `dtolnay/rust-toolchain`. --- .github/workflows/build.yml | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f6610a7..2c2b5a0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,10 +32,9 @@ jobs: persist-credentials: false - name: Install ${{ matrix.rust }} toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - name: cargo check (default features) run: cargo check --all-targets @@ -79,11 +78,7 @@ jobs: persist-credentials: false - name: Install rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - override: true - default: true + uses: dtolnay/rust-toolchain@nightly - name: cargo doc (all features) run: cargo doc --all-features --no-deps @@ -99,17 +94,11 @@ jobs: with: persist-credentials: false - name: Install rust toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: - toolchain: stable - override: true - default: true components: rustfmt - name: Check formatting - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check + run: cargo fmt --all -- --check clippy: name: Clippy @@ -120,13 +109,7 @@ jobs: with: persist-credentials: false - name: Install rust toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: - toolchain: stable - override: true - default: true components: clippy - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --all-features -- -D warnings + - run: cargo clippy --all-features -- --deny warnings From d4965b6d5cff72e999ad8611eb61a16691ca77c8 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Wed, 15 Mar 2023 11:07:43 -0400 Subject: [PATCH 010/133] CI: replace ubuntu 18.04 w/ 20.04. The Build+Test matrix job of the GitHub actions workflow was using Ubuntu 18.04, which is deprecated. This commit replaces it with Ubuntu 20.04, the oldest supported Ubuntu release available in GitHub actions at the time of writing. The other workflow task are using `ubuntu-latest` and do not need updating at this time. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2c2b5a0..add4bee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: - beta - nightly - 1.57 - os: [ubuntu-18.04] + os: [ubuntu-20.04] # but only stable on macos/windows (slower platforms) include: - os: macos-latest From 52b5c7a36cd6b6492ac10aa0e05dd2f95515340a Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 31 Mar 2023 17:24:01 +0200 Subject: [PATCH 011/133] Refresh example certificates (#174) --- examples/openssl.cnf | 25 +++++ examples/refresh-certificates.sh | 56 ++++++++++ examples/sample.pem | 170 +++++++++++++------------------ examples/sample.rsa | 50 ++++----- 4 files changed, 174 insertions(+), 127 deletions(-) create mode 100644 examples/openssl.cnf create mode 100755 examples/refresh-certificates.sh diff --git a/examples/openssl.cnf b/examples/openssl.cnf new file mode 100644 index 0000000..cda95b5 --- /dev/null +++ b/examples/openssl.cnf @@ -0,0 +1,25 @@ + +[ v3_end ] +basicConstraints = critical,CA:false +keyUsage = nonRepudiation, digitalSignature +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +subjectAltName = @alt_names + +[ v3_client ] +basicConstraints = critical,CA:false +keyUsage = nonRepudiation, digitalSignature +extendedKeyUsage = critical, clientAuth +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always + +[ v3_inter ] +subjectKeyIdentifier = hash +extendedKeyUsage = critical, serverAuth, clientAuth +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign + +[ alt_names ] +DNS.1 = testserver.com +DNS.2 = second.testserver.com +DNS.3 = localhost diff --git a/examples/refresh-certificates.sh b/examples/refresh-certificates.sh new file mode 100755 index 0000000..db98af7 --- /dev/null +++ b/examples/refresh-certificates.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +set -xe + +openssl req -nodes \ + -x509 \ + -days 3650 \ + -newkey rsa:4096 \ + -keyout ca.key \ + -out ca.cert \ + -sha256 \ + -batch \ + -subj "/CN=ponytown RSA CA" + +openssl req -nodes \ + -newkey rsa:3072 \ + -keyout inter.key \ + -out inter.req \ + -sha256 \ + -batch \ + -subj "/CN=ponytown RSA level 2 intermediate" + +openssl req -nodes \ + -newkey rsa:2048 \ + -keyout end.key \ + -out end.req \ + -sha256 \ + -batch \ + -subj "/CN=testserver.com" + +openssl rsa \ + -in end.key \ + -out sample.rsa + +openssl x509 -req \ + -in inter.req \ + -out inter.cert \ + -CA ca.cert \ + -CAkey ca.key \ + -sha256 \ + -days 3650 \ + -set_serial 123 \ + -extensions v3_inter -extfile openssl.cnf + +openssl x509 -req \ + -in end.req \ + -out end.cert \ + -CA inter.cert \ + -CAkey inter.key \ + -sha256 \ + -days 2000 \ + -set_serial 456 \ + -extensions v3_end -extfile openssl.cnf + +cat end.cert inter.cert ca.cert > sample.pem +rm *.key *.cert *.req diff --git a/examples/sample.pem b/examples/sample.pem index f2e9d92..50b24b4 100644 --- a/examples/sample.pem +++ b/examples/sample.pem @@ -1,113 +1,79 @@ -----BEGIN CERTIFICATE----- MIIEADCCAmigAwIBAgICAcgwDQYJKoZIhvcNAQELBQAwLDEqMCgGA1UEAwwhcG9u -eXRvd24gUlNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMB4XDTE2MDgxMzE2MDcwNFoX -DTIyMDIwMzE2MDcwNFowGTEXMBUGA1UEAwwOdGVzdHNlcnZlci5jb20wggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpVhh1/FNP2qvWenbZSghari/UThwe -dynfnHG7gc3JmygkEdErWBO/CHzHgsx7biVE5b8sZYNEDKFojyoPHGWK2bQM/FTy -niJCgNCLdn6hUqqxLAml3cxGW77hAWu94THDGB1qFe+eFiAUnDmob8gNZtAzT6Ky -b/JGJdrEU0wj+Rd7wUb4kpLInNH/Jc+oz2ii2AjNbGOZXnRz7h7Kv3sO9vABByYe -LcCj3qnhejHMqVhbAT1MD6zQ2+YKBjE52MsQKU/xhUpu9KkUyLh0cxkh3zrFiKh4 -Vuvtc+n7aeOv2jJmOl1dr0XLlSHBlmoKqH6dCTSbddQLmlK7dms8vE01AgMBAAGj -gb4wgbswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFMeUzGYV -bXwJNQVbY1+A8YXYZY8pMEIGA1UdIwQ7MDmAFJvEsUi7+D8vp8xcWvnEdVBGkpoW +eXRvd24gUlNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMB4XDTIyMDcwNDE0MzA1OFoX +DTI3MTIyNTE0MzA1OFowGTEXMBUGA1UEAwwOdGVzdHNlcnZlci5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDL35qLQLIqswCmHJxyczYF2p0YxXCq +gMvtRcKVElnifPMFrbGCY1aYBmhIiXPGRwhfythAtYfDQsrXFADZd52JPgZCR/u6 +DQMqKD2lcvFQkf7Kee/fNTOuQTQPh1XQx4ntxvicSATwEnuU28NwVnOU//Zzq2xn +Q34gUQNHWp1pN+B1La7emm/Ucgs1/2hMxwCZYUnRoiUoRGXUSzZuWokDOstPNkjc ++AjHmxONgowogmL2jKN9BjBw/8psGoqEOjMO+Lb9iekOCzX4kqHaRUbTlbSAviQu +2Q115xiZCBCZVtNE6DUG25buvpMSEXwpLd96nLywbrSCyueC7cd01/hpAgMBAAGj +gb4wgbswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFHGnzC5Q +A62Wmv4zfMk/kf/BxHevMEIGA1UdIwQ7MDmAFDMRUvwxXbYDBCxOdQ9xfBnNWUz0 oR6kHDAaMRgwFgYDVQQDDA9wb255dG93biBSU0EgQ0GCAXswOwYDVR0RBDQwMoIO dGVzdHNlcnZlci5jb22CFXNlY29uZC50ZXN0c2VydmVyLmNvbYIJbG9jYWxob3N0 -MA0GCSqGSIb3DQEBCwUAA4IBgQBsk5ivAaRAcNgjc7LEiWXFkMg703AqDDNx7kB1 -RDgLalLvrjOfOp2jsDfST7N1tKLBSQ9bMw9X4Jve+j7XXRUthcwuoYTeeo+Cy0/T -1Q78ctoX74E2nB958zwmtRykGrgE/6JAJDwGcgpY9kBPycGxTlCN926uGxHsDwVs -98cL6ZXptMLTR6T2XP36dAJZuOICSqmCSbFR8knc/gjUO36rXTxhwci8iDbmEVaf -BHpgBXGU5+SQ+QM++v6bHGf4LNQC5NZ4e4xvGax8ioYu/BRsB/T3Lx+RlItz4zdU -XuxCNcm3nhQV2ZHquRdbSdoyIxV5kJXel4wCmOhWIq7A2OBKdu5fQzIAzzLi65EN -RPAKsKB4h7hGgvciZQ7dsMrlGw0DLdJ6UrFyiR5Io7dXYT/+JP91lP5xsl6Lhg9O -FgALt7GSYRm2cZdgi9pO9rRr83Br1VjQT1vHz6yoZMXSqc4A2zcN2a2ZVq//rHvc -FZygs8miAhWPzqnpmgTj1cPiU1M= +MA0GCSqGSIb3DQEBCwUAA4IBgQBqKNIM/JBGRmGEopm5/WNKV8UoxKPA+2jR020t +RumXMAnJEfhsivF+Zw/rDmSDpmts/3cIlesKi47f13q4Mfj1QytQUDrsuQEyRTrV +Go6BOQQ4dkS+IqnIfSuue70wpvrZHhRHNFdFt9qM5wCLQokXlP988sEWUmyPPCbO +1BEpwWcP1kx+PdY8NKOhMnfq2RfluI/m4MA4NxJqAWajAhIbDNbvP8Ov4a71HPa6 +b1q9qIQE1ut8KycTrm9K32bVbvMHvR/TPUue8W0VvV2rWTGol5TSNgEQb9w6Kyf7 +N5HlRl9kZB4K8ckWH/JVn0pYNBQPgwbcUbJ/jp6w+LHrh+UW75maOY+IGjVICud8 +6Rc5DZZ2+AAbXJQZ1HMPrw9SW/16Eh/A4CIEsvbu9J+7IoSzhgcKFzOCUojzzRSj +iU7w/HsvpltmVCAZcZ/VARFbe1By2wXX2GSw2p2FVC8orXs76QyruPAVgSHCTVes +zzBo6GLScO/3b6uAcPM3MHRGGvE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIGnzCCAoegAwIBAgIBezANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9wb255 -dG93biBSU0EgQ0EwHhcNMTYwODEzMTYwNzA0WhcNMjYwODExMTYwNzA0WjAsMSow +MIIEnzCCAoegAwIBAgIBezANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9wb255 +dG93biBSU0EgQ0EwHhcNMjIwNzA0MTQzMDU4WhcNMzIwNzAxMTQzMDU4WjAsMSow KAYDVQQDDCFwb255dG93biBSU0EgbGV2ZWwgMiBpbnRlcm1lZGlhdGUwggGiMA0G -CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDIO5ONoB6s6oDayEHmxPGSmpDCfc++ -A5o0aRdIMerPW/KQlr56YggAiPZ/HOVFGP3lIBVQwUXAkyVn6MxKK1IMjVYh7WdP -WzeXgjMwLEL+7r0XXbbo2P2rzC/6tqFvhANA8GiXjTFmOm5h9GS73z78FkxcNgBo -lN1nsZwM5kf+xawusX5YsxjUFkIFTrlHRRl8A407nO3ZGtHzl8et27ooBlNG/Ys0 -fL8kNkyjg/KrowU/qCycSaxL12e066LgINDNdxWWw/jF+dm9gWYrQlRKDWFzw+qG -rnqUMHXwzAw/Qj0UPC1LtCVosysT3KpEPCmYTf1wFrT/TXPXPnYCBlTuo6fOLW0S -YZg5jc94h2JgS4zgCoYghJgnSzxHJ88/SBqEYtxoNbY92mpMHlu8I8XAgRyGjpk/ -wRb5gdsZ1vjwftW+cexyhtQDcdBa3csw064hL6018LgO8hM48EFFE0UcXgLk16Ur -awKj+/QXN2salh85529ysRxY3J0PA269h/cCAwEAAaNeMFwwHQYDVR0OBBYEFJvE -sUi7+D8vp8xcWvnEdVBGkpoWMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEF +CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCsTkd2SKiy3yy20lygOhKfOySo3qpq +TZVrpW11vQ58+6EcetXRnzIIK0HyhPmZrv9XKPpQclJvfY9jADNtu2CSj/v15OSB +Love3GzmXSZz2A8QUZBPWx6HczDG1hFGzrCZPKzpeLnFD1LPsKCUkUOHl1acyy24 +DaCacQJPzPQWbMhbGmYRlDNb+2R2K6UKMAEVe4IOTv2aSIKDGLI+xlaBXYAJj48L +//9eNmR3bMP3kkNKOKaaBk8vnYxKpZ+8ZHeHTmYWR9x1ZoMcbA9lKUwRpKAjY5JJ +NVZMDmjlVQVvvBrvhgz/zgXtfuaQCryZ0f1sEY/zXhdealo3fGVomeoniD4XwA1c +oaUFkbo5IM5HU/pXyAGRerDyhYLgRqQZMIRauvKRPN3jLsPOEQ0+gnXUUTr/YGIE +KY3/Axg4P3hzZCFqJ5IgkgWZr/dKr9p/0cxSUGHTVcpEFOlkKIIIdRuR7Ng5sJml +u7PAMWt6T+x02ORs1/WkyP7LyPQmuugYTicCAwEAAaNeMFwwHQYDVR0OBBYEFDMR +UvwxXbYDBCxOdQ9xfBnNWUz0MCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEF BQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jANBgkqhkiG9w0BAQsFAAOC -BAEAAZZhIHjNcLy0oMmi6brkWvaTL42hQPpzgtU8N+N/I8qm+6m3Rgnek8fr1fQX -ndFfrvlbgYUDydlcX7dpy4dJYaNdp+2y1mmor0sSgCuY9jWNpyMQOJ9ihrrIg+7L -CD2Vea/vPl9FAC/R0MOjs1fZ7Pui/ge/dmrF1VrznF3YfjHTbDTQ1rzNHpAhSUb3 -5uLgWttsMHVZevJDUa4PWy3wX7zyJsDPfjhGbVLonTYcLx8RmhliXh9U/v6Tmx/1 -lGtM4ZulO49D1jG0y5fcjFl63QUpaKh+v6AqfGlTfD5opG6WUJmqXClGEscZFj6b -al58GEmnE4aScYCvSFy87fTM/euHqSzIPGS488JwWDCDmGnNmv3x05+4ENo1vktU -xvW/dtFknbtDOP9J3I073lYi5AC4r6mZP0sxy+CbDHYtm7htpR19c2wTMJ01hUo2 -2YHwt412+MlTJjBFCK+PpDEjJ0etJb48lhUXHQJrHC2GL+1zyfA+eoKMMRdGMybm -zwAmqdTwQly1Z6woevtuHJ4fUp3Hv7mK3XtSXQ9kDKpXtcPYbJD2luPM3hDvVsta -SY5SQN1I5lFMDZDoBN8M2suA7RfqleOj6IwNJKS+AbetzMtw4NcNbGJwg6EL5v2n -HbPWoLps8e6MkfqVR9vG8ddz+nBN+QTJvlJv0nDM+z25BlTLrWb2epxyu5vBU5Ln -KE8/objQLSFtN17dnduf11cF08mgq4xaaHOBgvYoI1U/car4f9yZqyZ9+bpjD+4R -/h8N3hlHa7GTnJcrxseZGv/8QtPlJ1SBGlb1/iwCKIv54DLn2r5QEhXML2/SU+RY -LrBJf84TfkTuI4MBluJ+4XfGcLR50s1V7FjIm2lYNzCsvjMvbfcsnZK+krI8Qv4a -0Ivo1mzOBfbk6hpfHjoChvDIM73Rtt44vgdndJWIxvcUxT7dXcAf8ztA62HCicNW -Fh65GboY2VCsdoNfokR5XXJZaEOP9At2wI81XMd8+OvAw01z1aCQGwXHGEFfro9+ -RpYKPpMZn+tH0uzdOgbWruHV+Wm9MAI4TJW1pMjFOPam2YMB58MJ5XyulS15jKWW -JsYBTJ5mRJnJJYBsvGRstGJ+NL3hHND0KFzygREMhKWqDRB6zcyV0cQF59LUp9Ui -CPmLrxBvuJ3twn5dF/H3Df3NpyPYGAVsXRjVi7pyV1Vb3AqgRvDh76Jlq9GxTK5Q -3ld+hPXnSIsyqQukTymBsZCNPso8v8E9goGcfLXsTLuXjXOcanRpcA8I36YeDbI5 -dV+oLt/PGdEX58NyhG2w5pECGNaUnglJQxlzUsE1O2pJl+JlTc0cs4K9VgHi7OPH -TF3D/w2NKHQKH03neMEtR/O9YA== +AgEAYzqmX+cNPgVD2HWgbeimUraTpI9JP5P4TbOHWmaJKecoy3Hwr71xyAOGiVXL +urk1ZZe8n++GwuDEgRajN3HO9LR1Pu9qVIzTYIsz0ORRQHxujnF7CxK/I/vrIgde +pddUdHNS0Y0g8J1emH9BgoD8a2YsGX4iDY4S4hIGBbGvQp9z8U/uG1mViAmlXybM +b8bf0dx0tEFUyu8jsQP6nFLY/HhkEcvU6SnOzZHRsFko6NE44VIsHLd2+LS2LCM/ +NfAoTzgvj41M3zQCZapaHZc9KXfdcCvEFaySKGfEZeQTUR5W0FHsF5I4NLGryf5L +h3ENQ1tgBTO5WnqL/5rbgv6va9VionPM5sbEwAcancejnkVs3NoYPIPPgBFjaFmL +hNTpT9H2owdZvEwNDChVS0b8ukNNd4cERtvy0Ohc3mk0LGN0ABzrud0fIqa51LMh +0N3dkPkiZ4XYk4yLJ5EwCrCNNH50QkGCOWpInKIPeSYcALGgBDbCDLv6rV3oSKrV +tHCZQwXVKKgU4AQu7hlHBwJ61cH44ksydOidW3MNq1kDIp7ST8s7gVrItNgFnG+L +Jpo270riwSUlWDY4hXw5Ff5lE+bWCmFyyOkLevDkD9v8M4HdwEVvafYYwn75fCIS +5OnpSeIB08kKqCtW1WBwki0rYJjWqdzI7Z1MQ/AyScAKiGM= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIJBzCCBO+gAwIBAgIJAJuUqyA1Ag2pMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV -BAMMD3Bvbnl0b3duIFJTQSBDQTAeFw0xNjA4MTMxNjA3MDNaFw0yNjA4MTExNjA3 -MDNaMBoxGDAWBgNVBAMMD3Bvbnl0b3duIFJTQSBDQTCCBCIwDQYJKoZIhvcNAQEB -BQADggQPADCCBAoCggQBAL9B0WhEpdU7Dt7flCTUFkLEidfLvUm/Wyy6vXQz78dU -qatewsl1HER8pQ19SP3na42uI2OGObu60e3Bbm/PAS4v+hqknB8C7fzBZLifwYq5 -ZjRJPL+lorwYuvgMy5ImL0gBl0mBOE2tQyeM2/JXf5aXQHGGErrkhtxJ2+X9wEEi -y6IirzcJGENRQFk+XDMyDimklEpsFm9A162KxLrfUL2HeP6IlTjS4Y+oinxh5GJj -eNp95D28ih2qg7LPlb9NfhER7NPdID8aNk3rH2WQ82b3sjmHqD+AfHvC/Kk3pKsE -doyV1XqE6nisrWz06EOK5TzPfpwkgl7YsugJDgUj2Mn1wwQBWvniR88p4y5Dq126 -ruGCXLaHz5LETU0ohBb0RDxFqLVGX6QUSDPoiBInLbMh8H27PQcweKQ6YVEZaPzC -MapFuGO8CsV+WuKZgTz2iLu6Jwm8ibt+d4qTSKnltDI4IzFiKdfg4fvaQBLa9xBN -mkW5iPqbV5Ks8tcyzSlVSLTX+p00QEw8qQISAs5Jr7gaA3H/Wv/tkGi4ExgMdoZ6 -JywC/M3lpXgcJfnh5TyeE3o7SHEz36O3M5wuVOiccvcE0z581BwWhb9tN8pTXSgz -l3R7l0TK3FbGo+fmt9gj8H8CTc9cclZtm/BdlnOWDanGerJPM3Js2NOCYTzQOf8f -AAsGyqItqq1z7bD6HkZQ7Mjs+Cz6L/bRfvehZeK0DE1hENvLH/+kGuhyRx/JB4gW -Bt2CngBwnEBcuyhOhfuLGhLzj4gQNtayJoAG11OECllsVNNPo+5gV6EUO7pjJ+xK -K8WHO6WewUdqyA1K6eBuzSOnTuvnim4IXXhI/RmpWmQwo+hfJ3Ac+HSsoFgngW/k -ASBzPg8+Gpd/rKMD+/H5LefShD0hAuzVdBvo60H7WsK6eQ3/qoAC5GsUQhUEuI5l -s3NsUMhCFci5bHKJ+L3SW791Qog5eStohyJFdHRsrFJuXGOfJQRojYeKN+j3z1eE -1q8PI7Y+LNVoY4S1o6WO6aSWosS72KmwNqCVVUoOjjfuph13ONNtom7VbzmjMUuk -K7+LTGIrBREEtAN0U4kNGcrlmir1tRHRqS00ssYEYoDbAo/k9OEwrjxMBYx04nji -shijHVGfC4w7+gVhg9SeyQiGz9NnQgxzne8S7oQXrqops1wm2quaU58MEF9xuTxd -mlDA+SJhMKQpai9qyESVjeDoBiRMNZde6QgyXihtyAjPbSHCd4UNV1iCHqp++o4R -fbf4VCt34cZ1o8pxQB//qnyLbg3l9lfQ/D1YETOwj0hQteXmW5SxtVi+4OuRdtWx -s+/0lFUCrSq0YI/Sqyp8Fd/kdiv9tl4El9XISLXRrqECAwEAAaNQME4wHQYDVR0O -BBYEFETb4NlwlOrVgOwCAtS/dvoGbsbGMB8GA1UdIwQYMBaAFETb4NlwlOrVgOwC -AtS/dvoGbsbGMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggQBAB8owUwE -WnM1hLzunfgWdmrUw6876mGTwKMEY2g2Wa520+pT98W4IgfJSfreUWI1IrcHGwo5 -qr1GQDawqsVCZVmzKwwgr429XR7YXg0Frnu4l6vN/MmBSxqfDmO8BisBIBJA7nwF -+N+AlugAaGUd42/8T/3DfKzkQhI9vDFcy1SbmKjen5Mv6d14+nXFKWyflwUpMGAP -dM1KluG/teKCUOkHuTJmI/FAx5IznOdbQWxcnvUOuDhBcQasnU54NyIYt4k/jcD+ -9LX5jDCynI+T9i4GF2yOJIXjbPVQEi4Gfn/BqM22abreMEKut1hR8v1aneZmKs2g -hijmNTWv77ODpAnKsA+VEHoTiKiqmY1FHbqeR//0I+OPB82JAHM+iawasCdP4sNJ -TtKn2EksM49jp+6JZpRvQDW5J9iLVuCQ+Nph8zG4PDbohoO9DhDhyKOXJgMofUrj -EOn35XBEzX0xi4t9bapgtPNNOP0etHF6OroEXOMNDHp1F5Cpa+RN0jbWkBtpwA29 -yfbUzICCR90ulYe6zret53KVnNCKqCf1qxvxQf4RylBjZfe3wkPZxrHALVA8X/h5 -lYulkErYspEOZnhNevdznjOFcuG2pxNl8RYtYQMAjjHooGKcsDzHw8al4L/cBG+n -BQ/iU1tmWej+ykaxolYYKPo9GxJNB6eKOs0Uz2qnvhMdbf10rar29dG9Khc2N9jh -NT62HkkPCd49X9D2gL/mKYs1dkyj2soZYAUvkNyCbGnpt3V7CXjqtdAoUFg/Rn5H -H7MrBmYKJoLt0nb0tOtPg24x0V3IbpMP3aKdbbwJvKHiZJnjB5mI8WzFhlh3Hrpx -8SL1em0CCSGL++Ts1IPd7Mg+RhrW/fNeBMPpy8y5ZsT5IUpEQLmSbIbwdUl1VK+J -k0DFY9dT255yDY6y+mRMdN6i6ESlwFfkbD1yOyS8BPpR71fPpN6Z3Wb8C0v7d/el -DDT/OrSHWAiF3K1hKq549LpTbiSNoRlTbA1CDkifJ0VO8T7tqtR6ZeH7Du9R9Ogr -JTyqCdUwxS72YRczgDbRQbNL7hiNhzCzRXdLf3V6fareCh3dViRW4iVynSukuH5W -z9+F7uHnO0EGzxcaMpg2qqds+nZlkc0BgXT2M63bz9Zo9+TQTxSt/HePM3qLn+1l -jD1xbztjexcJvjpwFL4NEiOA++DwJAfPCtrAcX0x/fF/QZCQcbCPO/ES0eE9B5MN -F/Rt7frgbMwNB5xLe7hwUeHx69j5ga3UYUyceMWorsQQ46Y4UWPiQea0DAvh85FU -tTEIyyFhsFJ6UMtMpyfxvwshvZrImEaa9fIq96HixeA8Ey2qJ9h3GDiD0YdPpJg9 -uhZuLDgySxlb2xc= +MIIEsDCCApgCCQCfkxy3a+AgNjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9w +b255dG93biBSU0EgQ0EwHhcNMjIwNzA0MTQzMDU3WhcNMzIwNzAxMTQzMDU3WjAa +MRgwFgYDVQQDDA9wb255dG93biBSU0EgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCj6nW8pnN50UsH2NjL97xZKxlXPe5ptXfvqXczMsw0vB3gI4xJ +Tdmrnqo0K+VOH7vh+UXcOj2ZMY2ou6oDDK5Qpu9bvGPBIJH/rC1Ti2+u5Y4KTIUc +jWAtzQJeFn8+oCMfskpLdtlWLRdAuwqNHjvxXdd2JnsX1Wid85U/rG2SNPLGjJAF +xG7xzZC4VSO2WIXTGRMUkZfFc8fhWMjo3GaeF/qYjzfHDPWN/ll/7vfxyXJO/ohw +FzpJSZtKmI+6PLxqB/oFrKfTDQUGzxjfHp187bI3eyUFMJsp18/tLYkLyxSWIg3o +bq7ZVimHd1UG2Vb5Y+5pZkh22jmJ6bAa/kmNNwbsD+5vJhW1myGhmZSxkreYPWnS +6ELrSMvbXccFfTYmdBlWsZx/zUVUzVCPe9jdJki2VXlicohqtvBQqe6LGGO37vvv +Gwu1yzQ/rJy47rnaao7fSxqM8nsDjNR2Ev1v031QpEMWjfgUW0roW3H58RZSx+kU +gzIS2CjJIqKxCp894FUQbC6r0wwAuKltl3ywz5qWkxY0O9bXS0YdEXiri5pdsWjr +84shVVQwnoVD9539CLSdHZjlOCAzvSWHZH6ta2JZjUfYYz8cLyv2c2+y9BYrlvHw +T7U7BqzngUk72gcRXd5+Onp+16gGxpGJqaxqj94Nh/yTUnr2Jd9YaXeFmQIDAQAB +MA0GCSqGSIb3DQEBCwUAA4ICAQBzIRVRt3Yaw60tpkyz/i1xbKCbtC+HqYTEsXvZ +RvZ5X1qyLAcmu4EW9RHXnlLiawDbES6lCMFfdBUK03Wis7socvoFUCBRW337F4z2 +IivHfIge4u+w5ouUKPzcpj6oeuR06tmNytYbno6l8tXJpm1eeO4KNZ0ZtodmyB5D +yLrplFgxTdGGgyvxt8LoeLwGmPCyVt35x/Mz6x2lcq1+r7QJZ9sENhQYuA8UqHrw +fmNoVIMXMEcPLcWtFl6nKTK9LrqAu1jgTBqGGZKRn5CYBBK3pNEGKiOIsZXDbyFS +F59teFpJjyeJTbUbLxXDa15J6ExkHV9wFLEvfu/nzQzg8D9yzczSdbDkE2rrrL+s +Q/H/pIXO/DesCWQ37VALn3B5gm9UBd5uogbSw8eamiwRFLQ0snP80pJQGJoTNn0P +wrLLUf2gsKC2262igiA+imepm5wxbV9XGVZfHJgxCi5Zqrf6aWnjIqD2YtDvAHhs +V8ZWN3QTjdnEcQbG0544rocoLNX/FzmyDgjfZKY5r6wt+FWNc/R4clkF+KxasxqB +HdBs8j0lGV3ujvNXASLq9HI6VxZayrSfkR73hADCXIM/wzynKwMarvA4SXwYX9Pd +cJ4+FMqrevPpamMHUsNndS0KfDTdjDp+TSBf87yiyRkD1Ri4ePslyfNvRyv3Xs7k +47YFzA== -----END CERTIFICATE----- diff --git a/examples/sample.rsa b/examples/sample.rsa index b13bf5d..aec5347 100644 --- a/examples/sample.rsa +++ b/examples/sample.rsa @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAqVYYdfxTT9qr1np22UoIWq4v1E4cHncp35xxu4HNyZsoJBHR -K1gTvwh8x4LMe24lROW/LGWDRAyhaI8qDxxlitm0DPxU8p4iQoDQi3Z+oVKqsSwJ -pd3MRlu+4QFrveExwxgdahXvnhYgFJw5qG/IDWbQM0+ism/yRiXaxFNMI/kXe8FG -+JKSyJzR/yXPqM9ootgIzWxjmV50c+4eyr97DvbwAQcmHi3Ao96p4XoxzKlYWwE9 -TA+s0NvmCgYxOdjLEClP8YVKbvSpFMi4dHMZId86xYioeFbr7XPp+2njr9oyZjpd -Xa9Fy5UhwZZqCqh+nQk0m3XUC5pSu3ZrPLxNNQIDAQABAoIBAFKtZJgGsK6md4vq -kyiYSufrcBLaaEQ/rkQtYCJKyC0NAlZKFLRy9oEpJbNLm4cQSkYPXn3Qunx5Jj2k -2MYz+SgIDy7f7KHgr52Ew020dzNQ52JFvBgt6NTZaqL1TKOS1fcJSSNIvouTBerK -NCSXHzfb4P+MfEVe/w1c4ilE+kH9SzdEo2jK/sRbzHIY8TX0JbmQ4SCLLayr22YG -usIxtIYcWt3MMP/G2luRnYzzBCje5MXdpAhlHLi4TB6x4h5PmBKYc57uOVNngKLd -YyrQKcszW4Nx5v0a4HG3A5EtUXNCco1+5asXOg2lYphQYVh2R+1wgu5WiDjDVu+6 -EYgjFSkCgYEA0NBk6FDoxE/4L/4iJ4zIhu9BptN8Je/uS5c6wRejNC/VqQyw7SHb -hRFNrXPvq5Y+2bI/DxtdzZLKAMXOMjDjj0XEgfOIn2aveOo3uE7zf1i+njxwQhPu -uSYA9AlBZiKGr2PCYSDPnViHOspVJjxRuAgyWM1Qf+CTC0D95aj0oz8CgYEAz5n4 -Cb3/WfUHxMJLljJ7PlVmlQpF5Hk3AOR9+vtqTtdxRjuxW6DH2uAHBDdC3OgppUN4 -CFj55kzc2HUuiHtmPtx8mK6G+otT7Lww+nLSFL4PvZ6CYxqcio5MPnoYd+pCxrXY -JFo2W7e4FkBOxb5PF5So5plg+d0z/QiA7aFP1osCgYEAtgi1rwC5qkm8prn4tFm6 -hkcVCIXc+IWNS0Bu693bXKdGr7RsmIynff1zpf4ntYGpEMaeymClCY0ppDrMYlzU -RBYiFNdlBvDRj6s/H+FTzHRk2DT/99rAhY9nzVY0OQFoQIXK8jlURGrkmI/CYy66 -XqBmo5t4zcHM7kaeEBOWEKkCgYAYnO6VaRtPNQfYwhhoFFAcUc+5t+AVeHGW/4AY -M5qlAlIBu64JaQSI5KqwS0T4H+ZgG6Gti68FKPO+DhaYQ9kZdtam23pRVhd7J8y+ -xMI3h1kiaBqZWVxZ6QkNFzizbui/2mtn0/JB6YQ/zxwHwcpqx0tHG8Qtm5ZAV7PB -eLCYhQKBgQDALJxU/6hMTdytEU5CLOBSMby45YD/RrfQrl2gl/vA0etPrto4RkVq -UrkDO/9W4mZORClN3knxEFSTlYi8YOboxdlynpFfhcs82wFChs+Ydp1eEsVHAqtu -T+uzn0sroycBiBfVB949LExnzGDFUkhG0i2c2InarQYLTsIyHCIDEA== +MIIEpAIBAAKCAQEAy9+ai0CyKrMAphyccnM2BdqdGMVwqoDL7UXClRJZ4nzzBa2x +gmNWmAZoSIlzxkcIX8rYQLWHw0LK1xQA2XediT4GQkf7ug0DKig9pXLxUJH+ynnv +3zUzrkE0D4dV0MeJ7cb4nEgE8BJ7lNvDcFZzlP/2c6tsZ0N+IFEDR1qdaTfgdS2u +3ppv1HILNf9oTMcAmWFJ0aIlKERl1Es2blqJAzrLTzZI3PgIx5sTjYKMKIJi9oyj +fQYwcP/KbBqKhDozDvi2/YnpDgs1+JKh2kVG05W0gL4kLtkNdecYmQgQmVbTROg1 +BtuW7r6TEhF8KS3fepy8sG60gsrngu3HdNf4aQIDAQABAoIBAFTehqVFj2W7EqAT +9QSn9WtGcHNpbddsunfRvIj2FLj2LuzEO8r9s4Sh1jOsFKgL1e6asJ9vck7UtUAH +sbrV0pzZVx2sfZwb4p9gFRmU2eQigqCjVjnjGdqGhjeYrR62kjKLy96zFGskJpH3 +UkqnkoIKc/v+9qeeLxkg4G6JyFGOFHJAZEraxoGydJk9n/yBEZ/+3W7JUJaGOUNU +M7BYsCS2VOJr+cCqmCk1j8NvYvWWxTPsIXgGJl4EOoskzlzJnYLdh9fPFZu3uOIx +hpm3DBNp6X+qXf1lmx9EdpyeXKpLFIgJM7+nw2uWzxW7XMlRERi+5Tprc/pjrqUq +gpfyvMkCgYEA909QcJpS3qHoWyxGbI1zosVIZXdnj8L+GF/2kEQEU5iEYT+2M1U+ +gCPLr49gNwkD1FdBSCy+Fw20zi35jGmxNwhgp4V94CGYzqwQzpnvgIRBMiAIoEwI +CD5/t34DZ/82u8Gb7UYVrzOD54rJ628Q+tJEJak3TqoShbvcxJC/rXMCgYEA0wmO +SRoxrBE3rFzNQkqHbMHLe9LksW9YSIXdMBjq4DhzQEwI0YgPLajXnsLurqHaJrQA +JPtYkqiJkV7rvJLBo5wxwU+O2JKKa2jcMwuCZ4hOg5oBfK6ES9QJZUL7kDe2vsWy +rL+rnxJheUjDPBTopGHuuc9Nogid35CE0wy7S7MCgYArxB+KLeVofOKv79/uqgHC +1oL/Yegz6uAo1CLAWSki2iTjSPEnmHhdGPic8xSl6LSCyYZGDZT+Y3CR5FT7YmD4 +SkVAoEEsfwWZ3Z2D0n4uEjmvczfTlmD9hIH5qRVVPDcldxfvH64KuWUofslJHvi0 +Sq3AtHeTNknc3Ogu6SbivQKBgQC4ZAsMWHS6MTkBwvwdRd1Z62INyNDFL9JlW4FN +uxfN3cTlkwnJeiY48OOk9hFySDzBwFi3910Gl3fLqrIyy8+hUqIuk4LuO+vxuWdc +uluwdmqTlgZimGFDl/q1nXcMJYHo4fgh9D7R+E9ul2Luph43MtJRS447W2gFpNJJ +TUCA/QKBgQC07GFP2BN74UvL12f+FpZvE/UFtWnSZ8yJSq8oYpIbhmoF5EUF+XdA +E2y3l1cvmDJFo4RNZl+IQIbHACR3y1XOnh4/B9fMEsVQHK3x8exPk1vAk687bBG8 +TVDmdP52XEKHplcVoYKvGzw/wsObLAGyIbJ00t1VPU+7guTPsc+H/w== -----END RSA PRIVATE KEY----- From df93f7080cf80b986e8fcff8849ccc759913cfa8 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 9 May 2022 14:36:54 +0200 Subject: [PATCH 012/133] Add ConnectorBuilder::enable_all_versions() helper --- src/connector/builder.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/connector/builder.rs b/src/connector/builder.rs index a73d67c..c2d261c 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -174,6 +174,19 @@ impl ConnectorBuilder { }) } + /// Enable all HTTP versions + /// + /// For now, this enables both HTTP 1 and 2. In the future, other supported versions + /// will be enabled as well. + #[cfg(all(feature = "http1", feature = "http2"))] + pub fn enable_all_versions(mut self) -> ConnectorBuilder { + self.0.tls_config.alpn_protocols = vec![b"h2".to_vec()]; + ConnectorBuilder(WantsProtocols3 { + inner: self.0, + enable_http1: true, + }) + } + /// Override server name for the TLS stack /// /// By default, for each connection hyper-rustls will extract host portion From 68ed9e676d1188201f2f3ef42c86c2715837f61e Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Wed, 22 Mar 2023 13:15:41 -0400 Subject: [PATCH 013/133] deps: update rustls v0.20.1 -> v0.21.0 This commit updates hyper-rustls to use the freshly released rustls 0.21.0.work. We also use update to the recently released tokio-rustls v0.24.0 to match rustls versions there, and to webpki-roots 0.23.0. --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7f74f61..e50c84f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,15 +14,15 @@ http = "0.2" hyper = { version = "0.14", default-features = false, features = ["client"] } log = { version = "0.4.4", optional = true } rustls-native-certs = { version = "0.6", optional = true } -rustls = { version = "0.20.1", default-features = false } +rustls = { version = "0.21.0", default-features = false } tokio = "1.0" -tokio-rustls = { version = "0.23", default-features = false } -webpki-roots = { version = "0.22", optional = true } +tokio-rustls = { version = "0.24.0", default-features = false } +webpki-roots = { version = "0.23", optional = true } [dev-dependencies] futures-util = { version = "0.3.1", default-features = false } hyper = { version = "0.14", features = ["full"] } -rustls = { version = "0.20.1", default-features = false, features = ["tls12"] } +rustls = { version = "0.21.0", default-features = false, features = ["tls12"] } rustls-pemfile = "1.0.0" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } From 70fa4c18120017dc44a2bdfac6527f07253466ff Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Fri, 31 Mar 2023 09:48:29 -0400 Subject: [PATCH 014/133] crate: bump version from 0.23.2 -> 0.24.0. The update to Rustls 0.21.0 was a semver incompatible bump, and since types from that crate are part of our public API we must also bump the hyper-rustls version accordingly. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e50c84f..291f791 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.0" edition = "2021" rust-version = "1.57" license = "Apache-2.0/ISC/MIT" From 31a0236b56d3dd52174d75c2171b8c75c8d592dd Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sat, 1 Apr 2023 14:08:23 +0200 Subject: [PATCH 015/133] Update changelog for 0.24.0 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2cf9588..41bd9bb 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ and the [hyper HTTP library](https://github.com/hyperium/hyper). [![Documentation](https://docs.rs/hyper-rustls/badge.svg)](https://docs.rs/hyper-rustls/) # Release history +- 0.24.0 (2023-04-01): + * Upgrade to rustls 0.21.0, tokio-rustls 0.24.0 and webpki-roots 0.23.0. + * Add `ConnectorBuilder::enable_all_versions()` helper. - 0.23.2 (2022-12-08): * Strip brackets from IPv6 addresses in the servername. Thanks to @digitwolf. - 0.23.1 (2022-10-26): From 896456475f14588542c96fcd775b81cf94e03a6e Mon Sep 17 00:00:00 2001 From: Alex Touchet Date: Sat, 1 Apr 2023 13:14:32 -0700 Subject: [PATCH 016/133] Update repo URL and use SPDX license format --- Cargo.toml | 6 +++--- README.md | 4 ++-- src/lib.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 291f791..2efc683 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,11 +3,11 @@ name = "hyper-rustls" version = "0.24.0" edition = "2021" rust-version = "1.57" -license = "Apache-2.0/ISC/MIT" +license = "Apache-2.0 OR ISC OR MIT" readme = "README.md" description = "Rustls+hyper integration for pure rust HTTPS" -homepage = "https://github.com/ctz/hyper-rustls" -repository = "https://github.com/ctz/hyper-rustls" +homepage = "https://github.com/rustls/hyper-rustls" +repository = "https://github.com/rustls/hyper-rustls" [dependencies] http = "0.2" diff --git a/README.md b/README.md index 41bd9bb..47d0c35 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # hyper-rustls -This is an integration between the [rustls TLS stack](https://github.com/ctz/rustls) +This is an integration between the [rustls TLS stack](https://github.com/rustls/rustls) and the [hyper HTTP library](https://github.com/hyperium/hyper). -[![Build Status](https://github.com/ctz/hyper-rustls/workflows/hyper-rustls/badge.svg)](https://github.com/ctz/hyper-rustls/actions) +[![Build Status](https://github.com/rustls/hyper-rustls/workflows/hyper-rustls/badge.svg)](https://github.com/rustls/hyper-rustls/actions) [![Crate](https://img.shields.io/crates/v/hyper-rustls.svg)](https://crates.io/crates/hyper-rustls) [![Documentation](https://docs.rs/hyper-rustls/badge.svg)](https://docs.rs/hyper-rustls/) diff --git a/src/lib.rs b/src/lib.rs index 9be896e..af05074 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ //! # hyper-rustls //! //! A pure-Rust HTTPS connector for [hyper](https://hyper.rs), based on -//! [Rustls](https://github.com/ctz/rustls). +//! [Rustls](https://github.com/rustls/rustls). //! //! ## Example //! From 30e2bd676f57c2e2c1105f2747f4e49fc00eee45 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Tue, 4 Apr 2023 14:22:33 -0400 Subject: [PATCH 017/133] chore: delete unused Azure pipeline remnants. (#203) In 2021 the top-level Azure pipelines configuration in `.azure-pipelines.yml` was removed, but the `admin/` directory of YAML pipeline configurations remained. This commit removes the `admin/` directory since it isn't hasn't been used for anything in some time. --- admin/pipelines/cargo-steps.yml | 16 -------------- admin/pipelines/clippy.yml | 17 --------------- admin/pipelines/rustup.yml | 38 --------------------------------- 3 files changed, 71 deletions(-) delete mode 100644 admin/pipelines/cargo-steps.yml delete mode 100644 admin/pipelines/clippy.yml delete mode 100644 admin/pipelines/rustup.yml diff --git a/admin/pipelines/cargo-steps.yml b/admin/pipelines/cargo-steps.yml deleted file mode 100644 index 0a64af8..0000000 --- a/admin/pipelines/cargo-steps.yml +++ /dev/null @@ -1,16 +0,0 @@ -steps: - - script: cargo build - displayName: "cargo build (debug; default features)" - - - script: cargo test - displayName: "cargo test (debug; default features)" - env: { "RUST_BACKTRACE": "1" } - - script: cargo test --no-default-features --features webpki-tokio - displayName: "cargo test (debug; webpi-roots feature)" - env: { "RUST_BACKTRACE": "1" } - - script: cargo test --no-default-features - displayName: "cargo build (debug; no default features)" - env: { "RUST_BACKTRACE": "1" } - - - script: cargo test --release --no-run - displayName: "cargo test (release; no run)" diff --git a/admin/pipelines/clippy.yml b/admin/pipelines/clippy.yml deleted file mode 100644 index c1d9976..0000000 --- a/admin/pipelines/clippy.yml +++ /dev/null @@ -1,17 +0,0 @@ -parameters: - rustup_toolchain: 'stable' - working_directory: './' -jobs: -- job: clippy - pool: - vmImage: ubuntu-16.04 - steps: - - template: rustup.yml - parameters: - rustup_toolchain: ${{ parameters.rustup_toolchain }} - components: - - clippy - - script: | - cargo clippy - workingDirectory: ${{ parameters.working_directory }} - displayName: Run clippy diff --git a/admin/pipelines/rustup.yml b/admin/pipelines/rustup.yml deleted file mode 100644 index 9ba6868..0000000 --- a/admin/pipelines/rustup.yml +++ /dev/null @@ -1,38 +0,0 @@ -parameters: - rustup_toolchain: 'stable' - rustup_target: '' - components: [] - -steps: -# Linux and macOS. -- script: | - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none - export PATH=$PATH:$HOME/.cargo/bin - rustup default ${{ parameters.rustup_toolchain }} - rustup update - echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" - condition: ne( variables['Agent.OS'], 'Windows_NT' ) - displayName: Install rust -# Windows. -- script: | - curl -sSf -o rustup-init.exe https://win.rustup.rs - rustup-init.exe -y --default-toolchain none - set PATH=%PATH%;%USERPROFILE%\.cargo\bin - rustup default ${{ parameters.rustup_toolchain }} - rustup update - echo "##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin" - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: Install rust (windows) -# All platforms. -- script: | - rustc -Vv - cargo -V - displayName: Query rust and cargo versions -- ${{ if ne(parameters.rustup_target, '') }}: - - script: | - rustup target add ${{ parameters.rustup_target }} - displayName: Install support for ${{ parameters.rustup_target }} -- ${{ each component in parameters.components }}: - - script: | - rustup component add ${{ component }} - displayName: Install ${{ component }} From 843cb638462115b7999095ce360770f7a2a9cd3f Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Mon, 10 Apr 2023 10:11:49 -0700 Subject: [PATCH 018/133] Add documentation metadata to Cargo.toml so crates.io will link directly to it. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 2efc683..22f63d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ readme = "README.md" description = "Rustls+hyper integration for pure rust HTTPS" homepage = "https://github.com/rustls/hyper-rustls" repository = "https://github.com/rustls/hyper-rustls" +documentation = "https://docs.rs/hyper-rustls/" [dependencies] http = "0.2" From 4e697ec62337106e0d13bf7d44922921c04a23bd Mon Sep 17 00:00:00 2001 From: Julian Antonielli Date: Tue, 7 Feb 2023 10:40:51 +0000 Subject: [PATCH 019/133] Add `HttpsConnector::https_only` --- src/connector.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/connector.rs b/src/connector.rs index f10fbd1..6467701 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -23,6 +23,15 @@ pub struct HttpsConnector { override_server_name: Option, } +impl HttpsConnector { + /// Force the use of HTTPS when connecting. + /// + /// If a URL is not `https` when connecting, an error is returned. + pub fn https_only(&mut self, enable: bool) { + self.force_https = enable; + } +} + impl fmt::Debug for HttpsConnector { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("HttpsConnector") From a407b891d128d43c024595c7f3f7ccc814628e76 Mon Sep 17 00:00:00 2001 From: Julian Antonielli Date: Tue, 4 Apr 2023 18:53:10 +0100 Subject: [PATCH 020/133] Change `https_only` to `enforce_https` --- src/connector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 6467701..18ad689 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -27,8 +27,8 @@ impl HttpsConnector { /// Force the use of HTTPS when connecting. /// /// If a URL is not `https` when connecting, an error is returned. - pub fn https_only(&mut self, enable: bool) { - self.force_https = enable; + pub fn enforce_https(&mut self) { + self.force_https = true; } } From 7fab72c134e62ef4fc4cbb072c973d4d87c431bf Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 24 May 2023 14:01:21 +0200 Subject: [PATCH 021/133] Only check library against MSRV --- .github/workflows/build.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index add4bee..39cc8d0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,6 @@ jobs: - stable - beta - nightly - - 1.57 os: [ubuntu-20.04] # but only stable on macos/windows (slower platforms) include: @@ -68,6 +67,22 @@ jobs: - name: cargo test (release; no run) run: cargo test --release --no-run + msrv: + runs-on: ubuntu-20.04 + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + persist-credentials: false + + - name: Install rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.57" + + - name: Check MSRV + run: cargo check --lib --all-features + docs: name: Check for documentation errors runs-on: ubuntu-18.04 From 628da2b4064005c1a09783137b3d2b99a768f18c Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 24 May 2023 14:05:20 +0200 Subject: [PATCH 022/133] Bump MSRV to 1.60 for base64 (via rustls-native-certs) --- .github/workflows/build.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 39cc8d0..f971370 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,7 +78,7 @@ jobs: - name: Install rust toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "1.57" + toolchain: "1.60" - name: Check MSRV run: cargo check --lib --all-features diff --git a/Cargo.toml b/Cargo.toml index 22f63d8..3cd081c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "hyper-rustls" version = "0.24.0" edition = "2021" -rust-version = "1.57" +rust-version = "1.60" license = "Apache-2.0 OR ISC OR MIT" readme = "README.md" description = "Rustls+hyper integration for pure rust HTTPS" From a0dd81122033c05a4fc0dcc5d4792fabd3121484 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Wed, 24 May 2023 09:19:00 -0400 Subject: [PATCH 023/133] ci: Ubuntu 18.04 -> 20.04 for doc tests. (#206) The Ubuntu 18.04 runner type has been removed after a deprecation period. Without this change the "Check for documentation errors" tasks remain stuck in a queued state waiting for runners that will never appear. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f971370..74852c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -85,7 +85,7 @@ jobs: docs: name: Check for documentation errors - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - name: Checkout sources uses: actions/checkout@v3 From 286e1fa57ff5cac99994fab355f91c3454d6d83d Mon Sep 17 00:00:00 2001 From: "Heinz N. Gies" Date: Fri, 26 May 2023 15:45:13 +0200 Subject: [PATCH 024/133] Add TLSAcceptor and Builder (#186) Signed-off-by: Heinz N. Gies Co-authored-by: Dirkjan Ochtman Co-authored-by: Daniel McCarney --- Cargo.toml | 6 +- examples/server.rs | 150 +++++---------------------------------- src/acceptor.rs | 139 ++++++++++++++++++++++++++++++++++++ src/acceptor/builder.rs | 98 +++++++++++++++++++++++++ src/connector/builder.rs | 12 ++-- src/lib.rs | 55 +++++++++++++- tests/tests.rs | 1 + 7 files changed, 319 insertions(+), 142 deletions(-) create mode 100644 src/acceptor.rs create mode 100644 src/acceptor/builder.rs diff --git a/Cargo.toml b/Cargo.toml index 3cd081c..add8236 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ rustls = { version = "0.21.0", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.24.0", default-features = false } webpki-roots = { version = "0.23", optional = true } +futures-util = { version = "0.3" } [dev-dependencies] futures-util = { version = "0.3.1", default-features = false } @@ -28,7 +29,8 @@ rustls-pemfile = "1.0.0" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } [features] -default = ["native-tokio", "http1", "tls12", "logging"] +default = ["native-tokio", "http1", "tls12", "logging", "acceptor"] +acceptor = ["hyper/server", "tokio-runtime"] http1 = ["hyper/http1"] http2 = ["hyper/http2"] webpki-tokio = ["tokio-runtime", "webpki-roots"] @@ -45,7 +47,7 @@ required-features = ["native-tokio", "http1"] [[example]] name = "server" path = "examples/server.rs" -required-features = ["tokio-runtime"] +required-features = ["tokio-runtime", "acceptor"] [package.metadata.docs.rs] all-features = true diff --git a/examples/server.rs b/examples/server.rs index 69702d3..964303b 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -4,19 +4,16 @@ //! Certificate and private key are hardcoded to sample files. //! hyper will automatically use HTTP/2 if a client starts talking HTTP/2, //! otherwise HTTP/1.1 will be used. -use core::task::{Context, Poll}; -use futures_util::ready; -use hyper::server::accept::Accept; -use hyper::server::conn::{AddrIncoming, AddrStream}; + +#![cfg(feature = "acceptor")] + +use std::vec::Vec; +use std::{env, fs, io}; + +use hyper::server::conn::AddrIncoming; use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Method, Request, Response, Server, StatusCode}; -use std::future::Future; -use std::pin::Pin; -use std::sync::Arc; -use std::vec::Vec; -use std::{env, fs, io, sync}; -use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; -use tokio_rustls::rustls::ServerConfig; +use hyper_rustls::TlsAcceptor; fn main() { // Serve an echo service over HTTPS, with proper error handling. @@ -39,27 +36,21 @@ async fn run_server() -> Result<(), Box> { }; let addr = format!("127.0.0.1:{}", port).parse()?; + // Load public certificate. + let certs = load_certs("examples/sample.pem")?; + // Load private key. + let key = load_private_key("examples/sample.rsa")?; // Build TLS configuration. - let tls_cfg = { - // Load public certificate. - let certs = load_certs("examples/sample.pem")?; - // Load private key. - let key = load_private_key("examples/sample.rsa")?; - // Do not use client certificate authentication. - let mut cfg = rustls::ServerConfig::builder() - .with_safe_defaults() - .with_no_client_auth() - .with_single_cert(certs, key) - .map_err(|e| error(format!("{}", e)))?; - // Configure ALPN to accept HTTP/2, HTTP/1.1, and HTTP/1.0 in that order. - cfg.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()]; - sync::Arc::new(cfg) - }; // Create a TCP listener via tokio. let incoming = AddrIncoming::bind(&addr)?; + let acceptor = TlsAcceptor::builder() + .with_single_cert(certs, key) + .map_err(|e| error(format!("{}", e)))? + .with_all_versions_alpn() + .with_incoming(incoming); let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(echo)) }); - let server = Server::builder(TlsAcceptor::new(tls_cfg, incoming)).serve(service); + let server = Server::builder(acceptor).serve(service); // Run the future, keep going until an error occurs. println!("Starting to serve on https://{}.", addr); @@ -67,111 +58,6 @@ async fn run_server() -> Result<(), Box> { Ok(()) } -enum State { - Handshaking(tokio_rustls::Accept), - Streaming(tokio_rustls::server::TlsStream), -} - -// tokio_rustls::server::TlsStream doesn't expose constructor methods, -// so we have to TlsAcceptor::accept and handshake to have access to it -// TlsStream implements AsyncRead/AsyncWrite handshaking tokio_rustls::Accept first -pub struct TlsStream { - state: State, -} - -impl TlsStream { - fn new(stream: AddrStream, config: Arc) -> TlsStream { - let accept = tokio_rustls::TlsAcceptor::from(config).accept(stream); - TlsStream { - state: State::Handshaking(accept), - } - } -} - -impl AsyncRead for TlsStream { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context, - buf: &mut ReadBuf, - ) -> Poll> { - let pin = self.get_mut(); - match pin.state { - State::Handshaking(ref mut accept) => match ready!(Pin::new(accept).poll(cx)) { - Ok(mut stream) => { - let result = Pin::new(&mut stream).poll_read(cx, buf); - pin.state = State::Streaming(stream); - result - } - Err(err) => Poll::Ready(Err(err)), - }, - State::Streaming(ref mut stream) => Pin::new(stream).poll_read(cx, buf), - } - } -} - -impl AsyncWrite for TlsStream { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - let pin = self.get_mut(); - match pin.state { - State::Handshaking(ref mut accept) => match ready!(Pin::new(accept).poll(cx)) { - Ok(mut stream) => { - let result = Pin::new(&mut stream).poll_write(cx, buf); - pin.state = State::Streaming(stream); - result - } - Err(err) => Poll::Ready(Err(err)), - }, - State::Streaming(ref mut stream) => Pin::new(stream).poll_write(cx, buf), - } - } - - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match self.state { - State::Handshaking(_) => Poll::Ready(Ok(())), - State::Streaming(ref mut stream) => Pin::new(stream).poll_flush(cx), - } - } - - fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match self.state { - State::Handshaking(_) => Poll::Ready(Ok(())), - State::Streaming(ref mut stream) => Pin::new(stream).poll_shutdown(cx), - } - } -} - -pub struct TlsAcceptor { - config: Arc, - incoming: AddrIncoming, -} - -impl TlsAcceptor { - pub fn new(config: Arc, incoming: AddrIncoming) -> TlsAcceptor { - TlsAcceptor { config, incoming } - } -} - -impl Accept for TlsAcceptor { - type Conn = TlsStream; - type Error = io::Error; - - fn poll_accept( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll>> { - let pin = self.get_mut(); - match ready!(Pin::new(&mut pin.incoming).poll_accept(cx)) { - Some(Ok(sock)) => Poll::Ready(Some(Ok(TlsStream::new(sock, pin.config.clone())))), - Some(Err(e)) => Poll::Ready(Some(Err(e))), - None => Poll::Ready(None), - } - } -} - // Custom echo service, handling two different routes and a // catch-all 404 responder. async fn echo(req: Request) -> Result, hyper::Error> { diff --git a/src/acceptor.rs b/src/acceptor.rs new file mode 100644 index 0000000..e843be2 --- /dev/null +++ b/src/acceptor.rs @@ -0,0 +1,139 @@ +use core::task::{Context, Poll}; +use std::future::Future; +use std::io; +use std::pin::Pin; +use std::sync::Arc; + +use futures_util::ready; +use hyper::server::{ + accept::Accept, + conn::{AddrIncoming, AddrStream}, +}; +use rustls::ServerConfig; +use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; + +mod builder; +pub use builder::AcceptorBuilder; +use builder::WantsTlsConfig; + +enum State { + Handshaking(tokio_rustls::Accept), + Streaming(tokio_rustls::server::TlsStream), +} + +// tokio_rustls::server::TlsStream doesn't expose constructor methods, +// so we have to TlsAcceptor::accept and handshake to have access to it +// TlsStream implements AsyncRead/AsyncWrite by handshaking with tokio_rustls::Accept first +pub struct TlsStream { + state: State, +} + +impl TlsStream { + fn new(stream: AddrStream, config: Arc) -> TlsStream { + let accept = tokio_rustls::TlsAcceptor::from(config).accept(stream); + TlsStream { + state: State::Handshaking(accept), + } + } +} + +impl AsyncRead for TlsStream { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context, + buf: &mut ReadBuf, + ) -> Poll> { + let pin = self.get_mut(); + match pin.state { + State::Handshaking(ref mut accept) => match ready!(Pin::new(accept).poll(cx)) { + Ok(mut stream) => { + let result = Pin::new(&mut stream).poll_read(cx, buf); + pin.state = State::Streaming(stream); + result + } + Err(err) => Poll::Ready(Err(err)), + }, + State::Streaming(ref mut stream) => Pin::new(stream).poll_read(cx, buf), + } + } +} + +impl AsyncWrite for TlsStream { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + let pin = self.get_mut(); + match pin.state { + State::Handshaking(ref mut accept) => match ready!(Pin::new(accept).poll(cx)) { + Ok(mut stream) => { + let result = Pin::new(&mut stream).poll_write(cx, buf); + pin.state = State::Streaming(stream); + result + } + Err(err) => Poll::Ready(Err(err)), + }, + State::Streaming(ref mut stream) => Pin::new(stream).poll_write(cx, buf), + } + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.state { + State::Handshaking(_) => Poll::Ready(Ok(())), + State::Streaming(ref mut stream) => Pin::new(stream).poll_flush(cx), + } + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.state { + State::Handshaking(_) => Poll::Ready(Ok(())), + State::Streaming(ref mut stream) => Pin::new(stream).poll_shutdown(cx), + } + } +} + +/// A TLS acceptor that can be used with hyper servers. +pub struct TlsAcceptor { + config: Arc, + incoming: AddrIncoming, +} + +/// An Acceptor for the `https` scheme. +impl TlsAcceptor { + /// Provides a builder for a `TlsAcceptor`. + pub fn builder() -> AcceptorBuilder { + AcceptorBuilder::new() + } + /// Creates a new `TlsAcceptor` from a `ServerConfig` and an `AddrIncoming`. + pub fn new(config: Arc, incoming: AddrIncoming) -> TlsAcceptor { + TlsAcceptor { config, incoming } + } +} + +impl From<(C, I)> for TlsAcceptor +where + C: Into>, + I: Into, +{ + fn from((config, incoming): (C, I)) -> TlsAcceptor { + TlsAcceptor::new(config.into(), incoming.into()) + } +} + +impl Accept for TlsAcceptor { + type Conn = TlsStream; + type Error = io::Error; + + fn poll_accept( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { + let pin = self.get_mut(); + match ready!(Pin::new(&mut pin.incoming).poll_accept(cx)) { + Some(Ok(sock)) => Poll::Ready(Some(Ok(TlsStream::new(sock, pin.config.clone())))), + Some(Err(e)) => Poll::Ready(Some(Err(e))), + None => Poll::Ready(None), + } + } +} diff --git a/src/acceptor/builder.rs b/src/acceptor/builder.rs new file mode 100644 index 0000000..70c0ca7 --- /dev/null +++ b/src/acceptor/builder.rs @@ -0,0 +1,98 @@ +use std::sync::Arc; + +use hyper::server::conn::AddrIncoming; +use rustls::ServerConfig; + +use super::TlsAcceptor; +/// Builder for [`TlsAcceptor`] +pub struct AcceptorBuilder(State); + +/// State of a builder that needs a TLS client config next +pub struct WantsTlsConfig(()); + +impl AcceptorBuilder { + /// Creates a new [`AcceptorBuilder`] + pub fn new() -> Self { + Self(WantsTlsConfig(())) + } + + /// Passes a rustls [`ServerConfig`] to configure the TLS connection + pub fn with_tls_config(self, config: ServerConfig) -> AcceptorBuilder { + AcceptorBuilder(WantsAlpn(config)) + } + + /// Use rustls [defaults][with_safe_defaults] without [client authentication][with_no_client_auth] + /// + /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults + /// [with_no_client_auth]: rustls::ConfigBuilder::with_no_client_auth + pub fn with_single_cert( + self, + cert_chain: Vec, + key_der: rustls::PrivateKey, + ) -> Result, rustls::Error> { + Ok(AcceptorBuilder(WantsAlpn( + ServerConfig::builder() + .with_safe_defaults() + .with_no_client_auth() + .with_single_cert(cert_chain, key_der)?, + ))) + } +} + +impl Default for AcceptorBuilder { + fn default() -> Self { + Self::new() + } +} + +/// State of a builder that needs a incoming address next +pub struct WantsAlpn(ServerConfig); + +impl AcceptorBuilder { + /// Configure ALPN accept protocols in order + pub fn with_alpn_protocols( + mut self, + alpn_protocols: Vec>, + ) -> AcceptorBuilder { + self.0 .0.alpn_protocols = alpn_protocols; + AcceptorBuilder(WantsIncoming(self.0 .0)) + } + + /// Configure ALPN to accept HTTP/2 + pub fn with_http2_alpn(mut self) -> AcceptorBuilder { + self.0 .0.alpn_protocols = vec![b"h2".to_vec()]; + AcceptorBuilder(WantsIncoming(self.0 .0)) + } + + /// Configure ALPN to accept HTTP/1.0 + pub fn with_http10_alpn(mut self) -> AcceptorBuilder { + self.0 .0.alpn_protocols = vec![b"http/1.0".to_vec()]; + AcceptorBuilder(WantsIncoming(self.0 .0)) + } + + /// Configure ALPN to accept HTTP/1.1 + pub fn with_http11_alpn(mut self) -> AcceptorBuilder { + self.0 .0.alpn_protocols = vec![b"http/1.1".to_vec()]; + AcceptorBuilder(WantsIncoming(self.0 .0)) + } + + /// Configure ALPN to accept HTTP/2, HTTP/1.1, HTTP/1.0 in that order. + pub fn with_all_versions_alpn(mut self) -> AcceptorBuilder { + self.0 .0.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()]; + AcceptorBuilder(WantsIncoming(self.0 .0)) + } +} + +/// State of a builder that needs a incoming address next +pub struct WantsIncoming(ServerConfig); + +impl AcceptorBuilder { + /// Passes a [`AddrIncoming`] to configure the TLS connection and + /// creates the [`TlsAcceptor`] + pub fn with_incoming(self, incoming: impl Into) -> TlsAcceptor { + TlsAcceptor { + config: Arc::new(self.0 .0), + incoming: incoming.into(), + } + } +} diff --git a/src/connector/builder.rs b/src/connector/builder.rs index c2d261c..fdec7a8 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -274,13 +274,11 @@ impl ConnectorBuilder { #[cfg(test)] mod tests { - use super::ConnectorBuilder as HttpsConnectorBuilder; - // Typical usage #[test] #[cfg(all(feature = "webpki-roots", feature = "http1"))] fn test_builder() { - let _connector = HttpsConnectorBuilder::new() + let _connector = super::ConnectorBuilder::new() .with_webpki_roots() .https_only() .enable_http1() @@ -297,7 +295,7 @@ mod tests { .with_root_certificates(roots) .with_no_client_auth(); config_with_alpn.alpn_protocols = vec![b"fancyprotocol".to_vec()]; - let _connector = HttpsConnectorBuilder::new() + let _connector = super::ConnectorBuilder::new() .with_tls_config(config_with_alpn) .https_only() .enable_http1() @@ -312,7 +310,7 @@ mod tests { .with_safe_defaults() .with_root_certificates(roots) .with_no_client_auth(); - let connector = HttpsConnectorBuilder::new() + let connector = super::ConnectorBuilder::new() .with_tls_config(tls_config.clone()) .https_only() .enable_http1() @@ -321,13 +319,13 @@ mod tests { .tls_config .alpn_protocols .is_empty()); - let connector = HttpsConnectorBuilder::new() + let connector = super::ConnectorBuilder::new() .with_tls_config(tls_config.clone()) .https_only() .enable_http2() .build(); assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); - let connector = HttpsConnectorBuilder::new() + let connector = super::ConnectorBuilder::new() .with_tls_config(tls_config) .https_only() .enable_http1() diff --git a/src/lib.rs b/src/lib.rs index af05074..b207568 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ //! A pure-Rust HTTPS connector for [hyper](https://hyper.rs), based on //! [Rustls](https://github.com/rustls/rustls). //! -//! ## Example +//! ## Example client //! //! ```no_run //! # #[cfg(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1"))] @@ -26,10 +26,61 @@ //! # #[cfg(not(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1")))] //! # fn main() {} //! ``` +//! +//! ## Example server +//! +//! ```no_run +//! # #[cfg(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1", feature = "acceptor"))] +//! # fn main() { +//! use hyper::server::conn::AddrIncoming; +//! use hyper::service::{make_service_fn, service_fn}; +//! use hyper::{Body, Method, Request, Response, Server, StatusCode}; +//! use hyper_rustls::TlsAcceptor; +//! use std::io; +//! use std::fs::File; +//! +//! let mut rt = tokio::runtime::Runtime::new().unwrap(); +//! let addr = "127.0.0.1:1337".parse().unwrap(); +//! +//! // Load public certificate. +//! let certfile = File::open("examples/sample.pem").unwrap(); +//! let mut reader = io::BufReader::new(certfile); +//! +//! // Load and return certificate. +//! let certs = rustls_pemfile::certs(&mut reader).unwrap(); +//! let certs = certs.into_iter().map(rustls::Certificate).collect(); +//! +//! // Load private key. (see `examples/server.rs`) +//! let keyfile = File::open("examples/sample.rsa").unwrap(); +//! let mut reader = io::BufReader::new(keyfile); +//! +//! // Load and return a single private key. +//! let keys = rustls_pemfile::rsa_private_keys(&mut reader).unwrap(); +//! let key = rustls::PrivateKey(keys[0].clone()); +//! let https = hyper_rustls::HttpsConnectorBuilder::new() +//! .with_native_roots() +//! .https_only() +//! .enable_http1() +//! .build(); +//! +//! let incoming = AddrIncoming::bind(&addr).unwrap(); +//! let acceptor = TlsAcceptor::builder() +//! .with_single_cert(certs, key).unwrap() +//! .with_all_versions_alpn() +//! .with_incoming(incoming); +//! let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(|_req|async {Ok::<_, io::Error>(Response::new(Body::empty()))})) }); +//! let server = Server::builder(acceptor).serve(service); +//! // server.await.unwrap(); +//! # } +//! # #[cfg(not(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1")))] +//! # fn main() {} +//! ``` #![warn(missing_docs)] #![cfg_attr(docsrs, feature(doc_cfg))] +#[cfg(feature = "acceptor")] +mod acceptor; mod config; mod connector; mod stream; @@ -46,6 +97,8 @@ mod log { pub(crate) use {debug, trace}; } +#[cfg(feature = "acceptor")] +pub use crate::acceptor::{AcceptorBuilder, TlsAcceptor}; pub use crate::config::ConfigBuilderExt; pub use crate::connector::builder::ConnectorBuilder as HttpsConnectorBuilder; pub use crate::connector::HttpsConnector; diff --git a/tests/tests.rs b/tests/tests.rs index aa39880..72dd114 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -42,6 +42,7 @@ fn client() { assert!(rc.status.success()); } +#[cfg(feature = "acceptor")] #[test] fn server() { let mut srv = server_command() From 0da5554d3a9b986403c0e5680079e572fe1d581f Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 4 Jul 2023 12:37:16 +0200 Subject: [PATCH 025/133] Add link to release history --- README.md | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 47d0c35..2cae804 100644 --- a/README.md +++ b/README.md @@ -7,39 +7,8 @@ and the [hyper HTTP library](https://github.com/hyperium/hyper). [![Documentation](https://docs.rs/hyper-rustls/badge.svg)](https://docs.rs/hyper-rustls/) # Release history -- 0.24.0 (2023-04-01): - * Upgrade to rustls 0.21.0, tokio-rustls 0.24.0 and webpki-roots 0.23.0. - * Add `ConnectorBuilder::enable_all_versions()` helper. -- 0.23.2 (2022-12-08): - * Strip brackets from IPv6 addresses in the servername. Thanks to @digitwolf. -- 0.23.1 (2022-10-26): - * Allow overriding the servername. Thanks to @MikailBag. -- 0.23.0 (2021-11-21): - * Upgrade to rustls 0.20. Thanks to @g2p. - * Add new HttpsConnectorBuilder API. Thanks to @g2p. - * Add the tls12, logging, http1 and http2 features. Thanks to @g2p and @marwes. -- 0.22.1 (2020-12-27): - * Fixing docs.rs build; no other changes. -- 0.22.0 (2020-12-26): - * Use tokio 1.0, hyper 0.14, and rustls 0.19. Thanks to @paolobarbolini and @messense. - * Rework how the certificate store is chosen: now by an explicit API rather than - implicitly by crate features. Thanks to @djc. -- 0.21.0 (2020-07-05): - * Update dependencies. -- 0.20.0 (2020-02-24): - * Use newer rustls-native-certs which works in presence of invalid certificates. - * Update dependencies. -- 0.19.1 (2020-01-19): - * Remove dependency on hyper's tcp feature. -- 0.19.0 (2019-12-17): - * First release with async/await support. Many thanks to @CryZe, @alex, @markuskobler and @dbcfd. -- 0.18.0 (2019-11-23) - * Uses [rustls-native-certs](https://crates.io/crates/rustls-native-certs) - instead of compiled-in root certificates. -- 0.17.1 (2019-08-19) - * Fix accidental use of sync read/write. -- 0.17.0 (2019-08-11) - * Update dependencies. + +Release history can be found [on GitHub](https://github.com/rustls/hyper-rustls/releases). # License hyper-rustls is distributed under the following three licenses: From 1c8811a72d089aae0ed05e5416ae4ece21f97828 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 4 Jul 2023 12:37:38 +0200 Subject: [PATCH 026/133] Bump version to 0.24.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index add8236..699911d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.1" edition = "2021" rust-version = "1.60" license = "Apache-2.0 OR ISC OR MIT" From 73f42992e63af3d8017f89b506ca0a6ad2170072 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 15:40:33 -0400 Subject: [PATCH 027/133] Update webpki-roots requirement from 0.23 to 0.24 (#212) Updates the requirements on [webpki-roots](https://github.com/rustls/webpki-roots) to permit the latest version. - [Commits](https://github.com/rustls/webpki-roots/compare/v/0.23.1...v/0.24.0) --- updated-dependencies: - dependency-name: webpki-roots dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 699911d..8728ea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ rustls-native-certs = { version = "0.6", optional = true } rustls = { version = "0.21.0", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.24.0", default-features = false } -webpki-roots = { version = "0.23", optional = true } +webpki-roots = { version = "0.24", optional = true } futures-util = { version = "0.3" } [dev-dependencies] From 9b80236be66eb4243f2ca007caee02f5b9c43cd7 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 24 Jul 2023 16:07:55 +0200 Subject: [PATCH 028/133] Disable unnecessary default features from futures-util --- Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8728ea8..69aed7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,9 @@ rustls = { version = "0.21.0", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.24.0", default-features = false } webpki-roots = { version = "0.24", optional = true } -futures-util = { version = "0.3" } +futures-util = { version = "0.3", default-features = false } [dev-dependencies] -futures-util = { version = "0.3.1", default-features = false } hyper = { version = "0.14", features = ["full"] } rustls = { version = "0.21.0", default-features = false, features = ["tls12"] } rustls-pemfile = "1.0.0" From 1c17cd61e7d651466c26fccba5422679c9e64c58 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Wed, 26 Jul 2023 17:54:30 -0400 Subject: [PATCH 029/133] deps: update webpki-roots v0.24 -> 0.25 (#215) This commit updates the optional `webpki-roots` dependency from v0.24 to v0.25. One breaking change is addressed in `src/config.rs`. --- Cargo.toml | 2 +- src/config.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 69aed7c..6daff84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ rustls-native-certs = { version = "0.6", optional = true } rustls = { version = "0.21.0", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.24.0", default-features = false } -webpki-roots = { version = "0.24", optional = true } +webpki-roots = { version = "0.25", optional = true } futures-util = { version = "0.3", default-features = false } [dev-dependencies] diff --git a/src/config.rs b/src/config.rs index c7947c0..c4b4624 100644 --- a/src/config.rs +++ b/src/config.rs @@ -56,7 +56,6 @@ impl ConfigBuilderExt for ConfigBuilder { let mut roots = rustls::RootCertStore::empty(); roots.add_server_trust_anchors( webpki_roots::TLS_SERVER_ROOTS - .0 .iter() .map(|ta| { rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( From bacf79c0b1147933e58b2ed171a4543d7b9438b0 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:44:33 +0200 Subject: [PATCH 030/133] acceptor: move TlsAcceptor above TlsStream --- src/acceptor.rs | 91 +++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index e843be2..ce5975b 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -16,6 +16,52 @@ mod builder; pub use builder::AcceptorBuilder; use builder::WantsTlsConfig; +/// A TLS acceptor that can be used with hyper servers. +pub struct TlsAcceptor { + config: Arc, + incoming: AddrIncoming, +} + +/// An Acceptor for the `https` scheme. +impl TlsAcceptor { + /// Provides a builder for a `TlsAcceptor`. + pub fn builder() -> AcceptorBuilder { + AcceptorBuilder::new() + } + + /// Creates a new `TlsAcceptor` from a `ServerConfig` and an `AddrIncoming`. + pub fn new(config: Arc, incoming: AddrIncoming) -> TlsAcceptor { + TlsAcceptor { config, incoming } + } +} + +impl Accept for TlsAcceptor { + type Conn = TlsStream; + type Error = io::Error; + + fn poll_accept( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { + let pin = self.get_mut(); + match ready!(Pin::new(&mut pin.incoming).poll_accept(cx)) { + Some(Ok(sock)) => Poll::Ready(Some(Ok(TlsStream::new(sock, pin.config.clone())))), + Some(Err(e)) => Poll::Ready(Some(Err(e))), + None => Poll::Ready(None), + } + } +} + +impl From<(C, I)> for TlsAcceptor +where + C: Into>, + I: Into, +{ + fn from((config, incoming): (C, I)) -> TlsAcceptor { + TlsAcceptor::new(config.into(), incoming.into()) + } +} + enum State { Handshaking(tokio_rustls::Accept), Streaming(tokio_rustls::server::TlsStream), @@ -92,48 +138,3 @@ impl AsyncWrite for TlsStream { } } } - -/// A TLS acceptor that can be used with hyper servers. -pub struct TlsAcceptor { - config: Arc, - incoming: AddrIncoming, -} - -/// An Acceptor for the `https` scheme. -impl TlsAcceptor { - /// Provides a builder for a `TlsAcceptor`. - pub fn builder() -> AcceptorBuilder { - AcceptorBuilder::new() - } - /// Creates a new `TlsAcceptor` from a `ServerConfig` and an `AddrIncoming`. - pub fn new(config: Arc, incoming: AddrIncoming) -> TlsAcceptor { - TlsAcceptor { config, incoming } - } -} - -impl From<(C, I)> for TlsAcceptor -where - C: Into>, - I: Into, -{ - fn from((config, incoming): (C, I)) -> TlsAcceptor { - TlsAcceptor::new(config.into(), incoming.into()) - } -} - -impl Accept for TlsAcceptor { - type Conn = TlsStream; - type Error = io::Error; - - fn poll_accept( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll>> { - let pin = self.get_mut(); - match ready!(Pin::new(&mut pin.incoming).poll_accept(cx)) { - Some(Ok(sock)) => Poll::Ready(Some(Ok(TlsStream::new(sock, pin.config.clone())))), - Some(Err(e)) => Poll::Ready(Some(Err(e))), - None => Poll::Ready(None), - } - } -} From 94d1f9d639775adf53aafa23694b6f6e0cee7129 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:44:53 +0200 Subject: [PATCH 031/133] acceptor: move State below TlsStream --- src/acceptor.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index ce5975b..955483b 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -62,11 +62,6 @@ where } } -enum State { - Handshaking(tokio_rustls::Accept), - Streaming(tokio_rustls::server::TlsStream), -} - // tokio_rustls::server::TlsStream doesn't expose constructor methods, // so we have to TlsAcceptor::accept and handshake to have access to it // TlsStream implements AsyncRead/AsyncWrite by handshaking with tokio_rustls::Accept first @@ -138,3 +133,8 @@ impl AsyncWrite for TlsStream { } } } + +enum State { + Handshaking(tokio_rustls::Accept), + Streaming(tokio_rustls::server::TlsStream), +} From fe42b8f34d2fb32485eb2af1b5e24c3b231033a0 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:46:32 +0200 Subject: [PATCH 032/133] acceptor: host Poll::Ready() out of match arms --- src/acceptor.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index 955483b..40a7f68 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -44,11 +44,11 @@ impl Accept for TlsAcceptor { cx: &mut Context<'_>, ) -> Poll>> { let pin = self.get_mut(); - match ready!(Pin::new(&mut pin.incoming).poll_accept(cx)) { - Some(Ok(sock)) => Poll::Ready(Some(Ok(TlsStream::new(sock, pin.config.clone())))), - Some(Err(e)) => Poll::Ready(Some(Err(e))), - None => Poll::Ready(None), - } + Poll::Ready(match ready!(Pin::new(&mut pin.incoming).poll_accept(cx)) { + Some(Ok(sock)) => Some(Ok(TlsStream::new(sock, pin.config.clone()))), + Some(Err(e)) => Some(Err(e)), + None => None, + }) } } From 95dd3018956fb440653958dced2e79138f8923b3 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:48:35 +0200 Subject: [PATCH 033/133] Lint against unreachable_pub --- src/connector.rs | 2 +- src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 18ad689..f5e1b73 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -10,7 +10,7 @@ use tokio_rustls::TlsConnector; use crate::stream::MaybeHttpsStream; -pub mod builder; +pub(crate) mod builder; type BoxError = Box; diff --git a/src/lib.rs b/src/lib.rs index b207568..cd34b37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,7 +76,7 @@ //! # fn main() {} //! ``` -#![warn(missing_docs)] +#![warn(missing_docs, unreachable_pub)] #![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(feature = "acceptor")] @@ -87,7 +87,7 @@ mod stream; #[cfg(feature = "logging")] mod log { - pub use log::{debug, trace}; + pub(crate) use log::{debug, trace}; } #[cfg(not(feature = "logging"))] From c2150e1d0d31739e012db037f761d853bfaa1b29 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:50:39 +0200 Subject: [PATCH 034/133] Warn against clippy::use_self --- src/acceptor.rs | 12 ++++++------ src/connector.rs | 2 +- src/lib.rs | 2 +- src/stream.rs | 28 ++++++++++++++-------------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index 40a7f68..73e0ffa 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -30,8 +30,8 @@ impl TlsAcceptor { } /// Creates a new `TlsAcceptor` from a `ServerConfig` and an `AddrIncoming`. - pub fn new(config: Arc, incoming: AddrIncoming) -> TlsAcceptor { - TlsAcceptor { config, incoming } + pub fn new(config: Arc, incoming: AddrIncoming) -> Self { + Self { config, incoming } } } @@ -57,8 +57,8 @@ where C: Into>, I: Into, { - fn from((config, incoming): (C, I)) -> TlsAcceptor { - TlsAcceptor::new(config.into(), incoming.into()) + fn from((config, incoming): (C, I)) -> Self { + Self::new(config.into(), incoming.into()) } } @@ -70,9 +70,9 @@ pub struct TlsStream { } impl TlsStream { - fn new(stream: AddrStream, config: Arc) -> TlsStream { + fn new(stream: AddrStream, config: Arc) -> Self { let accept = tokio_rustls::TlsAcceptor::from(config).accept(stream); - TlsStream { + Self { state: State::Handshaking(accept), } } diff --git a/src/connector.rs b/src/connector.rs index f5e1b73..1e3cc4e 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -45,7 +45,7 @@ where C: Into>, { fn from((http, cfg): (H, C)) -> Self { - HttpsConnector { + Self { force_https: false, http, tls_config: cfg.into(), diff --git a/src/lib.rs b/src/lib.rs index cd34b37..bc26b76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,7 +76,7 @@ //! # fn main() {} //! ``` -#![warn(missing_docs, unreachable_pub)] +#![warn(missing_docs, unreachable_pub, clippy::use_self)] #![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(feature = "acceptor")] diff --git a/src/stream.rs b/src/stream.rs index 64ddc48..a0e8c68 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -21,8 +21,8 @@ pub enum MaybeHttpsStream { impl Connection for MaybeHttpsStream { fn connected(&self) -> Connected { match self { - MaybeHttpsStream::Http(s) => s.connected(), - MaybeHttpsStream::Https(s) => { + Self::Http(s) => s.connected(), + Self::Https(s) => { let (tcp, tls) = s.get_ref(); if tls.alpn_protocol() == Some(b"h2") { tcp.connected().negotiated_h2() @@ -37,21 +37,21 @@ impl Connection for MaybeHttpsSt impl fmt::Debug for MaybeHttpsStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - MaybeHttpsStream::Http(..) => f.pad("Http(..)"), - MaybeHttpsStream::Https(..) => f.pad("Https(..)"), + Self::Http(..) => f.pad("Http(..)"), + Self::Https(..) => f.pad("Https(..)"), } } } impl From for MaybeHttpsStream { fn from(inner: T) -> Self { - MaybeHttpsStream::Http(inner) + Self::Http(inner) } } impl From> for MaybeHttpsStream { fn from(inner: TlsStream) -> Self { - MaybeHttpsStream::Https(inner) + Self::Https(inner) } } @@ -63,8 +63,8 @@ impl AsyncRead for MaybeHttpsStream { buf: &mut ReadBuf<'_>, ) -> Poll> { match Pin::get_mut(self) { - MaybeHttpsStream::Http(s) => Pin::new(s).poll_read(cx, buf), - MaybeHttpsStream::Https(s) => Pin::new(s).poll_read(cx, buf), + Self::Http(s) => Pin::new(s).poll_read(cx, buf), + Self::Https(s) => Pin::new(s).poll_read(cx, buf), } } } @@ -77,24 +77,24 @@ impl AsyncWrite for MaybeHttpsStream { buf: &[u8], ) -> Poll> { match Pin::get_mut(self) { - MaybeHttpsStream::Http(s) => Pin::new(s).poll_write(cx, buf), - MaybeHttpsStream::Https(s) => Pin::new(s).poll_write(cx, buf), + Self::Http(s) => Pin::new(s).poll_write(cx, buf), + Self::Https(s) => Pin::new(s).poll_write(cx, buf), } } #[inline] fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match Pin::get_mut(self) { - MaybeHttpsStream::Http(s) => Pin::new(s).poll_flush(cx), - MaybeHttpsStream::Https(s) => Pin::new(s).poll_flush(cx), + Self::Http(s) => Pin::new(s).poll_flush(cx), + Self::Https(s) => Pin::new(s).poll_flush(cx), } } #[inline] fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match Pin::get_mut(self) { - MaybeHttpsStream::Http(s) => Pin::new(s).poll_shutdown(cx), - MaybeHttpsStream::Https(s) => Pin::new(s).poll_shutdown(cx), + Self::Http(s) => Pin::new(s).poll_shutdown(cx), + Self::Https(s) => Pin::new(s).poll_shutdown(cx), } } } From 0efd706b3328ec482e26c8feb9309ae43a9cc1b8 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:51:11 +0200 Subject: [PATCH 035/133] Address clippy issues in tests --- tests/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index 72dd114..e9cb839 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -24,7 +24,7 @@ fn client_command() -> Command { fn wait_for_server(addr: &str) { for i in 0..10 { - if let Ok(_) = TcpStream::connect(addr) { + if TcpStream::connect(addr).is_ok() { return; } thread::sleep(time::Duration::from_millis(i * 100)); @@ -72,7 +72,7 @@ fn server() { println!("curl stderr:\n{}", String::from_utf8_lossy(&output.stderr)); } - assert_eq!(String::from_utf8_lossy(&*output.stdout), "Try POST /echo\n"); + assert_eq!(String::from_utf8_lossy(&output.stdout), "Try POST /echo\n"); } #[test] From 84b7a7d8c513ded996ac44881a76e4b6c65df7a7 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:52:44 +0200 Subject: [PATCH 036/133] acceptor: make the acceptor module public --- src/acceptor.rs | 1 + src/lib.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index 73e0ffa..e4f7ac2 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -62,6 +62,7 @@ where } } +/// A TLS stream constructed by a [`TlsAcceptor`]. // tokio_rustls::server::TlsStream doesn't expose constructor methods, // so we have to TlsAcceptor::accept and handshake to have access to it // TlsStream implements AsyncRead/AsyncWrite by handshaking with tokio_rustls::Accept first diff --git a/src/lib.rs b/src/lib.rs index bc26b76..308f71e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,7 +80,8 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(feature = "acceptor")] -mod acceptor; +/// TLS acceptor implementing hyper's `Accept` trait. +pub mod acceptor; mod config; mod connector; mod stream; From 8ceb157c13b96ca83dc553630c66a69102247d87 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:56:57 +0200 Subject: [PATCH 037/133] acceptor: linearize AsyncRead and AsyncWrite implementations --- src/acceptor.rs | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index e4f7ac2..fc6594c 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -86,17 +86,19 @@ impl AsyncRead for TlsStream { buf: &mut ReadBuf, ) -> Poll> { let pin = self.get_mut(); - match pin.state { - State::Handshaking(ref mut accept) => match ready!(Pin::new(accept).poll(cx)) { - Ok(mut stream) => { - let result = Pin::new(&mut stream).poll_read(cx, buf); - pin.state = State::Streaming(stream); - result - } - Err(err) => Poll::Ready(Err(err)), - }, - State::Streaming(ref mut stream) => Pin::new(stream).poll_read(cx, buf), - } + let accept = match &mut pin.state { + State::Handshaking(accept) => accept, + State::Streaming(stream) => return Pin::new(stream).poll_read(cx, buf), + }; + + let mut stream = match ready!(Pin::new(accept).poll(cx)) { + Ok(stream) => stream, + Err(err) => return Poll::Ready(Err(err)), + }; + + let result = Pin::new(&mut stream).poll_read(cx, buf); + pin.state = State::Streaming(stream); + result } } @@ -107,17 +109,19 @@ impl AsyncWrite for TlsStream { buf: &[u8], ) -> Poll> { let pin = self.get_mut(); - match pin.state { - State::Handshaking(ref mut accept) => match ready!(Pin::new(accept).poll(cx)) { - Ok(mut stream) => { - let result = Pin::new(&mut stream).poll_write(cx, buf); - pin.state = State::Streaming(stream); - result - } - Err(err) => Poll::Ready(Err(err)), - }, - State::Streaming(ref mut stream) => Pin::new(stream).poll_write(cx, buf), - } + let accept = match &mut pin.state { + State::Handshaking(accept) => accept, + State::Streaming(stream) => return Pin::new(stream).poll_write(cx, buf), + }; + + let mut stream = match ready!(Pin::new(accept).poll(cx)) { + Ok(stream) => stream, + Err(err) => return Poll::Ready(Err(err)), + }; + + let result = Pin::new(&mut stream).poll_write(cx, buf); + pin.state = State::Streaming(stream); + result } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { From 554de0bf09a245cc125dfc045ce3fd69d88e0621 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 09:57:43 +0200 Subject: [PATCH 038/133] acceptor: replace ref mut patterns with &mut scrutinee --- src/acceptor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index fc6594c..db420b5 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -125,16 +125,16 @@ impl AsyncWrite for TlsStream { } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match self.state { + match &mut self.state { State::Handshaking(_) => Poll::Ready(Ok(())), - State::Streaming(ref mut stream) => Pin::new(stream).poll_flush(cx), + State::Streaming(stream) => Pin::new(stream).poll_flush(cx), } } fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match self.state { + match &mut self.state { State::Handshaking(_) => Poll::Ready(Ok(())), - State::Streaming(ref mut stream) => Pin::new(stream).poll_shutdown(cx), + State::Streaming(stream) => Pin::new(stream).poll_shutdown(cx), } } } From a3f645705ae291283a977c35d80e58316531029a Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 10:57:48 +0200 Subject: [PATCH 039/133] acceptor: add accessor methods on TlsStream --- src/acceptor.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index db420b5..4cf816d 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -9,7 +9,7 @@ use hyper::server::{ accept::Accept, conn::{AddrIncoming, AddrStream}, }; -use rustls::ServerConfig; +use rustls::{ServerConfig, ServerConnection}; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; mod builder; @@ -77,6 +77,26 @@ impl TlsStream { state: State::Handshaking(accept), } } + + /// Returns a reference to the underlying IO stream. + /// + /// This should always return `Some`, except if an error has already been yielded. + pub fn io(&self) -> Option<&AddrStream> { + match &self.state { + State::Handshaking(accept) => accept.get_ref(), + State::Streaming(stream) => Some(stream.get_ref().0), + } + } + + /// Returns a reference to the underlying [`rustls::ServerConnection']. + /// + /// This will start yielding `Some` only after the handshake has completed. + pub fn connection(&self) -> Option<&ServerConnection> { + match &self.state { + State::Handshaking(_) => None, + State::Streaming(stream) => Some(stream.get_ref().1), + } + } } impl AsyncRead for TlsStream { From 5a1a0e41c5c5114e5253d79ebcda4aa6950f568f Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 11:00:20 +0200 Subject: [PATCH 040/133] Avoid deprecated rustls API --- Cargo.toml | 2 +- src/config.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6daff84..0bbf65d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ http = "0.2" hyper = { version = "0.14", default-features = false, features = ["client"] } log = { version = "0.4.4", optional = true } rustls-native-certs = { version = "0.6", optional = true } -rustls = { version = "0.21.0", default-features = false } +rustls = { version = "0.21.6", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.24.0", default-features = false } webpki-roots = { version = "0.25", optional = true } diff --git a/src/config.rs b/src/config.rs index c4b4624..256856c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -54,7 +54,7 @@ impl ConfigBuilderExt for ConfigBuilder { #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))] fn with_webpki_roots(self) -> ConfigBuilder { let mut roots = rustls::RootCertStore::empty(); - roots.add_server_trust_anchors( + roots.add_trust_anchors( webpki_roots::TLS_SERVER_ROOTS .iter() .map(|ta| { From 078a3db262ff7670e0dde00aa104486495e9de9d Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 11:17:30 +0200 Subject: [PATCH 041/133] Run CI on a weekly schedule Probably don't need daily runs given the amount of changes. Run on Friday mornings so we can catch clippy changes from Rust releases that happen on Thursday relatively soon after. Also include merge group support. --- .github/workflows/build.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 74852c0..2bca97f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,12 @@ name: rustls permissions: contents: read -on: [push, pull_request] +on: + push: + pull_request: + merge_group: + schedule: + - cron: '23 6 * * 5' jobs: build: From 3ed760a8ada2426ceb3fe04d9b946b2fe7aad021 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 14 Aug 2023 11:19:29 +0200 Subject: [PATCH 042/133] Bump MSRV to 1.63 for socket2 0.5.3 --- .github/workflows/build.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2bca97f..0e7f979 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -83,7 +83,7 @@ jobs: - name: Install rust toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "1.60" + toolchain: "1.63" - name: Check MSRV run: cargo check --lib --all-features diff --git a/Cargo.toml b/Cargo.toml index 0bbf65d..d8d9240 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "hyper-rustls" version = "0.24.1" edition = "2021" -rust-version = "1.60" +rust-version = "1.63" license = "Apache-2.0 OR ISC OR MIT" readme = "README.md" description = "Rustls+hyper integration for pure rust HTTPS" From 6e6df0484c3c48d2b0fab77f859d78869fe89a19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 19:17:36 +0000 Subject: [PATCH 043/133] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0e7f979..a8a6e12 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: rust: stable steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false @@ -76,7 +76,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false @@ -93,7 +93,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false @@ -110,7 +110,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false - name: Install rust toolchain @@ -125,7 +125,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false - name: Install rust toolchain From 163b3f539a497ae9c4fa65f55a8133234ef33eb3 Mon Sep 17 00:00:00 2001 From: ad hoc Date: Fri, 15 Sep 2023 11:44:25 +0200 Subject: [PATCH 044/133] add AcceptorBuilder::with_acceptor method --- src/acceptor.rs | 40 +++++++++++++++++++++++----------------- src/acceptor/builder.rs | 10 +++++++++- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index 4cf816d..037b64e 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -17,9 +17,9 @@ pub use builder::AcceptorBuilder; use builder::WantsTlsConfig; /// A TLS acceptor that can be used with hyper servers. -pub struct TlsAcceptor { +pub struct TlsAcceptor { config: Arc, - incoming: AddrIncoming, + acceptor: A, } /// An Acceptor for the `https` scheme. @@ -31,12 +31,19 @@ impl TlsAcceptor { /// Creates a new `TlsAcceptor` from a `ServerConfig` and an `AddrIncoming`. pub fn new(config: Arc, incoming: AddrIncoming) -> Self { - Self { config, incoming } + Self { + config, + acceptor: incoming, + } } } -impl Accept for TlsAcceptor { - type Conn = TlsStream; +impl Accept for TlsAcceptor +where + A: Accept + Unpin, + A::Conn: AsyncRead + AsyncWrite + Unpin, +{ + type Conn = TlsStream; type Error = io::Error; fn poll_accept( @@ -44,7 +51,7 @@ impl Accept for TlsAcceptor { cx: &mut Context<'_>, ) -> Poll>> { let pin = self.get_mut(); - Poll::Ready(match ready!(Pin::new(&mut pin.incoming).poll_accept(cx)) { + Poll::Ready(match ready!(Pin::new(&mut pin.acceptor).poll_accept(cx)) { Some(Ok(sock)) => Some(Ok(TlsStream::new(sock, pin.config.clone()))), Some(Err(e)) => Some(Err(e)), None => None, @@ -66,22 +73,21 @@ where // tokio_rustls::server::TlsStream doesn't expose constructor methods, // so we have to TlsAcceptor::accept and handshake to have access to it // TlsStream implements AsyncRead/AsyncWrite by handshaking with tokio_rustls::Accept first -pub struct TlsStream { - state: State, +pub struct TlsStream { + state: State, } -impl TlsStream { - fn new(stream: AddrStream, config: Arc) -> Self { +impl TlsStream { + fn new(stream: C, config: Arc) -> Self { let accept = tokio_rustls::TlsAcceptor::from(config).accept(stream); Self { state: State::Handshaking(accept), } } - /// Returns a reference to the underlying IO stream. /// /// This should always return `Some`, except if an error has already been yielded. - pub fn io(&self) -> Option<&AddrStream> { + pub fn io(&self) -> Option<&C> { match &self.state { State::Handshaking(accept) => accept.get_ref(), State::Streaming(stream) => Some(stream.get_ref().0), @@ -99,7 +105,7 @@ impl TlsStream { } } -impl AsyncRead for TlsStream { +impl AsyncRead for TlsStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context, @@ -122,7 +128,7 @@ impl AsyncRead for TlsStream { } } -impl AsyncWrite for TlsStream { +impl AsyncWrite for TlsStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, @@ -159,7 +165,7 @@ impl AsyncWrite for TlsStream { } } -enum State { - Handshaking(tokio_rustls::Accept), - Streaming(tokio_rustls::server::TlsStream), +enum State { + Handshaking(tokio_rustls::Accept), + Streaming(tokio_rustls::server::TlsStream), } diff --git a/src/acceptor/builder.rs b/src/acceptor/builder.rs index 70c0ca7..9b95a82 100644 --- a/src/acceptor/builder.rs +++ b/src/acceptor/builder.rs @@ -90,9 +90,17 @@ impl AcceptorBuilder { /// Passes a [`AddrIncoming`] to configure the TLS connection and /// creates the [`TlsAcceptor`] pub fn with_incoming(self, incoming: impl Into) -> TlsAcceptor { + self.with_acceptor(incoming.into()) + } + + /// Passes an acceptor implementing [`Accept`] to configure the TLS connection and + /// creates the [`TlsAcceptor`] + /// + /// [`Accept`]: hyper::server::accept::Accept + pub fn with_acceptor(self, acceptor: A) -> TlsAcceptor { TlsAcceptor { config: Arc::new(self.0 .0), - incoming: incoming.into(), + acceptor, } } } From fcb72be6e3b0e060bfe5bc183a67c16ea56e7132 Mon Sep 17 00:00:00 2001 From: Tim Lundqvist Date: Thu, 5 Oct 2023 15:29:40 +0200 Subject: [PATCH 045/133] Connector: `enable_all_versions` with matching alpn vs features (#224) Fixes #208 --- src/connector/builder.rs | 51 ++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/connector/builder.rs b/src/connector/builder.rs index fdec7a8..a505e44 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -174,16 +174,22 @@ impl ConnectorBuilder { }) } - /// Enable all HTTP versions + /// Enable all HTTP versions built into this library (enabled with Cargo features) /// - /// For now, this enables both HTTP 1 and 2. In the future, other supported versions - /// will be enabled as well. - #[cfg(all(feature = "http1", feature = "http2"))] + /// For now, this could enable both HTTP 1 and 2, depending on active features. + /// In the future, other supported versions will be enabled as well. + #[cfg(feature = "http2")] + #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] pub fn enable_all_versions(mut self) -> ConnectorBuilder { - self.0.tls_config.alpn_protocols = vec![b"h2".to_vec()]; + #[cfg(feature = "http1")] + let alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + #[cfg(not(feature = "http1"))] + let alpn_protocols = vec![b"h2".to_vec()]; + + self.0.tls_config.alpn_protocols = alpn_protocols; ConnectorBuilder(WantsProtocols3 { inner: self.0, - enable_http1: true, + enable_http1: cfg!(feature = "http1"), }) } @@ -326,7 +332,7 @@ mod tests { .build(); assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); let connector = super::ConnectorBuilder::new() - .with_tls_config(tls_config) + .with_tls_config(tls_config.clone()) .https_only() .enable_http1() .enable_http2() @@ -335,5 +341,36 @@ mod tests { &connector.tls_config.alpn_protocols, &[b"h2".to_vec(), b"http/1.1".to_vec()] ); + let connector = super::ConnectorBuilder::new() + .with_tls_config(tls_config) + .https_only() + .enable_all_versions() + .build(); + assert_eq!( + &connector.tls_config.alpn_protocols, + &[b"h2".to_vec(), b"http/1.1".to_vec()] + ); + } + + #[test] + #[cfg(all(not(feature = "http1"), feature = "http2"))] + fn test_alpn_http2() { + let roots = rustls::RootCertStore::empty(); + let tls_config = rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(roots) + .with_no_client_auth(); + let connector = super::ConnectorBuilder::new() + .with_tls_config(tls_config.clone()) + .https_only() + .enable_http2() + .build(); + assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); + let connector = super::ConnectorBuilder::new() + .with_tls_config(tls_config) + .https_only() + .enable_all_versions() + .build(); + assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); } } From 5ab99d99f8749e640f5252adec6cc6e453cc80ac Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Thu, 26 Oct 2023 16:24:59 +0200 Subject: [PATCH 046/133] Bump version to 0.24.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d8d9240..9214af3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" edition = "2021" rust-version = "1.63" license = "Apache-2.0 OR ISC OR MIT" From 920fc2f5f62ee4e244ab1925f2427b7f12ee133a Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Thu, 26 Oct 2023 10:52:23 -0400 Subject: [PATCH 047/133] ci: check semver compat (#226) Use `cargo-semver-checks-action` in CI to try and catch semver breaking changes being made without the correct `Cargo.toml` version update. Note: not perfect - this check passing is necessary but not sufficient for maintaining semver. --- .github/workflows/build.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a8a6e12..7c67250 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -88,6 +88,18 @@ jobs: - name: Check MSRV run: cargo check --lib --all-features + semver: + name: Check semver compatibility + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Check semver + uses: obi1kenobi/cargo-semver-checks-action@v2 + docs: name: Check for documentation errors runs-on: ubuntu-20.04 From a2b282b815788d55ea611ca7f51e028863e7483e Mon Sep 17 00:00:00 2001 From: Alex Touchet Date: Thu, 26 Oct 2023 08:10:04 -0700 Subject: [PATCH 048/133] Fix build status badge and update Readme --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2cae804..274b47f 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,26 @@ # hyper-rustls -This is an integration between the [rustls TLS stack](https://github.com/rustls/rustls) -and the [hyper HTTP library](https://github.com/hyperium/hyper). -[![Build Status](https://github.com/rustls/hyper-rustls/workflows/hyper-rustls/badge.svg)](https://github.com/rustls/hyper-rustls/actions) +This is an integration between the [Rustls TLS stack](https://github.com/rustls/rustls) and the +[hyper HTTP library](https://github.com/hyperium/hyper). + +[![Build Status](https://github.com/rustls/hyper-rustls/actions/workflows/build.yml/badge.svg)](https://github.com/rustls/hyper-rustls/actions) [![Crate](https://img.shields.io/crates/v/hyper-rustls.svg)](https://crates.io/crates/hyper-rustls) -[![Documentation](https://docs.rs/hyper-rustls/badge.svg)](https://docs.rs/hyper-rustls/) +[![Documentation](https://docs.rs/hyper-rustls/badge.svg)](https://docs.rs/hyper-rustls) # Release history Release history can be found [on GitHub](https://github.com/rustls/hyper-rustls/releases). # License + hyper-rustls is distributed under the following three licenses: - Apache License version 2.0. - MIT license. - ISC license. -These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC -respectively. You may use this software under the terms of any -of these licenses, at your option. +These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC respectively. You may use this +software under the terms of any of these licenses, at your option. ## Running examples From 77154daea8663b9fd5263e70119ad145a050895e Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 15 Nov 2023 14:47:35 -0500 Subject: [PATCH 049/133] Remove undocumented panic in with_native_roots --- examples/client.rs | 2 +- src/config.rs | 21 +++++++++++++++++---- src/connector/builder.rs | 8 ++++---- src/lib.rs | 2 ++ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/examples/client.rs b/examples/client.rs index 4659b6d..9f9da94 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -60,7 +60,7 @@ async fn run_client() -> io::Result<()> { // Default TLS client config with native roots None => rustls::ClientConfig::builder() .with_safe_defaults() - .with_native_roots() + .with_native_roots()? .with_no_client_auth(), }; // Prepare the HTTPS connector diff --git a/src/config.rs b/src/config.rs index 256856c..1c74c45 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,9 +8,14 @@ use rustls::{ClientConfig, ConfigBuilder, WantsVerifier}; pub trait ConfigBuilderExt { /// This configures the platform's trusted certs, as implemented by /// rustls-native-certs + /// + /// This will return an error if no valid certs were found. In that case, + /// it's recommended to use `with_webpki_roots`. #[cfg(feature = "rustls-native-certs")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] - fn with_native_roots(self) -> ConfigBuilder; + fn with_native_roots( + self, + ) -> std::io::Result>; /// This configures the webpki roots, which are Mozilla's set of /// trusted roots as packaged by webpki-roots. @@ -23,7 +28,9 @@ impl ConfigBuilderExt for ConfigBuilder { #[cfg(feature = "rustls-native-certs")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] #[cfg_attr(not(feature = "logging"), allow(unused_variables))] - fn with_native_roots(self) -> ConfigBuilder { + fn with_native_roots( + self, + ) -> std::io::Result> { let mut roots = rustls::RootCertStore::empty(); let mut valid_count = 0; let mut invalid_count = 0; @@ -45,9 +52,15 @@ impl ConfigBuilderExt for ConfigBuilder { valid_count, invalid_count ); - assert!(!roots.is_empty(), "no CA certificates found"); + if roots.is_empty() { + crate::log::debug!("no valid native root CA certificates found"); + Err(std::io::Error::new( + std::io::ErrorKind::NotFound, + format!("no valid native root CA certificates found ({invalid_count} invalid)"), + ))? + } - self.with_root_certificates(roots) + Ok(self.with_root_certificates(roots)) } #[cfg(feature = "webpki-roots")] diff --git a/src/connector/builder.rs b/src/connector/builder.rs index a505e44..e0f06d0 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -59,13 +59,13 @@ impl ConnectorBuilder { /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(feature = "rustls-native-certs")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] - pub fn with_native_roots(self) -> ConnectorBuilder { - self.with_tls_config( + pub fn with_native_roots(self) -> std::io::Result> { + Ok(self.with_tls_config( ClientConfig::builder() .with_safe_defaults() - .with_native_roots() + .with_native_roots()? .with_no_client_auth(), - ) + )) } /// Shorthand for using rustls' [safe defaults][with_safe_defaults] diff --git a/src/lib.rs b/src/lib.rs index 308f71e..d2b8ab4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ //! let url = ("https://hyper.rs").parse().unwrap(); //! let https = hyper_rustls::HttpsConnectorBuilder::new() //! .with_native_roots() +//! .expect("no native root CA certificates found") //! .https_only() //! .enable_http1() //! .build(); @@ -59,6 +60,7 @@ //! let key = rustls::PrivateKey(keys[0].clone()); //! let https = hyper_rustls::HttpsConnectorBuilder::new() //! .with_native_roots() +//! .expect("no native root CA certificates found") //! .https_only() //! .enable_http1() //! .build(); From 5d9d4b58a6dd71091a5073cf3db3201f303d8f07 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 24 Nov 2023 10:10:30 +0100 Subject: [PATCH 050/133] Update to rustls alpha releases --- Cargo.toml | 16 ++++++----- examples/client.rs | 5 ++-- examples/server.rs | 20 ++++---------- src/acceptor/builder.rs | 5 ++-- src/config.rs | 29 +++++++------------- src/connector.rs | 5 ++-- src/connector/builder.rs | 58 +++++++++++++++++++++++++++++++++++----- src/lib.rs | 22 ++++++++------- 8 files changed, 94 insertions(+), 66 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9214af3..a5a8ce5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,26 +14,28 @@ documentation = "https://docs.rs/hyper-rustls/" http = "0.2" hyper = { version = "0.14", default-features = false, features = ["client"] } log = { version = "0.4.4", optional = true } -rustls-native-certs = { version = "0.6", optional = true } -rustls = { version = "0.21.6", default-features = false } +pki-types = { package = "rustls-pki-types", version = "0.2" } +rustls-native-certs = { version = "=0.7.0-alpha.2", optional = true } +rustls = { version = "=0.22.0-alpha.5", default-features = false } tokio = "1.0" -tokio-rustls = { version = "0.24.0", default-features = false } -webpki-roots = { version = "0.25", optional = true } +tokio-rustls = { version = "=0.25.0-alpha.3", default-features = false } +webpki-roots = { version = "=0.26.0-alpha.2", optional = true } futures-util = { version = "0.3", default-features = false } [dev-dependencies] hyper = { version = "0.14", features = ["full"] } -rustls = { version = "0.21.0", default-features = false, features = ["tls12"] } -rustls-pemfile = "1.0.0" +rustls = { version = "=0.22.0-alpha.5", default-features = false, features = ["tls12"] } +rustls-pemfile = "=2.0.0-alpha.2" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } [features] -default = ["native-tokio", "http1", "tls12", "logging", "acceptor"] +default = ["native-tokio", "http1", "tls12", "logging", "acceptor", "ring"] acceptor = ["hyper/server", "tokio-runtime"] http1 = ["hyper/http1"] http2 = ["hyper/http2"] webpki-tokio = ["tokio-runtime", "webpki-roots"] native-tokio = ["tokio-runtime", "rustls-native-certs"] +ring = ["rustls/ring"] tokio-runtime = ["hyper/runtime"] tls12 = ["tokio-rustls/tls12", "rustls/tls12"] logging = ["log", "tokio-rustls/logging", "rustls/logging"] diff --git a/examples/client.rs b/examples/client.rs index 9f9da94..773715b 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -47,10 +47,9 @@ async fn run_client() -> io::Result<()> { let tls = match ca { Some(ref mut rd) => { // Read trust roots - let certs = rustls_pemfile::certs(rd) - .map_err(|_| error("failed to load custom CA store".into()))?; + let certs = rustls_pemfile::certs(rd).collect::, _>>()?; let mut roots = RootCertStore::empty(); - roots.add_parsable_certificates(&certs); + roots.add_parsable_certificates(certs); // TLS client config using the custom CA store for lookups rustls::ClientConfig::builder() .with_safe_defaults() diff --git a/examples/server.rs b/examples/server.rs index 964303b..65519cf 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -14,6 +14,7 @@ use hyper::server::conn::AddrIncoming; use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Method, Request, Response, Server, StatusCode}; use hyper_rustls::TlsAcceptor; +use pki_types::{CertificateDer, PrivateKeyDer}; fn main() { // Serve an echo service over HTTPS, with proper error handling. @@ -80,34 +81,23 @@ async fn echo(req: Request) -> Result, hyper::Error> { } // Load public certificate from file. -fn load_certs(filename: &str) -> io::Result> { +fn load_certs(filename: &str) -> io::Result>> { // Open certificate file. let certfile = fs::File::open(filename) .map_err(|e| error(format!("failed to open {}: {}", filename, e)))?; let mut reader = io::BufReader::new(certfile); // Load and return certificate. - let certs = rustls_pemfile::certs(&mut reader) - .map_err(|_| error("failed to load certificate".into()))?; - Ok(certs - .into_iter() - .map(rustls::Certificate) - .collect()) + rustls_pemfile::certs(&mut reader).collect() } // Load private key from file. -fn load_private_key(filename: &str) -> io::Result { +fn load_private_key(filename: &str) -> io::Result> { // Open keyfile. let keyfile = fs::File::open(filename) .map_err(|e| error(format!("failed to open {}: {}", filename, e)))?; let mut reader = io::BufReader::new(keyfile); // Load and return a single private key. - let keys = rustls_pemfile::rsa_private_keys(&mut reader) - .map_err(|_| error("failed to load private key".into()))?; - if keys.len() != 1 { - return Err(error("expected a single private key".into())); - } - - Ok(rustls::PrivateKey(keys[0].clone())) + rustls_pemfile::private_key(&mut reader).map(|key| key.unwrap()) } diff --git a/src/acceptor/builder.rs b/src/acceptor/builder.rs index 9b95a82..eb9f62a 100644 --- a/src/acceptor/builder.rs +++ b/src/acceptor/builder.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use hyper::server::conn::AddrIncoming; +use pki_types::{CertificateDer, PrivateKeyDer}; use rustls::ServerConfig; use super::TlsAcceptor; @@ -27,8 +28,8 @@ impl AcceptorBuilder { /// [with_no_client_auth]: rustls::ConfigBuilder::with_no_client_auth pub fn with_single_cert( self, - cert_chain: Vec, - key_der: rustls::PrivateKey, + cert_chain: Vec>, + key_der: PrivateKeyDer<'static>, ) -> Result, rustls::Error> { Ok(AcceptorBuilder(WantsAlpn( ServerConfig::builder() diff --git a/src/config.rs b/src/config.rs index 1c74c45..25f0a93 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,5 @@ -use rustls::client::WantsTransparencyPolicyOrClientCert; +#[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] +use rustls::client::WantsClientCert; use rustls::{ClientConfig, ConfigBuilder, WantsVerifier}; /// Methods for configuring roots @@ -13,35 +14,29 @@ pub trait ConfigBuilderExt { /// it's recommended to use `with_webpki_roots`. #[cfg(feature = "rustls-native-certs")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] - fn with_native_roots( - self, - ) -> std::io::Result>; + fn with_native_roots(self) -> std::io::Result>; /// This configures the webpki roots, which are Mozilla's set of /// trusted roots as packaged by webpki-roots. #[cfg(feature = "webpki-roots")] #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))] - fn with_webpki_roots(self) -> ConfigBuilder; + fn with_webpki_roots(self) -> ConfigBuilder; } impl ConfigBuilderExt for ConfigBuilder { #[cfg(feature = "rustls-native-certs")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] #[cfg_attr(not(feature = "logging"), allow(unused_variables))] - fn with_native_roots( - self, - ) -> std::io::Result> { + fn with_native_roots(self) -> std::io::Result> { let mut roots = rustls::RootCertStore::empty(); let mut valid_count = 0; let mut invalid_count = 0; for cert in rustls_native_certs::load_native_certs().expect("could not load platform certs") { - let cert = rustls::Certificate(cert.0); - match roots.add(&cert) { + match roots.add(cert) { Ok(_) => valid_count += 1, Err(err) => { - crate::log::trace!("invalid cert der {:?}", cert.0); crate::log::debug!("certificate parsing failed: {:?}", err); invalid_count += 1 } @@ -65,18 +60,12 @@ impl ConfigBuilderExt for ConfigBuilder { #[cfg(feature = "webpki-roots")] #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))] - fn with_webpki_roots(self) -> ConfigBuilder { + fn with_webpki_roots(self) -> ConfigBuilder { let mut roots = rustls::RootCertStore::empty(); - roots.add_trust_anchors( + roots.extend( webpki_roots::TLS_SERVER_ROOTS .iter() - .map(|ta| { - rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) - }), + .cloned(), ); self.with_root_certificates(roots) } diff --git a/src/connector.rs b/src/connector.rs index 1e3cc4e..712c32b 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -5,6 +5,7 @@ use std::task::{Context, Poll}; use std::{fmt, io}; use hyper::{client::connect::Connection, service::Service, Uri}; +use pki_types::ServerName; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_rustls::TlsConnector; @@ -106,8 +107,8 @@ where hostname = trimmed; } - let hostname = match rustls::ServerName::try_from(hostname) { - Ok(dnsname) => dnsname, + let hostname = match ServerName::try_from(hostname) { + Ok(dnsname) => dnsname.to_owned(), Err(_) => { let err = io::Error::new(io::ErrorKind::Other, "invalid dnsname"); return Box::pin(async move { Err(Box::new(err).into()) }); diff --git a/src/connector/builder.rs b/src/connector/builder.rs index e0f06d0..76b0998 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -1,12 +1,13 @@ +#[cfg(feature = "tokio-runtime")] +use hyper::client::HttpConnector; +#[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] +use rustls::crypto::CryptoProvider; use rustls::ClientConfig; use super::HttpsConnector; #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] use crate::config::ConfigBuilderExt; -#[cfg(feature = "tokio-runtime")] -use hyper::client::HttpConnector; - /// A builder for an [`HttpsConnector`] /// /// This makes configuration flexible and explicit and ensures connector @@ -57,8 +58,11 @@ impl ConnectorBuilder { /// See [`ConfigBuilderExt::with_native_roots`] /// /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults - #[cfg(feature = "rustls-native-certs")] - #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] + #[cfg(all(feature = "ring", feature = "rustls-native-certs"))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "ring", feature = "rustls-native-certs"))) + )] pub fn with_native_roots(self) -> std::io::Result> { Ok(self.with_tls_config( ClientConfig::builder() @@ -68,14 +72,34 @@ impl ConnectorBuilder { )) } + /// Shorthand for using rustls' [safe defaults][with_safe_defaults] + /// with a custom [`CryptoProvider`] and native roots + /// + /// See [`ConfigBuilderExt::with_native_roots`] + /// + /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults + #[cfg(feature = "rustls-native-certs")] + #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] + pub fn with_provider_and_native_roots( + self, + provider: &'static dyn CryptoProvider, + ) -> std::io::Result> { + Ok(self.with_tls_config( + ClientConfig::builder_with_provider(provider) + .with_safe_defaults() + .with_native_roots()? + .with_no_client_auth(), + )) + } + /// Shorthand for using rustls' [safe defaults][with_safe_defaults] /// and Mozilla roots /// /// See [`ConfigBuilderExt::with_webpki_roots`] /// /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults - #[cfg(feature = "webpki-roots")] - #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))] + #[cfg(all(feature = "ring", feature = "webpki-roots"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "ring", feature = "webpki-roots"))))] pub fn with_webpki_roots(self) -> ConnectorBuilder { self.with_tls_config( ClientConfig::builder() @@ -84,6 +108,26 @@ impl ConnectorBuilder { .with_no_client_auth(), ) } + + /// Shorthand for using rustls' [safe defaults][with_safe_defaults] + /// with a custom [`CryptoProvider`] and Mozilla roots + /// + /// See [`ConfigBuilderExt::with_webpki_roots`] + /// + /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults + #[cfg(feature = "webpki-roots")] + #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))] + pub fn with_provider_and_webpki_roots( + self, + provider: &'static dyn CryptoProvider, + ) -> ConnectorBuilder { + self.with_tls_config( + ClientConfig::builder_with_provider(provider) + .with_safe_defaults() + .with_webpki_roots() + .with_no_client_auth(), + ) + } } impl Default for ConnectorBuilder { diff --git a/src/lib.rs b/src/lib.rs index d2b8ab4..aa26d0a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,12 +33,14 @@ //! ```no_run //! # #[cfg(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1", feature = "acceptor"))] //! # fn main() { +//! use std::io; +//! use std::fs::File; +//! //! use hyper::server::conn::AddrIncoming; //! use hyper::service::{make_service_fn, service_fn}; //! use hyper::{Body, Method, Request, Response, Server, StatusCode}; //! use hyper_rustls::TlsAcceptor; -//! use std::io; -//! use std::fs::File; +//! use pki_types::{CertificateDer, PrivateKeyDer}; //! //! let mut rt = tokio::runtime::Runtime::new().unwrap(); //! let addr = "127.0.0.1:1337".parse().unwrap(); @@ -48,16 +50,14 @@ //! let mut reader = io::BufReader::new(certfile); //! //! // Load and return certificate. -//! let certs = rustls_pemfile::certs(&mut reader).unwrap(); -//! let certs = certs.into_iter().map(rustls::Certificate).collect(); +//! let certs = rustls_pemfile::certs(&mut reader).collect::, _>>().unwrap(); //! //! // Load private key. (see `examples/server.rs`) //! let keyfile = File::open("examples/sample.rsa").unwrap(); //! let mut reader = io::BufReader::new(keyfile); //! //! // Load and return a single private key. -//! let keys = rustls_pemfile::rsa_private_keys(&mut reader).unwrap(); -//! let key = rustls::PrivateKey(keys[0].clone()); +//! let key = rustls_pemfile::private_key(&mut reader).unwrap().unwrap(); //! let https = hyper_rustls::HttpsConnectorBuilder::new() //! .with_native_roots() //! .expect("no native root CA certificates found") @@ -67,7 +67,7 @@ //! //! let incoming = AddrIncoming::bind(&addr).unwrap(); //! let acceptor = TlsAcceptor::builder() -//! .with_single_cert(certs, key).unwrap() +//! .with_single_cert(certs, key.into()).unwrap() //! .with_all_versions_alpn() //! .with_incoming(incoming); //! let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(|_req|async {Ok::<_, io::Error>(Response::new(Body::empty()))})) }); @@ -90,14 +90,16 @@ mod stream; #[cfg(feature = "logging")] mod log { - pub(crate) use log::{debug, trace}; + #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] + pub(crate) use log::debug; } #[cfg(not(feature = "logging"))] mod log { - macro_rules! trace ( ($($tt:tt)*) => {{}} ); + #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] macro_rules! debug ( ($($tt:tt)*) => {{}} ); - pub(crate) use {debug, trace}; + #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] + pub(crate) use debug; } #[cfg(feature = "acceptor")] From f9775bcc1c30b9a0c620ea6c623bbd8025e8494b Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 24 Nov 2023 10:45:28 +0100 Subject: [PATCH 051/133] Enable feature(doc_auto_cfg) --- src/config.rs | 4 ---- src/connector/builder.rs | 10 ---------- src/lib.rs | 2 +- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/config.rs b/src/config.rs index 25f0a93..a512433 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,19 +13,16 @@ pub trait ConfigBuilderExt { /// This will return an error if no valid certs were found. In that case, /// it's recommended to use `with_webpki_roots`. #[cfg(feature = "rustls-native-certs")] - #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] fn with_native_roots(self) -> std::io::Result>; /// This configures the webpki roots, which are Mozilla's set of /// trusted roots as packaged by webpki-roots. #[cfg(feature = "webpki-roots")] - #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))] fn with_webpki_roots(self) -> ConfigBuilder; } impl ConfigBuilderExt for ConfigBuilder { #[cfg(feature = "rustls-native-certs")] - #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] #[cfg_attr(not(feature = "logging"), allow(unused_variables))] fn with_native_roots(self) -> std::io::Result> { let mut roots = rustls::RootCertStore::empty(); @@ -59,7 +56,6 @@ impl ConfigBuilderExt for ConfigBuilder { } #[cfg(feature = "webpki-roots")] - #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))] fn with_webpki_roots(self) -> ConfigBuilder { let mut roots = rustls::RootCertStore::empty(); roots.extend( diff --git a/src/connector/builder.rs b/src/connector/builder.rs index 76b0998..e3ea1e9 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -59,10 +59,6 @@ impl ConnectorBuilder { /// /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(all(feature = "ring", feature = "rustls-native-certs"))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "ring", feature = "rustls-native-certs"))) - )] pub fn with_native_roots(self) -> std::io::Result> { Ok(self.with_tls_config( ClientConfig::builder() @@ -79,7 +75,6 @@ impl ConnectorBuilder { /// /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(feature = "rustls-native-certs")] - #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] pub fn with_provider_and_native_roots( self, provider: &'static dyn CryptoProvider, @@ -99,7 +94,6 @@ impl ConnectorBuilder { /// /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(all(feature = "ring", feature = "webpki-roots"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "ring", feature = "webpki-roots"))))] pub fn with_webpki_roots(self) -> ConnectorBuilder { self.with_tls_config( ClientConfig::builder() @@ -116,7 +110,6 @@ impl ConnectorBuilder { /// /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(feature = "webpki-roots")] - #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))] pub fn with_provider_and_webpki_roots( self, provider: &'static dyn CryptoProvider, @@ -209,7 +202,6 @@ impl ConnectorBuilder { /// /// This needs to be called explicitly, no protocol is enabled by default #[cfg(feature = "http2")] - #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] pub fn enable_http2(mut self) -> ConnectorBuilder { self.0.tls_config.alpn_protocols = vec![b"h2".to_vec()]; ConnectorBuilder(WantsProtocols3 { @@ -223,7 +215,6 @@ impl ConnectorBuilder { /// For now, this could enable both HTTP 1 and 2, depending on active features. /// In the future, other supported versions will be enabled as well. #[cfg(feature = "http2")] - #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] pub fn enable_all_versions(mut self) -> ConnectorBuilder { #[cfg(feature = "http1")] let alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; @@ -267,7 +258,6 @@ impl ConnectorBuilder { /// /// This needs to be called explicitly, no protocol is enabled by default #[cfg(feature = "http2")] - #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] pub fn enable_http2(mut self) -> ConnectorBuilder { self.0.inner.tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; ConnectorBuilder(WantsProtocols3 { diff --git a/src/lib.rs b/src/lib.rs index aa26d0a..a5d3c55 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -79,7 +79,7 @@ //! ``` #![warn(missing_docs, unreachable_pub, clippy::use_self)] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #[cfg(feature = "acceptor")] /// TLS acceptor implementing hyper's `Accept` trait. From 820bcc8dfdffa960f649d6849186cb2fbc11f770 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 24 Nov 2023 10:10:57 +0100 Subject: [PATCH 052/133] Bump version to 0.25.0-alpha.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a5a8ce5..68f4e01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.24.2" +version = "0.25.0-alpha.0" edition = "2021" rust-version = "1.63" license = "Apache-2.0 OR ISC OR MIT" From e1f693c8162b38363ccb6fa2a05aebdb53ebf9c2 Mon Sep 17 00:00:00 2001 From: tottoto Date: Fri, 1 Dec 2023 02:26:05 +0900 Subject: [PATCH 053/133] Bump alpha dependency versions --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 68f4e01..73966cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,16 +15,16 @@ http = "0.2" hyper = { version = "0.14", default-features = false, features = ["client"] } log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "0.2" } -rustls-native-certs = { version = "=0.7.0-alpha.2", optional = true } -rustls = { version = "=0.22.0-alpha.5", default-features = false } +rustls-native-certs = { version = "=0.7.0-alpha.3", optional = true } +rustls = { version = "=0.22.0-alpha.6", default-features = false } tokio = "1.0" -tokio-rustls = { version = "=0.25.0-alpha.3", default-features = false } +tokio-rustls = { version = "=0.25.0-alpha.4", default-features = false } webpki-roots = { version = "=0.26.0-alpha.2", optional = true } futures-util = { version = "0.3", default-features = false } [dev-dependencies] hyper = { version = "0.14", features = ["full"] } -rustls = { version = "=0.22.0-alpha.5", default-features = false, features = ["tls12"] } +rustls = { version = "=0.22.0-alpha.6", default-features = false, features = ["tls12"] } rustls-pemfile = "=2.0.0-alpha.2" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } From ad4e03d9ad2926490fd97b78234acc678bc68207 Mon Sep 17 00:00:00 2001 From: tottoto Date: Fri, 1 Dec 2023 02:27:08 +0900 Subject: [PATCH 054/133] Enable required ring feature on acceptor feature --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 73966cd..80126d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thre [features] default = ["native-tokio", "http1", "tls12", "logging", "acceptor", "ring"] -acceptor = ["hyper/server", "tokio-runtime"] +acceptor = ["hyper/server", "ring", "tokio-runtime"] http1 = ["hyper/http1"] http2 = ["hyper/http2"] webpki-tokio = ["tokio-runtime", "webpki-roots"] From b1177cc84a65e5a993a3d3a0c4335d78e9601e56 Mon Sep 17 00:00:00 2001 From: tottoto Date: Fri, 1 Dec 2023 02:30:26 +0900 Subject: [PATCH 055/133] Add ci to check feature powerset --- .github/workflows/build.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7c67250..7f94b76 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,3 +145,17 @@ jobs: with: components: clippy - run: cargo clippy --all-features -- --deny warnings + + features: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Install rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Install cargo-hack + uses: taiki-e/install-action@cargo-hack + - name: Check feature powerset + run: cargo hack --no-dev-deps check --feature-powerset --depth 2 From 29573affaa7c5701722d49426c94720514475726 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Sat, 2 Dec 2023 17:21:55 -0500 Subject: [PATCH 056/133] proj: git ignore .idea --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1e7caa9..e59fb83 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ Cargo.lock target/ +/.idea From 2d6e1c30d7772c35fdbc7ad506b9028734c721f4 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Sat, 2 Dec 2023 17:46:49 -0500 Subject: [PATCH 057/133] Cargo: update to rustls 0.22 This commit updates to rustls 0.22, taking the following associated updates: * rustls 0.22.0-alpha-6 -> 0.22 * pki-types 0.2 -> 1 * tokio-rustls 0.25.0-alpha.4 -> 0.25 * rustls-native-certs 0.7.0-alpha.3 -> 0.7 * webpki-roots 0.26.0-alpha.2 -> 0.26 * rustls-pemfile 2.0.0-alpha.2 -> 2 Breaking API changes are addressed as required. Notably, the builder fns that accept a custom provider and use the safe defaults are now fallible to account for a possible error if the provider's configuration is not compatible with the default safe protocol versions. --- Cargo.toml | 14 ++++++------ examples/client.rs | 2 -- src/acceptor/builder.rs | 5 ++--- src/connector/builder.rs | 46 +++++++++++++++------------------------- 4 files changed, 26 insertions(+), 41 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 80126d5..656fa20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,18 +14,18 @@ documentation = "https://docs.rs/hyper-rustls/" http = "0.2" hyper = { version = "0.14", default-features = false, features = ["client"] } log = { version = "0.4.4", optional = true } -pki-types = { package = "rustls-pki-types", version = "0.2" } -rustls-native-certs = { version = "=0.7.0-alpha.3", optional = true } -rustls = { version = "=0.22.0-alpha.6", default-features = false } +pki-types = { package = "rustls-pki-types", version = "1" } +rustls-native-certs = { version = "0.7", optional = true } +rustls = { version = "0.22", default-features = false } tokio = "1.0" -tokio-rustls = { version = "=0.25.0-alpha.4", default-features = false } -webpki-roots = { version = "=0.26.0-alpha.2", optional = true } +tokio-rustls = { version = "0.25", default-features = false } +webpki-roots = { version = "0.26", optional = true } futures-util = { version = "0.3", default-features = false } [dev-dependencies] hyper = { version = "0.14", features = ["full"] } -rustls = { version = "=0.22.0-alpha.6", default-features = false, features = ["tls12"] } -rustls-pemfile = "=2.0.0-alpha.2" +rustls = { version = "0.22", default-features = false, features = ["tls12"] } +rustls-pemfile = "2" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } [features] diff --git a/examples/client.rs b/examples/client.rs index 773715b..58c4c28 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -52,13 +52,11 @@ async fn run_client() -> io::Result<()> { roots.add_parsable_certificates(certs); // TLS client config using the custom CA store for lookups rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(roots) .with_no_client_auth() } // Default TLS client config with native roots None => rustls::ClientConfig::builder() - .with_safe_defaults() .with_native_roots()? .with_no_client_auth(), }; diff --git a/src/acceptor/builder.rs b/src/acceptor/builder.rs index eb9f62a..a4b2231 100644 --- a/src/acceptor/builder.rs +++ b/src/acceptor/builder.rs @@ -22,9 +22,9 @@ impl AcceptorBuilder { AcceptorBuilder(WantsAlpn(config)) } - /// Use rustls [defaults][with_safe_defaults] without [client authentication][with_no_client_auth] + /// Use rustls default crypto provider and safe defaults without + /// [client authentication][with_no_client_auth] /// - /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults /// [with_no_client_auth]: rustls::ConfigBuilder::with_no_client_auth pub fn with_single_cert( self, @@ -33,7 +33,6 @@ impl AcceptorBuilder { ) -> Result, rustls::Error> { Ok(AcceptorBuilder(WantsAlpn( ServerConfig::builder() - .with_safe_defaults() .with_no_client_auth() .with_single_cert(cert_chain, key_der)?, ))) diff --git a/src/connector/builder.rs b/src/connector/builder.rs index e3ea1e9..4e65f86 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -52,74 +52,64 @@ impl ConnectorBuilder { ConnectorBuilder(WantsSchemes { tls_config: config }) } - /// Shorthand for using rustls' [safe defaults][with_safe_defaults] - /// and native roots + /// Shorthand for using rustls' default crypto provider and safe defaults, with + /// native roots. /// /// See [`ConfigBuilderExt::with_native_roots`] - /// - /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(all(feature = "ring", feature = "rustls-native-certs"))] pub fn with_native_roots(self) -> std::io::Result> { Ok(self.with_tls_config( ClientConfig::builder() - .with_safe_defaults() .with_native_roots()? .with_no_client_auth(), )) } - /// Shorthand for using rustls' [safe defaults][with_safe_defaults] - /// with a custom [`CryptoProvider`] and native roots + /// Shorthand for using a custom [`CryptoProvider`] and native roots /// /// See [`ConfigBuilderExt::with_native_roots`] - /// - /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(feature = "rustls-native-certs")] pub fn with_provider_and_native_roots( self, - provider: &'static dyn CryptoProvider, + provider: CryptoProvider, ) -> std::io::Result> { Ok(self.with_tls_config( - ClientConfig::builder_with_provider(provider) - .with_safe_defaults() + ClientConfig::builder_with_provider(provider.into()) + .with_safe_default_protocol_versions() + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))? .with_native_roots()? .with_no_client_auth(), )) } - /// Shorthand for using rustls' [safe defaults][with_safe_defaults] - /// and Mozilla roots + /// Shorthand for using rustls' default crypto provider and its + /// safe defaults. /// /// See [`ConfigBuilderExt::with_webpki_roots`] - /// - /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(all(feature = "ring", feature = "webpki-roots"))] pub fn with_webpki_roots(self) -> ConnectorBuilder { self.with_tls_config( ClientConfig::builder() - .with_safe_defaults() .with_webpki_roots() .with_no_client_auth(), ) } - /// Shorthand for using rustls' [safe defaults][with_safe_defaults] - /// with a custom [`CryptoProvider`] and Mozilla roots + /// Shorthand for using a custom [`CryptoProvider`], Rustls' safe default + /// protocol versions and Mozilla roots /// /// See [`ConfigBuilderExt::with_webpki_roots`] - /// - /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults #[cfg(feature = "webpki-roots")] pub fn with_provider_and_webpki_roots( self, - provider: &'static dyn CryptoProvider, - ) -> ConnectorBuilder { - self.with_tls_config( - ClientConfig::builder_with_provider(provider) - .with_safe_defaults() + provider: CryptoProvider, + ) -> Result, rustls::Error> { + Ok(self.with_tls_config( + ClientConfig::builder_with_provider(provider.into()) + .with_safe_default_protocol_versions()? .with_webpki_roots() .with_no_client_auth(), - ) + )) } } @@ -331,7 +321,6 @@ mod tests { fn test_reject_predefined_alpn() { let roots = rustls::RootCertStore::empty(); let mut config_with_alpn = rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(roots) .with_no_client_auth(); config_with_alpn.alpn_protocols = vec![b"fancyprotocol".to_vec()]; @@ -347,7 +336,6 @@ mod tests { fn test_alpn() { let roots = rustls::RootCertStore::empty(); let tls_config = rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(roots) .with_no_client_auth(); let connector = super::ConnectorBuilder::new() From 3883ec9d0350ee2375587081c6166674c11236c3 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Sat, 2 Dec 2023 17:51:54 -0500 Subject: [PATCH 058/133] Cargo: version 0.25.0-alpha.0 -> 0.25 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 656fa20..cfc5314 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.25.0-alpha.0" +version = "0.25.0" edition = "2021" rust-version = "1.63" license = "Apache-2.0 OR ISC OR MIT" From 281a1bcaf8588ac56fff340d566d8ce0deb57a24 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 15 Nov 2023 11:57:00 -0800 Subject: [PATCH 059/133] Re-order impls for HttpsConnector --- src/connector.rs | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 712c32b..2951107 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -33,28 +33,6 @@ impl HttpsConnector { } } -impl fmt::Debug for HttpsConnector { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("HttpsConnector") - .field("force_https", &self.force_https) - .finish() - } -} - -impl From<(H, C)> for HttpsConnector -where - C: Into>, -{ - fn from((http, cfg): (H, C)) -> Self { - Self { - force_https: false, - http, - tls_config: cfg.into(), - override_server_name: None, - } - } -} - impl Service for HttpsConnector where T: Service, @@ -139,3 +117,25 @@ where } } } + +impl From<(H, C)> for HttpsConnector +where + C: Into>, +{ + fn from((http, cfg): (H, C)) -> Self { + Self { + force_https: false, + http, + tls_config: cfg.into(), + override_server_name: None, + } + } +} + +impl fmt::Debug for HttpsConnector { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("HttpsConnector") + .field("force_https", &self.force_https) + .finish() + } +} From 5650a59120858d50e42c0c1a730e4522899c1b73 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 15 Nov 2023 11:58:44 -0800 Subject: [PATCH 060/133] Clean up imports --- src/acceptor.rs | 6 ++---- src/acceptor/builder.rs | 1 + src/connector.rs | 4 +++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index 037b64e..02e72d0 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -5,10 +5,8 @@ use std::pin::Pin; use std::sync::Arc; use futures_util::ready; -use hyper::server::{ - accept::Accept, - conn::{AddrIncoming, AddrStream}, -}; +use hyper::server::accept::Accept; +use hyper::server::conn::{AddrIncoming, AddrStream}; use rustls::{ServerConfig, ServerConnection}; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; diff --git a/src/acceptor/builder.rs b/src/acceptor/builder.rs index a4b2231..ec14f17 100644 --- a/src/acceptor/builder.rs +++ b/src/acceptor/builder.rs @@ -5,6 +5,7 @@ use pki_types::{CertificateDer, PrivateKeyDer}; use rustls::ServerConfig; use super::TlsAcceptor; + /// Builder for [`TlsAcceptor`] pub struct AcceptorBuilder(State); diff --git a/src/connector.rs b/src/connector.rs index 2951107..7e0921f 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -4,7 +4,9 @@ use std::sync::Arc; use std::task::{Context, Poll}; use std::{fmt, io}; -use hyper::{client::connect::Connection, service::Service, Uri}; +use hyper::client::connect::Connection; +use hyper::service::Service; +use hyper::Uri; use pki_types::ServerName; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_rustls::TlsConnector; From 643712202663cab71dd969f9ca68a3a407c52d93 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 15 Nov 2023 12:05:16 -0800 Subject: [PATCH 061/133] Invert Connector scheme matching to reduce rightward drift --- src/connector.rs | 109 ++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 7e0921f..44f9763 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -60,61 +60,64 @@ where fn call(&mut self, dst: Uri) -> Self::Future { // dst.scheme() would need to derive Eq to be matchable; // use an if cascade instead - if let Some(sch) = dst.scheme() { - if sch == &http::uri::Scheme::HTTP && !self.force_https { - let connecting_future = self.http.call(dst); - - let f = async move { - let tcp = connecting_future - .await - .map_err(Into::into)?; - - Ok(MaybeHttpsStream::Http(tcp)) - }; - Box::pin(f) - } else if sch == &http::uri::Scheme::HTTPS { - let cfg = self.tls_config.clone(); - let mut hostname = match self.override_server_name.as_deref() { - Some(h) => h, - None => dst.host().unwrap_or_default(), - }; - - // Remove square brackets around IPv6 address. - if let Some(trimmed) = hostname - .strip_prefix('[') - .and_then(|h| h.strip_suffix(']')) - { - hostname = trimmed; - } - - let hostname = match ServerName::try_from(hostname) { - Ok(dnsname) => dnsname.to_owned(), - Err(_) => { - let err = io::Error::new(io::ErrorKind::Other, "invalid dnsname"); - return Box::pin(async move { Err(Box::new(err).into()) }); - } - }; - let connecting_future = self.http.call(dst); - - let f = async move { - let tcp = connecting_future - .await - .map_err(Into::into)?; - let connector = TlsConnector::from(cfg); - let tls = connector - .connect(hostname, tcp) - .await - .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; - Ok(MaybeHttpsStream::Https(tls)) - }; - Box::pin(f) - } else { - let err = - io::Error::new(io::ErrorKind::Other, format!("Unsupported scheme {}", sch)); - Box::pin(async move { Err(err.into()) }) + let scheme = match dst.scheme() { + Some(scheme) => scheme, + None => { + return Box::pin(async move { + Err(io::Error::new(io::ErrorKind::Other, "missing scheme").into()) + }) + } + }; + + if scheme == &http::uri::Scheme::HTTP && !self.force_https { + let connecting_future = self.http.call(dst); + + let f = async move { + let tcp = connecting_future + .await + .map_err(Into::into)?; + + Ok(MaybeHttpsStream::Http(tcp)) + }; + Box::pin(f) + } else if scheme == &http::uri::Scheme::HTTPS { + let cfg = self.tls_config.clone(); + let mut hostname = match self.override_server_name.as_deref() { + Some(h) => h, + None => dst.host().unwrap_or_default(), + }; + + // Remove square brackets around IPv6 address. + if let Some(trimmed) = hostname + .strip_prefix('[') + .and_then(|h| h.strip_suffix(']')) + { + hostname = trimmed; } + + let hostname = match ServerName::try_from(hostname) { + Ok(dns_name) => dns_name.to_owned(), + Err(_) => { + let err = io::Error::new(io::ErrorKind::Other, "invalid dnsname"); + return Box::pin(async move { Err(Box::new(err).into()) }); + } + }; + let connecting_future = self.http.call(dst); + + let f = async move { + let tcp = connecting_future + .await + .map_err(Into::into)?; + let connector = TlsConnector::from(cfg); + let tls = connector + .connect(hostname, tcp) + .await + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + Ok(MaybeHttpsStream::Https(tls)) + }; + Box::pin(f) } else { - let err = io::Error::new(io::ErrorKind::Other, "Missing scheme"); + let err = io::Error::new(io::ErrorKind::Other, format!("Unsupported scheme {scheme}")); Box::pin(async move { Err(err.into()) }) } } From b8d0c2fba93d00b1f96899329ead2e9690f68097 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 15 Nov 2023 12:09:33 -0800 Subject: [PATCH 062/133] Inline expressions in Connector HTTP scheme handling --- src/connector.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 44f9763..1b8f6e8 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -70,16 +70,8 @@ where }; if scheme == &http::uri::Scheme::HTTP && !self.force_https { - let connecting_future = self.http.call(dst); - - let f = async move { - let tcp = connecting_future - .await - .map_err(Into::into)?; - - Ok(MaybeHttpsStream::Http(tcp)) - }; - Box::pin(f) + let future = self.http.call(dst); + Box::pin(async move { Ok(MaybeHttpsStream::Http(future.await.map_err(Into::into)?)) }) } else if scheme == &http::uri::Scheme::HTTPS { let cfg = self.tls_config.clone(); let mut hostname = match self.override_server_name.as_deref() { From a6ee2fe19d7627af180cc30a08ac4e33abcfaa7b Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 15 Nov 2023 12:20:27 -0800 Subject: [PATCH 063/133] Reduce rightward drift by handling simple schemes --- src/connector.rs | 90 +++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 1b8f6e8..03f4dab 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -60,8 +60,20 @@ where fn call(&mut self, dst: Uri) -> Self::Future { // dst.scheme() would need to derive Eq to be matchable; // use an if cascade instead - let scheme = match dst.scheme() { - Some(scheme) => scheme, + match dst.scheme() { + Some(scheme) if scheme == &http::uri::Scheme::HTTP => { + let future = self.http.call(dst); + return Box::pin(async move { + Ok(MaybeHttpsStream::Http(future.await.map_err(Into::into)?)) + }); + } + Some(scheme) if scheme != &http::uri::Scheme::HTTPS => { + let message = format!("unsupported scheme {scheme}"); + return Box::pin(async move { + Err(io::Error::new(io::ErrorKind::Other, message).into()) + }); + } + Some(_) => {} None => { return Box::pin(async move { Err(io::Error::new(io::ErrorKind::Other, "missing scheme").into()) @@ -69,49 +81,41 @@ where } }; - if scheme == &http::uri::Scheme::HTTP && !self.force_https { - let future = self.http.call(dst); - Box::pin(async move { Ok(MaybeHttpsStream::Http(future.await.map_err(Into::into)?)) }) - } else if scheme == &http::uri::Scheme::HTTPS { - let cfg = self.tls_config.clone(); - let mut hostname = match self.override_server_name.as_deref() { - Some(h) => h, - None => dst.host().unwrap_or_default(), - }; - - // Remove square brackets around IPv6 address. - if let Some(trimmed) = hostname - .strip_prefix('[') - .and_then(|h| h.strip_suffix(']')) - { - hostname = trimmed; - } + let cfg = self.tls_config.clone(); + let mut hostname = match self.override_server_name.as_deref() { + Some(h) => h, + None => dst.host().unwrap_or_default(), + }; - let hostname = match ServerName::try_from(hostname) { - Ok(dns_name) => dns_name.to_owned(), - Err(_) => { - let err = io::Error::new(io::ErrorKind::Other, "invalid dnsname"); - return Box::pin(async move { Err(Box::new(err).into()) }); - } - }; - let connecting_future = self.http.call(dst); - - let f = async move { - let tcp = connecting_future - .await - .map_err(Into::into)?; - let connector = TlsConnector::from(cfg); - let tls = connector - .connect(hostname, tcp) - .await - .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; - Ok(MaybeHttpsStream::Https(tls)) - }; - Box::pin(f) - } else { - let err = io::Error::new(io::ErrorKind::Other, format!("Unsupported scheme {scheme}")); - Box::pin(async move { Err(err.into()) }) + // Remove square brackets around IPv6 address. + if let Some(trimmed) = hostname + .strip_prefix('[') + .and_then(|h| h.strip_suffix(']')) + { + hostname = trimmed; } + + let hostname = match ServerName::try_from(hostname) { + Ok(dns_name) => dns_name.to_owned(), + Err(_) => { + let err = io::Error::new(io::ErrorKind::Other, "invalid dnsname"); + return Box::pin(async move { Err(Box::new(err).into()) }); + } + }; + let connecting_future = self.http.call(dst); + + let f = async move { + let tcp = connecting_future + .await + .map_err(Into::into)?; + let connector = TlsConnector::from(cfg); + let tls = connector + .connect(hostname, tcp) + .await + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + Ok(MaybeHttpsStream::Https(tls)) + }; + Box::pin(f) } } From def00ca3d4d9dca46bfde5574f4b0f3d2b722a74 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 15 Nov 2023 13:19:50 -0800 Subject: [PATCH 064/133] Inline some single-use bindings --- src/connector.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 03f4dab..6ce366c 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -102,20 +102,19 @@ where return Box::pin(async move { Err(Box::new(err).into()) }); } }; - let connecting_future = self.http.call(dst); - let f = async move { + let connecting_future = self.http.call(dst); + Box::pin(async move { let tcp = connecting_future .await .map_err(Into::into)?; - let connector = TlsConnector::from(cfg); - let tls = connector - .connect(hostname, tcp) - .await - .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; - Ok(MaybeHttpsStream::Https(tls)) - }; - Box::pin(f) + Ok(MaybeHttpsStream::Https( + TlsConnector::from(cfg) + .connect(hostname, tcp) + .await + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?, + )) + }) } } From e19a299b6b08c17bf8307b59b071caa7f6f5a83b Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Sat, 18 Nov 2023 04:16:30 +0100 Subject: [PATCH 065/133] Update hyper to 1.x and integrate with hyper-util This updates the entire dependency stack to hyper 1.x and http 1.x. The tokio-runtime feature was removed since it no longer serves a purpose and tokio is a hard dependency. Since hyper 1.x removed the high-level server API that supported customizing the accept process of the server via an Accept trait, the acceptor in hyper-rustls is removed. The server example however was updated to showcase how rustls can be integrated with the low-level hyper 1.x API. Signed-off-by: Jens Reidel --- Cargo.toml | 23 +++--- examples/client.rs | 15 ++-- examples/server.rs | 84 ++++++++++++------- src/acceptor.rs | 169 --------------------------------------- src/acceptor/builder.rs | 107 ------------------------- src/connector.rs | 17 ++-- src/connector/builder.rs | 8 +- src/lib.rs | 67 ++-------------- src/stream.rs | 27 ++++--- tests/tests.rs | 1 - 10 files changed, 112 insertions(+), 406 deletions(-) delete mode 100644 src/acceptor.rs delete mode 100644 src/acceptor/builder.rs diff --git a/Cargo.toml b/Cargo.toml index cfc5314..e275ed9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,32 +11,33 @@ repository = "https://github.com/rustls/hyper-rustls" documentation = "https://docs.rs/hyper-rustls/" [dependencies] -http = "0.2" -hyper = { version = "0.14", default-features = false, features = ["client"] } +http = "1" +hyper = { version = "1", default-features = false } +hyper-util = { version = "0.1", default-features = false, features = ["client-legacy", "tokio"] } log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "1" } rustls-native-certs = { version = "0.7", optional = true } rustls = { version = "0.22", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.25", default-features = false } +tower-service = "0.3" webpki-roots = { version = "0.26", optional = true } futures-util = { version = "0.3", default-features = false } [dev-dependencies] -hyper = { version = "0.14", features = ["full"] } +http-body-util = "0.1" +hyper-util = { version = "0.1", default-features = false, features = ["server-auto"] } rustls = { version = "0.22", default-features = false, features = ["tls12"] } rustls-pemfile = "2" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } [features] -default = ["native-tokio", "http1", "tls12", "logging", "acceptor", "ring"] -acceptor = ["hyper/server", "ring", "tokio-runtime"] -http1 = ["hyper/http1"] -http2 = ["hyper/http2"] -webpki-tokio = ["tokio-runtime", "webpki-roots"] -native-tokio = ["tokio-runtime", "rustls-native-certs"] +default = ["native-tokio", "http1", "tls12", "logging", "ring"] +http1 = ["hyper-util/http1"] +http2 = ["hyper-util/http2"] +webpki-tokio = ["webpki-roots"] +native-tokio = ["rustls-native-certs"] ring = ["rustls/ring"] -tokio-runtime = ["hyper/runtime"] tls12 = ["tokio-rustls/tls12", "rustls/tls12"] logging = ["log", "tokio-rustls/logging", "rustls/logging"] @@ -48,7 +49,7 @@ required-features = ["native-tokio", "http1"] [[example]] name = "server" path = "examples/server.rs" -required-features = ["tokio-runtime", "acceptor"] +required-features = ["ring"] [package.metadata.docs.rs] all-features = true diff --git a/examples/client.rs b/examples/client.rs index 58c4c28..36d5c6f 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -2,8 +2,11 @@ //! //! First parameter is the mandatory URL to GET. //! Second parameter is an optional path to CA store. -use hyper::{body::to_bytes, client, Body, Uri}; +use http::Uri; +use http_body_util::{BodyExt, Empty}; +use hyper::body::Bytes; use hyper_rustls::ConfigBuilderExt; +use hyper_util::{client::legacy::Client, rt::TokioExecutor}; use rustls::RootCertStore; use std::str::FromStr; @@ -68,7 +71,7 @@ async fn run_client() -> io::Result<()> { .build(); // Build the hyper client from the HTTPS connector. - let client: client::Client<_, hyper::Body> = client::Client::builder().build(https); + let client: Client<_, Empty> = Client::builder(TokioExecutor::new()).build(https); // Prepare a chain of futures which sends a GET request, inspects // the returned headers, collects the whole body and prints it to @@ -81,10 +84,12 @@ async fn run_client() -> io::Result<()> { println!("Status:\n{}", res.status()); println!("Headers:\n{:#?}", res.headers()); - let body: Body = res.into_body(); - let body = to_bytes(body) + let body = res + .into_body() + .collect() .await - .map_err(|e| error(format!("Could not get body: {:?}", e)))?; + .map_err(|e| error(format!("Could not get body: {:?}", e)))? + .to_bytes(); println!("Body:\n{}", String::from_utf8_lossy(&body)); Ok(()) diff --git a/examples/server.rs b/examples/server.rs index 65519cf..ffdb38f 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -1,20 +1,25 @@ -//! Simple HTTPS echo service based on hyper-rustls +//! Simple HTTPS echo service based on hyper_util and rustls //! //! First parameter is the mandatory port to use. //! Certificate and private key are hardcoded to sample files. //! hyper will automatically use HTTP/2 if a client starts talking HTTP/2, //! otherwise HTTP/1.1 will be used. -#![cfg(feature = "acceptor")] - +use std::net::{Ipv4Addr, SocketAddr}; +use std::sync::Arc; use std::vec::Vec; use std::{env, fs, io}; -use hyper::server::conn::AddrIncoming; -use hyper::service::{make_service_fn, service_fn}; -use hyper::{Body, Method, Request, Response, Server, StatusCode}; -use hyper_rustls::TlsAcceptor; +use http::{Method, Request, Response, StatusCode}; +use http_body_util::{BodyExt, Full}; +use hyper::body::{Bytes, Incoming}; +use hyper::service::service_fn; +use hyper_util::rt::{TokioExecutor, TokioIo}; +use hyper_util::server::conn::auto::Builder; use pki_types::{CertificateDer, PrivateKeyDer}; +use rustls::ServerConfig; +use tokio::net::TcpListener; +use tokio_rustls::TlsAcceptor; fn main() { // Serve an echo service over HTTPS, with proper error handling. @@ -32,45 +37,70 @@ fn error(err: String) -> io::Error { async fn run_server() -> Result<(), Box> { // First parameter is port number (optional, defaults to 1337) let port = match env::args().nth(1) { - Some(ref p) => p.to_owned(), - None => "1337".to_owned(), + Some(ref p) => p.parse()?, + None => 1337, }; - let addr = format!("127.0.0.1:{}", port).parse()?; + let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port); // Load public certificate. let certs = load_certs("examples/sample.pem")?; // Load private key. let key = load_private_key("examples/sample.rsa")?; - // Build TLS configuration. + + println!("Starting to serve on https://{}", addr); // Create a TCP listener via tokio. - let incoming = AddrIncoming::bind(&addr)?; - let acceptor = TlsAcceptor::builder() + let incoming = TcpListener::bind(&addr).await?; + + // Build TLS configuration. + let mut server_config = ServerConfig::builder() + .with_no_client_auth() .with_single_cert(certs, key) - .map_err(|e| error(format!("{}", e)))? - .with_all_versions_alpn() - .with_incoming(incoming); - let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(echo)) }); - let server = Server::builder(acceptor).serve(service); - - // Run the future, keep going until an error occurs. - println!("Starting to serve on https://{}.", addr); - server.await?; - Ok(()) + .map_err(|e| error(e.to_string()))?; + server_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()]; + let tls_acceptor = TlsAcceptor::from(Arc::new(server_config)); + + let service = service_fn(echo); + + loop { + let (tcp_stream, _remote_addr) = incoming.accept().await?; + + let tls_acceptor = tls_acceptor.clone(); + tokio::spawn(async move { + let tls_stream = match tls_acceptor.accept(tcp_stream).await { + Ok(tls_stream) => tls_stream, + Err(err) => { + eprintln!("failed to perform tls handshake: {err:#}"); + return; + } + }; + if let Err(err) = Builder::new(TokioExecutor::new()) + .serve_connection(TokioIo::new(tls_stream), service) + .await + { + eprintln!("failed to serve connection: {err:#}"); + } + }); + } } // Custom echo service, handling two different routes and a // catch-all 404 responder. -async fn echo(req: Request) -> Result, hyper::Error> { - let mut response = Response::new(Body::empty()); +async fn echo(req: Request) -> Result>, hyper::Error> { + let mut response = Response::new(Full::default()); match (req.method(), req.uri().path()) { // Help route. (&Method::GET, "/") => { - *response.body_mut() = Body::from("Try POST /echo\n"); + *response.body_mut() = Full::from("Try POST /echo\n"); } // Echo service route. (&Method::POST, "/echo") => { - *response.body_mut() = req.into_body(); + *response.body_mut() = Full::from( + req.into_body() + .collect() + .await? + .to_bytes(), + ); } // Catch-all 404. _ => { diff --git a/src/acceptor.rs b/src/acceptor.rs deleted file mode 100644 index 02e72d0..0000000 --- a/src/acceptor.rs +++ /dev/null @@ -1,169 +0,0 @@ -use core::task::{Context, Poll}; -use std::future::Future; -use std::io; -use std::pin::Pin; -use std::sync::Arc; - -use futures_util::ready; -use hyper::server::accept::Accept; -use hyper::server::conn::{AddrIncoming, AddrStream}; -use rustls::{ServerConfig, ServerConnection}; -use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; - -mod builder; -pub use builder::AcceptorBuilder; -use builder::WantsTlsConfig; - -/// A TLS acceptor that can be used with hyper servers. -pub struct TlsAcceptor { - config: Arc, - acceptor: A, -} - -/// An Acceptor for the `https` scheme. -impl TlsAcceptor { - /// Provides a builder for a `TlsAcceptor`. - pub fn builder() -> AcceptorBuilder { - AcceptorBuilder::new() - } - - /// Creates a new `TlsAcceptor` from a `ServerConfig` and an `AddrIncoming`. - pub fn new(config: Arc, incoming: AddrIncoming) -> Self { - Self { - config, - acceptor: incoming, - } - } -} - -impl Accept for TlsAcceptor -where - A: Accept + Unpin, - A::Conn: AsyncRead + AsyncWrite + Unpin, -{ - type Conn = TlsStream; - type Error = io::Error; - - fn poll_accept( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll>> { - let pin = self.get_mut(); - Poll::Ready(match ready!(Pin::new(&mut pin.acceptor).poll_accept(cx)) { - Some(Ok(sock)) => Some(Ok(TlsStream::new(sock, pin.config.clone()))), - Some(Err(e)) => Some(Err(e)), - None => None, - }) - } -} - -impl From<(C, I)> for TlsAcceptor -where - C: Into>, - I: Into, -{ - fn from((config, incoming): (C, I)) -> Self { - Self::new(config.into(), incoming.into()) - } -} - -/// A TLS stream constructed by a [`TlsAcceptor`]. -// tokio_rustls::server::TlsStream doesn't expose constructor methods, -// so we have to TlsAcceptor::accept and handshake to have access to it -// TlsStream implements AsyncRead/AsyncWrite by handshaking with tokio_rustls::Accept first -pub struct TlsStream { - state: State, -} - -impl TlsStream { - fn new(stream: C, config: Arc) -> Self { - let accept = tokio_rustls::TlsAcceptor::from(config).accept(stream); - Self { - state: State::Handshaking(accept), - } - } - /// Returns a reference to the underlying IO stream. - /// - /// This should always return `Some`, except if an error has already been yielded. - pub fn io(&self) -> Option<&C> { - match &self.state { - State::Handshaking(accept) => accept.get_ref(), - State::Streaming(stream) => Some(stream.get_ref().0), - } - } - - /// Returns a reference to the underlying [`rustls::ServerConnection']. - /// - /// This will start yielding `Some` only after the handshake has completed. - pub fn connection(&self) -> Option<&ServerConnection> { - match &self.state { - State::Handshaking(_) => None, - State::Streaming(stream) => Some(stream.get_ref().1), - } - } -} - -impl AsyncRead for TlsStream { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context, - buf: &mut ReadBuf, - ) -> Poll> { - let pin = self.get_mut(); - let accept = match &mut pin.state { - State::Handshaking(accept) => accept, - State::Streaming(stream) => return Pin::new(stream).poll_read(cx, buf), - }; - - let mut stream = match ready!(Pin::new(accept).poll(cx)) { - Ok(stream) => stream, - Err(err) => return Poll::Ready(Err(err)), - }; - - let result = Pin::new(&mut stream).poll_read(cx, buf); - pin.state = State::Streaming(stream); - result - } -} - -impl AsyncWrite for TlsStream { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - let pin = self.get_mut(); - let accept = match &mut pin.state { - State::Handshaking(accept) => accept, - State::Streaming(stream) => return Pin::new(stream).poll_write(cx, buf), - }; - - let mut stream = match ready!(Pin::new(accept).poll(cx)) { - Ok(stream) => stream, - Err(err) => return Poll::Ready(Err(err)), - }; - - let result = Pin::new(&mut stream).poll_write(cx, buf); - pin.state = State::Streaming(stream); - result - } - - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match &mut self.state { - State::Handshaking(_) => Poll::Ready(Ok(())), - State::Streaming(stream) => Pin::new(stream).poll_flush(cx), - } - } - - fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match &mut self.state { - State::Handshaking(_) => Poll::Ready(Ok(())), - State::Streaming(stream) => Pin::new(stream).poll_shutdown(cx), - } - } -} - -enum State { - Handshaking(tokio_rustls::Accept), - Streaming(tokio_rustls::server::TlsStream), -} diff --git a/src/acceptor/builder.rs b/src/acceptor/builder.rs deleted file mode 100644 index ec14f17..0000000 --- a/src/acceptor/builder.rs +++ /dev/null @@ -1,107 +0,0 @@ -use std::sync::Arc; - -use hyper::server::conn::AddrIncoming; -use pki_types::{CertificateDer, PrivateKeyDer}; -use rustls::ServerConfig; - -use super::TlsAcceptor; - -/// Builder for [`TlsAcceptor`] -pub struct AcceptorBuilder(State); - -/// State of a builder that needs a TLS client config next -pub struct WantsTlsConfig(()); - -impl AcceptorBuilder { - /// Creates a new [`AcceptorBuilder`] - pub fn new() -> Self { - Self(WantsTlsConfig(())) - } - - /// Passes a rustls [`ServerConfig`] to configure the TLS connection - pub fn with_tls_config(self, config: ServerConfig) -> AcceptorBuilder { - AcceptorBuilder(WantsAlpn(config)) - } - - /// Use rustls default crypto provider and safe defaults without - /// [client authentication][with_no_client_auth] - /// - /// [with_no_client_auth]: rustls::ConfigBuilder::with_no_client_auth - pub fn with_single_cert( - self, - cert_chain: Vec>, - key_der: PrivateKeyDer<'static>, - ) -> Result, rustls::Error> { - Ok(AcceptorBuilder(WantsAlpn( - ServerConfig::builder() - .with_no_client_auth() - .with_single_cert(cert_chain, key_der)?, - ))) - } -} - -impl Default for AcceptorBuilder { - fn default() -> Self { - Self::new() - } -} - -/// State of a builder that needs a incoming address next -pub struct WantsAlpn(ServerConfig); - -impl AcceptorBuilder { - /// Configure ALPN accept protocols in order - pub fn with_alpn_protocols( - mut self, - alpn_protocols: Vec>, - ) -> AcceptorBuilder { - self.0 .0.alpn_protocols = alpn_protocols; - AcceptorBuilder(WantsIncoming(self.0 .0)) - } - - /// Configure ALPN to accept HTTP/2 - pub fn with_http2_alpn(mut self) -> AcceptorBuilder { - self.0 .0.alpn_protocols = vec![b"h2".to_vec()]; - AcceptorBuilder(WantsIncoming(self.0 .0)) - } - - /// Configure ALPN to accept HTTP/1.0 - pub fn with_http10_alpn(mut self) -> AcceptorBuilder { - self.0 .0.alpn_protocols = vec![b"http/1.0".to_vec()]; - AcceptorBuilder(WantsIncoming(self.0 .0)) - } - - /// Configure ALPN to accept HTTP/1.1 - pub fn with_http11_alpn(mut self) -> AcceptorBuilder { - self.0 .0.alpn_protocols = vec![b"http/1.1".to_vec()]; - AcceptorBuilder(WantsIncoming(self.0 .0)) - } - - /// Configure ALPN to accept HTTP/2, HTTP/1.1, HTTP/1.0 in that order. - pub fn with_all_versions_alpn(mut self) -> AcceptorBuilder { - self.0 .0.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()]; - AcceptorBuilder(WantsIncoming(self.0 .0)) - } -} - -/// State of a builder that needs a incoming address next -pub struct WantsIncoming(ServerConfig); - -impl AcceptorBuilder { - /// Passes a [`AddrIncoming`] to configure the TLS connection and - /// creates the [`TlsAcceptor`] - pub fn with_incoming(self, incoming: impl Into) -> TlsAcceptor { - self.with_acceptor(incoming.into()) - } - - /// Passes an acceptor implementing [`Accept`] to configure the TLS connection and - /// creates the [`TlsAcceptor`] - /// - /// [`Accept`]: hyper::server::accept::Accept - pub fn with_acceptor(self, acceptor: A) -> TlsAcceptor { - TlsAcceptor { - config: Arc::new(self.0 .0), - acceptor, - } - } -} diff --git a/src/connector.rs b/src/connector.rs index 6ce366c..60e6617 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -4,12 +4,13 @@ use std::sync::Arc; use std::task::{Context, Poll}; use std::{fmt, io}; -use hyper::client::connect::Connection; -use hyper::service::Service; -use hyper::Uri; +use http::Uri; +use hyper::rt; +use hyper_util::client::legacy::connect::Connection; +use hyper_util::rt::TokioIo; use pki_types::ServerName; -use tokio::io::{AsyncRead, AsyncWrite}; use tokio_rustls::TlsConnector; +use tower_service::Service; use crate::stream::MaybeHttpsStream; @@ -38,7 +39,7 @@ impl HttpsConnector { impl Service for HttpsConnector where T: Service, - T::Response: Connection + AsyncRead + AsyncWrite + Send + Unpin + 'static, + T::Response: Connection + rt::Read + rt::Write + Send + Unpin + 'static, T::Future: Send + 'static, T::Error: Into, { @@ -108,12 +109,12 @@ where let tcp = connecting_future .await .map_err(Into::into)?; - Ok(MaybeHttpsStream::Https( + Ok(MaybeHttpsStream::Https(TokioIo::new( TlsConnector::from(cfg) - .connect(hostname, tcp) + .connect(hostname, TokioIo::new(tcp)) .await .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?, - )) + ))) }) } } diff --git a/src/connector/builder.rs b/src/connector/builder.rs index 4e65f86..45a3daa 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -1,5 +1,4 @@ -#[cfg(feature = "tokio-runtime")] -use hyper::client::HttpConnector; +use hyper_util::client::legacy::connect::HttpConnector; #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] use rustls::crypto::CryptoProvider; use rustls::ClientConfig; @@ -18,7 +17,7 @@ use crate::config::ConfigBuilderExt; /// ``` /// use hyper_rustls::HttpsConnectorBuilder; /// -/// # #[cfg(all(feature = "webpki-roots", feature = "tokio-runtime", feature = "http1"))] +/// # #[cfg(all(feature = "webpki-roots", feature = "http1"))] /// let https = HttpsConnectorBuilder::new() /// .with_webpki_roots() /// .https_only() @@ -170,7 +169,6 @@ impl WantsProtocols1 { } } - #[cfg(feature = "tokio-runtime")] fn build(self) -> HttpsConnector { let mut http = HttpConnector::new(); // HttpConnector won't enforce scheme, but HttpsConnector will @@ -257,7 +255,6 @@ impl ConnectorBuilder { } /// This builds an [`HttpsConnector`] built on hyper's default [`HttpConnector`] - #[cfg(feature = "tokio-runtime")] pub fn build(self) -> HttpsConnector { self.0.inner.build() } @@ -288,7 +285,6 @@ pub struct WantsProtocols3 { #[cfg(feature = "http2")] impl ConnectorBuilder { /// This builds an [`HttpsConnector`] built on hyper's default [`HttpConnector`] - #[cfg(feature = "tokio-runtime")] pub fn build(self) -> HttpsConnector { self.0.inner.build() } diff --git a/src/lib.rs b/src/lib.rs index a5d3c55..7cfbe49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,9 +6,13 @@ //! ## Example client //! //! ```no_run -//! # #[cfg(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1"))] +//! # #[cfg(all(feature = "rustls-native-certs", feature = "http1"))] //! # fn main() { -//! use hyper::{Body, Client, StatusCode, Uri}; +//! use http::StatusCode; +//! use http_body_util::Empty; +//! use hyper::body::Bytes; +//! use hyper_util::client::legacy::Client; +//! use hyper_util::rt::TokioExecutor; //! //! let mut rt = tokio::runtime::Runtime::new().unwrap(); //! let url = ("https://hyper.rs").parse().unwrap(); @@ -19,71 +23,18 @@ //! .enable_http1() //! .build(); //! -//! let client: Client<_, hyper::Body> = Client::builder().build(https); +//! let client: Client<_, Empty> = Client::builder(TokioExecutor::new()).build(https); //! //! let res = rt.block_on(client.get(url)).unwrap(); //! assert_eq!(res.status(), StatusCode::OK); //! # } -//! # #[cfg(not(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1")))] -//! # fn main() {} -//! ``` -//! -//! ## Example server -//! -//! ```no_run -//! # #[cfg(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1", feature = "acceptor"))] -//! # fn main() { -//! use std::io; -//! use std::fs::File; -//! -//! use hyper::server::conn::AddrIncoming; -//! use hyper::service::{make_service_fn, service_fn}; -//! use hyper::{Body, Method, Request, Response, Server, StatusCode}; -//! use hyper_rustls::TlsAcceptor; -//! use pki_types::{CertificateDer, PrivateKeyDer}; -//! -//! let mut rt = tokio::runtime::Runtime::new().unwrap(); -//! let addr = "127.0.0.1:1337".parse().unwrap(); -//! -//! // Load public certificate. -//! let certfile = File::open("examples/sample.pem").unwrap(); -//! let mut reader = io::BufReader::new(certfile); -//! -//! // Load and return certificate. -//! let certs = rustls_pemfile::certs(&mut reader).collect::, _>>().unwrap(); -//! -//! // Load private key. (see `examples/server.rs`) -//! let keyfile = File::open("examples/sample.rsa").unwrap(); -//! let mut reader = io::BufReader::new(keyfile); -//! -//! // Load and return a single private key. -//! let key = rustls_pemfile::private_key(&mut reader).unwrap().unwrap(); -//! let https = hyper_rustls::HttpsConnectorBuilder::new() -//! .with_native_roots() -//! .expect("no native root CA certificates found") -//! .https_only() -//! .enable_http1() -//! .build(); -//! -//! let incoming = AddrIncoming::bind(&addr).unwrap(); -//! let acceptor = TlsAcceptor::builder() -//! .with_single_cert(certs, key.into()).unwrap() -//! .with_all_versions_alpn() -//! .with_incoming(incoming); -//! let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(|_req|async {Ok::<_, io::Error>(Response::new(Body::empty()))})) }); -//! let server = Server::builder(acceptor).serve(service); -//! // server.await.unwrap(); -//! # } -//! # #[cfg(not(all(feature = "rustls-native-certs", feature = "tokio-runtime", feature = "http1")))] +//! # #[cfg(not(all(feature = "rustls-native-certs", feature = "http1")))] //! # fn main() {} //! ``` #![warn(missing_docs, unreachable_pub, clippy::use_self)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -#[cfg(feature = "acceptor")] -/// TLS acceptor implementing hyper's `Accept` trait. -pub mod acceptor; mod config; mod connector; mod stream; @@ -102,8 +53,6 @@ mod log { pub(crate) use debug; } -#[cfg(feature = "acceptor")] -pub use crate::acceptor::{AcceptorBuilder, TlsAcceptor}; pub use crate::config::ConfigBuilderExt; pub use crate::connector::builder::ConnectorBuilder as HttpsConnectorBuilder; pub use crate::connector::HttpsConnector; diff --git a/src/stream.rs b/src/stream.rs index a0e8c68..9f017bc 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -4,9 +4,10 @@ use std::io; use std::pin::Pin; use std::task::{Context, Poll}; -use hyper::client::connect::{Connected, Connection}; +use hyper::rt; +use hyper_util::client::legacy::connect::{Connected, Connection}; -use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +use hyper_util::rt::TokioIo; use tokio_rustls::client::TlsStream; /// A stream that might be protected with TLS. @@ -15,19 +16,19 @@ pub enum MaybeHttpsStream { /// A stream over plain text. Http(T), /// A stream protected with TLS. - Https(TlsStream), + Https(TokioIo>>), } -impl Connection for MaybeHttpsStream { +impl Connection for MaybeHttpsStream { fn connected(&self) -> Connected { match self { Self::Http(s) => s.connected(), Self::Https(s) => { - let (tcp, tls) = s.get_ref(); + let (tcp, tls) = s.inner().get_ref(); if tls.alpn_protocol() == Some(b"h2") { - tcp.connected().negotiated_h2() + tcp.inner().connected().negotiated_h2() } else { - tcp.connected() + tcp.inner().connected() } } } @@ -49,18 +50,18 @@ impl From for MaybeHttpsStream { } } -impl From> for MaybeHttpsStream { - fn from(inner: TlsStream) -> Self { - Self::Https(inner) +impl From>> for MaybeHttpsStream { + fn from(inner: TlsStream>) -> Self { + Self::Https(TokioIo::new(inner)) } } -impl AsyncRead for MaybeHttpsStream { +impl rt::Read for MaybeHttpsStream { #[inline] fn poll_read( self: Pin<&mut Self>, cx: &mut Context, - buf: &mut ReadBuf<'_>, + buf: rt::ReadBufCursor<'_>, ) -> Poll> { match Pin::get_mut(self) { Self::Http(s) => Pin::new(s).poll_read(cx, buf), @@ -69,7 +70,7 @@ impl AsyncRead for MaybeHttpsStream { } } -impl AsyncWrite for MaybeHttpsStream { +impl rt::Write for MaybeHttpsStream { #[inline] fn poll_write( self: Pin<&mut Self>, diff --git a/tests/tests.rs b/tests/tests.rs index e9cb839..6730a28 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -42,7 +42,6 @@ fn client() { assert!(rc.status.success()); } -#[cfg(feature = "acceptor")] #[test] fn server() { let mut srv = server_command() From ad93d229da89a9498aaaef8de1075fafe401b675 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Mon, 8 Jan 2024 19:06:33 +0100 Subject: [PATCH 066/133] Bump version to 0.26.0 Signed-off-by: Jens Reidel --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e275ed9..c908326 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.25.0" +version = "0.26.0" edition = "2021" rust-version = "1.63" license = "Apache-2.0 OR ISC OR MIT" From 9bb9d595ec202699a155aee56c1a706c0e8bf47a Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 24 Jan 2024 11:01:59 +0100 Subject: [PATCH 067/133] Bump MSRV to 1.64 for rustls-platform-verifier --- .github/workflows/build.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7f94b76..5f93999 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -83,7 +83,7 @@ jobs: - name: Install rust toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "1.63" + toolchain: "1.64" - name: Check MSRV run: cargo check --lib --all-features diff --git a/Cargo.toml b/Cargo.toml index c908326..0f69ae4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "hyper-rustls" version = "0.26.0" edition = "2021" -rust-version = "1.63" +rust-version = "1.64" license = "Apache-2.0 OR ISC OR MIT" readme = "README.md" description = "Rustls+hyper integration for pure rust HTTPS" From 358286346dbf7c5385f6c41ab090b5d1eafbb081 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 24 Jan 2024 10:05:59 +0100 Subject: [PATCH 068/133] Add built-in support for rustls-platform-verifier --- Cargo.toml | 1 + src/config.rs | 25 ++++++++++++++++++++++++- src/connector/builder.rs | 12 ++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 0f69ae4..0bd3cf5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ hyper-util = { version = "0.1", default-features = false, features = ["client-le log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "1" } rustls-native-certs = { version = "0.7", optional = true } +rustls-platform-verifier = { version = "0.2", optional = true } rustls = { version = "0.22", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.25", default-features = false } diff --git a/src/config.rs b/src/config.rs index a512433..2af49c7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,11 @@ -#[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] +#[cfg(feature = "rustls-platform-verifier")] +use std::sync::Arc; + +#[cfg(any( + feature = "rustls-platform-verifier", + feature = "rustls-native-certs", + feature = "webpki-roots" +))] use rustls::client::WantsClientCert; use rustls::{ClientConfig, ConfigBuilder, WantsVerifier}; @@ -7,6 +14,14 @@ use rustls::{ClientConfig, ConfigBuilder, WantsVerifier}; /// This adds methods (gated by crate features) for easily configuring /// TLS server roots a rustls ClientConfig will trust. pub trait ConfigBuilderExt { + /// Use the platform's native verifier to verify server certificates. + /// + /// See the documentation for [rustls-platform-verifier] for more details. + /// + /// [rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier + #[cfg(feature = "rustls-platform-verifier")] + fn with_platform_verifier(self) -> ConfigBuilder; + /// This configures the platform's trusted certs, as implemented by /// rustls-native-certs /// @@ -22,6 +37,14 @@ pub trait ConfigBuilderExt { } impl ConfigBuilderExt for ConfigBuilder { + #[cfg(feature = "rustls-platform-verifier")] + fn with_platform_verifier(self) -> ConfigBuilder { + self.dangerous() + .with_custom_certificate_verifier(Arc::new( + rustls_platform_verifier::Verifier::default(), + )) + } + #[cfg(feature = "rustls-native-certs")] #[cfg_attr(not(feature = "logging"), allow(unused_variables))] fn with_native_roots(self) -> std::io::Result> { diff --git a/src/connector/builder.rs b/src/connector/builder.rs index 45a3daa..3e1abda 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -51,6 +51,18 @@ impl ConnectorBuilder { ConnectorBuilder(WantsSchemes { tls_config: config }) } + /// Use rustls' default crypto provider and other defaults, and the platform verifier + /// + /// See [`ConfigBuilderExt::with_platform_verifier()`]. + #[cfg(all(feature = "ring", feature = "rustls-platform-verifier"))] + pub fn with_platform_verifier(self) -> ConnectorBuilder { + self.with_tls_config( + ClientConfig::builder() + .with_platform_verifier() + .with_no_client_auth(), + ) + } + /// Shorthand for using rustls' default crypto provider and safe defaults, with /// native roots. /// From 68c7d05e28e1d8161495afd3cc9811d13f5b9644 Mon Sep 17 00:00:00 2001 From: BiagioFesta <15035284+BiagioFesta@users.noreply.github.com> Date: Tue, 20 Feb 2024 14:33:12 +0100 Subject: [PATCH 069/133] Cargo.toml: add aws-lc-rs feature as crypto backend --- .github/workflows/build.yml | 8 ++++++++ Cargo.toml | 1 + 2 files changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f93999..27ae1e5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,6 +40,14 @@ jobs: with: toolchain: ${{ matrix.rust }} + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v4 + - name: cargo check (default features) run: cargo check --all-targets diff --git a/Cargo.toml b/Cargo.toml index 0bd3cf5..f7e52a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thre [features] default = ["native-tokio", "http1", "tls12", "logging", "ring"] +aws-lc-rs = ["rustls/aws_lc_rs"] http1 = ["hyper-util/http1"] http2 = ["hyper-util/http2"] webpki-tokio = ["webpki-roots"] From 4030f86a95d7c3d2ebe87c7da86b5a8bde2857a1 Mon Sep 17 00:00:00 2001 From: Jeremiah Senkpiel Date: Wed, 20 Mar 2024 12:21:18 -0700 Subject: [PATCH 070/133] feat: add a builder() method to HttpsConnector It's become very idiomatic to have the builder api be accessed this way. --- src/connector.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/connector.rs b/src/connector.rs index 60e6617..37864da 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -28,6 +28,13 @@ pub struct HttpsConnector { } impl HttpsConnector { + /// Creates a [`crate::HttpsConnectorBuilder`] to configure a `HttpsConnector`. + /// + /// This is the same as [`crate::HttpsConnectorBuilder::new()`]. + pub fn builder() -> builder::ConnectorBuilder { + builder::ConnectorBuilder::new() + } + /// Force the use of HTTPS when connecting. /// /// If a URL is not `https` when connecting, an error is returned. From ccd5ec1bae06949846e15b5f930e796f3c147f7f Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Fri, 22 Mar 2024 09:44:41 -0400 Subject: [PATCH 071/133] examples: fix redundant Vec import --- examples/server.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/server.rs b/examples/server.rs index ffdb38f..576fc19 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -7,7 +7,6 @@ use std::net::{Ipv4Addr, SocketAddr}; use std::sync::Arc; -use std::vec::Vec; use std::{env, fs, io}; use http::{Method, Request, Response, StatusCode}; From 731d19eaf03fba83041524253c0d53a28b444fe5 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Fri, 22 Mar 2024 09:40:32 -0400 Subject: [PATCH 072/133] Cargo: update Rustls & associated crates to 0.23 * updates rustls 0.22 to 0.23 * updates tokio-rustls 0.25 to 0.26 * updates rustls-platform-verifier 0.2 to 0.3 * addresses default crypto provider requirements for tests, examples * makes aws-lc-rs the default crypto provider, matching upstream. Ring remains available opt-in with the `ring` feature. --- Cargo.toml | 12 ++++++------ examples/client.rs | 6 ++++++ examples/server.rs | 6 ++++++ src/connector/builder.rs | 29 ++++++++++++++++++++++++----- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f7e52a4..c707e53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,10 +17,10 @@ hyper-util = { version = "0.1", default-features = false, features = ["client-le log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "1" } rustls-native-certs = { version = "0.7", optional = true } -rustls-platform-verifier = { version = "0.2", optional = true } -rustls = { version = "0.22", default-features = false } +rustls-platform-verifier = { version = "0.3", optional = true } +rustls = { version = "0.23", default-features = false } tokio = "1.0" -tokio-rustls = { version = "0.25", default-features = false } +tokio-rustls = { version = "0.26", default-features = false } tower-service = "0.3" webpki-roots = { version = "0.26", optional = true } futures-util = { version = "0.3", default-features = false } @@ -28,12 +28,12 @@ futures-util = { version = "0.3", default-features = false } [dev-dependencies] http-body-util = "0.1" hyper-util = { version = "0.1", default-features = false, features = ["server-auto"] } -rustls = { version = "0.22", default-features = false, features = ["tls12"] } +rustls = { version = "0.23", default-features = false, features = ["tls12"] } rustls-pemfile = "2" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } [features] -default = ["native-tokio", "http1", "tls12", "logging", "ring"] +default = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] aws-lc-rs = ["rustls/aws_lc_rs"] http1 = ["hyper-util/http1"] http2 = ["hyper-util/http2"] @@ -51,7 +51,7 @@ required-features = ["native-tokio", "http1"] [[example]] name = "server" path = "examples/server.rs" -required-features = ["ring"] +required-features = ["aws-lc-rs"] [package.metadata.docs.rs] all-features = true diff --git a/examples/client.rs b/examples/client.rs index 36d5c6f..c45bc2a 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -26,6 +26,12 @@ fn error(err: String) -> io::Error { #[tokio::main] async fn run_client() -> io::Result<()> { + // Set a process wide default crypto provider. + #[cfg(feature = "ring")] + let _ = rustls::crypto::ring::default_provider().install_default(); + #[cfg(feature = "aws-lc-rs")] + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); + // First parameter is target URL (mandatory). let url = match env::args().nth(1) { Some(ref url) => Uri::from_str(url).map_err(|e| error(format!("{}", e)))?, diff --git a/examples/server.rs b/examples/server.rs index 576fc19..8f7803f 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -34,6 +34,12 @@ fn error(err: String) -> io::Error { #[tokio::main] async fn run_server() -> Result<(), Box> { + // Set a process wide default crypto provider. + #[cfg(feature = "ring")] + let _ = rustls::crypto::ring::default_provider().install_default(); + #[cfg(feature = "aws-lc-rs")] + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); + // First parameter is port number (optional, defaults to 1337) let port = match env::args().nth(1) { Some(ref p) => p.parse()?, diff --git a/src/connector/builder.rs b/src/connector/builder.rs index 3e1abda..b628b1a 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -17,12 +17,15 @@ use crate::config::ConfigBuilderExt; /// ``` /// use hyper_rustls::HttpsConnectorBuilder; /// -/// # #[cfg(all(feature = "webpki-roots", feature = "http1"))] -/// let https = HttpsConnectorBuilder::new() +/// # #[cfg(all(feature = "webpki-roots", feature = "http1", feature="aws-lc-rs"))] +/// # { +/// # let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); +/// let https = HttpsConnectorBuilder::new() /// .with_webpki_roots() /// .https_only() /// .enable_http1() /// .build(); +/// # } /// ``` pub struct ConnectorBuilder(State); @@ -54,7 +57,10 @@ impl ConnectorBuilder { /// Use rustls' default crypto provider and other defaults, and the platform verifier /// /// See [`ConfigBuilderExt::with_platform_verifier()`]. - #[cfg(all(feature = "ring", feature = "rustls-platform-verifier"))] + #[cfg(all( + any(feature = "ring", feature = "aws-lc-rs"), + feature = "rustls-platform-verifier" + ))] pub fn with_platform_verifier(self) -> ConnectorBuilder { self.with_tls_config( ClientConfig::builder() @@ -67,7 +73,10 @@ impl ConnectorBuilder { /// native roots. /// /// See [`ConfigBuilderExt::with_native_roots`] - #[cfg(all(feature = "ring", feature = "rustls-native-certs"))] + #[cfg(all( + any(feature = "ring", feature = "aws-lc-rs"), + feature = "rustls-native-certs" + ))] pub fn with_native_roots(self) -> std::io::Result> { Ok(self.with_tls_config( ClientConfig::builder() @@ -97,7 +106,7 @@ impl ConnectorBuilder { /// safe defaults. /// /// See [`ConfigBuilderExt::with_webpki_roots`] - #[cfg(all(feature = "ring", feature = "webpki-roots"))] + #[cfg(all(any(feature = "ring", feature = "aws-lc-rs"), feature = "webpki-roots"))] pub fn with_webpki_roots(self) -> ConnectorBuilder { self.with_tls_config( ClientConfig::builder() @@ -316,6 +325,7 @@ mod tests { #[test] #[cfg(all(feature = "webpki-roots", feature = "http1"))] fn test_builder() { + ensure_global_state(); let _connector = super::ConnectorBuilder::new() .with_webpki_roots() .https_only() @@ -327,6 +337,7 @@ mod tests { #[cfg(feature = "http1")] #[should_panic(expected = "ALPN protocols should not be pre-defined")] fn test_reject_predefined_alpn() { + ensure_global_state(); let roots = rustls::RootCertStore::empty(); let mut config_with_alpn = rustls::ClientConfig::builder() .with_root_certificates(roots) @@ -342,6 +353,7 @@ mod tests { #[test] #[cfg(all(feature = "http1", feature = "http2"))] fn test_alpn() { + ensure_global_state(); let roots = rustls::RootCertStore::empty(); let tls_config = rustls::ClientConfig::builder() .with_root_certificates(roots) @@ -403,4 +415,11 @@ mod tests { .build(); assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); } + + fn ensure_global_state() { + #[cfg(feature = "ring")] + let _ = rustls::crypto::ring::default_provider().install_default(); + #[cfg(feature = "aws-lc-rs")] + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); + } } From c9e25c4a566b6e73d3f265ea6d26fa71d7b02f97 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Mon, 25 Mar 2024 16:21:38 -0400 Subject: [PATCH 073/133] ci: add ring build to test phase Previously we did not have a test step that would run the unit tests assuming the equivalent of default features, but with the default crypto provider (now `aws-lc-rs`) with the alternative built-in option (now `ring`). --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27ae1e5..05a7f0d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,6 +66,11 @@ jobs: env: RUST_BACKTRACE: 1 + - name: cargo test (debug; defaults+ring) + run: cargo test --no-default-features --features ring,native-tokio,http1,tls12,logging + env: + RUST_BACKTRACE: 1 + - name: cargo test (debug; all features) run: cargo test --all-features env: From 0d387948b62641d30631170ad994d288c6fbde98 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Fri, 22 Mar 2024 09:45:40 -0400 Subject: [PATCH 074/133] Cargo: version 0.26.0 -> 0.27.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c707e53..6508406 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.26.0" +version = "0.27.0" edition = "2021" rust-version = "1.64" license = "Apache-2.0 OR ISC OR MIT" From 16d7e5915d10355cf465165bf1c0c6e3cfbb223f Mon Sep 17 00:00:00 2001 From: Toby Lawrence Date: Tue, 2 Apr 2024 14:55:27 -0400 Subject: [PATCH 075/133] Add feature flag for enabling FIPS. (#268) --- .github/workflows/build.yml | 7 +++++++ Cargo.toml | 1 + README.md | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 05a7f0d..9012a2d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,10 +72,17 @@ jobs: RUST_BACKTRACE: 1 - name: cargo test (debug; all features) + if: runner.os == 'Linux' run: cargo test --all-features env: RUST_BACKTRACE: 1 + - name: cargo test (debug; all features, excluding FIPS) + if: runner.os != 'Linux' + run: cargo test --features aws-lc-rs,http1,http2,webpki-tokio,native-tokio,ring,tls12,logging + env: + RUST_BACKTRACE: 1 + - name: cargo build (debug; no default features) run: cargo build --no-default-features diff --git a/Cargo.toml b/Cargo.toml index 6508406..b58b474 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ native-tokio = ["rustls-native-certs"] ring = ["rustls/ring"] tls12 = ["tokio-rustls/tls12", "rustls/tls12"] logging = ["log", "tokio-rustls/logging", "rustls/logging"] +fips = ["aws-lc-rs", "rustls/fips"] [[example]] name = "client" diff --git a/README.md b/README.md index 274b47f..5e25e0f 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,28 @@ cargo run --example server ```bash cargo run --example client "https://docs.rs/hyper-rustls/latest/hyper_rustls/" ``` + +## Crate features + +This crate exposes a number of features to add support for different portions of `hyper-util`, +`rustls`, and other dependencies. + +| Feature flag | Enabled by default | Description | +| ------------ | ------------------ | ----------- | +| `aws-lc-rs` | **yes** | Enables use of the [AWS-LC][aws-lc-rs] backend for [`rustls`][rustls] | +| `http1` | **yes** | Enables HTTP/1 support in [`hyper-util`][hyper-util] | +| `http2` | **no** | Enables HTTP/2 support in [`hyper-util`][hyper-util] | +| `webpki-tokio` | **no** | Uses a compiled-in set of root certificates trusted by Mozilla (via [`webpki-roots`][webpki-roots]) | +| `native-tokio` | **yes** | Use the platform's native certificate store at runtime (via [`rustls-native-certs`][rustls-native-certs]) | +| `ring` | **no** | Enables use of the [`ring`][ring] backend for [`rustls`][rustls] | +| `tls12` | **yes** | Enables support for TLS 1.2 (only TLS 1.3 supported when disabled) | +| `logging` | **yes** | Enables logging of protocol-level diagnostics and errors via [`log`][log] | +| `fips` | **no** | Enables support for using a FIPS 140-3 compliant backend via AWS-LC (enables `aws-lc-rs` feature) | + +[aws-lc-rs]: https://docs.rs/aws-lc-rs +[rustls]: https://docs.rs/rustls +[hyper-util]: https://docs.rs/hyper-util +[webpki-roots]: https://docs.rs/webpki-roots +[rustls-native-certs]: https://docs.rs/rustls-native-certs +[ring]: https://docs.rs/ring +[log]: https://docs.rs/log From 7d31dc5288210305dca6e108233db81621a41047 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 10 Apr 2024 11:08:28 -0400 Subject: [PATCH 076/133] Support custom server name resolution (#269) Co-authored-by: Daniel McCarney --- src/connector.rs | 92 +++++++++++++++++++++++++++++++--------- src/connector/builder.rs | 50 ++++++++++++++++++---- src/lib.rs | 4 +- 3 files changed, 117 insertions(+), 29 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 37864da..02a29a8 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -24,7 +24,7 @@ pub struct HttpsConnector { force_https: bool, http: T, tls_config: Arc, - override_server_name: Option, + server_name_resolver: Arc, } impl HttpsConnector { @@ -90,24 +90,10 @@ where }; let cfg = self.tls_config.clone(); - let mut hostname = match self.override_server_name.as_deref() { - Some(h) => h, - None => dst.host().unwrap_or_default(), - }; - - // Remove square brackets around IPv6 address. - if let Some(trimmed) = hostname - .strip_prefix('[') - .and_then(|h| h.strip_suffix(']')) - { - hostname = trimmed; - } - - let hostname = match ServerName::try_from(hostname) { - Ok(dns_name) => dns_name.to_owned(), - Err(_) => { - let err = io::Error::new(io::ErrorKind::Other, "invalid dnsname"); - return Box::pin(async move { Err(Box::new(err).into()) }); + let hostname = match self.server_name_resolver.resolve(&dst) { + Ok(hostname) => hostname, + Err(e) => { + return Box::pin(async move { Err(e) }); } }; @@ -135,7 +121,7 @@ where force_https: false, http, tls_config: cfg.into(), - override_server_name: None, + server_name_resolver: Arc::new(DefaultServerNameResolver::default()), } } } @@ -147,3 +133,69 @@ impl fmt::Debug for HttpsConnector { .finish() } } + +/// The default server name resolver, which uses the hostname in the URI. +#[derive(Default)] +pub struct DefaultServerNameResolver(()); + +impl ResolveServerName for DefaultServerNameResolver { + fn resolve( + &self, + uri: &Uri, + ) -> Result, Box> { + let mut hostname = uri.host().unwrap_or_default(); + + // Remove square brackets around IPv6 address. + if let Some(trimmed) = hostname + .strip_prefix('[') + .and_then(|h| h.strip_suffix(']')) + { + hostname = trimmed; + } + + ServerName::try_from(hostname.to_string()).map_err(|e| Box::new(e) as _) + } +} + +/// A server name resolver which always returns the same fixed name. +pub struct FixedServerNameResolver { + name: ServerName<'static>, +} + +impl FixedServerNameResolver { + /// Creates a new resolver returning the specified name. + pub fn new(name: ServerName<'static>) -> Self { + Self { name } + } +} + +impl ResolveServerName for FixedServerNameResolver { + fn resolve( + &self, + _: &Uri, + ) -> Result, Box> { + Ok(self.name.clone()) + } +} + +impl ResolveServerName for F +where + F: Fn(&Uri) -> Result, E>, + E: Into>, +{ + fn resolve( + &self, + uri: &Uri, + ) -> Result, Box> { + self(uri).map_err(Into::into) + } +} + +/// A trait implemented by types that can resolve a [`ServerName`] for a request. +pub trait ResolveServerName { + /// Maps a [`Uri`] into a [`ServerName`]. + fn resolve( + &self, + uri: &Uri, + ) -> Result, Box>; +} diff --git a/src/connector/builder.rs b/src/connector/builder.rs index b628b1a..e0b78fc 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -1,11 +1,14 @@ +use std::sync::Arc; + use hyper_util::client::legacy::connect::HttpConnector; #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] use rustls::crypto::CryptoProvider; use rustls::ClientConfig; -use super::HttpsConnector; +use super::{DefaultServerNameResolver, HttpsConnector, ResolveServerName}; #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] use crate::config::ConfigBuilderExt; +use pki_types::ServerName; /// A builder for an [`HttpsConnector`] /// @@ -153,7 +156,7 @@ impl ConnectorBuilder { ConnectorBuilder(WantsProtocols1 { tls_config: self.0.tls_config, https_only: true, - override_server_name: None, + server_name_resolver: None, }) } @@ -165,7 +168,7 @@ impl ConnectorBuilder { ConnectorBuilder(WantsProtocols1 { tls_config: self.0.tls_config, https_only: false, - override_server_name: None, + server_name_resolver: None, }) } } @@ -177,7 +180,7 @@ impl ConnectorBuilder { pub struct WantsProtocols1 { tls_config: ClientConfig, https_only: bool, - override_server_name: Option, + server_name_resolver: Option>, } impl WantsProtocols1 { @@ -186,7 +189,9 @@ impl WantsProtocols1 { force_https: self.https_only, http: conn, tls_config: std::sync::Arc::new(self.tls_config), - override_server_name: self.override_server_name, + server_name_resolver: self + .server_name_resolver + .unwrap_or_else(|| Arc::new(DefaultServerNameResolver::default())), } } @@ -237,6 +242,22 @@ impl ConnectorBuilder { }) } + /// Override server name for the TLS stack + /// + /// By default, for each connection hyper-rustls will extract host portion + /// of the destination URL and verify that server certificate contains + /// this value. + /// + /// If this method is called, hyper-rustls will instead use this resolver + /// to compute the value used to verify the server certificate. + pub fn with_server_name_resolver( + mut self, + resolver: impl ResolveServerName + 'static + Sync + Send, + ) -> Self { + self.0.server_name_resolver = Some(Arc::new(resolver)); + self + } + /// Override server name for the TLS stack /// /// By default, for each connection hyper-rustls will extract host portion @@ -246,9 +267,22 @@ impl ConnectorBuilder { /// If this method is called, hyper-rustls will instead verify that server /// certificate contains `override_server_name`. Domain name included in /// the URL will not affect certificate validation. - pub fn with_server_name(mut self, override_server_name: String) -> Self { - self.0.override_server_name = Some(override_server_name); - self + #[deprecated( + since = "0.27.1", + note = "use Self::with_server_name_resolver with FixedServerNameResolver instead" + )] + pub fn with_server_name(self, mut override_server_name: String) -> Self { + // remove square brackets around IPv6 address. + if let Some(trimmed) = override_server_name + .strip_prefix('[') + .and_then(|s| s.strip_suffix(']')) + { + override_server_name = trimmed.to_string(); + } + + self.with_server_name_resolver(move |_: &_| { + ServerName::try_from(override_server_name.clone()) + }) } } diff --git a/src/lib.rs b/src/lib.rs index 7cfbe49..1920e78 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,7 +55,9 @@ mod log { pub use crate::config::ConfigBuilderExt; pub use crate::connector::builder::ConnectorBuilder as HttpsConnectorBuilder; -pub use crate::connector::HttpsConnector; +pub use crate::connector::{ + DefaultServerNameResolver, FixedServerNameResolver, HttpsConnector, ResolveServerName, +}; pub use crate::stream::MaybeHttpsStream; /// The various states of the [`HttpsConnectorBuilder`] From cb05f463ed7d34e18fa580fd7249eddebcc39ec5 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Wed, 10 Apr 2024 12:09:05 -0400 Subject: [PATCH 077/133] Cargo: v0.27.0 -> v0.27.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b58b474..edd1306 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.27.0" +version = "0.27.1" edition = "2021" rust-version = "1.64" license = "Apache-2.0 OR ISC OR MIT" From b6d124c14e1b94f60e383ea9e9093d7307603e0d Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 19 Apr 2024 09:24:40 +0200 Subject: [PATCH 078/133] ci: use ubuntu-latest instead of ubuntu-20.04 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9012a2d..ef079be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: - stable - beta - nightly - os: [ubuntu-20.04] + os: [ubuntu-latest] # but only stable on macos/windows (slower platforms) include: - os: macos-latest @@ -93,7 +93,7 @@ jobs: run: cargo test --release --no-run msrv: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v4 @@ -122,7 +122,7 @@ jobs: docs: name: Check for documentation errors - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v4 From 78d214b518e9238da26958bc37c699490332283d Mon Sep 17 00:00:00 2001 From: Toby Lawrence Date: Fri, 26 Apr 2024 09:03:33 -0400 Subject: [PATCH 079/133] Avoid `aws-lc-rs` feature flag when building docs. (#273) --- .github/workflows/build.yml | 3 ++- Cargo.toml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ef079be..a101a65 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -133,7 +133,8 @@ jobs: uses: dtolnay/rust-toolchain@nightly - name: cargo doc (all features) - run: cargo doc --all-features --no-deps + # keep features in sync with Cargo.toml `[package.metadata.docs.rs]` section + run: cargo doc --no-default-features --features http1,http2,webpki-tokio,native-tokio,ring,tls12,logging --no-deps env: RUSTDOCFLAGS: -Dwarnings diff --git a/Cargo.toml b/Cargo.toml index edd1306..4804f4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,5 +55,6 @@ path = "examples/server.rs" required-features = ["aws-lc-rs"] [package.metadata.docs.rs] -all-features = true +no-default-features = true +features = ["http1", "http2", "webpki-tokio", "native-tokio", "ring", "tls12", "logging"] rustdoc-args = ["--cfg", "docsrs"] From 0a201234b514a47c3f3f3e0bc2f74ada73f8c94b Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 27 May 2024 13:37:58 +0200 Subject: [PATCH 080/133] Bump version to 0.27.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4804f4d..5947756 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.27.1" +version = "0.27.2" edition = "2021" rust-version = "1.64" license = "Apache-2.0 OR ISC OR MIT" From c56c76a99ab0e9413fba5cc04df2d4fcbfd45735 Mon Sep 17 00:00:00 2001 From: Jun Kurihara Date: Fri, 7 Jun 2024 13:47:56 +0900 Subject: [PATCH 081/133] fix: add rustls-platform-verifier flag for importing ConfigBuilderExt --- src/connector/builder.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/connector/builder.rs b/src/connector/builder.rs index e0b78fc..b2858b9 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -6,7 +6,11 @@ use rustls::crypto::CryptoProvider; use rustls::ClientConfig; use super::{DefaultServerNameResolver, HttpsConnector, ResolveServerName}; -#[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] +#[cfg(any( + feature = "rustls-native-certs", + feature = "webpki-roots", + feature = "rustls-platform-verifier" +))] use crate::config::ConfigBuilderExt; use pki_types::ServerName; From a8d14bbc4d0e35c2bad09501e3db118266bbeffc Mon Sep 17 00:00:00 2001 From: Jun Kurihara Date: Fri, 7 Jun 2024 17:14:24 +0900 Subject: [PATCH 082/133] docs: add a feature rustls-platform-verifier in the list of README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5e25e0f..047c19e 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ This crate exposes a number of features to add support for different portions of | `http2` | **no** | Enables HTTP/2 support in [`hyper-util`][hyper-util] | | `webpki-tokio` | **no** | Uses a compiled-in set of root certificates trusted by Mozilla (via [`webpki-roots`][webpki-roots]) | | `native-tokio` | **yes** | Use the platform's native certificate store at runtime (via [`rustls-native-certs`][rustls-native-certs]) | +| `rustls-platform-verifier` | **no** | Use the operating system's verifier for certificate verification (via [`rustls-platform-verifier`][rustls-platform-verifier]) | | `ring` | **no** | Enables use of the [`ring`][ring] backend for [`rustls`][rustls] | | `tls12` | **yes** | Enables support for TLS 1.2 (only TLS 1.3 supported when disabled) | | `logging` | **yes** | Enables logging of protocol-level diagnostics and errors via [`log`][log] | @@ -58,5 +59,6 @@ This crate exposes a number of features to add support for different portions of [hyper-util]: https://docs.rs/hyper-util [webpki-roots]: https://docs.rs/webpki-roots [rustls-native-certs]: https://docs.rs/rustls-native-certs +[rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier [ring]: https://docs.rs/ring [log]: https://docs.rs/log From ceb2f61cc46b70806139962a1e8652c377ed292a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 19:20:31 +0000 Subject: [PATCH 083/133] Bump seanmiddleditch/gha-setup-ninja from 4 to 5 Bumps [seanmiddleditch/gha-setup-ninja](https://github.com/seanmiddleditch/gha-setup-ninja) from 4 to 5. - [Release notes](https://github.com/seanmiddleditch/gha-setup-ninja/releases) - [Commits](https://github.com/seanmiddleditch/gha-setup-ninja/compare/v4...v5) --- updated-dependencies: - dependency-name: seanmiddleditch/gha-setup-ninja dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a101a65..632bab0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: - name: Install ninja-build tool for aws-lc-fips-sys on Windows if: runner.os == 'Windows' - uses: seanmiddleditch/gha-setup-ninja@v4 + uses: seanmiddleditch/gha-setup-ninja@v5 - name: cargo check (default features) run: cargo check --all-targets From d07f3f521a6bc770e798e90e12db46c5bbd0e54d Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 26 Jul 2024 10:46:11 +0200 Subject: [PATCH 084/133] Bump MSRV to 1.70 (for tokio 1.39) --- .github/workflows/build.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 632bab0..a05d11b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,7 +103,7 @@ jobs: - name: Install rust toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "1.64" + toolchain: "1.70" - name: Check MSRV run: cargo check --lib --all-features diff --git a/Cargo.toml b/Cargo.toml index 5947756..b0b6557 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "hyper-rustls" version = "0.27.2" edition = "2021" -rust-version = "1.64" +rust-version = "1.70" license = "Apache-2.0 OR ISC OR MIT" readme = "README.md" description = "Rustls+hyper integration for pure rust HTTPS" From b4f51325a16181f6a335cb0fb3be76dea0fc31a2 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Thu, 29 Aug 2024 00:31:53 +0200 Subject: [PATCH 085/133] Add ConnectorBuilder::with_provider_and_platform_verifier Signed-off-by: Jens Reidel --- src/connector/builder.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/connector/builder.rs b/src/connector/builder.rs index b2858b9..d0167f8 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -1,7 +1,11 @@ use std::sync::Arc; use hyper_util::client::legacy::connect::HttpConnector; -#[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] +#[cfg(any( + feature = "rustls-native-certs", + feature = "rustls-platform-verifier", + feature = "webpki-roots" +))] use rustls::crypto::CryptoProvider; use rustls::ClientConfig; @@ -61,7 +65,8 @@ impl ConnectorBuilder { ConnectorBuilder(WantsSchemes { tls_config: config }) } - /// Use rustls' default crypto provider and other defaults, and the platform verifier + /// Shorthand for using rustls' default crypto provider and other defaults, and + /// the platform verifier. /// /// See [`ConfigBuilderExt::with_platform_verifier()`]. #[cfg(all( @@ -76,6 +81,23 @@ impl ConnectorBuilder { ) } + /// Shorthand for using a custom [`CryptoProvider`] and the platform verifier. + /// + /// See [`ConfigBuilderExt::with_platform_verifier()`]. + #[cfg(feature = "rustls-platform-verifier")] + pub fn with_provider_and_platform_verifier( + self, + provider: CryptoProvider, + ) -> std::io::Result> { + Ok(self.with_tls_config( + ClientConfig::builder_with_provider(provider.into()) + .with_safe_default_protocol_versions() + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))? + .with_platform_verifier() + .with_no_client_auth(), + )) + } + /// Shorthand for using rustls' default crypto provider and safe defaults, with /// native roots. /// From a6a5687ff79330388ff84694b67a7eed6b4e5c51 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Thu, 29 Aug 2024 00:36:28 +0200 Subject: [PATCH 086/133] Take impl Into> in connector builder This allows for calling the methods with Arc in a backwards-compatible way. Signed-off-by: Jens Reidel --- src/connector/builder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/connector/builder.rs b/src/connector/builder.rs index d0167f8..2e47df8 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -87,7 +87,7 @@ impl ConnectorBuilder { #[cfg(feature = "rustls-platform-verifier")] pub fn with_provider_and_platform_verifier( self, - provider: CryptoProvider, + provider: impl Into>, ) -> std::io::Result> { Ok(self.with_tls_config( ClientConfig::builder_with_provider(provider.into()) @@ -120,7 +120,7 @@ impl ConnectorBuilder { #[cfg(feature = "rustls-native-certs")] pub fn with_provider_and_native_roots( self, - provider: CryptoProvider, + provider: impl Into>, ) -> std::io::Result> { Ok(self.with_tls_config( ClientConfig::builder_with_provider(provider.into()) @@ -151,7 +151,7 @@ impl ConnectorBuilder { #[cfg(feature = "webpki-roots")] pub fn with_provider_and_webpki_roots( self, - provider: CryptoProvider, + provider: impl Into>, ) -> Result, rustls::Error> { Ok(self.with_tls_config( ClientConfig::builder_with_provider(provider.into()) From 1d57d93899df15bf106cc65315e803f632d41b1c Mon Sep 17 00:00:00 2001 From: Yin Jifeng Date: Thu, 11 Jul 2024 22:16:56 +0800 Subject: [PATCH 087/133] enable `rustls-platform-verifier` for docs.rs --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b0b6557..27eeb29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,5 +56,5 @@ required-features = ["aws-lc-rs"] [package.metadata.docs.rs] no-default-features = true -features = ["http1", "http2", "webpki-tokio", "native-tokio", "ring", "tls12", "logging"] +features = ["http1", "http2", "webpki-tokio", "native-tokio", "ring", "tls12", "logging", "rustls-platform-verifier"] rustdoc-args = ["--cfg", "docsrs"] From f8c203647b125a2cadd7a162fe17a4ae4fcf3d38 Mon Sep 17 00:00:00 2001 From: Yin Jifeng Date: Wed, 4 Sep 2024 09:51:10 +0800 Subject: [PATCH 088/133] chore: sort features --- Cargo.toml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 27eeb29..b877fea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,5 +56,14 @@ required-features = ["aws-lc-rs"] [package.metadata.docs.rs] no-default-features = true -features = ["http1", "http2", "webpki-tokio", "native-tokio", "ring", "tls12", "logging", "rustls-platform-verifier"] +features = [ + "http1", + "http2", + "logging", + "native-tokio", + "ring", + "rustls-platform-verifier", + "tls12", + "webpki-tokio", +] rustdoc-args = ["--cfg", "docsrs"] From 3a4d5d768476509815e8a74f15bc7a2dcadc8265 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 30 Aug 2024 11:06:17 +0200 Subject: [PATCH 089/133] Move features before dependencies --- Cargo.toml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b877fea..445b64e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,18 @@ homepage = "https://github.com/rustls/hyper-rustls" repository = "https://github.com/rustls/hyper-rustls" documentation = "https://docs.rs/hyper-rustls/" +[features] +default = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] +aws-lc-rs = ["rustls/aws_lc_rs"] +http1 = ["hyper-util/http1"] +http2 = ["hyper-util/http2"] +webpki-tokio = ["webpki-roots"] +native-tokio = ["rustls-native-certs"] +ring = ["rustls/ring"] +tls12 = ["tokio-rustls/tls12", "rustls/tls12"] +logging = ["log", "tokio-rustls/logging", "rustls/logging"] +fips = ["aws-lc-rs", "rustls/fips"] + [dependencies] http = "1" hyper = { version = "1", default-features = false } @@ -32,18 +44,6 @@ rustls = { version = "0.23", default-features = false, features = ["tls12"] } rustls-pemfile = "2" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } -[features] -default = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] -aws-lc-rs = ["rustls/aws_lc_rs"] -http1 = ["hyper-util/http1"] -http2 = ["hyper-util/http2"] -webpki-tokio = ["webpki-roots"] -native-tokio = ["rustls-native-certs"] -ring = ["rustls/ring"] -tls12 = ["tokio-rustls/tls12", "rustls/tls12"] -logging = ["log", "tokio-rustls/logging", "rustls/logging"] -fips = ["aws-lc-rs", "rustls/fips"] - [[example]] name = "client" path = "examples/client.rs" From 516e3ac78ae49961ca39b5f982bfbb12ef3f4ab9 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 2 Sep 2024 13:25:33 +0200 Subject: [PATCH 090/133] Alphabetically sort features --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 445b64e..c3fe177 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,14 +13,14 @@ documentation = "https://docs.rs/hyper-rustls/" [features] default = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] aws-lc-rs = ["rustls/aws_lc_rs"] +fips = ["aws-lc-rs", "rustls/fips"] http1 = ["hyper-util/http1"] http2 = ["hyper-util/http2"] -webpki-tokio = ["webpki-roots"] +logging = ["log", "tokio-rustls/logging", "rustls/logging"] native-tokio = ["rustls-native-certs"] ring = ["rustls/ring"] tls12 = ["tokio-rustls/tls12", "rustls/tls12"] -logging = ["log", "tokio-rustls/logging", "rustls/logging"] -fips = ["aws-lc-rs", "rustls/fips"] +webpki-tokio = ["webpki-roots"] [dependencies] http = "1" From 139550b4919786fd0ae474bff1ad9c840edf6f55 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 30 Aug 2024 11:02:23 +0200 Subject: [PATCH 091/133] Upgrade to rustls-native-certs 0.8 --- Cargo.toml | 2 +- src/config.rs | 18 ++++++++++++++++-- src/lib.rs | 6 ++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c3fe177..596a3f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ hyper = { version = "1", default-features = false } hyper-util = { version = "0.1", default-features = false, features = ["client-legacy", "tokio"] } log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "1" } -rustls-native-certs = { version = "0.7", optional = true } +rustls-native-certs = { version = "0.8", optional = true } rustls-platform-verifier = { version = "0.3", optional = true } rustls = { version = "0.23", default-features = false } tokio = "1.0" diff --git a/src/config.rs b/src/config.rs index 2af49c7..5010cae 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,6 +8,8 @@ use std::sync::Arc; ))] use rustls::client::WantsClientCert; use rustls::{ClientConfig, ConfigBuilder, WantsVerifier}; +#[cfg(feature = "rustls-native-certs")] +use rustls_native_certs::CertificateResult; /// Methods for configuring roots /// @@ -52,8 +54,19 @@ impl ConfigBuilderExt for ConfigBuilder { let mut valid_count = 0; let mut invalid_count = 0; - for cert in rustls_native_certs::load_native_certs().expect("could not load platform certs") - { + let CertificateResult { certs, errors, .. } = rustls_native_certs::load_native_certs(); + if !errors.is_empty() { + crate::log::warn!("native root CA certificate loading errors: {errors:?}"); + } + + if certs.is_empty() { + return Err(std::io::Error::new( + std::io::ErrorKind::NotFound, + format!("no native root CA certificates found (errors: {errors:?})"), + )); + } + + for cert in certs { match roots.add(cert) { Ok(_) => valid_count += 1, Err(err) => { @@ -62,6 +75,7 @@ impl ConfigBuilderExt for ConfigBuilder { } } } + crate::log::debug!( "with_native_roots processed {} valid and {} invalid certs", valid_count, diff --git a/src/lib.rs b/src/lib.rs index 1920e78..89e355a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,6 +43,8 @@ mod stream; mod log { #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] pub(crate) use log::debug; + #[cfg(feature = "rustls-native-certs")] + pub(crate) use log::warn; } #[cfg(not(feature = "logging"))] @@ -51,6 +53,10 @@ mod log { macro_rules! debug ( ($($tt:tt)*) => {{}} ); #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] pub(crate) use debug; + #[cfg(feature = "rustls-native-certs")] + macro_rules! warn_ ( ($($tt:tt)*) => {{}} ); + #[cfg(feature = "rustls-native-certs")] + pub(crate) use warn_ as warn; } pub use crate::config::ConfigBuilderExt; From 6d1267ce6d9d198a1f25769ac4ecea42bf75c321 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 30 Aug 2024 11:03:59 +0200 Subject: [PATCH 092/133] Avoid io::Result type alias --- src/config.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index 5010cae..735cad7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -30,7 +30,9 @@ pub trait ConfigBuilderExt { /// This will return an error if no valid certs were found. In that case, /// it's recommended to use `with_webpki_roots`. #[cfg(feature = "rustls-native-certs")] - fn with_native_roots(self) -> std::io::Result>; + fn with_native_roots( + self, + ) -> Result, std::io::Error>; /// This configures the webpki roots, which are Mozilla's set of /// trusted roots as packaged by webpki-roots. @@ -49,7 +51,9 @@ impl ConfigBuilderExt for ConfigBuilder { #[cfg(feature = "rustls-native-certs")] #[cfg_attr(not(feature = "logging"), allow(unused_variables))] - fn with_native_roots(self) -> std::io::Result> { + fn with_native_roots( + self, + ) -> Result, std::io::Error> { let mut roots = rustls::RootCertStore::empty(); let mut valid_count = 0; let mut invalid_count = 0; From a1d92635f65d60c33171ddcd88101427b1642d56 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 30 Aug 2024 11:05:40 +0200 Subject: [PATCH 093/133] Import std::io directly --- src/config.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/config.rs b/src/config.rs index 735cad7..13de77d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "rustls-native-certs")] +use std::io; #[cfg(feature = "rustls-platform-verifier")] use std::sync::Arc; @@ -30,9 +32,7 @@ pub trait ConfigBuilderExt { /// This will return an error if no valid certs were found. In that case, /// it's recommended to use `with_webpki_roots`. #[cfg(feature = "rustls-native-certs")] - fn with_native_roots( - self, - ) -> Result, std::io::Error>; + fn with_native_roots(self) -> Result, io::Error>; /// This configures the webpki roots, which are Mozilla's set of /// trusted roots as packaged by webpki-roots. @@ -51,9 +51,7 @@ impl ConfigBuilderExt for ConfigBuilder { #[cfg(feature = "rustls-native-certs")] #[cfg_attr(not(feature = "logging"), allow(unused_variables))] - fn with_native_roots( - self, - ) -> Result, std::io::Error> { + fn with_native_roots(self) -> Result, io::Error> { let mut roots = rustls::RootCertStore::empty(); let mut valid_count = 0; let mut invalid_count = 0; @@ -64,8 +62,8 @@ impl ConfigBuilderExt for ConfigBuilder { } if certs.is_empty() { - return Err(std::io::Error::new( - std::io::ErrorKind::NotFound, + return Err(io::Error::new( + io::ErrorKind::NotFound, format!("no native root CA certificates found (errors: {errors:?})"), )); } @@ -87,8 +85,8 @@ impl ConfigBuilderExt for ConfigBuilder { ); if roots.is_empty() { crate::log::debug!("no valid native root CA certificates found"); - Err(std::io::Error::new( - std::io::ErrorKind::NotFound, + Err(io::Error::new( + io::ErrorKind::NotFound, format!("no valid native root CA certificates found ({invalid_count} invalid)"), ))? } From dc54bc01f345e409137f43587c2a9cc6e50c988c Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 30 Aug 2024 11:07:10 +0200 Subject: [PATCH 094/133] Bump version to 0.27.3 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 596a3f2..b8b1c10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" edition = "2021" rust-version = "1.70" license = "Apache-2.0 OR ISC OR MIT" From 4d5fe9a608a85b17acfe9fdddeca7509bb349320 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 20 Sep 2024 10:13:12 -0400 Subject: [PATCH 095/133] perf: forward write-vectored calls --- src/stream.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/stream.rs b/src/stream.rs index 9f017bc..f08e7b1 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -98,4 +98,24 @@ impl rt::Write for MaybeHttpsStream { Self::Https(s) => Pin::new(s).poll_shutdown(cx), } } + + #[inline] + fn is_write_vectored(&self) -> bool { + match self { + Self::Http(s) => s.is_write_vectored(), + Self::Https(s) => s.is_write_vectored(), + } + } + + #[inline] + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[io::IoSlice<'_>], + ) -> Poll> { + match Pin::get_mut(self) { + Self::Http(s) => Pin::new(s).poll_write_vectored(cx, bufs), + Self::Https(s) => Pin::new(s).poll_write_vectored(cx, bufs), + } + } } From 51a284650efd2f2696858a231543eb33b30a2c8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 19:27:37 +0000 Subject: [PATCH 096/133] Update rustls-platform-verifier requirement from 0.3 to 0.4 Updates the requirements on [rustls-platform-verifier](https://github.com/rustls/rustls-platform-verifier) to permit the latest version. - [Release notes](https://github.com/rustls/rustls-platform-verifier/releases) - [Changelog](https://github.com/rustls/rustls-platform-verifier/blob/main/CHANGELOG) - [Commits](https://github.com/rustls/rustls-platform-verifier/compare/v/0.3.0...v/0.4.0) --- updated-dependencies: - dependency-name: rustls-platform-verifier dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b8b1c10..61d53ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ hyper-util = { version = "0.1", default-features = false, features = ["client-le log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "1" } rustls-native-certs = { version = "0.8", optional = true } -rustls-platform-verifier = { version = "0.3", optional = true } +rustls-platform-verifier = { version = "0.4", optional = true } rustls = { version = "0.23", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.26", default-features = false } From 03fe2dbbc8b08b4e6bdf654c1d969cfa85134a34 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 22 Nov 2024 10:18:18 +0100 Subject: [PATCH 097/133] Bump MSRV to 1.71 to match other crates --- .github/workflows/build.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a05d11b..2486957 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,7 +103,7 @@ jobs: - name: Install rust toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "1.70" + toolchain: "1.71" - name: Check MSRV run: cargo check --lib --all-features diff --git a/Cargo.toml b/Cargo.toml index 61d53ce..21f818b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "hyper-rustls" version = "0.27.3" edition = "2021" -rust-version = "1.70" +rust-version = "1.71" license = "Apache-2.0 OR ISC OR MIT" readme = "README.md" description = "Rustls+hyper integration for pure rust HTTPS" From cbf6c967cc7f59bf4cd28d507ddc15294771f719 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Thu, 28 Nov 2024 15:14:37 -0500 Subject: [PATCH 098/133] tests: fix clippy::zombie_processes findings of the form: ``` error: spawned process is never `wait()`ed on --> tests/tests.rs:47:19 | 47 | let mut srv = server_command() | ___________________^ 48 | | .arg("1337") 49 | | .spawn() 50 | | .expect("cannot run server example"); | |____________________________________________^ | = note: consider calling `.wait()` = note: not doing so might leave behind zombie processes = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#zombie_processes = note: `-D clippy::zombie-processes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::zombie_processes)]` ``` --- tests/tests.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/tests.rs b/tests/tests.rs index 6730a28..91572bc 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -60,6 +60,8 @@ fn server() { .expect("cannot run curl"); srv.kill().unwrap(); + srv.wait() + .expect("failed to wait on server process"); if !output.status.success() { let version_stdout = Command::new("curl") @@ -91,6 +93,8 @@ fn custom_ca_store() { .expect("cannot run client example"); srv.kill().unwrap(); + srv.wait() + .expect("failed to wait on server process"); if !rc.status.success() { assert_eq!(String::from_utf8_lossy(&rc.stdout), ""); From fb8df676ce938a7e4c1bead87dc52c694a9f9f0d Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Tue, 17 Dec 2024 19:19:18 +0100 Subject: [PATCH 099/133] Actually use configured crypto provider for the platform verifier Signed-off-by: Jens Reidel --- src/config.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 13de77d..2179d5b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -43,9 +43,10 @@ pub trait ConfigBuilderExt { impl ConfigBuilderExt for ConfigBuilder { #[cfg(feature = "rustls-platform-verifier")] fn with_platform_verifier(self) -> ConfigBuilder { + let provider = self.crypto_provider().clone(); self.dangerous() .with_custom_certificate_verifier(Arc::new( - rustls_platform_verifier::Verifier::default(), + rustls_platform_verifier::Verifier::new().with_provider(provider), )) } From b82a8691dadea3c6568a78c32febb78ef67e304c Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Tue, 17 Dec 2024 19:57:02 +0100 Subject: [PATCH 100/133] Bump version to 0.27.4 Signed-off-by: Jens Reidel --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 21f818b..4b42025 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.27.3" +version = "0.27.4" edition = "2021" rust-version = "1.71" license = "Apache-2.0 OR ISC OR MIT" From 1b7d8cf4ff30fc04e915d8eaf11cc3299f179917 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 18 Dec 2024 10:14:33 +0100 Subject: [PATCH 101/133] Upgrade to rustls-platform-verifier 0.5 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4b42025..a1829a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ hyper-util = { version = "0.1", default-features = false, features = ["client-le log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "1" } rustls-native-certs = { version = "0.8", optional = true } -rustls-platform-verifier = { version = "0.4", optional = true } +rustls-platform-verifier = { version = "0.5", optional = true } rustls = { version = "0.23", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.26", default-features = false } From ac873442832d91b785d0945e87226095812e6d7f Mon Sep 17 00:00:00 2001 From: Saleem Rashid Date: Wed, 18 Dec 2024 23:41:52 +0000 Subject: [PATCH 102/133] Fix https_only/enforce_https enforcement --- src/connector.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/src/connector.rs b/src/connector.rs index 02a29a8..f4eeea2 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -69,7 +69,7 @@ where // dst.scheme() would need to derive Eq to be matchable; // use an if cascade instead match dst.scheme() { - Some(scheme) if scheme == &http::uri::Scheme::HTTP => { + Some(scheme) if scheme == &http::uri::Scheme::HTTP && !self.force_https => { let future = self.http.call(dst); return Box::pin(async move { Ok(MaybeHttpsStream::Http(future.await.map_err(Into::into)?)) @@ -199,3 +199,104 @@ pub trait ResolveServerName { uri: &Uri, ) -> Result, Box>; } + +#[cfg(all( + test, + any(feature = "ring", feature = "aws-lc-rs"), + any( + feature = "rustls-native-certs", + feature = "webpki-roots", + feature = "rustls-platform-verifier", + ) +))] +mod tests { + use std::future::poll_fn; + + use http::Uri; + use hyper_util::client::legacy::connect::HttpConnector; + use tower_service::Service; + + use super::HttpsConnector; + use crate::{ConfigBuilderExt, HttpsConnectorBuilder}; + + fn tls_config() -> rustls::ClientConfig { + #[cfg(feature = "rustls-native-certs")] + return rustls::ClientConfig::builder() + .with_native_roots() + .unwrap() + .with_no_client_auth(); + + #[cfg(feature = "webpki-roots")] + return rustls::ClientConfig::builder() + .with_webpki_roots() + .with_no_client_auth(); + + #[cfg(feature = "rustls-platform-verifier")] + return rustls::ClientConfig::builder() + .with_platform_verifier() + .with_no_client_auth(); + } + + fn https_or_http_connector() -> HttpsConnector { + HttpsConnectorBuilder::new() + .with_tls_config(tls_config()) + .https_or_http() + .enable_http1() + .build() + } + + fn https_only_connector() -> HttpsConnector { + HttpsConnectorBuilder::new() + .with_tls_config(tls_config()) + .https_only() + .enable_http1() + .build() + } + + async fn oneshot(mut service: S, req: Req) -> Result + where + S: Service, + { + poll_fn(|cx| service.poll_ready(cx)).await?; + service.call(req).await + } + + fn https_uri() -> Uri { + Uri::from_static("https://google.com") + } + + fn http_uri() -> Uri { + Uri::from_static("http://google.com") + } + + #[tokio::test] + async fn connects_https() { + oneshot(https_or_http_connector(), https_uri()) + .await + .unwrap(); + } + + #[tokio::test] + async fn connects_http() { + oneshot(https_or_http_connector(), http_uri()) + .await + .unwrap(); + } + + #[tokio::test] + async fn connects_https_only() { + oneshot(https_only_connector(), https_uri()) + .await + .unwrap(); + } + + #[tokio::test] + async fn enforces_https_only() { + let message = oneshot(https_only_connector(), http_uri()) + .await + .unwrap_err() + .to_string(); + + assert_eq!(message, "unsupported scheme http"); + } +} From 985f32320492b4efd9ae15ae1f5c7f640878d66c Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 20 Dec 2024 09:11:01 +0100 Subject: [PATCH 103/133] Re-order verifier options --- src/connector.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index f4eeea2..28bcd21 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -220,6 +220,11 @@ mod tests { use crate::{ConfigBuilderExt, HttpsConnectorBuilder}; fn tls_config() -> rustls::ClientConfig { + #[cfg(feature = "rustls-platform-verifier")] + return rustls::ClientConfig::builder() + .with_platform_verifier() + .with_no_client_auth(); + #[cfg(feature = "rustls-native-certs")] return rustls::ClientConfig::builder() .with_native_roots() @@ -230,11 +235,6 @@ mod tests { return rustls::ClientConfig::builder() .with_webpki_roots() .with_no_client_auth(); - - #[cfg(feature = "rustls-platform-verifier")] - return rustls::ClientConfig::builder() - .with_platform_verifier() - .with_no_client_auth(); } fn https_or_http_connector() -> HttpsConnector { From 5669885e6333ac23e9266a309f65def50a9387fa Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 20 Dec 2024 09:14:12 +0100 Subject: [PATCH 104/133] Re-order test module items --- src/connector.rs | 90 ++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 28bcd21..cac175b 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -219,22 +219,35 @@ mod tests { use super::HttpsConnector; use crate::{ConfigBuilderExt, HttpsConnectorBuilder}; - fn tls_config() -> rustls::ClientConfig { - #[cfg(feature = "rustls-platform-verifier")] - return rustls::ClientConfig::builder() - .with_platform_verifier() - .with_no_client_auth(); + #[tokio::test] + async fn connects_https() { + oneshot(https_or_http_connector(), https_uri()) + .await + .unwrap(); + } - #[cfg(feature = "rustls-native-certs")] - return rustls::ClientConfig::builder() - .with_native_roots() - .unwrap() - .with_no_client_auth(); + #[tokio::test] + async fn connects_http() { + oneshot(https_or_http_connector(), http_uri()) + .await + .unwrap(); + } - #[cfg(feature = "webpki-roots")] - return rustls::ClientConfig::builder() - .with_webpki_roots() - .with_no_client_auth(); + #[tokio::test] + async fn connects_https_only() { + oneshot(https_only_connector(), https_uri()) + .await + .unwrap(); + } + + #[tokio::test] + async fn enforces_https_only() { + let message = oneshot(https_only_connector(), http_uri()) + .await + .unwrap_err() + .to_string(); + + assert_eq!(message, "unsupported scheme http"); } fn https_or_http_connector() -> HttpsConnector { @@ -253,6 +266,24 @@ mod tests { .build() } + fn tls_config() -> rustls::ClientConfig { + #[cfg(feature = "rustls-platform-verifier")] + return rustls::ClientConfig::builder() + .with_platform_verifier() + .with_no_client_auth(); + + #[cfg(feature = "rustls-native-certs")] + return rustls::ClientConfig::builder() + .with_native_roots() + .unwrap() + .with_no_client_auth(); + + #[cfg(feature = "webpki-roots")] + return rustls::ClientConfig::builder() + .with_webpki_roots() + .with_no_client_auth(); + } + async fn oneshot(mut service: S, req: Req) -> Result where S: Service, @@ -268,35 +299,4 @@ mod tests { fn http_uri() -> Uri { Uri::from_static("http://google.com") } - - #[tokio::test] - async fn connects_https() { - oneshot(https_or_http_connector(), https_uri()) - .await - .unwrap(); - } - - #[tokio::test] - async fn connects_http() { - oneshot(https_or_http_connector(), http_uri()) - .await - .unwrap(); - } - - #[tokio::test] - async fn connects_https_only() { - oneshot(https_only_connector(), https_uri()) - .await - .unwrap(); - } - - #[tokio::test] - async fn enforces_https_only() { - let message = oneshot(https_only_connector(), http_uri()) - .await - .unwrap_err() - .to_string(); - - assert_eq!(message, "unsupported scheme http"); - } } From 515822c2dce2bb9e328603ae3786759b6913a5e3 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 20 Dec 2024 09:19:45 +0100 Subject: [PATCH 105/133] tests: use concrete type for helper function --- src/connector.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index cac175b..bbb8919 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -284,10 +284,7 @@ mod tests { .with_no_client_auth(); } - async fn oneshot(mut service: S, req: Req) -> Result - where - S: Service, - { + async fn oneshot>(mut service: S, req: Uri) -> Result { poll_fn(|cx| service.poll_ready(cx)).await?; service.call(req).await } From a38dfaec6b59a882180e4742ad91dc89af3cf2ce Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 20 Dec 2024 09:15:15 +0100 Subject: [PATCH 106/133] tests: inline trivial helper functions --- src/connector.rs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index bbb8919..b023214 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -221,28 +221,28 @@ mod tests { #[tokio::test] async fn connects_https() { - oneshot(https_or_http_connector(), https_uri()) + oneshot(https_or_http_connector(), Scheme::Https) .await .unwrap(); } #[tokio::test] async fn connects_http() { - oneshot(https_or_http_connector(), http_uri()) + oneshot(https_or_http_connector(), Scheme::Http) .await .unwrap(); } #[tokio::test] async fn connects_https_only() { - oneshot(https_only_connector(), https_uri()) + oneshot(https_only_connector(), Scheme::Https) .await .unwrap(); } #[tokio::test] async fn enforces_https_only() { - let message = oneshot(https_only_connector(), http_uri()) + let message = oneshot(https_only_connector(), Scheme::Http) .await .unwrap_err() .to_string(); @@ -284,16 +284,21 @@ mod tests { .with_no_client_auth(); } - async fn oneshot>(mut service: S, req: Uri) -> Result { + async fn oneshot>( + mut service: S, + scheme: Scheme, + ) -> Result { poll_fn(|cx| service.poll_ready(cx)).await?; - service.call(req).await - } - - fn https_uri() -> Uri { - Uri::from_static("https://google.com") + service + .call(Uri::from_static(match scheme { + Scheme::Https => "https://google.com", + Scheme::Http => "http://google.com", + })) + .await } - fn http_uri() -> Uri { - Uri::from_static("http://google.com") + enum Scheme { + Https, + Http, } } From 4d0a441d7c193af2fc046999b0a5a6b966d193dc Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 20 Dec 2024 09:29:58 +0100 Subject: [PATCH 107/133] tests: inline connector setup --- src/connector.rs | 50 +++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index b023214..96369d8 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -213,36 +213,37 @@ mod tests { use std::future::poll_fn; use http::Uri; - use hyper_util::client::legacy::connect::HttpConnector; + use hyper_util::rt::TokioIo; + use tokio::net::TcpStream; use tower_service::Service; - use super::HttpsConnector; - use crate::{ConfigBuilderExt, HttpsConnectorBuilder}; + use super::*; + use crate::{ConfigBuilderExt, HttpsConnectorBuilder, MaybeHttpsStream}; #[tokio::test] async fn connects_https() { - oneshot(https_or_http_connector(), Scheme::Https) + connect(Allow::Any, Scheme::Https) .await .unwrap(); } #[tokio::test] async fn connects_http() { - oneshot(https_or_http_connector(), Scheme::Http) + connect(Allow::Any, Scheme::Http) .await .unwrap(); } #[tokio::test] async fn connects_https_only() { - oneshot(https_only_connector(), Scheme::Https) + connect(Allow::Https, Scheme::Https) .await .unwrap(); } #[tokio::test] async fn enforces_https_only() { - let message = oneshot(https_only_connector(), Scheme::Http) + let message = connect(Allow::Https, Scheme::Http) .await .unwrap_err() .to_string(); @@ -250,22 +251,6 @@ mod tests { assert_eq!(message, "unsupported scheme http"); } - fn https_or_http_connector() -> HttpsConnector { - HttpsConnectorBuilder::new() - .with_tls_config(tls_config()) - .https_or_http() - .enable_http1() - .build() - } - - fn https_only_connector() -> HttpsConnector { - HttpsConnectorBuilder::new() - .with_tls_config(tls_config()) - .https_only() - .enable_http1() - .build() - } - fn tls_config() -> rustls::ClientConfig { #[cfg(feature = "rustls-platform-verifier")] return rustls::ClientConfig::builder() @@ -284,10 +269,18 @@ mod tests { .with_no_client_auth(); } - async fn oneshot>( - mut service: S, + async fn connect( + allow: Allow, scheme: Scheme, - ) -> Result { + ) -> Result>, BoxError> { + let builder = HttpsConnectorBuilder::new().with_tls_config(tls_config()); + let mut service = match allow { + Allow::Https => builder.https_only(), + Allow::Any => builder.https_or_http(), + } + .enable_http1() + .build(); + poll_fn(|cx| service.poll_ready(cx)).await?; service .call(Uri::from_static(match scheme { @@ -297,6 +290,11 @@ mod tests { .await } + enum Allow { + Https, + Any, + } + enum Scheme { Https, Http, From ae297aae5800e20420133b562238a6101aacb237 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 20 Dec 2024 09:32:42 +0100 Subject: [PATCH 108/133] tests: inline tls_config() helper And avoid unused code warnings for redundant verifier configs. --- Cargo.toml | 1 + src/connector.rs | 32 +++++++++++++------------------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a1829a3..c971434 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ webpki-roots = { version = "0.26", optional = true } futures-util = { version = "0.3", default-features = false } [dev-dependencies] +cfg-if = "1" http-body-util = "0.1" hyper-util = { version = "0.1", default-features = false, features = ["server-auto"] } rustls = { version = "0.23", default-features = false, features = ["tls12"] } diff --git a/src/connector.rs b/src/connector.rs index 96369d8..0ca5c5e 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -251,29 +251,23 @@ mod tests { assert_eq!(message, "unsupported scheme http"); } - fn tls_config() -> rustls::ClientConfig { - #[cfg(feature = "rustls-platform-verifier")] - return rustls::ClientConfig::builder() - .with_platform_verifier() - .with_no_client_auth(); - - #[cfg(feature = "rustls-native-certs")] - return rustls::ClientConfig::builder() - .with_native_roots() - .unwrap() - .with_no_client_auth(); - - #[cfg(feature = "webpki-roots")] - return rustls::ClientConfig::builder() - .with_webpki_roots() - .with_no_client_auth(); - } - async fn connect( allow: Allow, scheme: Scheme, ) -> Result>, BoxError> { - let builder = HttpsConnectorBuilder::new().with_tls_config(tls_config()); + let config_builder = rustls::ClientConfig::builder(); + cfg_if::cfg_if! { + if #[cfg(feature = "rustls-platform-verifier")] { + let config_builder = config_builder.with_platform_verifier(); + } else if #[cfg(feature = "rustls-native-certs")] { + let config_builder = config_builder.with_native_roots().unwrap(); + } else if #[cfg(feature = "webpki-roots")] { + let config_builder = config_builder.with_webpki_roots(); + } + } + let config = config_builder.with_no_client_auth(); + + let builder = HttpsConnectorBuilder::new().with_tls_config(config); let mut service = match allow { Allow::Https => builder.https_only(), Allow::Any => builder.https_or_http(), From 426c0a7091b8ca4a938440fdb527c5a37e53a5ab Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 20 Dec 2024 09:33:43 +0100 Subject: [PATCH 109/133] Bump version to 0.27.5 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c971434..1003d82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.27.4" +version = "0.27.5" edition = "2021" rust-version = "1.71" license = "Apache-2.0 OR ISC OR MIT" From 8f9728a8cb9b5c52b0ef23169dd968e98b8ef42a Mon Sep 17 00:00:00 2001 From: Paolo Barbolini Date: Sun, 16 Feb 2025 17:15:55 +0100 Subject: [PATCH 110/133] build: drop unused dependency on `futures-util` --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1003d82..8d081cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ tokio = "1.0" tokio-rustls = { version = "0.26", default-features = false } tower-service = "0.3" webpki-roots = { version = "0.26", optional = true } -futures-util = { version = "0.3", default-features = false } [dev-dependencies] cfg-if = "1" From 76d427f142f403558b59d172911dd82ec8a91c47 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Thu, 22 May 2025 13:18:28 +0200 Subject: [PATCH 111/133] Upgrade webpki-roots to 1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8d081cd..477227d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ rustls = { version = "0.23", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.26", default-features = false } tower-service = "0.3" -webpki-roots = { version = "0.26", optional = true } +webpki-roots = { version = "1", optional = true } [dev-dependencies] cfg-if = "1" From e6a23710aa02b81ccf03d54801df8faace53eb68 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Thu, 22 May 2025 13:18:46 +0200 Subject: [PATCH 112/133] Bump version to 0.27.6 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 477227d..6986222 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.27.5" +version = "0.27.6" edition = "2021" rust-version = "1.71" license = "Apache-2.0 OR ISC OR MIT" From 3b2997abc8bbfe200478341c604fd19b9a2fb0de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:56:13 +0000 Subject: [PATCH 113/133] Bump seanmiddleditch/gha-setup-ninja from 5 to 6 Bumps [seanmiddleditch/gha-setup-ninja](https://github.com/seanmiddleditch/gha-setup-ninja) from 5 to 6. - [Release notes](https://github.com/seanmiddleditch/gha-setup-ninja/releases) - [Commits](https://github.com/seanmiddleditch/gha-setup-ninja/compare/v5...v6) --- updated-dependencies: - dependency-name: seanmiddleditch/gha-setup-ninja dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2486957..19f9672 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: - name: Install ninja-build tool for aws-lc-fips-sys on Windows if: runner.os == 'Windows' - uses: seanmiddleditch/gha-setup-ninja@v5 + uses: seanmiddleditch/gha-setup-ninja@v6 - name: cargo check (default features) run: cargo check --all-targets From 6931bc43a9d5644298ea10a1065b9269b605ad33 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 6 Jun 2025 11:06:29 +0200 Subject: [PATCH 114/133] Seal ConfigBuilderExt extension trait This is technically semver-breaking, but we think it's unlikely that anyone has actually implemented the trait. --- src/config.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 2179d5b..41e0e30 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,7 +17,7 @@ use rustls_native_certs::CertificateResult; /// /// This adds methods (gated by crate features) for easily configuring /// TLS server roots a rustls ClientConfig will trust. -pub trait ConfigBuilderExt { +pub trait ConfigBuilderExt: sealed::Sealed { /// Use the platform's native verifier to verify server certificates. /// /// See the documentation for [rustls-platform-verifier] for more details. @@ -106,3 +106,11 @@ impl ConfigBuilderExt for ConfigBuilder { self.with_root_certificates(roots) } } + +mod sealed { + use super::*; + + pub trait Sealed {} + + impl Sealed for ConfigBuilder {} +} From aff7441ec40be7c334886f8807f32cccecb5adbe Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Thu, 5 Jun 2025 14:45:15 +0200 Subject: [PATCH 115/133] Upgrade to rustls-platform-verifier 0.6 --- Cargo.toml | 4 ++-- src/config.rs | 34 +++++++++++++++++++++++++++------- src/connector.rs | 2 +- src/connector/builder.rs | 23 +++++++++++++++++++---- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6986222..cf10f44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyper-rustls" -version = "0.27.6" +version = "0.27.7" edition = "2021" rust-version = "1.71" license = "Apache-2.0 OR ISC OR MIT" @@ -29,7 +29,7 @@ hyper-util = { version = "0.1", default-features = false, features = ["client-le log = { version = "0.4.4", optional = true } pki-types = { package = "rustls-pki-types", version = "1" } rustls-native-certs = { version = "0.8", optional = true } -rustls-platform-verifier = { version = "0.5", optional = true } +rustls-platform-verifier = { version = "0.6", optional = true } rustls = { version = "0.23", default-features = false } tokio = "1.0" tokio-rustls = { version = "0.26", default-features = false } diff --git a/src/config.rs b/src/config.rs index 41e0e30..3838261 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,5 @@ #[cfg(feature = "rustls-native-certs")] use std::io; -#[cfg(feature = "rustls-platform-verifier")] -use std::sync::Arc; #[cfg(any( feature = "rustls-platform-verifier", @@ -12,6 +10,8 @@ use rustls::client::WantsClientCert; use rustls::{ClientConfig, ConfigBuilder, WantsVerifier}; #[cfg(feature = "rustls-native-certs")] use rustls_native_certs::CertificateResult; +#[cfg(feature = "rustls-platform-verifier")] +use rustls_platform_verifier::BuilderVerifierExt; /// Methods for configuring roots /// @@ -22,10 +22,26 @@ pub trait ConfigBuilderExt: sealed::Sealed { /// /// See the documentation for [rustls-platform-verifier] for more details. /// + /// # Panics + /// + /// Since 0.27.7, this method will panic if the platform verifier cannot be initialized. + /// Use `try_with_platform_verifier()` instead to handle errors gracefully. + /// /// [rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier + #[deprecated(since = "0.27.7", note = "use `try_with_platform_verifier` instead")] #[cfg(feature = "rustls-platform-verifier")] fn with_platform_verifier(self) -> ConfigBuilder; + /// Use the platform's native verifier to verify server certificates. + /// + /// See the documentation for [rustls-platform-verifier] for more details. + /// + /// [rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier + #[cfg(feature = "rustls-platform-verifier")] + fn try_with_platform_verifier( + self, + ) -> Result, rustls::Error>; + /// This configures the platform's trusted certs, as implemented by /// rustls-native-certs /// @@ -43,11 +59,15 @@ pub trait ConfigBuilderExt: sealed::Sealed { impl ConfigBuilderExt for ConfigBuilder { #[cfg(feature = "rustls-platform-verifier")] fn with_platform_verifier(self) -> ConfigBuilder { - let provider = self.crypto_provider().clone(); - self.dangerous() - .with_custom_certificate_verifier(Arc::new( - rustls_platform_verifier::Verifier::new().with_provider(provider), - )) + self.try_with_platform_verifier() + .expect("failure to initialize platform verifier") + } + + #[cfg(feature = "rustls-platform-verifier")] + fn try_with_platform_verifier( + self, + ) -> Result, rustls::Error> { + BuilderVerifierExt::with_platform_verifier(self) } #[cfg(feature = "rustls-native-certs")] diff --git a/src/connector.rs b/src/connector.rs index 0ca5c5e..f8abe45 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -258,7 +258,7 @@ mod tests { let config_builder = rustls::ClientConfig::builder(); cfg_if::cfg_if! { if #[cfg(feature = "rustls-platform-verifier")] { - let config_builder = config_builder.with_platform_verifier(); + let config_builder = config_builder.try_with_platform_verifier()?; } else if #[cfg(feature = "rustls-native-certs")] { let config_builder = config_builder.with_native_roots().unwrap(); } else if #[cfg(feature = "webpki-roots")] { diff --git a/src/connector/builder.rs b/src/connector/builder.rs index 2e47df8..417d130 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -74,11 +74,26 @@ impl ConnectorBuilder { feature = "rustls-platform-verifier" ))] pub fn with_platform_verifier(self) -> ConnectorBuilder { - self.with_tls_config( + self.try_with_platform_verifier() + .expect("failure to initialize platform verifier") + } + + /// Shorthand for using rustls' default crypto provider and other defaults, and + /// the platform verifier. + /// + /// See [`ConfigBuilderExt::with_platform_verifier()`]. + #[cfg(all( + any(feature = "ring", feature = "aws-lc-rs"), + feature = "rustls-platform-verifier" + ))] + pub fn try_with_platform_verifier( + self, + ) -> Result, rustls::Error> { + Ok(self.with_tls_config( ClientConfig::builder() - .with_platform_verifier() + .try_with_platform_verifier()? .with_no_client_auth(), - ) + )) } /// Shorthand for using a custom [`CryptoProvider`] and the platform verifier. @@ -92,8 +107,8 @@ impl ConnectorBuilder { Ok(self.with_tls_config( ClientConfig::builder_with_provider(provider.into()) .with_safe_default_protocol_versions() + .and_then(|builder| builder.try_with_platform_verifier()) .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))? - .with_platform_verifier() .with_no_client_auth(), )) } From a322abaf05f28593b76814c62e9317df4c4df3ab Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 27 Jun 2025 09:27:17 +0200 Subject: [PATCH 116/133] Apply suggestions from clippy 1.88 --- examples/client.rs | 12 ++++++------ examples/server.rs | 12 ++++++------ src/config.rs | 6 ++---- tests/tests.rs | 6 +++--- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/examples/client.rs b/examples/client.rs index c45bc2a..71c6888 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -15,7 +15,7 @@ use std::{env, fs, io}; fn main() { // Send GET request and inspect result, with proper error handling. if let Err(e) = run_client() { - eprintln!("FAILED: {}", e); + eprintln!("FAILED: {e}"); std::process::exit(1); } } @@ -34,7 +34,7 @@ async fn run_client() -> io::Result<()> { // First parameter is target URL (mandatory). let url = match env::args().nth(1) { - Some(ref url) => Uri::from_str(url).map_err(|e| error(format!("{}", e)))?, + Some(ref url) => Uri::from_str(url).map_err(|e| error(format!("{e}")))?, None => { println!("Usage: client "); return Ok(()); @@ -44,8 +44,8 @@ async fn run_client() -> io::Result<()> { // Second parameter is custom Root-CA store (optional, defaults to native cert store). let mut ca = match env::args().nth(2) { Some(ref path) => { - let f = fs::File::open(path) - .map_err(|e| error(format!("failed to open {}: {}", path, e)))?; + let f = + fs::File::open(path).map_err(|e| error(format!("failed to open {path}: {e}")))?; let rd = io::BufReader::new(f); Some(rd) } @@ -86,7 +86,7 @@ async fn run_client() -> io::Result<()> { let res = client .get(url) .await - .map_err(|e| error(format!("Could not get: {:?}", e)))?; + .map_err(|e| error(format!("Could not get: {e:?}")))?; println!("Status:\n{}", res.status()); println!("Headers:\n{:#?}", res.headers()); @@ -94,7 +94,7 @@ async fn run_client() -> io::Result<()> { .into_body() .collect() .await - .map_err(|e| error(format!("Could not get body: {:?}", e)))? + .map_err(|e| error(format!("Could not get body: {e:?}")))? .to_bytes(); println!("Body:\n{}", String::from_utf8_lossy(&body)); diff --git a/examples/server.rs b/examples/server.rs index 8f7803f..6cbcf45 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -23,7 +23,7 @@ use tokio_rustls::TlsAcceptor; fn main() { // Serve an echo service over HTTPS, with proper error handling. if let Err(e) = run_server() { - eprintln!("FAILED: {}", e); + eprintln!("FAILED: {e}"); std::process::exit(1); } } @@ -52,7 +52,7 @@ async fn run_server() -> Result<(), Box> { // Load private key. let key = load_private_key("examples/sample.rsa")?; - println!("Starting to serve on https://{}", addr); + println!("Starting to serve on https://{addr}"); // Create a TCP listener via tokio. let incoming = TcpListener::bind(&addr).await?; @@ -118,8 +118,8 @@ async fn echo(req: Request) -> Result>, hyper::Er // Load public certificate from file. fn load_certs(filename: &str) -> io::Result>> { // Open certificate file. - let certfile = fs::File::open(filename) - .map_err(|e| error(format!("failed to open {}: {}", filename, e)))?; + let certfile = + fs::File::open(filename).map_err(|e| error(format!("failed to open {filename}: {e}")))?; let mut reader = io::BufReader::new(certfile); // Load and return certificate. @@ -129,8 +129,8 @@ fn load_certs(filename: &str) -> io::Result>> { // Load private key from file. fn load_private_key(filename: &str) -> io::Result> { // Open keyfile. - let keyfile = fs::File::open(filename) - .map_err(|e| error(format!("failed to open {}: {}", filename, e)))?; + let keyfile = + fs::File::open(filename).map_err(|e| error(format!("failed to open {filename}: {e}")))?; let mut reader = io::BufReader::new(keyfile); // Load and return a single private key. diff --git a/src/config.rs b/src/config.rs index 3838261..db911b7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -93,16 +93,14 @@ impl ConfigBuilderExt for ConfigBuilder { match roots.add(cert) { Ok(_) => valid_count += 1, Err(err) => { - crate::log::debug!("certificate parsing failed: {:?}", err); + crate::log::debug!("certificate parsing failed: {err:?}"); invalid_count += 1 } } } crate::log::debug!( - "with_native_roots processed {} valid and {} invalid certs", - valid_count, - invalid_count + "with_native_roots processed {valid_count} valid and {invalid_count} invalid certs" ); if roots.is_empty() { crate::log::debug!("no valid native root CA certificates found"); diff --git a/tests/tests.rs b/tests/tests.rs index 91572bc..9e59038 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -29,7 +29,7 @@ fn wait_for_server(addr: &str) { } thread::sleep(time::Duration::from_millis(i * 100)); } - panic!("failed to connect to {:?} after 10 tries", addr); + panic!("failed to connect to {addr:?} after 10 tries"); } #[test] @@ -55,7 +55,7 @@ fn server() { let output = Command::new("curl") .arg("--insecure") .arg("--http1.0") - .arg(format!("https://{}", addr)) + .arg(format!("https://{addr}")) .output() .expect("cannot run curl"); @@ -87,7 +87,7 @@ fn custom_ca_store() { wait_for_server(addr); let rc = client_command() - .arg(format!("https://{}", addr)) + .arg(format!("https://{addr}")) .arg("examples/sample.pem") .output() .expect("cannot run client example"); From 6d3e00b99487cdcdc9b42d353cd19f909802a42d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 02:21:04 +0000 Subject: [PATCH 117/133] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19f9672..ac97477 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: rust: stable steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -96,7 +96,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -113,7 +113,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -125,7 +125,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -143,7 +143,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Install rust toolchain @@ -158,7 +158,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Install rust toolchain @@ -171,7 +171,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Install rust toolchain From 5e9b69b4128abfc147e8b6fa55977eac4c3f575c Mon Sep 17 00:00:00 2001 From: Markus Probst Date: Fri, 6 Jun 2025 14:00:04 +0200 Subject: [PATCH 118/133] Added HttpsConnector::new function --- src/connector.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/connector.rs b/src/connector.rs index f8abe45..7fb7add 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -35,6 +35,23 @@ impl HttpsConnector { builder::ConnectorBuilder::new() } + /// Creates a new `HttpsConnector`. + /// + /// The recommended way to create a `HttpsConnector` is to use a [`crate::HttpsConnectorBuilder`]. See [`HttpsConnector::builder()`]. + pub fn new( + http: T, + tls_config: impl Into>, + force_https: bool, + server_name_resolver: Arc, + ) -> Self { + Self { + http, + tls_config: tls_config.into(), + force_https, + server_name_resolver, + } + } + /// Force the use of HTTPS when connecting. /// /// If a URL is not `https` when connecting, an error is returned. From 7d02129e37b55cd142246d3280ea8031622af05a Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 26 Oct 2025 12:49:56 +0100 Subject: [PATCH 119/133] ci: rely on Cargo.lock for dependency versions --- .github/workflows/build.yml | 26 +- .gitignore | 1 - Cargo.lock | 1210 +++++++++++++++++++++++++++++++++++ 3 files changed, 1223 insertions(+), 14 deletions(-) create mode 100644 Cargo.lock diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ac97477..3e2d04b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,48 +49,48 @@ jobs: uses: seanmiddleditch/gha-setup-ninja@v6 - name: cargo check (default features) - run: cargo check --all-targets + run: cargo check --locked --all-targets - name: cargo test (debug; default features) - run: cargo test + run: cargo test --locked env: RUST_BACKTRACE: 1 - name: cargo test (debug; native-tokio only) - run: cargo test --no-default-features --features native-tokio + run: cargo test --locked --no-default-features --features native-tokio env: RUST_BACKTRACE: 1 - name: cargo test (debug; webpki-tokio only) - run: cargo test --no-default-features --features webpki-tokio + run: cargo test --locked --no-default-features --features webpki-tokio env: RUST_BACKTRACE: 1 - name: cargo test (debug; defaults+ring) - run: cargo test --no-default-features --features ring,native-tokio,http1,tls12,logging + run: cargo test --locked --no-default-features --features ring,native-tokio,http1,tls12,logging env: RUST_BACKTRACE: 1 - name: cargo test (debug; all features) if: runner.os == 'Linux' - run: cargo test --all-features + run: cargo test --locked --all-features env: RUST_BACKTRACE: 1 - name: cargo test (debug; all features, excluding FIPS) if: runner.os != 'Linux' - run: cargo test --features aws-lc-rs,http1,http2,webpki-tokio,native-tokio,ring,tls12,logging + run: cargo test --locked --features aws-lc-rs,http1,http2,webpki-tokio,native-tokio,ring,tls12,logging env: RUST_BACKTRACE: 1 - name: cargo build (debug; no default features) - run: cargo build --no-default-features + run: cargo build --locked --no-default-features - name: cargo test (debug; no default features; no run) - run: cargo test --no-default-features --no-run + run: cargo test --locked --no-default-features --no-run - name: cargo test (release; no run) - run: cargo test --release --no-run + run: cargo test --locked --release --no-run msrv: runs-on: ubuntu-latest @@ -106,7 +106,7 @@ jobs: toolchain: "1.71" - name: Check MSRV - run: cargo check --lib --all-features + run: cargo check --lib --locked --all-features semver: name: Check semver compatibility @@ -134,7 +134,7 @@ jobs: - name: cargo doc (all features) # keep features in sync with Cargo.toml `[package.metadata.docs.rs]` section - run: cargo doc --no-default-features --features http1,http2,webpki-tokio,native-tokio,ring,tls12,logging --no-deps + run: cargo doc --locked --no-default-features --features http1,http2,webpki-tokio,native-tokio,ring,tls12,logging --no-deps env: RUSTDOCFLAGS: -Dwarnings @@ -165,7 +165,7 @@ jobs: uses: dtolnay/rust-toolchain@stable with: components: clippy - - run: cargo clippy --all-features -- --deny warnings + - run: cargo clippy --locked --all-features -- --deny warnings features: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index e59fb83..01de0fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ -Cargo.lock target/ /.idea diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..3fb9dfe --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1210 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "aws-lc-fips-sys" +version = "0.13.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede71ad84efb06d748d9af3bc500b14957a96282a69a6833b1420dcacb411cc3" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", + "regex", +] + +[[package]] +name = "aws-lc-rs" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" +dependencies = [ + "aws-lc-fips-sys", + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +dependencies = [ + "cfg-if", + "http", + "http-body-util", + "hyper", + "hyper-util", + "log", + "rustls", + "rustls-native-certs", + "rustls-pemfile", + "rustls-pki-types", + "rustls-platform-verifier", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "libc", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mio" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustls" +version = "0.23.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.103.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d651ec480de84b762e7be71e6efa7461699c19d9e2c272c8d93455f567786e" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webpki-roots" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" From ac0a469d063d504ae42bfbbad1d6649287725de7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 19:18:18 +0000 Subject: [PATCH 120/133] Bump webpki-roots from 1.0.3 to 1.0.4 Bumps [webpki-roots](https://github.com/rustls/webpki-roots) from 1.0.3 to 1.0.4. - [Release notes](https://github.com/rustls/webpki-roots/releases) - [Commits](https://github.com/rustls/webpki-roots/compare/v/1.0.3...v/1.0.4) --- updated-dependencies: - dependency-name: webpki-roots dependency-version: 1.0.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fb9dfe..e23d5ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -953,9 +953,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ "rustls-pki-types", ] From 27185ea40a78084b317040162ae74475a242b980 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 22:29:25 +0000 Subject: [PATCH 121/133] Bump rustls from 0.23.34 to 0.23.35 Bumps [rustls](https://github.com/rustls/rustls) from 0.23.34 to 0.23.35. - [Release notes](https://github.com/rustls/rustls/releases) - [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustls/rustls/compare/v/0.23.34...v/0.23.35) --- updated-dependencies: - dependency-name: rustls dependency-version: 0.23.35 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e23d5ba..199eaf8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -627,9 +627,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustls" -version = "0.23.34" +version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" dependencies = [ "aws-lc-rs", "log", From 0f8b70654f89da1a4926789be0c6a77013f163ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Nov 2025 19:02:40 +0000 Subject: [PATCH 122/133] Bump hyper from 1.7.0 to 1.8.0 Bumps [hyper](https://github.com/hyperium/hyper) from 1.7.0 to 1.8.0. - [Release notes](https://github.com/hyperium/hyper/releases) - [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/hyper/compare/v1.7.0...v1.8.0) --- updated-dependencies: - dependency-name: hyper dependency-version: 1.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 199eaf8..5ba0b9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,9 +343,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "1744436df46f0bde35af3eda22aeaba453aada65d8f1c171cd8a5f59030bd69f" dependencies = [ "atomic-waker", "bytes", From 23c93e935e44403e3025dc6849caa31256fa708f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 19:03:04 +0000 Subject: [PATCH 123/133] Bump hyper-util from 0.1.17 to 0.1.18 Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.17 to 0.1.18. - [Release notes](https://github.com/hyperium/hyper-util/releases) - [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.17...v0.1.18) --- updated-dependencies: - dependency-name: hyper-util dependency-version: 0.1.18 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ba0b9c..4d18159 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -387,9 +387,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" dependencies = [ "bytes", "futures-channel", From d7e51d9b4843d3437336cfef675b2261d16d9c9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 19:02:31 +0000 Subject: [PATCH 124/133] Bump hyper from 1.8.0 to 1.8.1 Bumps [hyper](https://github.com/hyperium/hyper) from 1.8.0 to 1.8.1. - [Release notes](https://github.com/hyperium/hyper/releases) - [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/hyper/compare/v1.8.0...v1.8.1) --- updated-dependencies: - dependency-name: hyper dependency-version: 1.8.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d18159..9f30f79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,9 +343,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744436df46f0bde35af3eda22aeaba453aada65d8f1c171cd8a5f59030bd69f" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", "bytes", From 3e799673a6c1cc0e4b3d64ee50d8448fcf977c10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:26:58 +0000 Subject: [PATCH 125/133] Bump actions/checkout from 5 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3e2d04b..d8e30f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: rust: stable steps: - name: Checkout sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false @@ -96,7 +96,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false @@ -113,7 +113,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false @@ -125,7 +125,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false @@ -143,7 +143,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false - name: Install rust toolchain @@ -158,7 +158,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false - name: Install rust toolchain @@ -171,7 +171,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false - name: Install rust toolchain From 8a9b24181ae76eda784f33447bca8c7c3d4e5f8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:32:45 +0000 Subject: [PATCH 126/133] Bump http from 1.3.1 to 1.4.0 Bumps [http](https://github.com/hyperium/http) from 1.3.1 to 1.4.0. - [Release notes](https://github.com/hyperium/http/releases) - [Changelog](https://github.com/hyperium/http/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/http/compare/v1.3.1...v1.4.0) --- updated-dependencies: - dependency-name: http dependency-version: 1.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9f30f79..15adec7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,12 +297,11 @@ checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] From 977c00cec4739b8d5396072c882e52158799ee96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 19:02:41 +0000 Subject: [PATCH 127/133] Bump hyper-util from 0.1.18 to 0.1.19 Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.18 to 0.1.19. - [Release notes](https://github.com/hyperium/hyper-util/releases) - [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.18...v0.1.19) --- updated-dependencies: - dependency-name: hyper-util dependency-version: 0.1.19 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15adec7..d9de460 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -386,9 +386,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "bytes", "futures-channel", From 91e77e9150f1270e9c5773a7f0165db90afc3e51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 19:02:20 +0000 Subject: [PATCH 128/133] Bump rustls-native-certs from 0.8.2 to 0.8.3 Bumps [rustls-native-certs](https://github.com/rustls/rustls-native-certs) from 0.8.2 to 0.8.3. - [Release notes](https://github.com/rustls/rustls-native-certs/releases) - [Commits](https://github.com/rustls/rustls-native-certs/compare/v/0.8.2...v/0.8.3) --- updated-dependencies: - dependency-name: rustls-native-certs dependency-version: 0.8.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9de460..4b99f35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,9 +525,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl-probe" -version = "0.1.6" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" [[package]] name = "pin-project-lite" @@ -642,9 +642,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ "openssl-probe", "rustls-pki-types", From e2a7bb350a576c54a705e6179aad640391e460dd Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Tue, 16 Dec 2025 13:47:13 +0100 Subject: [PATCH 129/133] Exclude development scripts from published package During a dependency review we noticed that the hyper-rustls crate includes various development scripts. These development scripts shouldn't be there as they might, at some point become problematic. As of now they prevent any downstream user from enabling the `[bans.build.interpreted]` option of cargo deny. I opted for using an explicit include list instead of an exclude list to prevent these files from being included in the published packages to make sure that everything that's included is an conscious choice. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index cf10f44..e44bca7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ description = "Rustls+hyper integration for pure rust HTTPS" homepage = "https://github.com/rustls/hyper-rustls" repository = "https://github.com/rustls/hyper-rustls" documentation = "https://docs.rs/hyper-rustls/" +include = ["Cargo.toml", "LICENSE-MIT", "LICENSE-APACHE", "LICENSE-ICS", "README.md", "src/**/*.rs"] [features] default = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] From fcb5d663831451140891659f3a10c84e2f6cec30 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Thu, 1 Jan 2026 12:33:35 +0100 Subject: [PATCH 130/133] Take semver-compatible dependency updates --- Cargo.lock | 93 +++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b99f35..a159fce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -19,9 +19,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "aws-lc-fips-sys" -version = "0.13.9" +version = "0.13.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede71ad84efb06d748d9af3bc500b14957a96282a69a6833b1420dcacb411cc3" +checksum = "57900537c00a0565a35b63c4c281b372edfc9744b072fd4a3b414350a8f5ed48" dependencies = [ "bindgen", "cc", @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.14.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" +checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288" dependencies = [ "aws-lc-fips-sys", "aws-lc-sys", @@ -44,11 +44,10 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.32.3" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c" +checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1" dependencies = [ - "bindgen", "cc", "cmake", "dunce", @@ -83,15 +82,15 @@ checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.43" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ "find-msvc-tools", "jobserver", @@ -133,9 +132,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.54" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" dependencies = [ "cc", ] @@ -186,9 +185,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "find-msvc-tools" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" [[package]] name = "fnv" @@ -291,9 +290,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "http" @@ -426,9 +425,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jni" @@ -464,9 +463,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" @@ -480,9 +479,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "memchr" @@ -498,9 +497,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "wasi", @@ -553,18 +552,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -663,9 +662,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "zeroize", ] @@ -699,9 +698,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.7" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ "aws-lc-rs", "ring", @@ -786,9 +785,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.108" +version = "2.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4" dependencies = [ "proc-macro2", "quote", @@ -853,9 +852,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -872,9 +871,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-core", @@ -882,9 +881,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", ] @@ -897,9 +896,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "unicode-ident" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "untrusted" @@ -943,9 +942,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d651ec480de84b762e7be71e6efa7461699c19d9e2c272c8d93455f567786e" +checksum = "ee3e3b5f5e80bc89f30ce8d0343bf4e5f12341c51f3e26cbeecbc7c85443e85b" dependencies = [ "rustls-pki-types", ] From 13260f90294d96c4126ed9765bdd8a6e49cb06f7 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Thu, 1 Jan 2026 12:33:51 +0100 Subject: [PATCH 131/133] Drop dependency on rustls-pemfile --- Cargo.lock | 11 ----------- Cargo.toml | 2 -- examples/client.rs | 24 +++++++++--------------- examples/server.rs | 34 ++++++++-------------------------- src/connector.rs | 2 +- src/connector/builder.rs | 2 +- 6 files changed, 19 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a159fce..cbe158b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -374,8 +374,6 @@ dependencies = [ "log", "rustls", "rustls-native-certs", - "rustls-pemfile", - "rustls-pki-types", "rustls-platform-verifier", "tokio", "tokio-rustls", @@ -651,15 +649,6 @@ dependencies = [ "security-framework", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.13.2" diff --git a/Cargo.toml b/Cargo.toml index e44bca7..1bc51a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,6 @@ http = "1" hyper = { version = "1", default-features = false } hyper-util = { version = "0.1", default-features = false, features = ["client-legacy", "tokio"] } log = { version = "0.4.4", optional = true } -pki-types = { package = "rustls-pki-types", version = "1" } rustls-native-certs = { version = "0.8", optional = true } rustls-platform-verifier = { version = "0.6", optional = true } rustls = { version = "0.23", default-features = false } @@ -42,7 +41,6 @@ cfg-if = "1" http-body-util = "0.1" hyper-util = { version = "0.1", default-features = false, features = ["server-auto"] } rustls = { version = "0.23", default-features = false, features = ["tls12"] } -rustls-pemfile = "2" tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } [[example]] diff --git a/examples/client.rs b/examples/client.rs index 71c6888..abbf0f0 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -7,10 +7,12 @@ use http_body_util::{BodyExt, Empty}; use hyper::body::Bytes; use hyper_rustls::ConfigBuilderExt; use hyper_util::{client::legacy::Client, rt::TokioExecutor}; +use rustls::pki_types::pem::PemObject; +use rustls::pki_types::CertificateDer; use rustls::RootCertStore; use std::str::FromStr; -use std::{env, fs, io}; +use std::{env, io}; fn main() { // Send GET request and inspect result, with proper error handling. @@ -41,22 +43,14 @@ async fn run_client() -> io::Result<()> { } }; - // Second parameter is custom Root-CA store (optional, defaults to native cert store). - let mut ca = match env::args().nth(2) { - Some(ref path) => { - let f = - fs::File::open(path).map_err(|e| error(format!("failed to open {path}: {e}")))?; - let rd = io::BufReader::new(f); - Some(rd) - } - None => None, - }; - // Prepare the TLS client config - let tls = match ca { - Some(ref mut rd) => { + let tls = match env::args().nth(2) { + Some(path) => { // Read trust roots - let certs = rustls_pemfile::certs(rd).collect::, _>>()?; + let certs = CertificateDer::pem_file_iter(&path) + .and_then(|res| res.collect::, _>>()) + .map_err(|err| error(format!("could not read CA store {path}: {err}")))?; + let mut roots = RootCertStore::empty(); roots.add_parsable_certificates(certs); // TLS client config using the custom CA store for lookups diff --git a/examples/server.rs b/examples/server.rs index 6cbcf45..52372b6 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -7,7 +7,7 @@ use std::net::{Ipv4Addr, SocketAddr}; use std::sync::Arc; -use std::{env, fs, io}; +use std::{env, io}; use http::{Method, Request, Response, StatusCode}; use http_body_util::{BodyExt, Full}; @@ -15,7 +15,8 @@ use hyper::body::{Bytes, Incoming}; use hyper::service::service_fn; use hyper_util::rt::{TokioExecutor, TokioIo}; use hyper_util::server::conn::auto::Builder; -use pki_types::{CertificateDer, PrivateKeyDer}; +use rustls::pki_types::pem::PemObject; +use rustls::pki_types::{CertificateDer, PrivateKeyDer}; use rustls::ServerConfig; use tokio::net::TcpListener; use tokio_rustls::TlsAcceptor; @@ -48,9 +49,12 @@ async fn run_server() -> Result<(), Box> { let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port); // Load public certificate. - let certs = load_certs("examples/sample.pem")?; + let certs = CertificateDer::pem_file_iter("examples/sample.pem")? + .collect::, _>>() + .map_err(|e| error(format!("could not read certificate file: {e}")))?; // Load private key. - let key = load_private_key("examples/sample.rsa")?; + let key = PrivateKeyDer::from_pem_file("examples/sample.rsa") + .map_err(|e| error(format!("could not read private key file: {e}")))?; println!("Starting to serve on https://{addr}"); @@ -114,25 +118,3 @@ async fn echo(req: Request) -> Result>, hyper::Er }; Ok(response) } - -// Load public certificate from file. -fn load_certs(filename: &str) -> io::Result>> { - // Open certificate file. - let certfile = - fs::File::open(filename).map_err(|e| error(format!("failed to open {filename}: {e}")))?; - let mut reader = io::BufReader::new(certfile); - - // Load and return certificate. - rustls_pemfile::certs(&mut reader).collect() -} - -// Load private key from file. -fn load_private_key(filename: &str) -> io::Result> { - // Open keyfile. - let keyfile = - fs::File::open(filename).map_err(|e| error(format!("failed to open {filename}: {e}")))?; - let mut reader = io::BufReader::new(keyfile); - - // Load and return a single private key. - rustls_pemfile::private_key(&mut reader).map(|key| key.unwrap()) -} diff --git a/src/connector.rs b/src/connector.rs index 7fb7add..8740b62 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -8,7 +8,7 @@ use http::Uri; use hyper::rt; use hyper_util::client::legacy::connect::Connection; use hyper_util::rt::TokioIo; -use pki_types::ServerName; +use rustls::pki_types::ServerName; use tokio_rustls::TlsConnector; use tower_service::Service; diff --git a/src/connector/builder.rs b/src/connector/builder.rs index 417d130..3937900 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -7,6 +7,7 @@ use hyper_util::client::legacy::connect::HttpConnector; feature = "webpki-roots" ))] use rustls::crypto::CryptoProvider; +use rustls::pki_types::ServerName; use rustls::ClientConfig; use super::{DefaultServerNameResolver, HttpsConnector, ResolveServerName}; @@ -16,7 +17,6 @@ use super::{DefaultServerNameResolver, HttpsConnector, ResolveServerName}; feature = "rustls-platform-verifier" ))] use crate::config::ConfigBuilderExt; -use pki_types::ServerName; /// A builder for an [`HttpsConnector`] /// From 77881eb4519a05029e5b3b4e90f79cebb76abe2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 19:02:29 +0000 Subject: [PATCH 132/133] Bump rustls from 0.23.35 to 0.23.36 Bumps [rustls](https://github.com/rustls/rustls) from 0.23.35 to 0.23.36. - [Release notes](https://github.com/rustls/rustls/releases) - [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustls/rustls/compare/v/0.23.35...v/0.23.36) --- updated-dependencies: - dependency-name: rustls dependency-version: 0.23.36 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cbe158b..889a13d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -623,9 +623,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustls" -version = "0.23.35" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ "aws-lc-rs", "log", From 39e429017f85a102d1c1487a5afa13396e6cdee5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 19:02:45 +0000 Subject: [PATCH 133/133] Bump webpki-roots from 1.0.4 to 1.0.5 Bumps [webpki-roots](https://github.com/rustls/webpki-roots) from 1.0.4 to 1.0.5. - [Release notes](https://github.com/rustls/webpki-roots/releases) - [Commits](https://github.com/rustls/webpki-roots/compare/v/1.0.4...v/1.0.5) --- updated-dependencies: - dependency-name: webpki-roots dependency-version: 1.0.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 889a13d..b33dd0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -940,9 +940,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" dependencies = [ "rustls-pki-types", ]