Full Code of rustls/rustls for AI

main 757dc157f290 cached
475 files
8.3 MB
2.2M tokens
4417 symbols
1 requests
Download .txt
Showing preview only (8,787K chars total). Download the full file or copy to clipboard to get everything.
Repository: rustls/rustls
Branch: main
Commit: 757dc157f290
Files: 475
Total size: 8.3 MB

Directory structure:
gitextract_21a4tl8l/

├── .cargo/
│   └── config.toml
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── dependency-update.md
│   │   └── feature_request.md
│   ├── codecov.yml
│   ├── renovate.json
│   ├── typos.toml
│   └── workflows/
│       ├── build.yml
│       ├── cifuzz.yml
│       ├── daily-tests.yml
│       └── docs.yml
├── .gitignore
├── .lycheeignore
├── .rustfmt.toml
├── .rustfmt.unstable.toml
├── .taplo.toml
├── BENCHMARKING.md
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE
├── LICENSE-APACHE
├── LICENSE-ISC
├── LICENSE-MIT
├── README.md
├── RELEASING.md
├── ROADMAP.md
├── SECURITY.md
├── admin/
│   ├── all-features-except
│   ├── all-workspace-members
│   ├── bench-measure.mk
│   ├── bench-range
│   ├── capture-certdata
│   ├── clippy
│   ├── coverage
│   ├── pull-readme
│   └── threads-seq.rs
├── ci-bench/
│   ├── Cargo.toml
│   ├── README.md
│   └── src/
│       ├── benchmark.rs
│       ├── main.rs
│       ├── util.rs
│       └── valgrind.rs
├── connect-tests/
│   ├── Cargo.toml
│   └── tests/
│       ├── badssl.rs
│       ├── common/
│       │   └── mod.rs
│       └── topsites.rs
├── deny.toml
├── examples/
│   ├── Cargo.toml
│   ├── README.md
│   ├── src/
│   │   └── bin/
│   │       ├── ech-client.rs
│   │       ├── limitedclient.rs
│   │       ├── server_acceptor.rs
│   │       ├── simple_0rtt_client.rs
│   │       ├── simple_0rtt_server.rs
│   │       ├── simpleclient.rs
│   │       ├── simpleserver.rs
│   │       ├── tlsclient-mio.rs
│   │       └── tlsserver-mio.rs
│   └── tests/
│       └── limitedclient.rs
├── fuzz/
│   ├── .gitignore
│   ├── Cargo.toml
│   ├── README.md
│   └── fuzzers/
│       ├── client.rs
│       ├── deframer.rs
│       ├── fragment.rs
│       ├── message.rs
│       ├── persist.rs
│       ├── server.rs
│       └── server_name.rs
├── openssl-tests/
│   ├── Cargo.toml
│   └── src/
│       ├── early_exporter.rs
│       ├── ffdhe.rs
│       ├── ffdhe_kx_with_openssl.rs
│       ├── lib.rs
│       ├── raw_key_openssl_interop.rs
│       ├── utils.rs
│       └── validate_ffdhe_params.rs
├── provider-example/
│   ├── Cargo.toml
│   ├── examples/
│   │   ├── client.rs
│   │   └── server.rs
│   └── src/
│       ├── aead.rs
│       ├── hash.rs
│       ├── hmac.rs
│       ├── hpke.rs
│       ├── kx.rs
│       ├── lib.rs
│       ├── sign.rs
│       ├── ticketer.rs
│       └── verify.rs
├── rustls/
│   ├── .clippy.toml
│   ├── Cargo.toml
│   ├── examples/
│   │   └── internal/
│   │       └── test_ca.rs
│   └── src/
│       ├── bs_debug.rs
│       ├── builder.rs
│       ├── check.rs
│       ├── client/
│       │   ├── config.rs
│       │   ├── connection.rs
│       │   ├── ech.rs
│       │   ├── handy.rs
│       │   ├── hs.rs
│       │   ├── mod.rs
│       │   ├── test.rs
│       │   ├── tls12.rs
│       │   └── tls13.rs
│       ├── common_state.rs
│       ├── compress.rs
│       ├── conn/
│       │   ├── kernel.rs
│       │   ├── mod.rs
│       │   ├── receive.rs
│       │   └── send.rs
│       ├── crypto/
│       │   ├── cipher/
│       │   │   ├── messages.rs
│       │   │   ├── mod.rs
│       │   │   └── record_layer.rs
│       │   ├── enums.rs
│       │   ├── hash.rs
│       │   ├── hmac.rs
│       │   ├── hpke.rs
│       │   ├── kx/
│       │   │   ├── ffdhe.rs
│       │   │   └── mod.rs
│       │   ├── mod.rs
│       │   ├── signer.rs
│       │   ├── test_provider.rs
│       │   ├── tls12.rs
│       │   └── tls13.rs
│       ├── enums.rs
│       ├── error/
│       │   ├── mod.rs
│       │   └── tests.rs
│       ├── hash_hs.rs
│       ├── key_log.rs
│       ├── lib.rs
│       ├── limited_cache.rs
│       ├── lock.rs
│       ├── manual/
│       │   ├── defaults.rs
│       │   ├── features.rs
│       │   ├── fips.rs
│       │   ├── howto.rs
│       │   ├── implvulns.rs
│       │   ├── mod.rs
│       │   └── tlsvulns.rs
│       ├── msgs/
│       │   ├── client_hello.rs
│       │   ├── codec.rs
│       │   ├── deframer/
│       │   │   ├── buffers.rs
│       │   │   ├── handshake.rs
│       │   │   └── mod.rs
│       │   ├── enums.rs
│       │   ├── fragmenter.rs
│       │   ├── handshake.rs
│       │   ├── handshake_test.rs
│       │   ├── macros.rs
│       │   ├── mod.rs
│       │   └── server_hello.rs
│       ├── quic.rs
│       ├── server/
│       │   ├── config.rs
│       │   ├── connection.rs
│       │   ├── handy.rs
│       │   ├── hs.rs
│       │   ├── mod.rs
│       │   ├── test.rs
│       │   ├── tls12.rs
│       │   └── tls13.rs
│       ├── suites.rs
│       ├── testdata/
│       │   ├── eddsakey.der
│       │   ├── nistp256key.der
│       │   ├── nistp256key.pkcs8.der
│       │   ├── nistp384key.der
│       │   ├── nistp384key.pkcs8.der
│       │   ├── nistp521key.der
│       │   ├── nistp521key.pkcs8.der
│       │   ├── rsa2048key.pkcs1.der
│       │   ├── rsa2048key.pkcs8.der
│       │   └── rsa4096key.pkcs8.der
│       ├── ticketer.rs
│       ├── time_provider.rs
│       ├── tls12.rs
│       ├── tls13/
│       │   ├── key_schedule.rs
│       │   └── mod.rs
│       ├── vecbuf.rs
│       ├── verify.rs
│       ├── versions.rs
│       ├── webpki/
│       │   ├── anchors.rs
│       │   ├── client_verifier.rs
│       │   ├── mod.rs
│       │   ├── server_verifier.rs
│       │   └── verify.rs
│       └── x509.rs
├── rustls-aws-lc-rs/
│   ├── Cargo.toml
│   └── src/
│       ├── data/
│       │   ├── alg-rsa-pkcs1-sha256-absent-params.der
│       │   ├── alg-rsa-pkcs1-sha384-absent-params.der
│       │   └── alg-rsa-pkcs1-sha512-absent-params.der
│       ├── hash.rs
│       ├── hmac.rs
│       ├── hpke.rs
│       ├── kx.rs
│       ├── lib.rs
│       ├── quic.rs
│       ├── sign.rs
│       ├── ticketer.rs
│       ├── tls12.rs
│       ├── tls13.rs
│       └── verify.rs
├── rustls-bench/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
├── rustls-fuzzing-provider/
│   ├── Cargo.toml
│   ├── src/
│   │   └── lib.rs
│   └── tests/
│       └── smoke.rs
├── rustls-post-quantum/
│   ├── Cargo.toml
│   ├── README.md
│   ├── README.tpl
│   ├── benches/
│   │   └── benchmarks.rs
│   ├── examples/
│   │   └── client.rs
│   └── src/
│       └── lib.rs
├── rustls-provider-test/
│   ├── Cargo.toml
│   ├── README.md
│   └── tests/
│       ├── hpke.rs
│       └── rfc-9180-test-vectors.json
├── rustls-ring/
│   ├── Cargo.toml
│   ├── benches/
│   │   └── benchmarks.rs
│   └── src/
│       ├── data/
│       │   ├── alg-rsa-pkcs1-sha256-absent-params.der
│       │   ├── alg-rsa-pkcs1-sha384-absent-params.der
│       │   └── alg-rsa-pkcs1-sha512-absent-params.der
│       ├── hash.rs
│       ├── hmac.rs
│       ├── kx.rs
│       ├── lib.rs
│       ├── quic.rs
│       ├── sign.rs
│       ├── ticketer.rs
│       ├── tls12.rs
│       ├── tls13.rs
│       └── verify.rs
├── rustls-test/
│   ├── Cargo.toml
│   ├── benches/
│   │   ├── data/
│   │   │   ├── cert-arstechnica.0.der
│   │   │   ├── cert-arstechnica.1.der
│   │   │   ├── cert-arstechnica.2.der
│   │   │   ├── cert-duckduckgo.0.der
│   │   │   ├── cert-duckduckgo.1.der
│   │   │   ├── cert-duckduckgo.2.der
│   │   │   ├── cert-github.0.der
│   │   │   ├── cert-github.1.der
│   │   │   ├── cert-github.2.der
│   │   │   ├── cert-google.0.der
│   │   │   ├── cert-google.1.der
│   │   │   ├── cert-google.2.der
│   │   │   ├── cert-hn.0.der
│   │   │   ├── cert-hn.1.der
│   │   │   ├── cert-reddit.0.der
│   │   │   ├── cert-reddit.1.der
│   │   │   ├── cert-rustlang.0.der
│   │   │   ├── cert-rustlang.1.der
│   │   │   ├── cert-servo.0.der
│   │   │   ├── cert-servo.1.der
│   │   │   ├── cert-servo.2.der
│   │   │   ├── cert-stackoverflow.0.der
│   │   │   ├── cert-stackoverflow.1.der
│   │   │   ├── cert-twitter.0.der
│   │   │   ├── cert-twitter.1.der
│   │   │   ├── cert-wapo.0.der
│   │   │   ├── cert-wapo.1.der
│   │   │   ├── cert-wapo.2.der
│   │   │   ├── cert-wikipedia.0.der
│   │   │   └── cert-wikipedia.1.der
│   │   └── verifybench.rs
│   ├── src/
│   │   └── lib.rs
│   └── tests/
│       ├── api/
│       │   ├── api.rs
│       │   ├── client_cert_verifier.rs
│       │   ├── compress.rs
│       │   ├── crypto.rs
│       │   ├── ffdhe.rs
│       │   ├── io.rs
│       │   ├── kx.rs
│       │   ├── quic.rs
│       │   ├── raw_keys.rs
│       │   ├── resolve.rs
│       │   ├── resume.rs
│       │   └── server_cert_verifier.rs
│       ├── api.rs
│       ├── bogo.rs
│       ├── key_log_file_env/
│       │   └── tests.rs
│       ├── key_log_file_env.rs
│       └── process_provider.rs
├── rustls-util/
│   ├── Cargo.toml
│   └── src/
│       ├── key_log_file.rs
│       ├── lib.rs
│       └── stream.rs
├── test-ca/
│   ├── README.md
│   ├── ecdsa-p256/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── ecdsa-p384/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── ecdsa-p521/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── eddsa/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── rsa-2048/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── rsa-3072/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   └── rsa-4096/
│       ├── ca.cert
│       ├── ca.der
│       ├── ca.key
│       ├── client.cert
│       ├── client.chain
│       ├── client.der
│       ├── client.expired.crl.pem
│       ├── client.fullchain
│       ├── client.key
│       ├── client.revoked.crl.pem
│       ├── client.spki.pem
│       ├── end.cert
│       ├── end.chain
│       ├── end.der
│       ├── end.expired.crl.pem
│       ├── end.fullchain
│       ├── end.key
│       ├── end.revoked.crl.pem
│       ├── end.spki.pem
│       ├── inter.cert
│       ├── inter.der
│       ├── inter.expired.crl.pem
│       ├── inter.key
│       └── inter.revoked.crl.pem
└── website/
    ├── README.md
    ├── config.toml
    ├── content/
    │   ├── blog/
    │   │   ├── 2025-09-03-rustls-and-rust-foundation.md
    │   │   └── _index.md
    │   ├── perf/
    │   │   ├── 2024-10-18-report.md
    │   │   ├── 2024-10-31-arm64.md
    │   │   ├── 2024-11-28-threading/
    │   │   │   └── index.md
    │   │   ├── 2024-12-17-pq-kx/
    │   │   │   └── index.md
    │   │   ├── 2025-07-31-report.md
    │   │   ├── 2026-03-07-report.md
    │   │   └── _index.md
    │   └── release/
    │       └── _index.md
    ├── static/
    │   └── style.css
    └── templates/
        ├── base.html
        ├── index.html
        ├── macros.html
        ├── pages.html
        ├── report-page.html
        └── reports.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .cargo/config.toml
================================================
[alias]

fmt-unstable = ["fmt", "--all", "--", "--config-path", ".rustfmt.unstable.toml"]


================================================
FILE: .github/FUNDING.yml
================================================
github: ["cpu", "ctz", "djc"]


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Checklist**
* [ ] I've searched the issue tracker for similar bugs.

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Use one of the examples to connect to `....`
2. ...
3. See error

**Applicable Version(s)**
A list of versions and platforms you've tested with.

**Expected behavior**
A clear and concise description of what you expected to happen.

**Additional context**
Add any other context about the problem here.
For example, consider including verbose logs or a packet capture. For help
with this [see the manual](https://docs.rs/rustls/latest/rustls/manual/_03_howto/index.html#debugging).


================================================
FILE: .github/ISSUE_TEMPLATE/dependency-update.md
================================================
---
name: Dependency Update
about: Request a dependency be updated
title: Dependency update request
labels: ''
assignees: ''

---

<!--
Please note that we are only interested in **semver-incompatible** update requests. Updates to dependencies that are
semver-compatible can be done in dependent projects without needing changes in this repository.

For example, if you are here because you believe Rustls is bringing in dependency `foo` at version `0.2.1` and
you wish Rustls used `0.2.2` instead, you should not file an issue and instead should run `cargo update` in your
dependent project. It would only be appropriate to file an issue if you require Rustls use `foo` at version `0.3.0+`.
-->

**Checklist**
* [ ] I've searched the issue tracker for similar requests
* [ ] I've confirmed my request is for a semver-incompatible update

**Is your dependency update request related to a problem? Please describe.**
A clear and concise description of what the problem is.

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Checklist**
* [ ] I've searched the issue tracker for similar requests

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/codecov.yml
================================================
coverage:
  status:
    patch:
      default:
        threshold: 0.05%
    project:
      default:
        threshold: 0.05%


================================================
FILE: .github/renovate.json
================================================
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base"
  ],
  "labels": [
    "dependencies"
  ],
  "lockFileMaintenance": {
    "enabled": true
  },
  "prCreation": "not-pending",
  "rangeStrategy": "update-lockfile",
  "rebaseWhen": "behind-base-branch",
  "github-actions": {
    "fileMatch": [
      "^ci\\/.*/[^/]+\\.ya?ml$"
    ]
  },
  "packageRules": [
    {
      "matchManagers": [
        "cargo"
      ],
      "matchUpdateTypes": [
        "patch"
      ],
      "enabled": false
    },
    {
      "matchManagers": [
        "cargo"
      ],
      "matchUpdateTypes": [
        "minor"
      ],
      "matchCurrentVersion": "!/^0/",
      "enabled": false
    }
  ]
}


================================================
FILE: .github/typos.toml
================================================
[default.extend-words]
# encrypter as an active verb
encrypter = "encrypter"

# "type", but side-stepping the keyword and avoiding the very ugly r#type
typ = "typ"

# pn -> packet number in quic parlance
pn = "pn"

# as in Josh
Aas = "Aas"

[files]
extend-exclude = ["*.bin", "*.json", "*.json.in", "*.svg", "macros.html", "test-ca/"]


================================================
FILE: .github/workflows/build.yml
================================================
name: rustls

permissions:
  contents: read

on:
  push:
    branches: ['main', 'rel-*', 'ci/*']
    tags:
    - '**'
  pull_request:
  merge_group:
  schedule:
    - cron: '0 18 * * *'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  RUSTFLAGS: --deny warnings
  AWS_LC_SYS_NO_JITTER_ENTROPY: 1

jobs:
  build:
    name: Build+test
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        rust:
          - stable
          - beta
          - nightly
        os:
          - ubuntu-latest
          - windows-latest
          - macos-latest
        exclude:
          # only stable on macos/windows (slower platforms)
          - os: windows-latest
            rust: beta
          - os: windows-latest
            rust: nightly
          - os: macos-latest
            rust: beta
          - os: macos-latest
            rust: nightly
          # and never use macos/windows for merge checks
          - os: ${{ github.event_name == 'merge_group' && 'windows-latest' }}
          - os: ${{ github.event_name == 'merge_group' && 'macos-latest' }}
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install ${{ matrix.rust }} toolchain
        uses: dtolnay/rust-toolchain@master
        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@v6

      - name: Install golang for aws-lc-fips-sys on macos
        if: runner.os == 'MacOS'
        uses: actions/setup-go@v6
        with:
          go-version: "1.26.1"

      - name: cargo build (debug; default features)
        run: cargo build --locked

      # nb. feature sets that include "fips" should be --release --
      # this is required for fips on windows.
      # nb. "--all-targets" does not include doctests
      - name: cargo test (release; all features)
        run: cargo test --locked --release --all-features --all-targets
        env:
          RUST_BACKTRACE: 1

      # nb. this is separate since `--doc` option cannot be combined with other target option(s) ref:
      # - https://doc.rust-lang.org/cargo/commands/cargo-test.html
      - name: cargo test --doc (release; all-features)
        run: cargo test --locked --release --all-features --doc
        env:
          RUST_BACKTRACE: 1

      - name: cargo build (debug; no-std)
        run: |
          cargo build --locked --lib -p rustls $(admin/all-features-except std,brotli rustls)
          cargo build --locked --lib -p rustls-ring --no-default-features
          cargo build --locked --lib -p rustls-aws-lc-rs --no-default-features --features aws-lc-sys


      - name: cargo build (debug; rustls-provider-example)
        run: cargo build --locked -p rustls-provider-example

      - name: cargo build (debug; rustls-provider-example lib in no-std mode)
        run: cargo build --locked -p rustls-provider-example --no-default-features

      - name: cargo test (debug; rustls-provider-example; all features)
        run: cargo test --locked --all-features -p rustls-provider-example

      - name: cargo build (debug; rustls-provider-test)
        run: cargo build --locked -p rustls-provider-test

      - name: cargo test (debug; rustls-provider-test; all features)
        run: cargo test --locked --all-features -p rustls-provider-test

      - name: cargo package --all-features -p rustls
        run: cargo package --all-features -p rustls

  msrv:
    name: MSRV
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - uses: dtolnay/rust-toolchain@master
        with:
          toolchain: "1.83"

      - run: cargo check --locked --lib --all-features -p rustls

  features:
    name: Features
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          target: x86_64-unknown-none

      - name: cargo build (debug; default features)
        run: |
          cargo build --locked -p rustls
          cargo build --locked -p rustls-ring
          cargo build --locked -p rustls-aws-lc-rs

      - name: cargo test (debug; default features)
        run: cargo test --locked
        working-directory: rustls
        env:
          RUST_BACKTRACE: 1

      - name: cargo test (debug; no default features)
        run: |
          cargo test --locked -p rustls --no-default-features
          cargo test --locked -p rustls-ring --no-default-features
          cargo test --locked -p rustls-aws-lc-rs --no-default-features --features aws-lc-sys

      - name: cargo test (debug; no default features; std)
        run: |
          cargo test --locked -p rustls-ring --no-default-features --features std
          cargo test --locked -p rustls-aws-lc-rs --no-default-features --features std --features aws-lc-sys

      - name: cargo test (release; no run)
        run: cargo test --locked --release --no-run
        working-directory: rustls

  bogo:
    name: BoGo test suite
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Install golang toolchain
        uses: actions/setup-go@v6
        with:
          go-version: "1.26"
          cache: false

      - name: Run test suite (ring)
        working-directory: bogo
        run: ./runme
        env:
          BOGO_SHIM_PROVIDER: ring

      - name: Run test suite (aws-lc-rs)
        working-directory: bogo
        run: ./runme
        env:
          BOGO_SHIM_PROVIDER: aws-lc-rs

      - name: Run test suite (aws-lc-rs-fips)
        working-directory: bogo
        run: ./runme
        env:
          BOGO_SHIM_PROVIDER: aws-lc-rs-fips

  fuzz:
    name: Smoke-test fuzzing targets
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Install cargo fuzz
        uses: taiki-e/cache-cargo-install-action@v3
        with:
          tool: cargo-fuzz

      - name: Smoke-test fuzz targets
        env:
          # cargo fuzz uses a bunch of -Z options
          RUSTC_BOOTSTRAP: 1
        run: |
          cargo fuzz build
          for target in $(cargo fuzz list) ; do
            cargo fuzz run $target -- -max_total_time=10
          done

  benchmarks:
    name: Run benchmarks
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Smoke-test benchmark program (ring)
        run: cargo run -p rustls-bench --profile=bench --locked --features ring -- --multiplier 0.1

      - name: Smoke-test benchmark program (aws-lc-rs)
        run: cargo run -p rustls-bench --profile=bench --locked --features aws-lc-rs -- --multiplier 0.1

      - name: Smoke-test benchmark program (fips)
        run: cargo run -p rustls-bench --profile=bench --locked --features fips -- --provider aws-lc-rs-fips --multiplier 0.1

      - name: Run micro-benchmarks
        run: cargo bench --locked --all-features
        env:
          RUSTFLAGS: --cfg=bench
          # unit-benchmarks are permanantly unstable
          RUSTC_BOOTSTRAP: 1

  docs:
    name: Check for documentation errors
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install rust toolchain
        # use nightly to mirror docs.rs
        uses: dtolnay/rust-toolchain@nightly

      - name: cargo doc (rustls; all features)
        run: cargo doc --locked --all-features --no-deps --document-private-items --package rustls
        env:
          RUSTDOCFLAGS: -Dwarnings

      - name: Check README.md
        run: |
          cargo build --locked --all-features
          ./admin/pull-readme
          git diff --exit-code

      - name: Spell check code
        uses: crate-ci/typos@v1
        with:
          config: .github/typos.toml


  coverage:
    name: Measure coverage
    runs-on: ubuntu-latest
    if: github.event_name != 'merge_group'
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@nightly
        with:
          components: llvm-tools

      - name: Install cargo-llvm-cov
        uses: taiki-e/cache-cargo-install-action@v3
        with:
          tool: cargo-llvm-cov

      - name: Measure coverage
        run: ./admin/coverage --lcov --output-path final.info

      - name: Report to codecov.io
        uses: codecov/codecov-action@v5
        with:
          files: final.info
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: false

  minver:
    name: Check minimum versions of direct dependencies
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Install cargo-minimal-versions
        uses: taiki-e/install-action@cargo-minimal-versions

      # cargo-minimal-versions requires cargo-hack
      - name: Install cargo-hack
        uses: taiki-e/install-action@cargo-hack

      - name: Check direct-minimal-versions
        run: cargo minimal-versions --direct --ignore-private check
        working-directory: rustls/
        env:
          # `cargo minimal-versions` uses unstable cargo features
          RUSTC_BOOTSTRAP: 1

  cross:
    name: cross-target testing
    runs-on: ubuntu-latest
    if: github.event_name != 'merge_group'
    strategy:
      matrix:
        target:
          # 32-bit Android (Linux) targets:
          - armv7-linux-androideabi
          - i686-linux-android
          - thumbv7neon-linux-androideabi
          # Other standard 32-bit (Linux) targets
          - i586-unknown-linux-gnu
          - i686-unknown-linux-gnu
          # exotic Linux targets:
          - riscv64gc-unknown-linux-gnu
          - s390x-unknown-linux-gnu
          # additional target(s):
          # NOTE: This could have some overlap with 64-bit ARM-style CPU on macOS CI host;
          # may have similar ARM-style CPU overlap with standard Windows & possibly Linux in the future
          - aarch64-linux-android
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Install cross
        uses: taiki-e/cache-cargo-install-action@v3
        with:
          tool: cross
          git: https://github.com/cross-rs/cross
          # known-working main in feb 2025, bump as needed
          rev: c7dee4d
      - run: cross test --package rustls --target ${{ matrix.target }}
      - run: cross test --package rustls-test --features aws-lc-rs --no-default-features --target ${{ matrix.target }}

  semver:
    name: Check semver compatibility
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Check semver
        uses: obi1kenobi/cargo-semver-checks-action@v2

  format:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false
      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt
      - name: Check formatting
        run: cargo fmt --all -- --check
      - name: Check formatting (connect-tests workspace)
        run: cargo fmt --all --manifest-path=connect-tests/Cargo.toml -- --check
      - name: Check formatting (fuzz workspace)
        run: cargo fmt --all --manifest-path=fuzz/Cargo.toml -- --check

  format-unstable:
    name: Format (unstable)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false
      - name: Install rust nightly toolchain
        uses: dtolnay/rust-toolchain@nightly
        with:
          components: rustfmt
      - name: Check formatting (unstable)
        run: cargo fmt --all -- --check --config-path .rustfmt.unstable.toml
      - name: Check formatting (unstable, connect-tests workspace)
        run: cargo fmt --all --manifest-path=connect-tests/Cargo.toml -- --check --config-path .rustfmt.unstable.toml
      - name: Check formatting (unstable, fuzz workspace)
        run: cargo fmt --all --manifest-path=fuzz/Cargo.toml -- --check --config-path .rustfmt.unstable.toml
      - if: ${{ failure() }}
        run: echo "Nightly formatting check failed. Please run \`cargo +nightly fmt-unstable\`"

  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install valgrind
        if: runner.os == 'Linux'
        run: sudo apt-get update && sudo apt-get install -y valgrind

      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - run: ./admin/clippy -- --deny warnings

  clippy-nightly:
    name: Clippy (Nightly)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install valgrind
        if: runner.os == 'Linux'
        run: sudo apt-get update && sudo apt-get install -y valgrind

      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@nightly
        with:
          components: clippy
      # Do not deny warnings, as nightly clippy sometimes has false negatives.
      - run: ./admin/clippy

  check-external-types:
    name: Validate external types appearing in public API
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false
      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: nightly-2025-10-18
          # ^ sync with https://github.com/awslabs/cargo-check-external-types/blob/main/rust-toolchain.toml
      - name: Install cargo-check-external-types
        uses: taiki-e/cache-cargo-install-action@v3
        with:
          tool: cargo-check-external-types
      - name: run cargo-check-external-types for rustls/
        working-directory: rustls/
        run: cargo check-external-types

  taplo:
    name: Taplo
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Install taplo-cli
        uses: taiki-e/cache-cargo-install-action@v3
        with:
          tool: taplo-cli
      - run: taplo format --check

  openssl-tests:
    name: Run openssl-tests
    runs-on: ubuntu-latest
    env:
      VERSION: openssl-3.4.0
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Cache ${{ env.VERSION }}
        uses: actions/cache@v5
        id: cache-openssl
        with:
          path: ${{ env.VERSION }}
          key: ${{ env.VERSION }}

      - name: Fetch and build ${{ env.VERSION }}
        if: steps.cache-openssl.outputs.cache-hit != 'true'
        run: |
          wget https://github.com/openssl/openssl/releases/download/$VERSION/$VERSION.tar.gz
          tar -xzf $VERSION.tar.gz
          cd $VERSION/
          ./Configure --prefix=$(pwd)/built/ --libdir=lib
          make -j$(nproc)
          make install

      - name: Use ${{ env.VERSION }}
        run: |
         path=$(pwd)/$VERSION/built/
         echo "$path/bin" >> $GITHUB_PATH
         echo "LD_LIBRARY_PATH=$path/lib" >> $GITHUB_ENV

      - name: openssl version
        run: openssl version

      - name: cargo test (in openssl-tests/)
        working-directory: openssl-tests/
        run: cargo test --locked -- --include-ignored
        env:
          RUST_BACKTRACE: 1

  audit:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v6
    - uses: EmbarkStudios/cargo-deny-action@v2


================================================
FILE: .github/workflows/cifuzz.yml
================================================
name: CIFuzz
permissions:
  contents: read
on: [pull_request]

concurrency:
  group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  Fuzzing:
    runs-on: ubuntu-latest
    steps:
    - name: Build Fuzzers
      id: build
      uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
      with:
        oss-fuzz-project-name: 'rustls'
        dry-run: false
        language: rust
    - name: Run Fuzzers
      uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
      with:
        oss-fuzz-project-name: 'rustls'
        fuzz-seconds: 150
        dry-run: false
        language: rust
    - name: Upload Crash
      uses: actions/upload-artifact@v7
      if: failure() && steps.build.outcome == 'success'
      with:
        name: artifacts
        path: ./out/artifacts


================================================
FILE: .github/workflows/daily-tests.yml
================================================
name: daily-tests

permissions:
  contents: read

on:
  workflow_dispatch:
  schedule:
    # We run these tests on a daily basis (at a time slightly offset from the
    # top of the hour), as their runtime is either too long for the usual per-PR
    # CI, or because they rely on external 3rd party services that can be flaky.
    - cron: '15 18 * * *'

jobs:
  connect-tests:
    name: Connect Tests
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        # test a bunch of toolchains on ubuntu
        rust:
          - stable
          - beta
          - nightly
        os: [ubuntu-latest]
        # but only stable on macos/windows (slower platforms)
        include:
          - os: macos-latest
            rust: stable
          - os: windows-latest
            rust: stable
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install ${{ matrix.rust }} toolchain
        uses: dtolnay/rust-toolchain@master
        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@v6

      - name: Build example programs
        run: cargo build --locked -p rustls-examples

      - name: Run connect tests
        run: cargo test --locked -p rustls-connect-tests --manifest-path=connect-tests/Cargo.toml
        env:
          RUST_BACKTRACE: 1

  example-tests:
    name: Example Tests
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        # test a bunch of toolchains on ubuntu
        rust:
          - stable
          - beta
          - nightly
        os: [ubuntu-latest]
        # but only stable on macos/windows (slower platforms)
        include:
          - os: macos-latest
            rust: stable
          - os: windows-latest
            rust: stable
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install ${{ matrix.rust }} toolchain
        uses: dtolnay/rust-toolchain@master
        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@v6

      - name: Check simple client
        run: cargo run --locked -p rustls-examples --bin simpleclient

      - name: Check limited client
        run: cargo run --locked -p rustls-examples --bin limitedclient

      - name: Check simple 0rtt client
        run: cargo run --locked -p rustls-examples --bin simple_0rtt_client

      # Test the server_acceptor binary builds - we invoke with --help since it
      # will run a server process that doesn't exit when invoked with no args
      - name: Check server acceptor
        run: cargo run --locked -p rustls-examples --bin server_acceptor -- --help

      - name: Check ech-client (research.cloudflare.com)
        run: >
          cargo run --locked -p rustls-examples --bin ech-client -- cloudflare-ech.com research.cloudflare.com --path /cdn-cgi/trace |
            grep 'sni=encrypted'

      - name: Check ech-client (defo.ie)
        run: >
          cargo run --locked -p rustls-examples --bin ech-client -- --host min-ng.test.defo.ie --path "echstat.php?format=json" public.test.defo.ie min-ng.test.defo.ie |
            grep '"SSL_ECH_STATUS": "success"'

      - name: Check ech-client (tls-ech.dev)
        run: >
          cargo run --locked -p rustls-examples --bin ech-client -- --path "/" public.tls-ech.dev tls-ech.dev |
            grep 'You are using ECH.'

      - name: Check provider-example client
        run: cargo run --locked -p rustls-provider-example --example client

      - name: Check rustls-post-quantum client
        run: cargo run --locked -p rustls-post-quantum --example client | grep 'kex=X25519MLKEM768'

      - name: Smoke test for secp256r1mlkem768 interop
        run: cargo run --locked -p rustls-examples --bin tlsclient-mio -- --http --key-exchange secp256r1mlkem768 --verbose openquantumsafe.org

  feature-powerset:
    name: Feature Powerset
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Install cargo hack
        uses: taiki-e/install-action@cargo-hack

      - name: Check feature powerset
        run: >
            cargo hack check
            --package rustls
            --feature-powerset
            --no-dev-deps
        env:
          RUSTFLAGS: --deny warnings


================================================
FILE: .github/workflows/docs.yml
================================================
name: documentation

permissions:
  contents: read

on:
  workflow_dispatch:
  pull_request:
  push:
    branches:
      - main
  schedule:
    - cron: '0 18 * * *'

jobs:
  generate:
    name: Generate pre-release documentation
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install rust toolchain
        uses: dtolnay/rust-toolchain@nightly

      - name: Install zola
        uses: taiki-e/install-action@v2
        with:
          tool: zola@0.19.1

      - name: Generate version information
        run: |
          echo >tag.html \
            "<script>var version = document.querySelector(\"span.version\");" \
            "version.innerHTML += \"<br>(pre-release docs from <tt>$GITHUB_REF</tt>)\";" \
            "version.title = \"commit $GITHUB_SHA\";" \
            "</script>"

      - name: cargo doc
        # keep features in sync with Cargo.toml `[package.metadata.docs.rs]` section
        run: cargo doc --locked --features brotli,hashbrown,log,zlib --no-deps --package rustls
        env:
          RUSTDOCFLAGS: -Dwarnings --cfg=rustls_docsrs --html-after-content tag.html

      - name: Generate other pages
        run: |
          cd website && zola build --output-dir ../target/website/

      - name: Restore lychee cache
        uses: actions/cache@v5
        with:
          path: .lycheecache
          key: cache-lychee-${{ github.sha }}
          restore-keys: cache-lychee-

      - name: Check links
        uses: lycheeverse/lychee-action@v2
        with:
          args: >
            --accept 200..=204,403,429,500
            --cache
            --max-cache-age 1d
            --exclude-path 'website/content/'
            '**/*.md'
            'target/doc/**/*.html'
          fail: true

      - name: Massage rustdoc output
        run: |
          # lockfile causes deployment step to go wrong, due to permissions
          rm -f target/doc/.lock
          # move the result into website root
          mv target/doc/* target/website/
          mv target/website/rustls target/website/docs

      - name: Package and upload artifact
        uses: actions/upload-pages-artifact@v4
        with:
          path: ./target/website/

  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    if: github.repository == 'rustls/rustls' && github.ref == 'refs/heads/main'
    needs: generate
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4


================================================
FILE: .gitignore
================================================
target/
*.gcda
*.gcno
*.info
sslkeylogfile.txt
admin/rustfmt
.DS_Store
._.DS_Store
**/.DS_Store
**/._.DS_Store
/.idea
/default.profraw


================================================
FILE: .lycheeignore
================================================
^file\:\/\/\/.*\/target\/doc\/index\.html$
^http:\/\/www\.adobe\.com/$


================================================
FILE: .rustfmt.toml
================================================
# keep in sync with .rustfmt.unstable.toml
chain_width = 40
style_edition = "2024"


================================================
FILE: .rustfmt.unstable.toml
================================================
# keep in sync with .rustfmt.toml
chain_width = 40
style_edition = "2024"

# format imports
group_imports = "StdExternalCrate"
imports_granularity = "Module"


================================================
FILE: .taplo.toml
================================================
[formatting]
align_comments = false
column_width = 110


================================================
FILE: BENCHMARKING.md
================================================
# Benchmarking

This repository includes benchmarks for multiple use cases. They are described below, along with
information on how to run them.

## Throughput and memory usage benchmarks

These benchmarks measure the throughput and memory footprint you get from rustls. They have been
used in the past to compare performance against OpenSSL:

- See [the most up-to-date reports](https://rustls.dev/perf/).
- See the [historical results from December 2023](https://github.com/aochagavia/rustls-bench-results).
- See the [historical results from July 2019](https://jbp.io/2019/07/01/rustls-vs-openssl-performance.html).

You can also use them to evaluate rustls' performance on different hardware (e.g. a bare-metal server
with support for AVX-512 instructions vs. a cloud VM with a consumer-grade CPU).

The measured aspects are:

1. Bulk data transfer throughput in MiB/s;
2. Handshake throughput (full, session id, tickets) in handshakes per second;
3. Memory usage per connection.

If you are interested in comparing against OpenSSL, check out the [twin OpenSSL
benchmarks](https://github.com/ctz/openssl-bench), which produce similar measurements.

#### Building

The benchmarks are implemented in `rustls-bench/src/main.rs`.
Use `cargo build --profile=bench -p rustls-bench --features aws-lc-rs` to obtain the corresponding
binary (you can toggle conditionally compiled code with the `--no-default-features` and `--features`
flags) or simply run below, which will build and run the benchmark.

Note: The usage of `--release` instead of `--profile=bench` also works, but it is less performant.

#### Running

There is a makefile in [admin/bench-measure.mk](admin/bench-measure.mk) providing useful commands to
facilitate benchmarking:

- `make measure`: runs bulk transfer and handshake throughput benchmarks using a predefined list of
  cipher suites.
- `make memory`: measures memory usage for different amounts of connections.

You can inspect the makefile to get an idea of the command line arguments accepted by `bench`. With
the right arguments, you can run benchmarks for other cipher suites (through `cargo run --release`
or by directly launching the compiled binary).

#### Reducing noise

We usually extend the duration of the benchmarks in an attempt to neutralize the effect of cold CPU
and page caches, giving us more accurate results. This is done through the `BENCH_MULTIPLIER`
environment variable, which tells the benchmark runner to multiply the amount of work done. For
instance, `BENCH_MULTIPLIER=8` will ensure we do 8 times the work.

Additional ways to reduce noise are:

- Disabling ASLR (through `setarch -R`).
- Disabling CPU dynamic frequency scaling (usually on the BIOS/UEFI level).
- Disabling CPU hyper-threading (usually on the BIOS/UEFI level).
- Setting the Linux CPU governor to performance for all cores.
- Running the benchmarks multiple times (e.g. 30) and taking the median for each scenario (the
  [December 2023 results](https://github.com/aochagavia/rustls-bench-results) include Python code
  doing this).

## CI benchmarks

These benchmarks are meant to provide _automated_ and _accurate_ feedback on a PR's performance
impact compared to the main branch. By automating them we ensure they are regularly used, by keeping
them accurate we ensure they are actionable (i.e. too much noise would train reviewers to ignore the
information).

The benchmarks themselves are located under [ci-bench](ci-bench), together with a detailed readme
(including instructions on how to run them locally). The automated runner lives in its own
[repository](https://github.com/rustls/rustls-bench-app) and is deployed to a bare-metal machine to
ensure low-noise results.

## Nightly benchmarks

There are some `#[bench]` benchmarks spread throughout the codebase. We do not use them
systematically, but they help understand the performance of smaller pieces of code (one or two
functions), which would be difficult to see when the unit-of-benchmark is an entire handshake.

These benchmarks require a nightly compiler. If you are using `rustup`, you can run them with
`RUSTFLAGS=--cfg=bench cargo +nightly bench`


================================================
FILE: CHANGELOG.md
================================================
# Changelog

The detailed list of changes in each release can be found at
https://github.com/rustls/rustls/releases.


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of conduct

This project adopts the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct).
Please email rustls-mod@googlegroups.com to report any instance of misconduct, or if you
have any comments or questions on the Code of Conduct.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

Thanks for considering helping this project.  There are many
ways you can help: using the library and reporting bugs,
reporting usability issues, making additions and improvements
to the library, documentation and finding security bugs.

## Reporting bugs

Please file a github issue.  Include as much information as
possible.  Suspected protocol bugs are easier debugged with
a pcap or reproduction steps.

Feel free to file github issues to get help, or ask a question.

If you believe you've found a security bug please
[open a draft security advisory](https://github.com/rustls/rustls/security/advisories/new)
in GitHub, and not as a regular repository issue. See [SECURITY.md] for more
information.

[SECURITY.md]: SECURITY.md

## Code changes

Some ideas and guidelines for contributions:

- For large features, file an issue prior to starting work.
  This means everyone can see what is in progress prior to a PR.
- Feel free to submit a PR even if the work is not totally finished,
  for feedback or to hand-over.
- Prefer not to reference github issue or PR numbers in commits.
- Try to keep code formatting commits separate from functional commits.
- See [`.github/workflows/build.yml`](.github/workflows/build.yml) for
  how to run the various test suites, and how to make coverage measurements.
- I run `cargo outdated` prior to major releases; but PRs to update specific
  dependencies are welcome.

## Commit history

We prefer to keep the commit history clean and easy to follow. As such, we prefer small commits
that do one thing. In particular:

* Avoid mixing refactoring and functional changes in the same commit if possible
* Make mechanical changes (like renaming or moving code around) in a separate commit
* Isolate updates to `Cargo.lock` in their own commits

Our default workflow is to rebase clean commit history from a PR to `main`.

## Security bugs

Please report security bugs by [opening a draft security advisory](https://github.com/rustls/rustls/security/advisories/new)
in GitHub, and not as a regular repository issue.

See [SECURITY.md] for more information.

If you're *looking* for security bugs, this crate is set up for
`cargo fuzz` but would benefit from more runtime, targets and corpora.

## Testing

- Features involving additions to the public API should have (at least)
  API-level tests (see [`rustls-test/tests/api/`](rustls-test/tests/api/)).
- Protocol additions should have some coverage -- consider enabling
  corresponding tests in the bogo suite, or writing some ad hoc tests.

PRs which cause test failures or a significant coverage decrease
are unlikely to be accepted.

### Testing with multiple `CryptoProvider`s

Generally any test that relies on a `CryptoProvider` anywhere, should
be run against all `CryptoProvider`s, such that
`cargo test --all-features` runs the test several times.

For integration tests -- where the amount of test code is more significant,
we instantiate the tests by importing them multiple times, and then the tests
resolve the provider module to use via `super::provider`.  For example, see
`rustls-test/tests/api.rs` and `rustls-test/tests/api/kx.rs`.

## Style guide

### Ordering

#### Top-down ordering within modules

Within a module, we prefer to order items top-down. This means that items within
a module will depend on items defined below them, but not (usually) above them.
The idea here is that the public API, with more internal dependencies, will be
read (and changed) more often, and putting it closer to the top of the module
makes it more accessible.

This can be surprising to many engineers who are used to the bottom-up ordering
used in languages like Python, where items can have a run-time dependency on
other items defined in the same module.

Usually `const` values will thus go on the bottom of the module (least complex,
usually no dependencies of their own), although in larger modules it can make
sense to place a `const` directly below the user (especially if there is a
single user, or just a few co-located users).

The `#[cfg(test)] mod tests {}` module goes on the very bottom, if present.
Other module definitions (like `mod foo { .. }`) can be ordered among other
items as it makes sense in the context of the items imported from them.
Module declarations (like `mod foo;`) should be ordered before other items
but after imports. Imports from local modules (both declared and defined)
should be kept close to the module declaration/definition.

Files that have substantial amounts of code inside inline modules should
probably avoid also having much code outside of these modules.

#### Ordering for a given type

For a given type, we prefer to order items as follows:

1. The type definition (`struct` or `enum`)
2. The inherent `impl` block (that is, not a trait implementation)
3. `impl` blocks for traits, from most specific to least specific.
   The least specific would be something like a `Debug` or `Clone` impl.

#### Ordering associated functions within an inherent `impl` block

Here's a guide to how we like to order associated functions:

0. Associated functions (that is, `fn foo() {}` instead of `fn foo(&self) {}`)
1. Constructors, starting with the constructor that takes the least arguments
2. Public API that takes a `&mut self`
3. Public API that takes a `&self`
4. Private API that takes a `&mut self`
5. Private API that takes a `&self`
6. `const` values

Note that we usually also practice top-down ordering here; where these are in
conflict, make a choice that you think makes sense. For getters and setters, the
order should typically mirror the order of the fields in the type definition.

#### Attribute ordering

Order attributes so that documentation appears first, and the attributes with the
most effect on the meaning and function of the type appear last.  For example:

```rust
/// Doc comment always first
#[cfg(feature-gates)]
#[allow(lint-configuration)]
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct Foo;
```

Prefer to write `derive`d traits in alphabetical order.

### Functions

#### Consider avoiding short single-use functions

While single-use functions can make sense if the algorithm is sufficiently complex
that it warrants an explicit name and interface, using many short single-use
functions can make the code harder to follow, due to having to jump around in order
to gain an understanding of what's going on. When writing a single-use function,
consider whether it needs the dedicated interface, or if it could be inlined into
its caller instead.

#### Consider avoiding free-standing functions

If a function's semantics or implementation are strongly dependent on one of its
arguments, and the argument is defined in a type within the current crate,
prefer using a method on the type. Similarly, if a function is taking multiple
arguments that originate from the same common type in all call-sites it is
a strong candidate for becoming a method on the type.

#### Order arguments from most specific to least specific

When writing a function, we prefer to order arguments from most specific to
least specific. This means that an `image_id` might go before the `domain`,
which will go before the `app` context. More specific arguments are more
differentiating between a given function and other functions, so putting them
first makes it easier to infer the context/meaning of the function (compared to
starting with a number of generic context-like types).

#### Use `impl` where possible

We prefer to use `impl ...` for arguments and return types when there's a single
use of the type. Generic type argument bounds add a level of indirection that's
harder to read in one pass.

#### Avoid type elision for fully qualified function calls

We prefer to write [fully qualified function calls] with types included, rather
than elided. For example:

```rust
// Incorrect:
<_>::default()

// Correct:
CertificateChain::default()
```

[fully qualified function calls]: https://doc.rust-lang.org/beta/reference/expressions/call-expr.html#disambiguating-function-calls

#### Validation

Where possible, avoid writing `validate` or `check` type functions that try to
check for error conditions based on the state of a populated object. Prefer
["parse, don't validate"](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
style and try to use the type system to make it impossible for invalid states to
be represented.

#### Error handling

We use `Result` types pervasively throughout the code to signal error cases.
Outside of unit/integration tests we prefer to avoid `unwrap()` and `expect()`
calls unless there is a clear invariant which can be locally validated by the
structure of the code. If there is such an invariant, we usually add a comment
explaining how the invariant is upheld. In other cases (especially for error
cases which can arise from network traffic, which could represent an attacker),
we always prefer to handle errors and ultimately return an error to the network
peer or close the connection.

### Expressions

#### Avoid single-use bindings

We generally make full use of the expression-oriented nature of Rust. For
example, when using iterators we prefer to use `map` and other combinators
instead of `for`-loops when possible, and will often avoid variable bindings if
a variable is only used once. Naming variables takes cognitive efforts, and so
does tracking references to bindings in your mind. One metric we like to
minimize is the number of mutable bindings in a given scope.

Remember that the overall goal is to make the code easy to understand.
Combinators can help with this by eliding boilerplate (like replacing a
`None => None` arm with a `map()` call), but they can also make it harder to
understand the code. One example is that a combinator chain like
`.map().map_err()` might be harder to understand than a `match` statement
(since, in this case, both of the arms have a significant transformation).

#### Use early `return` and `continue` to reduce nesting

The typed nature of Rust can cause some code to end up at deeply indented
levels, which we call "rightward drift". This makes lines shorter, making the
code harder to read. To avoid this, try to `return` early for error cases, or
`continue` early in a loop to skip an iteration.

#### Hoist common expression returns

When writing a `match` or `if` expression that has arms that each share a return
type (e.g. `Ok(...)`), hoist the commonality outside the `match`. This helps
separate out the important differences and reduces code duplication.

```rust
// Incorrect:
match foo {
    1..10 => Ok(do_one_thing()),
    _ => Ok(do_another()),
}

// Correct:
Ok(match foo {
    1..10 => do_one_thing(),
    _ => do_another(),
})
```

#### Avoid `ref` in match patterns

When writing match expressions, try to avoid using `ref` in patterns. Prefer
taking a reference on the
[scrutinee](https://doc.rust-lang.org/reference/expressions/match-expr.html)
of the `match`.

Since the addition of [binding
modes](https://rust-lang.github.io/rfcs/2005-match-ergonomics.html) for improved
match ergonomics the `ref` keyword is unidiomatic and can be unfamiliar to
readers.

### Naming

#### Use concise names

We prefer concise names, especially for local variables, but prefer to
expand acronyms/abbreviations that are not very well known (e.g. prefer
`key_usage` instead of `ku`, `anonymous` instead of `anon`). Extremely common
short-forms like `url` are acceptable.

Avoid adding a suffix for a variable that describes its type (provided that its
type is hard to confuse with other types -- for example, we do still use `_id`
suffixes because we usually use numeric IDs for database entities). The
precision/conciseness trade-off for variable names also depends on the scope of
the binding.

#### Avoid `get_` prefixes

Per the
[API guidelines](https://rust-lang.github.io/api-guidelines/naming.html#getter-names-follow-rust-convention-c-getter),
`get_()` prefixes are discouraged.

#### Enum variants

When implementing or modifying an `enum` type, list its variants in alphabetical
order. It's acceptable to ignore this advice when matching the order imposed by
an external source, e.g. a standards document.

Prefer active verbs for variant names. E.g. `Allow` instead of `Allowed`,
`Forbid` instead of `Forbidden`. Avoid faux-bools like `Yes` and `No`, instead
preferring variant names that are descriptive of the different states.

#### Don't elide generic lifetimes

We prefer not to elide lifetimes when naming types that are generic over
lifetimes. Always include a lifetime placeholder (e.g. `<'_>`) to avoid
confusion.

### Imports

We use 3 blocks of imports in our Rust files:

1. `std` imports
2. Imports from external crates
3. Crate-internal imports

We believe that this makes it easier to see where a particular import comes from.

Within the import blocks we prefer to separate imports that don't share a parent
module. For example,

```rust
// Incorrect
use alloc::{format, vec::Vec};

// Correct
use alloc::format;
use alloc::vec::Vec;
```

We prefer to reference types and traits by an imported symbol name instead of
using qualified references. Qualification paths generally add noise and are
unnecessary. The one exception to this is when the symbol name is overly
generic, or easily confused between different crates. In this case we prefer to
import the symbol name under an alias, or if the parent module name is short,
using a one-level qualified path. E.g. for a crate with a local `Error` type,
prefer to `import std::error::Error as StdError`.

### Exports

We prefer to export types under a single name, avoiding re-exporting types from
the top-level `lib.rs`. The exception to this are "paved path" exports that we
expect every user will need. The canonical example of such types are
`client::ClientConfig` and `server::ServerConfig`. In general this sort of type
is rare and most new types should be exported only from the module in which they
are defined.

### Misc

#### Numeric literals

Prefer a numeric base that fits with the domain of the value being used. E.g.
use hexadecimal for protocol message literals, and octal for UNIX privileges.
Use digit grouping to make larger numeric constants easy to read, e.g. use
`100_000_000` instead of `100000000`.

#### Avoid type aliases

We prefer to avoid type aliases as they obfuscate the underlying type and
don't provide additional type safety. Using the
[newtype idiom](https://doc.rust-lang.org/rust-by-example/generics/new_types.html)
is one alternative when an abstraction boundary is worth the added complexity.

#### Type exhaustiveness

Public enums should be marked as _either_ `#[non_exhaustive]` or `#[allow(clippy::exhaustive_enums)]`.
The latter is suitable for enums that are already complete by definition.  For example:
`enum CoinFlip { Heads, Tails }` is complete.  Err on the side of marking something `#[non_exhaustive]`.

The same applies to structs, with the detail that no manual marking is needed for
structures with at least one private field.

## Design and Architecture

Some general concepts about how the library should fit together:

- Linker friendliness
- Small mandatory API
- Safe and sensible defaults
- Separation of mechanism and policy

### Linker friendliness

When a program incorporates rustls, we should try to ensure that parts
that are not used can be discarded by the linker.

The linker can discard code if it is unreachable by the code that is referenced
by the downstream program.  This generally means that:

- runtime trait-based or function pointer dynamic dispatch is good,
- compile-time trait-based generics are good (so long as the same code is
  not monomorphized multiple times in a typical program),
- enum-based dispatch is bad.

Here is an example that is less good:

```rust
enum Algorithm {
    Aes128,
    ChaCha20,
}

fn encrypt(alg: Algorithm, buffer: &mut [u8]) {
    match alg {
        Algorithm::Aes128 => encrypt_aes128(buffer),
        Algorithm::ChaCha20 => encrypt_chacha20(buffer),
    }
}
```

A program that only used `encrypt(Algorithm::ChaCha20, ..)` would end
up with a copy of AES inside.  (If such a function was
inlined into its caller, the reference to `encrypt_aes128` could
theoretically be deleted if the compiler can be certain of the value
of `alg`.  This is not guaranteed to happen.)

Instead, prefer:

```rust
trait Algorithm {
    fn encrypt(&self, buffer: &mut [u8]);
}

struct Aes128;
struct ChaCha20;

impl Algorithm for Aes128 {
    fn encrypt(&self, buffer: &mut [u8]) {
        encrypt_aes128(buffer)
    }
}

impl Algorithm for ChaCha20 {
    fn encrypt(&self, buffer: &mut [u8]) {
        encrypt_chacha20(buffer)
    }
}
```

(or a function-pointer equivalent, which would be less idiomatic Rust.)

Some judgement is needed: this is only worth it if a reasonable program
would not use all the possibilities, and the individual parts are large
enough to have an impact on the size of a final program.

### Small mandatory API

We should try to keep the API for achieving the most common goals
as simple as possible.  Good models for this are `simpleclient` and
`simpleserver`.  The purpose of this is to allow people interacting
with the library for the first time to make progress.

### Safe and sensible defaults

We should be confident to make decisions on behalf of our users and
express that in the [library's defaults][defaults].  It is good to
encode our experience of TLS in this way, and we should not require that
users are experts in TLS to end up with a result that is working,
secure, stable, and performant.

[defaults]: https://docs.rs/rustls/latest/rustls/manual/_05_defaults/index.html

### Separation of mechanism and policy

A configuration knob with a good default is preferable to a fixed
behavior, even if the end result is the same for 99% of users.

With that said, we should take care to avoid overloading users with
choices, and direct them (with examples, documentation, and simplified
top-level APIs) away from that complexity.

There is quite a lot of nuance here: configuration should avoid allowing
bad outcomes (in the cryptographic, memory safety, and "good netizen" senses).
Where that is not possible we typically include `danger` in API naming to
assist code reviewers of end-user code.

## Licensing

Contributions are made under [rustls's licenses](LICENSE).


================================================
FILE: Cargo.toml
================================================
[workspace]
members = [
  # Bogo test shim
  "bogo",
  # CI benchmarks
  "ci-bench",
  # Network-based tests
  "connect-tests",
  # tests and example code
  "examples",
  # Tests that require OpenSSL
  "openssl-tests",
  # example of custom provider
  "provider-example",
  # the main library and tests
  "rustls",
  # AWS-LC based crypto provider
  "rustls-aws-lc-rs",
  # the ring crypto provider
  "rustls-ring",
  # common code for testing the core crate
  "rustls-test",
  # benchmarking tool
  "rustls-bench",
  # experimental post-quantum algorithm support
  "rustls-post-quantum",
  # rustls cryptography provider integration tests
  "rustls-provider-test",
  # rustls cryptography provider for fuzzing
  "rustls-fuzzing-provider",
  # utility code
  "rustls-util",
]

## Deliberately not included in `members`:
exclude = [
  # `cargo fuzz` integration (requires nightly)
  "fuzz",
]

default-members = [
  # ---
  "examples",
  "rustls",
  "rustls-aws-lc-rs",
  "rustls-ring",
  "rustls-test",
]
resolver = "2"

[workspace.dependencies]
anyhow = "1.0.73"
asn1 = "0.24"
async-trait = "0.1.74"
aws-lc-rs = { version = "1.14", default-features = false }
base64 = "0.22"
bencher = "0.1.5"
brotli = { version = "8", default-features = false, features = ["std"] }
brotli-decompressor = "5.0.0"
byteorder = "1.4.3"
chacha20poly1305 = { version = "0.10", default-features = false, features = ["alloc"] }
clap = { version = "4.3.21", features = ["derive", "env"] }
crabgrind = "0.2"
criterion = "0.8"
der = "0.7"
ecdsa = { version = "0.16.8", features = ["pem"] }
env_logger = "0.11"
graviola = "0.3"
hashbrown = { version = "0.16", default-features = false, features = ["default-hasher", "inline-more"] }
hex = "0.4"
hickory-resolver = { version = "0.25", features = ["https-aws-lc-rs", "webpki-roots"] }
hmac = "0.12"
hpke-rs = "0.6"
hpke-rs-crypto = "0.6"
hpke-rs-rust-crypto = "0.6"
itertools = "0.14"
log = { version = "0.4.8" }
macro_rules_attribute = "0.2"
mio = { version = "1", features = ["net", "os-poll"] }
num-bigint = "0.4.4"
once_cell = { version = "1.16", default-features = false, features = ["alloc", "race"] }
openssl = "0.10"
p256 = { version = "0.13.2", default-features = false, features = ["alloc", "ecdsa", "pkcs8"] }
pkcs8 = "0.10.2"
pki-types = { package = "rustls-pki-types", version = "1.14", features = ["alloc"] }
rand_core = { version = "0.6", features = ["getrandom"] }
rayon = "1.7"
rcgen = { version = "0.14.4", features = ["pem", "aws_lc_rs"], default-features = false }
regex = "1"
ring = "0.17"
rsa = { version = "0.9", features = ["sha2"], default-features = false }
rustc-hash = "2"
rustls-graviola = { version = "0.3" }
rustls-test = { path = "rustls-test/", default-features = false }
rustls-fuzzing-provider = { path = "rustls-fuzzing-provider/" }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sha2 = { version = "0.10", default-features = false }
signature = "2"
subtle = { version = "2.5.0", default-features = false }
time = { version = "0.3.6", default-features = false }
tikv-jemallocator = "0.6"
tokio = { version = "1.34", features = ["io-util", "macros", "net", "rt"] }
webpki = { package = "rustls-webpki", version = "=0.104.0-alpha.2", features = [
  "alloc",
], default-features = false }
webpki-roots = "1"
x25519-dalek = "2"
x509-parser = "0.18"
zeroize = "1.8"
zlib-rs = "0.6"

[profile.bench]
codegen-units = 1
lto = true

[workspace.lints.clippy]
alloc_instead_of_core = "warn"
cloned_instead_of_copied = "warn"
manual_let_else = "warn"
needless_collect = "warn"
needless_pass_by_ref_mut = "warn"
or_fun_call = "warn"
redundant_clone = "warn"
std_instead_of_core = "warn"
upper_case_acronyms = "warn"
use_self = "warn"

# Relax these clippy lints:
# - too_many_arguments: some things just need a lot of state, wrapping it
#   doesn't necessarily make it easier to follow what's going on
too_many_arguments = "allow"

# - new_without_default: for internal constructors, the indirection is not
#   helpful
new_without_default = "allow"

[workspace.lints.rust]
elided_lifetimes_in_paths = "warn"
trivial_numeric_casts = "warn"
unexpected_cfgs = { level = "warn", check-cfg = [
  "cfg(bench)",
  "cfg(coverage_nightly)",
  "cfg(rustls_docsrs)",
] }
unnameable_types = "warn"
unreachable_pub = "warn"
unused_extern_crates = "warn"
unused_import_braces = "warn"
unused_qualifications = "warn"

# ensure all our tests are against the local copy, never
# against the latest _published_ copy.
[patch.crates-io]
rustls = { path = "rustls" }


================================================
FILE: LICENSE
================================================
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.



================================================
FILE: LICENSE-APACHE
================================================
                              Apache License
                        Version 2.0, January 2004
                     http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

   "License" shall mean the terms and conditions for use, reproduction,
   and distribution as defined by Sections 1 through 9 of this document.

   "Licensor" shall mean the copyright owner or entity authorized by
   the copyright owner that is granting the License.

   "Legal Entity" shall mean the union of the acting entity and all
   other entities that control, are controlled by, or are under common
   control with that entity. For the purposes of this definition,
   "control" means (i) the power, direct or indirect, to cause the
   direction or management of such entity, whether by contract or
   otherwise, or (ii) ownership of fifty percent (50%) or more of the
   outstanding shares, or (iii) beneficial ownership of such entity.

   "You" (or "Your") shall mean an individual or Legal Entity
   exercising permissions granted by this License.

   "Source" form shall mean the preferred form for making modifications,
   including but not limited to software source code, documentation
   source, and configuration files.

   "Object" form shall mean any form resulting from mechanical
   transformation or translation of a Source form, including but
   not limited to compiled object code, generated documentation,
   and conversions to other media types.

   "Work" shall mean the work of authorship, whether in Source or
   Object form, made available under the License, as indicated by a
   copyright notice that is included in or attached to the work
   (an example is provided in the Appendix below).

   "Derivative Works" shall mean any work, whether in Source or Object
   form, that is based on (or derived from) the Work and for which the
   editorial revisions, annotations, elaborations, or other modifications
   represent, as a whole, an original work of authorship. For the purposes
   of this License, Derivative Works shall not include works that remain
   separable from, or merely link (or bind by name) to the interfaces of,
   the Work and Derivative Works thereof.

   "Contribution" shall mean any work of authorship, including
   the original version of the Work and any modifications or additions
   to that Work or Derivative Works thereof, that is intentionally
   submitted to Licensor for inclusion in the Work by the copyright owner
   or by an individual or Legal Entity authorized to submit on behalf of
   the copyright owner. For the purposes of this definition, "submitted"
   means any form of electronic, verbal, or written communication sent
   to the Licensor or its representatives, including but not limited to
   communication on electronic mailing lists, source code control systems,
   and issue tracking systems that are managed by, or on behalf of, the
   Licensor for the purpose of discussing and improving the Work, but
   excluding communication that is conspicuously marked or otherwise
   designated in writing by the copyright owner as "Not a Contribution."

   "Contributor" shall mean Licensor and any individual or Legal Entity
   on behalf of whom a Contribution has been received by Licensor and
   subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   copyright license to reproduce, prepare Derivative Works of,
   publicly display, publicly perform, sublicense, and distribute the
   Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   (except as stated in this section) patent license to make, have made,
   use, offer to sell, sell, import, and otherwise transfer the Work,
   where such license applies only to those patent claims licensable
   by such Contributor that are necessarily infringed by their
   Contribution(s) alone or by combination of their Contribution(s)
   with the Work to which such Contribution(s) was submitted. If You
   institute patent litigation against any entity (including a
   cross-claim or counterclaim in a lawsuit) alleging that the Work
   or a Contribution incorporated within the Work constitutes direct
   or contributory patent infringement, then any patent licenses
   granted to You under this License for that Work shall terminate
   as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
   Work or Derivative Works thereof in any medium, with or without
   modifications, and in Source or Object form, provided that You
   meet the following conditions:

   (a) You must give any other recipients of the Work or
       Derivative Works a copy of this License; and

   (b) You must cause any modified files to carry prominent notices
       stating that You changed the files; and

   (c) You must retain, in the Source form of any Derivative Works
       that You distribute, all copyright, patent, trademark, and
       attribution notices from the Source form of the Work,
       excluding those notices that do not pertain to any part of
       the Derivative Works; and

   (d) If the Work includes a "NOTICE" text file as part of its
       distribution, then any Derivative Works that You distribute must
       include a readable copy of the attribution notices contained
       within such NOTICE file, excluding those notices that do not
       pertain to any part of the Derivative Works, in at least one
       of the following places: within a NOTICE text file distributed
       as part of the Derivative Works; within the Source form or
       documentation, if provided along with the Derivative Works; or,
       within a display generated by the Derivative Works, if and
       wherever such third-party notices normally appear. The contents
       of the NOTICE file are for informational purposes only and
       do not modify the License. You may add Your own attribution
       notices within Derivative Works that You distribute, alongside
       or as an addendum to the NOTICE text from the Work, provided
       that such additional attribution notices cannot be construed
       as modifying the License.

   You may add Your own copyright statement to Your modifications and
   may provide additional or different license terms and conditions
   for use, reproduction, or distribution of Your modifications, or
   for any such Derivative Works as a whole, provided Your use,
   reproduction, and distribution of the Work otherwise complies with
   the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
   any Contribution intentionally submitted for inclusion in the Work
   by You to the Licensor shall be under the terms and conditions of
   this License, without any additional terms or conditions.
   Notwithstanding the above, nothing herein shall supersede or modify
   the terms of any separate license agreement you may have executed
   with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
   names, trademarks, service marks, or product names of the Licensor,
   except as required for reasonable and customary use in describing the
   origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
   agreed to in writing, Licensor provides the Work (and each
   Contributor provides its Contributions) on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   implied, including, without limitation, any warranties or conditions
   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
   PARTICULAR PURPOSE. You are solely responsible for determining the
   appropriateness of using or redistributing the Work and assume any
   risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
   whether in tort (including negligence), contract, or otherwise,
   unless required by applicable law (such as deliberate and grossly
   negligent acts) or agreed to in writing, shall any Contributor be
   liable to You for damages, including any direct, indirect, special,
   incidental, or consequential damages of any character arising as a
   result of this License or out of the use or inability to use the
   Work (including but not limited to damages for loss of goodwill,
   work stoppage, computer failure or malfunction, or any and all
   other commercial damages or losses), even if such Contributor
   has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
   the Work or Derivative Works thereof, You may choose to offer,
   and charge a fee for, acceptance of support, warranty, indemnity,
   or other liability obligations and/or rights consistent with this
   License. However, in accepting such obligations, You may act only
   on Your own behalf and on Your sole responsibility, not on behalf
   of any other Contributor, and only if You agree to indemnify,
   defend, and hold each Contributor harmless for any liability
   incurred by, or claims asserted against, such Contributor by reason
   of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

   To apply the Apache License to your work, attach the following
   boilerplate notice, with the fields enclosed by brackets "[]"
   replaced with your own identifying information. (Don't include
   the brackets!)  The text should be enclosed in the appropriate
   comment syntax for the file format. We also recommend that a
   file or class name and description of purpose be included on the
   same "printed page" as the copyright notice for easier
   identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


================================================
FILE: LICENSE-ISC
================================================
ISC License (ISC)
Copyright (c) 2016, Joseph Birr-Pixton <jpixton@gmail.com>

Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.


================================================
FILE: LICENSE-MIT
================================================
Copyright (c) 2016 Joseph Birr-Pixton <jpixton@gmail.com>

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
<p align="center">
  <img width="460" height="300" src="https://raw.githubusercontent.com/rustls/rustls/main/admin/rustls-logo-web.png">
</p>

<p align="center">
Rustls is a modern TLS library written in Rust.
</p>

# Status

Rustls is used in production at many organizations and projects. We aim to maintain
reasonable API surface stability but the API may evolve as we make changes to accommodate
new features or performance improvements.

We have a [roadmap](ROADMAP.md) for our future plans. We also have [benchmarks](BENCHMARKING.md) to
prevent performance regressions and to let you evaluate rustls on your target hardware.

If you'd like to help out, please see [CONTRIBUTING.md](CONTRIBUTING.md).

[![Build Status](https://github.com/rustls/rustls/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/rustls/rustls/actions/workflows/build.yml?query=branch%3Amain)
[![Coverage Status (codecov.io)](https://codecov.io/gh/rustls/rustls/branch/main/graph/badge.svg)](https://codecov.io/gh/rustls/rustls/)
[![Documentation](https://docs.rs/rustls/badge.svg)](https://docs.rs/rustls/)
[![Chat](https://img.shields.io/discord/976380008299917365?logo=discord)](https://discord.gg/MCSB76RU96)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9034/badge)](https://www.bestpractices.dev/projects/9034)

The maintainers pronounce "rustls" as rustles (rather than rust-TLS), but we don't feel strongly
about it.

## Changelog

The detailed list of changes in each release can be found at
https://github.com/rustls/rustls/releases.

# Documentation

https://docs.rs/rustls/

# Approach

Rustls is a TLS library that aims to provide a good level of cryptographic security,
requires no configuration to achieve that security, and provides no unsafe features or
obsolete cryptography by default.

Rustls implements TLS1.2 and TLS1.3 for both clients and servers. See [the full
list of protocol features](https://docs.rs/rustls/latest/rustls/manual/_04_features/index.html).

### Platform support

While Rustls itself is platform independent, it requires the use of cryptography primitives
for implementing the cryptography algorithms used in TLS. In Rustls, a
[`crypto::CryptoProvider`] represents a collection of crypto primitive implementations.

By providing a custom instance of the [`crypto::CryptoProvider`] struct, you
can replace all cryptography dependencies of rustls.  This is a route to being portable
to a wider set of architectures and environments, or compliance requirements.  See the
[`crypto::CryptoProvider`] documentation for more details.

Rustls requires Rust 1.83 or later.

[`crypto::CryptoProvider`]: https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html

### Cryptography providers

Since Rustls 0.22 it has been possible to choose the provider of the cryptographic primitives
that Rustls uses. This may be appealing if you have specific platform, compliance or feature
requirements.

From 0.24, users must explicitly provide a crypto provider when constructing `ClientConfig` or
`ServerConfig` instances. See the [`crypto::CryptoProvider`] documentation for more details.

#### First-party providers

The Rustls project currently maintains two cryptography providers:

* [`rustls-aws-lc-rs`] - a provider that uses the [`aws-lc-rs`] crate for cryptography.
While this provider can be harder to build on [some platforms][aws-lc-rs-platforms-faq], it provides excellent
performance and a complete feature set (including post-quantum algorithms).
* [`rustls-ring`] - a provider that uses the [`ring`] crate for cryptography. This
provider is easier to build on a variety of platforms, but has a more limited feature set
(for example, it does not support post-quantum algorithms).

The Rustls team recommends using the [`rustls-aws-lc-rs`] crate for its complete feature set
and performance. See [the aws-lc-rs FAQ][aws-lc-rs-platforms-faq] for more details of the
platform/architecture support constraints in aws-lc-rs.

See the documentation for [`crypto::CryptoProvider`] for details on how providers are
selected.

(For rustls versions prior to 0.24, both of these providers were shipped as part of the rustls
crate, and Cargo features were used to select the preferred provider. The `aws-lc-rs` feature
was enabled by default.)

[`rustls-aws-lc-rs`]: https://crates.io/crates/rustls-aws-lc-rs
[`aws-lc-rs`]: https://crates.io/crates/aws-lc-rs
[aws-lc-rs-platforms-faq]: https://aws.github.io/aws-lc-rs/faq.html#can-i-run-aws-lc-rs-on-x-platform-or-architecture
[`rustls-ring`]: https://crates.io/crates/rustls-ring
[`ring`]: https://crates.io/crates/ring

#### Third-party providers

The community has also started developing third-party providers for Rustls:

* [`boring-rustls-provider`] - a work-in-progress provider that uses [`boringssl`] for
cryptography.
* [`rustls-ccm`] - adds AES-CCM cipher suites (TLS 1.2 and 1.3) using [`RustCrypto`], for IoT/constrained-device protocols (IEEE 2030.5, Matter, RFC 7925).
* [`rustls-graviola`] - a provider that uses [`graviola`] for cryptography.
* [`rustls-mbedtls-provider`] - a provider that uses [`mbedtls`] for cryptography.
* [`rustls-openssl`] - a provider that uses [OpenSSL] for cryptography.
* [`rustls-rustcrypto`] - an experimental provider that uses the crypto primitives
from [`RustCrypto`] for cryptography.
* [`rustls-symcrypt`] - a provider that uses Microsoft's [SymCrypt] library.
* [`rustls-wolfcrypt-provider`] - a work-in-progress provider that uses [`wolfCrypt`] for cryptography.

[`rustls-ccm`]: https://github.com/jsulmont/rustls-ccm
[`rustls-graviola`]: https://crates.io/crates/rustls-graviola
[`graviola`]: https://github.com/ctz/graviola
[`rustls-mbedtls-provider`]: https://github.com/fortanix/rustls-mbedtls-provider
[`mbedtls`]: https://github.com/Mbed-TLS/mbedtls
[`rustls-openssl`]: https://github.com/tofay/rustls-openssl
[OpenSSL]: https://openssl-library.org/
[`rustls-symcrypt`]: https://github.com/microsoft/rustls-symcrypt
[SymCrypt]: https://github.com/microsoft/SymCrypt
[`boring-rustls-provider`]: https://github.com/janrueth/boring-rustls-provider
[`boringssl`]: https://github.com/google/boringssl
[`rustls-rustcrypto`]: https://github.com/RustCrypto/rustls-rustcrypto
[`RustCrypto`]: https://github.com/RustCrypto
[`rustls-wolfcrypt-provider`]: https://github.com/wolfSSL/rustls-wolfcrypt-provider
[`wolfCrypt`]: https://www.wolfssl.com/products/wolfcrypt

#### Custom provider

We also provide a simple example of writing your own provider in the [custom provider example].
This example implements a minimal provider using parts of the [`RustCrypto`] ecosystem.

See the [Making a custom CryptoProvider] section of the documentation for more information
on this topic.

[custom provider example]: https://github.com/rustls/rustls/tree/main/provider-example/
[`RustCrypto`]: https://github.com/RustCrypto
[Making a custom CryptoProvider]: https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html#making-a-custom-cryptoprovider

# Example code

Our [examples] directory contains demos that show how to handle I/O using the
[`stream::Stream`] helper, as well as more complex asynchronous I/O using [`mio`].
If you're already using Tokio for an async runtime you may prefer to use
[`tokio-rustls`] instead of interacting with rustls directly.

The [`mio`] based examples are the most complete, and discussed below. Users
new to Rustls may prefer to look at the simple client/server examples before
diving in to the more complex MIO examples.

[examples]: examples/
[`stream::Stream`]: https://docs.rs/rustls/latest/rustls/struct.Stream.html
[`mio`]: https://docs.rs/mio/latest/mio/
[`tokio-rustls`]: https://docs.rs/tokio-rustls/latest/tokio_rustls/

## Client example program

The MIO client example program is named `tlsclient-mio`.

Some sample runs:

```
$ cargo run --bin tlsclient-mio -- --http mozilla-modern.badssl.com
HTTP/1.1 200 OK
Server: nginx/1.6.2 (Ubuntu)
Date: Wed, 01 Jun 2016 18:44:00 GMT
Content-Type: text/html
Content-Length: 644
(...)
```

or

```
$ cargo run --bin tlsclient-mio -- --http expired.badssl.com
TLS error: InvalidCertificate(Expired)
Connection closed
```

Run `cargo run --bin tlsclient-mio -- --help` for more options.

## Server example program

The MIO server example program is named `tlsserver-mio`.

Here's a sample run; we start a TLS echo server, then connect to it with
`openssl` and `tlsclient-mio`:

```
$ cargo run --bin tlsserver-mio -- --certs test-ca/rsa-2048/end.fullchain --key test-ca/rsa-2048/end.key -p 8443 echo &
$ echo hello world | openssl s_client -ign_eof -quiet -connect localhost:8443
depth=2 CN = ponytown RSA CA
verify error:num=19:self signed certificate in certificate chain
hello world
^C
$ echo hello world | cargo run --bin tlsclient-mio -- --cafile test-ca/rsa-2048/ca.cert --port 8443 localhost
hello world
^C
```

Run `cargo run --bin tlsserver-mio -- --help` for more options.

# License

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.

# Project Membership

- Joe Birr-Pixton ([@ctz], Project Founder - full-time funded by [Prossimo])
- Dirkjan Ochtman ([@djc], Co-maintainer)
- Daniel McCarney ([@cpu], Co-maintainer)
- Josh Aas ([@bdaehlie], Project Management)

[@ctz]: https://github.com/ctz
[@djc]: https://github.com/djc
[@cpu]: https://github.com/cpu
[@bdaehlie]: https://github.com/bdaehlie
[Prossimo]: https://www.memorysafety.org/initiative/rustls/

# Code of conduct

This project adopts the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct).
Please email rustls-mod@googlegroups.com to report any instance of misconduct, or if you
have any comments or questions on the Code of Conduct.


================================================
FILE: RELEASING.md
================================================
## Before making a release

1. Run `cargo update` followed by `cargo outdated`, to check if we have any
   dependency updates which are not already automatically taken by their semver specs.
   - If we do, take them if possible.  There should be dependabot PRs submitted for these already, but if
     not make separate commits for these and land those first.
2. Run the daily-tests CI workflow to check if we have any unfixed regressions.
   You can run the workflow manually for the to-be-released branch by visiting
   [the daily-tests workflow](https://github.com/rustls/rustls/actions/workflows/daily-tests.yml)
   in your browser and selecting "Run workflow".
3. Update `rustls/Cargo.toml` to set the correct version. Then run `cargo update` again in repo root and in `fuzz/`
   so that lock files pick the new rustls version.
4. Make a commit with the new version number, something like 'Prepare $VERSION'.  This
   should not contain functional changes: just version numbers, and perhaps markdown changes.
5. Do a dry run: in `rustls/` check `cargo publish --dry-run`.
   - Do not use `--allow-dirty`; use a separate working tree if needed.
6. Come up with text detailing headline changes for this release.  General guidelines:
   * :green_heart: include any breaking changes.
   * :green_heart: include any major new headline features.
   * :green_heart: include any major, user-visible bug fixes.
   * :green_heart: include any new API deprecations.
   * :green_heart: emphasise contributions from outside the maintainer team.
   * :x: omit any internal build, process or test improvements.
   * :x: omit any minor or user-invisible bug fixes.
   * :x: omit any changes to dependency versions (unless these cause breaking changes).
7. Open a PR with the above commit and include the release notes in the description.
   Wait for review and CI to confirm it as green.
   - Any red _should_ naturally block the release.
   - If rustc nightly is broken, this _may_ be acceptable if the reason is understood
     and does not point to a defect in rustls.  eg, at the time of writing in releasing 0.20:
     - `cargo fuzz` is broken: https://github.com/rust-fuzz/cargo-fuzz/issues/276
     - oss fuzz is broken: https://github.com/google/oss-fuzz/issues/6268
     (Both of these share the same root cause of LLVM13 breaking changes; which are
      unfortunately common when rustc nightly takes a new LLVM.)

## Making a release

1. Tag the released version: eg. `git tag -m '0.20.0' v/0.20.0`
2. Push the tag: eg. `git push origin v/0.20.0`
3. Do the release: `cargo publish` when sat in `rustls/`.
   - Do not use `--allow-dirty`; use a separate working tree if needed.

## After making a release

1. Create a new GitHub release for that tag.  Use "Generate release notes" (against the tag for the previous release)
   as a starting point for the release description.  Then add the "headlines" produced earlier at the top.
2. Update dependent crates (eg, hyper-rustls, rustls-native-certs, etc.) if this was a semver-incompatible release.

## Maintenance point releases

When point releases for bug fixes and small backwards compatible changes, but `main` contains unreleased breaking
changes we follow a modified release process using a longer-lived maintenance branch.

1. Check if there is an existing release branch, e.g. `rel-0.21` for point releases in the `0.21.x` series.
   - If there is, use that branch.
   - If there is not, create a new branch from the tag for the previous release, e.g. `git checkout -b rel-0.21 v/0.21.0`.
     Remember to also create a branch protection rule for the release branch, matching the settings from `main`.
2. Make pull-requests for any changes you want to include in the point release, targeted against the release branch.
3. Follow the usual release process, but use the release branch instead of `main` when making the release.
   - For example, `cargo publish` should be run from the release branch, not `main`.


================================================
FILE: ROADMAP.md
================================================
# Rustls development roadmap

## Future priorities

Specific features, in rough order of priority:

* **Address asynchronous handshake interruption**.
  Allow completion of user-provided operations to be deferred.
  rustls/rustls#850

* **Support Encrypted Client Hello (ECH) (Server Side)**.
  Encrypted Client Hello is an upcoming standard from the TLS WG providing better
  protection for some of the data sent by a client in the initial Client Hello
  message. Rustls already supports client side ECH, we will add server side support.
  rustls/rustls#1980

General priorities:

* **Additional Performance Optimization**.
  Additional performance optimization including CPU usage, latency, and memory
  usage. The goal is to outperform OpenSSL across the board if we are not already.

* **Improve OpenSSL Compatibility**.
  Continue to improve the OpenSSL compatibility layer.

* **Rustls API Refinements**.
  Continue to improve the Rustls API. Aim for ease of use, clarity.

## Past priorities

Delivered in 0.23.11:

* **Enforce Confidentiality / Integrity Limits**.
  The QUIC use of TLS mandates limited usage of AEAD keys. While TLS 1.3 and 1.2
  do not require this, the same kinds of issues can apply here, and we should
  consider implementing limits for TLS over TCP as well.
  rustls/rustls#755

Delivered in 0.23.10:

* **Support Encrypted Client Hello (Client Side)**.
  Encrypted Client Hello is an upcoming standard from the TLS WG providing better
  protection for some of the data sent by a client in the initial Client Hello
  message.
  rustls/rustls#1718

Delivered in 0.23.9:

* **Support RFC 8879 Certificate Compression**.
  Support for a TLS extension that substantially shrinks certificates (one of the
  largest parts of the TLS handshake), improving handshake latency by decreasing
  bandwidth used.
  rustls/rustls#534

Delivered in [rustls-openssl-compat](https://github.com/rustls/rustls-openssl-compat) 0.1.0:

* **OpenSSL API Compatibility Layer**.
  Add an OpenSSL C API compatibility layer for adoption purposes.

Delivered in 0.23.2:

* **Support Post-Quantum Hybrid Key Exchange**.
  Experimental, optional support for the `X25519Kyber768Draft00` key exchange.
  This should track [the draft](https://datatracker.ietf.org/doc/draft-tls-westerbaan-xyber768d00/).
  rustls/rustls#1687

Delivered in 0.23:

* **FIPS Certification for Default Cryptographic Library**.
  Change the default cryptographic library to something with FIPS certification.
  rustls/rustls#1540

* **Add No-Allocation / Write-Through API**.
  Would make handshakes faster and give the caller more control over allocations.
  RFC: rustls/rustls#1420

* **Support no_std**.
  Enables use of rustls in more memory-constrained environments.
  RFC: rustls/rustls#1399

Delivered in [rustls-platform-verifier](https://github.com/rustls/rustls-platform-verifier) 0.1.0:

* **Improve OS Trust Verifier Support**.
  While we currently have a way to trust certificates stored in the platform trust
  store, platform trust stores can have other ways of restricting how/when roots
  that they expose are trusted. In order to rely on these (on Windows, Android,
  and Apple platforms) we should rely on the platform verifier directly.

Delivered in 0.22:

* **Enable Pluggable Cryptographic Back-ends**.
  Allow plugging in different cryptographic back-ends.
  rustls/rustls#1184

* **Comprehensive Performance Benchmarking**.
  Performance should be a headline feature of Rustls. We need to develop a more
  comprehensive benchmarking system so that we can assess and improve performance
  from multiple angles, including CPU usage, latency, and memory usage.

Delivered in 0.21:

* **Support IP Address Certificates**.
  There are some popular use cases where applications want TLS certificates for
  services that don’t have their own host name, relying on the IP address directly
  instead. This is common in Kubernetes deployments and service meshes.
  rustls/rustls#184

* **Implement RFC 8446 Appendix C.4 in session cache**.
  TLS clients should use session tickets at most once for resumption. Without this,
  TLS clients may be tracked across connections through reuse of session tickets.
  Requires changes of the internal APIs to the session caching infrastructure.
  rustls/rustls#466

* **Improve Client Certificate Authentication Support**.
  Rustls and webpki currently do not provide access to client information supplied
  as part of the certificate, and there’s no infrastructure to deal with revocation
  checks.
  rustls/rustls-ffi#87

Delivered in 0.20:

* **Add/extend support for TLS 1.3 Early Data**.
  Early data allows clients to submit data before the TLS handshake is complete
  in some cases (idempotent requests, data where replay is not a risk), improving
  latency in the cases of, for example, HTTP requests by submitting the request
  in parallel with the TLS handshake.


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

Security fixes will be backported only to the rustls versions for which the
original semver-compatible release was published less than 2 years ago.

For example, as of 2025-05-09 the latest release is 0.23.27.

* 0.23.0 was released in February of 2024
* 0.22.0 was released in December of 2023
* 0.21.0 was released in March of 2023
* 0.20.0 was released in September of 2021
* 0.19.0 was released in November of 2020

Therefore 0.23.x and 0.22.x will be updated, while 0.21.x, 0.20.x and 0.19.x
will not be.

> [!NOTE]
> We use the date of `crates.io` publication when evaluating the security
> policy. For example, while the Rustls 0.20.0 GitHub release note was created
> Jul, 2023 the actual release in `crates.io` was published in Sept. 2021.

### Minimum Supported Rust Version

From time to time we will update our minimum supported Rust version (MSRV)
in the course of normal development, subject to these constraints:

- Our MSRV will be no more recent than 9 versions old, or approximately 12 months.

> [!TIP]
> At the time of writing, the most recent Rust release is 1.90.  That means
> our MSRV could be as recent as 1.81. As it happens, it is 1.83.

- Our MSRV policy only covers the core library crate: it does not cover tests
  or example code, and is not binding on our dependencies.

- We do not consider MSRV changes to be breaking for the purposes of semver.

- Once we reach 1.0.0, we will not make MSRV changes in patch releases.
  (Prior to reaching 1.0.0, cargo does not support patch releases.)

- We will not make MSRV changes to security maintenance branches.

> [!NOTE]
> For the avoidance of doubt: security maintenance branches exist for each
> release line _that is not the latest_: so (at the time of writing) 0.22
> and 0.21 have maintenance branches, but 0.23 does not and is released from
> the `main` branch.

#### MSRV of new dependencies

We may take _non-default_ optional new dependencies on a crate with a later
MSRV than this policy.

> [!NOTE]
> This is currently the case for our optional dependency on `zlib-rs`, which
> has a current MSRV of 1.75.

## Reporting a Vulnerability

Before reporting a security bug, make sure to:

- Consider the threat model. Misconfiguration that is unlikely to happen accidentally is
  unlikely to be a security bug.
- If applicable, compare the behavior to other TLS implementations. If the behavior is consistent
  with other implementations, it is less likely to be a security bug.

Please report security bugs [via github](https://github.com/rustls/rustls/security/advisories/new).
Make sure to disclose any use of AI assistance upfront.

We'll then:

- Prepare a fix and regression tests.
- Backport the fix and make a patch release for most recent release.
- Submit an advisory to [rustsec/advisory-db](https://github.com/RustSec/advisory-db).
- Refer to the advisory on the main README.md and release notes.

If you're *looking* for security bugs, this crate is set up for
`cargo fuzz` but would benefit from more runtime, targets and corpora.


================================================
FILE: admin/all-features-except
================================================
#!/usr/bin/env python3

DESCRIPTION = """
Usage: admin/all-features-except a,b,c crate

Prints the set of all features declared by the given crate, minus
a, b and c.

The output is decorated with `--no-default-features --features` meaning
it can be used directly with cargo, for example:

$ cargo build $(admin/all-features-except std,log rustls)

It is assumed but not verified that the remaining features do not
have dependencies on the disabled features (otherwise, cargo will
re-enable them without notification).
"""

import subprocess
import argparse
import json


def crate_features(crate_name):
    js = json.loads(
        subprocess.check_output(
            ["cargo", "metadata", "--no-deps", "--format-version=1"]
        )
    )
    package = [p for p in js["packages"] if p["name"] == crate_name]
    if len(package) != 1:
        raise ValueError(f"crate {crate_name} not found in {js}")
    return set(package[0]["features"].keys())


if __name__ == "__main__":
    ap = argparse.ArgumentParser(description=DESCRIPTION)
    ap.add_argument(
        dest="except_features",
        metavar="FEATURE,FEATURE,..",
        type=lambda x: set(x.strip().split(",")),
        help="Which features to remove from the complete set of features",
    )
    ap.add_argument("crate", help="Which crate to determine features for")
    opts = ap.parse_args()

    features = crate_features(opts.crate)

    for f in opts.except_features:
        try:
            features.remove(f)
        except KeyError as e:
            ap.error(f"feature `{f}' not found (known are {features})")

    # drop default, as it may re-enable other features
    features.discard("default")

    print("--no-default-features", "--features", ",".join(sorted(features)))


================================================
FILE: admin/all-workspace-members
================================================
#!/usr/bin/env python3

"""
Usage: admin/all-workspace-members

Prints the set of all workspace members by package name, suitable
for passing to cargo with the `-p`/`--package` option.

"Workspace members" are computed by cargo, and included as
the `workspace_members` item returned from `cargo metadata`.
See
<https://doc.rust-lang.org/cargo/reference/workspaces.html#the-members-and-exclude-fields>
for documentation on what makes a package a workspace member
or not.
"""

import subprocess
import argparse
import json


def workspace_packages():
    js = json.loads(
        subprocess.check_output(
            ["cargo", "metadata", "--no-deps", "--format-version=1"]
        )
    )
    members = js["workspace_members"]
    packages = [p for p in js["packages"] if p["id"] in members]
    return packages


if __name__ == "__main__":
    ap = argparse.ArgumentParser(description=__doc__)
    opts = ap.parse_args()

    for p in workspace_packages():
        print(p["name"])


================================================
FILE: admin/bench-measure.mk
================================================
.PHONY: perf perffull perf13 measure memory clean

RECORD=perf record -F2000 --call-graph dwarf,16000 --
FLAMEGRAPH=perf script | ~/FlameGraph/stackcollapse-perf.pl | ~/FlameGraph/flamegraph.pl >
MEMUSAGE=/usr/bin/env time -f %M
BENCH:=./target/release/rustls-bench
PROVIDER:=aws-lc-rs

perf: $(BENCH)
	$(RECORD) $(BENCH) bulk TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
	$(FLAMEGRAPH) perf-aes128-rustls.svg

perffull: $(BENCH)
	$(RECORD) $(BENCH) bulk TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$(FLAMEGRAPH) perf-aes256-rustls.svg
	$(RECORD) $(BENCH) bulk TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
	$(FLAMEGRAPH) perf-chacha-rustls.svg
	$(RECORD) $(BENCH) handshake TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$(FLAMEGRAPH) perf-fullhs-rustls.svg
	$(RECORD) $(BENCH) handshake-resume TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$(FLAMEGRAPH) perf-resume-rustls.svg
	$(RECORD) $(BENCH) handshake-ticket TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$(FLAMEGRAPH) perf-ticket-rustls.svg

perf13:
	$(RECORD) $(BENCH) handshake-ticket TLS13_AES_256_GCM_SHA384
	$(FLAMEGRAPH) perf-ticket13-rustls.svg

measure: $(BENCH)
	$^ bulk TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
	$^ bulk TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$^ bulk TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
	$^ --key-type rsa2048 bulk TLS13_AES_256_GCM_SHA384
	$^ handshake TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$^ handshake TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
	$^ handshake-resume TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$^ handshake-ticket TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$^ handshake TLS13_AES_256_GCM_SHA384
	$^ handshake-resume TLS13_AES_256_GCM_SHA384
	$^ handshake-ticket TLS13_AES_256_GCM_SHA384

memory: $(BENCH)
	$(MEMUSAGE) $^ memory TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 100
	$(MEMUSAGE) $^ memory TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 1000
	$(MEMUSAGE) $^ memory TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 5000
	$(MEMUSAGE) $^ memory TLS13_AES_256_GCM_SHA384 100
	$(MEMUSAGE) $^ memory TLS13_AES_256_GCM_SHA384 1000
	$(MEMUSAGE) $^ memory TLS13_AES_256_GCM_SHA384 5000

threads: $(BENCH)
	for t in $(shell admin/threads-seq.rs) ; do \
	  $^ --threads $$t handshake TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ; \
	  $^ --threads $$t handshake-resume TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ; \
	  $^ --threads $$t handshake-ticket TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ; \
	  $^ --key-type rsa2048 --threads $$t handshake TLS13_AES_256_GCM_SHA384 ; \
	  $^ --threads $$t handshake-ticket TLS13_AES_256_GCM_SHA384 ; \
	  $^ --threads $$t bulk TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ; \
	  $^ --key-type rsa2048 --threads $$t bulk TLS13_AES_256_GCM_SHA384 ; \
	done

thread-latency: $(BENCH)
	$^ --threads $$(nproc) --api buffered --key-type rsa2048 --latency-prefix latency-fullhs-tls12 handshake TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$^ --threads $$(nproc) --api buffered --key-type rsa2048 --latency-prefix latency-fullhs-tls13 handshake TLS13_AES_256_GCM_SHA384
	$^ --threads $$(nproc) --api buffered --key-type rsa2048 --latency-prefix latency-resume-tls12 handshake-resume TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
	$^ --threads $$(nproc) --api buffered --key-type rsa2048 --latency-prefix latency-resume-tls13 handshake-ticket TLS13_AES_256_GCM_SHA384

clean:
	rm -f perf-*.svg
	cargo clean

$(BENCH): .FORCE
	cargo build --profile=bench -p rustls-bench --features $(PROVIDER)

.FORCE:


================================================
FILE: admin/bench-range
================================================
#!/usr/bin/env python3

import subprocess

suite = 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'

print('len,send,recv')

for len in [16, 32, 64, 128, 512, 1024, 4096, 8192, 32768, 65536, 131072, 262144, 1048576]:
    out = subprocess.check_output(['./target/release/examples/bench', 'bulk', suite, str(len)])
    lines = out.splitlines()

    for l in out.splitlines():
        items = l.split()
        if items[3] == 'send':
            send = float(items[4])
        if items[3] == 'recv':
            recv = float(items[4])

    print('%d,%g,%g' % (len, send, recv))


================================================
FILE: admin/capture-certdata
================================================
#!/usr/bin/env python3

import subprocess
import base64
from os import path

SITES = dict(
    google = 'www.google.com',
    duckduckgo = 'duckduckgo.com',
    github = 'github.com',
    wikipedia = 'wikipedia.org',
    arstechnica = 'arstechnica.com',
    reddit = 'reddit.com',
    hn = 'news.ycombinator.com',
    servo = 'servo.org',
    rustlang = 'www.rust-lang.org',
    wapo = 'www.washingtonpost.com',
    twitter = 'twitter.com',
    stackoverflow = 'stackoverflow.com',
)

def extract_certs(lines):
    buffer = None

    for l in lines:
        if b'-----BEGIN CERT' in l:
            buffer = b''
        elif b'-----END CERT' in l and buffer is not None:
            yield base64.b64decode(buffer)
            buffer = None
        elif buffer is not None:
            buffer += l

def collect(hostname):
    subp = subprocess.Popen([
        'openssl',
        's_client',
        '-showcerts',
        '-connect',
        hostname + ':443',
        ],
        stderr = subprocess.PIPE,
        stdout = subprocess.PIPE,
        stdin = subprocess.PIPE)
    stdout, stderr = subp.communicate('')

    stdout = stdout.splitlines()
    certs = list(extract_certs(stdout))
    return certs

if __name__ == '__main__':
    certfile = lambda name, i: 'rustls-test/benches/data/cert-%s.%d.der' % (name, i)

    for name, hostname in SITES.items():
        if path.exists(certfile(name, 0)):
            continue
        certchain = collect(hostname)

        for i, cert in enumerate(certchain):
            open(certfile(name, i), 'wb').write(cert)
            print('wrote', certfile(name, i))


================================================
FILE: admin/clippy
================================================
#!/bin/bash

# Runs clippy on every package in this repo.
#
# Passes through any extra arguments to each invocation.
#
# Exits non-zero if any clippy invocation exits non-zero,
# but always runs them all.

rc=0
script_args="$@"

function run_clippy() {
  if ! ( set -x ; cargo clippy --locked "$@" $script_args ) ; then
    rc=$PIPESTATUS
  fi
}

# because examples enable rustls' features, `--workspace --no-default-features` is not
# the same as `--package rustls --no-default-features` so run it separately
run_clippy --package rustls --no-default-features --all-targets

# run all workspace members (individually, because we don't want feature unification)
for p in $(admin/all-workspace-members) ; do
  case "$p" in
    rustls-bench)
      ALL_FEATURES=$(admin/all-features-except graviola rustls-bench)
      ;;
    *)
      ALL_FEATURES="--all-features"
      ;;
  esac

  run_clippy --package $p $ALL_FEATURES --all-targets
done

# not part of the workspace
run_clippy --manifest-path=fuzz/Cargo.toml --all-features --all-targets

exit $rc


================================================
FILE: admin/coverage
================================================
#!/usr/bin/env bash

set -e

# for branch coverage support, which is unstable
export RUSTC_BOOTSTRAP=1
OPTIONS=--branch

source <(cargo llvm-cov show-env --export-prefix $OPTIONS "$@")
cargo llvm-cov clean --workspace

cargo build --locked --all-targets --all-features
cargo test --locked --all-features # this presumably enables `fips`
cargo test -p rustls-ring --locked
cargo test -p rustls-aws-lc-rs --locked
cargo test -p rustls-test --locked --features aws-lc-rs # aws-lc-rs, but no fips

# ensure both zlib and brotli are tested, irrespective of their order
cargo test --locked $(admin/all-features-except zlib rustls)
cargo test --locked $(admin/all-features-except brotli rustls)

## bogo
cargo test --locked --test bogo -- --ignored --test-threads 1

cargo llvm-cov report --ignore-filename-regex "(bogo|rustls-test)/" $OPTIONS "$@"


================================================
FILE: admin/pull-readme
================================================
#!/usr/bin/env sh
# Extract the introductory documentation into the README.md

set -e

awk 'BEGIN { take=1 }/# Approach/{take=0;print}take' < README.md > README.md.new
grep '^//!' rustls/src/lib.rs | \
       sed -e 's@^\/\/\! *@@g' | \
       sed -e 's@](manual::_04_features)@](https://docs.rs/rustls/latest/rustls/manual/_04_features/index.html)@' | \
       sed -e 's@\[`crypto::CryptoProvider`\]: crate::crypto::CryptoProvider@[`crypto::CryptoProvider`]: https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html@' | \
       awk '/# Rustls - a modern TLS library/{take=1;next}/## Design overview/{take=0}take' >> README.md.new
awk '/# Example code/{take=1}take' < README.md >> README.md.new
mv README.md.new README.md


================================================
FILE: admin/threads-seq.rs
================================================
#!/usr/bin/env -S cargo +nightly --quiet -Zscript

//! # `admin/thread-seq N`
//!
//! This program prints a sequence of N integers for multithreaded
//! performance testing.  The integers are numbers of threads to
//! be sampled in a test.  The goal is to assist in graphing
//! how per-thread throughput relates to concurrency.
//!
//! The sequence is (at most) length N, starts at 2, includes the
//! number of CPU cores, and ends at 1.5 the number of CPU cores.
//! It does not have repeated items.
//!
//! We exceed the number of cores specifically to see the
//! "elbow" in the graph, when the number of threads tested
//! exceeds the number of cores.  (This is good because otherwise
//! -- assuming the software under test is perfectly scalable --
//! the graph would be a straight line parallel with the x axis.)

use std::{cmp, env, error, num::NonZeroUsize, str::FromStr, thread};

fn main() -> Result<(), Box<dyn error::Error + Send + Sync + 'static>> {
    let mut args = env::args();
    args.next(); // skip argv[0]
    let count = args
        .next()
        .map(|c| NonZeroUsize::from_str(&c))
        .transpose()?
        .unwrap_or(NonZeroUsize::new(16).unwrap())
        .get();

    let default_cpus = thread::available_parallelism()?;
    let cpus = env::var("CPU_COUNT")
        .map(|c| NonZeroUsize::from_str(&c))
        .unwrap_or(Ok(default_cpus))?
        .get();

    let end = (cpus as f64 * 1.5).floor() as usize;

    let before_count = (count as f64 * 0.75).floor() as usize;
    let after_count = count - before_count;

    let before = (2..cpus).step_by(cmp::max(1, cpus / before_count));
    let after = (cpus..end).step_by(cmp::max(1, (end - cpus) / after_count));

    for x in before.chain(after) {
        print!("{} ", x);
    }
    println!();
    Ok(())
}


================================================
FILE: ci-bench/Cargo.toml
================================================
[package]
name = "rustls-ci-bench"
version = "0.0.1"
edition = "2021"
license = "Apache-2.0 OR ISC OR MIT"
description = "Rustls CPU instruction counting benchmarks."
publish = false

[dependencies]
anyhow = { workspace = true }
async-trait = { workspace = true }
byteorder = { workspace = true }
clap = { workspace = true }
itertools = { workspace = true }
rayon = { workspace = true }
rustc-hash = { workspace = true }
rustls = { path = "../rustls" }
rustls-aws-lc-rs = { path = "../rustls-aws-lc-rs" }
rustls-ring = { path = "../rustls-ring" }
rustls-test = { workspace = true, default-features = false }
rustls-fuzzing-provider = { workspace = true }

[target.'cfg(target_os = "linux")'.dependencies]
crabgrind = { workspace = true }

[lints]
workspace = true


================================================
FILE: ci-bench/README.md
================================================
# CI Bench

This crate is meant for CI benchmarking. It has two modes of operation:

1. Measure CPU instructions using `callgrind`.
2. Measure wall-time (runs each benchmark multiple times, leaving it to the caller to do statistical
   analysis).

## Usage

You can get detailed usage information through `cargo run --release -- --help`. Below are the most
important bits.

### Running all benchmarks in instruction count mode

_Note: this step requires having `valgrind` in your path._

Use `cargo run --release -- run-all --output-dir foo` to generate the results inside the `foo`
directory. Within that directory, you will find an `icounts.csv` file with the instruction counts
for the different scenarios we support. It should look like the following:

```csv
handshake_no_resume_1.2_rsa_aes_server,11327015
handshake_no_resume_1.2_rsa_aes_client,4314952
handshake_session_id_1.2_rsa_aes_server,11342136
handshake_session_id_1.2_rsa_aes_client,4327564
handshake_tickets_1.2_rsa_aes_server,11347746
handshake_tickets_1.2_rsa_aes_client,4331424
transfer_no_resume_1.2_rsa_aes_server,8775780
transfer_no_resume_1.2_rsa_aes_client,8818847
handshake_no_resume_1.3_rsa_aes_server,11517007
handshake_no_resume_1.3_rsa_aes_client,4212770
...
... rest omitted for brevity
...
```

In the `callgrind` subdirectory you will find output files emitted by the `callgrind` tool, which
are useful to report detailed instruction count differences when comparing two benchmark runs. This
subdirectory also contains log information from callgrind itself (in `.log` files), which can be
used to diagnose unexpected callgrind crashes.

### Running all benchmarks in wall-time mode

Use `cargo run --release -- walltime --iterations-per-scenario 3` to print the CSV results to stdout
(we use 3 iterations here for demonstration purposes, but recommend 100 iterations to deal with
noise). The output should look like the following (one column per iteration):

```csv
handshake_no_resume_ring_1.2_rsa_aes,6035261,1714158,977368
handshake_session_id_ring_1.2_rsa_aes,1537632,2445849,1766888
handshake_tickets_ring_1.2_rsa_aes,1553743,2418286,1636431
transfer_no_resume_ring_1.2_rsa_aes,10192862,10374258,8988854
handshake_no_resume_ring_1.3_rsa_aes,1010150,1400602,936029
...
... rest omitted for brevity
...
```

### Comparing results from an instruction count benchmark run

Use `cargo run --release -- compare foo bar`. It will output a report using GitHub-flavored markdown
for local use. Note that not all reported differences are significant. When you need to know if a
result is significant you should rely on the CI benchmark report, which automatically categorizes
results into significant / negligible based on historic data.

### Supported scenarios

We benchmark the following scenarios:

- Handshake without resumption (`handshake_no_resume`)
- Handshake with ticket resumption (`handshake_tickets`)
- Handshake with session id resumption (`handshake_session_id`)
- Encrypt, transfer and decrypt 1MB of data sent by the server
  (`transfer_no_resume`)

The scenarios are benchmarked with different TLS versions, certificate key types and cipher suites.
CPU counts are measured independently for the server side and for the client side. Hence, we end up
with names like `transfer_no_resume_1.3_rsa_aes_client`.

## Internals

We have made an effort to heavily document the source code of the benchmarks. In addition to that,
here are some high-level considerations that can help you hack on the crate.

### Environment configuration

An important goal of this benchmarking setup is that it should run with minimal noise. Measuring CPU
instructions using `callgrind` yields excellent results, regardless of your environment. The
wall-time benchmarks, however, require a more elaborate benchmarking environment: running them on a
laptop is too noisy, but running them on a carefully configured bare-metal server yields accurate
measurements (up to 1% resolution, according to our tests).

### Instruction count mode

Instruction counting is done with `callgrind`, and is precise in the sense that only operations
we want to measure are included.  We tell `callgrind` to start with collection disabled,
with `--collect-atstart=no`.  Then we use
[client requests](https://valgrind.org/docs/manual/cl-manual.html#cl-manual.clientrequests) via
the [crabgrind crate](https://docs.rs/crabgrind/latest/crabgrind/) to enable and disable collection
(see `callgrind::CountInstructions`).

Since we want to measure server and client instruction counts separately, the benchmark runner
spawns two child processes for each benchmark (one for the client, one for the server) and pipes
their stdio to each other for communication (i.e. stdio acts as the transport layer).

If you need to debug benchmarks in instruction count mode, here are a few tricks that might help:

- For printf debugging, you should use `eprintln!`, because child processes use stdio as the
  transport for the TLS connection (i.e. if you print something to stdout, you won't even see it
  _and_ the other side of the connection will choke on it).
- When using a proper debugger, remember that each side of the connection runs as a child process.

### Wall-time mode

To increase determinism, it is important that wall-time mode benchmarks run in a single process and
thread. All IO is done in-memory and there is no complex setup like in the case of the instruction
counting mode. Because of this, the easiest way to debug the crate is by running the benchmarks in
wall-time mode.

### Code reuse between benchmarking modes

Originally, we only supported the instruction count mode, implemented using blocking IO. Even though
the code was generic over the `Reader` and `Writer`, it could not be reused for the wall-time mode
because it was blocking (e.g. if the client side of the connection is waiting for a read, the thread
is blocked and the server never gets a chance to write).

The solution was to:

1. Rewrite the IO code to use async / await.
2. Keep using blocking operations under the hood in instruction-count mode, disguised as `Future`s
   that complete after a single `poll`. This way we avoid using an async runtime, which could
   introduce non-determinism.
3. Use non-blocking operations under the hood in wall-time mode, which simulate IO through shared
   in-memory buffers. The server and client `Future`s are polled in turns, so again we avoid
   pulling in an async runtime and keep things as deterministic as possible.

### Why measure CPU instructions

This technique has been successfully used in tracking the Rust compiler's performance, and is
known to work well when comparing two versions of the same code. It has incredibly low noise,
and therefore makes for a very good metric for automatic PR checking (i.e. the automatic check
will reliably identify significant performance changes).

It is not possible to deduce the exact change in runtime based on the instruction count
difference (e.g. a 5% increase in instructions does not necessarily result in a 5% increase in
runtime). However, if there is a significant change in instruction count, you can be fairly
confident there is a significant change in runtime too. This is very useful information to have
when reviewing a PR.

For more information, including the alternatives we considered, check out [this comment]
(https://github.com/rustls/rustls/issues/1385#issuecomment-1668023152) in the issue tracker.

### Why measure wall-time

While instruction counts are a useful proxy to detect changes in runtime performance, they do not
account for important factors such as cache misses and branch mispredictions. As an example,
consider two equivalent functions that calculate an aggregate value based on a `Vec<u64>`: if they
use roughly the same code, yet a different memory access pattern, that could result in a similar
instruction count, yet significantly different runtime.

The bigger the change in code, the higher the chance that memory layout and access patterns are
significantly affected. For that reason, having wall-time measurements is important as a complement
to instruction counts.


================================================
FILE: ci-bench/src/benchmark.rs
================================================
use core::borrow::Borrow;
use core::cmp;
use std::sync::Arc;

use rustc_hash::FxHashMap;
use rustls::crypto::{CryptoProvider, TicketProducer};
use rustls_test::KeyType;

use crate::Side;
use crate::valgrind::InstructionCounts;

/// Get the reported instruction counts for the provided benchmark
pub(crate) fn get_reported_instr_count(
    bench: &Benchmark,
    results: &FxHashMap<&str, InstructionCounts>,
) -> InstructionCounts {
    results[&bench.name()]
}

/// Specifies which functionality is being benchmarked
#[derive(Copy, Clone)]
pub(crate) enum BenchmarkKind {
    /// Perform the handshake and exit
    Handshake(ResumptionKind),
    /// Perform the handshake and transfer 1MB of data
    Transfer,
}

impl BenchmarkKind {
    /// Returns the [`ResumptionKind`] used in the handshake part of the benchmark
    pub(crate) fn resumption_kind(self) -> ResumptionKind {
        match self {
            Self::Handshake(kind) => kind,
            Self::Transfer => ResumptionKind::No,
        }
    }
}

/// The kind of resumption used during the handshake
#[derive(PartialEq, Clone, Copy)]
pub(crate) enum ResumptionKind {
    /// No resumption
    No,
    /// Session ID
    SessionId,
    /// Session tickets
    Tickets,
}

impl ResumptionKind {
    pub(crate) const ALL: &'static [Self] = &[Self::No, Self::SessionId, Self::Tickets];

    /// Returns a user-facing label that identifies the resumption kind
    pub(crate) fn label(&self) -> &'static str {
        match *self {
            Self::No => "no_resume",
            Self::SessionId => "session_id",
            Self::Tickets => "tickets",
        }
    }
}

/// Parameters associated to a benchmark
#[derive(Clone, Debug)]
pub(crate) struct BenchmarkParams {
    /// Which `CryptoProvider` to test.
    ///
    /// The choice of cipher suite is baked into this.
    pub provider: Arc<CryptoProvider>,
    /// How to make a suitable [`rustls::crypto::TicketProducer`].
    pub ticketer: &'static fn() -> Arc<dyn TicketProducer>,
    /// Where to get keys for server auth
    pub auth_key: AuthKeySource,
    /// A user-facing label that identifies these params
    pub label: String,
    /// Call this once this BenchmarkParams is sure to be used
    pub warm_up: Option<fn()>,
}

impl BenchmarkParams {
    /// Create a new set of benchmark params
    pub(crate) const fn new(
        provider: Arc<CryptoProvider>,
        ticketer: &'static fn() -> Arc<dyn TicketProducer>,
        auth_key: AuthKeySource,
        label: String,
        warm_up: Option<fn()>,
    ) -> Self {
        Self {
            provider,
            ticketer,
            auth_key,
            label,
            warm_up,
        }
    }
}

#[derive(Clone, Debug)]
pub(crate) enum AuthKeySource {
    KeyType(KeyType),
    FuzzingProvider,
}

/// A benchmark specification
pub(crate) struct Benchmark {
    /// The name of the benchmark, as shown in the benchmark results
    name: String,
    /// The benchmark kind
    pub kind: BenchmarkKind,
    /// The benchmark's parameters
    pub params: BenchmarkParams,
}

impl Benchmark {
    /// Create a new benchmark
    pub(crate) fn new(name: String, kind: BenchmarkKind, params: BenchmarkParams) -> Self {
        Self { name, kind, params }
    }

    /// Returns the benchmark's unique name
    pub(crate) fn name(&self) -> &str {
        &self.name
    }

    /// Returns the benchmark's unique name with the side appended to it
    pub(crate) fn name_with_side(&self, side: Side) -> String {
        format!("{}_{}", self.name, side.as_str())
    }
}

impl Borrow<str> for Benchmark {
    fn borrow(&self) -> &str {
        &self.name
    }
}

impl PartialEq for Benchmark {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name
    }
}

impl Eq for Benchmark {}

impl PartialOrd for Benchmark {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Benchmark {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.name.cmp(&other.name)
    }
}


================================================
FILE: ci-bench/src/main.rs
================================================
use core::hint::black_box;
use core::mem;
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::fs::File;
use std::io::{self, BufRead, BufReader, Write};
use std::os::fd::{AsRawFd, FromRawFd};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Instant;

use anyhow::Context;
use async_trait::async_trait;
use clap::{Parser, Subcommand, ValueEnum};
use itertools::Itertools;
use rayon::iter::Either;
use rayon::prelude::*;
use rustc_hash::FxHashMap;
use rustls::client::Resumption;
use rustls::crypto::{CipherSuite, CryptoProvider, GetRandomFailed, SecureRandom, TicketProducer};
use rustls::enums::ProtocolVersion;
use rustls::server::{NoServerSessionStorage, ServerSessionMemoryCache, WebPkiClientVerifier};
use rustls::{
    ClientConfig, ClientConnection, Connection, HandshakeKind, RootCertStore, ServerConfig,
    ServerConnection,
};
use rustls_test::KeyType;

use crate::benchmark::{
    AuthKeySource, Benchmark, BenchmarkKind, BenchmarkParams, ResumptionKind,
    get_reported_instr_count,
};
use crate::util::async_io::{self, AsyncRead, AsyncWrite};
use crate::util::transport::{
    read_handshake_message, read_plaintext_to_end_bounded, send_handshake_message,
    write_all_plaintext_bounded,
};
use crate::valgrind::{CallgrindRunner, CountInstructions, DhatRunner, MemoryDetails};

mod benchmark;
mod util;
mod valgrind;

/// The size in bytes of the plaintext sent in the transfer benchmark
const TRANSFER_PLAINTEXT_SIZE: usize = 1024 * 1024 * 10; // 10 MB

/// The amount of times a resumed handshake should be executed during benchmarking.
///
/// Handshakes with session resumption execute a very small amount of instructions (less than 200_000
/// for some parameters), so a small difference in instructions accounts for a high difference in
/// percentage (making the benchmark more sensitive to noise, because differences as low as 500
/// instructions already raise a flag). Running the handshake multiple times gives additional weight
/// to the instructions involved in the handshake, and less weight to noisy one-time setup code.
///
/// More specifically, great part of the noise in resumed handshakes comes from the usage of
/// [`rustls::client::ClientSessionMemoryCache`] and [`rustls::server::ServerSessionMemoryCache`],
/// which rely on a randomized `HashMap` under the hood (you can check for yourself by that
/// `HashMap` by a `FxHashMap`, which brings the noise down to acceptable levels in a single run).
const RESUMED_HANDSHAKE_RUNS: usize = 30;

/// The name of the file where the instruction counts are stored after a `run-all` run
const ICOUNTS_FILENAME: &str = "icounts.csv";

/// The name of the file where the memory data are stored after a `run-all` run
const MEMORY_FILENAME: &str = "memory.csv";

/// Default size in bytes for internal buffers (256 KB)
const DEFAULT_BUFFER_SIZE: usize = 262144;

#[derive(Parser)]
#[command(about)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Command,
}

#[derive(Subcommand)]
pub enum Command {
    /// Run all benchmarks and print the measured CPU instruction counts in CSV format
    RunAll {
        #[arg(short, long, default_value = "target/ci-bench")]
        output_dir: PathBuf,
    },
    /// Run a named benchmark and print the measured CPU instruction counts in CSV format
    RunSingle {
        /// The name of the benchmark.
        bench: String,
        #[arg(short, long, default_value = "target/ci-bench")]
        output_dir: PathBuf,
    },
    /// Run a single benchmark at the provided name (used by the bench runner to start each benchmark in its own process)
    RunPipe {
        name: String,
        side: Side,
        measurement_mode: Mode,
    },
    /// Run all benchmarks in walltime mode and print the measured timings in CSV format
    Walltime {
        #[arg(short, long)]
        iterations_per_scenario: usize,
    },
    /// Compare the icount results from two previous benchmark runs and print a user-friendly markdown overview
    Compare {
        /// Path to the directory with the results of a previous `run-all` execution
        baseline_dir: PathBuf,
        /// Path to the directory with the results of a previous `run-all` execution
        candidate_dir: PathBuf,
    },
    /// Compare the memory results from two previous benchmark runs and print a user-friendly markdown overview
    CompareMemory {
        comparator: CompareMemoryOperand,
        /// Path to the directory with the results of a previous `run-all` execution
        baseline_dir: PathBuf,
        /// Path to the directory with the results of a previous `run-all` execution
        candidate_dir: PathBuf,
    },
}

#[derive(Copy, Clone, Debug, Default, ValueEnum)]
pub enum CompareMemoryOperand {
    #[default]
    TotalBytes,
    TotalBlocks,
    PeakBytes,
    PeakBlocks,
}

impl CompareMemoryOperand {
    fn choose(&self, memory: MemoryDetails) -> u64 {
        match self {
            Self::TotalBytes => memory.heap_total_bytes,
            Self::TotalBlocks => memory.heap_total_blocks,
            Self::PeakBytes => memory.heap_peak_bytes,
            Self::PeakBlocks => memory.heap_peak_blocks,
        }
    }
}

#[derive(Copy, Clone, ValueEnum)]
pub enum Side {
    Server,
    Client,
}

#[derive(Copy, Clone, ValueEnum)]
pub enum Mode {
    Instruction,
    Memory,
}

impl Side {
    /// Returns the string representation of the side
    pub fn as_str(self) -> &'static str {
        match self {
            Self::Client => "client",
            Self::Server => "server",
        }
    }
}

fn main() -> anyhow::Result<()> {
    let benchmarks = all_benchmarks()?;

    let cli = Cli::parse();
    match cli.command {
        Command::RunAll { output_dir } => {
            let executable = std::env::args().next().unwrap();
            let results = run_all(
                executable,
                output_dir.clone(),
                &benchmarks.iter().collect::<Vec<_>>(),
            )?;
            output_csv(results, output_dir)?;
        }
        Command::RunSingle { bench, output_dir } => {
            let executable = std::env::args().next().unwrap();
            let Some(benchmark) = benchmarks.get(bench.as_str()) else {
                let mut output = String::new();
                for bench in all_benchmarks()? {
                    output.push_str(&format!(" - {:?}\n", bench.name()));
                }

                return Err(anyhow::anyhow!(
                    "Benchmark {bench:?} not found\n\nAvailable are:\n{output}"
                ));
            };
            let results = run_all(executable, output_dir.clone(), &[benchmark])?;
            output_csv(results, output_dir)?;
        }
        Command::RunPipe {
            name,
            side,
            measurement_mode,
        } => {
            let bench = benchmarks
                .get(name.as_str())
                .ok_or_else(|| anyhow::anyhow!("Benchmark not found: {name}"))?;

            if let Some(warm_up) = bench.params.warm_up {
                warm_up();
            }

            let stdin_lock = io::stdin().lock();
            let stdout_lock = io::stdout().lock();

            // `StdinLock` and `StdoutLock` are buffered, which makes the instruction counts less
            // deterministic (the growth of the internal buffers varies across runs, causing
            // differences of hundreds of instructions). To counter this, we do the actual io
            // operations through `File`, which is unbuffered. The `stdin_lock` and `stdout_lock`
            // variables are kept around to ensure exclusive access.

            // safety: the file descriptor is valid and we have exclusive access to it for the
            // duration of the lock
            let mut stdin = unsafe { File::from_raw_fd(stdin_lock.as_raw_fd()) };
            let mut stdout = unsafe { File::from_raw_fd(stdout_lock.as_raw_fd()) };

            // When measuring instructions, we do multiple resumed handshakes, for
            // reasons explained in the comments to `RESUMED_HANDSHAKE_RUNS`.
            let resumed_reps = match measurement_mode {
                Mode::Instruction => RESUMED_HANDSHAKE_RUNS,
                _ => 1,
            };

            let handshake_buf = &mut [0u8; DEFAULT_BUFFER_SIZE];
            let resumption_kind = bench.kind.resumption_kind();
            let io = StepperIo {
                reader: &mut stdin,
                writer: &mut stdout,
                handshake_buf,
            };
            async_io::block_on_single_poll(async {
                match side {
                    Side::Server => {
                        run_bench(
                            ServerSideStepper {
                                io,
                                config: ServerSideStepper::make_config(
                                    &bench.params,
                                    resumption_kind,
                                ),
                            },
                            bench.kind,
                            resumed_reps,
                        )
                        .await
                    }
                    Side::Client => {
                        run_bench(
                            ClientSideStepper {
                                io,
                                resumption_kind,
                                config: ClientSideStepper::make_config(
                                    &bench.params,
                                    resumption_kind,
                                ),
                            },
                            bench.kind,
                            resumed_reps,
                        )
                        .await
                    }
                }
            })
            .with_context(|| format!("{} crashed for {} side", bench.name(), side.as_str()))?;

            // Prevent stdin / stdout from being closed
            mem::forget(stdin);
            mem::forget(stdout);
        }
        Command::Walltime {
            iterations_per_scenario,
        } => {
            let mut timings = BTreeMap::new();
            for _ in 0..iterations_per_scenario {
                for bench in &benchmarks {
                    let start = Instant::now();

                    // The variables below are used to initialize the client and server configs. We
                    // let them go through `black_box` to ensure the optimizer doesn't take
                    // advantage of knowing both the client and the server side of the
                    // configuration.
                    let resumption_kind = black_box(bench.kind.resumption_kind());
                    let params = black_box(&bench.params);

                    let (mut client_writer, mut server_reader) =
                        async_io::async_pipe(DEFAULT_BUFFER_SIZE);
                    let (mut server_writer, mut client_reader) =
                        async_io::async_pipe(DEFAULT_BUFFER_SIZE);

                    let server_side = async move {
                        let handshake_buf = &mut [0u8; DEFAULT_BUFFER_SIZE];
                        run_bench(
                            ServerSideStepper {
                                io: StepperIo {
                                    reader: &mut server_reader,
                                    writer: &mut server_writer,
                                    handshake_buf,
                                },
                                config: ServerSideStepper::make_config(params, resumption_kind),
                            },
                            bench.kind,
                            RESUMED_HANDSHAKE_RUNS,
                        )
                        .await
                    };

                    let client_side = async move {
                        let handshake_buf = &mut [0u8; DEFAULT_BUFFER_SIZE];
                        run_bench(
                            ClientSideStepper {
                                io: StepperIo {
                                    reader: &mut client_reader,
                                    writer: &mut client_writer,
                                    handshake_buf,
                                },
                                resumption_kind,
                                config: ClientSideStepper::make_config(params, resumption_kind),
                            },
                            bench.kind,
                            RESUMED_HANDSHAKE_RUNS,
                        )
                        .await
                    };

                    let (client_result, server_result) =
                        async_io::block_on_concurrent(client_side, server_side);
                    client_result
                        .with_context(|| format!("client side of {} crashed", bench.name()))?;
                    server_result
                        .with_context(|| format!("server side of {} crashed", bench.name()))?;

                    timings
                        .entry(bench.name().to_string())
                        .or_insert_with(|| Vec::with_capacity(iterations_per_scenario))
                        .push(start.elapsed());
                }
            }

            // Output the results
            for (name, bench_timings) in timings.into_iter() {
                print!("{}", name);
                for timing in bench_timings {
                    print!(",{}", timing.as_nanos())
                }
                println!();
            }
        }
        Command::Compare {
            baseline_dir,
            candidate_dir,
        } => {
            let baseline = read_icount_results(&baseline_dir.join(ICOUNTS_FILENAME))?;
            let candidate = read_icount_results(&candidate_dir.join(ICOUNTS_FILENAME))?;
            let result =
                compare_icount_results(&baseline_dir, &candidate_dir, &baseline, &candidate)?;
            print_icount_report(&result);
        }
        Command::CompareMemory {
            comparator,
            baseline_dir,
            candidate_dir,
        } => {
            let baseline = read_memory_results(&baseline_dir.join(MEMORY_FILENAME))?;
            let candidate = read_memory_results(&candidate_dir.join(MEMORY_FILENAME))?;

            print_memory_report(&compare_memory_results(&baseline, &candidate, comparator)?);
        }
    }

    Ok(())
}

fn output_csv(
    results: Vec<(String, CombinedMeasurement)>,
    output_dir: PathBuf,
) -> anyhow::Result<()> {
    // Output results in CSV (note: not using a library here to avoid extra dependencies)
    let mut csv_file =
        File::create(output_dir.join(ICOUNTS_FILENAME)).context("cannot create output csv file")?;
    for (name, combined) in &results {
        writeln!(csv_file, "{name},{}", combined.instructions)?;
    }

    let mut csv_file =
        File::create(output_dir.join(MEMORY_FILENAME)).context("cannot create output csv file")?;
    for (name, combined) in results {
        writeln!(
            csv_file,
            "{name},{},{},{},{}",
            combined.memory.heap_total_bytes,
            combined.memory.heap_total_blocks,
            combined.memory.heap_peak_bytes,
            combined.memory.heap_peak_blocks,
        )?;
    }

    Ok(())
}

/// Returns all benchmarks
fn all_benchmarks() -> anyhow::Result<BTreeSet<Benchmark>> {
    let mut benchmarks = BTreeSet::new();
    for param in all_benchmarks_params() {
        add_benchmark_group(&mut benchmarks, param);
    }

    Ok(benchmarks)
}

/// The benchmark params to use for each group of benchmarks
fn all_benchmarks_params() -> Vec<BenchmarkParams> {
    let mut all = Vec::new();

    for (provider, ticketer, provider_name, warm_up) in [
        (
            derandomize(rustls_ring::DEFAULT_PROVIDER),
            &(ring_ticketer as fn() -> Arc<dyn TicketProducer>),
            "ring",
            None,
        ),
        (
            derandomize(rustls_aws_lc_rs::DEFAULT_PROVIDER),
            &(aws_lc_rs_ticketer as fn() -> Arc<dyn TicketProducer>),
            "aws_lc_rs",
            Some(warm_up_aws_lc_rs as fn()),
        ),
    ] {
        for (key_type, suite_name, name) in [
            (
                KeyType::Rsa2048,
                CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                "1.2_rsa_aes",
            ),
            (
                KeyType::Rsa2048,
                CipherSuite::TLS13_AES_128_GCM_SHA256,
                "1.3_rsa_aes",
            ),
            (
                KeyType::EcdsaP256,
                CipherSuite::TLS13_AES_128_GCM_SHA256,
                "1.3_ecdsap256_aes",
            ),
            (
                KeyType::EcdsaP384,
                CipherSuite::TLS13_AES_128_GCM_SHA256,
                "1.3_ecdsap384_aes",
            ),
            (
                KeyType::Rsa2048,
                CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
                "1.3_rsa_chacha",
            ),
            (
                KeyType::EcdsaP256,
                CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
                "1.3_ecdsap256_chacha",
            ),
            (
                KeyType::EcdsaP384,
                CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
                "1.3_ecdsap384_chacha",
            ),
        ] {
            all.push(BenchmarkParams::new(
                select_suite(provider.clone(), suite_name),
                ticketer,
                AuthKeySource::KeyType(key_type),
                format!("{provider_name}_{name}"),
                warm_up,
            ));
        }
    }

    let make_ticketer =
        &((|| Arc::new(rustls_fuzzing_provider::Ticketer)) as fn() -> Arc<dyn TicketProducer>);

    all.push(BenchmarkParams::new(
        rustls_fuzzing_provider::PROVIDER_TLS13.into(),
        make_ticketer,
        AuthKeySource::FuzzingProvider,
        "1.3_no_crypto".to_string(),
        None,
    ));

    all.push(BenchmarkParams::new(
        rustls_fuzzing_provider::PROVIDER_TLS12.into(),
        make_ticketer,
        AuthKeySource::FuzzingProvider,
        "1.2_no_crypto".to_string(),
        None,
    ));

    all
}

fn ring_ticketer() -> Arc<dyn TicketProducer> {
    rustls_ring::DEFAULT_PROVIDER
        .ticketer_factory
        .ticketer()
        .unwrap()
}

fn aws_lc_rs_ticketer() -> Arc<dyn TicketProducer> {
    rustls_aws_lc_rs::DEFAULT_PROVIDER
        .ticketer_factory
        .ticketer()
        .unwrap()
}

fn select_suite(mut provider: CryptoProvider, name: CipherSuite) -> Arc<CryptoProvider> {
    provider
        .tls12_cipher_suites
        .to_mut()
        .retain(|suite| suite.common.suite == name);
    provider
        .tls13_cipher_suites
        .to_mut()
        .retain(|suite| suite.common.suite == name);
    provider.into()
}

fn derandomize(base: CryptoProvider) -> CryptoProvider {
    CryptoProvider {
        secure_random: &NotRandom,
        ..base
    }
}

fn warm_up_aws_lc_rs() {
    // "Warm up" provider's actual entropy source.  aws-lc-rs particularly
    // has an expensive process here, which is one-time (per calling thread)
    // so not useful to include in benchmark measurements.
    rustls_aws_lc_rs::DEFAULT_PROVIDER
        .secure_random
        .fill(&mut [0u8])
        .unwrap();
}

#[derive(Debug)]
struct NotRandom;

impl SecureRandom for NotRandom {
    fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
        buf.fill(0x5a);
        Ok(())
    }
}

/// Adds a group of benchmarks for the specified parameters
///
/// The benchmarks in the group are:
///
/// - Handshake without resumption
/// - Handshake with session id resumption
/// - Handshake with ticket resumption
/// - Transfer a 1MB data stream from the server to the client
fn add_benchmark_group(benchmarks: &mut BTreeSet<Benchmark>, params: BenchmarkParams) {
    let params_label = params.label.clone();

    // Create handshake benchmarks for all resumption kinds
    for &resumption_param in ResumptionKind::ALL {
        let handshake_bench = Benchmark::new(
            format!("handshake_{}_{params_label}", resumption_param.label()),
            BenchmarkKind::Handshake(resumption_param),
            params.clone(),
        );

        assert!(benchmarks.insert(handshake_bench), "duplicate benchmark");
    }

    // Benchmark data transfer
    assert!(
        benchmarks.insert(Benchmark::new(
            format!("transfer_no_resume_{params_label}"),
            BenchmarkKind::Transfer,
            params
        )),
        "duplicate benchmark"
    );
}

/// Run all the provided benches under callgrind to retrieve their instruction count
fn run_all(
    executable: String,
    output_dir: PathBuf,
    benches: &[&Benchmark],
) -> anyhow::Result<Vec<(String, CombinedMeasurement)>> {
    for bench in benches {
        if let Some(warm_up) = bench.params.warm_up {
            warm_up();
        }
    }

    // Run the benchmarks in parallel
    let cg_runner = CallgrindRunner::new(executable.clone(), output_dir.clone())?;
    let cg_results: Vec<_> = benches
        .par_iter()
        .map(|bench| (bench, cg_runner.run_bench(bench)))
        .collect();

    let dh_runner = DhatRunner::new(executable, output_dir)?;
    let dh_results: Vec<_> = benches
        .par_iter()
        .map(|bench| (bench, dh_runner.run_bench(bench)))
        .collect();

    // Report possible errors
    let (errors, cg_results): (Vec<_>, FxHashMap<_, _>) =
        cg_results
            .into_iter()
            .partition_map(|(bench, result)| match result {
                Err(_) => Either::Left(()),
                Ok(instr_counts) => Either::Right((bench.name(), instr_counts)),
            });
    if !errors.is_empty() {
        // Note: there is no need to explicitly report the names of each crashed benchmark, because
        // names and other details are automatically printed to stderr by the child process upon
        // crashing
        anyhow::bail!("One or more benchmarks crashed");
    }
    let (errors, dh_results): (Vec<_>, FxHashMap<_, _>) =
        dh_results
            .into_iter()
            .partition_map(|(bench, result)| match result {
                Err(_) => Either::Left(()),
                Ok(heap_profile) => Either::Right((bench.name(), heap_profile)),
            });
    if !errors.is_empty() {
        // Note: there is no need to explicitly report the names of each crashed benchmark, because
        // names and other details are automatically printed to stderr by the child process upon
        // crashing
        anyhow::bail!("One or more benchmarks crashed");
    }

    // Gather results keeping the original order of the benchmarks
    let mut measurements = Vec::new();
    for bench in benches {
        let instr_counts = get_reported_instr_count(bench, &cg_results);
        let memory = &dh_results[bench.name()];
        measurements.push((
            bench.name_with_side(Side::Server),
            CombinedMeasurement {
                instructions: instr_counts.server,
                memory: memory.server,
            },
        ));
        measurements.push((
            bench.name_with_side(Side::Client),
            CombinedMeasurement {
                instructions: instr_counts.client,
                memory: memory.client,
            },
        ));
    }

    Ok(measurements)
}

pub struct CombinedMeasurement {
    instructions: u64,
    memory: MemoryDetails,
}

/// Drives the different steps in a benchmark.
///
/// See [`run_bench`] for specific details on how it is used.
#[async_trait(?Send)]
trait BenchStepper {
    type Endpoint;

    async fn handshake(&mut self) -> anyhow::Result<Self::Endpoint>;
    async fn sync_before_resumed_handshake(&mut self) -> anyhow::Result<()>;
    async fn transmit_data(&mut self, endpoint: &mut Self::Endpoint) -> anyhow::Result<()>;
    fn handshake_kind(&self, endpoint: &Self::Endpoint) -> HandshakeKind;
}

/// Stepper fields necessary for IO
struct StepperIo<'a> {
    reader: &'a mut dyn AsyncRead,
    writer: &'a mut dyn AsyncWrite,
    handshake_buf: &'a mut [u8],
}

/// A benchmark stepper for the client-side of the connection
struct ClientSideStepper<'a> {
    io: StepperIo<'a>,
    resumption_kind: ResumptionKind,
    config: Arc<ClientConfig>,
}

impl ClientSideStepper<'_> {
    fn make_config(params: &BenchmarkParams, resume: ResumptionKind) -> Arc<ClientConfig> {
        let cfg = ClientConfig::builder(params.provider.clone());

        let mut cfg = match params.auth_key {
            AuthKeySource::KeyType(key_type) => {
                let mut root_store = RootCertStore::empty();
                root_store
                    .add(key_type.ca_cert())
                    .unwrap();

                cfg.with_root_certificates(root_store)
                    .with_no_client_auth()
                    .unwrap()
            }

            AuthKeySource::FuzzingProvider => cfg
                .dangerous()
                .with_custom_certificate_verifier(rustls_fuzzing_provider::server_verifier())
                .with_no_client_auth()
                .unwrap(),
        };

        if resume != ResumptionKind::No {
            cfg.resumption = Resumption::in_memory_sessions(128);
        } else {
            cfg.resumption = Resumption::disabled();
        }

        Arc::new(cfg)
    }
}

#[async_trait(?Send)]
impl BenchStepper for ClientSideStepper<'_> {
    type Endpoint = ClientConnection;

    async fn handshake(&mut self) -> anyhow::Result<Self::Endpoint> {
        let server_name = "localhost".try_into().unwrap();
        let mut client = self
            .config
            .connect(server_name)
            .build()
            .unwrap();
        client.set_buffer_limit(None);

        loop {
            send_handshake_message(&mut client, self.io.writer, self.io.handshake_buf).await?;
            if !client.is_handshaking() && !client.wants_write() {
                break;
            }
            read_handshake_message(&mut client, self.io.reader, self.io.handshake_buf).await?;
        }

        // Session ids and tickets are no longer part of the handshake in TLS 1.3, so we need to
        // explicitly receive them from the server
        if self.resumption_kind != ResumptionKind::No
            && client.protocol_version().unwrap() == ProtocolVersion::TLSv1_3
        {
            read_handshake_message(&mut client, self.io.reader, self.io.handshake_buf).await?;
        }

        Ok(client)
    }

    async fn sync_before_resumed_handshake(&mut self) -> anyhow::Result<()> {
        // The client syncs by receiving a single byte (we assert that it matches the `42` byte sent
        // by the server, just to be sure)
        let buf = &mut [0];
        self.io.reader.read_exact(buf).await?;
        assert_eq!(buf[0], 42);
        Ok(())
    }

    async fn transmit_data(&mut self, endpoint: &mut Self::Endpoint) -> anyhow::Result<()> {
        let total_plaintext_read = read_plaintext_to_end_bounded(endpoint, self.io.reader).await?;
        assert_eq!(total_plaintext_read, TRANSFER_PLAINTEXT_SIZE);
        Ok(())
    }

    fn handshake_kind(&self, endpoint: &Self::Endpoint) -> HandshakeKind {
        endpoint.handshake_kind().unwrap()
    }
}

/// A benchmark stepper for the server-side of the connection
struct ServerSideStepper<'a> {
    io: StepperIo<'a>,
    config: Arc<ServerConfig>,
}

impl ServerSideStepper<'_> {
    fn make_config(params: &BenchmarkParams, resume: ResumptionKind) -> Arc<ServerConfig> {
        let cfg = ServerConfig::builder(params.provider.clone());

        let mut cfg = match params.auth_key {
            AuthKeySource::KeyType(key_type) => cfg
                .with_client_cert_verifier(WebPkiClientVerifier::no_client_auth())
                .with_single_cert(key_type.identity(), key_type.key())
                .expect("bad certs/private key?"),

            AuthKeySource::FuzzingProvider => cfg
                .with_client_cert_verifier(WebPkiClientVerifier::no_client_auth())
                .with_server_credential_resolver(rustls_fuzzing_provider::server_cert_resolver())
                .unwrap(),
        };

        if resume == ResumptionKind::SessionId {
            cfg.session_storage = ServerSessionMemoryCache::new(128);
        } else if resume == ResumptionKind::Tickets {
            cfg.ticketer = Some((params.ticketer)());
        } else {
            cfg.session_storage = Arc::new(NoServerSessionStorage {});
        }

        Arc::new(cfg)
    }
}

#[async_trait(?Send)]
impl BenchStepper for ServerSideStepper<'_> {
    type Endpoint = ServerConnection;

    async fn handshake(&mut self) -> anyhow::Result<Self::Endpoint> {
        let mut server = ServerConnection::new(self.config.clone()).unwrap();
        server.set_buffer_limit(None);

        while server.is_handshaking() {
            read_handshake_message(&mut server, self.io.reader, self.io.handshake_buf).await?;
            send_handshake_message(&mut server, self.io.writer, self.io.handshake_buf).await?;
        }

        Ok(server)
    }

    async fn sync_before_resumed_handshake(&mut self) -> anyhow::Result<()> {
        // The server syncs by sending a single byte
        self.io.writer.write_all(&[42]).await?;
        self.io.writer.flush().await?;
        Ok(())
    }

    async fn transmit_data(&mut self, endpoint: &mut Self::Endpoint) -> anyhow::Result<()> {
        write_all_plaintext_bounded(endpoint, self.io.writer, TRANSFER_PLAINTEXT_SIZE).await?;
        Ok(())
    }

    fn handshake_kind(&self, endpoint: &Self::Endpoint) -> HandshakeKind {
        endpoint.handshake_kind().unwrap()
    }
}

/// Runs the benchmark using the provided stepper
async fn run_bench<T: BenchStepper>(
    mut stepper: T,
    kind: BenchmarkKind,
    resumed_reps: usize,
) -> anyhow::Result<()> {
    match kind {
        BenchmarkKind::Handshake(ResumptionKind::No) => {
            // Just count instructions for one handshake.
            let _count = CountInstructions::start();
            black_box(stepper.handshake().await?);
        }
        BenchmarkKind::Handshake(_) => {
            // The first handshake performed is non-resumed, because the client didn't have a
            // session ID / ticket.  This is not measured.
            stepper.handshake().await?;

            let _count = CountInstructions::start();
            for _ in 0..resumed_reps {
                // Wait for the endpoints to sync (i.e. the server must have discarded the previous
                // connection and be ready for a new handshake, otherwise the client will start a
                // handshake before the server is ready and the bytes will be fed to the old
                // connection!)
                stepper
                    .sync_before_resumed_handshake()
                    .await?;
                let endpoint = stepper.handshake().await?;
                assert_eq!(stepper.handshake_kind(&endpoint), HandshakeKind::Resumed);
            }
        }
        BenchmarkKind::Transfer => {
            // Measurement includes the transfer, but not the handshake.
            let mut endpoint = stepper.handshake().await?;
            let _count = CountInstructions::start();
            stepper
                .transmit_data(&mut endpoint)
                .await?;
        }
    }

    Ok(())
}

/// The results of a comparison between two `run-all` executions
struct CompareResult {
    /// Results for benchmark scenarios we know are fairly deterministic.
    ///
    /// The string is a detailed diff between the instruction counts obtained from callgrind.
    diffs: Vec<(Diff, String)>,
    /// Benchmark scenarios present in the candidate but missing in the baseline
    missing_in_baseline: Vec<String>,
}

/// The results of a comparison between two `run-all` executions
struct MemoryCompareResult {
    diffs: Vec<MemoryDiff>,
    /// Benchmark scenarios present in the candidate but missing in the baseline
    missing_in_baseline: Vec<String>,
}

/// Contains information about instruction counts and their difference for a specific scenario
#[derive(Clone)]
struct Diff {
    scenario: String,
    baseline: u64,
    candidate: u64,
    diff: i64,
    diff_ratio: f64,
}

/// Contains information about memory usage and a difference for a specific scenario & comparator
#[derive(Clone)]
struct MemoryDiff {
    scenario: String,
    baseline: MemoryDetails,
    candidate: MemoryDetails,
    comparator: CompareMemoryOperand,
    diff: i64,
    diff_ratio: f64,
}

/// Reads the (benchmark, instruction count) pairs from previous CSV output
fn read_icount_results(path: &Path) -> anyhow::Result<HashMap<String, u64>> {
    let file = File::open(path).context(format!(
        "CSV file for comparison not found: {}",
        path.display()
    ))?;

    let mut measurements = HashMap::new();
    for line in BufReader::new(file).lines() {
        let line = line.context("Unable to read results from CSV file")?;
        let line = line.trim();
        let mut parts = line.split(',');
        measurements.insert(
            parts
                .next()
                .ok_or_else(|| anyhow::anyhow!("CSV is wrongly formatted"))?
                .to_string(),
            parts
                .next()
                .ok_or_else(|| anyhow::anyhow!("CSV is wrongly formatted"))?
                .parse()
                .context("Unable to parse instruction count from CSV")?,
        );
    }

    Ok(measurements)
}

/// Reads the (benchmark, instruction count) pairs from previous CSV output
fn read_memory_results(path: &Path) -> anyhow::Result<HashMap<String, MemoryDetails>> {
    let file = File::open(path).context(format!(
        "CSV file for comparison not found: {}",
        path.display()
    ))?;

    let mut measurements = HashMap::new();
    for line in BufReader::new(file).lines() {
        let line = line.context("Unable to read results from CSV file")?;
        let line = line.trim();
        let mut parts = line.split(',');
        measurements.insert(
            parts
                .next()
                .ok_or_else(|| anyhow::anyhow!("CSV is wrongly formatted"))?
                .to_string(),
            MemoryDetails {
                heap_total_bytes: parts
                    .next()
                    .ok_or_else(|| anyhow::anyhow!("CSV is wrongly formatted"))?
                    .parse()
                    .context("Unable to parse heap total bytes from CSV")?,
                heap_total_blocks: parts
                    .next()
                    .ok_or_else(|| anyhow::anyhow!("CSV is wrongly formatted"))?
                    .parse()
                    .context("Unable to parse heap total blocks from CSV")?,
                heap_peak_bytes: parts
                    .next()
                    .ok_or_else(|| anyhow::anyhow!("CSV is wrongly formatted"))?
                    .parse()
                    .context("Unable to parse heap peak bytes from CSV")?,
                heap_peak_blocks: parts
                    .next()
                    .ok_or_else(|| anyhow::anyhow!("CSV is wrongly formatted"))?
                    .parse()
                    .context("Unable to parse heap peak blocks from CSV")?,
            },
        );
    }

    Ok(measurements)
}

/// Returns an internal representation of the comparison between the baseline and the candidate
/// measurements
fn compare_icount_results(
    baseline_dir: &Path,
    candidate_dir: &Path,
    baseline: &HashMap<String, u64>,
    candidate: &HashMap<String, u64>,
) -> anyhow::Result<CompareResult> {
    let mut diffs = Vec::new();
    let mut missing = Vec::new();

    for (scenario, &instr_count) in candidate {
        let Some(&baseline_instr_count) = baseline.get(scenario) else {
            missing.push(scenario.clone());
            continue;
        };

        let diff = instr_count as i64 - baseline_instr_count as i64;
        let diff_ratio = diff as f64 / baseline_instr_count as f64;
        let diff = Diff {
            scenario: scenario.clone(),
            baseline: baseline_instr_count,
            candidate: instr_count,
            diff,
            diff_ratio,
        };

        diffs.push(diff);
    }

    diffs.sort_by(|diff1, diff2| {
        diff2
            .diff_ratio
            .abs()
            .total_cmp(&diff1.diff_ratio.abs())
    });

    let mut diffs_with_callgrind_diff = Vec::new();
    for diff in diffs {
        let detailed_diff = valgrind::callgrind_diff(baseline_dir, candidate_dir, &diff.scenario)?;
        diffs_with_callgrind_diff.push((diff, detailed_diff));
    }

    Ok(CompareResult {
        diffs: diffs_with_callgrind_diff,
        missing_in_baseline: missing,
    })
}

/// Returns an internal representation of the comparison between the baseline and the candidate
/// measurements
fn compare_memory_results(
    baseline: &HashMap<String, MemoryDetails>,
    candidate: &HashMap<String, MemoryDetails>,
    comparator: CompareMemoryOperand,
) -> anyhow::Result<MemoryCompareResult> {
    let mut diffs = Vec::new();
    let mut missing = Vec::new();

    for (scenario, &candidate_memory) in candidate {
        let Some(&baseline_memory) = baseline.get(scenario) else {
            missing.push(scenario.clone());
            continue;
        };

        let candidate_count = comparator.choose(candidate_memory);
        let baseline_count = comparator.choose(baseline_memory);

        let diff = candidate_count as i64 - baseline_count as i64;
        let diff_ratio = diff as f64 / baseline_count as f64;
        let diff = MemoryDiff {
            scenario: scenario.clone(),
            baseline: baseline_memory,
            candidate: candidate_memory,
            comparator,
            diff,
            diff_ratio,
        };

        diffs.push(diff);
    }

    diffs.sort_by(|diff1, diff2| {
        diff2
            .diff_ratio
            .abs()
            .total_cmp(&diff1.diff_ratio.abs())
    });

    Ok(MemoryCompareResult {
        diffs,
        missing_in_baseline: missing,
    })
}

/// Prints a report of the comparison to stdout, using GitHub-flavored markdown
fn print_icount_report(result: &CompareResult) {
    println!("# Benchmark results");

    if !result.missing_in_baseline.is_empty() {
        println!("### ⚠️ Warning: missing benchmarks");
        println!();
        println!(
            "The following benchmark scenarios are present in the candidate but not in the baseline:"
        );
        println!();
        for scenario in &result.missing_in_baseline {
            println!("* {scenario}");
        }
    }

    println!("## Instruction count differences");
    if result.diffs.is_empty() {
        println!("_There are no instruction count differences_");
    } else {
        table(
            result
                .diffs
                .iter()
                .map(|(diff, _)| diff),
            true,
        );
        println!("<details>");
        println!("<summary>Details per scenario</summary>\n");
        for (diff, detailed_diff) in &result.diffs {
            println!("#### {}", diff.scenario);
            println!("```");
            println!("{detailed_diff}");
            println!("```");
        }
        println!("</details>\n")
    }
}

fn print_memory_report(result: &MemoryCompareResult) {
    println!("# Memory measurement results");

    if !result.missing_in_baseline.is_empty() {
        println!("### ⚠️ Warning: missing benchmarks");
        println!();
        println!(
            "The following benchmark scenarios are present in the candidate but not in the baseline:"
        );
        println!();
        for scenario in &result.missing_in_baseline {
            println!("* {scenario}");
        }
    }

    println!("## Memory measurement differences");
    if result.diffs.is_empty() {
        println!("_There are no memory measurement differences_");
    } else {
        memory_table(&result.diffs, true);
    }
}

/// Renders the diffs as a markdown table
fn table<'a>(diffs: impl Iterator<Item = &'a Diff>, emoji_feedback: bool) {
    println!("| Scenario | Baseline | Candidate | Diff |");
    println!("| --- | ---: | ---: | ---: |");
    for diff in diffs {
        let emoji = match emoji_feedback {
            true if diff.diff > 0 => "⚠️ ",
            true if diff.diff < 0 => "✅ ",
            _ => "",
        };

        println!(
            "| {} | {} | {} | {}{} ({:.2}%) |",
            diff.scenario,
            diff.baseline,
            diff.candidate,
            emoji,
            diff.diff,
            diff.diff_ratio * 100.0
        )
    }
}

/// Renders the diffs as a markdown table
fn memory_table(diffs: &[MemoryDiff], emoji_feedback: bool) {
    println!("| Scenario | Baseline | Candidate | Diff |");
    println!("| --- | ---: | ---: | ---: |");
    for diff in diffs {
        let emoji = match emoji_feedback {
            true if diff.diff_ratio > 0.01 => "⚠️ ",
            true if diff.diff_ratio < -0.01 => "✅ ",
            _ => "",
        };

        println!(
            "| {} | Total {}B / {}# <br/> Peak {}B / {}# | Total {}B / {}# <br/> Peak {}B / {}# | {:?} {}{} ({:.2}%) |",
            diff.scenario,
            diff.baseline.heap_total_bytes,
            diff.baseline.heap_total_blocks,
            diff.baseline.heap_peak_bytes,
            diff.baseline.heap_peak_blocks,
            diff.candidate.heap_total_bytes,
            diff.candidate.heap_total_blocks,
            diff.candidate.heap_peak_bytes,
            diff.candidate.heap_peak_blocks,
            diff.comparator,
            emoji,
            diff.diff,
            diff.diff_ratio * 100.0
        )
    }
}


================================================
FILE: ci-bench/src/util.rs
================================================
pub(crate) mod async_io {
    //! Async IO building blocks required for sharing code between the instruction count and
    //! wall-time benchmarks

    use core::cell::{Cell, RefCell};
    use core::future::Future;
    use core::pin::{Pin, pin};
    use core::task::{Poll, RawWaker, RawWakerVTable, Waker};
    use core::{ptr, task};
    use std::collections::VecDeque;
    use std::fs::File;
    use std::io;
    use std::rc::Rc;

    use async_trait::async_trait;

    /// Block on a future that should complete in a single poll.
    ///
    /// Safe to use when the underlying futures are blocking (e.g. waiting for an IO operation to
    /// complete, and returning Poll::Ready afterwards, without yielding in between).
    ///
    /// Useful when counting CPU instructions, because the server and the client side of the
    /// connection run in two separate processes and communicate through stdio using blocking
    /// operations.
    pub(crate) fn block_on_single_poll(
        future: impl Future<Output = anyhow::Result<()>>,
    ) -> anyhow::Result<()> {
        // We don't need a waker, because the future will complete in one go
        let waker = noop_waker();
        let mut ctx = task::Context::from_waker(&waker);

        match pin!(future).poll(&mut ctx) {
            Poll::Ready(result) => result,
            Poll::Pending => {
                panic!("the provided future did not finish after one poll!")
            }
        }
    }

    /// Block on two futures that are run concurrently and return their results.
    ///
    /// Useful when measuring wall-time, because the server and the client side of the connection
    /// run in a single process _and_ thread to minimize noise. Each side of the connection runs
    /// inside its own future and they are polled in turns.
    ///
    /// Using this together with blocking futures can lead to deadlocks (i.e. when one of the
    /// futures is blocked while it waits on a message from the other).
    pub(crate) fn block_on_concurrent(
        x: impl Future<Output = anyhow::Result<()>>,
        y: impl Future<Output = anyhow::Result<()>>,
    ) -> (anyhow::Result<()>, anyhow::Result<()>) {
        let mut x = pin!(x);
        let mut y = pin!(y);

        // The futures won't complete right away, but since there are only two of them we can poll
        // them in turns without a more complex waking mechanism.
        let waker = noop_waker();
        let mut ctx = task::Context::from_waker(&waker);

        let mut x_output = None;
        let mut y_output = None;

        // Fuel makes sure we can exit a potential infinite loop if the futures are endlessly
        // waiting on each other due to a bug (e.g. a read without a corresponding write)
        let mut fuel = 1_000;
        loop {
            let futures_done = x_output.is_some() && y_output.is_some();
            if futures_done || fuel == 0 {
                break;
            }

            fuel -= 1;

            if x_output.is_none() {
                match x.as_mut().poll(&mut ctx) {
                    Poll::Ready(output) => x_output = Some(output),
                    Poll::Pending => {}
                }
            }

            if y_output.is_none() {
                match y.as_mut().poll(&mut ctx) {
                    Poll::Ready(output) => y_output = Some(output),
                    Poll::Pending => {}
                }
            }
        }

        match (x_output, y_output) {
            (Some(x_output), Some(y_output)) => (x_output, y_output),
            _ => panic!("at least one of the futures seems to be stuck"),
        }
    }

    // Copied from Waker::noop, which we cannot use directly because it hasn't been stabilized
    fn noop_waker() -> Waker {
        const VTABLE: RawWakerVTable = RawWakerVTable::new(|_| RAW, |_| {}, |_| {}, |_| {});
        const RAW: RawWaker = RawWaker::new(ptr::null(), &VTABLE);
        unsafe { Waker::from_raw(RAW) }
    }

    /// Read bytes asynchronously
    #[async_trait(?Send)]
    pub(crate) trait AsyncRead {
        async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>;
        async fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()>;
    }

    /// Write bytes asynchronously
    #[async_trait(?Send)]
    pub(crate) trait AsyncWrite {
        async fn write_all(&mut self, buf: &[u8]) -> io::Result<()>;
        async fn flush(&mut self) -> io::Result<()>;
    }

    // Blocking implementation of AsyncRead for files (used to read from stdin)
    #[async_trait(?Send)]
    impl AsyncRead for File {
        async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            io::Read::read(self, buf)
        }

        async fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
            io::Read::read_exact(self, buf)
        }
    }

    // Blocking implementation of AsyncWrite for files (used to write to stdout)
    #[async_trait(?Send)]
    impl AsyncWrite for File {
        async fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
            io::Write::write_all(self, buf)
        }

        async fn flush(&mut self) -> io::Result<()> {
            io::Write::flush(self)
        }
    }

    /// Creates an unidirectional byte pipe of the given capacity, suitable for async reading and
    /// writing
    pub(crate) fn async_pipe(capacity: usize) -> (AsyncSender, AsyncReceiver) {
        let open = Rc::new(Cell::new(true));
        let buf = Rc::new(RefCell::new(VecDeque::with_capacity(capacity)));
        (
            AsyncSender {
                inner: AsyncPipeSide {
                    open: Rc::clone(&open),
                    buf: Rc::clone(&buf),
                },
            },
            AsyncReceiver {
                inner: AsyncPipeSide { open, buf },
            },
        )
    }

    /// The sender end of an asynchronous byte pipe
    pub(crate) struct AsyncSender {
        inner: AsyncPipeSide,
    }

    /// The receiver end of an asynchronous byte pipe
    pub(crate) struct AsyncReceiver {
        inner: AsyncPipeSide,
    }

    struct AsyncPipeSide {
        open: Rc<Cell<bool>>,
        buf: Rc<RefCell<VecDeque<u8>>>,
    }

    impl Drop for AsyncPipeSide {
        fn drop(&mut self) {
            self.open.set(false);
        }
    }

    #[async_trait(?Send)]
    impl AsyncRead for AsyncReceiver {
        async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            AsyncPipeReadFuture {
                reader: self,
                user_buf: buf,
            }
            .await
        }

        async fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
            let mut read = 0;
            while read < buf.len() {
                read += self.read(&mut buf[read..]).await?;
            }

            Ok(())
        }
    }

    #[async_trait(?Send)]
    impl AsyncWrite for AsyncSender {
        async fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
            AsyncPipeWriteFuture {
                writer: self,
                user_buf: buf,
            }
            .await
        }

        async fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    struct AsyncPipeReadFuture<'a> {
        reader: &'a AsyncReceiver,
        user_buf: &'a mut [u8],
    }

    impl Future for AsyncPipeReadFuture<'_> {
        type Output = io::Result<usize>;

        fn poll(mut self: Pin<&mut Self>, _: &mut task::Context<'_>) -> Poll<Self::Output> {
            let inner_buf = &mut self.reader.inner.buf.borrow_mut();
            if inner_buf.is_empty() {
                return if self.reader.inner.open.get() {
                    // Wait for data to arrive, or EOF
                    Poll::Pending
                } else {
                    // EOF
                    Poll::Ready(Ok(0))
                };
            }

            let bytes_to_write = inner_buf.len().min(self.user_buf.len());

            // This is a convoluted way to copy the bytes from the inner buffer into the user's
            // buffer
            let (first_half, second_half) = inner_buf.as_slices();
            let bytes_to_write_from_first_half = first_half.len().min(bytes_to_write);
            let bytes_to_write_from_second_half =
                bytes_to_write.saturating_sub(bytes_to_write_from_first_half);
            self.user_buf[..bytes_to_write_from_first_half]
                .copy_from_slice(&first_half[..bytes_to_write_from_first_half]);
            self.user_buf[bytes_to_write_from_first_half..bytes_to_write]
                .copy_from_slice(&second_half[..bytes_to_write_from_second_half]);

            inner_buf.drain(..bytes_to_write);

            Poll::Ready(Ok(bytes_to_write))
        }
    }

    struct AsyncPipeWriteFuture<'a> {
        writer: &'a AsyncSender,
        user_buf: &'a [u8],
    }

    impl Future for AsyncPipeWriteFuture<'_> {
        type Output = io::Result<()>;

        fn poll(mut self: Pin<&mut Self>, _: &mut task::Context<'_>) -> Poll<Self::Output> {
            if !self.writer.inner.open.get() {
                return Poll::Ready(Err(io::Error::other("channel was closed")));
            }

            let mut pipe_buf = self.writer.inner.buf.borrow_mut();
            let capacity_left = pipe_buf.capacity() - pipe_buf.len();
            let bytes_to_write = self.user_buf.len().min(capacity_left);
            pipe_buf.extend(&self.user_buf[..bytes_to_write]);

            if self.user_buf.len() > capacity_left {
                self.user_buf = &self.user_buf[bytes_to_write..];

                // Continue writing later once capacity is available
                Poll::Pending
            } else {
                Poll::Ready(Ok(()))
            }
        }
    }

    #[cfg(test)]
    mod test {
        use super::*;

        #[test]
        fn test_block_on_concurrent_minimal_capacity() {
            test_block_on_concurrent(1);
        }

        #[test]
        fn test_block_on_concurrent_enough_capacity() {
            test_block_on_concurrent(100);
        }

        fn test_block_on_concurrent(capacity: usize) {
            let (mut server_writer, mut client_reader) = async_pipe(capacity);
            let (mut client_writer, mut server_reader) = async_pipe(capacity);

            let client = async {
                client_writer
                    .write_all(b"hello")
                    .await
                    .unwrap();

                let mut buf = [0; 2];
                client_reader
                    .read_exact(&mut buf)
                    .await
                    .unwrap();
                assert_eq!(&buf, b"42");

                client_writer
                    .write_all(b"bye bye")
                    .await
                    .unwrap();

                Ok(())
            };

            let server = async {
                let mut buf = [0; 5];
                server_reader
                    .read_exact(&mut buf)
                    .await
                    .unwrap();
                assert_eq!(&buf, b"hello");

                server_writer
                    .write_all(b"42")
                    .await
                    .unwrap();

                let mut buf = [0; 7];
                server_reader
                    .read_exact(&mut buf)
                    .await
                    .unwrap();
                assert_eq!(&buf, b"bye bye");

                Ok(())
            };

            let (client_result, server_result) = block_on_concurrent(client, server);
            client_result.unwrap();
            server_result.unwrap();
        }
    }
}

pub(crate) mod transport {
    //! Custom functions to interact between rustls clients and a servers.
    //!
    //! The goal of these functions is to ensure messages are exchanged in chunks of a fixed size, to make
    //! instruction counts more deterministic. This is particularly important for the receiver of the
    //! data. Without it, the amount of bytes received in a single `read` call can wildly differ among
    //! benchmark runs, which in turn influences the resizing of rustls' internal buffers, and therefore
    //! affects the instruction count (resulting in consistent noise above 2% for the client-side of the
    //! data transfer benchmarks, which is unacceptable).
    //!
    //! Note that this approach introduces extra copies, because we are using an intermediate buffer,
    //! but that doesn't matter (we are measuring performance differences, and overhead is automatically
    //! ignored as long as it remains constant).

    use std::io::{Cursor, Read, Write};

    use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
    use rustls::{ClientConnection, Connection, ServerConnection};

    use super::async_io::{AsyncRead, AsyncWrite};

    /// Sends one side's handshake data to the other side in one go.
    ///
    /// Because it is not possible for the receiver to know beforehand how many bytes are contained in
    /// the message, the transmission consists of a leading big-endian u32 specifying the message's
    /// length, followed by the message itself.
    ///
    /// The receiving end should use [`read_handshake_message`] to process the transmission.
    pub(crate) async fn send_handshake_message(
        conn: &mut impl Connection,
        writer: &mut dyn AsyncWrite,
        buf: &mut [u8],
    ) -> anyhow::Result<()> {
        // Write all bytes the connection wants to send to an intermediate buffer
        let mut written = 0;
        while conn.wants_write() {
            if written >= buf.len() {
                anyhow::bail!(
                    "Not enough space in buffer for outgoing message (buf len = {})",
                    buf.len()
                );
            }

            written += conn.write_tls(&mut &mut buf[written..])?;
        }

        if written == 0 {
            return Ok(());
        }

        // Write the whole buffer in one go, preceded by its length
        let mut length_buf = Vec::with_capacity(4);
        length_buf.write_u32::<BigEndian>(written as u32)?;
        writer.write_all(&length_buf).await?;
        writer
            .write_all(&buf[..written])
            .await?;
        writer.flush().await?;

        Ok(())
    }

    /// Receives one side's handshake data to the other side in one go.
    ///
    /// Used in combination with [`send_handshake_message`] (see that function's documentation for
    /// more details).
    pub(crate) async fn read_handshake_message(
        conn: &mut impl Connection,
        reader: &mut dyn AsyncRead,
        buf: &mut [u8],
    ) -> anyhow::Result<usize> {
        // Read the length of the message to an intermediate buffer and parse it
        let mut length_buf = [0; 4];
        reader
            .read_exact(&mut length_buf)
            .await?;
        let length = Cursor::new(length_buf).read_u32::<BigEndian>()? as usize;

        // Read the rest of the message to an intermediate buffer
        if length >= buf.len() {
            anyhow::bail!(
                "Not enough space in buffer for incoming message (msg len = {length}, buf len = {})",
                buf.len()
            );
        }

        reader
            .read_exact(&mut buf[..length])
            .await?;

        // Feed the data to rustls
        let in_memory_reader = &mut &buf[..length];
        while conn.read_tls(in_memory_reader)? != 0 {
            conn.process_new_packets()?;
        }

        Ok(length)
    }

    /// Reads plaintext until the reader reaches EOF, using a bounded amount of memory.
    ///
    /// Returns the amount of plaintext bytes received.
    pub(crate) async fn read_plaintext_to_end_bounded(
        client: &mut ClientConnection,
        reader: &mut dyn AsyncRead,
    ) -> anyhow::Result<usize> {
        let mut chunk_buf = [0u8; 262_144];
        let mut plaintext_buf = [0u8; 262_144];
        let mut total_plaintext_bytes_read = 0;

        loop {
            // Read until the whole chunk is received
            let mut chunk_buf_end = 0;
            while chunk_buf_end != chunk_buf.len() {
                let read = reader
                    .read(&mut chunk_buf[chunk_buf_end..])
                    .await?;
                if read == 0 {
                    // Stream closed
                    break;
                }

                chunk_buf_end += read;
            }

            if chunk_buf_end == 0 {
                // Stream closed
                break;
            }

            // Load the buffer's bytes into rustls
            let mut chunk_buf_offset = 0;
            while chunk_buf_offset < chunk_buf_end {
                let read = client.read_tls(&mut &chunk_buf[chunk_buf_offset..chunk_buf_end])?;
                chunk_buf_offset += read;

                // Process packets to free space in the message buffer
                let state = client.process_new_packets()?;
                let available_plaintext_bytes = state.plaintext_bytes_to_read();
                let mut plaintext_bytes_read = 0;
                while plaintext_bytes_read < available_plaintext_bytes {
                    plaintext_bytes_read += client
                        .reader()
                        .read(&mut plaintext_buf)?;
                }

                total_plaintext_bytes_read += plaintext_bytes_read;
            }
        }

        Ok(total_plaintext_bytes_read)
    }

    /// Writes a plaintext of size `plaintext_size`, using a bounded amount of memory
    pub(crate) async fn write_all_plaintext_bounded(
        server: &mut ServerConnection,
        writer: &mut dyn AsyncWrite,
        plaintext_size: usize,
    ) -> anyhow::Result<()> {
        let mut send_buf = [0u8; 262_144];
        assert_eq!(plaintext_size % send_buf.len(), 0);
        let iterations = plaintext_size / send_buf.len();

        for _ in 0..iterations {
            server.writer().write_all(&send_buf)?;

            // Empty the server's buffer, so we can re-fill it in the next iteration
            while server.wants_write() {
                let written = server.write_tls(&mut send_buf.as_mut())?;
                writer
                    .write_all(&send_buf[..written])
                    .await?;
                writer.flush().await?;
            }
        }

        Ok(())
    }
}


================================================
FILE: ci-bench/src/valgrind.rs
================================================
use core::ops::Sub;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Stdio};

use anyhow::Context;

use crate::Side;
use crate::benchmark::Benchmark;

/// A callgrind-based benchmark runner
pub(crate) struct CallgrindRunner {
    /// The path to the ci-bench executable
    ///
    /// This is necessary because the callgrind runner works by spawning child processes
    executable: String,
    /// The directory where the callgrind output will be stored
    output_dir: PathBuf,
}

impl CallgrindRunner {
    /// Returns a new callgrind-based benchmark runner
    pub(crate) fn new(executable: String, output_dir: PathBuf) -> anyhow::Result<Self> {
        ensure_valgrind_tool_available("--tool=callgrind")?;

        let callgrind_output_dir = output_dir.join(CALLGRIND_OUTPUT_SUBDIR);
        std::fs::create_dir_all(&callgrind_output_dir)
            .context("Failed to create callgrind output directory")?;

        Ok(Self {
            executable,
            output_dir: callgrind_output_dir,
        })
    }

    /// Runs the benchmark at the specified index and returns the instruction counts for each side
    pub(crate) fn run_bench(&self, bench: &Benchmark) -> anyhow::Result<InstructionCounts> {
        // The server and client are started as child processes, and communicate with each other
        // through stdio.

        let mut server = Self::run_bench_side(
            &self.executable,
            bench.name(),
            Side::Server,
            &bench.name_with_side(Side::Server),
            Stdio::piped(),
            Stdio::piped(),
            &self.output_dir,
        )
        .context("server side bench crashed")?;

        let client = Self::run_bench_side(
            &self.executable,
            bench.name(),
            Side::Client,
            &bench.name_with_side(Side::Client),
            Stdio::from(server.process.stdout.take().unwrap()),
            Stdio::from(server.process.stdin.take().unwrap()),
            &self.output_dir,
        )
        .context("client side bench crashed")?;

        Ok(InstructionCounts {
            server: server.wait_and_get_instr_count()?,
            client: client.wait_and_get_instr_count()?,
        })
    }

    /// See docs for [`Self::run_bench`]
    fn run_bench_side(
        executable: &str,
        bench_name: &str,
        side: Side,
        output_name: &str,
        stdin: Stdio,
        stdout: Stdio,
        output_dir: &Path,
    ) -> anyhow::Result<BenchSubprocess> {
        let output_file = output_dir.join(output_name);
        let log_file = output_dir.join(format!("{output_name}.log"));

        // Run under setarch to disable ASLR, to reduce noise
        let mut cmd = Command::new("setarch");
        let child = cmd
            .arg("-R")
            .arg("valgrind")
            .arg("--tool=callgrind")
            // Do not count instructions from the start, instead this is controlled by `CountInstructions`
            .arg("--collect-atstart=no")
            // Disable the cache simulation, since we are only interested in instruction counts
            .arg("--cache-sim=no")
            // Save callgrind's logs, which would otherwise be printed to stderr (we want to
            // keep stderr free of noise, to see any errors from the child process)
            .arg(format!("--log-file={}", log_file.display()))
            // The file where the instruction counts will be stored
            .arg(format!("--callgrind-out-file={}", output_file.display()))
            .arg(executable)
            .arg("run-pipe")
            .arg(bench_name)
            .arg(side.as_str())
            .arg("instruction")
            .stdin(stdin)
            .stdout(stdout)
            .stderr(Stdio::inherit())
            .spawn()
            .context("Failed to run benchmark in callgrind")?;

        Ok(BenchSubprocess {
            process: child,
            output: ValgrindOutput::Callgrind { output_file },
        })
    }
}

/// A DHAT-based benchmark runner that measures runtime memory use.
pub(crate) struct DhatRunner {
    /// The path to the ci-bench executable
    ///
    /// This is necessary because the runner works by spawning child processes
    executable: String,
    /// The directory where the output will be stored
    output_dir: PathBuf,
}

impl DhatRunner {
    /// Returns a new callgrind-based benchmark runner
    pub(crate) fn new(executable: String, output_dir: PathBuf) -> anyhow::Result<Self> {
        ensure_valgrind_tool_available("--tool=dhat")?;

        let output_dir = output_dir.join("dhat");
        std::fs::create_dir_all(&output_dir).context("Failed to create DHAT output directory")?;

        Ok(Self {
            executable,
            output_dir,
        })
    }

    /// Runs the benchmark at the specified index and returns the memory usage for each side
    pub(crate) fn run_bench(&self, bench: &Benchmark) -> anyhow::Result<MemoryProfile> {
        // The server and client are started as child processes, and communicate with each other
        // through stdio.

        let mut server = Self::run_bench_side(
            &self.executable,
            bench.name(),
            Side::Server,
            &bench.name_with_side(Side::Server),
            Stdio::piped(),
            Stdio::piped(),
            &self.output_dir,
        )
        .context("server side bench crashed")?;

        let client = Self::run_bench_side(
            &self.executable,
            bench.name(),
            Side::Client,
            &bench.name_with_side(Side::Client),
            Stdio::from(server.process.stdout.take().unwrap()),
            Stdio::from(server.process.stdin.take().unwrap()),
            &self.output_dir,
        )
        .context("client side bench crashed")?;

        Ok(MemoryProfile {
            server: server.wait_and_get_memory_details()?,
            client: client.wait_and_get_memory_details()?,
        })
    }

    /// See docs for [`Self::run_bench`]
    fn run_bench_side(
        executable: &str,
        bench_name: &str,
        side: Side,
        output_name: &str,
        stdin: Stdio,
        stdout: Stdio,
        output_dir: &Path,
    ) -> anyhow::Result<BenchSubprocess> {
        let output_file = output_dir.join(output_name);
        let log_file = output_dir.join(format!("{output_name}.log"));

        // Run under setarch to disable ASLR, to reduce noise
        let mut cmd = Command::new("setarch");
        let child = cmd
            .arg("-R")
            .arg("valgrind")
            .arg("--tool=dhat")
            // We extract output from DHAT's logs, which contain a summary.
            .arg(format!("--log-file={}", log_file.display()))
            // Also save the detailed JSON
            .arg(format!("--dhat-out-file={}", output_file.display()))
            .arg(executable)
            .arg("run-pipe")
            .arg(bench_name)
            .arg(side.as_str())
            .arg("memory")
            .stdin(stdin)
            .stdout(stdout)
            .stderr(Stdio::inherit())
            .spawn()
            .context("Failed to run benchmark in DHAT")?;

        Ok(BenchSubprocess {
            process: child,
            output: ValgrindOutput::Dhat { log_file },
        })
    }
}

/// The subdirectory in which the callgrind output should be stored
const CALLGRIND_OUTPUT_SUBDIR: &str = "callgrind";

/// Returns an error if valgrind is not available
fn ensure_valgrind_tool_available(tool: &str) -> anyhow::Result<()> {
    let result = Command::new("valgrind")
        .arg(tool)
        .arg("--version")
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .status();

    match result {
        Err(e) => anyhow::bail!(
            "Unexpected error while launching valgrind {tool}. Error: {}",
            e
        ),
        Ok(status) => {
            if status.success() {
                Ok(())
            } else {
                anyhow::bail!(
                    "Failed to launch valgrind {tool}. Error: {}. Please ensure that valgrind is installed and on the $PATH.",
                    status
                )
            }
        }
    }
}

/// A running subprocess for one of the sides of the benchmark (client or server)
struct BenchSubprocess {
    /// The benchmark's child process, running under valgrind
    process: Child,
    /// Valgrind's output file for this benchmark
    output: ValgrindOutput,
}

enum ValgrindOutput {
    Callgrind { output_file: PathBuf },
    Dhat { log_file: PathBuf },
}

impl BenchSubprocess {
    /// Waits for the process to finish and returns the measured instruction count
    fn wait_and_get_instr_count(mut self) -> anyhow::Result<u64> {
        let status = self
            .process
            .wait()
            .context("Failed to run benchmark in callgrind")?;
        if !status.success() {
            anyhow::bail!(
                "Failed to run benchmark in callgrind. Exit code: {:?}",
                status.code()
            );
        }

        let ValgrindOutput::Callgrind { output_file } = self.output else {
            panic!("wait_and_get_instr_count() is for Callgrind users");
        };

        parse_callgrind_output(&output_file)
    }

    /// Waits for the process to finish and returns the measured peak heap usage
    fn wait_and_get_memory_details(mut self) -> anyhow::Result<MemoryDetails> {
        let status = self
            .process
            .wait()
            .context("Failed to run benchmark in DHAT")?;
        if !status.success() {
            anyhow::bail!(
                "Failed to run benchmark in DHAT. Exit code: {:?}",
                status.code()
            );
        }

        let ValgrindOutput::Dhat { log_file } = self.output else {
            panic!("wait_and_get_memory_details() is for DHAT users");
        };

        MemoryDetails::from_file(&log_file)
    }
}

/// Returns the instruction count, extracted from the callgrind output file at the provided path
fn parse_callgrind_output(file: &Path) -> anyhow::Result<u64> {
    let file_in = File::open(file).context("Unable to open callgrind output file")?;

    for line in BufReader::new(file_in).lines() {
        let line = line.context("Error reading callgrind output file")?;
        if let Some(line) = line.strip_prefix("summary: ") {
            let instr_count = line
                .trim()
                .parse()
                .context("Unable to parse instruction counts from callgrind output file")?;

            return Ok(instr_count);
        }
    }

    anyhow::bail!("`summary` section not found in callgrind output file")
}

/// The instruction counts, for each side, after running a benchmark
#[derive(Copy, Clone)]
pub(crate) struct InstructionCounts {
    pub client: u64,
    pub server: u64,
}

impl Sub for InstructionCounts {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        Self {
            client: self.client - rhs.client,
            server: self.server - rhs.server,
        }
    }
}

/// Peak heap usage in bytes, for each side
#[derive(Copy, Clone)]
pub(crate) struct MemoryProfile {
    pub client: MemoryDetails,
    pub server: MemoryDetails,
}

#[derive(Copy, Clone, Default)]
pub(crate) struct MemoryDetails {
    pub heap_total_bytes: u64,
    pub heap_total_blocks: u64,
    pub heap_peak_bytes: u64,
    pub heap_peak_blocks: u64,
}

impl MemoryDetails {
    /// Returns the heap usage, extracted from the DHAT log file at the provided path
    fn from_file(file: &Path) -> anyhow::Result<Self> {
        let file_in = File::open(file).context("Unable to open DHAT log file")?;
        let mut out = Self::default();

        /*
         * Sample:
         *
         * ==1018358== Total:     690,380 bytes in 4,158 blocks
         * ==1018358== At t-gmax: 70,539 bytes in 220 blocks
         * ==1018358== At t-end:  8,648 bytes in 2 blocks
         * ==1018358== Reads:     861,492 bytes
         * ==1018358== Writes:    782,958 bytes
         */

        for line in BufReader::new(file_in).lines() {
            let line = line.context("Error reading DHAT log file")?;

            match line
                .split_whitespace()
                .collect::<Vec<&str>>()
                .as_slice()
            {
                [_, "Total:", bytes, "bytes", "in", blocks, "blocks"] => {
                    out.heap_total_bytes = parse_u64(bytes);
                    out.heap_total_blocks = parse_u64(blocks);
                }
                [_, "At", "t-gmax:", bytes, "bytes", "in", blocks, "blocks"] => {
                    out.heap_peak_bytes = parse_u64(bytes);
                    out.heap_peak_blocks = parse_u64(blocks);
                }
                _ => {}
            }
        }

        fn parse_u64(s: &str) -> u64 {
            s.replace(",", "").parse().unwrap()
        }

        Ok(out)
    }
}

/// Returns the detailed instruction diff between the baseline and the candidate
pub(crate) fn callgrind_diff(
    baseline: &Path,
    candidate: &Path,
    scenario: &str,
) -> anyhow::Result<String> {
    // callgrind_annotate formats the callgrind output file, suitable for comparison with
    // callgrind_differ
    let callgrind_annotate_base = Command::new("callgrind_annotate")
        .arg(
            baseline
                .join(CALLGRIND_OUTPUT_SUBDIR)
                .join(scenario),
        )
        // do not annotate source, to keep output compact
        .arg("--auto=no")
        .output()
        .context("error waiting for callgrind_annotate to finish")?;

    let callgrind_annotate_candidate = Command::new("callgrind_annotate")
        .arg(
            candidate
                .join(CALLGRIND_OUTPUT_SUBDIR)
                .join(scenario),
        )
        // do not annotate source, to keep output compact
        .arg("--auto=no")
        .output()
        .context("error waiting for callgrind_annotate to finish")?;

    if !callgrind_annotate_base.status.success() {
        anyhow::bail!(
            "callgrind_annotate for base finished with an error (code = {:?})",
            callgrind_annotate_base.status.code()
        )
    }

    if !callgrind_annotate_candidate
        .status
        .success()
    {
        anyhow::bail!(
            "callgrind_annotate for candidate finished with an error (code = {:?})",
            callgrind_annotate_candidate
                .status
                .code()
        )
    }

    let string_base = String::from_utf8(callgrind_annotate_base.stdout)
        .context("callgrind_annotate produced invalid UTF8")?;
    let string_candidate = String::from_utf8(callgrind_annotate_candidate.stdout)
        .context("callgrind_annotate produced invalid UTF8")?;

    // TODO: reinstate actual diffing, using `callgrind_differ` crate
    Ok(format!(
        "Base output:\n{string_base}\n\
         =====\n\n\
         Candidate output:\n{string_candidate}\n"
    ))
}

/// A RAII-like object for enabling callgrind instruction counting.
///
/// Warning: must not be nested.
///
/// Instructions outside the scope of these objects are not counted.
pub(crate) struct CountInstructions;

impl CountInstructions {
    pub(crate) fn start() -> Self {
        #[cfg(target_os = "linux")]
        crabgrind::callgrind::toggle_collect();
        Self
    }
}

impl Drop for CountInstructions {
    fn drop(&mut self) {
        #[cfg(target_os = "linux")]
        crabgrind::callgrind::toggle_collect();
    }
}


================================================
FILE: connect-tests/Cargo.toml
================================================
[package]
name = "rustls-connect-tests"
version = "0.0.1"
edition = "2021"
license = "Apache-2.0 OR ISC OR MIT"
des
Download .txt
gitextract_21a4tl8l/

├── .cargo/
│   └── config.toml
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── dependency-update.md
│   │   └── feature_request.md
│   ├── codecov.yml
│   ├── renovate.json
│   ├── typos.toml
│   └── workflows/
│       ├── build.yml
│       ├── cifuzz.yml
│       ├── daily-tests.yml
│       └── docs.yml
├── .gitignore
├── .lycheeignore
├── .rustfmt.toml
├── .rustfmt.unstable.toml
├── .taplo.toml
├── BENCHMARKING.md
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE
├── LICENSE-APACHE
├── LICENSE-ISC
├── LICENSE-MIT
├── README.md
├── RELEASING.md
├── ROADMAP.md
├── SECURITY.md
├── admin/
│   ├── all-features-except
│   ├── all-workspace-members
│   ├── bench-measure.mk
│   ├── bench-range
│   ├── capture-certdata
│   ├── clippy
│   ├── coverage
│   ├── pull-readme
│   └── threads-seq.rs
├── ci-bench/
│   ├── Cargo.toml
│   ├── README.md
│   └── src/
│       ├── benchmark.rs
│       ├── main.rs
│       ├── util.rs
│       └── valgrind.rs
├── connect-tests/
│   ├── Cargo.toml
│   └── tests/
│       ├── badssl.rs
│       ├── common/
│       │   └── mod.rs
│       └── topsites.rs
├── deny.toml
├── examples/
│   ├── Cargo.toml
│   ├── README.md
│   ├── src/
│   │   └── bin/
│   │       ├── ech-client.rs
│   │       ├── limitedclient.rs
│   │       ├── server_acceptor.rs
│   │       ├── simple_0rtt_client.rs
│   │       ├── simple_0rtt_server.rs
│   │       ├── simpleclient.rs
│   │       ├── simpleserver.rs
│   │       ├── tlsclient-mio.rs
│   │       └── tlsserver-mio.rs
│   └── tests/
│       └── limitedclient.rs
├── fuzz/
│   ├── .gitignore
│   ├── Cargo.toml
│   ├── README.md
│   └── fuzzers/
│       ├── client.rs
│       ├── deframer.rs
│       ├── fragment.rs
│       ├── message.rs
│       ├── persist.rs
│       ├── server.rs
│       └── server_name.rs
├── openssl-tests/
│   ├── Cargo.toml
│   └── src/
│       ├── early_exporter.rs
│       ├── ffdhe.rs
│       ├── ffdhe_kx_with_openssl.rs
│       ├── lib.rs
│       ├── raw_key_openssl_interop.rs
│       ├── utils.rs
│       └── validate_ffdhe_params.rs
├── provider-example/
│   ├── Cargo.toml
│   ├── examples/
│   │   ├── client.rs
│   │   └── server.rs
│   └── src/
│       ├── aead.rs
│       ├── hash.rs
│       ├── hmac.rs
│       ├── hpke.rs
│       ├── kx.rs
│       ├── lib.rs
│       ├── sign.rs
│       ├── ticketer.rs
│       └── verify.rs
├── rustls/
│   ├── .clippy.toml
│   ├── Cargo.toml
│   ├── examples/
│   │   └── internal/
│   │       └── test_ca.rs
│   └── src/
│       ├── bs_debug.rs
│       ├── builder.rs
│       ├── check.rs
│       ├── client/
│       │   ├── config.rs
│       │   ├── connection.rs
│       │   ├── ech.rs
│       │   ├── handy.rs
│       │   ├── hs.rs
│       │   ├── mod.rs
│       │   ├── test.rs
│       │   ├── tls12.rs
│       │   └── tls13.rs
│       ├── common_state.rs
│       ├── compress.rs
│       ├── conn/
│       │   ├── kernel.rs
│       │   ├── mod.rs
│       │   ├── receive.rs
│       │   └── send.rs
│       ├── crypto/
│       │   ├── cipher/
│       │   │   ├── messages.rs
│       │   │   ├── mod.rs
│       │   │   └── record_layer.rs
│       │   ├── enums.rs
│       │   ├── hash.rs
│       │   ├── hmac.rs
│       │   ├── hpke.rs
│       │   ├── kx/
│       │   │   ├── ffdhe.rs
│       │   │   └── mod.rs
│       │   ├── mod.rs
│       │   ├── signer.rs
│       │   ├── test_provider.rs
│       │   ├── tls12.rs
│       │   └── tls13.rs
│       ├── enums.rs
│       ├── error/
│       │   ├── mod.rs
│       │   └── tests.rs
│       ├── hash_hs.rs
│       ├── key_log.rs
│       ├── lib.rs
│       ├── limited_cache.rs
│       ├── lock.rs
│       ├── manual/
│       │   ├── defaults.rs
│       │   ├── features.rs
│       │   ├── fips.rs
│       │   ├── howto.rs
│       │   ├── implvulns.rs
│       │   ├── mod.rs
│       │   └── tlsvulns.rs
│       ├── msgs/
│       │   ├── client_hello.rs
│       │   ├── codec.rs
│       │   ├── deframer/
│       │   │   ├── buffers.rs
│       │   │   ├── handshake.rs
│       │   │   └── mod.rs
│       │   ├── enums.rs
│       │   ├── fragmenter.rs
│       │   ├── handshake.rs
│       │   ├── handshake_test.rs
│       │   ├── macros.rs
│       │   ├── mod.rs
│       │   └── server_hello.rs
│       ├── quic.rs
│       ├── server/
│       │   ├── config.rs
│       │   ├── connection.rs
│       │   ├── handy.rs
│       │   ├── hs.rs
│       │   ├── mod.rs
│       │   ├── test.rs
│       │   ├── tls12.rs
│       │   └── tls13.rs
│       ├── suites.rs
│       ├── testdata/
│       │   ├── eddsakey.der
│       │   ├── nistp256key.der
│       │   ├── nistp256key.pkcs8.der
│       │   ├── nistp384key.der
│       │   ├── nistp384key.pkcs8.der
│       │   ├── nistp521key.der
│       │   ├── nistp521key.pkcs8.der
│       │   ├── rsa2048key.pkcs1.der
│       │   ├── rsa2048key.pkcs8.der
│       │   └── rsa4096key.pkcs8.der
│       ├── ticketer.rs
│       ├── time_provider.rs
│       ├── tls12.rs
│       ├── tls13/
│       │   ├── key_schedule.rs
│       │   └── mod.rs
│       ├── vecbuf.rs
│       ├── verify.rs
│       ├── versions.rs
│       ├── webpki/
│       │   ├── anchors.rs
│       │   ├── client_verifier.rs
│       │   ├── mod.rs
│       │   ├── server_verifier.rs
│       │   └── verify.rs
│       └── x509.rs
├── rustls-aws-lc-rs/
│   ├── Cargo.toml
│   └── src/
│       ├── data/
│       │   ├── alg-rsa-pkcs1-sha256-absent-params.der
│       │   ├── alg-rsa-pkcs1-sha384-absent-params.der
│       │   └── alg-rsa-pkcs1-sha512-absent-params.der
│       ├── hash.rs
│       ├── hmac.rs
│       ├── hpke.rs
│       ├── kx.rs
│       ├── lib.rs
│       ├── quic.rs
│       ├── sign.rs
│       ├── ticketer.rs
│       ├── tls12.rs
│       ├── tls13.rs
│       └── verify.rs
├── rustls-bench/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
├── rustls-fuzzing-provider/
│   ├── Cargo.toml
│   ├── src/
│   │   └── lib.rs
│   └── tests/
│       └── smoke.rs
├── rustls-post-quantum/
│   ├── Cargo.toml
│   ├── README.md
│   ├── README.tpl
│   ├── benches/
│   │   └── benchmarks.rs
│   ├── examples/
│   │   └── client.rs
│   └── src/
│       └── lib.rs
├── rustls-provider-test/
│   ├── Cargo.toml
│   ├── README.md
│   └── tests/
│       ├── hpke.rs
│       └── rfc-9180-test-vectors.json
├── rustls-ring/
│   ├── Cargo.toml
│   ├── benches/
│   │   └── benchmarks.rs
│   └── src/
│       ├── data/
│       │   ├── alg-rsa-pkcs1-sha256-absent-params.der
│       │   ├── alg-rsa-pkcs1-sha384-absent-params.der
│       │   └── alg-rsa-pkcs1-sha512-absent-params.der
│       ├── hash.rs
│       ├── hmac.rs
│       ├── kx.rs
│       ├── lib.rs
│       ├── quic.rs
│       ├── sign.rs
│       ├── ticketer.rs
│       ├── tls12.rs
│       ├── tls13.rs
│       └── verify.rs
├── rustls-test/
│   ├── Cargo.toml
│   ├── benches/
│   │   ├── data/
│   │   │   ├── cert-arstechnica.0.der
│   │   │   ├── cert-arstechnica.1.der
│   │   │   ├── cert-arstechnica.2.der
│   │   │   ├── cert-duckduckgo.0.der
│   │   │   ├── cert-duckduckgo.1.der
│   │   │   ├── cert-duckduckgo.2.der
│   │   │   ├── cert-github.0.der
│   │   │   ├── cert-github.1.der
│   │   │   ├── cert-github.2.der
│   │   │   ├── cert-google.0.der
│   │   │   ├── cert-google.1.der
│   │   │   ├── cert-google.2.der
│   │   │   ├── cert-hn.0.der
│   │   │   ├── cert-hn.1.der
│   │   │   ├── cert-reddit.0.der
│   │   │   ├── cert-reddit.1.der
│   │   │   ├── cert-rustlang.0.der
│   │   │   ├── cert-rustlang.1.der
│   │   │   ├── cert-servo.0.der
│   │   │   ├── cert-servo.1.der
│   │   │   ├── cert-servo.2.der
│   │   │   ├── cert-stackoverflow.0.der
│   │   │   ├── cert-stackoverflow.1.der
│   │   │   ├── cert-twitter.0.der
│   │   │   ├── cert-twitter.1.der
│   │   │   ├── cert-wapo.0.der
│   │   │   ├── cert-wapo.1.der
│   │   │   ├── cert-wapo.2.der
│   │   │   ├── cert-wikipedia.0.der
│   │   │   └── cert-wikipedia.1.der
│   │   └── verifybench.rs
│   ├── src/
│   │   └── lib.rs
│   └── tests/
│       ├── api/
│       │   ├── api.rs
│       │   ├── client_cert_verifier.rs
│       │   ├── compress.rs
│       │   ├── crypto.rs
│       │   ├── ffdhe.rs
│       │   ├── io.rs
│       │   ├── kx.rs
│       │   ├── quic.rs
│       │   ├── raw_keys.rs
│       │   ├── resolve.rs
│       │   ├── resume.rs
│       │   └── server_cert_verifier.rs
│       ├── api.rs
│       ├── bogo.rs
│       ├── key_log_file_env/
│       │   └── tests.rs
│       ├── key_log_file_env.rs
│       └── process_provider.rs
├── rustls-util/
│   ├── Cargo.toml
│   └── src/
│       ├── key_log_file.rs
│       ├── lib.rs
│       └── stream.rs
├── test-ca/
│   ├── README.md
│   ├── ecdsa-p256/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── ecdsa-p384/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── ecdsa-p521/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── eddsa/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── rsa-2048/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   ├── rsa-3072/
│   │   ├── ca.cert
│   │   ├── ca.der
│   │   ├── ca.key
│   │   ├── client.cert
│   │   ├── client.chain
│   │   ├── client.der
│   │   ├── client.expired.crl.pem
│   │   ├── client.fullchain
│   │   ├── client.key
│   │   ├── client.revoked.crl.pem
│   │   ├── client.spki.pem
│   │   ├── end.cert
│   │   ├── end.chain
│   │   ├── end.der
│   │   ├── end.expired.crl.pem
│   │   ├── end.fullchain
│   │   ├── end.key
│   │   ├── end.revoked.crl.pem
│   │   ├── end.spki.pem
│   │   ├── inter.cert
│   │   ├── inter.der
│   │   ├── inter.expired.crl.pem
│   │   ├── inter.key
│   │   └── inter.revoked.crl.pem
│   └── rsa-4096/
│       ├── ca.cert
│       ├── ca.der
│       ├── ca.key
│       ├── client.cert
│       ├── client.chain
│       ├── client.der
│       ├── client.expired.crl.pem
│       ├── client.fullchain
│       ├── client.key
│       ├── client.revoked.crl.pem
│       ├── client.spki.pem
│       ├── end.cert
│       ├── end.chain
│       ├── end.der
│       ├── end.expired.crl.pem
│       ├── end.fullchain
│       ├── end.key
│       ├── end.revoked.crl.pem
│       ├── end.spki.pem
│       ├── inter.cert
│       ├── inter.der
│       ├── inter.expired.crl.pem
│       ├── inter.key
│       └── inter.revoked.crl.pem
└── website/
    ├── README.md
    ├── config.toml
    ├── content/
    │   ├── blog/
    │   │   ├── 2025-09-03-rustls-and-rust-foundation.md
    │   │   └── _index.md
    │   ├── perf/
    │   │   ├── 2024-10-18-report.md
    │   │   ├── 2024-10-31-arm64.md
    │   │   ├── 2024-11-28-threading/
    │   │   │   └── index.md
    │   │   ├── 2024-12-17-pq-kx/
    │   │   │   └── index.md
    │   │   ├── 2025-07-31-report.md
    │   │   ├── 2026-03-07-report.md
    │   │   └── _index.md
    │   └── release/
    │       └── _index.md
    ├── static/
    │   └── style.css
    └── templates/
        ├── base.html
        ├── index.html
        ├── macros.html
        ├── pages.html
        ├── report-page.html
        └── reports.html
Download .txt
Showing preview only (375K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4417 symbols across 163 files)

FILE: admin/threads-seq.rs
  function main (line 22) | fn main() -> Result<(), Box<dyn error::Error + Send + Sync + 'static>> {

FILE: ci-bench/src/benchmark.rs
  function get_reported_instr_count (line 13) | pub(crate) fn get_reported_instr_count(
  type BenchmarkKind (line 22) | pub(crate) enum BenchmarkKind {
    method resumption_kind (line 31) | pub(crate) fn resumption_kind(self) -> ResumptionKind {
  type ResumptionKind (line 41) | pub(crate) enum ResumptionKind {
    constant ALL (line 51) | pub(crate) const ALL: &'static [Self] = &[Self::No, Self::SessionId, S...
    method label (line 54) | pub(crate) fn label(&self) -> &'static str {
  type BenchmarkParams (line 65) | pub(crate) struct BenchmarkParams {
    method new (line 82) | pub(crate) const fn new(
  type AuthKeySource (line 100) | pub(crate) enum AuthKeySource {
  type Benchmark (line 106) | pub(crate) struct Benchmark {
    method new (line 117) | pub(crate) fn new(name: String, kind: BenchmarkKind, params: Benchmark...
    method name (line 122) | pub(crate) fn name(&self) -> &str {
    method name_with_side (line 127) | pub(crate) fn name_with_side(&self, side: Side) -> String {
    method borrow (line 133) | fn borrow(&self) -> &str {
  method eq (line 139) | fn eq(&self, other: &Self) -> bool {
  method partial_cmp (line 147) | fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
  method cmp (line 153) | fn cmp(&self, other: &Self) -> cmp::Ordering {

FILE: ci-bench/src/main.rs
  constant TRANSFER_PLAINTEXT_SIZE (line 44) | const TRANSFER_PLAINTEXT_SIZE: usize = 1024 * 1024 * 10;
  constant RESUMED_HANDSHAKE_RUNS (line 58) | const RESUMED_HANDSHAKE_RUNS: usize = 30;
  constant ICOUNTS_FILENAME (line 61) | const ICOUNTS_FILENAME: &str = "icounts.csv";
  constant MEMORY_FILENAME (line 64) | const MEMORY_FILENAME: &str = "memory.csv";
  constant DEFAULT_BUFFER_SIZE (line 67) | const DEFAULT_BUFFER_SIZE: usize = 262144;
  type Cli (line 71) | pub struct Cli {
  type Command (line 77) | pub enum Command {
  type CompareMemoryOperand (line 119) | pub enum CompareMemoryOperand {
    method choose (line 128) | fn choose(&self, memory: MemoryDetails) -> u64 {
  type Side (line 139) | pub enum Side {
    method as_str (line 152) | pub fn as_str(self) -> &'static str {
  type Mode (line 145) | pub enum Mode {
  function main (line 160) | fn main() -> anyhow::Result<()> {
  function output_csv (line 372) | fn output_csv(
  function all_benchmarks (line 400) | fn all_benchmarks() -> anyhow::Result<BTreeSet<Benchmark>> {
  function all_benchmarks_params (line 410) | fn all_benchmarks_params() -> Vec<BenchmarkParams> {
  function ring_ticketer (line 496) | fn ring_ticketer() -> Arc<dyn TicketProducer> {
  function aws_lc_rs_ticketer (line 503) | fn aws_lc_rs_ticketer() -> Arc<dyn TicketProducer> {
  function select_suite (line 510) | fn select_suite(mut provider: CryptoProvider, name: CipherSuite) -> Arc<...
  function derandomize (line 522) | fn derandomize(base: CryptoProvider) -> CryptoProvider {
  function warm_up_aws_lc_rs (line 529) | fn warm_up_aws_lc_rs() {
  type NotRandom (line 540) | struct NotRandom;
  method fill (line 543) | fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
  function add_benchmark_group (line 557) | fn add_benchmark_group(benchmarks: &mut BTreeSet<Benchmark>, params: Ben...
  function run_all (line 583) | fn run_all(
  type CombinedMeasurement (line 659) | pub struct CombinedMeasurement {
  type BenchStepper (line 668) | trait BenchStepper {
    method handshake (line 671) | async fn handshake(&mut self) -> anyhow::Result<Self::Endpoint>;
    method sync_before_resumed_handshake (line 672) | async fn sync_before_resumed_handshake(&mut self) -> anyhow::Result<()>;
    method transmit_data (line 673) | async fn transmit_data(&mut self, endpoint: &mut Self::Endpoint) -> an...
    method handshake_kind (line 674) | fn handshake_kind(&self, endpoint: &Self::Endpoint) -> HandshakeKind;
    type Endpoint (line 726) | type Endpoint = ClientConnection;
    method handshake (line 728) | async fn handshake(&mut self) -> anyhow::Result<Self::Endpoint> {
    method sync_before_resumed_handshake (line 756) | async fn sync_before_resumed_handshake(&mut self) -> anyhow::Result<()> {
    method transmit_data (line 765) | async fn transmit_data(&mut self, endpoint: &mut Self::Endpoint) -> an...
    method handshake_kind (line 771) | fn handshake_kind(&self, endpoint: &Self::Endpoint) -> HandshakeKind {
    type Endpoint (line 812) | type Endpoint = ServerConnection;
    method handshake (line 814) | async fn handshake(&mut self) -> anyhow::Result<Self::Endpoint> {
    method sync_before_resumed_handshake (line 826) | async fn sync_before_resumed_handshake(&mut self) -> anyhow::Result<()> {
    method transmit_data (line 833) | async fn transmit_data(&mut self, endpoint: &mut Self::Endpoint) -> an...
    method handshake_kind (line 838) | fn handshake_kind(&self, endpoint: &Self::Endpoint) -> HandshakeKind {
  type StepperIo (line 678) | struct StepperIo<'a> {
  type ClientSideStepper (line 685) | struct ClientSideStepper<'a> {
  function make_config (line 692) | fn make_config(params: &BenchmarkParams, resume: ResumptionKind) -> Arc<...
  type ServerSideStepper (line 777) | struct ServerSideStepper<'a> {
  function make_config (line 783) | fn make_config(params: &BenchmarkParams, resume: ResumptionKind) -> Arc<...
  function run_bench (line 844) | async fn run_bench<T: BenchStepper>(
  type CompareResult (line 887) | struct CompareResult {
  type MemoryCompareResult (line 897) | struct MemoryCompareResult {
  type Diff (line 905) | struct Diff {
  type MemoryDiff (line 915) | struct MemoryDiff {
  function read_icount_results (line 925) | fn read_icount_results(path: &Path) -> anyhow::Result<HashMap<String, u6...
  function read_memory_results (line 953) | fn read_memory_results(path: &Path) -> anyhow::Result<HashMap<String, Me...
  function compare_icount_results (line 999) | fn compare_icount_results(
  function compare_memory_results (line 1048) | fn compare_memory_results(
  function print_icount_report (line 1093) | fn print_icount_report(result: &CompareResult) {
  function print_memory_report (line 1131) | fn print_memory_report(result: &MemoryCompareResult) {
  function table (line 1155) | fn table<'a>(diffs: impl Iterator<Item = &'a Diff>, emoji_feedback: bool) {
  function memory_table (line 1178) | fn memory_table(diffs: &[MemoryDiff], emoji_feedback: bool) {

FILE: ci-bench/src/util.rs
  function block_on_single_poll (line 25) | pub(crate) fn block_on_single_poll(
  function block_on_concurrent (line 48) | pub(crate) fn block_on_concurrent(
  function noop_waker (line 96) | fn noop_waker() -> Waker {
  type AsyncRead (line 104) | pub(crate) trait AsyncRead {
    method read (line 105) | async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>;
    method read_exact (line 106) | async fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()>;
    method read (line 119) | async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
    method read_exact (line 123) | async fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
    method read (line 181) | async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
    method read_exact (line 189) | async fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
  type AsyncWrite (line 111) | pub(crate) trait AsyncWrite {
    method write_all (line 112) | async fn write_all(&mut self, buf: &[u8]) -> io::Result<()>;
    method flush (line 113) | async fn flush(&mut self) -> io::Result<()>;
    method write_all (line 131) | async fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
    method flush (line 135) | async fn flush(&mut self) -> io::Result<()> {
    method write_all (line 201) | async fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
    method flush (line 209) | async fn flush(&mut self) -> io::Result<()> {
  function async_pipe (line 142) | pub(crate) fn async_pipe(capacity: usize) -> (AsyncSender, AsyncReceiver) {
  type AsyncSender (line 159) | pub(crate) struct AsyncSender {
  type AsyncReceiver (line 164) | pub(crate) struct AsyncReceiver {
  type AsyncPipeSide (line 168) | struct AsyncPipeSide {
  method drop (line 174) | fn drop(&mut self) {
  type AsyncPipeReadFuture (line 214) | struct AsyncPipeReadFuture<'a> {
  type Output (line 220) | type Output = io::Result<usize>;
  method poll (line 222) | fn poll(mut self: Pin<&mut Self>, _: &mut task::Context<'_>) -> Poll<Sel...
  type AsyncPipeWriteFuture (line 253) | struct AsyncPipeWriteFuture<'a> {
  type Output (line 259) | type Output = io::Result<()>;
  method poll (line 261) | fn poll(mut self: Pin<&mut Self>, _: &mut task::Context<'_>) -> Poll<Sel...
  function test_block_on_concurrent_minimal_capacity (line 287) | fn test_block_on_concurrent_minimal_capacity() {
  function test_block_on_concurrent_enough_capacity (line 292) | fn test_block_on_concurrent_enough_capacity() {
  function test_block_on_concurrent (line 296) | fn test_block_on_concurrent(capacity: usize) {
  function send_handshake_message (line 379) | pub(crate) async fn send_handshake_message(
  function read_handshake_message (line 417) | pub(crate) async fn read_handshake_message(
  function read_plaintext_to_end_bounded (line 453) | pub(crate) async fn read_plaintext_to_end_bounded(
  function write_all_plaintext_bounded (line 505) | pub(crate) async fn write_all_plaintext_bounded(

FILE: ci-bench/src/valgrind.rs
  type CallgrindRunner (line 13) | pub(crate) struct CallgrindRunner {
    method new (line 24) | pub(crate) fn new(executable: String, output_dir: PathBuf) -> anyhow::...
    method run_bench (line 38) | pub(crate) fn run_bench(&self, bench: &Benchmark) -> anyhow::Result<In...
    method run_bench_side (line 71) | fn run_bench_side(
  type DhatRunner (line 117) | pub(crate) struct DhatRunner {
    method new (line 128) | pub(crate) fn new(executable: String, output_dir: PathBuf) -> anyhow::...
    method run_bench (line 141) | pub(crate) fn run_bench(&self, bench: &Benchmark) -> anyhow::Result<Me...
    method run_bench_side (line 174) | fn run_bench_side(
  constant CALLGRIND_OUTPUT_SUBDIR (line 215) | const CALLGRIND_OUTPUT_SUBDIR: &str = "callgrind";
  function ensure_valgrind_tool_available (line 218) | fn ensure_valgrind_tool_available(tool: &str) -> anyhow::Result<()> {
  type BenchSubprocess (line 245) | struct BenchSubprocess {
    method wait_and_get_instr_count (line 259) | fn wait_and_get_instr_count(mut self) -> anyhow::Result<u64> {
    method wait_and_get_memory_details (line 279) | fn wait_and_get_memory_details(mut self) -> anyhow::Result<MemoryDetai...
  type ValgrindOutput (line 252) | enum ValgrindOutput {
  function parse_callgrind_output (line 300) | fn parse_callgrind_output(file: &Path) -> anyhow::Result<u64> {
  type InstructionCounts (line 320) | pub(crate) struct InstructionCounts {
  type Output (line 326) | type Output = Self;
  method sub (line 328) | fn sub(self, rhs: Self) -> Self::Output {
  type MemoryProfile (line 338) | pub(crate) struct MemoryProfile {
  type MemoryDetails (line 344) | pub(crate) struct MemoryDetails {
    method from_file (line 353) | fn from_file(file: &Path) -> anyhow::Result<Self> {
  function callgrind_diff (line 396) | pub(crate) fn callgrind_diff(
  type CountInstructions (line 462) | pub(crate) struct CountInstructions;
    method start (line 465) | pub(crate) fn start() -> Self {
  method drop (line 473) | fn drop(&mut self) {

FILE: connect-tests/tests/badssl.rs
  function connect (line 10) | fn connect(hostname: &str) -> TlsClient {
  function no_cbc (line 15) | fn no_cbc() {
  function no_rc4 (line 26) | fn no_rc4() {
  function expired (line 37) | fn expired() {
  function wrong_host (line 46) | fn wrong_host() {
  function self_signed (line 55) | fn self_signed() {
  function no_dh (line 64) | fn no_dh() {
  function mozilla_old (line 75) | fn mozilla_old() {
  function mozilla_inter (line 83) | fn mozilla_inter() {
  function mozilla_modern (line 91) | fn mozilla_modern() {
  function sha256 (line 99) | fn sha256() {
  function too_many_sans (line 107) | fn too_many_sans() {
  function rsa8192 (line 117) | fn rsa8192() {
  function sha1_2016 (line 125) | fn sha1_2016() {
  function self_signed (line 135) | fn self_signed() {

FILE: connect-tests/tests/common/mod.rs
  function tlsserver_find (line 6) | pub(super) fn tlsserver_find() -> &'static str {
  function tlsclient_find (line 10) | pub(super) fn tlsclient_find() -> &'static str {
  type TlsClient (line 14) | pub(super) struct TlsClient {
    method new (line 31) | pub(super) fn new(hostname: &str) -> Self {
    method cafile (line 49) | pub(super) fn cafile(&mut self, cafile: &Path) -> &mut Self {
    method cache (line 54) | pub(super) fn cache(&mut self, cache: &str) -> &mut Self {
    method no_sni (line 59) | pub(super) fn no_sni(&mut self) -> &mut Self {
    method insecure (line 64) | pub(super) fn insecure(&mut self) -> &mut Self {
    method verbose (line 69) | pub(super) fn verbose(&mut self) -> &mut Self {
    method max_fragment_size (line 74) | pub(super) fn max_fragment_size(&mut self, max_fragment_size: usize) -...
    method port (line 79) | pub(super) fn port(&mut self, port: u16) -> &mut Self {
    method expect (line 84) | pub(super) fn expect(&mut self, expect: &str) -> &mut Self {
    method expect_log (line 90) | pub(super) fn expect_log(&mut self, expect: &str) -> &mut Self {
    method suite (line 96) | pub(super) fn suite(&mut self, suite: &str) -> &mut Self {
    method fails (line 101) | pub(super) fn fails(&mut self) -> &mut Self {
    method go (line 106) | pub(super) fn go(&self) -> Option<()> {

FILE: connect-tests/tests/topsites.rs
  function check (line 12) | fn check(hostname: &str) {
  function joe (line 20) | fn joe() {
  function google (line 25) | fn google() {
  function github (line 30) | fn github() {
  function aws (line 35) | fn aws() {
  function microsoft (line 40) | fn microsoft() {
  function wikipedia (line 45) | fn wikipedia() {
  function twitter (line 50) | fn twitter() {
  function facebook (line 55) | fn facebook() {
  function baidu (line 60) | fn baidu() {
  function netflix (line 65) | fn netflix() {
  function stackoverflow (line 70) | fn stackoverflow() {
  function apple (line 75) | fn apple() {
  function cloudflare_1_1_1_1_dns (line 80) | fn cloudflare_1_1_1_1_dns() {

FILE: examples/src/bin/ech-client.rs
  function main (line 53) | async fn main() -> Result<(), Box<dyn Error>> {
  type Args (line 175) | struct Args {
  function lookup_ech_configs (line 229) | async fn lookup_ech_configs(
  function read_ech (line 266) | fn read_ech(path: &str) -> Result<EchConfigListBytes<'static>, Box<dyn E...

FILE: examples/src/bin/limitedclient.rs
  function main (line 15) | fn main() {
  constant PROVIDER (line 62) | const PROVIDER: CryptoProvider = CryptoProvider {

FILE: examples/src/bin/server_acceptor.rs
  function main (line 24) | fn main() {
  type TestPki (line 115) | struct TestPki {
    method new (line 125) | fn new() -> Self {
    method server_config (line 199) | fn server_config(&self, crl_path: &str, _hello: ClientHello<'_>) -> Ar...
    method crl (line 240) | fn crl(
  type CrlUpdater (line 281) | struct CrlUpdater {
    method run (line 288) | fn run(self) {
  type Args (line 329) | struct Args {

FILE: examples/src/bin/simple_0rtt_client.rs
  function start_connection (line 28) | fn start_connection(config: &Arc<ClientConfig>, domain_name: &str, port:...
  function main (line 79) | fn main() {

FILE: examples/src/bin/simple_0rtt_server.rs
  function main (line 28) | fn main() -> Result<(), Box<dyn StdError>> {

FILE: examples/src/bin/simpleclient.rs
  function main (line 18) | fn main() {

FILE: examples/src/bin/simpleserver.rs
  function main (line 23) | fn main() -> Result<(), Box<dyn StdError>> {

FILE: examples/src/bin/tlsclient-mio.rs
  constant CLIENT (line 40) | const CLIENT: mio::Token = mio::Token(0);
  type TlsClient (line 44) | struct TlsClient {
    method new (line 52) | fn new(sock: TcpStream, server_name: ServerName<'static>, cfg: Arc<Cli...
    method ready (line 65) | fn ready(&mut self, ev: &mio::event::Event) {
    method read_source_to_end (line 82) | fn read_source_to_end(&mut self, rd: &mut dyn Read) -> io::Result<usiz...
    method do_read (line 93) | fn do_read(&mut self) {
    method do_write (line 152) | fn do_write(&mut self) {
    method register (line 159) | fn register(&mut self, registry: &mio::Registry) {
    method reregister (line 167) | fn reregister(&mut self, registry: &mio::Registry) {
    method event_set (line 176) | fn event_set(&self) -> mio::Interest {
    method is_closed (line 189) | fn is_closed(&self) -> bool {
  method write (line 194) | fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
  method flush (line 198) | fn flush(&mut self) -> io::Result<()> {
  method read (line 204) | fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> {
  type Args (line 217) | struct Args {
    method provider (line 283) | fn provider(&self) -> CryptoProvider {
  function find_key_exchange (line 313) | fn find_key_exchange(name: &str) -> &'static dyn SupportedKxGroup {
  function filter_suites (line 326) | fn filter_suites(mut provider: CryptoProvider, suites: &[String]) -> Cry...
  function lookup_versions (line 374) | fn lookup_versions(versions: &[String]) -> Vec<ProtocolVersion> {
  function load_certs (line 391) | fn load_certs(filename: &str) -> Vec<CertificateDer<'static>> {
  function load_private_key (line 398) | fn load_private_key(filename: &str) -> PrivateKeyDer<'static> {
  type NoCertificateVerification (line 417) | pub(super) struct NoCertificateVerification(CryptoProvider);
    method new (line 420) | pub(super) fn new(provider: CryptoProvider) -> Self {
  method verify_identity (line 426) | fn verify_identity(&self, _identity: &ServerIdentity<'_>) -> Result<Peer...
  method verify_tls12_signature (line 430) | fn verify_tls12_signature(
  method verify_tls13_signature (line 437) | fn verify_tls13_signature(
  method supported_verify_schemes (line 444) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method request_ocsp_response (line 450) | fn request_ocsp_response(&self) -> bool {
  method hash_config (line 454) | fn hash_config(&self, _: &mut dyn Hasher) {}
  method supported_certificate_types (line 456) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  method root_hint_subjects (line 460) | fn root_hint_subjects(&self) -> Option<Arc<[DistinguishedName]>> {
  function make_config (line 467) | fn make_config(args: &Args) -> Arc<ClientConfig> {
  function main (line 532) | fn main() {

FILE: examples/src/bin/tlsserver-mio.rs
  constant LISTENER (line 41) | const LISTENER: mio::Token = mio::Token(0);
  type ServerMode (line 45) | enum ServerMode {
  type TlsServer (line 59) | struct TlsServer {
    method new (line 68) | fn new(server: TcpListener, mode: ServerMode, cfg: Arc<ServerConfig>) ...
    method accept (line 78) | fn accept(&mut self, registry: &mio::Registry) -> Result<(), io::Error> {
    method conn_event (line 104) | fn conn_event(&mut self, registry: &mio::Registry, event: &mio::event:...
  type OpenConnection (line 125) | struct OpenConnection {
    method new (line 164) | fn new(
    method ready (line 184) | fn ready(&mut self, registry: &mio::Registry, ev: &mio::event::Event) {
    method close_back (line 211) | fn close_back(&mut self) {
    method do_tls_read (line 218) | fn do_tls_read(&mut self) {
    method try_plain_read (line 249) | fn try_plain_read(&mut self) {
    method try_back_read (line 279) | fn try_back_read(&mut self) {
    method incoming_plaintext (line 315) | fn incoming_plaintext(&mut self, buf: &[u8]) {
    method send_http_response_once (line 336) | fn send_http_response_once(&mut self) {
    method tls_write (line 349) | fn tls_write(&mut self) -> io::Result<usize> {
    method do_tls_write_and_handle_error (line 354) | fn do_tls_write_and_handle_error(&mut self) {
    method register (line 362) | fn register(&mut self, registry: &mio::Registry) {
    method reregister (line 375) | fn reregister(&mut self, registry: &mio::Registry) {
    method deregister (line 382) | fn deregister(&mut self, registry: &mio::Registry) {
    method event_set (line 394) | fn event_set(&self) -> mio::Interest {
    method is_closed (line 407) | fn is_closed(&self) -> bool {
  function open_back (line 137) | fn open_back(mode: &ServerMode) -> Option<TcpStream> {
  function try_read (line 150) | fn try_read(r: io::Result<usize>) -> io::Result<Option<usize>> {
  type Args (line 422) | struct Args {
    method provider (line 474) | fn provider(&self) -> (Vec<ProtocolVersion>, CryptoProvider) {
  function filter_suites (line 498) | fn filter_suites(mut provider: CryptoProvider, suites: &[String]) -> Cry...
  function lookup_versions (line 546) | fn lookup_versions(versions: &[String]) -> Vec<ProtocolVersion> {
  function load_certs (line 563) | fn load_certs(filename: &Path) -> Vec<CertificateDer<'static>> {
  function load_private_key (line 570) | fn load_private_key(filename: &Path) -> PrivateKeyDer<'static> {
  function load_ocsp (line 574) | fn load_ocsp(filename: Option<&Path>) -> Vec<u8> {
  function load_crls (line 587) | fn load_crls(
  function make_config (line 597) | fn make_config(args: &Args) -> Arc<ServerConfig> {
  function main (line 676) | fn main() {

FILE: examples/tests/limitedclient.rs
  function limited_no_aes_symbols (line 14) | fn limited_no_aes_symbols() {
  function limited_no_tls12_symbols (line 31) | fn limited_no_tls12_symbols() {
  function tls12 (line 43) | fn tls12(sym: &str) -> bool {
  function find_symbols_in_executable (line 54) | fn find_symbols_in_executable(f: impl Fn(&str) -> bool, exe: &str) -> Ve...

FILE: fuzz/fuzzers/server.rs
  function fuzz_buffered_api (line 21) | fn fuzz_buffered_api(data: &[u8]) {
  function fuzz_acceptor_api (line 34) | fn fuzz_acceptor_api(data: &[u8]) {
  function fuzz_accepted (line 59) | fn fuzz_accepted(stream: &mut dyn io::Read, accepted: Accepted) {
  function service_connection (line 72) | fn service_connection(stream: &mut dyn io::Read, server: &mut ServerConn...

FILE: openssl-tests/src/early_exporter.rs
  function test_early_exporter (line 17) | fn test_early_exporter() {
  function load_certs (line 138) | fn load_certs() -> Vec<CertificateDer<'static>> {
  function load_private_key (line 145) | fn load_private_key() -> PrivateKeyDer<'static> {
  constant CERT_CHAIN_FILE (line 149) | const CERT_CHAIN_FILE: &str = "../test-ca/rsa-2048/end.fullchain";
  constant PRIV_KEY_FILE (line 150) | const PRIV_KEY_FILE: &str = "../test-ca/rsa-2048/end.key";
  constant CA_PEM_FILE (line 151) | const CA_PEM_FILE: &str = "../test-ca/rsa-2048/ca.cert";

FILE: openssl-tests/src/ffdhe.rs
  constant FFDHE2048_GROUP (line 11) | pub(crate) const FFDHE2048_GROUP: &dyn SupportedKxGroup =
  type FfdheKxGroup (line 15) | pub(crate) struct FfdheKxGroup(pub NamedGroup, pub FfdheGroup<'static>);
  method start (line 18) | fn start(&self) -> Result<StartedKeyExchange, rustls::Error> {
  method ffdhe_group (line 41) | fn ffdhe_group(&self) -> Option<FfdheGroup<'static>> {
  method name (line 45) | fn name(&self) -> NamedGroup {
  type ActiveFfdheKx (line 59) | struct ActiveFfdheKx {
  method complete (line 68) | fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret...
  method pub_key (line 76) | fn pub_key(&self) -> &[u8] {
  method ffdhe_group (line 80) | fn ffdhe_group(&self) -> Option<FfdheGroup<'static>> {
  method group (line 84) | fn group(&self) -> NamedGroup {
  function to_bytes_be_with_len (line 89) | fn to_bytes_be_with_len(n: BigUint, len_bytes: usize) -> Vec<u8> {

FILE: openssl-tests/src/ffdhe_kx_with_openssl.rs
  function rustls_server_with_ffdhe_kx_tls13 (line 19) | fn rustls_server_with_ffdhe_kx_tls13() {
  function rustls_server_with_ffdhe_kx_tls12 (line 24) | fn rustls_server_with_ffdhe_kx_tls12() {
  function test_rustls_server_with_ffdhe_kx (line 28) | fn test_rustls_server_with_ffdhe_kx(provider: CryptoProvider, iters: usi...
  function rustls_client_with_ffdhe_kx (line 76) | fn rustls_client_with_ffdhe_kx() {
  function test_rustls_client_with_ffdhe_kx (line 80) | fn test_rustls_client_with_ffdhe_kx(iters: usize) {
  function rustls_client_with_ffdhe_kx_repeated (line 161) | fn rustls_client_with_ffdhe_kx_repeated() {
  function rustls_server_with_ffdhe_tls13_repeated (line 167) | fn rustls_server_with_ffdhe_tls13_repeated() {
  function rustls_server_with_ffdhe_tls12_repeated (line 173) | fn rustls_server_with_ffdhe_tls12_repeated() {
  function root_ca (line 177) | fn root_ca() -> RootCertStore {
  function load_certs (line 183) | fn load_certs() -> Vec<CertificateDer<'static>> {
  function load_private_key (line 190) | fn load_private_key() -> PrivateKeyDer<'static> {
  constant FFDHE_PROVIDER (line 194) | const FFDHE_PROVIDER: CryptoProvider = CryptoProvider {
  constant FFDHE_TLS12_PROVIDER (line 201) | const FFDHE_TLS12_PROVIDER: CryptoProvider = CryptoProvider {
  constant FFDHE_TLS13_PROVIDER (line 206) | const FFDHE_TLS13_PROVIDER: CryptoProvider = CryptoProvider {
  function server_config_with_ffdhe_kx (line 211) | fn server_config_with_ffdhe_kx(provider: CryptoProvider) -> ServerConfig {
  constant CERT_CHAIN_FILE (line 221) | const CERT_CHAIN_FILE: &str = "../test-ca/rsa-2048/end.fullchain";
  constant PRIV_KEY_FILE (line 222) | const PRIV_KEY_FILE: &str = "../test-ca/rsa-2048/end.key";
  constant CA_FILE (line 223) | const CA_FILE: &str = "../test-ca/rsa-2048/ca.der";
  constant CA_PEM_FILE (line 224) | const CA_PEM_FILE: &str = "../test-ca/rsa-2048/ca.cert";

FILE: openssl-tests/src/raw_key_openssl_interop.rs
  function make_config (line 30) | pub(super) fn make_config(client_private_key: &str, server_pub_key: &str...
  function run_client (line 64) | pub(super) fn run_client(config: ClientConfig, port: u16) -> Result<Stri...
  type SimpleRpkServerVerifier (line 89) | struct SimpleRpkServerVerifier {
    method new (line 95) | fn new(trusted_spki: Vec<SubjectPublicKeyInfoDer<'static>>) -> Self {
  method verify_identity (line 104) | fn verify_identity(&self, identity: &ServerIdentity<'_>) -> Result<PeerV...
  method verify_tls12_signature (line 115) | fn verify_tls12_signature(
  method verify_tls13_signature (line 122) | fn verify_tls13_signature(
  method supported_verify_schemes (line 129) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method request_ocsp_response (line 133) | fn request_ocsp_response(&self) -> bool {
  method supported_certificate_types (line 137) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  method hash_config (line 141) | fn hash_config(&self, _: &mut dyn Hasher) {
  function make_config (line 169) | pub(super) fn make_config(server_private_key: &str, client_pub_key: &str...
  function run_server (line 204) | pub(super) fn run_server(
  type SimpleRpkClientVerifier (line 242) | struct SimpleRpkClientVerifier {
    method new (line 248) | pub(crate) fn new(trusted_spki: Vec<SubjectPublicKeyInfoDer<'static>>)...
  method verify_identity (line 257) | fn verify_identity(&self, identity: &ClientIdentity<'_>) -> Result<PeerV...
  method verify_tls12_signature (line 268) | fn verify_tls12_signature(
  method verify_tls13_signature (line 275) | fn verify_tls13_signature(
  method root_hint_subjects (line 282) | fn root_hint_subjects(&self) -> Arc<[DistinguishedName]> {
  method supported_verify_schemes (line 286) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method supported_certificate_types (line 290) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  constant SERVER_PRIV_KEY_FILE (line 313) | const SERVER_PRIV_KEY_FILE: &str = "../test-ca/ecdsa-p256/end.key";
  constant SERVER_PUB_KEY_FILE (line 314) | const SERVER_PUB_KEY_FILE: &str = "../test-ca/ecdsa-p256/end.spki.pem";
  constant SERVER_CERT_KEY_FILE (line 315) | const SERVER_CERT_KEY_FILE: &str = "../test-ca/ecdsa-p256/end.cert";
  constant CLIENT_PUB_KEY_FILE (line 316) | const CLIENT_PUB_KEY_FILE: &str = "../test-ca/ecdsa-p256/client.spki.pem";
  constant CLIENT_PRIV_KEY_FILE (line 317) | const CLIENT_PRIV_KEY_FILE: &str = "../test-ca/ecdsa-p256/client.key";
  constant CLIENT_CERT_KEY_FILE (line 318) | const CLIENT_CERT_KEY_FILE: &str = "../test-ca/ecdsa-p256/client.cert";
  function tcp_listener (line 320) | fn tcp_listener() -> TcpListener {
  function test_rust_server_and_rust_client (line 325) | fn test_rust_server_and_rust_client() {
  function test_rust_x509_server_with_openssl_raw_key_and_x509_client (line 367) | fn test_rust_x509_server_with_openssl_raw_key_and_x509_client() {
  function test_rust_server_with_openssl_client (line 420) | fn test_rust_server_with_openssl_client() {
  function process_openssl_client_interaction (line 462) | fn process_openssl_client_interaction(
  function test_rust_client_with_openssl_server (line 495) | fn test_rust_client_with_openssl_server() {

FILE: openssl-tests/src/utils.rs
  function verify_openssl3_available (line 3) | pub(crate) fn verify_openssl3_available() {
  function verify_openssl3_available_internal (line 9) | fn verify_openssl3_available_internal() {

FILE: openssl-tests/src/validate_ffdhe_params.rs
  function ffdhe_params_correct (line 10) | fn ffdhe_params_correct() {
  function test_ffdhe_params_correct (line 25) | fn test_ffdhe_params_correct(name: NamedGroup, group: FfdheGroup<'static...
  function get_ffdhe_params_from_openssl (line 33) | fn get_ffdhe_params_from_openssl(ffdhe_group: NamedGroup) -> (Vec<u8>, V...
  function parse_dh_params_pem (line 61) | fn parse_dh_params_pem(data: &[u8]) -> (Vec<u8>, Vec<u8>) {

FILE: provider-example/examples/client.rs
  function main (line 9) | fn main() {

FILE: provider-example/examples/server.rs
  function main (line 10) | fn main() {
  type TestPki (line 55) | struct TestPki {
    method new (line 61) | fn new() -> Self {
    method server_config (line 95) | fn server_config(self) -> Arc<ServerConfig> {

FILE: provider-example/src/aead.rs
  type Chacha20Poly1305 (line 13) | pub(crate) struct Chacha20Poly1305;
  method encrypter (line 16) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 23) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 30) | fn key_len(&self) -> usize {
  method extract_keys (line 34) | fn extract_keys(
  method encrypter (line 44) | fn encrypter(&self, key: AeadKey, iv: &[u8], _: &[u8]) -> Box<dyn Messag...
  method decrypter (line 51) | fn decrypter(&self, key: AeadKey, iv: &[u8]) -> Box<dyn MessageDecrypter> {
  method key_block_shape (line 58) | fn key_block_shape(&self) -> KeyBlockShape {
  method extract_keys (line 66) | fn extract_keys(
  type Tls13Cipher (line 81) | struct Tls13Cipher(chacha20poly1305::ChaCha20Poly1305, Iv);
  method encrypt (line 84) | fn encrypt(
  method encrypted_payload_len (line 107) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  method decrypt (line 113) | fn decrypt<'a>(
  type Tls12Cipher (line 130) | struct Tls12Cipher(chacha20poly1305::ChaCha20Poly1305, Iv);
  method encrypt (line 133) | fn encrypt(
  method encrypted_payload_len (line 155) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  method decrypt (line 161) | fn decrypt<'a>(
  constant CHACHAPOLY1305_OVERHEAD (line 184) | const CHACHAPOLY1305_OVERHEAD: usize = 16;
  type EncryptBufferAdapter (line 186) | struct EncryptBufferAdapter<'a>(&'a mut OutboundOpaque);
  function as_ref (line 189) | fn as_ref(&self) -> &[u8] {
  function as_mut (line 195) | fn as_mut(&mut self) -> &mut [u8] {
  method extend_from_slice (line 201) | fn extend_from_slice(&mut self, other: &[u8]) -> chacha20poly1305::aead:...
  method truncate (line 206) | fn truncate(&mut self, len: usize) {
  type DecryptBufferAdapter (line 211) | struct DecryptBufferAdapter<'a, 'p>(&'a mut InboundOpaque<'p>);
  function as_ref (line 214) | fn as_ref(&self) -> &[u8] {
  function as_mut (line 220) | fn as_mut(&mut self) -> &mut [u8] {
  method extend_from_slice (line 226) | fn extend_from_slice(&mut self, _: &[u8]) -> chacha20poly1305::aead::Res...
  method truncate (line 230) | fn truncate(&mut self, len: usize) {

FILE: provider-example/src/hash.rs
  type Sha256 (line 6) | pub(crate) struct Sha256;
    method start (line 9) | fn start(&self) -> Box<dyn hash::Context> {
    method hash (line 13) | fn hash(&self, data: &[u8]) -> hash::Output {
    method algorithm (line 17) | fn algorithm(&self) -> HashAlgorithm {
    method output_len (line 21) | fn output_len(&self) -> usize {
  type Sha256Context (line 26) | struct Sha256Context(sha2::Sha256);
    method fork_finish (line 29) | fn fork_finish(&self) -> hash::Output {
    method fork (line 33) | fn fork(&self) -> Box<dyn hash::Context> {
    method finish (line 37) | fn finish(self: Box<Self>) -> hash::Output {
    method update (line 41) | fn update(&mut self, data: &[u8]) {

FILE: provider-example/src/hmac.rs
  type Sha256Hmac (line 7) | pub(crate) struct Sha256Hmac;
    method with_key (line 10) | fn with_key(&self, key: &[u8]) -> Box<dyn crypto::hmac::Key> {
    method hash_output_len (line 14) | fn hash_output_len(&self) -> usize {
  type Sha256HmacKey (line 19) | struct Sha256HmacKey(Hmac<Sha256>);
    method sign_concat (line 22) | fn sign_concat(&self, first: &[u8], middle: &[&[u8]], last: &[u8]) -> ...
    method tag_len (line 32) | fn tag_len(&self) -> usize {

FILE: provider-example/src/hpke.rs
  type HpkeRs (line 80) | pub struct HpkeRs(HpkeSuite);
    method start (line 83) | fn start(&self) -> Result<hpke_rs::Hpke<HpkeRustCrypto>, Error> {
  method seal (line 94) | fn seal(
  method setup_sealer (line 109) | fn setup_sealer(
  method open (line 125) | fn open(
  method setup_opener (line 148) | fn setup_opener(
  method generate_key_pair (line 163) | fn generate_key_pair(&self) -> Result<(HpkePublicKey, HpkePrivateKey), E...
  method suite (line 180) | fn suite(&self) -> HpkeSuite {
  type HpkeRsSender (line 186) | struct HpkeRsSender {
  method seal (line 191) | fn seal(&mut self, aad: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, Erro...
  type HpkeRsReceiver (line 199) | struct HpkeRsReceiver {
  method open (line 204) | fn open(&mut self, aad: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, Err...
  function smoke_test (line 220) | fn smoke_test() {
  function test_fips (line 277) | fn test_fips() {

FILE: provider-example/src/kx.rs
  type KeyExchange (line 8) | pub(crate) struct KeyExchange {
  method complete (line 14) | fn complete(self: Box<Self>, peer: &[u8]) -> Result<SharedSecret, rustls...
  method pub_key (line 23) | fn pub_key(&self) -> &[u8] {
  method group (line 27) | fn group(&self) -> NamedGroup {
  constant ALL_KX_GROUPS (line 32) | pub(crate) const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[&X25519];
  type X25519 (line 35) | pub(crate) struct X25519;
  method start (line 38) | fn start(&self) -> Result<StartedKeyExchange, rustls::Error> {
  method name (line 46) | fn name(&self) -> NamedGroup {

FILE: provider-example/src/lib.rs
  function provider (line 46) | pub fn provider() -> CryptoProvider {
  type Provider (line 59) | struct Provider;
  method fill (line 62) | fn fill(&self, bytes: &mut [u8]) -> Result<(), GetRandomFailed> {
  method load_private_key (line 71) | fn load_private_key(
  method ticketer (line 88) | fn ticketer(&self) -> Result<Arc<dyn TicketProducer>, Error> {
  method fips (line 101) | fn fips(&self) -> FipsStatus {
  function other_err (line 141) | fn other_err(err: impl core::error::Error + Send + Sync + 'static) -> Er...
  function other_err (line 148) | fn other_err(error: impl fmt::Display + Send + Sync + 'static) -> Error {
  constant SIX_HOURS (line 169) | const SIX_HOURS: Duration = Duration::from_secs(6 * 60 * 60);

FILE: provider-example/src/sign.rs
  type EcdsaSigningKeyP256 (line 11) | pub(crate) struct EcdsaSigningKeyP256 {
    type Error (line 17) | type Error = pkcs8::Error;
    method try_from (line 19) | fn try_from(value: PrivatePkcs8KeyDer<'_>) -> Result<Self, Self::Error> {
  method choose_scheme (line 30) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn S...
  method public_key (line 38) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method sign (line 50) | fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, rustls::Erro...
  method scheme (line 57) | fn scheme(&self) -> SignatureScheme {

FILE: provider-example/src/ticketer.rs
  type AeadTicketer (line 19) | pub(super) struct AeadTicketer {
    method new (line 36) | pub(super) fn new() -> Result<Box<dyn TicketProducer>, Error> {
  method encrypt (line 55) | fn encrypt(&self, message: &[u8]) -> Option<Vec<u8>> {
  method decrypt (line 90) | fn decrypt(&self, ciphertext: &[u8]) -> Option<Vec<u8>> {
  method lifetime (line 128) | fn lifetime(&self) -> Duration {
  method fmt (line 136) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  function basic_pairwise_test (line 150) | fn basic_pairwise_test() {
  function refuses_decrypt_before_encrypt (line 158) | fn refuses_decrypt_before_encrypt() {
  function refuses_decrypt_larger_than_largest_encryption (line 164) | fn refuses_decrypt_larger_than_largest_encryption() {
  function aead_ticketer_is_debug_and_producestickets (line 177) | fn aead_ticketer_is_debug_and_producestickets() {

FILE: provider-example/src/verify.rs
  type RsaPssSha256Verify (line 24) | struct RsaPssSha256Verify;
  method public_key_alg_id (line 27) | fn public_key_alg_id(&self) -> AlgorithmIdentifier {
  method signature_alg_id (line 31) | fn signature_alg_id(&self) -> AlgorithmIdentifier {
  method verify_signature (line 35) | fn verify_signature(
  type RsaPkcs1Sha256Verify (line 52) | struct RsaPkcs1Sha256Verify;
  method public_key_alg_id (line 55) | fn public_key_alg_id(&self) -> AlgorithmIdentifier {
  method signature_alg_id (line 59) | fn signature_alg_id(&self) -> AlgorithmIdentifier {
  method verify_signature (line 63) | fn verify_signature(
  function decode_spki_spk (line 79) | fn decode_spki_spk(spki_spk: &[u8]) -> Result<RsaPublicKey, InvalidSigna...

FILE: rustls-aws-lc-rs/src/hash.rs
  type Hash (line 10) | pub(crate) struct Hash(&'static digest::Algorithm, HashAlgorithm);
    method start (line 13) | fn start(&self) -> Box<dyn crypto::hash::Context> {
    method hash (line 17) | fn hash(&self, bytes: &[u8]) -> crypto::hash::Output {
    method output_len (line 23) | fn output_len(&self) -> usize {
    method algorithm (line 27) | fn algorithm(&self) -> HashAlgorithm {
    method fips (line 31) | fn fips(&self) -> FipsStatus {
  type Context (line 36) | struct Context(digest::Context);
    method fork_finish (line 39) | fn fork_finish(&self) -> crypto::hash::Output {
    method fork (line 43) | fn fork(&self) -> Box<dyn crypto::hash::Context> {
    method finish (line 47) | fn finish(self: Box<Self>) -> crypto::hash::Output {
    method update (line 51) | fn update(&mut self, data: &[u8]) {
  function convert (line 56) | fn convert(val: digest::Digest) -> crypto::hash::Output {

FILE: rustls-aws-lc-rs/src/hmac.rs
  type Hmac (line 12) | pub(crate) struct Hmac(&'static hmac::Algorithm);
    method with_key (line 15) | fn with_key(&self, key: &[u8]) -> Box<dyn crypto::hmac::Key> {
    method hash_output_len (line 19) | fn hash_output_len(&self) -> usize {
    method fips (line 23) | fn fips(&self) -> FipsStatus {
  type Key (line 28) | struct Key(hmac::Key);
    method sign_concat (line 31) | fn sign_concat(&self, first: &[u8], middle: &[&[u8]], last: &[u8]) -> ...
    method tag_len (line 41) | fn tag_len(&self) -> usize {

FILE: rustls-aws-lc-rs/src/hpke.rs
  type HpkeAwsLcRs (line 247) | pub struct HpkeAwsLcRs<const KEY_SIZE: usize, const KDF_SIZE: usize> {
  function key_schedule (line 258) | fn key_schedule(
  function key_schedule_labeled_expand (line 296) | fn key_schedule_labeled_expand<const L: usize>(
  method seal (line 319) | fn seal(
  method setup_sealer (line 330) | fn setup_sealer(
  method open (line 339) | fn open(
  method setup_opener (line 351) | fn setup_opener(
  method fips (line 360) | fn fips(&self) -> FipsStatus {
  method generate_key_pair (line 382) | fn generate_key_pair(&self) -> Result<(HpkePublicKey, HpkePrivateKey), E...
  method suite (line 386) | fn suite(&self) -> HpkeSuite {
  method fmt (line 392) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type Sealer (line 398) | struct Sealer<const KEY_SIZE: usize, const KDF_SIZE: usize> {
  function new (line 406) | fn new(
  function test_only_new (line 424) | fn test_only_new(
  method seal (line 439) | fn seal(&mut self, aad: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, Erro...
  method fmt (line 459) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type Opener (line 466) | struct Opener<const KEY_SIZE: usize, const KDF_SIZE: usize> {
  function new (line 474) | fn new(
  method open (line 491) | fn open(&mut self, aad: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, Err...
  method fmt (line 513) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type DhKem (line 524) | struct DhKem<const KDF_SIZE: usize> {
  function encap (line 536) | fn encap(
  function test_only_encap (line 551) | fn test_only_encap(
  function encap_impl (line 562) | fn encap_impl(
  function decap (line 598) | fn decap(
  function extract_and_expand (line 635) | fn extract_and_expand(&self, dh: &[u8], kem_context: &[u8]) -> [u8; KDF_...
  function generate_p_curve_key_pair (line 686) | fn generate_p_curve_key_pair(
  function generate_x25519_key_pair (line 709) | fn generate_x25519_key_pair() -> Result<(HpkePublicKey, HpkePrivateKey),...
  function generate_key_pair (line 720) | fn generate_key_pair(
  type KeySchedule (line 736) | struct KeySchedule<const KEY_SIZE: usize> {
  function compute_nonce (line 747) | fn compute_nonce(&self) -> [u8; NONCE_LEN] {
  function increment_seq_num (line 769) | fn increment_seq_num(&mut self) -> Result<(), aws_lc_rs::error::Unspecif...
  method advance (line 791) | fn advance(&mut self) -> Result<Nonce, aws_lc_rs::error::Unspecified> {
  function labeled_extract_for_expand (line 801) | fn labeled_extract_for_expand(
  function labeled_extract_for_prk (line 819) | fn labeled_extract_for_prk(
  function labeled_expand (line 837) | fn labeled_expand<const L: usize>(
  type Label (line 862) | enum Label {
    method as_ref (line 873) | fn as_ref(&self) -> &[u8] {
  type LabeledSuiteId (line 889) | enum LabeledSuiteId {
    method encoded (line 901) | fn encoded(&self) -> Vec<u8> {
  type AeadKey (line 916) | struct AeadKey<const KEY_LEN: usize>([u8; KEY_LEN]);
  method drop (line 920) | fn drop(&mut self) {
  type KemSharedSecret (line 926) | struct KemSharedSecret<const KDF_LEN: usize>([u8; KDF_LEN]);
  method drop (line 930) | fn drop(&mut self) {
  function key_rejected_err (line 935) | fn key_rejected_err(e: aws_lc_rs::error::KeyRejected) -> Error {
  constant CHACHA_KEY_LEN (line 941) | const CHACHA_KEY_LEN: usize = 32;
  function smoke_test (line 954) | fn smoke_test() {
  function test_fips (line 1012) | fn test_fips() {
  function check_test_vectors (line 1057) | fn check_test_vectors() {
  type TestHpke (line 1094) | trait TestHpke: Hpke {
    method setup_test_sealer (line 1095) | fn setup_test_sealer(
    method setup_test_sealer (line 1104) | fn setup_test_sealer(
  type TestVector (line 1137) | struct TestVector {
    method suite (line 1161) | fn suite(&self) -> HpkeSuite {
    method applicable (line 1171) | fn applicable(&self) -> Option<&'static dyn TestHpke> {
    method lookup_suite (line 1180) | fn lookup_suite(
  type TestEncryption (line 1154) | struct TestEncryption {
  function test_vectors (line 1191) | fn test_vectors() -> Vec<TestVector> {

FILE: rustls-aws-lc-rs/src/kx.rs
  type MlKem (line 62) | pub(crate) struct MlKem {
  method start (line 68) | fn start(&self) -> Result<StartedKeyExchange, Error> {
  method start_and_complete (line 84) | fn start_and_complete(&self, client_share: &[u8]) -> Result<CompletedKey...
  method name (line 99) | fn name(&self) -> NamedGroup {
  method fips (line 103) | fn fips(&self) -> FipsStatus {
  type Active (line 120) | struct Active {
  method complete (line 130) | fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret...
  method pub_key (line 139) | fn pub_key(&self) -> &[u8] {
  method group (line 143) | fn group(&self) -> NamedGroup {
  constant X25519_LEN (line 148) | const X25519_LEN: usize = 32;
  constant SECP256R1_LEN (line 149) | const SECP256R1_LEN: usize = 65;
  constant MLKEM768_CIPHERTEXT_LEN (line 150) | const MLKEM768_CIPHERTEXT_LEN: usize = 1088;
  constant MLKEM768_ENCAP_LEN (line 151) | const MLKEM768_ENCAP_LEN: usize = 1184;
  type KxGroup (line 154) | struct KxGroup {
    method fmt (line 214) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method start (line 183) | fn start(&self) -> Result<StartedKeyExchange, Error> {
  method name (line 201) | fn name(&self) -> NamedGroup {
  method fips (line 205) | fn fips(&self) -> FipsStatus {
  function uncompressed_point (line 250) | fn uncompressed_point(point: &[u8]) -> bool {
  type KeyExchange (line 259) | struct KeyExchange {
  method complete (line 269) | fn complete(self: Box<Self>, peer: &[u8]) -> Result<SharedSecret, Error> {
  method group (line 279) | fn group(&self) -> NamedGroup {
  method pub_key (line 284) | fn pub_key(&self) -> &[u8] {
  function kxgroup_fmt_yields_name (line 294) | fn kxgroup_fmt_yields_name() {
  function bench_x25519 (line 302) | fn bench_x25519(b: &mut test::Bencher) {
  function bench_ecdh_p256 (line 307) | fn bench_ecdh_p256(b: &mut test::Bencher) {
  function bench_ecdh_p384 (line 312) | fn bench_ecdh_p384(b: &mut test::Bencher) {
  function bench_any (line 316) | fn bench_any(b: &mut test::Bencher, kxg: &dyn super::SupportedKxGroup) {

FILE: rustls-aws-lc-rs/src/lib.rs
  constant DEFAULT_FIPS_PROVIDER (line 88) | pub const DEFAULT_FIPS_PROVIDER: CryptoProvider = DEFAULT_PROVIDER;
  constant DEFAULT_PROVIDER (line 91) | pub const DEFAULT_PROVIDER: CryptoProvider = CryptoProvider {
  constant DEFAULT_TLS13_PROVIDER (line 102) | pub const DEFAULT_TLS13_PROVIDER: CryptoProvider = CryptoProvider {
  constant DEFAULT_TLS12_PROVIDER (line 110) | pub const DEFAULT_TLS12_PROVIDER: CryptoProvider = CryptoProvider {
  type AwsLcRs (line 122) | struct AwsLcRs;
  method fill (line 125) | fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
  method fips (line 133) | fn fips(&self) -> FipsStatus {
  method load_private_key (line 139) | fn load_private_key(
  method fips (line 162) | fn fips(&self) -> FipsStatus {
  method ticketer (line 180) | fn ticketer(&self) -> Result<Arc<dyn TicketProducer>, Error> {
  method fips (line 196) | fn fips(&self) -> FipsStatus {
  constant SIX_HOURS (line 202) | const SIX_HOURS: Duration = Duration::from_secs(6 * 60 * 60);
  function agree_ephemeral (line 366) | pub(super) fn agree_ephemeral(
  function fips (line 377) | fn fips() -> FipsStatus {
  function unspecified_err (line 384) | fn unspecified_err(e: aws_lc_rs::error::Unspecified) -> Error {
  constant MAX_FRAGMENT_LEN (line 388) | const MAX_FRAGMENT_LEN: usize = 16384;
  function default_suites_are_fips (line 398) | fn default_suites_are_fips() {
  function default_suites (line 413) | fn default_suites() {

FILE: rustls-aws-lc-rs/src/quic.rs
  type HeaderProtectionKey (line 9) | pub(crate) struct HeaderProtectionKey(aead::quic::HeaderProtectionKey);
    method new (line 12) | pub(crate) fn new(key: AeadKey, alg: &'static aead::quic::Algorithm) -...
    method xor_in_place (line 16) | fn xor_in_place(
    method encrypt_in_place (line 72) | fn encrypt_in_place(
    method decrypt_in_place (line 81) | fn decrypt_in_place(
    method sample_len (line 91) | fn sample_len(&self) -> usize {
  type PacketKey (line 96) | pub(crate) struct PacketKey {
    method new (line 108) | pub(crate) fn new(
    method encrypt_in_place (line 127) | fn encrypt_in_place(
    method decrypt_in_place (line 154) | fn decrypt_in_place<'a>(
    method tag_len (line 175) | fn tag_len(&self) -> usize {
    method confidentiality_limit (line 180) | fn confidentiality_limit(&self) -> u64 {
    method integrity_limit (line 185) | fn integrity_limit(&self) -> u64 {
  type KeyBuilder (line 190) | pub(crate) struct KeyBuilder {
    method packet_key (line 198) | fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn quic::PacketKey> {
    method header_protection_key (line 208) | fn header_protection_key(&self, key: AeadKey) -> Box<dyn quic::HeaderP...
    method aead_key_len (line 212) | fn aead_key_len(&self) -> usize {
    method fips (line 216) | fn fips(&self) -> FipsStatus {
  function test_short_packet (line 230) | fn test_short_packet(version: Version, expected: &[u8]) {
  function short_packet_header_protection (line 283) | fn short_packet_header_protection() {
  function short_packet_header_protection_v2 (line 295) | fn short_packet_header_protection_v2() {
  function initial_test_vector_v2 (line 307) | fn initial_test_vector_v2() {
  function test_multipath_aead_basic (line 370) | fn test_multipath_aead_basic() {
  function test_multipath_aead_roundtrip (line 409) | fn test_multipath_aead_roundtrip() {

FILE: rustls-aws-lc-rs/src/sign.rs
  type RsaSigningKey (line 17) | pub(super) struct RsaSigningKey {
    method to_signer (line 22) | fn to_signer(&self, scheme: SignatureScheme) -> RsaSigner {
    constant SCHEMES (line 40) | const SCHEMES: &[SignatureScheme] = &[
    type Error (line 67) | type Error = Error;
    method try_from (line 71) | fn try_from(der: &PrivateKeyDer<'_>) -> Result<Self, Self::Error> {
  method choose_scheme (line 51) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn S...
  method public_key (line 58) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method fmt (line 92) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type RsaSigner (line 98) | struct RsaSigner {
    method sign (line 105) | fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
  method sign (line 117) | fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, Error> {
  method scheme (line 121) | fn scheme(&self) -> SignatureScheme {
  method fmt (line 127) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type EcdsaSigner (line 139) | pub(super) struct EcdsaSigner {
    method new (line 147) | fn new(
    method sign (line 169) | fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
    type Error (line 210) | type Error = Error;
    method try_from (line 216) | fn try_from(der: &PrivateKeyDer<'_>) -> Result<Self, Error> {
  method choose_scheme (line 179) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn S...
  method public_key (line 187) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method sign (line 200) | fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, Error> {
  method scheme (line 204) | fn scheme(&self) -> SignatureScheme {
  method fmt (line 248) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type Ed25519Signer (line 260) | pub(super) struct Ed25519Signer {
    method sign (line 266) | fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
    type Error (line 296) | type Error = Error;
    method try_from (line 304) | fn try_from(der: &PrivatePkcs8KeyDer<'_>) -> Result<Self, Error> {
  method choose_scheme (line 272) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn S...
  method public_key (line 280) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method sign (line 286) | fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, Error> {
  method scheme (line 290) | fn scheme(&self) -> SignatureScheme {
  method fmt (line 318) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  function load_key (line 326) | fn load_key(
  function can_load_ecdsa_nistp256_pkcs8 (line 345) | fn can_load_ecdsa_nistp256_pkcs8() {
  function can_load_ecdsa_nistp256_sec1 (line 356) | fn can_load_ecdsa_nistp256_sec1() {
  function can_sign_ecdsa_nistp256 (line 365) | fn can_sign_ecdsa_nistp256() {
  function can_load_ecdsa_nistp384_pkcs8 (line 401) | fn can_load_ecdsa_nistp384_pkcs8() {
  function can_load_ecdsa_nistp384_sec1 (line 412) | fn can_load_ecdsa_nistp384_sec1() {
  function can_sign_ecdsa_nistp384 (line 421) | fn can_sign_ecdsa_nistp384() {
  function can_load_ecdsa_nistp521_pkcs8 (line 457) | fn can_load_ecdsa_nistp521_pkcs8() {
  function can_load_ecdsa_nistp521_sec1 (line 468) | fn can_load_ecdsa_nistp521_sec1() {
  function can_sign_ecdsa_nistp521 (line 477) | fn can_sign_ecdsa_nistp521() {
  function can_load_eddsa_pkcs8 (line 517) | fn can_load_eddsa_pkcs8() {
  function can_sign_eddsa (line 527) | fn can_sign_eddsa() {
  function can_load_rsa2048_pkcs8 (line 551) | fn can_load_rsa2048_pkcs8() {
  function can_load_rsa2048_pkcs1 (line 562) | fn can_load_rsa2048_pkcs1() {
  function can_sign_rsa2048 (line 571) | fn can_sign_rsa2048() {
  function cannot_load_invalid_pkcs8_encoding (line 608) | fn cannot_load_invalid_pkcs8_encoding() {
  function bench_rsa2048_pkcs1_sha256 (line 637) | fn bench_rsa2048_pkcs1_sha256(b: &mut test::Bencher) {
  function bench_rsa2048_pss_sha256 (line 656) | fn bench_rsa2048_pss_sha256(b: &mut test::Bencher) {
  function bench_eddsa (line 675) | fn bench_eddsa(b: &mut test::Bencher) {
  function bench_ecdsa_p256_sha256 (line 690) | fn bench_ecdsa_p256_sha256(b: &mut test::Bencher) {
  function bench_ecdsa_p384_sha384 (line 706) | fn bench_ecdsa_p384_sha384(b: &mut test::Bencher) {
  function bench_ecdsa_p521_sha512 (line 722) | fn bench_ecdsa_p521_sha512(b: &mut test::Bencher) {
  function bench_load_and_validate_rsa2048 (line 738) | fn bench_load_and_validate_rsa2048(b: &mut test::Bencher) {
  function bench_load_and_validate_rsa4096 (line 749) | fn bench_load_and_validate_rsa4096(b: &mut test::Bencher) {
  function bench_load_and_validate_p256 (line 760) | fn bench_load_and_validate_p256(b: &mut test::Bencher) {
  function bench_load_and_validate_p384 (line 771) | fn bench_load_and_validate_p384(b: &mut test::Bencher) {
  function bench_load_and_validate_p521 (line 782) | fn bench_load_and_validate_p521(b: &mut test::Bencher) {
  function bench_load_and_validate_eddsa (line 793) | fn bench_load_and_validate_eddsa(b: &mut test::Bencher) {
  constant SAMPLE_TLS13_MESSAGE (line 802) | const SAMPLE_TLS13_MESSAGE: &[u8] = &[

FILE: rustls-aws-lc-rs/src/ticketer.rs
  type Rfc5077Ticketer (line 20) | pub(super) struct Rfc5077Ticketer {
    method new (line 30) | pub(super) fn new() -> Result<Box<dyn TicketProducer>, Error> {
  method encrypt (line 73) | fn encrypt(&self, message: &[u8]) -> Option<Vec<u8>> {
  method decrypt (line 121) | fn decrypt(&self, ciphertext: &[u8]) -> Option<Vec<u8>> {
  method lifetime (line 171) | fn lifetime(&self) -> Duration {
  method fmt (line 179) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  function basic_pairwise_test (line 193) | fn basic_pairwise_test() {
  function refuses_decrypt_before_encrypt (line 201) | fn refuses_decrypt_before_encrypt() {
  function refuses_decrypt_larger_than_largest_encryption (line 207) | fn refuses_decrypt_larger_than_largest_encryption() {
  function rfc5077ticketer_is_debug_and_producestickets (line 220) | fn rfc5077ticketer_is_debug_and_producestickets() {

FILE: rustls-aws-lc-rs/src/tls12.rs
  type GcmAlgorithm (line 124) | pub(crate) struct GcmAlgorithm(&'static aead::Algorithm);
  method decrypter (line 127) | fn decrypter(&self, dec_key: AeadKey, dec_iv: &[u8]) -> Box<dyn MessageD...
  method encrypter (line 143) | fn encrypter(
  method key_block_shape (line 168) | fn key_block_shape(&self) -> KeyBlockShape {
  method extract_keys (line 176) | fn extract_keys(
  method fips (line 190) | fn fips(&self) -> FipsStatus {
  type ChaCha20Poly1305 (line 195) | pub(crate) struct ChaCha20Poly1305;
  method decrypter (line 198) | fn decrypter(&self, dec_key: AeadKey, iv: &[u8]) -> Box<dyn MessageDecry...
  method encrypter (line 208) | fn encrypter(&self, enc_key: AeadKey, enc_iv: &[u8], _: &[u8]) -> Box<dy...
  method key_block_shape (line 218) | fn key_block_shape(&self) -> KeyBlockShape {
  method extract_keys (line 226) | fn extract_keys(
  method fips (line 240) | fn fips(&self) -> FipsStatus {
  type GcmMessageEncrypter (line 246) | struct GcmMessageEncrypter {
  type GcmMessageDecrypter (line 252) | struct GcmMessageDecrypter {
  constant GCM_EXPLICIT_NONCE_LEN (line 257) | const GCM_EXPLICIT_NONCE_LEN: usize = 8;
  constant GCM_OVERHEAD (line 258) | const GCM_OVERHEAD: usize = GCM_EXPLICIT_NONCE_LEN + 16;
  method decrypt (line 261) | fn decrypt<'a>(
  method encrypt (line 305) | fn encrypt(
  method encrypted_payload_len (line 330) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  type ChaCha20Poly1305MessageEncrypter (line 338) | struct ChaCha20Poly1305MessageEncrypter {
  type ChaCha20Poly1305MessageDecrypter (line 346) | struct ChaCha20Poly1305MessageDecrypter {
  constant CHACHAPOLY1305_OVERHEAD (line 351) | const CHACHAPOLY1305_OVERHEAD: usize = 16;
  method decrypt (line 354) | fn decrypt<'a>(
  method encrypt (line 391) | fn encrypt(
  method encrypted_payload_len (line 415) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  function gcm_iv (line 420) | fn gcm_iv(write_iv: &[u8], explicit: &[u8]) -> Iv {
  type Tls12Prf (line 438) | struct Tls12Prf(&'static tls_prf::Algorithm);
  method for_key_exchange (line 441) | fn for_key_exchange(
  method new_secret (line 459) | fn new_secret(&self, secret: &[u8; 48]) -> Box<dyn PrfSecret> {
  method fips (line 466) | fn fips(&self) -> FipsStatus {
  type Tls12PrfSecret (line 473) | struct Tls12PrfSecret {
  method prf (line 479) | fn prf(&self, output: &mut [u8], label: &[u8], seed: &[u8]) {
  type Secret (line 493) | enum Secret {
    method as_ref (line 499) | fn as_ref(&self) -> &[u8] {

FILE: rustls-aws-lc-rs/src/tls13.rs
  type Chacha20Poly1305Aead (line 78) | struct Chacha20Poly1305Aead(AeadAlgorithm);
  method encrypter (line 81) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 89) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 97) | fn key_len(&self) -> usize {
  method extract_keys (line 101) | fn extract_keys(
  method fips (line 109) | fn fips(&self) -> FipsStatus {
  type Aes256GcmAead (line 114) | struct Aes256GcmAead(AeadAlgorithm);
  method encrypter (line 117) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 121) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 125) | fn key_len(&self) -> usize {
  method extract_keys (line 129) | fn extract_keys(
  method fips (line 137) | fn fips(&self) -> FipsStatus {
  type Aes128GcmAead (line 142) | struct Aes128GcmAead(AeadAlgorithm);
  method encrypter (line 145) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 149) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 153) | fn key_len(&self) -> usize {
  method extract_keys (line 157) | fn extract_keys(
  method fips (line 165) | fn fips(&self) -> FipsStatus {
  type AeadAlgorithm (line 171) | struct AeadAlgorithm(&'static aead::Algorithm);
    method encrypter (line 175) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
    method decrypter (line 191) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
    method key_len (line 206) | fn key_len(&self) -> usize {
  type AeadMessageEncrypter (line 211) | struct AeadMessageEncrypter {
  type AeadMessageDecrypter (line 216) | struct AeadMessageDecrypter {
  method encrypt (line 222) | fn encrypt(
  method encrypted_payload_len (line 248) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  method decrypt (line 254) | fn decrypt<'a>(
  type GcmMessageEncrypter (line 277) | struct GcmMessageEncrypter {
  method encrypt (line 283) | fn encrypt(
  method encrypted_payload_len (line 307) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  type GcmMessageDecrypter (line 312) | struct GcmMessageDecrypter {
  method decrypt (line 318) | fn decrypt<'a>(
  type AwsLcHkdf (line 341) | struct AwsLcHkdf(hkdf::Algorithm, hmac::Algorithm);
  method extract_from_zero_ikm (line 344) | fn extract_from_zero_ikm(&self, salt: Option<&[u8]>) -> Box<dyn HkdfExpa...
  method extract_from_secret (line 356) | fn extract_from_secret(&self, salt: Option<&[u8]>, secret: &[u8]) -> Box...
  method expander_for_okm (line 368) | fn expander_for_okm(&self, okm: &OkmBlock) -> Box<dyn HkdfExpander> {
  method hmac_sign (line 375) | fn hmac_sign(&self, key: &OkmBlock, message: &[u8]) -> crypto::hmac::Tag {
  method fips (line 379) | fn fips(&self) -> FipsStatus {
  type AwsLcHkdfExpander (line 384) | struct AwsLcHkdfExpander {
  method expand_slice (line 390) | fn expand_slice(&self, info: &[&[u8]], output: &mut [u8]) -> Result<(), ...
  method expand_block (line 397) | fn expand_block(&self, info: &[&[u8]]) -> OkmBlock {
  method hash_len (line 407) | fn hash_len(&self) -> usize {
  type Len (line 412) | struct Len(usize);
  method len (line 415) | fn len(&self) -> usize {

FILE: rustls-aws-lc-rs/src/verify.rs
  type AwsLcRsAlgorithm (line 45) | struct AwsLcRsAlgorithm {
  method public_key_alg_id (line 53) | fn public_key_alg_id(&self) -> AlgorithmIdentifier {
  method signature_alg_id (line 57) | fn signature_alg_id(&self) -> AlgorithmIdentifier {
  method verify_signature (line 61) | fn verify_signature(
  method fips_status (line 89) | fn fips_status(&self) -> FipsStatus {

FILE: rustls-bench/src/main.rs
  function main (line 25) | pub fn main() {
  type Args (line 98) | struct Args {
    method command (line 134) | fn command(&self) -> &Command {
  type Command (line 142) | enum Command {
  type Api (line 198) | enum Api {
    method use_buffered (line 205) | fn use_buffered(&self) -> bool {
  function all_tests (line 210) | fn all_tests(args: &Args) {
  function bench_handshake (line 239) | fn bench_handshake(params: &Parameters) {
  function bench_handshake_buffered (line 278) | fn bench_handshake_buffered(
  function multithreaded (line 346) | fn multithreaded(
  function report_handshake_result (line 368) | fn report_handshake_result(variant: &str, params: &Parameters, rounds: u...
  function report_timings (line 392) | fn report_timings(
  type Timings (line 422) | struct Timings {
  function bench_bulk (line 427) | fn bench_bulk(params: &Parameters) {
  function bench_bulk_buffered (line 456) | fn bench_bulk_buffered(
  function report_bulk_result (line 487) | fn report_bulk_result(variant: &str, params: &Parameters, timings: Vec<T...
  function bench_memory (line 509) | fn bench_memory(
  function lookup_matching_benches (line 556) | fn lookup_matching_benches(
  type Parameters (line 580) | struct Parameters {
    method new (line 605) | fn new(bench: &BenchmarkParam, args: &Args) -> Self {
    method with_plaintext_size (line 622) | fn with_plaintext_size(&self, plaintext_size: u64) -> Self {
    method with_max_fragment (line 628) | fn with_max_fragment(&self, max_fragment_size: Option<usize>) -> Self {
    method with_client_auth (line 634) | fn with_client_auth(&self, client_auth: ClientAuth) -> Self {
    method with_resume (line 640) | fn with_resume(&self, resume: ResumptionParam) -> Self {
    method without_latency_measurement (line 646) | fn without_latency_measurement(&self) -> Self {
    method server_config (line 652) | fn server_config(&self) -> Arc<ServerConfig> {
    method client_config (line 702) | fn client_config(&self) -> Arc<ClientConfig> {
    method apply_work_multiplier (line 733) | fn apply_work_multiplier(&self, work: u64) -> u64 {
    method open_latency_file (line 737) | fn open_latency_file(&self, role: &str) -> LatencyOutput {
  type LatencyOutput (line 742) | struct LatencyOutput {
    method new (line 747) | fn new(prefix: Option<&str>, role: &str) -> Self {
    method sample (line 757) | fn sample(&mut self, secs: f64) {
  type ClientAuth (line 765) | enum ClientAuth {
    method label (line 771) | fn label(&self) -> &'static str {
  type ResumptionParam (line 780) | enum ResumptionParam {
    method from_subcommand (line 787) | fn from_subcommand(cmd: &Command) -> Self {
    method as_handshake_kind (line 796) | fn as_handshake_kind(&self) -> HandshakeKind {
    method label (line 803) | fn label(&self) -> &'static str {
  type Provider (line 813) | enum Provider {
    method build (line 827) | fn build(self) -> CryptoProvider {
    method build_with_cipher_suite (line 841) | fn build_with_cipher_suite(&self, name: CipherSuite) -> CryptoProvider {
    method supports_benchmark (line 854) | fn supports_benchmark(&self, param: &BenchmarkParam) -> bool {
    method supports_key_type (line 860) | fn supports_key_type(&self, _key_type: KeyType) -> bool {
    method choose_default (line 869) | fn choose_default() -> Self {
  type BenchmarkParam (line 897) | struct BenchmarkParam {
    method new (line 904) | const fn new(key_type: KeyType, ciphersuite: CipherSuite, version: Pro...
  type RequestedKeyType (line 914) | enum RequestedKeyType {
  method from (line 922) | fn from(val: RequestedKeyType) -> Self {
  function do_handshake_step (line 932) | fn do_handshake_step(
  function do_handshake (line 946) | fn do_handshake(
  function time (line 954) | fn time<F, T>(time_out: &mut f64, mut f: F) -> T
  function transfer (line 965) | fn transfer(
  type TempBuffers (line 1030) | struct TempBuffers {
    method new (line 1035) | fn new() -> Self {
  function wall_time (line 1042) | fn wall_time() -> f64 {
  function duration_nanos (line 1050) | fn duration_nanos(d: Duration) -> f64 {

FILE: rustls-fuzzing-provider/src/lib.rs
  constant PROVIDER (line 30) | pub const PROVIDER: crypto::CryptoProvider = crypto::CryptoProvider {
  constant PROVIDER_TLS12 (line 40) | pub const PROVIDER_TLS12: crypto::CryptoProvider = crypto::CryptoProvider {
  constant PROVIDER_TLS13 (line 45) | pub const PROVIDER_TLS13: crypto::CryptoProvider = crypto::CryptoProvider {
  function server_verifier (line 50) | pub fn server_verifier() -> Arc<dyn ServerVerifier> {
  function server_cert_resolver (line 64) | pub fn server_cert_resolver() -> Arc<dyn ServerCredentialResolver> {
  type DummyCert (line 74) | struct DummyCert(Arc<Credentials>);
  method resolve (line 77) | fn resolve(&self, client_hello: &ClientHello<'_>) -> Result<SelectedCred...
  type Provider (line 87) | struct Provider;
    method fill (line 90) | fn fill(&self, bytes: &mut [u8]) -> Result<(), GetRandomFailed> {
    method load_private_key (line 104) | fn load_private_key(
    method ticketer (line 113) | fn ticketer(&self) -> Result<Arc<dyn TicketProducer>, Error> {
    method fips (line 117) | fn fips(&self) -> FipsStatus {
  constant RAND (line 101) | const RAND: &[u8] = b"Rand";
  constant TLS13_FUZZING_SUITE (line 122) | pub const TLS13_FUZZING_SUITE: &Tls13CipherSuite = &Tls13CipherSuite {
  constant TLS_FUZZING_SUITE (line 134) | pub const TLS_FUZZING_SUITE: &Tls12CipherSuite = &Tls12CipherSuite {
  type Ticketer (line 148) | pub struct Ticketer;
  method encrypt (line 151) | fn encrypt(&self, plain: &[u8]) -> Option<Vec<u8>> {
  method decrypt (line 155) | fn decrypt(&self, cipher: &[u8]) -> Option<Vec<u8>> {
  method lifetime (line 159) | fn lifetime(&self) -> Duration {
  type Hash (line 164) | struct Hash;
    method start (line 167) | fn start(&self) -> Box<dyn hash::Context> {
    method hash (line 171) | fn hash(&self, _data: &[u8]) -> hash::Output {
    method algorithm (line 175) | fn algorithm(&self) -> HashAlgorithm {
    method output_len (line 179) | fn output_len(&self) -> usize {
  type HashContext (line 184) | struct HashContext;
    method fork_finish (line 187) | fn fork_finish(&self) -> hash::Output {
    method fork (line 191) | fn fork(&self) -> Box<dyn hash::Context> {
    method finish (line 195) | fn finish(self: Box<Self>) -> hash::Output {
    method update (line 199) | fn update(&mut self, _data: &[u8]) {}
  constant HASH_OUTPUT (line 202) | const HASH_OUTPUT: &[u8] = b"HashHashHashHashHashHashHashHash";
  type Hmac (line 204) | struct Hmac;
    method with_key (line 207) | fn with_key(&self, _key: &[u8]) -> Box<dyn crypto::hmac::Key> {
    method hash_output_len (line 211) | fn hash_output_len(&self) -> usize {
  type HmacKey (line 216) | struct HmacKey;
    method sign_concat (line 219) | fn sign_concat(&self, _first: &[u8], _middle: &[&[u8]], _last: &[u8]) ...
    method tag_len (line 223) | fn tag_len(&self) -> usize {
  constant HMAC_OUTPUT (line 228) | const HMAC_OUTPUT: &[u8] = b"HmacHmacHmacHmacHmacHmacHmacHmac";
  type ActiveKeyExchange (line 230) | struct ActiveKeyExchange;
    method complete (line 233) | fn complete(self: Box<Self>, peer: &[u8]) -> Result<SharedSecret, Erro...
    method pub_key (line 240) | fn pub_key(&self) -> &[u8] {
    method group (line 244) | fn group(&self) -> NamedGroup {
  constant KEY_EXCHANGE_GROUP (line 249) | const KEY_EXCHANGE_GROUP: &dyn SupportedKxGroup = &KeyExchangeGroup;
  type KeyExchangeGroup (line 252) | struct KeyExchangeGroup;
  method start (line 255) | fn start(&self) -> Result<StartedKeyExchange, Error> {
  method name (line 259) | fn name(&self) -> NamedGroup {
  constant KX_PEER_SHARE (line 264) | const KX_PEER_SHARE: &[u8] = b"KxPeerShareKxPeerShareKxPeerShare";
  constant KX_SHARED_SECRET (line 265) | const KX_SHARED_SECRET: &[u8] = b"KxSharedSecretKxSharedSecret";
  type Aead (line 267) | struct Aead;
  method encrypter (line 270) | fn encrypter(&self, _key: AeadKey, _iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 274) | fn decrypter(&self, _key: AeadKey, _iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 278) | fn key_len(&self) -> usize {
  method extract_keys (line 282) | fn extract_keys(
  method encrypter (line 292) | fn encrypter(&self, _key: AeadKey, _iv: &[u8], _: &[u8]) -> Box<dyn Mess...
  method decrypter (line 296) | fn decrypter(&self, _key: AeadKey, _iv: &[u8]) -> Box<dyn MessageDecrypt...
  method key_block_shape (line 300) | fn key_block_shape(&self) -> KeyBlockShape {
  method extract_keys (line 308) | fn extract_keys(
  type Tls13Cipher (line 318) | struct Tls13Cipher;
  method encrypt (line 321) | fn encrypt(
  method encrypted_payload_len (line 350) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  method decrypt (line 356) | fn decrypt<'a>(
  type Tls12Cipher (line 387) | struct Tls12Cipher;
  method encrypt (line 390) | fn encrypt(
  method encrypted_payload_len (line 417) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  method decrypt (line 423) | fn decrypt<'a>(
  constant AEAD_MASK (line 454) | const AEAD_MASK: &[u8] = b"AeadMaskPattern";
  constant AEAD_TAG (line 455) | const AEAD_TAG: &[u8] = b"AeadTagA";
  constant AEAD_OVERHEAD (line 456) | const AEAD_OVERHEAD: usize = 16;
  type VerifyAlgorithm (line 469) | struct VerifyAlgorithm;
  method public_key_alg_id (line 472) | fn public_key_alg_id(&self) -> AlgorithmIdentifier {
  method signature_alg_id (line 476) | fn signature_alg_id(&self) -> AlgorithmIdentifier {
  method verify_signature (line 480) | fn verify_signature(
  type SigningKey (line 494) | pub struct SigningKey;
    method choose_scheme (line 497) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn...
    method public_key (line 504) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
    method sign (line 510) | fn sign(self: Box<Self>, _message: &[u8]) -> Result<Vec<u8>, Error> {
    method scheme (line 514) | fn scheme(&self) -> SignatureScheme {
  constant SIGNATURE_SCHEME (line 519) | const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::ECDSA_NISTP25...
  constant SIGNATURE (line 521) | const SIGNATURE: &[u8] = &[

FILE: rustls-fuzzing-provider/tests/smoke.rs
  function pairwise_tls12 (line 14) | fn pairwise_tls12() {
  function pairwise_tls13 (line 45) | fn pairwise_tls13() {
  function test_version (line 75) | fn test_version(provider: CryptoProvider) -> Transcript {
  type Transcript (line 137) | struct Transcript {

FILE: rustls-post-quantum/benches/benchmarks.rs
  function bench_client (line 12) | fn bench_client(c: &mut Criterion) {
  function bench_server (line 31) | fn bench_server(c: &mut Criterion) {
  function bench_clienthello (line 68) | fn bench_clienthello(c: &mut Criterion) {
  function do_client_hello (line 121) | fn do_client_hello(config: &Arc<ClientConfig>) -> usize {
  function separate_provider (line 129) | fn separate_provider() -> CryptoProvider {
  type SeparateX25519Mlkem768 (line 144) | struct SeparateX25519Mlkem768;
  method start (line 147) | fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, Error> {
  method name (line 154) | fn name(&self) -> NamedGroup {
  type Active (line 159) | struct Active {
  method complete (line 165) | fn complete(self: Box<Self>, _peer: &[u8]) -> Result<SharedSecret, Error> {
  method hybrid_component (line 169) | fn hybrid_component(&self) -> Option<(NamedGroup, &[u8])> {
  method group (line 173) | fn group(&self) -> NamedGroup {
  method pub_key (line 177) | fn pub_key(&self) -> &[u8] {

FILE: rustls-post-quantum/examples/client.rs
  function main (line 14) | fn main() {

FILE: rustls-post-quantum/src/lib.rs
  function provider (line 22) | pub fn provider() -> CryptoProvider {
  type PqAwsLcRs (line 50) | pub(super) struct PqAwsLcRs;
  method load_private_key (line 53) | fn load_private_key(
  method fips (line 80) | fn fips(&self) -> bool {
  type PqdsaSigningKey (line 85) | struct PqdsaSigningKey {
  method choose_scheme (line 91) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn S...
  method public_key (line 102) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method algorithm (line 111) | fn algorithm(&self) -> SignatureAlgorithm {
  method fmt (line 117) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type PqdsaSigner (line 124) | struct PqdsaSigner {
  method sign (line 130) | fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
  method scheme (line 145) | fn scheme(&self) -> SignatureScheme {
  method fmt (line 151) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type PqdsaKeyKind (line 159) | enum PqdsaKeyKind {
    method iter (line 166) | fn iter() -> impl Iterator<Item = Self> {
    method to_alg (line 170) | fn to_alg(self) -> &'static PqdsaSigningAlgorithm {
    method scheme (line 178) | fn scheme(&self) -> SignatureScheme {
    method alg_id (line 186) | fn alg_id(&self) -> AlgorithmIdentifier {
  function ml_dsa (line 300) | fn ml_dsa() {
  function do_handshake (line 344) | fn do_handshake(
  function transfer (line 359) | fn transfer(

FILE: rustls-provider-test/tests/hpke.rs
  function check_test_vectors (line 13) | fn check_test_vectors() {
  type TestVector (line 44) | struct TestVector {
    method suite (line 64) | fn suite(&self) -> HpkeSuite {
    method applicable (line 74) | fn applicable(&self) -> Option<Vec<(&'static dyn Hpke, &'static dyn Hp...
    method lookup_suite (line 106) | fn lookup_suite(
  type TestEncryption (line 58) | struct TestEncryption {
  function test_vectors (line 117) | fn test_vectors() -> Vec<TestVector> {

FILE: rustls-ring/benches/benchmarks.rs
  function bench_ewouldblock (line 7) | fn bench_ewouldblock(c: &mut Bencher) {

FILE: rustls-ring/src/hash.rs
  type Hash (line 10) | pub(crate) struct Hash(&'static digest::Algorithm, HashAlgorithm);
    method start (line 13) | fn start(&self) -> Box<dyn crypto::hash::Context> {
    method hash (line 17) | fn hash(&self, bytes: &[u8]) -> crypto::hash::Output {
    method output_len (line 23) | fn output_len(&self) -> usize {
    method algorithm (line 27) | fn algorithm(&self) -> HashAlgorithm {
    method fips (line 31) | fn fips(&self) -> FipsStatus {
  type Context (line 36) | struct Context(digest::Context);
    method fork_finish (line 39) | fn fork_finish(&self) -> crypto::hash::Output {
    method fork (line 43) | fn fork(&self) -> Box<dyn crypto::hash::Context> {
    method finish (line 47) | fn finish(self: Box<Self>) -> crypto::hash::Output {
    method update (line 51) | fn update(&mut self, data: &[u8]) {
  function convert (line 56) | fn convert(val: digest::Digest) -> crypto::hash::Output {

FILE: rustls-ring/src/hmac.rs
  type Hmac (line 12) | pub(crate) struct Hmac(&'static hmac::Algorithm);
    method with_key (line 15) | fn with_key(&self, key: &[u8]) -> Box<dyn crypto::hmac::Key> {
    method hash_output_len (line 19) | fn hash_output_len(&self) -> usize {
    method fips (line 23) | fn fips(&self) -> FipsStatus {
  type Key (line 28) | struct Key(hmac::Key);
    method sign_concat (line 31) | fn sign_concat(&self, first: &[u8], middle: &[&[u8]], last: &[u8]) -> ...
    method tag_len (line 41) | fn tag_len(&self) -> usize {

FILE: rustls-ring/src/kx.rs
  type KxGroup (line 14) | struct KxGroup {
    method fmt (line 74) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method start (line 43) | fn start(&self) -> Result<StartedKeyExchange, Error> {
  method name (line 61) | fn name(&self) -> NamedGroup {
  method fips (line 65) | fn fips(&self) -> FipsStatus {
  function uncompressed_point (line 110) | fn uncompressed_point(point: &[u8]) -> bool {
  type KeyExchange (line 119) | struct KeyExchange {
  method complete (line 129) | fn complete(self: Box<Self>, peer: &[u8]) -> Result<SharedSecret, Error> {
  method group (line 139) | fn group(&self) -> NamedGroup {
  method pub_key (line 144) | fn pub_key(&self) -> &[u8] {
  function kxgroup_fmt_yields_name (line 154) | fn kxgroup_fmt_yields_name() {
  function bench_x25519 (line 162) | fn bench_x25519(b: &mut test::Bencher) {
  function bench_ecdh_p256 (line 167) | fn bench_ecdh_p256(b: &mut test::Bencher) {
  function bench_ecdh_p384 (line 172) | fn bench_ecdh_p384(b: &mut test::Bencher) {
  function bench_any (line 176) | fn bench_any(b: &mut test::Bencher, kxg: &dyn super::SupportedKxGroup) {

FILE: rustls-ring/src/lib.rs
  constant DEFAULT_PROVIDER (line 61) | pub const DEFAULT_PROVIDER: CryptoProvider = CryptoProvider {
  constant DEFAULT_TLS13_PROVIDER (line 72) | pub const DEFAULT_TLS13_PROVIDER: CryptoProvider = CryptoProvider {
  constant DEFAULT_TLS12_PROVIDER (line 80) | pub const DEFAULT_TLS12_PROVIDER: CryptoProvider = CryptoProvider {
  type Ring (line 87) | struct Ring;
  method fill (line 90) | fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
  method load_private_key (line 99) | fn load_private_key(
  method ticketer (line 133) | fn ticketer(&self) -> Result<Arc<dyn TicketProducer>, Error> {
  method fips (line 146) | fn fips(&self) -> FipsStatus {
  function agree_ephemeral (line 272) | pub(super) fn agree_ephemeral(
  function fips (line 282) | pub fn fips() -> FipsStatus {
  constant SIX_HOURS (line 287) | const SIX_HOURS: Duration = Duration::from_secs(6 * 60 * 60);

FILE: rustls-ring/src/quic.rs
  type HeaderProtectionKey (line 9) | pub(crate) struct HeaderProtectionKey(aead::quic::HeaderProtectionKey);
    method new (line 12) | pub(crate) fn new(key: AeadKey, alg: &'static aead::quic::Algorithm) -...
    method xor_in_place (line 16) | fn xor_in_place(
    method encrypt_in_place (line 72) | fn encrypt_in_place(
    method decrypt_in_place (line 81) | fn decrypt_in_place(
    method sample_len (line 91) | fn sample_len(&self) -> usize {
  type PacketKey (line 96) | pub(crate) struct PacketKey {
    method new (line 108) | pub(crate) fn new(
    method encrypt_in_place (line 127) | fn encrypt_in_place(
    method decrypt_in_place (line 154) | fn decrypt_in_place<'a>(
    method tag_len (line 175) | fn tag_len(&self) -> usize {
    method confidentiality_limit (line 180) | fn confidentiality_limit(&self) -> u64 {
    method integrity_limit (line 185) | fn integrity_limit(&self) -> u64 {
  type KeyBuilder (line 190) | pub(crate) struct KeyBuilder {
    method packet_key (line 198) | fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn quic::PacketKey> {
    method header_protection_key (line 208) | fn header_protection_key(&self, key: AeadKey) -> Box<dyn quic::HeaderP...
    method aead_key_len (line 212) | fn aead_key_len(&self) -> usize {
    method fips (line 216) | fn fips(&self) -> FipsStatus {
  function test_short_packet (line 230) | fn test_short_packet(version: Version, expected: &[u8]) {
  function short_packet_header_protection (line 283) | fn short_packet_header_protection() {
  function short_packet_header_protection_v2 (line 295) | fn short_packet_header_protection_v2() {
  function initial_test_vector_v2 (line 307) | fn initial_test_vector_v2() {
  function test_multipath_aead_basic (line 370) | fn test_multipath_aead_basic() {
  function test_multipath_aead_roundtrip (line 409) | fn test_multipath_aead_roundtrip() {

FILE: rustls-ring/src/sign.rs
  type RsaSigningKey (line 17) | pub(super) struct RsaSigningKey {
    method to_signer (line 22) | fn to_signer(&self, scheme: SignatureScheme) -> RsaSigner {
    constant SCHEMES (line 40) | const SCHEMES: &[SignatureScheme] = &[
    type Error (line 67) | type Error = Error;
    method try_from (line 71) | fn try_from(der: &PrivateKeyDer<'_>) -> Result<Self, Self::Error> {
  method choose_scheme (line 51) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn S...
  method public_key (line 58) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method fmt (line 92) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type RsaSigner (line 98) | struct RsaSigner {
    method sign (line 105) | fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
  method sign (line 117) | fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, Error> {
  method scheme (line 121) | fn scheme(&self) -> SignatureScheme {
  method fmt (line 127) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type EcdsaSigner (line 139) | pub(super) struct EcdsaSigner {
    method new (line 148) | fn new(
    method convert_sec1_to_pkcs8 (line 173) | fn convert_sec1_to_pkcs8(
    method sign (line 191) | fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
    constant PKCS8_PREFIX_ECDSA_NISTP256 (line 204) | const PKCS8_PREFIX_ECDSA_NISTP256: &[u8] = b"\x02\x01\x00\
    constant PKCS8_PREFIX_ECDSA_NISTP384 (line 214) | const PKCS8_PREFIX_ECDSA_NISTP384: &[u8] = b"\x02\x01\x00\
    type Error (line 251) | type Error = Error;
    method try_from (line 257) | fn try_from(der: &PrivateKeyDer<'_>) -> Result<Self, Self::Error> {
  method choose_scheme (line 221) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn S...
  method public_key (line 229) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method sign (line 241) | fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, Error> {
  method scheme (line 245) | fn scheme(&self) -> SignatureScheme {
  method fmt (line 281) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  type Ed25519Signer (line 293) | pub(super) struct Ed25519Signer {
    method sign (line 299) | fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
    type Error (line 329) | type Error = Error;
    method try_from (line 337) | fn try_from(der: &PrivatePkcs8KeyDer<'_>) -> Result<Self, Self::Error> {
  method choose_scheme (line 305) | fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn S...
  method public_key (line 313) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method sign (line 319) | fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, Error> {
  method scheme (line 323) | fn scheme(&self) -> SignatureScheme {
  method fmt (line 351) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  function load_key (line 359) | fn load_key(
  function wrap_concat_in_sequence (line 369) | pub(crate) fn wrap_concat_in_sequence(bytes_a: &[u8], bytes_b: &[u8]) ->...
  function wrap_in_octet_string (line 374) | pub(crate) fn wrap_in_octet_string(bytes: &[u8]) -> Vec<u8> {
  function asn1_wrap (line 378) | fn asn1_wrap(tag: u8, bytes_a: &[u8], bytes_b: &[u8]) -> Vec<u8> {
  constant DER_SEQUENCE_TAG (line 411) | const DER_SEQUENCE_TAG: u8 = 0x30;
  constant DER_OCTET_STRING_TAG (line 412) | const DER_OCTET_STRING_TAG: u8 = 0x04;
  function can_load_ecdsa_nistp256_pkcs8 (line 424) | fn can_load_ecdsa_nistp256_pkcs8() {
  function can_load_ecdsa_nistp256_sec1 (line 435) | fn can_load_ecdsa_nistp256_sec1() {
  function can_sign_ecdsa_nistp256 (line 444) | fn can_sign_ecdsa_nistp256() {
  function can_load_ecdsa_nistp384_pkcs8 (line 480) | fn can_load_ecdsa_nistp384_pkcs8() {
  function can_load_ecdsa_nistp384_sec1 (line 491) | fn can_load_ecdsa_nistp384_sec1() {
  function can_sign_ecdsa_nistp384 (line 500) | fn can_sign_ecdsa_nistp384() {
  function can_load_eddsa_pkcs8 (line 536) | fn can_load_eddsa_pkcs8() {
  function can_sign_eddsa (line 546) | fn can_sign_eddsa() {
  function can_load_rsa2048_pkcs8 (line 570) | fn can_load_rsa2048_pkcs8() {
  function can_load_rsa2048_pkcs1 (line 581) | fn can_load_rsa2048_pkcs1() {
  function can_sign_rsa2048 (line 590) | fn can_sign_rsa2048() {
  function cannot_load_invalid_pkcs8_encoding (line 627) | fn cannot_load_invalid_pkcs8_encoding() {
  function bench_rsa2048_pkcs1_sha256 (line 656) | fn bench_rsa2048_pkcs1_sha256(b: &mut test::Bencher) {
  function bench_rsa2048_pss_sha256 (line 675) | fn bench_rsa2048_pss_sha256(b: &mut test::Bencher) {
  function bench_eddsa (line 694) | fn bench_eddsa(b: &mut test::Bencher) {
  function bench_ecdsa_p256_sha256 (line 709) | fn bench_ecdsa_p256_sha256(b: &mut test::Bencher) {
  function bench_ecdsa_p384_sha384 (line 725) | fn bench_ecdsa_p384_sha384(b: &mut test::Bencher) {
  function bench_load_and_validate_rsa2048 (line 741) | fn bench_load_and_validate_rsa2048(b: &mut test::Bencher) {
  function bench_load_and_validate_rsa4096 (line 752) | fn bench_load_and_validate_rsa4096(b: &mut test::Bencher) {
  function bench_load_and_validate_p256 (line 763) | fn bench_load_and_validate_p256(b: &mut test::Bencher) {
  function bench_load_and_validate_p384 (line 774) | fn bench_load_and_validate_p384(b: &mut test::Bencher) {
  function bench_load_and_validate_eddsa (line 785) | fn bench_load_and_validate_eddsa(b: &mut test::Bencher) {
  constant SAMPLE_TLS13_MESSAGE (line 794) | const SAMPLE_TLS13_MESSAGE: &[u8] = &[

FILE: rustls-ring/src/ticketer.rs
  type AeadTicketer (line 17) | pub(super) struct AeadTicketer {
    method new (line 35) | pub(super) fn new() -> Result<Box<dyn TicketProducer>, Error> {
  method encrypt (line 59) | fn encrypt(&self, message: &[u8]) -> Option<Vec<u8>> {
  method decrypt (line 99) | fn decrypt(&self, ciphertext: &[u8]) -> Option<Vec<u8>> {
  method lifetime (line 142) | fn lifetime(&self) -> Duration {
  method fmt (line 150) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  function basic_pairwise_test (line 167) | fn basic_pairwise_test() {
  function refuses_decrypt_before_encrypt (line 175) | fn refuses_decrypt_before_encrypt() {
  function refuses_decrypt_larger_than_largest_encryption (line 181) | fn refuses_decrypt_larger_than_largest_encryption() {
  function aeadticketer_is_debug_and_producestickets (line 194) | fn aeadticketer_is_debug_and_producestickets() {

FILE: rustls-ring/src/tls12.rs
  type GcmAlgorithm (line 120) | pub(crate) struct GcmAlgorithm(&'static aead::Algorithm);
  method decrypter (line 123) | fn decrypter(&self, dec_key: AeadKey, dec_iv: &[u8]) -> Box<dyn MessageD...
  method encrypter (line 137) | fn encrypter(
  method key_block_shape (line 149) | fn key_block_shape(&self) -> KeyBlockShape {
  method extract_keys (line 157) | fn extract_keys(
  method fips (line 171) | fn fips(&self) -> FipsStatus {
  type ChaCha20Poly1305 (line 176) | pub(crate) struct ChaCha20Poly1305;
  method decrypter (line 179) | fn decrypter(&self, dec_key: AeadKey, iv: &[u8]) -> Box<dyn MessageDecry...
  method encrypter (line 189) | fn encrypter(&self, enc_key: AeadKey, enc_iv: &[u8], _: &[u8]) -> Box<dy...
  method key_block_shape (line 199) | fn key_block_shape(&self) -> KeyBlockShape {
  method extract_keys (line 207) | fn extract_keys(
  method fips (line 221) | fn fips(&self) -> FipsStatus {
  type GcmMessageEncrypter (line 227) | struct GcmMessageEncrypter {
  type GcmMessageDecrypter (line 233) | struct GcmMessageDecrypter {
  constant GCM_EXPLICIT_NONCE_LEN (line 238) | const GCM_EXPLICIT_NONCE_LEN: usize = 8;
  constant GCM_OVERHEAD (line 239) | const GCM_OVERHEAD: usize = GCM_EXPLICIT_NONCE_LEN + 16;
  method decrypt (line 242) | fn decrypt<'a>(
  method encrypt (line 283) | fn encrypt(
  method encrypted_payload_len (line 308) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  type ChaCha20Poly1305MessageEncrypter (line 316) | struct ChaCha20Poly1305MessageEncrypter {
  type ChaCha20Poly1305MessageDecrypter (line 324) | struct ChaCha20Poly1305MessageDecrypter {
  constant CHACHAPOLY1305_OVERHEAD (line 329) | const CHACHAPOLY1305_OVERHEAD: usize = 16;
  method decrypt (line 332) | fn decrypt<'a>(
  method encrypt (line 369) | fn encrypt(
  method encrypted_payload_len (line 393) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  function gcm_iv (line 398) | fn gcm_iv(write_iv: &[u8], explicit: &[u8]) -> Iv {
  constant MAX_FRAGMENT_LEN (line 416) | const MAX_FRAGMENT_LEN: usize = 16384;
  function check_sha256 (line 428) | fn check_sha256() {
  function check_sha512 (line 446) | fn check_sha512() {
  function check_sha384 (line 464) | fn check_sha384() {
  function bench_sha256 (line 490) | fn bench_sha256(b: &mut test::Bencher) {

FILE: rustls-ring/src/tls13.rs
  type Chacha20Poly1305Aead (line 78) | struct Chacha20Poly1305Aead(AeadAlgorithm);
  method encrypter (line 81) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 85) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 89) | fn key_len(&self) -> usize {
  method extract_keys (line 93) | fn extract_keys(
  method fips (line 101) | fn fips(&self) -> FipsStatus {
  type Aes256GcmAead (line 106) | struct Aes256GcmAead(AeadAlgorithm);
  method encrypter (line 109) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 113) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 117) | fn key_len(&self) -> usize {
  method extract_keys (line 121) | fn extract_keys(
  method fips (line 129) | fn fips(&self) -> FipsStatus {
  type Aes128GcmAead (line 134) | struct Aes128GcmAead(AeadAlgorithm);
  method encrypter (line 137) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 141) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 145) | fn key_len(&self) -> usize {
  method extract_keys (line 149) | fn extract_keys(
  method fips (line 157) | fn fips(&self) -> FipsStatus {
  type AeadAlgorithm (line 163) | struct AeadAlgorithm(&'static aead::Algorithm);
    method encrypter (line 166) | fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
    method decrypter (line 174) | fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
    method key_len (line 182) | fn key_len(&self) -> usize {
  type Tls13MessageEncrypter (line 187) | struct Tls13MessageEncrypter {
  type Tls13MessageDecrypter (line 192) | struct Tls13MessageDecrypter {
  method encrypt (line 198) | fn encrypt(
  method encrypted_payload_len (line 224) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  method decrypt (line 230) | fn decrypt<'a>(
  type RingHkdf (line 253) | struct RingHkdf(hkdf::Algorithm, hmac::Algorithm);
  method extract_from_zero_ikm (line 256) | fn extract_from_zero_ikm(&self, salt: Option<&[u8]>) -> Box<dyn HkdfExpa...
  method extract_from_secret (line 268) | fn extract_from_secret(&self, salt: Option<&[u8]>, secret: &[u8]) -> Box...
  method expander_for_okm (line 280) | fn expander_for_okm(&self, okm: &OkmBlock) -> Box<dyn HkdfExpander> {
  method hmac_sign (line 287) | fn hmac_sign(&self, key: &OkmBlock, message: &[u8]) -> crypto::hmac::Tag {
  method fips (line 291) | fn fips(&self) -> FipsStatus {
  type RingHkdfExpander (line 296) | struct RingHkdfExpander {
  method expand_slice (line 302) | fn expand_slice(&self, info: &[&[u8]], output: &mut [u8]) -> Result<(), ...
  method expand_block (line 309) | fn expand_block(&self, info: &[&[u8]]) -> OkmBlock {
  method hash_len (line 319) | fn hash_len(&self) -> usize {
  type Len (line 324) | struct Len(usize);
  method len (line 327) | fn len(&self) -> usize {
  type ByteArray (line 341) | struct ByteArray<const N: usize>([u8; N]);
  function from (line 344) | fn from(array: [u8; N]) -> Self {
  function test_case_1 (line 352) | fn test_case_1() {
  function test_case_2 (line 380) | fn test_case_2() {
  function test_case_3 (line 406) | fn test_case_3() {
  function test_salt_not_provided (line 429) | fn test_salt_not_provided() {
  function test_output_length_bounds (line 461) | fn test_output_length_bounds() {

FILE: rustls-ring/src/verify.rs
  type RingAlgorithm (line 27) | struct RingAlgorithm {
  method public_key_alg_id (line 34) | fn public_key_alg_id(&self) -> AlgorithmIdentifier {
  method signature_alg_id (line 38) | fn signature_alg_id(&self) -> AlgorithmIdentifier {
  method verify_signature (line 42) | fn verify_signature(

FILE: rustls-test/benches/verifybench.rs
  function reddit_cert (line 75) | fn reddit_cert(b: &mut test::Bencher) {
  function github_cert (line 88) | fn github_cert(b: &mut test::Bencher) {
  function arstechnica_cert (line 102) | fn arstechnica_cert(b: &mut test::Bencher) {
  function servo_cert (line 116) | fn servo_cert(b: &mut test::Bencher) {
  function twitter_cert (line 130) | fn twitter_cert(b: &mut test::Bencher) {
  function wikipedia_cert (line 143) | fn wikipedia_cert(b: &mut test::Bencher) {
  function google_cert (line 156) | fn google_cert(b: &mut test::Bencher) {
  function hn_cert (line 170) | fn hn_cert(b: &mut test::Bencher) {
  function stackoverflow_cert (line 183) | fn stackoverflow_cert(b: &mut test::Bencher) {
  function duckduckgo_cert (line 196) | fn duckduckgo_cert(b: &mut test::Bencher) {
  function rustlang_cert (line 210) | fn rustlang_cert(b: &mut test::Bencher) {
  function wapo_cert (line 223) | fn wapo_cert(b: &mut test::Bencher) {
  type Context (line 236) | struct Context {
    method new (line 244) | fn new(provider: &CryptoProvider, domain: &'static str, certs: &[&'sta...
    method verify_once (line 266) | fn verify_once(&self) {

FILE: rustls-test/src/lib.rs
  function transfer (line 203) | pub fn transfer(left: &mut impl Connection, right: &mut impl Connection)...
  function transfer_eof (line 230) | pub fn transfer_eof(conn: &mut impl Connection) {
  type Altered (line 237) | pub enum Altered {
  function transfer_altered (line 244) | pub fn transfer_altered<F>(
  type KeyType (line 310) | pub enum KeyType {
    method all_for_provider (line 340) | pub fn all_for_provider(provider: &CryptoProvider) -> &'static [Self] {
    method bytes_for (line 351) | fn bytes_for(&self, part: &str) -> &'static [u8] {
    method identity (line 363) | pub fn identity(&self) -> Arc<Identity<'static>> {
    method spki (line 374) | pub fn spki(&self) -> SubjectPublicKeyInfoDer<'static> {
    method load_key (line 378) | pub fn load_key(&self, provider: &CryptoProvider) -> Box<dyn SigningKe...
    method key (line 385) | pub fn key(&self) -> PrivateKeyDer<'static> {
    method client_identity (line 391) | pub fn client_identity(&self) -> Arc<Identity<'static>> {
    method end_entity_crl (line 402) | pub fn end_entity_crl(&self) -> CertificateRevocationListDer<'static> {
    method client_crl (line 406) | pub fn client_crl(&self) -> CertificateRevocationListDer<'static> {
    method intermediate_crl (line 410) | pub fn intermediate_crl(&self) -> CertificateRevocationListDer<'static> {
    method end_entity_crl_expired (line 414) | pub fn end_entity_crl_expired(&self) -> CertificateRevocationListDer<'...
    method client_key (line 418) | pub fn client_key(&self) -> PrivateKeyDer<'static> {
    method client_spki (line 424) | pub fn client_spki(&self) -> SubjectPublicKeyInfoDer<'static> {
    method certified_client_key (line 428) | pub fn certified_client_key(&self, provider: &CryptoProvider) -> Resul...
    method credentials_with_raw_pub_key (line 442) | pub fn credentials_with_raw_pub_key(
    method credentials_with_cert_chain (line 459) | pub fn credentials_with_cert_chain(
    method crl (line 469) | fn crl(&self, role: &str, r#type: &str) -> CertificateRevocationListDe...
    method ca_distinguished_name (line 476) | pub fn ca_distinguished_name(&self) -> DistinguishedName {
    method client_root_store (line 490) | pub fn client_root_store(&self) -> Arc<RootCertStore> {
    method ca_cert (line 496) | pub fn ca_cert(&self) -> CertificateDer<'_> {
  type ServerConfigExt (line 509) | pub trait ServerConfigExt {
    method finish (line 510) | fn finish(self, kt: KeyType) -> ServerConfig;
    method finish (line 514) | fn finish(self, kt: KeyType) -> ServerConfig {
  function make_server_config (line 521) | pub fn make_server_config(kt: KeyType, provider: &CryptoProvider) -> Ser...
  function make_server_config_with_kx_groups (line 525) | pub fn make_server_config_with_kx_groups(
  function make_server_config_with_mandatory_client_auth_crls (line 540) | pub fn make_server_config_with_mandatory_client_auth_crls(
  function make_server_config_with_mandatory_client_auth (line 552) | pub fn make_server_config_with_mandatory_client_auth(
  function make_server_config_with_optional_client_auth (line 563) | pub fn make_server_config_with_optional_client_auth(
  function make_server_config_with_client_verifier (line 578) | pub fn make_server_config_with_client_verifier(
  function make_server_config_with_raw_key_support (line 589) | pub fn make_server_config_with_raw_key_support(
  function make_client_config_with_raw_key_support (line 607) | pub fn make_client_config_with_raw_key_support(
  type ClientConfigExt (line 624) | pub trait ClientConfigExt {
    method finish (line 625) | fn finish(self, kt: KeyType) -> ClientConfig;
    method finish_with_creds (line 626) | fn finish_with_creds(self, kt: KeyType) -> ClientConfig;
    method add_root_certs (line 627) | fn add_root_certs(self, kt: KeyType) -> ConfigBuilder<ClientConfig, Wa...
    method finish (line 631) | fn finish(self, kt: KeyType) -> ClientConfig {
    method finish_with_creds (line 637) | fn finish_with_creds(self, kt: KeyType) -> ClientConfig {
    method add_root_certs (line 643) | fn add_root_certs(self, kt: KeyType) -> ConfigBuilder<ClientConfig, Wa...
  function make_client_config (line 653) | pub fn make_client_config(kt: KeyType, provider: &CryptoProvider) -> Cli...
  function make_client_config_with_kx_groups (line 657) | pub fn make_client_config_with_kx_groups(
  function make_client_config_with_auth (line 672) | pub fn make_client_config_with_auth(kt: KeyType, provider: &CryptoProvid...
  function make_client_config_with_verifier (line 676) | pub fn make_client_config_with_verifier(
  function webpki_client_verifier_builder (line 687) | pub fn webpki_client_verifier_builder(
  function webpki_server_verifier_builder (line 694) | pub fn webpki_server_verifier_builder(
  function make_pair (line 701) | pub fn make_pair(kt: KeyType, provider: &CryptoProvider) -> (ClientConne...
  function make_pair_for_configs (line 708) | pub fn make_pair_for_configs(
  function make_pair_for_arc_configs (line 715) | pub fn make_pair_for_arc_configs(
  function make_disjoint_suite_configs (line 729) | pub fn make_disjoint_suite_configs(provider: CryptoProvider) -> (ClientC...
  function do_handshake (line 756) | pub fn do_handshake(client: &mut impl Connection, server: &mut impl Conn...
  type ErrorFromPeer (line 768) | pub enum ErrorFromPeer {
  function do_handshake_until_error (line 773) | pub fn do_handshake_until_error(
  function do_handshake_altered (line 791) | pub fn do_handshake_altered(
  function do_handshake_until_both_error (line 814) | pub fn do_handshake_until_both_error(
  function server_name (line 845) | pub fn server_name(name: &'static str) -> ServerName<'static> {
  type TestNonBlockIo (line 858) | pub struct TestNonBlockIo {
    method read (line 876) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
    method write (line 890) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
    method flush (line 897) | fn flush(&mut self) -> io::Result<()> {
  method drop (line 903) | fn drop(&mut self) {
  function do_suite_and_kx_test (line 910) | pub fn do_suite_and_kx_test(
  type MockServerVerifier (line 1027) | pub struct MockServerVerifier {
    method accepts_anything (line 1096) | pub fn accepts_anything() -> Self {
    method expects_ocsp_response (line 1103) | pub fn expects_ocsp_response(response: &[u8]) -> Self {
    method rejects_certificate (line 1110) | pub fn rejects_certificate(err: Error) -> Self {
    method rejects_tls12_signatures (line 1117) | pub fn rejects_tls12_signatures(err: Error) -> Self {
    method rejects_tls13_signatures (line 1124) | pub fn rejects_tls13_signatures(err: Error) -> Self {
    method offers_no_signature_schemes (line 1131) | pub fn offers_no_signature_schemes() -> Self {
    method expects_raw_public_keys (line 1138) | pub fn expects_raw_public_keys(provider: &CryptoProvider) -> Self {
  method verify_identity (line 1038) | fn verify_identity(&self, identity: &ServerIdentity<'_>) -> Result<PeerV...
  method verify_tls12_signature (line 1049) | fn verify_tls12_signature(
  method verify_tls13_signature (line 1060) | fn verify_tls13_signature(
  method supported_verify_schemes (line 1077) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method request_ocsp_response (line 1081) | fn request_ocsp_response(&self) -> bool {
  method supported_certificate_types (line 1085) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  method hash_config (line 1092) | fn hash_config(&self, _: &mut dyn Hasher) {}
  method default (line 1148) | fn default() -> Self {
  type MockClientVerifier (line 1169) | pub struct MockClientVerifier {
    method new (line 1180) | pub fn new(
  method verify_identity (line 1202) | fn verify_identity(&self, _identity: &ClientIdentity<'_>) -> Result<Peer...
  method verify_tls12_signature (line 1206) | fn verify_tls12_signature(
  method verify_tls13_signature (line 1218) | fn verify_tls13_signature(
  method root_hint_subjects (line 1235) | fn root_hint_subjects(&self) -> Arc<[DistinguishedName]> {
  method client_auth_mandatory (line 1239) | fn client_auth_mandatory(&self) -> bool {
  method supported_verify_schemes (line 1243) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method supported_certificate_types (line 1251) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  type RawTls (line 1263) | pub struct RawTls {
    method new_client (line 1272) | pub fn new_client(conn: ClientConnection) -> Self {
    method new_server (line 1282) | pub fn new_server(conn: ServerConnection) -> Self {
    method new (line 1291) | fn new(suite: SupportedCipherSuite, secrets: rustls::ExtractedSecrets)...
    method encrypt_and_send (line 1345) | pub fn encrypt_and_send(
    method receive_and_decrypt (line 1360) | pub fn receive_and_decrypt(
  function aes_128_gcm_with_1024_confidentiality_limit (line 1395) | pub fn aes_128_gcm_with_1024_confidentiality_limit(
  function unsafe_plaintext_crypto_provider (line 1444) | pub fn unsafe_plaintext_crypto_provider(provider: CryptoProvider) -> Arc...
  type ServerCheckCertResolve (line 1469) | pub struct ServerCheckCertResolve {
  method resolve (line 1480) | fn resolve(&self, client_hello: &ClientHello<'_>) -> Result<SelectedCred...
  type OtherSession (line 1560) | pub struct OtherSession<'a, C: Connection> {
  function new (line 1573) | pub fn new(sess: &'a mut C) -> Self {
  function new_buffered (line 1586) | pub fn new_buffered(sess: &'a mut C) -> Self {
  function new_fails (line 1592) | pub fn new_fails(sess: &'a mut C) -> Self {
  function flush_vectored (line 1598) | fn flush_vectored(&mut self, b: &[io::IoSlice<'_>]) -> io::Result<usize> {
  function writev_lengths (line 1633) | pub fn writev_lengths(&self) -> Vec<Vec<usize>> {
  function message_lengths (line 1645) | pub fn message_lengths(&self) -> Vec<usize> {
  function read (line 1673) | fn read(&mut self, mut b: &mut [u8]) -> io::Result<usize> {
  function write (line 1680) | fn write(&mut self, _: &[u8]) -> io::Result<usize> {
  function flush (line 1684) | fn flush(&mut self) -> io::Result<()> {
  function write_vectored (line 1696) | fn write_vectored(&mut self, b: &[io::IoSlice<'_>]) -> io::Result<usize> {
  function check_read (line 1708) | pub fn check_read(reader: &mut dyn io::Read, bytes: &[u8]) {
  function check_read_and_close (line 1716) | pub fn check_read_and_close(reader: &mut dyn io::Read, expect: &[u8]) {
  function check_read_err (line 1723) | pub fn check_read_err(reader: &mut dyn io::Read, err_kind: io::ErrorKind) {
  function check_fill_buf (line 1731) | pub fn check_fill_buf(reader: &mut dyn io::BufRead, bytes: &[u8]) {
  function check_fill_buf_err (line 1740) | pub fn check_fill_buf_err(reader: &mut dyn io::BufRead, err_kind: io::Er...
  function certificate_error_expecting_name (line 1745) | pub fn certificate_error_expecting_name(expected: &str) -> CertificateEr...
  type Aead (line 1770) | pub(super) struct Aead;
  method encrypter (line 1773) | fn encrypter(&self, _key: AeadKey, _iv: Iv) -> Box<dyn MessageEncrypter> {
  method decrypter (line 1777) | fn decrypter(&self, _key: AeadKey, _iv: Iv) -> Box<dyn MessageDecrypter> {
  method key_len (line 1781) | fn key_len(&self) -> usize {
  method extract_keys (line 1785) | fn extract_keys(
  type Encrypter (line 1794) | struct Encrypter;
  method encrypt (line 1797) | fn encrypt(
  method encrypted_payload_len (line 1812) | fn encrypted_payload_len(&self, payload_len: usize) -> usize {
  type Decrypter (line 1817) | struct Decrypter;
  method decrypt (line 1820) | fn decrypt<'a>(
  type ClientStorageOp (line 1832) | pub enum ClientStorageOp {
  type ClientStorage (line 1842) | pub struct ClientStorage {
    method new (line 1849) | pub fn new() -> Self {
    method alter_max_early_data_size (line 1857) | pub fn alter_max_early_data_size(&mut self, expected: u32, altered: u3...
    method ops (line 1861) | pub fn ops(&self) -> Vec<ClientStorageOp> {
    method ops_and_reset (line 1865) | pub fn ops_and_reset(&self) -> Vec<ClientStorageOp> {
    method fmt (line 1871) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method set_kx_hint (line 1877) | fn set_kx_hint(&self, key: ClientSessionKey<'static>, group: NamedGrou...
    method kx_hint (line 1885) | fn kx_hint(&self, key: &ClientSessionKey<'_>) -> Option<NamedGroup> {
    method set_tls12_session (line 1894) | fn set_tls12_session(
    method tls12_session (line 1907) | fn tls12_session(&self, key: &ClientSessionKey<'_>) -> Option<rustls::...
    method remove_tls12_session (line 1919) | fn remove_tls12_session(&self, key: &ClientSessionKey<'static>) {
    method insert_tls13_ticket (line 1927) | fn insert_tls13_ticket(&self, key: ClientSessionKey<'static>, mut valu...
    method take_tls13_ticket (line 1940) | fn take_tls13_ticket(&self, key: &ClientSessionKey<'static>) -> Option...
  function provider_with_one_suite (line 1950) | pub fn provider_with_one_suite(
  function provider_with_suites (line 1957) | pub fn provider_with_suites(
  function basic_client_hello (line 2054) | pub fn basic_client_hello(mut extensions: Vec<Extension>) -> Vec<u8> {
  function client_hello_with_extensions (line 2065) | pub fn client_hello_with_extensions(extensions: Vec<Extension>) -> Vec<u...
  function client_hello (line 2078) | pub fn client_hello(
  function handshake_framing (line 2111) | pub fn handshake_framing(ty: HandshakeType, body: Vec<u8>) -> Vec<u8> {
  function message_framing (line 2118) | pub fn message_framing(ty: ContentType, vers: ProtocolVersion, body: Vec...
  type Extension (line 2126) | pub struct Extension {
    method new_sig_algs (line 2132) | pub fn new_sig_algs() -> Self {
    method new_kx_groups (line 2145) | pub fn new_kx_groups() -> Self {
    method new_versions (line 2152) | pub fn new_versions() -> Self {
    method new_dummy_key_share (line 2161) | pub fn new_dummy_key_share() -> Self {
    method new_quic_transport_params (line 2178) | pub fn new_quic_transport_params(body: &[u8]) -> Self {
    constant ELLIPTIC_CURVES (line 2185) | pub const ELLIPTIC_CURVES: u16 = 0x000a;
    constant SIGNATURE_ALGORITHMS (line 2186) | pub const SIGNATURE_ALGORITHMS: u16 = 0x000d;
    constant SUPPORTED_VERSIONS (line 2187) | pub const SUPPORTED_VERSIONS: u16 = 0x002b;
    constant KEY_SHARE (line 2188) | pub const KEY_SHARE: u16 = 0x0033;
    constant TRANSPORT_PARAMETERS (line 2189) | pub const TRANSPORT_PARAMETERS: u16 = 0x0039;
  function alert (line 2193) | pub fn alert(desc: AlertDescription, suffix: &[u8]) -> Vec<u8> {
  function warning_alert (line 2200) | pub fn warning_alert(desc: AlertDescription) -> Vec<u8> {
  function len_u8 (line 2209) | pub fn len_u8(mut body: Vec<u8>) -> Vec<u8> {
  function len_u16 (line 2215) | pub fn len_u16(mut body: Vec<u8>) -> Vec<u8> {
  function len_u24 (line 2221) | pub fn len_u24(mut body: Vec<u8>) -> Vec<u8> {
  function vector_of (line 2230) | pub fn vector_of<const N: usize>(items: impl IntoIterator<Item = [u8; N]...
  constant ALERT_LEVEL_WARNING (line 2234) | const ALERT_LEVEL_WARNING: u8 = 1;
  constant ALERT_LEVEL_FATAL (line 2235) | const ALERT_LEVEL_FATAL: u8 = 2;

FILE: rustls-test/tests/api.rs
  type CountingLogger (line 75) | struct CountingLogger;
    method install (line 82) | fn install() {
    method reset (line 87) | fn reset() {
    method enabled (line 95) | fn enabled(&self, _metadata: &log::Metadata<'_>) -> bool {
    method log (line 99) | fn log(&self, record: &log::Record<'_>) {
    method flush (line 108) | fn flush(&self) {}
  type LogCounts (line 112) | struct LogCounts {
    method new (line 121) | fn new() -> Self {
    method reset (line 127) | fn reset(&mut self) {
    method add (line 131) | fn add(&mut self, level: log::Level, message: String) {

FILE: rustls-test/tests/api/api.rs
  function alpn_test_error (line 47) | fn alpn_test_error(
  function alpn_test (line 76) | fn alpn_test(
  function alpn (line 85) | fn alpn() {
  function connection_level_alpn_protocols (line 120) | fn connection_level_alpn_protocols() {
  function version_test (line 151) | fn version_test(
  function apply_versions (line 179) | fn apply_versions(provider: CryptoProvider, versions: &[ProtocolVersion]...
  function versions (line 197) | fn versions() {
  function config_builder_for_client_rejects_empty_kx_groups (line 245) | fn config_builder_for_client_rejects_empty_kx_groups() {
  function config_builder_for_client_rejects_empty_cipher_suites (line 262) | fn config_builder_for_client_rejects_empty_cipher_suites() {
  function config_builder_for_server_rejects_empty_kx_groups (line 280) | fn config_builder_for_server_rejects_empty_kx_groups() {
  function config_builder_for_server_rejects_empty_cipher_suites (line 297) | fn config_builder_for_server_rejects_empty_cipher_suites() {
  function config_builder_for_client_with_time (line 315) | fn config_builder_for_client_with_time() {
  function config_builder_for_server_with_time (line 323) | fn config_builder_for_server_with_time() {
  function client_can_get_server_cert (line 331) | fn client_can_get_server_cert() {
  function client_can_get_server_cert_after_resumption (line 345) | fn client_can_get_server_cert_after_resumption() {
  function server_can_get_client_cert (line 371) | fn server_can_get_client_cert() {
  function server_can_get_client_cert_after_resumption (line 389) | fn server_can_get_client_cert_after_resumption() {
  function test_config_builders_debug (line 414) | fn test_config_builders_debug() {
  function test_tls13_valid_early_plaintext_alert (line 447) | fn test_tls13_valid_early_plaintext_alert() {
  function test_tls13_too_short_early_plaintext_alert (line 475) | fn test_tls13_too_short_early_plaintext_alert() {
  function test_tls13_late_plaintext_alert (line 497) | fn test_tls13_late_plaintext_alert() {
  function client_error_is_sticky (line 517) | fn client_error_is_sticky() {
  function server_error_is_sticky (line 531) | fn server_error_is_sticky() {
  function server_is_send_and_sync (line 546) | fn server_is_send_and_sync() {
  function client_is_send_and_sync (line 554) | fn client_is_send_and_sync() {
  function server_config_is_clone (line 561) | fn server_config_is_clone() {
  function client_config_is_clone (line 566) | fn client_config_is_clone() {
  function client_connection_is_debug (line 571) | fn client_connection_is_debug() {
  function server_connection_is_debug (line 577) | fn server_connection_is_debug() {
  function server_exposes_offered_sni (line 583) | fn server_exposes_offered_sni() {
  function server_exposes_offered_sni_smashed_to_lowercase (line 606) | fn server_exposes_offered_sni_smashed_to_lowercase() {
  function test_keys_match (line 630) | fn test_keys_match() {
  type SigningKeyNoneSpki (line 649) | struct SigningKeyNoneSpki;
  method choose_scheme (line 652) | fn choose_scheme(&self, _offered: &[SignatureScheme]) -> Option<Box<dyn ...
  method public_key (line 656) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  type SigningKeySomeSpki (line 663) | struct SigningKeySomeSpki;
  method public_key (line 666) | fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
  method choose_scheme (line 678) | fn choose_scheme(&self, _offered: &[SignatureScheme]) -> Option<Box<dyn ...
  function do_exporter_test (line 683) | fn do_exporter_test(
  function test_tls12_exporter (line 743) | fn test_tls12_exporter() {
  function test_tls13_exporter (line 766) | fn test_tls13_exporter() {
  function test_tls13_exporter_maximum_output_length (line 777) | fn test_tls13_exporter_maximum_output_length() {
  function find_suite (line 828) | fn find_suite(suite: CipherSuite) -> SupportedCipherSuite {
  function test_ciphersuites (line 846) | fn test_ciphersuites() -> Vec<(ProtocolVersion, KeyType, CipherSuite)> {
  function negotiated_ciphersuite_default (line 904) | fn negotiated_ciphersuite_default() {
  function all_suites_covered (line 918) | fn all_suites_covered() {
  function negotiated_ciphersuite_client (line 926) | fn negotiated_ciphersuite_client() {
  function negotiated_ciphersuite_server (line 944) | fn negotiated_ciphersuite_server() {
  function negotiated_ciphersuite_server_ignoring_client_preference (line 962) | fn negotiated_ciphersuite_server_ignoring_client_preference() {
  function expected_kx_for_version (line 1000) | fn expected_kx_for_version(version: ProtocolVersion) -> NamedGroup {
  function assert_lt (line 1012) | fn assert_lt(left: usize, right: usize) {
  function connection_types_are_not_huge (line 1019) | fn connection_types_are_not_huge() {
  function test_client_rejects_illegal_tls13_ccs (line 1026) | fn test_client_rejects_illegal_tls13_ccs() {
  function test_no_warning_logging_during_successful_sessions (line 1053) | fn test_no_warning_logging_during_successful_sessions() {
  function test_explicit_provider_selection (line 1090) | fn test_explicit_provider_selection() {
  type FaultyRandom (line 1102) | struct FaultyRandom {
    method fill (line 1108) | fn fill(&self, output: &mut [u8]) -> Result<(), rustls::crypto::GetRan...
  function test_client_construction_fails_if_random_source_fails_in_first_request (line 1129) | fn test_client_construction_fails_if_random_source_fails_in_first_reques...
  function test_client_construction_fails_if_random_source_fails_in_second_request (line 1153) | fn test_client_construction_fails_if_random_source_fails_in_second_reque...
  function test_client_construction_requires_66_bytes_of_random_material (line 1177) | fn test_client_construction_requires_66_bytes_of_random_material() {
  function test_client_removes_tls12_session_if_server_sends_undecryptable_first_message (line 1201) | fn test_client_removes_tls12_session_if_server_sends_undecryptable_first...
  function test_client_fips_service_indicator (line 1260) | fn test_client_fips_service_indicator() {
  function test_server_fips_service_indicator (line 1268) | fn test_server_fips_service_indicator() {
  function test_connection_fips_service_indicator (line 1276) | fn test_connection_fips_service_indicator() {
  function test_client_fips_service_indicator_includes_require_ems (line 1288) | fn test_client_fips_service_indicator_includes_require_ems() {
  function test_server_fips_service_indicator_includes_require_ems (line 1306) | fn test_server_fips_service_indicator_includes_require_ems() {
  function test_client_fips_service_indicator_includes_ech_hpke_suite (line 1325) | fn test_client_fips_service_indicator_includes_ech_hpke_suite() {
  function test_illegal_server_renegotiation_attempt_after_tls13_handshake (line 1371) | fn test_illegal_server_renegotiation_attempt_after_tls13_handshake() {
  function test_illegal_server_renegotiation_attempt_after_tls12_handshake (line 1404) | fn test_illegal_server_renegotiation_attempt_after_tls12_handshake() {
  function test_illegal_client_renegotiation_attempt_after_tls13_handshake (line 1444) | fn test_illegal_client_renegotiation_attempt_after_tls13_handshake() {
  function test_illegal_client_renegotiation_attempt_during_tls12_handshake (line 1471) | fn test_illegal_client_renegotiation_attempt_during_tls12_handshake() {
  function tls13_packed_handshake (line 1500) | fn tls13_packed_handshake() {
  function large_client_hello (line 1550) | fn large_client_hello() {
  function large_client_hello_acceptor (line 1563) | fn large_client_hello_acceptor() {
  function acceptor_with_illegal_max_fragment_size (line 1578) | fn acceptor_with_illegal_max_fragment_size() {
  function excess_client_hello_acceptor (line 1611) | fn excess_client_hello_acceptor() {
  function server_invalid_sni_policy (line 1633) | fn server_invalid_sni_policy() {
  type ServerCheckSni (line 1715) | struct ServerCheckSni {
  method resolve (line 1720) | fn resolve(&self, client_hello: &ClientHello<'_>) -> Result<SelectedCred...

FILE: rustls-test/tests/api/client_cert_verifier.rs
  function ver_ok (line 21) | fn ver_ok() -> Result<PeerVerified, Error> {
  function ver_unreachable (line 26) | fn ver_unreachable() -> Result<PeerVerified, Error> {
  function ver_err (line 31) | fn ver_err() -> Result<PeerVerified, Error> {
  function server_config_with_verifier (line 35) | fn server_config_with_verifier(
  function client_verifier_works (line 47) | fn client_verifier_works() {
  function client_verifier_no_schemes (line 66) | fn client_verifier_no_schemes() {
  function client_verifier_no_auth_yes_root (line 91) | fn client_verifier_no_auth_yes_root() {
  function client_verifier_fails_properly (line 125) | fn client_verifier_fails_properly() {
  function server_allow_any_anonymous_or_authenticated_client (line 153) | fn server_allow_any_anonymous_or_authenticated_client() {
  function client_auth_works (line 185) | fn client_auth_works() {
  function client_mandatory_auth_client_revocation_works (line 202) | fn client_mandatory_auth_client_revocation_works() {
  function client_mandatory_auth_intermediate_revocation_works (line 275) | fn client_mandatory_auth_intermediate_revocation_works() {
  function client_optional_auth_client_revocation_works (line 327) | fn client_optional_auth_client_revocation_works() {

FILE: rustls-test/tests/api/compress.rs
  function test_server_uses_cached_compressed_certificates (line 31) | fn test_server_uses_cached_compressed_certificates() {
  function test_server_uses_uncompressed_certificate_if_compression_fails (line 72) | fn test_server_uses_uncompressed_certificate_if_compression_fails() {
  function test_client_uses_uncompressed_certificate_if_compression_fails (line 84) | fn test_client_uses_uncompressed_certificate_if_compression_fails() {
  type FailingCompressor (line 97) | struct FailingCompressor;
    method compress (line 100) | fn compress(
    method algorithm (line 109) | fn algorithm(&self) -> CertificateCompressionAlgorithm {
  type NeverDecompressor (line 115) | struct NeverDecompressor;
    method decompress (line 118) | fn decompress(
    method algorithm (line 126) | fn algorithm(&self) -> CertificateCompressionAlgorithm {
  function test_server_can_opt_out_of_compression_cache (line 133) | fn test_server_can_opt_out_of_compression_cache() {
  function test_cert_decompression_by_client_produces_invalid_cert_payload (line 176) | fn test_cert_decompression_by_client_produces_invalid_cert_payload() {
  function test_cert_decompression_by_server_produces_invalid_cert_payload (line 198) | fn test_cert_decompression_by_server_produces_invalid_cert_payload() {
  function test_cert_decompression_by_server_fails (line 221) | fn test_cert_decompression_by_server_fails() {
  function test_cert_decompression_by_server_would_result_in_excessively_large_cert (line 245) | fn test_cert_decompression_by_server_would_result_in_excessively_large_c...
  type GarbageDecompressor (line 278) | struct GarbageDecompressor;
    method decompress (line 281) | fn decompress(
    method algorithm (line 290) | fn algorithm(&self) -> CertificateCompressionAlgorithm {
  type FailingDecompressor (line 296) | struct FailingDecompressor;
    method decompress (line 299) | fn decompress(
    method algorithm (line 307) | fn algorithm(&self) -> CertificateCompressionAlgorithm {
  type IdentityCompressor (line 313) | struct IdentityCompressor;
    method compress (line 316) | fn compress(
    method algorithm (line 324) | fn algorithm(&self) -> CertificateCompressionAlgorithm {

FILE: rustls-test/tests/api/crypto.rs
  function key_log_for_tls12 (line 24) | fn key_log_for_tls12() {
  function key_log_for_tls13 (line 61) | fn key_log_for_tls13() {
  type KeyLogToVec (line 136) | struct KeyLogToVec {
    method new (line 142) | fn new(who: &'static str) -> Self {
    method take (line 149) | fn take(&self) -> Vec<KeyLogItem> {
  method log (line 155) | fn log(&self, label: &str, client: &[u8], secret: &[u8]) {
  type KeyLogItem (line 169) | struct KeyLogItem {
  function test_secret_extraction_enabled (line 177) | fn test_secret_extraction_enabled() {
  function test_secret_extract_produces_correct_variant (line 254) | fn test_secret_extract_produces_correct_variant() {
  function test_secret_extraction_disabled_or_too_early (line 317) | fn test_secret_extraction_disabled_or_too_early() {
  function test_refresh_traffic_keys_during_handshake (line 370) | fn test_refresh_traffic_keys_during_handshake() {
  function test_refresh_traffic_keys (line 387) | fn test_refresh_traffic_keys() {
  function test_automatic_refresh_traffic_keys (line 422) | fn test_automatic_refresh_traffic_keys() {
  function tls12_connection_fails_after_key_reaches_confidentiality_limit (line 484) | fn tls12_connection_fails_after_key_reaches_confidentiality_limit() {
  function test_keys_match_for_all_signing_key_types (line 523) | fn test_keys_match_for_all_signing_key_types() {
  constant CONFIDENTIALITY_LIMIT (line 535) | const CONFIDENTIALITY_LIMIT: u64 = 1024;

FILE: rustls-test/tests/api/ffdhe.rs
  function config_builder_for_client_rejects_cipher_suites_without_compatible_kx_groups (line 25) | fn config_builder_for_client_rejects_cipher_suites_without_compatible_kx...
  function ffdhe_ciphersuite (line 50) | fn ffdhe_ciphersuite() {
  function server_avoids_dhe_cipher_suites_when_client_has_no_known_dhe_in_groups_ext (line 82) | fn server_avoids_dhe_cipher_suites_when_client_has_no_known_dhe_in_group...
  function server_avoids_cipher_suite_with_no_common_kx_groups (line 129) | fn server_avoids_cipher_suite_with_no_common_kx_groups() {
  function non_ffdhe_kx_does_not_have_ffdhe_group (line 255) | fn non_ffdhe_kx_does_not_have_ffdhe_group() {
  function ffdhe_provider (line 263) | fn ffdhe_provider() -> CryptoProvider {
  constant FFDHE2048_KX_GROUP (line 276) | const FFDHE2048_KX_GROUP: FfdheKxGroup = FfdheKxGroup(NamedGroup::FFDHE2...
  constant FFDHE3072_KX_GROUP (line 277) | const FFDHE3072_KX_GROUP: FfdheKxGroup = FfdheKxGroup(NamedGroup::FFDHE3...
  constant FFDHE4096_KX_GROUP (line 278) | const FFDHE4096_KX_GROUP: FfdheKxGroup = FfdheKxGroup(NamedGroup::FFDHE4...
  type FfdheKxGroup (line 291) | struct FfdheKxGroup(pub NamedGroup, pub FfdheGroup<'static>);
  method start (line 294) | fn start(&self) -> Result<StartedKeyExchange, rustls::Error> {
  method ffdhe_group (line 316) | fn ffdhe_group(&self) -> Option<FfdheGroup<'static>> {
  method name (line 320) | fn name(&self) -> NamedGroup {
  type ActiveFfdheKx (line 325) | struct ActiveFfdheKx {
  method complete (line 334) | fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret...
  method pub_key (line 342) | fn pub_key(&self) -> &[u8] {
  method ffdhe_group (line 346) | fn ffdhe_group(&self) -> Option<FfdheGroup<'static>> {
  method group (line 350) | fn group(&self) -> NamedGroup {
  function to_bytes_be_with_len (line 355) | fn to_bytes_be_with_len(n: BigUint, len_bytes: usize) -> Vec<u8> {

FILE: rustls-test/tests/api/io.rs
  function buffered_client_data_sent (line 30) | fn buffered_client_data_sent() {
  function buffered_server_data_sent (line 53) | fn buffered_server_data_sent() {
  function buffered_both_data_sent (line 76) | fn buffered_both_data_sent() {
  function server_respects_buffer_limit_pre_handshake (line 115) | fn server_respects_buffer_limit_pre_handshake() {
  function server_respects_buffer_limit_pre_handshake_with_vectored_write (line 143) | fn server_respects_buffer_limit_pre_handshake_with_vectored_write() {
  function server_respects_buffer_limit_post_handshake (line 167) | fn server_respects_buffer_limit_post_handshake() {
  function client_respects_buffer_limit_pre_handshake (line 196) | fn client_respects_buffer_limit_pre_handshake() {
  function client_respects_buffer_limit_pre_handshake_with_vectored_write (line 224) | fn client_respects_buffer_limit_pre_handshake_with_vectored_write() {
  function client_respects_buffer_limit_post_handshake (line 248) | fn client_respects_buffer_limit_post_handshake() {
  function client_detects_broken_write_vectored_impl (line 276) | fn client_detects_broken_write_vectored_impl() {
  function buf_read (line 305) | fn buf_read() {
  function server_read_returns_wouldblock_when_no_data (line 338) | fn server_read_returns_wouldblock_when_no_data() {
  function client_read_returns_wouldblock_when_no_data (line 345) | fn client_read_returns_wouldblock_when_no_data() {
  function server_fill_buf_returns_wouldblock_when_no_data (line 352) | fn server_fill_buf_returns_wouldblock_when_no_data() {
  function client_fill_buf_returns_wouldblock_when_no_data (line 359) | fn client_fill_buf_returns_wouldblock_when_no_data() {
  function new_server_returns_initial_io_state (line 366) | fn new_server_returns_initial_io_state() {
  function new_client_returns_initial_io_state (line 376) | fn new_client_returns_initial_io_state() {
  function client_complete_io_for_handshake (line 386) | fn client_complete_io_for_handshake() {
  function buffered_client_complete_io_for_handshake (line 397) | fn buffered_client_complete_io_for_handshake() {
  function client_complete_io_for_handshake_eof (line 409) | fn client_complete_io_for_handshake_eof() {
  function client_complete_io_for_write (line 419) | fn client_complete_io_for_write() {
  function client_complete_io_with_nonblocking_io (line 449) | fn client_complete_io_with_nonblocking_io() {
  function buffered_client_complete_io_for_write (line 554) | fn buffered_client_complete_io_for_write() {
  function client_complete_io_for_read (line 584) | fn client_complete_io_for_read() {
  function server_complete_io_for_handshake (line 606) | fn server_complete_io_for_handshake() {
  function server_complete_io_for_handshake_eof (line 620) | fn server_complete_io_for_handshake_eof() {
  function server_complete_io_for_write (line 630) | fn server_complete_io_for_write() {
  function server_complete_io_for_write_eof (line 659) | fn server_complete_io_for_write_eof() {
  type EofWriter (line 689) | struct EofWriter<const N: usize> {
  method write (line 694) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  method flush (line 700) | fn flush(&mut self) -> io::Result<()> {
  method read (line 706) | fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
  function server_complete_io_for_read (line 712) | fn server_complete_io_for_read() {
  function server_complete_io_for_handshake_ending_with_alert (line 734) | fn server_complete_io_for_handshake_ending_with_alert() {
  function client_stream_write (line 752) | fn client_stream_write() {
  function server_stream_write (line 758) | fn server_stream_write() {
  type StreamKind (line 764) | enum StreamKind {
  function test_client_stream_write (line 769) | fn test_client_stream_write(stream_kind: StreamKind) {
  function test_server_stream_write (line 786) | fn test_server_stream_write(stream_kind: StreamKind) {
  function client_stream_read (line 804) | fn client_stream_read() {
  function server_stream_read (line 812) | fn server_stream_read() {
  type ReadKind (line 820) | enum ReadKind {
  function test_stream_read (line 825) | fn test_stream_read(read_kind: ReadKind, mut stream: impl BufRead, data:...
  function test_client_stream_read (line 838) | fn test_client_stream_read(stream_kind: StreamKind, read_kind: ReadKind) {
  function test_server_stream_read (line 859) | fn test_server_stream_read(stream_kind: StreamKind, read_kind: ReadKind) {
  function test_client_write_and_vectored_write_equivalence (line 881) | fn test_client_write_and_vectored_write_equivalence() {
  type FailsWrites (line 907) | struct FailsWrites {
  method read (line 913) | fn read(&mut self, _b: &mut [u8]) -> io::Result<usize> {
  method write (line 919) | fn write(&mut self, b: &[u8]) -> io::Result<usize> {
  method flush (line 928) | fn flush(&mut self) -> io::Result<()> {
  function stream_write_reports_underlying_io_error_before_plaintext_processed (line 934) | fn stream_write_reports_underlying_io_error_before_plaintext_processed() {
  function stream_write_swallows_underlying_io_error_after_plaintext_processed (line 954) | fn stream_write_swallows_underlying_io_error_after_plaintext_processed() {
  function client_stream_handshake_error (line 972) | fn client_stream_handshake_error() {
  function client_streamowned_handshake_error (line 995) | fn client_streamowned_handshake_error() {
  function server_stream_handshake_error (line 1018) | fn server_stream_handshake_error() {
  function server_streamowned_handshake_error (line 1041) | fn server_streamowned_handshake_error() {
  function vectored_write_for_server_appdata (line 1062) | fn vectored_write_for_server_appdata() {
  function vectored_write_for_client_appdata (line 1087) | fn vectored_write_for_client_appdata() {
  function vectored_write_for_server_handshake_with_half_rtt_data (line 1112) | fn vectored_write_for_server_handshake_with_half_rtt_data() {
  function check_half_rtt_does_not_work (line 1157) | fn check_half_rtt_does_not_work(server_config: ServerConfig) {
  function vectored_write_for_server_handshake_no_half_rtt_with_client_auth (line 1204) | fn vectored_write_for_server_handshake_no_half_rtt_with_client_auth() {
  function vectored_write_for_server_handshake_no_half_rtt_by_default (line 1214) | fn vectored_write_for_server_handshake_no_half_rtt_by_default() {
  function vectored_write_for_client_handshake (line 1221) | fn vectored_write_for_client_handshake() {
  function vectored_write_with_slow_client (line 1258) | fn vectored_write_with_slow_client() {
  function test_client_mtu_reduction (line 1288) | fn test_client_mtu_reduction() {
  function test_server_mtu_reduction (line 1312) | fn test_server_mtu_reduction() {
  function check_client_max_fragment_size (line 1361) | fn check_client_max_fragment_size(size: usize) -> Option<Error> {
  function bad_client_max_fragment_sizes (line 1372) | fn bad_client_max_fragment_sizes() {
  function handshakes_complete_and_data_flows_with_gratuitous_max_fragment_sizes (line 1393) | fn handshakes_complete_and_data_flows_with_gratuitous_max_fragment_sizes...
  function test_acceptor (line 1427) | fn test_acceptor() {
  function test_acceptor_rejected_handshake (line 1543) | fn test_acceptor_rejected_handshake() {
  function test_received_plaintext_backpressure (line 1585) | fn test_received_plaintext_backpressure() {
  function test_plaintext_buffer_limit (line 1590) | fn test_plaintext_buffer_limit(limit: Option<usize>, plaintext_limit: us...
  function server_flush_does_nothing (line 1689) | fn server_flush_does_nothing() {
  function client_flush_does_nothing (line 1695) | fn client_flush_does_nothing() {
  function server_close_notify (line 1701) | fn server_close_notify() {
  function client_close_notify (line 1741) | fn client_close_notify() {
  function server_closes_uncleanly (line 1781) | fn server_closes_uncleanly() {
  function client_closes_uncleanly (line 1827) | fn client_closes_uncleanly() {
  function test_complete_io_errors_if_close_notify_received_too_early (line 1873) | fn test_complete_io_errors_if_close_notify_received_too_early() {
  function test_complete_io_with_no_io_needed (line 1905) | fn test_complete_io_with_no_io_needed() {
  function test_junk_after_close_notify_received (line 1939) | fn test_junk_after_close_notify_received() {
  function test_data_after_close_notify_is_ignored (line 1982) | fn test_data_after_close_notify_is_ignored() {
  function test_close_notify_sent_prior_to_handshake_complete (line 2014) | fn test_close_notify_sent_prior_to_handshake_complete() {
  function test_subsequent_close_notify_ignored (line 2041) | fn test_subsequent_close_notify_ignored() {
  function test_second_close_notify_after_handshake (line 2052) | fn test_second_close_notify_after_handshake() {
  function test_read_tls_artificial_eof_after_close_notify (line 2065) | fn test_read_tls_artificial_eof_after_close_notify() {
  type FakeStream (line 2081) | struct FakeStream<'a>(&'a [u8]);
  method read (line 2084) | fn read(&mut self, b: &mut [u8]) -> io::Result<usize> {
  method write (line 2094) | fn write(&mut self, b: &[u8]) -> io::Result<usize> {
  method flush (line 2098) | fn flush(&mut self) -> io::Result<()> {

FILE: rustls-test/tests/api/kx.rs
  function test_client_config_keyshare (line 27) | fn test_client_config_keyshare() {
  function test_client_config_keyshare_mismatch (line 38) | fn test_client_config_keyshare_mismatch() {
  function exercise_all_key_exchange_methods (line 60) | fn exercise_all_key_exchange_methods() {
  function test_client_sends_helloretryrequest (line 91) | fn test_client_sends_helloretryrequest() {
  function test_client_attempts_to_use_unsupported_kx_group (line 203) | fn test_client_attempts_to_use_unsupported_kx_group() {
  function test_client_sends_share_for_less_preferred_group (line 259) | fn test_client_sends_share_for_less_preferred_group() {
  function test_server_rejects_clients_without_any_kx_groups (line 327) | fn test_server_rejects_clients_without_any_kx_groups() {
  function test_server_rejects_clients_without_any_kx_group_overlap (line 358) | fn test_server_rejects_clients_without_any_kx_group_overlap() {
  function hybrid_kx_component_share_offered_but_server_chooses_something_else (line 391) | fn hybrid_kx_component_share_offered_but_server_chooses_something_else() {
  type FakeHybrid (line 420) | struct FakeHybrid;
  method start (line 423) | fn start(&self) -> Result<StartedKeyExchange, Error> {
  method name (line 427) | fn name(&self) -> NamedGroup {
  type FakeHybridActive (line 432) | struct FakeHybridActive;
  method complete (line 435) | fn complete(self: Box<Self>, _peer_pub_key: &[u8]) -> Result<SharedSecre...
  method pub_key (line 439) | fn pub_key(&self) -> &[u8] {
  method group (line 443) | fn group(&self) -> NamedGroup {
  method component (line 449) | fn component(&self) -> (NamedGroup, &[u8]) {
  method complete_component (line 453) | fn complete_component(self: Box<Self>, _peer_pub_key: &[u8]) -> Result<S...
  method as_key_exchange (line 457) | fn as_key_exchange(&self) -> &(dyn ActiveKeyExchange + 'static) {
  method into_key_exchange (line 461) | fn into_key_exchange(self: Box<Self>) -> Box<dyn ActiveKeyExchange> {

FILE: rustls-test/tests/api/quic.rs
  function step (line 20) | fn step(
  function test_quic_handshake (line 40) | fn test_quic_handshake() {
  function test_quic_rejects_missing_alpn (line 243) | fn test_quic_rejects_missing_alpn() {
  function test_quic_no_tls13_error (line 279) | fn test_quic_no_tls13_error() {
  function test_quic_invalid_early_data_size (line 308) | fn test_quic_invalid_early_data_size() {
  function test_quic_read_hs_deframer_failure (line 336) | fn test_quic_read_hs_deframer_failure() {
  function test_quic_server_no_params_received (line 360) | fn test_quic_server_no_params_received() {
  function test_quic_server_no_tls12 (line 385) | fn test_quic_server_no_tls12() {
  function do_quic_handshake (line 414) | fn do_quic_handshake(client: &mut impl Connection, server: &mut impl Con...
  function quic_transfer (line 421) | fn quic_transfer(sender: &mut impl Connection, receiver: &mut impl Conne...
  function test_quic_resumption_data_basic (line 434) | fn test_quic_resumption_data_basic() {
  function test_quic_resumption_data_0rtt (line 480) | fn test_quic_resumption_data_0rtt() {
  function packet_key_api (line 589) | fn packet_key_api() {
  function test_quic_exporter (line 766) | fn test_quic_exporter() {
  function test_fragmented_append (line 812) | fn test_fragmented_append() {
  function server_rejects_client_hello_with_trailing_fragment (line 845) | fn server_rejects_client_hello_with_trailing_fragment() {

FILE: rustls-test/tests/api/raw_keys.rs
  function successful_raw_key_connection_and_correct_peer_certificates (line 17) | fn successful_raw_key_connection_and_correct_peer_certificates() {
  function correct_certificate_type_extensions_from_client_hello (line 57) | fn correct_certificate_type_extensions_from_client_hello() {
  function only_client_supports_raw_keys (line 79) | fn only_client_supports_raw_keys() {
  function only_server_supports_raw_keys (line 105) | fn only_server_supports_raw_keys() {

FILE: rustls-test/tests/api/resolve.rs
  function server_cert_resolve_with_sni (line 30) | fn server_cert_resolve_with_sni() {
  function server_cert_resolve_with_alpn (line 56) | fn server_cert_resolve_with_alpn() {
  function server_cert_resolve_with_named_groups (line 86) | fn server_cert_resolve_with_named_groups() {
  function client_trims_terminating_dot (line 113) | fn client_trims_terminating_dot() {
  function check_sigalgs_reduced_by_ciphersuite (line 138) | fn check_sigalgs_reduced_by_ciphersuite(
  function find_suite (line 169) | fn find_suite(suite: CipherSuite) -> SupportedCipherSuite {
  function server_cert_resolve_reduces_sigalgs_for_rsa_ciphersuite (line 188) | fn server_cert_resolve_reduces_sigalgs_for_rsa_ciphersuite() {
  function server_cert_resolve_reduces_sigalgs_for_ecdsa_ciphersuite (line 204) | fn server_cert_resolve_reduces_sigalgs_for_ecdsa_ciphersuite() {
  function client_with_sni_disabled_does_not_send_sni (line 226) | fn client_with_sni_disabled_does_not_send_sni() {
  type ServerCheckNoSni (line 254) | struct ServerCheckNoSni {}
  method resolve (line 257) | fn resolve(&self, client_hello: &ClientHello<'_>) -> Result<SelectedCred...
  type ClientCheckCertResolve (line 265) | struct ClientCheckCertResolve {
    method new (line 273) | fn new(
  method drop (line 288) | fn drop(&mut self) {
  method resolve (line 297) | fn resolve(&self, request: &CredentialRequest<'_>) -> Option<SelectedCre...
  method supported_certificate_types (line 314) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  method hash_config (line 318) | fn hash_config(&self, _: &mut dyn Hasher) {}
  function test_client_cert_resolve (line 321) | fn test_client_cert_resolve(
  function default_signature_schemes (line 353) | fn default_signature_schemes(version: ProtocolVersion) -> Vec<SignatureS...
  function client_cert_resolve_default (line 381) | fn client_cert_resolve_default() {
  function client_cert_resolve_server_no_hints (line 399) | fn client_cert_resolve_server_no_hints() {
  function client_cert_resolve_server_added_hint (line 414) | fn client_cert_resolve_server_added_hint() {
  function server_exposes_offered_sni_even_if_resolver_fails (line 433) | fn server_exposes_offered_sni_even_if_resolver_fails() {
  function sni_resolver_works (line 464) | fn sni_resolver_works() {
  function sni_resolver_rejects_wrong_names (line 501) | fn sni_resolver_rejects_wrong_names() {
  function sni_resolver_lower_cases_configured_names (line 526) | fn sni_resolver_lower_cases_configured_names() {
  function sni_resolver_lower_cases_queried_names (line 554) | fn sni_resolver_lower_cases_queried_names() {
  function sni_resolver_rejects_bad_certs (line 583) | fn sni_resolver_rejects_bad_certs() {

FILE: rustls-test/tests/api/resume.rs
  function client_only_attempts_resumption_with_compatible_security (line 28) | fn client_only_attempts_resumption_with_compatible_security() {
  function resumption_combinations (line 89) | fn resumption_combinations() {
  function expected_kx_for_version (line 166) | fn expected_kx_for_version(version: ProtocolVersion) -> NamedGroup {
  function test_client_tls12_no_resume_after_server_downgrade (line 180) | fn test_client_tls12_no_resume_after_server_downgrade() {
  function test_tls13_client_resumption_does_not_reuse_tickets (line 239) | fn test_tls13_client_resumption_does_not_reuse_tickets() {
  function tls13_stateful_resumption (line 292) | fn tls13_stateful_resumption() {
  function tls13_stateless_resumption (line 364) | fn tls13_stateless_resumption() {
  function early_data_not_available (line 441) | fn early_data_not_available() {
  function early_data_configs (line 446) | fn early_data_configs() -> (Arc<ClientConfig>, Arc<ServerConfig>) {
  function early_data_is_available_on_resumption (line 459) | fn early_data_is_available_on_resumption() {
  function early_data_not_available_on_server_before_client_hello (line 545) | fn early_data_not_available_on_server_before_client_hello() {
  function early_data_is_limited_on_client (line 555) | fn early_data_is_limited_on_client() {
  function early_data_configs_allowing_client_to_send_excess_data (line 598) | fn early_data_configs_allowing_client_to_send_excess_data() -> (Arc<Clie...
  function server_detects_excess_early_data (line 616) | fn server_detects_excess_early_data() {
  function server_detects_excess_streamed_early_data (line 651) | fn server_detects_excess_streamed_early_data() {
  type ServerStorage (line 707) | struct ServerStorage {
    method new (line 715) | fn new() -> Self {
    method puts (line 724) | fn puts(&self) -> usize {
    method gets (line 727) | fn gets(&self) -> usize {
    method takes (line 730) | fn takes(&self) -> usize {
    method fmt (line 736) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method put (line 746) | fn put(&self, key: ServerSessionKey<'_>, value: Vec<u8>) -> bool {
    method get (line 752) | fn get(&self, key: ServerSessionKey<'_>) -> Option<Vec<u8>> {
    method take (line 758) | fn take(&self, key: ServerSessionKey<'_>) -> Option<Vec<u8>> {
    method can_cache (line 764) | fn can_cache(&self) -> bool {

FILE: rustls-test/tests/api/server_cert_verifier.rs
  function client_can_override_certificate_verification (line 34) | fn client_can_override_certificate_verification() {
  function client_can_override_certificate_verification_and_reject_certificate (line 55) | fn client_can_override_certificate_verification_and_reject_certificate() {
  function client_can_override_certificate_verification_and_reject_tls12_signatures (line 85) | fn client_can_override_certificate_verification_and_reject_tls12_signatu...
  function client_can_override_certificate_verification_and_reject_tls13_signatures (line 113) | fn client_can_override_certificate_verification_and_reject_tls13_signatu...
  function client_can_override_certificate_verification_and_offer_no_signature_schemes (line 141) | fn client_can_override_certificate_verification_and_offer_no_signature_s...
  function test_pinned_ocsp_response_given_to_custom_server_cert_verifier (line 171) | fn test_pinned_ocsp_response_given_to_custom_server_cert_verifier() {
  function client_can_request_certain_trusted_cas (line 196) | fn client_can_request_certain_trusted_cas() {
  function client_checks_server_certificate_with_given_ip_address (line 278) | fn client_checks_server_certificate_with_given_ip_address() {
  function client_checks_server_certificate_with_given_name (line 331) | fn client_checks_server_certificate_with_given_name() {
  function client_check_server_certificate_ee_revoked (line 356) | fn client_check_server_certificate_ee_revoked() {
  function client_check_server_certificate_ee_unknown_revocation (line 389) | fn client_check_server_certificate_ee_unknown_revocation() {
  function client_check_server_certificate_intermediate_revoked (line 445) | fn client_check_server_certificate_intermediate_revoked() {
  function client_check_server_certificate_ee_crl_expired (line 502) | fn client_check_server_certificate_ee_crl_expired() {
  function client_check_server_certificate_helper_api (line 562) | fn client_check_server_certificate_helper_api() {
  function client_check_server_valid_purpose (line 599) | fn client_check_server_valid_purpose() {
  type ResolvesCertChainByCaName (line 637) | struct ResolvesCertChainByCaName(Vec<(DistinguishedName, Credentials)>);
  method resolve (line 640) | fn resolve(&self, client_hello: &ClientHello<'_>) -> Result<SelectedCred...
  type ServerVerifierWithCasExt (line 680) | struct ServerVerifierWithCasExt {
  method verify_identity (line 686) | fn verify_identity(&self, identity: &ServerIdentity<'_>) -> Result<PeerV...
  method verify_tls12_signature (line 690) | fn verify_tls12_signature(
  method verify_tls13_signature (line 698) | fn verify_tls13_signature(
  method supported_verify_schemes (line 706) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method request_ocsp_response (line 710) | fn request_ocsp_response(&self) -> bool {
  method supported_certificate_types (line 714) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  method root_hint_subjects (line 719) | fn root_hint_subjects(&self) -> Option<Arc<[DistinguishedName]>> {
  method hash_config (line 724) | fn hash_config(&self, h: &mut dyn Hasher) {

FILE: rustls-test/tests/bogo.rs
  function run_bogo_tests_ring (line 7) | fn run_bogo_tests_ring() {
  function run_bogo_tests_aws_lc_rs (line 13) | fn run_bogo_tests_aws_lc_rs() {
  function run_bogo_tests_aws_lc_rs_fips (line 19) | fn run_bogo_tests_aws_lc_rs_fips() {
  function run_bogo_tests (line 23) | fn run_bogo_tests(provider: &str) {

FILE: rustls-test/tests/key_log_file_env.rs
  function serialized (line 34) | fn serialized(f: impl FnOnce()) {

FILE: rustls-test/tests/key_log_file_env/tests.rs
  function exercise_key_log_file_for_client (line 40) | fn exercise_key_log_file_for_client() {
  function exercise_key_log_file_for_server (line 63) | fn exercise_key_log_file_for_server() {

FILE: rustls-test/tests/process_provider.rs
  function test_explicit_choice_required (line 19) | fn test_explicit_choice_required() {

FILE: rustls-util/src/key_log_file.rs
  type KeyLogFileInner (line 14) | struct KeyLogFileInner {
    method new (line 20) | fn new(var: Option<OsString>) -> Self {
    method try_write (line 49) | fn try_write(&mut self, label: &str, client_random: &[u8], secret: &[u...
  method fmt (line 69) | fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
  type KeyLogFile (line 85) | pub struct KeyLogFile(Mutex<KeyLogFileInner>);
    method new (line 90) | pub fn new() -> Self {
  method log (line 97) | fn log(&self, label: &str, client_random: &[u8], secret: &[u8]) {
  method fmt (line 115) | fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
  function init (line 127) | fn init() {
  function test_env_var_is_not_set (line 134) | fn test_env_var_is_not_set() {
  function test_env_var_cannot_be_opened (line 145) | fn test_env_var_cannot_be_opened() {
  function test_env_var_cannot_be_written (line 156) | fn test_env_var_cannot_be_written() {

FILE: rustls-util/src/lib.rs
  function complete_io (line 38) | pub fn complete_io(

FILE: rustls-util/src/stream.rs
  type Stream (line 17) | pub struct Stream<'a, C: 'a + ?Sized, T: 'a + Read + Write + ?Sized> {
  function new (line 32) | pub fn new(conn: &'a mut C, sock: &'a mut T) -> Self {
  function complete_prior_io (line 38) | fn complete_prior_io(&mut self) -> Result<()> {
  function prepare_read (line 50) | fn prepare_read(&mut self) -> Result<()> {
  function fill_buf (line 67) | fn fill_buf(mut self) -> Result<&'a [u8]> {
  method read (line 78) | fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
  method fill_buf (line 89) | fn fill_buf(&mut self) -> Result<&[u8]> {
  method consume (line 98) | fn consume(&mut self, amt: usize) {
  method write (line 108) | fn write(&mut self, buf: &[u8]) -> Result<usize> {
  method write_vectored (line 121) | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
  method flush (line 137) | fn flush(&mut self) -> Result<()> {
  type StreamOwned (line 158) | pub struct StreamOwned<C: Sized, T: Read + Write + Sized> {
  function new (line 176) | pub fn new(conn: C, sock: T) -> Self {
  function get_ref (line 181) | pub fn get_ref(&self) -> &T {
  function get_mut (line 186) | pub fn get_mut(&mut self) -> &mut T {
  function into_parts (line 191) | pub fn into_parts(self) -> (C, T) {
  function as_stream (line 201) | fn as_stream(&'a mut self) -> Stream<'a, C, T> {
  method read (line 214) | fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
  method fill_buf (line 224) | fn fill_buf(&mut self) -> Result<&[u8]> {
  method consume (line 228) | fn consume(&mut self, amt: usize) {
  method write (line 238) | fn write(&mut self, buf: &[u8]) -> Result<usize> {
  method flush (line 242) | fn flush(&mut self) -> Result<()> {
  function stream_can_be_created_for_connection_and_tcpstream (line 256) | fn stream_can_be_created_for_connection_and_tcpstream() {
  function streamowned_can_be_created_for_client_and_tcpstream (line 261) | fn streamowned_can_be_created_for_client_and_tcpstream() {
  function streamowned_can_be_created_for_server_and_tcpstream (line 266) | fn streamowned_can_be_created_for_server_and_tcpstream() {

FILE: rustls/examples/internal/test_ca.rs
  function main (line 21) | fn main() -> Result<(), Box<dyn core::error::Error>> {
  function crl_for_serial (line 143) | fn crl_for_serial(serial_number: SerialNumber) -> CertificateRevocationL...
  function expired_crl (line 160) | fn expired_crl() -> CertificateRevocationListParams {
  constant ROLES (line 173) | const ROLES: [Role; 4] = [
  type Role (line 181) | enum Role {
    method params (line 189) | fn params(&self, alg: &'static SigAlgContext) -> CertificateParams {
    method common_name (line 225) | fn common_name(&self, alg: &'static SigAlgContext) -> DistinguishedName {
    method key_file_path (line 241) | fn key_file_path(&self, alg: &'static SigAlgContext) -> PathBuf {
    method cert_pem_file_path (line 246) | fn cert_pem_file_path(&self, alg: &'static SigAlgContext) -> PathBuf {
    method cert_der_file_path (line 251) | fn cert_der_file_path(&self, alg: &'static SigAlgContext) -> PathBuf {
    method label (line 256) | fn label(&self) -> &'static str {
  type SigAlgContext (line 299) | struct SigAlgContext {
    method output_directory (line 305) | fn output_directory(&self) -> PathBuf {
    method key_pair (line 318) | fn key_pair(&self) -> KeyPair {
  constant ISSUER_KEY_USAGES (line 332) | const ISSUER_KEY_USAGES: &[KeyUsagePurpose; 7] = &[
  constant ISSUER_EXTENDED_KEY_USAGES (line 342) | const ISSUER_EXTENDED_KEY_USAGES: &[ExtendedKeyUsagePurpose; 2] = &[
  constant EE_KEY_USAGES (line 347) | const EE_KEY_USAGES: &[KeyUsagePurpose; 2] = &[

FILE: rustls/src/bs_debug.rs
  type BsDebug (line 13) | pub(crate) struct BsDebug<'a>(pub(crate) &'a [u8]);
  function fmt (line 16) | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
  function debug (line 50) | fn debug() {

FILE: rustls/src/builder.rs
  type ConfigBuilder (line 129) | pub struct ConfigBuilder<Side: ConfigSide, State> {
  function crypto_provider (line 138) | pub fn crypto_provider(&self) -> &Arc<CryptoProvider> {
  function fmt (line 144) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type WantsVerifier (line 161) | pub struct WantsVerifier {
  type ConfigSide (line 169) | pub trait ConfigSide: crate::sealed::Sealed {}

FILE: rustls/src/check.rs
  function inappropriate_message (line 40) | pub(crate) fn inappropriate_message(
  function inappropriate_handshake_message (line 54) | pub(crate) fn inappropriate_handshake_message(

FILE: rustls/src/client/config.rs
  type ClientConfig (line 61) | pub struct ClientConfig {
    method builder (line 179) | pub fn builder(provider: Arc<CryptoProvider>) -> ConfigBuilder<Self, W...
    method builder_with_details (line 192) | pub fn builder_with_details(
    method connect (line 210) | pub fn connect(self: &Arc<Self>, server_name: ServerName<'static>) -> ...
    method dangerous (line 220) | pub fn dangerous(&mut self) -> danger::DangerousClientConfig<'_> {
    method fips (line 229) | pub fn fips(&self) -> FipsStatus {
    method provider (line 242) | pub fn provider(&self) -> &Arc<CryptoProvider> {
    method resolver (line 250) | pub fn resolver(&self) -> &Arc<dyn ClientCredentialResolver> {
    method verifier (line 258) | pub fn verifier(&self) -> &Arc<dyn verify::ServerVerifier> {
    method supports_version (line 262) | pub(crate) fn supports_version(&self, v: ProtocolVersion) -> bool {
    method find_cipher_suite (line 266) | pub(super) fn find_cipher_suite(&self, suite: CipherSuite) -> Option<S...
    method current_time (line 273) | pub(super) fn current_time(&self) -> Result<UnixTime, Error> {
    method config_hash (line 281) | pub(super) fn config_hash(&self) -> [u8; 32] {
  type HashAdapter (line 286) | struct HashAdapter<'a>(&'a mut dyn hash::Context);
  method finish (line 289) | fn finish(&self) -> u64 {
  method write (line 299) | fn write(&mut self, bytes: &[u8]) {
  type ClientSessionStore (line 312) | pub trait ClientSessionStore: fmt::Debug + Send + Sync {
    method set_kx_hint (line 314) | fn set_kx_hint(&self, key: ClientSessionKey<'static>, group: NamedGroup);
    method kx_hint (line 320) | fn kx_hint(&self, key: &ClientSessionKey<'_>) -> Option<NamedGroup>;
    method set_tls12_session (line 325) | fn set_tls12_session(&self, key: ClientSessionKey<'static>, value: Tls...
    method tls12_session (line 328) | fn tls12_session(&self, key: &ClientSessionKey<'_>) -> Option<Tls12Ses...
    method remove_tls12_session (line 331) | fn remove_tls12_session(&self, key: &ClientSessionKey<'static>);
    method insert_tls13_ticket (line 339) | fn insert_tls13_ticket(&self, key: ClientSessionKey<'static>, value: T...
    method take_tls13_ticket (line 344) | fn take_tls13_ticket(&self, key: &ClientSessionKey<'static>) -> Option...
  type ClientSessionKey (line 350) | pub struct ClientSessionKey<'a> {
  function to_owned (line 360) | pub fn to_owned(&self) -> ClientSessionKey<'static> {
  type ClientCredentialResolver (line 374) | pub trait ClientCredentialResolver: fmt::Debug + Send + Sync {
    method resolve (line 392) | fn resolve(&self, request: &CredentialRequest<'_>) -> Option<SelectedC...
    method supported_certificate_types (line 400) | fn supported_certificate_types(&self) -> &'static [CertificateType];
    method hash_config (line 403) | fn hash_config(&self, h: &mut dyn Hasher);
  type CredentialRequest (line 407) | pub struct CredentialRequest<'a> {
  function root_hint_subjects (line 424) | pub fn root_hint_subjects(&self) -> &[DistinguishedName] {
  function signature_schemes (line 429) | pub fn signature_schemes(&self) -> &[SignatureScheme] {
  function negotiated_type (line 438) | pub fn negotiated_type(&self) -> CertificateType {
  type SecurityDomain (line 449) | pub(super) struct SecurityDomain {
    method new (line 466) | pub(crate) fn new(
    method with_verifier (line 511) | fn with_verifier(&self, verifier: Arc<dyn verify::ServerVerifier + 'st...
  type Resumption (line 530) | pub struct Resumption {
    method in_memory_sessions (line 544) | pub fn in_memory_sessions(num: usize) -> Self {
    method store (line 554) | pub fn store(store: Arc<dyn ClientSessionStore>) -> Self {
    method disabled (line 562) | pub fn disabled() -> Self {
    method tls12_resumption (line 573) | pub fn tls12_resumption(mut self, tls12: Tls12Resumption) -> Self {
  method default (line 582) | fn default() -> Self {
  type Tls12Resumption (line 590) | pub enum Tls12Resumption {
  function with_root_certificates (line 619) | pub fn with_root_certificates(
  function with_webpki_verifier (line 636) | pub fn with_webpki_verifier(
  function with_ech (line 661) | pub fn with_ech(mut self, mode: EchMode) -> Self {
  function dangerous (line 668) | pub fn dangerous(self) -> danger::DangerousClientConfigBuilder {
  type WantsClientCert (line 678) | pub struct WantsClientCert {
  function with_client_auth_cert (line 694) | pub fn with_client_auth_cert(
  function with_no_client_auth (line 704) | pub fn with_no_client_auth(self) -> Result<ClientConfig, Error> {
  function with_client_credential_resolver (line 709) | pub fn with_client_credential_resolver(
  type DangerousClientConfig (line 766) | pub struct DangerousClientConfig<'a> {
  function set_certificate_verifier (line 773) | pub fn set_certificate_verifier(&mut self, verifier: Arc<dyn ServerVerif...
  type DangerousClientConfigBuilder (line 780) | pub struct DangerousClientConfigBuilder {
    method with_custom_certificate_verifier (line 787) | pub fn with_custom_certificate_verifier(

FILE: rustls/src/client/connection.rs
  type ClientConnection (line 28) | pub struct ClientConnection {
    method fmt (line 33) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method early_data (line 58) | pub fn early_data(&mut self) -> Option<WriteEarlyData<'_>> {
    method is_early_data_accepted (line 77) | pub fn is_early_data_accepted(&self) -> bool {
    method dangerous_extract_secrets (line 83) | pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Err...
    method ech_status (line 88) | pub fn ech_status(&self) -> EchStatus {
    method write_early_data (line 92) | fn write_early_data(&mut self, data: &[u8]) -> io::Result<usize> {
    method tls13_tickets_received (line 106) | pub fn tls13_tickets_received(&self) -> u32 {
  method read_tls (line 116) | fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
  method write_tls (line 120) | fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Err...
  method wants_read (line 124) | fn wants_read(&self) -> bool {
  method wants_write (line 128) | fn wants_write(&self) -> bool {
  method reader (line 132) | fn reader(&mut self) -> Reader<'_> {
  method writer (line 136) | fn writer(&mut self) -> Writer<'_> {
  method process_new_packets (line 140) | fn process_new_packets(&mut self) -> Result<IoState, Error> {
  method exporter (line 144) | fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
  method dangerous_extract_secrets (line 148) | fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
  method set_buffer_limit (line 152) | fn set_buffer_limit(&mut self, limit: Option<usize>) {
  method set_plaintext_buffer_limit (line 156) | fn set_plaintext_buffer_limit(&mut self, limit: Option<usize>) {
  method refresh_traffic_keys (line 161) | fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
  method send_close_notify (line 165) | fn send_close_notify(&mut self) {
  method is_handshaking (line 169) | fn is_handshaking(&self) -> bool {
  method fips (line 173) | fn fips(&self) -> FipsStatus {
  type Target (line 179) | type Target = ConnectionOutputs;
  method deref (line 181) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 187) | fn deref_mut(&mut self) -> &mut Self::Target {
  type ClientConnectionBuilder (line 195) | pub struct ClientConnectionBuilder {
    method with_alpn (line 203) | pub fn with_alpn(mut self, alpn_protocols: Vec<ApplicationProtocol<'st...
    method build (line 209) | pub fn build(self) -> Result<ClientConnection, Error> {
  type WriteEarlyData (line 238) | pub struct WriteEarlyData<'a> {
  function new (line 243) | fn new(sess: &'a mut ClientConnection) -> Self {
  function bytes_left (line 249) | pub fn bytes_left(&self) -> usize {
  function exporter (line 277) | pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
  function write (line 283) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  function flush (line 287) | fn flush(&mut self) -> io::Result<()> {
  function for_client (line 293) | pub(crate) fn for_client(
  function is_early_data_accepted (line 318) | pub(crate) fn is_early_data_accepted(&self) -> bool {
  type EarlyData (line 323) | pub(super) struct EarlyData {
    method new (line 329) | fn new() -> Self {
    method is_enabled (line 336) | fn is_enabled(&self) -> bool {
    method is_accepted (line 343) | fn is_accepted(&self) -> bool {
    method enable (line 350) | fn enable(&mut self, max_data: usize) {
    method start (line 356) | fn start(&mut self) {
    method rejected (line 361) | fn rejected(&mut self) {
    method accepted (line 366) | fn accepted(&mut self) {
    method finished (line 372) | pub(super) fn finished(&mut self) {
    method check_write (line 380) | fn check_write(&mut self, sz: usize) -> io::Result<usize> {
    method check_write_opt (line 385) | fn check_write_opt(&mut self, sz: usize) -> Option<usize> {
    method bytes_left (line 402) | fn bytes_left(&self) -> usize {
  type EarlyDataState (line 408) | enum EarlyDataState {
  type ClientConnectionData (line 417) | pub(crate) struct ClientConnectionData {
    method new (line 423) | fn new() -> Self {
  type ClientSide (line 434) | pub struct ClientSide;
    type Data (line 439) | type Data = ClientConnectionData;
    type State (line 440) | type State = super::hs::ClientState;
  method emit (line 444) | fn emit(&mut self, ev: Event<'_>) {

FILE: rustls/src/client/ech.rs
  type EchMode (line 37) | pub enum EchMode {
    method fips (line 51) | pub fn fips(&self) -> FipsStatus {
    method from (line 60) | fn from(config: EchConfig) -> Self {
    method from (line 66) | fn from(config: EchGreaseConfig) -> Self {
  type EchConfig (line 75) | pub struct EchConfig {
    method new (line 99) | pub fn new(
    method for_retry (line 115) | pub fn for_retry(
    method state (line 126) | pub(super) fn state(
    method hpke_info (line 148) | pub(crate) fn hpke_info(&self) -> Vec<u8> {
    method new_for_configs (line 156) | fn new_for_configs(
  type EchGreaseConfig (line 206) | pub struct EchGreaseConfig {
    method new (line 221) | pub fn new(suite: &'static dyn Hpke, placeholder_key: HpkePublicKey) -...
    method grease_ext (line 232) | pub(crate) fn grease_ext(
  type EchStatus (line 300) | pub enum EchStatus {
  type EchState (line 315) | pub(crate) struct EchState {
    method new (line 353) | pub(crate) fn new(
    method ech_hello (line 407) | pub(crate) fn ech_hello(
    method confirm_acceptance (line 472) | pub(crate) fn confirm_acceptance(
    method confirm_hrr_acceptance (line 519) | pub(crate) fn confirm_hrr_acceptance(
    method transcript_hrr_update (line 566) | pub(crate) fn transcript_hrr_update(
    method encode_inner_hello (line 585) | fn encode_inner_hello(
    method grease_psk (line 756) | fn grease_psk(&self, psk_offer: &mut PresharedKeyOffer) -> Result<(), ...
    method server_hello_conf (line 790) | fn server_hello_conf(
    method hello_retry_request_conf (line 815) | fn hello_retry_request_conf(retry_req: &HelloRetryRequest) -> Message<...
    method ech_conf_message (line 821) | fn ech_conf_message(hmp: HandshakeMessagePayload<'_>) -> Message<'_> {
  constant SERVER_HELLO_ECH_CONFIRMATION_SPAN (line 841) | const SERVER_HELLO_ECH_CONFIRMATION_SPAN: core::ops::Range<usize> =
  type EchAccepted (line 847) | pub(crate) struct EchAccepted {
  function server_hello_conf_alters_server_hello_random (line 860) | fn server_hello_conf_alters_server_hello_random() {

FILE: rustls/src/client/handy.rs
  type NoClientSessionStorage (line 11) | pub(super) struct NoClientSessionStorage;
  method set_kx_hint (line 14) | fn set_kx_hint(&self, _: ClientSessionKey<'static>, _: NamedGroup) {}
  method kx_hint (line 16) | fn kx_hint(&self, _: &ClientSessionKey<'_>) -> Option<NamedGroup> {
  method set_tls12_session (line 20) | fn set_tls12_session(&self, _: ClientSessionKey<'static>, _: Tls12Sessio...
  method tls12_session (line 22) | fn tls12_session(&self, _: &ClientSessionKey<'_>) -> Option<Tls12Session> {
  method remove_tls12_session (line 26) | fn remove_tls12_session(&self, _: &ClientSessionKey<'_>) {}
  method insert_tls13_ticket (line 28) | fn insert_tls13_ticket(&self, _: ClientSessionKey<'static>, _: Tls13Sess...
  method take_tls13_ticket (line 30) | fn take_tls13_ticket(&self, _: &ClientSessionKey<'_>) -> Option<Tls13Ses...
  constant MAX_TLS13_TICKETS_PER_SERVER (line 45) | const MAX_TLS13_TICKETS_PER_SERVER: usize = 8;
  type ServerData (line 47) | struct ServerData {
  method default (line 58) | fn default() -> Self {
  type ClientSessionMemoryCache (line 71) | pub struct ClientSessionMemoryCache {
    method new (line 78) | pub fn new(size: usize) -> Self {
    method fmt (line 148) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method set_kx_hint (line 88) | fn set_kx_hint(&self, key: ClientSessionKey<'static>, group: NamedGroup) {
  method kx_hint (line 95) | fn kx_hint(&self, key: &ClientSessionKey<'_>) -> Option<NamedGroup> {
  method set_tls12_session (line 103) | fn set_tls12_session(&self, key: ClientSessionKey<'static>, value: Tls12...
  method tls12_session (line 110) | fn tls12_session(&self, key: &ClientSessionKey<'_>) -> Option<Tls12Sessi...
  method remove_tls12_session (line 118) | fn remove_tls12_session(&self, key: &ClientSessionKey<'static>) {
  method insert_tls13_ticket (line 126) | fn insert_tls13_ticket(&self, key: ClientSessionKey<'static>, value: Tls...
  method take_tls13_ticket (line 138) | fn take_tls13_ticket(&self, key: &ClientSessionKey<'static>) -> Option<T...
  type FailResolveClientCert (line 159) | pub(super) struct FailResolveClientCert {}
  method resolve (line 162) | fn resolve(&self, _: &CredentialRequest<'_>) -> Option<SelectedCredentia...
  method supported_certificate_types (line 166) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  method hash_config (line 170) | fn hash_config(&self, _: &mut dyn Hasher) {}
  function test_noclientsessionstorage_does_nothing (line 194) | fn test_noclientsessionstorage_does_nothing() {

FILE: rustls/src/client/hs.rs
  type ClientState (line 44) | pub(crate) enum ClientState {
  method handle (line 52) | fn handle<'m>(self, input: Input<'m>, output: &mut dyn Output<'m>) -> Re...
  method wants_input (line 61) | fn wants_input(&self) -> bool {
  method handle_decrypt_error (line 65) | fn handle_decrypt_error(&mut self) {
  method into_external_state (line 71) | fn into_external_state(
  type ExpectServerHello (line 84) | pub(crate) struct ExpectServerHello {
    method with_version (line 103) | fn with_version<T: Suite + 'static>(
    method handle (line 173) | fn handle(
  type ExpectServerHelloOrHelloRetryRequest (line 226) | struct ExpectServerHelloOrHelloRetryRequest {
    method into_expect_server_hello (line 232) | fn into_expect_server_hello(self) -> ClientState {
    method handle_hello_retry_request (line 236) | fn handle_hello_retry_request(
    method handle (line 382) | fn handle<'m>(
  type ClientHelloInput (line 407) | pub(crate) struct ClientHelloInput {
    method new (line 420) | pub(super) fn new(
    method start_handshake (line 485) | pub(super) fn start_handshake(
  function emit_client_hello_for_retry (line 537) | fn emit_client_hello_for_retry(
  type GroupAndKeyShare (line 897) | pub(super) struct GroupAndKeyShare {
    method new (line 903) | pub(super) fn new(group: &'static dyn SupportedKxGroup) -> Result<Self...
  function prepare_resumption (line 927) | fn prepare_resumption<'a>(
  function process_alpn_protocol (line 979) | pub(super) fn process_alpn_protocol(
  type ClientSessionValue (line 1004) | pub(super) enum ClientSessionValue {
    method retrieve (line 1010) | fn retrieve(
    method common (line 1056) | fn common(&self) -> &ClientSessionCommon {
    method tls13 (line 1063) | fn tls13(&self) -> Option<&Tls13Session> {
  type Target (line 1072) | type Target = ClientSessionCommon;
  method deref (line 1074) | fn deref(&self) -> &Self::Target {
  type ClientHandler (line 1079) | pub(crate) trait ClientHandler<T>: fmt::Debug + Sealed + Send + Sync {
    method handle_server_hello (line 1080) | fn handle_server_hello(

FILE: rustls/src/client/mod.rs
  type Retrieved (line 62) | pub(crate) struct Retrieved<T> {
  function new (line 68) | pub(crate) fn new(value: T, retrieved_at: UnixTime) -> Self {
  function map (line 75) | pub(crate) fn map<M>(&self, f: impl FnOnce(&T) -> Option<&M>) -> Option<...
  function obfuscated_ticket_age (line 84) | pub(crate) fn obfuscated_ticket_age(&self) -> u32 {
  function has_expired (line 95) | pub(crate) fn has_expired(&self) -> bool {
  type Target (line 106) | type Target = T;
  method deref (line 108) | fn deref(&self) -> &Self::Target {
  type Tls13Session (line 115) | pub struct Tls13Session {
    method from_slice (line 126) | pub fn from_slice(bytes: &[u8], provider: &CryptoProvider) -> Result<S...
    method new (line 145) | pub(crate) fn new(
    method encode (line 172) | pub fn encode(&self, buf: &mut Vec<u8>) {
    method _reset_max_early_data_size (line 183) | pub fn _reset_max_early_data_size(&mut self, expected: u32, desired: u...
    method rewind_epoch (line 193) | pub fn rewind_epoch(&mut self, delta: u32) {
  type Target (line 199) | type Target = ClientSessionCommon;
  method deref (line 201) | fn deref(&self) -> &Self::Target {
  type Tls13ClientSessionInput (line 208) | pub(crate) struct Tls13ClientSessionInput {
  type Tls12Session (line 216) | pub struct Tls12Session {
    method from_slice (line 227) | pub fn from_slice(bytes: &[u8], provider: &CryptoProvider) -> Result<S...
    method new (line 249) | pub(crate) fn new(
    method encode (line 269) | pub fn encode(&self, buf: &mut Vec<u8>) {
    method rewind_epoch (line 279) | pub fn rewind_epoch(&mut self, delta: u32) {
  type Target (line 285) | type Target = ClientSessionCommon;
  method deref (line 287) | fn deref(&self) -> &Self::Target {
  type ClientSessionCommon (line 294) | pub struct ClientSessionCommon {
    method new (line 302) | pub(crate) fn new(
    method peer_identity (line 316) | pub(crate) fn peer_identity(&self) -> &Identity<'static> {
    method ticket (line 320) | pub(crate) fn ticket(&self) -> &[u8] {
    method encode (line 326) | fn encode(&self, bytes: &mut Vec<u8>) {
    method read (line 333) | fn read(r: &mut Reader<'a>) -> Result<Self, InvalidMessage> {
  type ServerCertDetails (line 344) | struct ServerCertDetails {
    method new (line 350) | fn new(cert_chain: CertificateChain<'static>, ocsp_response: Vec<u8>) ...
  type ClientHelloDetails (line 358) | struct ClientHelloDetails {
    method new (line 366) | fn new(alpn_protocols: Vec<ApplicationProtocol<'static>>, extension_or...
    method server_sent_unsolicited_extensions (line 375) | fn server_sent_unsolicited_extensions(
  type ClientAuthDetails (line 399) | enum ClientAuthDetails {
    method resolve (line 411) | fn resolve(

FILE: rustls/src/client/test.rs
  function tls12_client_session_value_roundtrip (line 43) | fn tls12_client_session_value_roundtrip() {
  function tls13_client_session_value_roundtrip (line 81) | fn tls13_client_session_value_roundtrip() {
  function test_no_session_ticket_request_on_tls_1_3 (line 125) | fn test_no_session_ticket_request_on_tls_1_3() {
  function test_no_renegotiation_scsv_on_tls_1_3 (line 137) | fn test_no_renegotiation_scsv_on_tls_1_3() {
  function test_client_does_not_offer_sha1 (line 152) | fn test_client_does_not_offer_sha1() {
  function test_client_rejects_hrr_with_varied_session_id (line 174) | fn test_client_rejects_hrr_with_varied_session_id() {
  function test_client_rejects_no_extended_master_secret_extension_when_require_ems_or_fips (line 211) | fn test_client_rejects_no_extended_master_secret_extension_when_require_...
  function cas_extension_in_client_hello_if_server_verifier_requests_it (line 253) | fn cas_extension_in_client_hello_if_server_verifier_requests_it() {
  function test_client_with_custom_verifier_can_accept_ecdsa_sha1_signatures (line 282) | fn test_client_with_custom_verifier_can_accept_ecdsa_sha1_signatures() {
  type ExpectSha1EcdsaVerifier (line 373) | struct ExpectSha1EcdsaVerifier {
  method verify_identity (line 378) | fn verify_identity(&self, _identity: &ServerIdentity<'_>) -> Result<Peer...
  method verify_tls12_signature (line 382) | fn verify_tls12_signature(
  method verify_tls13_signature (line 393) | fn verify_tls13_signature(
  method request_ocsp_response (line 400) | fn request_ocsp_response(&self) -> bool {
  method supported_verify_schemes (line 404) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method hash_config (line 408) | fn hash_config(&self, _: &mut dyn Hasher) {}
  function test_client_requiring_rpk_rejects_server_that_only_offers_x509_id_by_omission (line 412) | fn test_client_requiring_rpk_rejects_server_that_only_offers_x509_id_by_...
  function test_client_requiring_rpk_rejects_server_that_only_offers_x509_id (line 421) | fn test_client_requiring_rpk_rejects_server_that_only_offers_x509_id() {
  function test_client_requiring_rpk_rejects_server_that_only_demands_x509_by_omission (line 433) | fn test_client_requiring_rpk_rejects_server_that_only_demands_x509_by_om...
  function test_client_requiring_rpk_rejects_server_that_only_demands_x509 (line 445) | fn test_client_requiring_rpk_rejects_server_that_only_demands_x509() {
  function test_client_requiring_rpk_accepts_rpk_server (line 458) | fn test_client_requiring_rpk_accepts_rpk_server() {
  function client_requiring_rpk_receives_server_ee (line 471) | fn client_requiring_rpk_receives_server_ee(
  function client_credentials (line 541) | fn client_credentials(provider: &CryptoProvider) -> Credentials {
  function client_key (line 552) | fn client_key() -> PrivateKeyDer<'static> {
  function x25519_provider (line 559) | fn x25519_provider(provider: CryptoProvider) -> Option<CryptoProvider> {
  type ServerVerifierWithAuthorityNames (line 570) | struct ServerVerifierWithAuthorityNames(Arc<[DistinguishedName]>);
  method root_hint_subjects (line 573) | fn root_hint_subjects(&self) -> Option<Arc<[DistinguishedName]>> {
  method verify_identity (line 578) | fn verify_identity(&self, _identity: &ServerIdentity<'_>) -> Result<Peer...
  method verify_tls12_signature (line 583) | fn verify_tls12_signature(
  method verify_tls13_signature (line 591) | fn verify_tls13_signature(
  method supported_verify_schemes (line 598) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method request_ocsp_response (line 602) | fn request_ocsp_response(&self) -> bool {
  method hash_config (line 606) | fn hash_config(&self, _: &mut dyn Hasher) {}
  type ServerVerifierRequiringRpk (line 610) | struct ServerVerifierRequiringRpk;
  method verify_identity (line 614) | fn verify_identity(&self, _identity: &ServerIdentity<'_>) -> Result<Peer...
  method verify_tls12_signature (line 619) | fn verify_tls12_signature(
  method verify_tls13_signature (line 627) | fn verify_tls13_signature(
  method supported_verify_schemes (line 634) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
  method request_ocsp_response (line 638) | fn request_ocsp_response(&self) -> bool {
  method supported_certificate_types (line 642) | fn supported_certificate_types(&self) -> &'static [CertificateType] {
  method hash_config (line 646) | fn hash_config(&self, _: &mut dyn Hasher) {}
  type FakeServerCrypto (line 650) | struct FakeServerCrypto {
    method new (line 656) | fn new(provider: Arc<CryptoProvider>) -> Self {
    method server_handshake_encrypter (line 663) | fn server_handshake_encrypter(&self) -> Box<dyn MessageEncrypter> {
  method will_log (line 682) | fn will_log(&self, _label: &str) -> bool {
  method log (line 686) | fn log(&self, label: &str, _client_random: &[u8], secret: &[u8]) {
  function hybrid_kx_component_share_offered_if_supported_separately (line 697) | fn hybrid_kx_component_share_offered_if_supported_separately() {
  function hybrid_kx_component_share_not_offered_unless_supported_separately (line 717) | fn hybrid_kx_component_share_not_offered_unless_supported_separately() {
  function client_hello_sent_for_config (line 739) | fn client_hello_sent_for_config(config: ClientConfig) -> Result<ClientHe...
  constant HYBRID_PROVIDER (line 762) | const HYBRID_PROVIDER: CryptoProvider = CryptoProvider {
  constant FAKE_HYBRID (line 767) | const FAKE_HYBRID: &FakeHybrid = &FakeHybrid {
  constant FAKE_KX_GROUP (line 771) | const FAKE_KX_GROUP: &dyn SupportedKxGroup = &FakeKeyExchangeGroup(Named...
  type FakeHybrid (line 774) | pub(crate) struct FakeHybrid {
    method component (line 790) | fn component(&self) -> (NamedGroup, &[u8]) {
    method complete_component (line 794) | fn complete_component(self: Box<Self>, peer_pub_key: &[u8]) -> Result<...
    method as_key_exchange (line 801) | fn as_key_exchange(&self) -> &(dyn kx::ActiveKeyExchange + 'static) {
    method into_key_exchange (line 805) | fn into_key_exchange(self: Box<Self>) -> Box<dyn kx::ActiveKeyExchange> {
    method complete (line 811) | fn complete(self: Box<Self>, peer: &[u8]) -> Result<SharedSecret, Erro...
    method pub_key (line 818) | fn pub_key(&self) -> &[u8] {
    method group (line 822) | fn group(&self) -> NamedGroup {
  method start (line 780) | fn start(&self) -> Result<StartedKeyExchange, Error> {
  method name (line 784) | fn name(&self) -> NamedGroup {
  constant KX_PEER_SHARE (line 827) | const KX_PEER_SHARE: &[u8] = b"KxPeerShareKxPeerShareKxPeerShare";
  constant KX_SHARED_SECRET (line 828) | const KX_SHARED_SECRET: &[u8] = b"KxSharedSecretKxSharedSecret";
  function roots (line 830) | fn roots() -> RootCertStore {

FILE: rustls/src/client/tls12.rs
  type Tls12State (line 38) | pub(crate) enum Tls12State {
    method handle (line 51) | pub(crate) fn handle<'m>(
  type Handler (line 81) | struct Handler;
    method handle_server_hello (line 84) | fn handle_server_hello(
  type ExpectCertificate (line 256) | struct ExpectCertificate {
    method handle (line 266) | fn handle(
  method from (line 303) | fn from(value: Box<ExpectCertificate>) -> Self {
  type ExpectCertificateStatusOrServerKx (line 308) | struct ExpectCertificateStatusOrServerKx {
    method handle (line 318) | fn handle(
  method from (line 363) | fn from(value: Box<ExpectCertificateStatusOrServerKx>) -> Self {
  type ExpectCertificateStatus (line 368) | struct ExpectCertificateStatus {
    method handle_input (line 378) | fn handle_input(mut self, Input { message, .. }: Input<'_>) -> Result<...
  type ExpectServerKx (line 406) | struct ExpectServerKx {
    method handle_input (line 416) | fn handle_input(mut self, Input { message, .. }: Input<'_>) -> Result<...
    method handle (line 456) | fn handle(
  method from (line 466) | fn from(value: Box<ExpectServerKx>) -> Self {
  function emit_certificate (line 471) | fn emit_certificate(
  function emit_client_kx (line 487) | fn emit_client_kx(
  function emit_certverify (line 516) | fn emit_certverify(
  function emit_ccs (line 541) | fn emit_ccs(output: &mut dyn Output<'_>) {
  function emit_finished (line 551) | fn emit_finished(
  type ServerKxDetails (line 572) | struct ServerKxDetails {
    method new (line 578) | fn new(params: Vec<u8>, sig: DigitallySignedStruct) -> Self {
  type ExpectServerDoneOrCertReq (line 589) | struct ExpectServerDoneOrCertReq {
    method handle (line 600) | fn handle(
  method from (line 640) | fn from(value: Box<ExpectServerDoneOrCertReq>) -> Self {
  type ExpectCertificateRequest (line 645) | struct ExpectCertificateRequest {
    method handle_input (line 656) | fn handle_input(mut self, Input { message, .. }: Input<'_>) -> Result<...
  type ExpectServerDone (line 696) | struct ExpectServerDone {
    method handle_input (line 707) | fn handle_input(
    method handle (line 908) | fn handle(
  method from (line 918) | fn from(value: Box<ExpectServerDone>) -> Self {
  type ExpectNewTicket (line 923) | struct ExpectNewTicket {
    method handle (line 934) | fn handle(
  method from (line 962) | fn from(value: Box<ExpectNewTicket>) -> Self {
  type ExpectCcs (line 968) | struct ExpectCcs {
    method handle (line 980) | fn handle(
  method from (line 1018) | fn from(value: Box<ExpectCcs>) -> Self {
  type ExpectFinished (line 1023) | pub(super) struct ExpectFinished {
    method save_session (line 1035) | fn save_session(&mut self) {
    method handle (line 1082) | fn handle(
    method handle_decrypt_error (line 1153) | pub(super) fn handle_decrypt_error(&self) {
  method from (line 1165) | fn from(value: Box<ExpectFinished>) -> Self {
  type HandshakeState (line 1170) | struct HandshakeState {
  type ExpectTraffic (line 1179) | pub(super) struct ExpectTraffic {
    method handle (line 1188) | fn handle<'m>(
    method into_external_state (line 1205) | pub(super) fn into_external_state(
  method update_rx_secret (line 1217) | fn update_rx_secret(&mut self) -> Result<ConnectionTrafficSecrets, Error> {
  method handle_new_session_ticket (line 1222) | fn handle_new_session_ticket(
  method from (line 1233) | fn from(value: Box<ExpectTraffic>) -> Self {

FILE: rustls/src/client/tls13.rs
  type Tls13State (line 54) | pub(crate) enum Tls13State {
    method handle (line 69) | pub(crate) fn handle<'m>(
  type Handler (line 91) | struct Handler;
    method handle_server_hello (line 96) | fn handle_server_hello(
  type KeyExchangeChoice (line 286) | enum KeyExchangeChoice {
    method new (line 294) | fn new(
    method complete (line 325) | fn complete(self, peer_pub_key: &[u8]) -> Result<SharedSecret, Error> {
  function initial_key_share (line 333) | pub(super) fn initial_key_share(
  function fill_in_psk_binder (line 361) | pub(super) fn fill_in_psk_binder(
  function prepare_resumption (line 392) | pub(super) fn prepare_resumption(
  function derive_early_traffic_secret (line 435) | pub(super) fn derive_early_traffic_secret(
  function emit_fake_ccs (line 466) | pub(super) fn emit_fake_ccs(sent_tls13_fake_ccs: &mut bool, output: &mut...
  function validate_encrypted_extensions (line 480) | fn validate_encrypted_extensions(
  type ExpectEncryptedExtensions (line 495) | struct ExpectEncryptedExtensions {
    method handle (line 505) | fn handle(
  method from (line 663) | fn from(value: Box<ExpectEncryptedExtensions>) -> Self {
  function check_cert_type (line 668) | fn check_cert_type(
  type ExpectCertificateOrCompressedCertificateOrCertReq (line 685) | struct ExpectCertificateOrCompressedCertificateOrCertReq {
    method handle (line 695) | fn handle(
  method from (line 755) | fn from(value: Box<ExpectCertificateOrCompressedCertificateOrCertReq>) -...
  type ExpectCertificateOrCompressedCertificate (line 762) | struct ExpectCertificateOrCompressedCertificate {
    method handle (line 772) | fn handle(
  method from (line 817) | fn from(value: Box<ExpectCertificateOrCompressedCertificate>) -> Self {
  type ExpectCertificateOrCertReq (line 822) | struct ExpectCertificateOrCertReq {
    method handle (line 832) | fn handle(
  method from (line 878) | fn from(value: Box<ExpectCertificateOrCertReq>) -> Self {
  type ExpectCertificateRequest (line 886) | struct ExpectCertificateRequest {
    method handle_input (line 897) | fn handle_input(mut self, Input { message, .. }: Input<'_>) -> Result<...
  type ExpectCompressedCertificate (line 979) | struct ExpectCompressedCertificate {
    method handle_input (line 989) | fn handle_input(mut self, Input { message, .. }: Input<'_>) -> Result<...
  type ExpectCertificate (line 1039) | struct ExpectCertificate {
    method handle_input (line 1049) | fn handle_input(mut self, Input { message, .. }: Input<'_>) -> Result<...
    method handle_cert_payload (line 1059) | fn handle_cert_payload(
    method handle (line 1090) | fn handle(
  method from (line 1100) | fn from(value: Box<ExpectCertificate>) -> Self {
  type ExpectCertificateVerify (line 1106) | struct ExpectCertificateVerify {
    method handle (line 1117) | fn handle(
  method from (line 1180) | fn from(value: Box<ExpectCertificateVerify>) -> Self {
  function emit_compressed_certificate_tls13 (line 1185) | fn emit_compressed_certificate_tls13(
  function emit_certificate_tls13 (line 1211) | fn emit_certificate_tls13(
  function emit_certverify_tls13 (line 1229) | fn emit_certverify_tls13(
  function emit_finished_tls13 (line 1245) | fn emit_finished_tls13(
  function emit_end_of_early_data_tls13 (line 1256) | fn emit_end_of_early_data_tls13(transcript: &mut HandshakeHash, output: ...
  type ExpectFinished (line 1268) | struct ExpectFinished {
    method handle (line 1279) | fn handle(
  method from (line 1431) | fn from(value: Box<ExpectFinished>) -> Self {
  type HandshakeState (line 1436) | struct HandshakeState {
  type ExpectTraffic (line 1447) | pub(super) struct ExpectTraffic {
    method handle_new_ticket_impl (line 1461) | fn handle_new_ticket_impl(&self, nst: &NewSessionTicketPayloadTls13) -...
    method handle_new_ticket_tls13 (line 1485) | fn handle_new_ticket_tls13(
    method handle_key_update (line 1495) | fn handle_key_update(
    method handle (line 1526) | fn handle<'m>(
    method into_external_state (line 1564) | pub(super) fn into_external_state(
  method update_rx_secret (line 1587) | fn update_rx_secret(&mut self) -> Result<ConnectionTrafficSecrets, Error> {
  method handle_new_session_ticket (line 1592) | fn handle_new_session_ticket(
  method from (line 1601) | fn from(value: Box<ExpectTraffic>) -> Self {
  type ExpectQuicTraffic (line 1606) | pub(super) struct ExpectQuicTraffic(ExpectTraffic);
    method handle (line 1609) | fn handle(
    method into_external_state (line 1624) | pub(super) fn into_external_state(
  method update_rx_secret (line 1647) | fn update_rx_secret(&mut self) -> Result<ConnectionTrafficSecrets, Error> {
  method handle_new_session_ticket (line 1653) | fn handle_new_session_ticket(&self, nst: &NewSessionTicketPayloadTls13) ...
  method from (line 1659) | fn from(value: Box<ExpectQuicTraffic>) -> Self {
  type Ech (line 1664) | struct Ech {
  constant ALLOWED_PLAINTEXT_EXTS (line 1670) | const ALLOWED_PLAINTEXT_EXTS: &[ExtensionType] = &[
  constant DISALLOWED_TLS13_EXTS (line 1678) | const DISALLOWED_TLS13_EXTS: &[ExtensionType] = &[

FILE: rustls/src/common_state.rs
  type CommonState (line 23) | pub struct CommonState {
    method new (line 30) | pub(crate) fn new(side: Side) -> Self {
    method wants_write (line 41) | pub fn wants_write(&self) -> bool {
    method send_close_notify (line 52) | pub fn send_close_notify(&mut self) {
    method is_handshaking (line 63) | pub fn is_handshaking(&self) -> bool {
    method fmt (line 83) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type Target (line 69) | type Target = ConnectionOutputs;
  method deref (line 71) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 77) | fn deref_mut(&mut self) -> &mut Self::Target {
  type ConnectionOutputs (line 91) | pub struct ConnectionOutputs {
    method peer_identity (line 111) | pub fn peer_identity(&self) -> Option<&Identity<'static>> {
    method alpn_protocol (line 120) | pub fn alpn_protocol(&self) -> Option<&ApplicationProtocol<'static>> {
    method negotiated_cipher_suite (line 127) | pub fn negotiated_cipher_suite(&self) -> Option<SupportedCipherSuite> {
    method negotiated_key_exchange_group (line 140) | pub fn negotiated_key_exchange_group(&self) -> Option<&'static dyn Sup...
    method protocol_version (line 147) | pub fn protocol_version(&self) -> Option<ProtocolVersion> {
    method handshake_kind (line 157) | pub fn handshake_kind(&self) -> Option<HandshakeKind> {
    method into_kernel_parts (line 161) | pub(super) fn into_kernel_parts(self) -> Option<(ProtocolVersion, Supp...
  function maybe_send_fatal_alert (line 201) | pub(crate) fn maybe_send_fatal_alert(send: &mut dyn SendOutput, error: &...
  type HandshakeKind (line 211) | pub enum HandshakeKind {
  type Output (line 241) | pub(crate) trait Output<'m> {
    method emit (line 242) | fn emit(&mut self, ev: Event<'_>);
    method output (line 244) | fn output(&mut self, ev: OutputEvent<'_>);
    method send_msg (line 246) | fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool);
    method quic (line 248) | fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
    method received_plaintext (line 252) | fn received_plaintext(&mut self, _payload: Payload<'m>) {}
    method start_traffic (line 254) | fn start_traffic(&mut self);
    method receive (line 256) | fn receive(&mut self) -> &mut ReceivePath;
    method send (line 258) | fn send(&mut self) -> &mut dyn SendOutput;
  type ConnectionOutput (line 261) | pub(crate) trait ConnectionOutput {
    method handle (line 176) | fn handle(&mut self, ev: OutputEvent<'_>) {
    method handle (line 262) | fn handle(&mut self, ev: OutputEvent<'_>);
  type Event (line 266) | pub(crate) enum Event<'a> {
  type OutputEvent (line 274) | pub(crate) enum OutputEvent<'a> {
  type EarlyDataEvent (line 285) | pub(crate) enum EarlyDataEvent {
  type UnborrowedPayload (line 302) | pub(crate) enum UnborrowedPayload {
    method unborrow (line 316) | pub(crate) fn unborrow(locator: &Locator, payload: Payload<'_>) -> Self {
    method reborrow (line 329) | pub(crate) fn reborrow<'b>(self, delocator: &Delocator<'b>) -> Payload...
  type Side (line 340) | pub enum Side {
  type Protocol (line 348) | pub(crate) enum Protocol {
    method is_quic (line 356) | pub(crate) fn is_quic(&self) -> bool {
  type HandshakeFlight (line 361) | pub(crate) struct HandshakeFlight<'a, const TLS13: bool> {
  function new (line 367) | pub(crate) fn new(transcript: &'a mut HandshakeHash) -> Self {
  function add (line 374) | pub(crate) fn add(&mut self, hs: HandshakeMessagePayload<'_>) {
  function finish (line 381) | pub(crate) fn finish(self, output: &mut dyn Output<'_>) {
  type HandshakeFlightTls12 (line 394) | pub(crate) type HandshakeFlightTls12<'a> = HandshakeFlight<'a, false>;
  type HandshakeFlightTls13 (line 395) | pub(crate) type HandshakeFlightTls13<'a> = HandshakeFlight<'a, true>;

FILE: rustls/src/compress.rs
  function default_cert_decompressors (line 47) | pub fn default_cert_decompressors() -> &'static [&'static dyn CertDecomp...
  type CertDecompressor (line 57) | pub trait CertDecompressor: Debug + Send + Sync {
    method decompress (line 64) | fn decompress(&self, input: &[u8], output: &mut [u8]) -> Result<(), De...
    method algorithm (line 67) | fn algorithm(&self) -> CertificateCompressionAlgorithm;
    method decompress (line 141) | fn decompress(&self, input: &[u8], output: &mut [u8]) -> Result<(), De...
    method algorithm (line 149) | fn algorithm(&self) -> CertificateCompressionAlgorithm {
    method decompress (line 203) | fn decompress(&self, input: &[u8], output: &mut [u8]) -> Result<(), De...
    method algorithm (line 217) | fn algorithm(&self) -> CertificateCompressionAlgorithm {
  function default_cert_compressors (line 72) | pub fn default_cert_compressors() -> &'static [&'static dyn CertCompress...
  type CertCompressor (line 82) | pub trait CertCompressor: Debug + Send + Sync {
    method compress (line 91) | fn compress(
    method algorithm (line 98) | fn algorithm(&self) -> CertificateCompressionAlgorithm;
    method compress (line 161) | fn compress(
    method algorithm (line 181) | fn algorithm(&self) -> CertificateCompressionAlgorithm {
    method compress (line 229) | fn compress(
    method algorithm (line 246) | fn algorithm(&self) -> CertificateCompressionAlgorithm {
  type CompressionLevel (line 104) | pub enum CompressionLevel {
  type DecompressionFailed (line 119) | pub struct DecompressionFailed;
  type CompressionFailed (line 124) | pub struct CompressionFailed;
  constant ZLIB_DECOMPRESSOR (line 135) | pub const ZLIB_DECOMPRESSOR: &dyn CertDecompressor = &ZlibRsDecompressor;
  type ZlibRsDecompressor (line 138) | struct ZlibRsDecompressor;
  constant ZLIB_COMPRESSOR (line 155) | pub const ZLIB_COMPRESSOR: &dyn CertCompressor = &ZlibRsCompressor;
  type ZlibRsCompressor (line 158) | struct ZlibRsCompressor;
  constant BROTLI_DECOMPRESSOR (line 197) | pub const BROTLI_DECOMPRESSOR: &dyn CertDecompressor = &BrotliDecompressor;
  type BrotliDecompressor (line 200) | struct BrotliDecompressor;
  constant BROTLI_COMPRESSOR (line 223) | pub const BROTLI_COMPRESSOR: &dyn CertCompressor = &BrotliCompressor;
  type BrotliCompressor (line 226) | struct BrotliCompressor;
  constant BUFFER_SIZE (line 254) | const BUFFER_SIZE: usize = 4096;
  constant LGWIN (line 257) | const LGWIN: u32 = 22;
  constant QUALITY_FAST (line 261) | const QUALITY_FAST: u32 = 4;
  constant QUALITY_SLOW (line 264) | const QUALITY_SLOW: u32 = 11;
  type CompressionCache (line 277) | pub enum CompressionCache {
    method new (line 303) | pub fn new(size: usize) -> Self {
    method compression_for (line 319) | pub(crate) fn compression_for(
    method compression_for_impl (line 330) | fn compression_for_impl(
    method uncached_compression (line 388) | fn uncached_compression(
  type CompressionCacheInner (line 290) | pub struct CompressionCacheInner {
  method default (line 412) | fn default() -> Self {
  type CompressionCacheEntry (line 419) | pub(crate) struct CompressionCacheEntry {
    method compressed_cert_payload (line 429) | pub(crate) fn compressed_cert_payload(&self) -> CompressedCertificateP...
  function test_zlib (line 442) | fn test_zlib() {
  function test_brotli (line 448) | fn test_brotli() {
  function test_compressor (line 452) | fn test_compressor(comp: &dyn CertCompressor, decomp: &dyn CertDecompres...
  function test_trivial_pairwise (line 461) | fn test_trivial_pairwise(
  function test_decompress_wrong_len (line 487) | fn test_decompress_wrong_len(comp: &dyn CertCompressor, decomp: &dyn Cer...
  function test_decompress_garbage (line 507) | fn test_decompress_garbage(decomp: &dyn CertDecompressor) {
  function test_cache_evicts_lru (line 517) | fn test_cache_evicts_lru() {

FILE: rustls/src/conn/kernel.rs
  type KernelConnection (line 51) | pub struct KernelConnection<Side> {
  function new (line 62) | pub(crate) fn new(
  function negotiated_cipher_suite (line 82) | pub fn negotiated_cipher_suite(&self) -> SupportedCipherSuite {
  function protocol_version (line 87) | pub fn protocol_version(&self) -> ProtocolVersion {
  function update_tx_secret (line 102) | pub fn update_tx_secret(&mut self) -> Result<(u64, ConnectionTrafficSecr...
  function update_rx_secret (line 123) | pub fn update_rx_secret(&mut self) -> Result<(u64, ConnectionTrafficSecr...
  function handle_new_session_ticket (line 195) | pub fn handle_new_session_ticket(&mut self, payload: &[u8]) -> Result<()...
  type KernelState (line 211) | pub(crate) trait KernelState: Send + Sync {
    method update_rx_secret (line 213) | fn update_rx_secret(&mut self) -> Result<ConnectionTrafficSecrets, Err...
    method handle_new_session_ticket (line 219) | fn handle_new_session_ticket(

FILE: rustls/src/conn/mod.rs
  type Connection (line 47) | pub trait Connection: Debug + Deref<Target = ConnectionOutputs> + DerefM...
    method read_tls (line 70) | fn read_tls(&mut self, rd: &mut dyn Read) -> Result<usize, io::Error>;
    method write_tls (line 80) | fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::E...
    method wants_read (line 91) | fn wants_read(&self) -> bool;
    method wants_write (line 96) | fn wants_write(&self) -> bool;
    method reader (line 99) | fn reader(&mut self) -> Reader<'_>;
    method writer (line 102) | fn writer(&mut self) -> Writer<'_>;
    method process_new_packets (line 122) | fn process_new_packets(&mut self) -> Result<IoState, Error>;
    method exporter (line 137) | fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error>;
    method dangerous_extract_secrets (line 142) | fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error>;
    method set_buffer_limit (line 187) | fn set_buffer_limit(&mut self, limit: Option<usize>);
    method set_plaintext_buffer_limit (line 192) | fn set_plaintext_buffer_limit(&mut self, limit: Option<usize>);
    method refresh_traffic_keys (line 220) | fn refresh_traffic_keys(&mut self) -> Result<(), Error>;
    method send_close_notify (line 229) | fn send_close_notify(&mut self);
    method is_handshaking (line 238) | fn is_handshaking(&self) -> bool;
    method fips (line 247) | fn fips(&self) -> FipsStatus;
  type Reader (line 251) | pub struct Reader<'a> {
  function check_no_bytes_state (line 259) | fn check_no_bytes_state(&self) -> io::Result<()> {
  function into_first_chunk (line 278) | pub fn into_first_chunk(self) -> io::Result<&'a [u8]> {
  method read (line 310) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
  method fill_buf (line 330) | fn fill_buf(&mut self) -> io::Result<&[u8]> {
  method consume (line 339) | fn consume(&mut self, amt: usize) {
  constant UNEXPECTED_EOF_MESSAGE (line 345) | const UNEXPECTED_EOF_MESSAGE: &str = "peer closed connection without sen...
  type Writer (line 349) | pub struct Writer<'a> {
  function new (line 358) | pub(crate) fn new(sink: &'a mut dyn PlaintextSink) -> Self {
  function write (line 373) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  function write_vectored (line 377) | fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usi...
  function flush (line 381) | fn flush(&mut self) -> io::Result<()> {
  type PlaintextSink (line 391) | pub(crate) trait PlaintextSink {
    method write (line 392) | fn write(&mut self, buf: &[u8]) -> io::R
Condensed preview — 475 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (9,239K chars).
[
  {
    "path": ".cargo/config.toml",
    "chars": 90,
    "preview": "[alias]\n\nfmt-unstable = [\"fmt\", \"--all\", \"--\", \"--config-path\", \".rustfmt.unstable.toml\"]\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 30,
    "preview": "github: [\"cpu\", \"ctz\", \"djc\"]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 783,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Checklist**\n* "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/dependency-update.md",
    "chars": 1300,
    "preview": "---\nname: Dependency Update\nabout: Request a dependency be updated\ntitle: Dependency update request\nlabels: ''\nassignees"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 669,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Checklist**"
  },
  {
    "path": ".github/codecov.yml",
    "chars": 124,
    "preview": "coverage:\n  status:\n    patch:\n      default:\n        threshold: 0.05%\n    project:\n      default:\n        threshold: 0."
  },
  {
    "path": ".github/renovate.json",
    "chars": 728,
    "preview": "{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"config:base\"\n  ],\n  \"labels\": [\n"
  },
  {
    "path": ".github/typos.toml",
    "chars": 335,
    "preview": "[default.extend-words]\n# encrypter as an active verb\nencrypter = \"encrypter\"\n\n# \"type\", but side-stepping the keyword an"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 17406,
    "preview": "name: rustls\n\npermissions:\n  contents: read\n\non:\n  push:\n    branches: ['main', 'rel-*', 'ci/*']\n    tags:\n    - '**'\n  "
  },
  {
    "path": ".github/workflows/cifuzz.yml",
    "chars": 882,
    "preview": "name: CIFuzz\npermissions:\n  contents: read\non: [pull_request]\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.e"
  },
  {
    "path": ".github/workflows/daily-tests.yml",
    "chars": 4987,
    "preview": "name: daily-tests\n\npermissions:\n  contents: read\n\non:\n  workflow_dispatch:\n  schedule:\n    # We run these tests on a dai"
  },
  {
    "path": ".github/workflows/docs.yml",
    "chars": 2708,
    "preview": "name: documentation\n\npermissions:\n  contents: read\n\non:\n  workflow_dispatch:\n  pull_request:\n  push:\n    branches:\n     "
  },
  {
    "path": ".gitignore",
    "chars": 135,
    "preview": "target/\n*.gcda\n*.gcno\n*.info\nsslkeylogfile.txt\nadmin/rustfmt\n.DS_Store\n._.DS_Store\n**/.DS_Store\n**/._.DS_Store\n/.idea\n/d"
  },
  {
    "path": ".lycheeignore",
    "chars": 71,
    "preview": "^file\\:\\/\\/\\/.*\\/target\\/doc\\/index\\.html$\n^http:\\/\\/www\\.adobe\\.com/$\n"
  },
  {
    "path": ".rustfmt.toml",
    "chars": 83,
    "preview": "# keep in sync with .rustfmt.unstable.toml\nchain_width = 40\nstyle_edition = \"2024\"\n"
  },
  {
    "path": ".rustfmt.unstable.toml",
    "chars": 158,
    "preview": "# keep in sync with .rustfmt.toml\nchain_width = 40\nstyle_edition = \"2024\"\n\n# format imports\ngroup_imports = \"StdExternal"
  },
  {
    "path": ".taplo.toml",
    "chars": 55,
    "preview": "[formatting]\nalign_comments = false\ncolumn_width = 110\n"
  },
  {
    "path": "BENCHMARKING.md",
    "chars": 4142,
    "preview": "# Benchmarking\n\nThis repository includes benchmarks for multiple use cases. They are described below, along with\ninforma"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 117,
    "preview": "# Changelog\n\nThe detailed list of changes in each release can be found at\nhttps://github.com/rustls/rustls/releases.\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 263,
    "preview": "# Code of conduct\n\nThis project adopts the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct).\nP"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 18382,
    "preview": "# Contributing\n\nThanks for considering helping this project.  There are many\nways you can help: using the library and re"
  },
  {
    "path": "Cargo.toml",
    "chars": 4509,
    "preview": "[workspace]\nmembers = [\n  # Bogo test shim\n  \"bogo\",\n  # CI benchmarks\n  \"ci-bench\",\n  # Network-based tests\n  \"connect-"
  },
  {
    "path": "LICENSE",
    "chars": 286,
    "preview": "Rustls is distributed under the following three licenses:\n\n- Apache License version 2.0.\n- MIT license.\n- ISC license.\n\n"
  },
  {
    "path": "LICENSE-APACHE",
    "chars": 10847,
    "preview": "                              Apache License\n                        Version 2.0, January 2004\n                     http"
  },
  {
    "path": "LICENSE-ISC",
    "chars": 775,
    "preview": "ISC License (ISC)\nCopyright (c) 2016, Joseph Birr-Pixton <jpixton@gmail.com>\n\nPermission to use, copy, modify, and/or di"
  },
  {
    "path": "LICENSE-MIT",
    "chars": 1082,
    "preview": "Copyright (c) 2016 Joseph Birr-Pixton <jpixton@gmail.com>\n\nPermission is hereby granted, free of charge, to any\nperson o"
  },
  {
    "path": "README.md",
    "chars": 9916,
    "preview": "<p align=\"center\">\n  <img width=\"460\" height=\"300\" src=\"https://raw.githubusercontent.com/rustls/rustls/main/admin/rustl"
  },
  {
    "path": "RELEASING.md",
    "chars": 3967,
    "preview": "## Before making a release\n\n1. Run `cargo update` followed by `cargo outdated`, to check if we have any\n   dependency up"
  },
  {
    "path": "ROADMAP.md",
    "chars": 4903,
    "preview": "# Rustls development roadmap\n\n## Future priorities\n\nSpecific features, in rough order of priority:\n\n* **Address asynchro"
  },
  {
    "path": "SECURITY.md",
    "chars": 3072,
    "preview": "# Security Policy\n\n## Supported Versions\n\nSecurity fixes will be backported only to the rustls versions for which the\nor"
  },
  {
    "path": "admin/all-features-except",
    "chars": 1751,
    "preview": "#!/usr/bin/env python3\n\nDESCRIPTION = \"\"\"\nUsage: admin/all-features-except a,b,c crate\n\nPrints the set of all features d"
  },
  {
    "path": "admin/all-workspace-members",
    "chars": 982,
    "preview": "#!/usr/bin/env python3\n\n\"\"\"\nUsage: admin/all-workspace-members\n\nPrints the set of all workspace members by package name,"
  },
  {
    "path": "admin/bench-measure.mk",
    "chars": 3331,
    "preview": ".PHONY: perf perffull perf13 measure memory clean\n\nRECORD=perf record -F2000 --call-graph dwarf,16000 --\nFLAMEGRAPH=perf"
  },
  {
    "path": "admin/bench-range",
    "chars": 566,
    "preview": "#!/usr/bin/env python3\n\nimport subprocess\n\nsuite = 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'\n\nprint('len,send,recv')\n\nfor "
  },
  {
    "path": "admin/capture-certdata",
    "chars": 1606,
    "preview": "#!/usr/bin/env python3\n\nimport subprocess\nimport base64\nfrom os import path\n\nSITES = dict(\n    google = 'www.google.com'"
  },
  {
    "path": "admin/clippy",
    "chars": 1048,
    "preview": "#!/bin/bash\n\n# Runs clippy on every package in this repo.\n#\n# Passes through any extra arguments to each invocation.\n#\n#"
  },
  {
    "path": "admin/coverage",
    "chars": 842,
    "preview": "#!/usr/bin/env bash\n\nset -e\n\n# for branch coverage support, which is unstable\nexport RUSTC_BOOTSTRAP=1\nOPTIONS=--branch\n"
  },
  {
    "path": "admin/pull-readme",
    "chars": 737,
    "preview": "#!/usr/bin/env sh\n# Extract the introductory documentation into the README.md\n\nset -e\n\nawk 'BEGIN { take=1 }/# Approach/"
  },
  {
    "path": "admin/threads-seq.rs",
    "chars": 1802,
    "preview": "#!/usr/bin/env -S cargo +nightly --quiet -Zscript\n\n//! # `admin/thread-seq N`\n//!\n//! This program prints a sequence of "
  },
  {
    "path": "ci-bench/Cargo.toml",
    "chars": 764,
    "preview": "[package]\nname = \"rustls-ci-bench\"\nversion = \"0.0.1\"\nedition = \"2021\"\nlicense = \"Apache-2.0 OR ISC OR MIT\"\ndescription ="
  },
  {
    "path": "ci-bench/README.md",
    "chars": 8133,
    "preview": "# CI Bench\n\nThis crate is meant for CI benchmarking. It has two modes of operation:\n\n1. Measure CPU instructions using `"
  },
  {
    "path": "ci-bench/src/benchmark.rs",
    "chars": 4047,
    "preview": "use core::borrow::Borrow;\nuse core::cmp;\nuse std::sync::Arc;\n\nuse rustc_hash::FxHashMap;\nuse rustls::crypto::{CryptoProv"
  },
  {
    "path": "ci-bench/src/main.rs",
    "chars": 41787,
    "preview": "use core::hint::black_box;\nuse core::mem;\nuse std::collections::{BTreeMap, BTreeSet, HashMap};\nuse std::fs::File;\nuse st"
  },
  {
    "path": "ci-bench/src/util.rs",
    "chars": 18326,
    "preview": "pub(crate) mod async_io {\n    //! Async IO building blocks required for sharing code between the instruction count and\n "
  },
  {
    "path": "ci-bench/src/valgrind.rs",
    "chars": 15559,
    "preview": "use core::ops::Sub;\nuse std::fs::File;\nuse std::io::{BufRead, BufReader};\nuse std::path::{Path, PathBuf};\nuse std::proce"
  },
  {
    "path": "connect-tests/Cargo.toml",
    "chars": 389,
    "preview": "[package]\nname = \"rustls-connect-tests\"\nversion = \"0.0.1\"\nedition = \"2021\"\nlicense = \"Apache-2.0 OR ISC OR MIT\"\ndescript"
  },
  {
    "path": "connect-tests/tests/badssl.rs",
    "chars": 3849,
    "preview": "// These tests use the various test servers run by Google\n// at badssl.com.\n\n#[allow(dead_code)]\nmod common;\n\nmod online"
  },
  {
    "path": "connect-tests/tests/common/mod.rs",
    "chars": 4897,
    "preview": "use std::path::{Path, PathBuf};\nuse std::process;\n\nuse regex::Regex;\n\npub(super) fn tlsserver_find() -> &'static str {\n "
  },
  {
    "path": "connect-tests/tests/topsites.rs",
    "chars": 1271,
    "preview": "// These tests check we can handshake with a selection of\n// common hosts.\n//\n// Rules: only hosts that can really handl"
  },
  {
    "path": "deny.toml",
    "chars": 379,
    "preview": "[licenses]\nversion = 2\nallow = [\n  \"Apache-2.0\",\n  \"BSD-3-Clause\",\n  \"CDLA-Permissive-2.0\",\n  \"ISC\",\n  \"MIT\",\n  \"MPL-2.0"
  },
  {
    "path": "examples/Cargo.toml",
    "chars": 637,
    "preview": "[package]\nname = \"rustls-examples\"\nversion = \"0.0.1\"\nedition = \"2021\"\nlicense = \"Apache-2.0 OR ISC OR MIT\"\ndescription ="
  },
  {
    "path": "examples/README.md",
    "chars": 1992,
    "preview": "# Rustls Examples\n\nThis directory contains a number of examples that use Rustls.\n\nWe recommend new users start by lookin"
  },
  {
    "path": "examples/src/bin/ech-client.rs",
    "chars": 10064,
    "preview": "//! This is a simple example demonstrating how to use Encrypted Client Hello (ECH) with\n//! rustls and hickory-dns.\n//!\n"
  },
  {
    "path": "examples/src/bin/limitedclient.rs",
    "chars": 2020,
    "preview": "//! limitedclient: This example demonstrates usage of ClientConfig building\n//! so that unused cryptography in rustls ca"
  },
  {
    "path": "examples/src/bin/server_acceptor.rs",
    "chars": 13535,
    "preview": "//! A TLS server that accepts connections using a custom `Acceptor`, demonstrating how fresh\n//! CRL information can be "
  },
  {
    "path": "examples/src/bin/simple_0rtt_client.rs",
    "chars": 3945,
    "preview": "//! This is an example client that uses rustls for TLS, and sends early 0-RTT data.\n//!\n//! Usage:\n//!\n//! ```\n//! cargo"
  },
  {
    "path": "examples/src/bin/simple_0rtt_server.rs",
    "chars": 3835,
    "preview": "//! This is an example server that streams 0-RTT early data from the client.\n//!\n//! Usage: cargo r --bin simple_0rtt_se"
  },
  {
    "path": "examples/src/bin/simpleclient.rs",
    "chars": 2011,
    "preview": "//! This is the simplest possible client using rustls that does something useful:\n//! it accepts the default configurati"
  },
  {
    "path": "examples/src/bin/simpleserver.rs",
    "chars": 1967,
    "preview": "//! This is the simplest possible server using rustls that does something useful:\n//! it accepts the default configurati"
  },
  {
    "path": "examples/src/bin/tlsclient-mio.rs",
    "chars": 17435,
    "preview": "//! This is an example client that uses rustls for TLS, and [mio] for I/O.\n//!\n//! It uses command line flags to demonst"
  },
  {
    "path": "examples/src/bin/tlsserver-mio.rs",
    "chars": 22076,
    "preview": "//! This is an example server that uses rustls for TLS, and [mio] for I/O.\n//!\n//! It uses command line flags to demonst"
  },
  {
    "path": "examples/tests/limitedclient.rs",
    "chars": 2527,
    "preview": "//! Check that `limitedclient` is successful in its goal of not linking in any\n//! AES code.\n//!\n//! We also check `simp"
  },
  {
    "path": "fuzz/.gitignore",
    "chars": 18,
    "preview": "\ntarget\nartifacts\n"
  },
  {
    "path": "fuzz/Cargo.toml",
    "chars": 803,
    "preview": "[package]\nname = \"rustls-fuzz\"\nversion = \"0.0.1\"\nauthors = [\"Automatically generated\"]\npublish = false\nedition = \"2021\"\n"
  },
  {
    "path": "fuzz/README.md",
    "chars": 742,
    "preview": "# Fuzz Testing\n\nRustls supports fuzz testing using [cargo-fuzz]. Fuzz tests are automatically\nrun during continuous inte"
  },
  {
    "path": "fuzz/fuzzers/client.rs",
    "chars": 1024,
    "preview": "#![no_main]\n#[macro_use]\nextern crate libfuzzer_sys;\nextern crate rustls;\n\nuse std::io;\nuse std::sync::Arc;\n\nuse rustls:"
  },
  {
    "path": "fuzz/fuzzers/deframer.rs",
    "chars": 173,
    "preview": "#![no_main]\n#[macro_use]\nextern crate libfuzzer_sys;\nextern crate rustls;\n\nuse rustls::internal::fuzzing::fuzz_deframer;"
  },
  {
    "path": "fuzz/fuzzers/fragment.rs",
    "chars": 175,
    "preview": "#![no_main]\n#[macro_use]\nextern crate libfuzzer_sys;\nextern crate rustls;\n\nuse rustls::internal::fuzzing::fuzz_fragmente"
  },
  {
    "path": "fuzz/fuzzers/message.rs",
    "chars": 169,
    "preview": "#![no_main]\n#[macro_use]\nextern crate libfuzzer_sys;\nextern crate rustls;\n\nuse rustls::internal::fuzzing::fuzz_message;\n"
  },
  {
    "path": "fuzz/fuzzers/persist.rs",
    "chars": 195,
    "preview": "#![no_main]\n#[macro_use]\nextern crate libfuzzer_sys;\nextern crate rustls;\n\nuse rustls::internal::fuzzing::fuzz_server_se"
  },
  {
    "path": "fuzz/fuzzers/server.rs",
    "chars": 2322,
    "preview": "#![no_main]\n#[macro_use]\nextern crate libfuzzer_sys;\nextern crate rustls;\n\nuse std::io;\nuse std::sync::Arc;\n\nuse rustls:"
  },
  {
    "path": "fuzz/fuzzers/server_name.rs",
    "chars": 271,
    "preview": "#![no_main]\n#[macro_use]\nextern crate libfuzzer_sys;\nextern crate rustls;\n\nuse rustls::pki_types::ServerName;\n\nfuzz_targ"
  },
  {
    "path": "openssl-tests/Cargo.toml",
    "chars": 502,
    "preview": "[package]\ndescription = \"Rustls tests that require OpenSSL\"\nedition = \"2021\"\nlicense = \"Apache-2.0 OR ISC OR MIT\"\nname ="
  },
  {
    "path": "openssl-tests/src/early_exporter.rs",
    "chars": 4606,
    "preview": "use std::io::{Read, Write};\nuse std::net::{TcpListener, TcpStream};\nuse std::sync::Arc;\nuse std::{str, thread};\n\nuse ope"
  },
  {
    "path": "openssl-tests/src/ffdhe.rs",
    "chars": 2672,
    "preview": "use num_bigint::BigUint;\nuse rustls::Tls12CipherSuite;\nuse rustls::crypto::kx::ffdhe::{FFDHE2048, FfdheGroup};\nuse rustl"
  },
  {
    "path": "openssl-tests/src/ffdhe_kx_with_openssl.rs",
    "chars": 7036,
    "preview": "use std::borrow::Cow;\nuse std::io::{Read, Write};\nuse std::net::{TcpListener, TcpStream};\nuse std::sync::Arc;\nuse std::{"
  },
  {
    "path": "openssl-tests/src/lib.rs",
    "chars": 140,
    "preview": "#![cfg(test)]\n\nmod early_exporter;\nmod ffdhe;\nmod ffdhe_kx_with_openssl;\nmod raw_key_openssl_interop;\nmod utils;\nmod val"
  },
  {
    "path": "openssl-tests/src/raw_key_openssl_interop.rs",
    "chars": 20984,
    "preview": "//! This module provides tests for the interoperability of raw public keys with OpenSSL, and also\n//! demonstrates how t"
  },
  {
    "path": "openssl-tests/src/utils.rs",
    "chars": 1713,
    "preview": "use once_cell::sync::Lazy;\n\npub(crate) fn verify_openssl3_available() {\n    static VERIFIED: Lazy<()> = Lazy::new(verify"
  },
  {
    "path": "openssl-tests/src/validate_ffdhe_params.rs",
    "chars": 2954,
    "preview": "use base64::prelude::*;\nuse rustls::crypto::kx::NamedGroup;\nuse rustls::crypto::kx::ffdhe::{\n    FFDHE2048, FFDHE3072, F"
  },
  {
    "path": "provider-example/Cargo.toml",
    "chars": 1052,
    "preview": "[package]\nname = \"rustls-provider-example\"\nversion = \"0.0.1\"\nedition = \"2021\"\nlicense = \"Apache-2.0 OR ISC OR MIT\"\ndescr"
  },
  {
    "path": "provider-example/examples/client.rs",
    "chars": 1422,
    "preview": "use std::io::{Read, Write, stdout};\nuse std::net::TcpStream;\nuse std::sync::Arc;\n\nuse rustls::{ClientConfig, RootCertSto"
  },
  {
    "path": "provider-example/examples/server.rs",
    "chars": 3991,
    "preview": "use std::io::Write;\nuse std::sync::Arc;\n\nuse rustls::crypto::Identity;\nuse rustls::pki_types::{CertificateDer, PrivateKe"
  },
  {
    "path": "provider-example/src/aead.rs",
    "chars": 7301,
    "preview": "use alloc::boxed::Box;\n\nuse chacha20poly1305::aead::Buffer;\nuse chacha20poly1305::{AeadInPlace, KeyInit, KeySizeUser};\nu"
  },
  {
    "path": "provider-example/src/hash.rs",
    "chars": 963,
    "preview": "use alloc::boxed::Box;\n\nuse rustls::crypto::{HashAlgorithm, hash};\nuse sha2::Digest;\n\npub(crate) struct Sha256;\n\nimpl ha"
  },
  {
    "path": "provider-example/src/hmac.rs",
    "chars": 871,
    "preview": "use alloc::boxed::Box;\n\nuse hmac::{Hmac, Mac};\nuse rustls::crypto;\nuse sha2::{Digest, Sha256};\n\npub(crate) struct Sha256"
  },
  {
    "path": "provider-example/src/hpke.rs",
    "chars": 9431,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt::Debug;\n\nuse hpke_rs_crypto::HpkeCrypto;\nuse hpke_rs_crypto::t"
  },
  {
    "path": "provider-example/src/kx.rs",
    "chars": 1433,
    "preview": "use alloc::boxed::Box;\n\nuse rustls::crypto::kx::{\n    ActiveKeyExchange, NamedGroup, SharedSecret, StartedKeyExchange, S"
  },
  {
    "path": "provider-example/src/lib.rs",
    "chars": 5051,
    "preview": "#![no_std]\n\nextern crate alloc;\n#[cfg(feature = \"std\")]\nextern crate std;\n\nuse alloc::borrow::Cow;\nuse alloc::boxed::Box"
  },
  {
    "path": "provider-example/src/sign.rs",
    "chars": 1782,
    "preview": "use alloc::boxed::Box;\nuse alloc::sync::Arc;\nuse alloc::vec::Vec;\n\nuse pkcs8::{DecodePrivateKey, EncodePublicKey};\nuse r"
  },
  {
    "path": "provider-example/src/ticketer.rs",
    "chars": 6137,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt;\nuse core::fmt::{Debug, Formatter};\nuse core::sync::atomic::{A"
  },
  {
    "path": "provider-example/src/verify.rs",
    "chars": 2896,
    "preview": "use der::Reader;\nuse rsa::signature::Verifier;\nuse rsa::{BigUint, RsaPublicKey, pkcs1v15, pss};\nuse rustls::crypto::{Sig"
  },
  {
    "path": "rustls/.clippy.toml",
    "chars": 406,
    "preview": "upper-case-acronyms-aggressive = true\ncheck-inconsistent-struct-field-initializers = true\n\ndisallowed-types = [\n  { path"
  },
  {
    "path": "rustls/Cargo.toml",
    "chars": 2012,
    "preview": "[package]\nname = \"rustls\"\nversion = \"0.24.0-dev.0\"\nedition = \"2021\"\nrust-version = \"1.83\"\nlicense = \"Apache-2.0 OR ISC O"
  },
  {
    "path": "rustls/examples/internal/test_ca.rs",
    "chars": 13381,
    "preview": "use core::net::IpAddr;\nuse core::str::FromStr;\nuse core::sync::atomic::{AtomicU64, Ordering};\nuse core::time::Duration;\n"
  },
  {
    "path": "rustls/src/bs_debug.rs",
    "chars": 2929,
    "preview": "use core::fmt;\n\n/// Alternative implementation of `fmt::Debug` for byte slice.\n///\n/// Standard `Debug` implementation f"
  },
  {
    "path": "rustls/src/builder.rs",
    "chars": 7795,
    "preview": "use alloc::format;\nuse core::fmt;\nuse core::marker::PhantomData;\n\nuse crate::client::EchMode;\nuse crate::crypto::CryptoP"
  },
  {
    "path": "rustls/src/check.rs",
    "chars": 2400,
    "preview": "use crate::enums::{ContentType, HandshakeType};\nuse crate::error::Error;\nuse crate::log::warn;\nuse crate::msgs::MessageP"
  },
  {
    "path": "rustls/src/client/config.rs",
    "chars": 31289,
    "preview": "use alloc::vec::Vec;\nuse core::any::Any;\nuse core::fmt;\nuse core::hash::{Hash, Hasher};\nuse core::marker::PhantomData;\n\n"
  },
  {
    "path": "rustls/src/client/connection.rs",
    "chars": 13369,
    "preview": "use alloc::vec::Vec;\nuse core::ops::{Deref, DerefMut};\nuse core::{fmt, mem};\nuse std::io;\n\nuse pki_types::{FipsStatus, S"
  },
  {
    "path": "rustls/src/client/ech.rs",
    "chars": 37595,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nuse pki_types::{DnsName, EchConfigListBytes, FipsStatus, Se"
  },
  {
    "path": "rustls/src/client/handy.rs",
    "chars": 8172,
    "preview": "use core::hash::Hasher;\n\nuse super::config::{ClientCredentialResolver, ClientSessionStore};\nuse super::{ClientSessionKey"
  },
  {
    "path": "rustls/src/client/hs.rs",
    "chars": 39494,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::borrow::Borrow;\nuse core::fmt;\nuse core::ops::Dere"
  },
  {
    "path": "rustls/src/client/mod.rs",
    "chars": 13195,
    "preview": "use alloc::vec::Vec;\nuse core::ops::Deref;\nuse core::time::Duration;\n\nuse pki_types::UnixTime;\nuse zeroize::Zeroizing;\n\n"
  },
  {
    "path": "rustls/src/client/test.rs",
    "chars": 27783,
    "preview": "use alloc::borrow::Cow;\nuse alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::hash::Hasher;\nuse core::sync::atomic::{Ato"
  },
  {
    "path": "rustls/src/client/tls12.rs",
    "chars": 41378,
    "preview": "use alloc::borrow::ToOwned;\nuse alloc::boxed::Box;\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::time::Duration;\n\npub(c"
  },
  {
    "path": "rustls/src/client/tls13.rs",
    "chars": 58947,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nuse subtle::ConstantTimeEq;\n\nuse super::config::{ClientConf"
  },
  {
    "path": "rustls/src/common_state.rs",
    "chars": 13407,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt;\nuse core::ops::{Deref, DerefMut, Range};\n\nuse pki_types::DnsN"
  },
  {
    "path": "rustls/src/compress.rs",
    "chars": 22164,
    "preview": "//! Certificate compression and decompression support\n//!\n//! This crate supports compression and decompression everywhe"
  },
  {
    "path": "rustls/src/conn/kernel.rs",
    "chars": 8969,
    "preview": "//! Kernel connection API.\n//!\n//! This module gives you the bare minimum you need to implement a TLS connection\n//! tha"
  },
  {
    "path": "rustls/src/conn/mod.rs",
    "chars": 35548,
    "preview": "use alloc::boxed::Box;\nuse core::fmt::{self, Debug};\nuse core::ops::{Deref, DerefMut};\nuse std::io;\n\nuse kernel::KernelC"
  },
  {
    "path": "rustls/src/conn/receive.rs",
    "chars": 23340,
    "preview": "use core::marker::PhantomData;\nuse core::mem;\nuse core::ops::Range;\n\nuse super::SendOutput;\nuse crate::SideData;\nuse cra"
  },
  {
    "path": "rustls/src/conn/send.rs",
    "chars": 12752,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\n\nuse crate::crypto::cipher::{\n    EncodedMessage, EncryptionState, MessageEn"
  },
  {
    "path": "rustls/src/crypto/cipher/messages.rs",
    "chars": 19533,
    "preview": "use alloc::vec::Vec;\nuse core::fmt;\nuse core::ops::{Deref, DerefMut, Range};\n\nuse crate::crypto::cipher::EncryptionState"
  },
  {
    "path": "rustls/src/crypto/cipher/mod.rs",
    "chars": 17832,
    "preview": "use alloc::boxed::Box;\nuse alloc::string::ToString;\nuse core::{array, fmt};\n\nuse pki_types::FipsStatus;\nuse zeroize::Zer"
  },
  {
    "path": "rustls/src/crypto/cipher/record_layer.rs",
    "chars": 10144,
    "preview": "use alloc::boxed::Box;\nuse core::cmp::min;\n\nuse crate::crypto::cipher::{\n    EncodedMessage, InboundOpaque, MessageDecry"
  },
  {
    "path": "rustls/src/crypto/enums.rs",
    "chars": 24300,
    "preview": "use crate::crypto::hash;\n\nenum_builder! {\n    /// The `CipherSuite` TLS protocol enum.  Values in this enum are taken\n  "
  },
  {
    "path": "rustls/src/crypto/hash.rs",
    "chars": 2574,
    "preview": "use alloc::boxed::Box;\n\nuse pki_types::FipsStatus;\n\nuse super::enums::HashAlgorithm;\n\n/// Describes a single cryptograph"
  },
  {
    "path": "rustls/src/crypto/hmac.rs",
    "chars": 3268,
    "preview": "use alloc::boxed::Box;\nuse core::mem;\n\nuse pki_types::FipsStatus;\nuse zeroize::Zeroize;\n\n/// A concrete HMAC implementat"
  },
  {
    "path": "rustls/src/crypto/hpke.rs",
    "chars": 8494,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt::Debug;\n\nuse pki_types::FipsStatus;\nuse zeroize::Zeroize;\n\nuse"
  },
  {
    "path": "rustls/src/crypto/kx/ffdhe.rs",
    "chars": 21393,
    "preview": "//! This module contains parameters for FFDHE named groups as defined\n//! in [RFC 7919 Appendix A](https://datatracker.i"
  },
  {
    "path": "rustls/src/crypto/kx/mod.rs",
    "chars": 25291,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt::Debug;\nuse core::ops::Deref;\n\nuse pki_types::FipsStatus;\nuse "
  },
  {
    "path": "rustls/src/crypto/mod.rs",
    "chars": 25982,
    "preview": "use alloc::borrow::Cow;\nuse alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::borrow::Borrow;\nuse core::fmt::{self, Debu"
  },
  {
    "path": "rustls/src/crypto/signer.rs",
    "chars": 17746,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt::Debug;\nuse core::hash::{Hash, Hasher};\nuse core::iter;\n\n#[cfg"
  },
  {
    "path": "rustls/src/crypto/test_provider.rs",
    "chars": 16078,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::time::Duration;\nuse std::borrow::Cow;\n\nuse crate::"
  },
  {
    "path": "rustls/src/crypto/tls12.rs",
    "chars": 3833,
    "preview": "use alloc::boxed::Box;\n\nuse pki_types::FipsStatus;\n\nuse super::hmac;\nuse super::kx::ActiveKeyExchange;\nuse crate::enums:"
  },
  {
    "path": "rustls/src/crypto/tls13.rs",
    "chars": 9150,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\n\nuse pki_types::FipsStatus;\nuse zeroize::Zeroize;\n\nuse super::hmac;\nuse supe"
  },
  {
    "path": "rustls/src/enums.rs",
    "chars": 7743,
    "preview": "#![expect(missing_docs)]\n\nuse alloc::borrow::Cow;\nuse alloc::vec::Vec;\n\nuse crate::crypto::cipher::Payload;\nuse crate::e"
  },
  {
    "path": "rustls/src/error/mod.rs",
    "chars": 61397,
    "preview": "//! Error types used throughout rustls.\n\nuse alloc::format;\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse core::op"
  },
  {
    "path": "rustls/src/error/tests.rs",
    "chars": 11223,
    "preview": "use alloc::string::ToString;\nuse core::time::Duration;\nuse std::{println, vec};\n\nuse pki_types::ServerName;\n\nuse super::"
  },
  {
    "path": "rustls/src/hash_hs.rs",
    "chars": 10848,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::mem;\n\nuse crate::crypto::{HashAlgorithm, hash};\nuse crate::msgs::{"
  },
  {
    "path": "rustls/src/key_log.rs",
    "chars": 2404,
    "preview": "use core::fmt::Debug;\n\n/// This trait represents the ability to do something useful\n/// with key material, such as loggi"
  },
  {
    "path": "rustls/src/lib.rs",
    "chars": 19611,
    "preview": "//! # Rustls - a modern TLS library\n//!\n//! Rustls is a TLS library that aims to provide a good level of cryptographic s"
  },
  {
    "path": "rustls/src/limited_cache.rs",
    "chars": 7023,
    "preview": "use alloc::collections::VecDeque;\nuse core::borrow::Borrow;\nuse core::fmt::Debug;\nuse core::hash::Hash;\n\nuse crate::hash"
  },
  {
    "path": "rustls/src/lock.rs",
    "chars": 756,
    "preview": "pub use std_lock::*;\n\nmod std_lock {\n    use std::sync::Mutex as StdMutex;\n    pub use std::sync::MutexGuard;\n\n    /// A"
  },
  {
    "path": "rustls/src/manual/defaults.rs",
    "chars": 2593,
    "preview": "/*!\n\n## Rationale for defaults\n\n### Why is AES-GCM preferred over chacha20-poly1305?\n\nHardware support for accelerating "
  },
  {
    "path": "rustls/src/manual/features.rs",
    "chars": 4644,
    "preview": "/*!\n\nThe below list reflects the support provided from the first-party provider crates\n[`rustls-aws-lc-rs`] or [`rustls-"
  },
  {
    "path": "rustls/src/manual/fips.rs",
    "chars": 1069,
    "preview": "/*! # Using rustls with FIPS-approved cryptography\n\nTo use FIPS-approved cryptography with rustls, you should use a FIPS"
  },
  {
    "path": "rustls/src/manual/howto.rs",
    "chars": 6133,
    "preview": "/*! # Customising private key usage\n\nBy default rustls supports PKCS#8-format[^1] RSA or ECDSA keys, plus PKCS#1-format "
  },
  {
    "path": "rustls/src/manual/implvulns.rs",
    "chars": 5471,
    "preview": "/*! # A review of TLS Implementation Vulnerabilities\n\nAn important part of engineering involves studying and learning fr"
  },
  {
    "path": "rustls/src/manual/mod.rs",
    "chars": 1157,
    "preview": "/*!\n\nThis documentation primarily aims to explain design decisions taken in rustls.\n\nIt does this from a few aspects: ho"
  },
  {
    "path": "rustls/src/manual/tlsvulns.rs",
    "chars": 10904,
    "preview": "/*! # A review of protocol vulnerabilities\n\n## CBC MAC-then-encrypt ciphersuites\n\nBack in 2000 [Bellare and Namprempre]("
  },
  {
    "path": "rustls/src/msgs/client_hello.rs",
    "chars": 28455,
    "preview": "use alloc::boxed::Box;\nuse alloc::string::String;\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::ops::{Deref, DerefMut};"
  },
  {
    "path": "rustls/src/msgs/codec.rs",
    "chars": 18936,
    "preview": "use alloc::vec::Vec;\nuse core::fmt::{self, Debug};\nuse core::marker::PhantomData;\nuse core::mem;\n\nuse pki_types::{Certif"
  },
  {
    "path": "rustls/src/msgs/deframer/buffers.rs",
    "chars": 8715,
    "preview": "use alloc::vec::Vec;\nuse core::ops::Range;\nuse std::io;\n\n#[derive(Default, Debug)]\n#[expect(unreachable_pub)]\npub struct"
  },
  {
    "path": "rustls/src/msgs/deframer/handshake.rs",
    "chars": 18139,
    "preview": "use core::mem;\nuse core::ops::Range;\nuse std::collections::VecDeque;\n\nuse super::buffers::{Coalescer, Delocator, Locator"
  },
  {
    "path": "rustls/src/msgs/deframer/mod.rs",
    "chars": 7535,
    "preview": "use core::mem;\n\nuse super::{HEADER_SIZE, read_opaque_message_header};\nuse crate::crypto::cipher::{EncodedMessage, Inboun"
  },
  {
    "path": "rustls/src/msgs/enums.rs",
    "chars": 8866,
    "preview": "#![allow(clippy::upper_case_acronyms)]\n#![allow(non_camel_case_types)]\n\nenum_builder! {\n    /// The `ClientCertificateTy"
  },
  {
    "path": "rustls/src/msgs/fragmenter.rs",
    "chars": 6790,
    "preview": "use crate::Error;\nuse crate::crypto::cipher::{EncodedMessage, OutboundPlain, Payload};\nuse crate::enums::{ContentType, P"
  },
  {
    "path": "rustls/src/msgs/handshake.rs",
    "chars": 40948,
    "preview": "use alloc::collections::BTreeSet;\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::ops::{Deref, DerefMut};\nuse core::time:"
  },
  {
    "path": "rustls/src/msgs/handshake_test.rs",
    "chars": 39983,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::time::Duration;\nuse std::{format, println, vec};\n\nuse pki_types::{"
  },
  {
    "path": "rustls/src/msgs/macros.rs",
    "chars": 12654,
    "preview": "/// A macro which defines an enum type.\nmacro_rules! enum_builder {\n    (\n        $(#[doc = $comment:literal])*\n        "
  },
  {
    "path": "rustls/src/msgs/mod.rs",
    "chars": 31118,
    "preview": "#![expect(missing_docs)]\n//! <https://langsec.org> cat says:\n//!\n//! ```text\n//!  ___ _   _ _    _      ___ ___ ___ ___ "
  },
  {
    "path": "rustls/src/msgs/server_hello.rs",
    "chars": 15850,
    "preview": "use alloc::boxed::Box;\nuse alloc::collections::BTreeSet;\nuse alloc::vec::Vec;\nuse core::ops::{Deref, DerefMut};\n\nuse pki"
  },
  {
    "path": "rustls/src/quic.rs",
    "chars": 39312,
    "preview": "use alloc::boxed::Box;\nuse alloc::collections::VecDeque;\nuse alloc::vec::Vec;\nuse core::fmt::Debug;\n\nuse pki_types::Fips"
  },
  {
    "path": "rustls/src/server/config.rs",
    "chars": 30413,
    "preview": "use alloc::borrow::Cow;\nuse alloc::vec::Vec;\nuse core::fmt::Debug;\nuse core::marker::PhantomData;\n\n#[cfg(feature = \"webp"
  },
  {
    "path": "rustls/src/server/connection.rs",
    "chars": 21528,
    "preview": "use alloc::borrow::Cow;\nuse alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt;\nuse core::fmt::{Debug, Formatter};\nus"
  },
  {
    "path": "rustls/src/server/handy.rs",
    "chars": 10199,
    "preview": "use alloc::vec::Vec;\nuse core::fmt::Debug;\n\nuse crate::server::{ServerSessionKey, StoresServerSessions};\n\n/// Something "
  },
  {
    "path": "rustls/src/server/hs.rs",
    "chars": 28464,
    "preview": "use alloc::borrow::ToOwned;\nuse alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::borrow::Borrow;\nuse core::fmt;\n\nuse pk"
  },
  {
    "path": "rustls/src/server/mod.rs",
    "chars": 6897,
    "preview": "use alloc::vec::Vec;\n\nuse pki_types::{DnsName, UnixTime};\n\nuse crate::crypto::cipher::Payload;\nuse crate::crypto::{Ciphe"
  },
  {
    "path": "rustls/src/server/test.rs",
    "chars": 13760,
    "preview": "use alloc::borrow::Cow;\nuse alloc::boxed::Box;\nuse std::vec;\n\nuse pki_types::UnixTime;\n\nuse super::hs::ClientHelloInput;"
  },
  {
    "path": "rustls/src/server/tls12.rs",
    "chars": 36011,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec;\nuse alloc::vec::Vec;\n\npub(crate) use client_hello::TLS12_HANDLER;\nuse pki_types::"
  },
  {
    "path": "rustls/src/server/tls13.rs",
    "chars": 56974,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::time::Duration;\n\npub(crate) use client_hello::TLS1"
  },
  {
    "path": "rustls/src/suites.rs",
    "chars": 6807,
    "preview": "use core::fmt;\n\nuse pki_types::FipsStatus;\n\nuse crate::common_state::Protocol;\nuse crate::crypto::cipher::{AeadKey, Iv};"
  },
  {
    "path": "rustls/src/ticketer.rs",
    "chars": 10487,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::mem;\nuse core::time::Duration;\nuse std::sync::{RwLock, RwLockReadG"
  },
  {
    "path": "rustls/src/time_provider.rs",
    "chars": 800,
    "preview": "//! The library's source of time.\n\nuse core::fmt::Debug;\n\nuse pki_types::UnixTime;\n\n/// An object that provides the curr"
  },
  {
    "path": "rustls/src/tls12.rs",
    "chars": 14948,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::fmt;\n\nuse pki_types::FipsStatus;\nuse zeroize::Zero"
  },
  {
    "path": "rustls/src/tls13/key_schedule.rs",
    "chars": 45362,
    "preview": "//! Key schedule maintenance for TLS1.3\n\nuse alloc::boxed::Box;\nuse core::ops::Deref;\n\nuse crate::common_state::{Output,"
  },
  {
    "path": "rustls/src/tls13/mod.rs",
    "chars": 6785,
    "preview": "use core::fmt;\n\nuse pki_types::FipsStatus;\n\nuse crate::common_state::Protocol;\nuse crate::crypto::{self, SignatureScheme"
  },
  {
    "path": "rustls/src/vecbuf.rs",
    "chars": 10158,
    "preview": "use alloc::collections::VecDeque;\nuse alloc::vec::Vec;\nuse core::mem;\nuse std::io;\nuse std::io::Read;\n\nuse crate::crypto"
  },
  {
    "path": "rustls/src/verify.rs",
    "chars": 17332,
    "preview": "use alloc::vec::Vec;\nuse core::fmt::Debug;\nuse core::hash::Hasher;\n\nuse pki_types::{CertificateDer, ServerName, SubjectP"
  },
  {
    "path": "rustls/src/versions.rs",
    "chars": 3190,
    "preview": "use crate::enums::ProtocolVersion;\nuse crate::tls12::Tls12CipherSuite;\nuse crate::tls13::Tls13CipherSuite;\n\n/// A TLS pr"
  },
  {
    "path": "rustls/src/webpki/anchors.rs",
    "chars": 4622,
    "preview": "use alloc::vec::Vec;\nuse alloc::{fmt, format};\n\nuse pki_types::{CertificateDer, TrustAnchor};\nuse webpki::anchor_from_tr"
  },
  {
    "path": "rustls/src/webpki/client_verifier.rs",
    "chars": 24539,
    "preview": "use alloc::vec::Vec;\n\nuse pki_types::CertificateRevocationListDer;\nuse webpki::{\n    CertRevocationList, ExpirationPolic"
  },
  {
    "path": "rustls/src/webpki/mod.rs",
    "chars": 10908,
    "preview": "use alloc::vec::Vec;\nuse core::fmt;\n\nuse pki_types::CertificateRevocationListDer;\nuse webpki::{CertRevocationList, Inval"
  },
  {
    "path": "rustls/src/webpki/server_verifier.rs",
    "chars": 16048,
    "preview": "use alloc::vec::Vec;\nuse core::hash::{Hash, Hasher};\n\nuse pki_types::CertificateRevocationListDer;\nuse webpki::{CertRevo"
  },
  {
    "path": "rustls/src/webpki/verify.rs",
    "chars": 8831,
    "preview": "use pki_types::{\n    CertificateDer, ServerName, SignatureVerificationAlgorithm, SubjectPublicKeyInfoDer, UnixTime,\n};\nu"
  },
  {
    "path": "rustls/src/x509.rs",
    "chars": 3794,
    "preview": "// Additional x509/asn1 functions to those provided in webpki/ring.\n\nuse alloc::vec::Vec;\n\n/// Prepend stuff to `bytes` "
  },
  {
    "path": "rustls-aws-lc-rs/Cargo.toml",
    "chars": 973,
    "preview": "[package]\nname = \"rustls-aws-lc-rs\"\nversion = \"0.1.0-dev.0\"\nedition = \"2021\"\nrust-version = \"1.83\"\nlicense = \"Apache-2.0"
  },
  {
    "path": "rustls-aws-lc-rs/src/data/alg-rsa-pkcs1-sha256-absent-params.der",
    "chars": 8,
    "preview": "\u0006\t*H\r\u0001\u0001\u000b"
  },
  {
    "path": "rustls-aws-lc-rs/src/data/alg-rsa-pkcs1-sha384-absent-params.der",
    "chars": 8,
    "preview": "\u0006\t*H\r\u0001\u0001\f"
  },
  {
    "path": "rustls-aws-lc-rs/src/data/alg-rsa-pkcs1-sha512-absent-params.der",
    "chars": 8,
    "preview": "\u0006\t*H\r\u0001\u0001\r"
  },
  {
    "path": "rustls-aws-lc-rs/src/hash.rs",
    "chars": 1431,
    "preview": "use alloc::boxed::Box;\n\nuse aws_lc_rs::digest;\nuse pki_types::FipsStatus;\nuse rustls::crypto::{self, HashAlgorithm};\n\npu"
  },
  {
    "path": "rustls-aws-lc-rs/src/hmac.rs",
    "chars": 1262,
    "preview": "use alloc::boxed::Box;\n\nuse aws_lc_rs::hmac;\nuse pki_types::FipsStatus;\nuse rustls::crypto;\n\npub(crate) static HMAC_SHA2"
  },
  {
    "path": "rustls-aws-lc-rs/src/hpke.rs",
    "chars": 42365,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt::{self, Debug, Formatter};\n\nuse aws_lc_rs::aead::{\n    self, A"
  },
  {
    "path": "rustls-aws-lc-rs/src/kx.rs",
    "chars": 10696,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt;\n\nuse aws_lc_rs::rand::SystemRandom;\nuse aws_lc_rs::{agreement"
  },
  {
    "path": "rustls-aws-lc-rs/src/lib.rs",
    "chars": 14027,
    "preview": "//! A `CryptoProvider` implementation backed by *aws-lc-rs*.\n//!\n//! # aws-lc-rs FIPS approval status\n//!\n//! This is co"
  },
  {
    "path": "rustls-aws-lc-rs/src/quic.rs",
    "chars": 15725,
    "preview": "use alloc::boxed::Box;\n\nuse aws_lc_rs::aead;\nuse pki_types::FipsStatus;\nuse rustls::crypto::cipher::{AeadKey, Iv, Nonce}"
  },
  {
    "path": "rustls-aws-lc-rs/src/sign.rs",
    "chars": 26443,
    "preview": "use alloc::boxed::Box;\nuse alloc::string::ToString;\nuse alloc::sync::Arc;\nuse alloc::vec::Vec;\nuse alloc::{format, vec};"
  },
  {
    "path": "rustls-aws-lc-rs/src/ticketer.rs",
    "chars": 8246,
    "preview": "use alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::fmt;\nuse core::fmt::{Debug, Formatter};\nuse core::sync::atomic::{A"
  },
  {
    "path": "rustls-aws-lc-rs/src/tls12.rs",
    "chars": 16958,
    "preview": "use alloc::boxed::Box;\n\nuse aws_lc_rs::{aead, tls_prf};\nuse pki_types::FipsStatus;\nuse rustls::crypto::cipher::{\n    Aea"
  },
  {
    "path": "rustls-aws-lc-rs/src/tls13.rs",
    "chars": 13603,
    "preview": "use alloc::boxed::Box;\n\nuse aws_lc_rs::hkdf::KeyType;\nuse aws_lc_rs::{aead, hkdf, hmac};\nuse pki_types::FipsStatus;\nuse "
  },
  {
    "path": "rustls-aws-lc-rs/src/verify.rs",
    "chars": 13663,
    "preview": "use aws_lc_rs::signature;\nuse pki_types::{\n    AlgorithmIdentifier, FipsStatus, InvalidSignature, SignatureVerificationA"
  },
  {
    "path": "rustls-bench/Cargo.toml",
    "chars": 692,
    "preview": "[package]\nname = \"rustls-bench\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\nclap = { workspace = "
  },
  {
    "path": "rustls-bench/src/main.rs",
    "chars": 33132,
    "preview": "// This program does assorted benchmarking of rustls.\n//\n// Note: we don't use any of the standard 'cargo bench', 'test:"
  },
  {
    "path": "rustls-fuzzing-provider/Cargo.toml",
    "chars": 278,
    "preview": "[package]\nname = \"rustls-fuzzing-provider\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\nrustls = {"
  },
  {
    "path": "rustls-fuzzing-provider/src/lib.rs",
    "chars": 14338,
    "preview": "use core::time::Duration;\nuse std::borrow::Cow;\nuse std::sync::Arc;\n\nuse rustls::client::WebPkiServerVerifier;\nuse rustl"
  },
  {
    "path": "rustls-fuzzing-provider/tests/smoke.rs",
    "chars": 3837,
    "preview": "use std::fs;\nuse std::io::Write;\nuse std::sync::Arc;\n\nuse rustls::crypto::CryptoProvider;\nuse rustls::{ClientConfig, Con"
  },
  {
    "path": "rustls-post-quantum/Cargo.toml",
    "chars": 966,
    "preview": "[package]\nname = \"rustls-post-quantum\"\nversion = \"0.2.4\"\nedition = \"2021\"\nrust-version = \"1.79\"\nlicense = \"Apache-2.0 OR"
  },
  {
    "path": "rustls-post-quantum/README.md",
    "chars": 926,
    "preview": "<p align=\"center\">\n  <img width=\"460\" height=\"300\" src=\"https://raw.githubusercontent.com/rustls/rustls/main/admin/rustl"
  }
]

// ... and 275 more files (download for full content)

About this extraction

This page contains the full source code of the rustls/rustls GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 475 files (8.3 MB), approximately 2.2M tokens, and a symbol index with 4417 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!