diff --git a/.bazelrc b/.bazelrc index d640015b42a..06e4d2d2424 100644 --- a/.bazelrc +++ b/.bazelrc @@ -491,3 +491,7 @@ try-import %workspace%/repo.bazelrc try-import %workspace%/clang.bazelrc try-import %workspace%/user.bazelrc try-import %workspace%/local_tsan.bazelrc + +# OpenSSL-specific configuration (use with --config=openssl) +# To use the default BoringSSL backend, simply don't specify this config +try-import %workspace%/openssl/openssl.bazelrc diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 5783a8b191b..00000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,103 +0,0 @@ -version: 2 -updates: - -# We currently have CI to make sure that all python `requirements.txt` files -# are listed here, and only existing `requirements.txt` files are listed here. -# -# Until https://github.com/envoyproxy/envoy/issues/26163 is resolved `Dockerfiles`, -# and `go.mod` files need to be kept in sync manually. -# -# Please ensure any new ones are added here, and any that are removed are removed here also. - -- package-ecosystem: "pip" - directory: "/tools/base" - open-pull-requests-limit: 20 - schedule: - interval: "daily" - time: "06:00" - -- package-ecosystem: "docker" - directory: "/.devcontainer" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "docker" - directory: "/ci" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "docker" - directory: "/ci/matrix" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "docker" - directory: "/distribution/docker" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "gomod" - directory: "/" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "gomod" - directory: "/contrib/golang/filters/http/test/test_data" - groups: - contrib-golang: - patterns: - - "*" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "gomod" - directory: "/contrib/golang/filters/http/test/test_data/dummy" - groups: - contrib-golang: - patterns: - - "*" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "gomod" - directory: "/contrib/golang/filters/network/test/test_data" - groups: - contrib-golang: - patterns: - - "*" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "gomod" - directory: "/contrib/golang/router/cluster_specifier/test/test_data/simple" - groups: - contrib-golang: - patterns: - - "*" - schedule: - interval: daily - time: "06:00" - -- package-ecosystem: "gomod" - directory: "/contrib/golang/upstreams/http/tcp/test/test_data" - groups: - contrib-golang: - patterns: - - "*" - schedule: - interval: daily - time: "06:00" diff --git a/.github/workflows/envoy-openssl-auto-merge.yml b/.github/workflows/envoy-openssl-auto-merge.yml new file mode 100644 index 00000000000..0e2155a5d87 --- /dev/null +++ b/.github/workflows/envoy-openssl-auto-merge.yml @@ -0,0 +1,70 @@ +name: Auto-merge Bot PRs + +on: + workflow_run: + workflows: ["OpenSSL testing"] + types: + - completed + +permissions: + pull-requests: write + contents: write + +jobs: + enable-auto-merge: + if: | + github.repository == 'envoyproxy/envoy-openssl' + && github.event.workflow_run.conclusion == 'success' + && github.event.workflow_run.repository.full_name == github.repository + runs-on: ubuntu-latest + + steps: + - name: Get PR info + id: pr + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const prs = context.payload.workflow_run.pull_requests; + if (prs.length === 0) { + core.notice("No pull request associated with this workflow_run (likely from a fork). Skipping workflow."); + // Explicitly set a flag so next steps can check + core.setOutput("skip", "true"); + return; + } + const prNumber = prs[0].number; + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber + }); + core.setOutput("pr_number", pr.number); + core.setOutput("pr_author", pr.user.login); + core.setOutput("labels", pr.labels.map(l => l.name).join(",")); + + - name: Print info + if: ${{ steps.pr.outputs.skip != 'true' }} + run: | + echo "PR author: ${{ steps.pr.outputs.pr_author }}" + echo "Labels: ${{ steps.pr.outputs.labels }}" + if [[ "${{ steps.pr.outputs.pr_author }}" != "update-openssl-envoy[bot]" ]]; then + echo "::notice title=Skip reason::PR author is not update-openssl-envoy[bot]" + fi + if [[ "${{ steps.pr.outputs.labels }}" != *"auto-merge"* ]]; then + echo "::notice title=Skip reason::Label 'auto-merge' not found" + fi + + - name: Merge PR + if: ${{ steps.pr.outputs.skip != 'true' && contains(steps.pr.outputs.labels, 'auto-merge') && steps.pr.outputs.pr_author == 'update-openssl-envoy[bot]' }} + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const prNumber = parseInt('${{ steps.pr.outputs.pr_number }}'); + await github.rest.pulls.merge({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber, + merge_method: 'merge' + }); + core.notice(`✅ PR #${prNumber} merged automatically.`); diff --git a/.github/workflows/envoy-openssl.yml b/.github/workflows/envoy-openssl.yml new file mode 100644 index 00000000000..2e001e45c10 --- /dev/null +++ b/.github/workflows/envoy-openssl.yml @@ -0,0 +1,58 @@ +name: OpenSSL testing + +permissions: + contents: read + +on: + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + + +jobs: + openssl: + runs-on: ubuntu-24.04 + timeout-minutes: 180 + permissions: + contents: read + packages: read + if: >- + ${{ github.repository == 'envoyproxy/envoy-openssl' }} + steps: + - name: Free disk space + uses: envoyproxy/toolshed/gh-actions/diskspace@actions-v0.3.28 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - run: | + ./ci/run_envoy_docker.sh './ci/do_ci.sh dev @bssl-compat//test/... //test/...' + env: + BAZEL_BUILD_EXTRA_OPTIONS: >- + --config=rbe + --config=bes + --config=remote-ci + --config=openssl + ENVOY_RBE: 1 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + boringssl: + runs-on: ubuntu-24.04 + timeout-minutes: 180 + permissions: + contents: read + packages: read + if: >- + ${{ github.repository == 'envoyproxy/envoy-openssl' }} + steps: + - name: Free disk space + uses: envoyproxy/toolshed/gh-actions/diskspace@actions-v0.3.28 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - run: | + ./ci/run_envoy_docker.sh './ci/do_ci.sh dev //test/...' + env: + BAZEL_BUILD_EXTRA_OPTIONS: >- + --config=rbe + --config=bes + --config=remote-ci + ENVOY_RBE: 1 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/envoy-sync-scheduled.yaml b/.github/workflows/envoy-sync-scheduled.yaml new file mode 100644 index 00000000000..30decd46e80 --- /dev/null +++ b/.github/workflows/envoy-sync-scheduled.yaml @@ -0,0 +1,54 @@ +name: Sync from Upstream (Scheduled) + +permissions: + contents: read + +on: + schedule: + - cron: "0 */6 * * *" + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }} + +jobs: + sync: + if: github.repository == 'envoyproxy/envoy-openssl' + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + branch_name: + - release/v1.32 + - release/v1.34 + - release/v1.35 + steps: + - id: appauth + uses: envoyproxy/toolshed/gh-actions/appauth@actions-v0.3.23 + with: + key: ${{ secrets.ENVOY_CI_UPDATE_BOT_KEY }} + app_id: ${{ secrets.ENVOY_CI_UPDATE_APP_ID }} + + # Checkout the branch we're merging into + - name: "Checkout ${{ github.repository }}[${{ matrix.branch_name }}]" + uses: actions/checkout@v4 + with: + token: ${{ steps.appauth.outputs.token }} + ref: ${{ matrix.branch_name }} + fetch-depth: 0 + + # Configure the git user info on the repository + - run: git config user.name "${{ github.actor }}" + - run: git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com" + + # Checkout & run the script from the default branch + - name: 'Checkout ci/envoy-sync-receive.sh' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.repository.default_branch }} + sparse-checkout: 'ci/envoy-sync-receive.sh' + sparse-checkout-cone-mode: false + path: '.script' + - run: .script/ci/envoy-sync-receive.sh ${{ matrix.branch_name }} + env: + GH_TOKEN: ${{ steps.appauth.outputs.token }} diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..e69de29bb2d diff --git a/CODEOWNERS b/CODEOWNERS index 35fb44b3cd5..84a7c30d167 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -457,3 +457,7 @@ extensions/upstreams/tcp @ggreenway @mattklein123 /contrib/peak_ewma/filters/http/ @rroblak @UNOWNED /contrib/peak_ewma/load_balancing_policies/ @rroblak @UNOWNED /contrib/kae/ @Misakokoro @UNOWNED + +# OpenSSL FIXME: Maybe create another group "owners"? +/bssl-compat/ @envoyproxy/envoy-openssl-sync +/openssl/ @envoyproxy/envoy-openssl-sync diff --git a/README.md b/README.md index 4f115fbaa42..3ddab3df9bd 100644 --- a/README.md +++ b/README.md @@ -2,101 +2,121 @@ [Cloud-native high-performance edge/middle/service proxy](https://www.envoyproxy.io/) -Envoy is hosted by the [Cloud Native Computing Foundation](https://cncf.io) (CNCF). If you are a -company that wants to help shape the evolution of technologies that are container-packaged, -dynamically-scheduled and microservices-oriented, consider joining the CNCF. For details about who's -involved and how Envoy plays a role, read the CNCF -[announcement](https://www.cncf.io/blog/2017/09/13/cncf-hosts-envoy/). - -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1266/badge)](https://bestpractices.coreinfrastructure.org/projects/1266) -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/envoyproxy/envoy/badge)](https://securityscorecards.dev/viewer/?uri=github.com/envoyproxy/envoy) -[![CLOMonitor](https://img.shields.io/endpoint?url=https://clomonitor.io/api/projects/cncf/envoy/badge)](https://clomonitor.io/projects/cncf/envoy) -[![Azure Pipelines](https://dev.azure.com/cncf/envoy/_apis/build/status/11?branchName=main)](https://dev.azure.com/cncf/envoy/_build/latest?definitionId=11&branchName=main) -[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/envoy.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:envoy) -[![Jenkins](https://powerci.osuosl.org/buildStatus/icon?job=build-envoy-static-master&subject=ppc64le%20build)](https://powerci.osuosl.org/job/build-envoy-static-master/) -[![Jenkins](https://ibmz-ci.osuosl.org/buildStatus/icon?job=Envoy_IBMZ_CI&subject=s390x%20build)](https://ibmz-ci.osuosl.org/job/Envoy_IBMZ_CI/) - -## Documentation - -* [Official documentation](https://www.envoyproxy.io/) -* [FAQ](https://www.envoyproxy.io/docs/envoy/latest/faq/overview) -* [Example documentation](https://github.com/envoyproxy/examples/) -* [Blog](https://medium.com/@mattklein123/envoy-threading-model-a8d44b922310) about the threading model -* [Blog](https://medium.com/@mattklein123/envoy-hot-restart-1d16b14555b5) about hot restart -* [Blog](https://medium.com/@mattklein123/envoy-stats-b65c7f363342) about stats architecture -* [Blog](https://medium.com/@mattklein123/the-universal-data-plane-api-d15cec7a) about universal data plane API -* [Blog](https://medium.com/@mattklein123/lyfts-envoy-dashboards-5c91738816b1) on Lyft's Envoy dashboards - -## Related - -* [data-plane-api](https://github.com/envoyproxy/data-plane-api): v2 API definitions as a standalone - repository. This is a read-only mirror of [api](api/). -* [envoy-perf](https://github.com/envoyproxy/envoy-perf): Performance testing framework. -* [envoy-filter-example](https://github.com/envoyproxy/envoy-filter-example): Example of how to add new filters - and link to the main repository. - -## Contact - -* [envoy-announce](https://groups.google.com/forum/#!forum/envoy-announce): Low frequency mailing - list where we will email announcements only. -* [envoy-security-announce](https://groups.google.com/forum/#!forum/envoy-security-announce): Low frequency mailing - list where we will email security related announcements only. -* [envoy-users](https://groups.google.com/forum/#!forum/envoy-users): General user discussion. -* [envoy-dev](https://groups.google.com/forum/#!forum/envoy-dev): Envoy developer discussion (APIs, - feature design, etc.). -* [envoy-maintainers](https://groups.google.com/forum/#!forum/envoy-maintainers): Use this list - to reach all core Envoy maintainers. -* [Twitter](https://twitter.com/EnvoyProxy/): Follow along on Twitter! -* [Slack](https://envoyproxy.slack.com/): Slack, to get invited go [here](https://communityinviter.com/apps/envoyproxy/envoy). - * NOTE: Response to user questions is best effort on Slack. For a "guaranteed" response please email - envoy-users@ per the guidance in the following linked thread. - -Please see [this](https://groups.google.com/forum/#!topic/envoy-announce/l9zjYsnS3TY) email thread -for information on email list usage. - -## Contributing - -Contributing to Envoy is fun and modern C++ is a lot less scary than you might think if you don't -have prior experience. To get started: - -* [Contributing guide](CONTRIBUTING.md) -* [Beginner issues](https://github.com/envoyproxy/envoy/issues?q=is%3Aopen+is%3Aissue+label%3Abeginner) -* [Build/test quick start using docker](ci#building-and-running-tests-as-a-developer) -* [Developer guide](DEVELOPER.md) -* Consider installing the Envoy [development support toolchain](https://github.com/envoyproxy/envoy/blob/main/support/README.md), which helps automate parts of the development process, particularly those involving code review. -* Please make sure that you let us know if you are working on an issue so we don't duplicate work! - -## Community Meeting - -The Envoy team has a scheduled meeting time twice per month on Tuesday at 9am PT. The public -Google calendar is [here](https://goo.gl/PkDijT). The meeting will only be held -if there are agenda items listed in the [meeting -minutes](https://goo.gl/5Cergb). Any member of the community should be able to -propose agenda items by adding to the minutes. The maintainers will either confirm -the additions to the agenda, or will cancel the meeting within 24 hours of the scheduled -date if there is no confirmed agenda. - -## Security - -### Security Audit - -There has been several third party engagements focused on Envoy security: -* In 2018 Cure53 performed a security audit, [full report](docs/security/audit_cure53_2018.pdf). -* In 2021 Ada Logics performed an audit on our fuzzing infrastructure with recommendations for improvements, [full report](docs/security/audit_fuzzer_adalogics_2021.pdf). - -### Reporting security vulnerabilities - -If you've found a vulnerability or a potential vulnerability in Envoy please let us know at -[envoy-security](mailto:envoy-security@googlegroups.com). We'll send a confirmation -email to acknowledge your report, and we'll send an additional email when we've identified the issue -positively or negatively. - -For further details please see our complete [security release process](SECURITY.md). - -### ppc64le builds - -Builds for the ppc64le architecture or using aws-lc are not covered by the envoy security policy. The ppc64le architecture is currently best-effort and not maintained by the Envoy maintainers. - -## Releases - -For further details please see our [release process](https://github.com/envoyproxy/envoy/blob/main/RELEASES.md). +# Envoy OpenSSL + +This README deals with the specifics of this [envoyproxy/envoy-openssl](https://github.com/envoyproxy/envoy-openssl) repository, describing primarily how it differs from the regular [envoyproxy/envoy](https://github.com/envoyproxy/envoy) repository. The full README for the regular [envoyproxy/envoy](https://github.com/envoyproxy/envoy) repository can be found [here](https://github.com/envoyproxy/envoy/blob/main/README.md). + +## Repository Structure + +This repository is a copy of the regular [envoyproxy/envoy](https://github.com/envoyproxy/envoy) +repository, with additions & modifications that enable Envoy to be built on OpenSSL rather than +BoringSSL. In addition to the regular Envoy repository structure, already described in +[REPO_LAYOUT.md](REPO_LAYOUT.md), this repository has the following additions & modifications that +are specific to building Envoy on OpenSSL: + +* `bssl-compat` This additional directory contains the BoringSSL Compatability Layer implementation. This provides an implementation of the BoringSSL API on top of the OpenSSL libraries. +* `openssl` This additional directory contains config & script files for building Envoy on the `bssl-compat` library rather than on BoringSSL. Where possible, these scripts are minimal wrappers, and delegate most of their behavior to the corresponding scripts in the regular envoy `ci` directory. +* `WORKSPACE` This is the regular envoy `WORKSPACE` file with an additional `local_repository` declaration for the `bssl-compat` library. + +## Branching + +It is intended that this repository contains the same `release/v1.xx` branch structure as the +regular envoy repository, starting from `release/v1.26`. Each of those branches is a copy of the +identically named branch from the regular [envoyproxy/envoy](https://github.com/envoyproxy/envoy) +repository, with the addition of: + +* The additional script & config files, required to build on OpenSSL, as described above. +* Modifications to envoy source code that cannot be hidden in the `bssl-compat` layer. + +Note that the initial `release/v1.26` branch is *not* intended for production. +It is anticipated that `release/v1.28` will be the first branch to reach production. + +## Synchronizing + +Since this repository is primarily a copy of the [envoyproxy/envoy](https://github.com/envoyproxy/envoy) repository, +the process of keeping this repository in sync with the regular envoy repository is automated. + +This automation is implemented by the +[envoy-sync-scheduled.yaml](.github/workflows/envoy-sync-scheduled.yaml) +workflow which executes on a daily schedule. For each of the branches listed in +the workflow's strategy matrix, a merge is attempted from the [envoyproxy/envoy](https://github.com/envoyproxy/envoy) +repository into the identically named branch in this repository. + +- If the merge is successful, it: + - pushes the feature branch to the repository + - creates the associated pull request if it doesn't already exist + - closes the associated issue if it already exists +- If the merge is unsuccessful, it: + - leaves the associated pull request untouched if it already exists + - creates the associated issue issue if it doesn't already exist + - adds a comment on the associated issue to describe the merge fail + +Note that the feature branches created by this automation are named +`auto-merge-`. These repeatable names allow the workflow to reuse & +update existing branches and pull requests, rather than creating new ones each time. + +## Building + +The process for building envoy-openssl is very similar to building regular envoy, wherever possible +reusing the same builder image and the same scripts, and the same steps. + +Building the envoy-openssl project is done in a build container which is based on the regular envoy +build container, but with some additional requirements installed, including OpenSSL 3.0.x. This build +container is launched using the the `openssl/run_envoy_docker.sh` script, which handles some openssl +specific config and then passes control to the regular `ci/run_envoy_docker.sh` script. + +Building & running tests, and building the envoy binary itself, is done using the regular +`ci/do_ci.sh` script. + +Although the regular `ci/do_ci.sh` script supports many options for building & testing different +variants of envoy, as descibed in [ci/README](ci/README.md), including the use of various sanitizers, +the envoy-openssl project has so far only been built and tested using the `debug` options described +below. All of the other `ci/do_ci.sh` options that are described in the regular envoy documentation +[here](https://github.com/envoyproxy/envoy/tree/main/ci#readme) _may_ work but have not been tested. + +To build the envoy executable and run specified tests, in debug mode: +```bash +./openssl/run_envoy_docker.sh './ci/do_ci.sh debug //test/extensions/transport_sockets/tls/...' +``` + +To build just the envoy executable, in debug mode: +```bash +./openssl/run_envoy_docker.sh './ci/do_ci.sh debug.server_only' +``` + +After running these build commands, the resulting envoy executable can be found in the host's file +system at `/tmp/envoy-docker-build/envoy/x64/source/exe/envoy/envoy`. Note that you can place the +build artifacts at a different location on the host by setting ENVOY_DOCKER_BUILD_DIR environment +variable _before_ invoking the `openssl/run_envoy_docker.sh` script. For example, running the +following command would put the build artifact in `/build/envoy/x64/source/exe/envoy/envoy`: +```bash +ENVOY_DOCKER_BUILD_DIR=/build ./openssl/run_envoy_docker.sh './ci/do_ci.sh debug.server_only' +``` + +Note that, in addition to running the `do_ci.sh` script directly in batch mode, as done in the examples +above, the `openssl/run_envoy_docker.sh` script can also be used to run an interactive shell, which +can be more convenient, for example when repeatedly building & running tests: + +```bash +host $ ./openssl/run_envoy_docker.sh bash + +container $ ./ci/do_ci.sh debug //test/extensions/transport_sockets/tls/... +container $ ./ci/do_ci.sh debug //test/common/runtime/... +``` + +## Running Envoy + +When running the envoy executable in the build container, by default it will fail, with the following error +message, bacause the build image only has OpenSSL 1.1.x installed, but the envoy executable needs to load +and use OpenSSL 3.0.x libraries: + +```bash +$ /build/envoy/x64/source/exe/envoy/envoy --version +Expecting to load OpenSSL version 3.0.x but got 1.1.6 +``` + +To ensure that envoy loads the OpenSSL 3.0.x libraries, their path needs to be prepended to `LD_LIBRARY_PATH` before it is executed: +```bash +$ LD_LIBRARY_PATH=$OPENSSL_ROOT_DIR/lib64:$LD_LIBRARY_PATH /build/envoy/x64/source/exe/envoy/envoy --version +/build/envoy/x64/source/exe/envoy/envoy version: dcd3e1c50ace27b14441fc8b28650b62c0bf2dd2/1.26.8-dev/Modified/DEBUG/BoringSSL +``` diff --git a/SSL_BACKEND_SELECTION.md b/SSL_BACKEND_SELECTION.md new file mode 100644 index 00000000000..3679223e16f --- /dev/null +++ b/SSL_BACKEND_SELECTION.md @@ -0,0 +1,140 @@ +# SSL Backend Selection Support + +This document describes how to build Envoy with either BoringSSL (upstream default) or OpenSSL (via bssl-compat). + +## Overview + +The build system now supports selecting between two SSL backends: +- **BoringSSL** (default) - The upstream SSL library used by Envoy +- **OpenSSL** (via bssl-compat) - OpenSSL 3.0.x with a BoringSSL compatibility layer + +## Usage + +### Building with BoringSSL (Default) + +Simply build as normal without any special flags: + +```bash +bazel build //source/exe:envoy-static +``` + +### Building with OpenSSL + +Use the `--config=openssl` flag (recommended): + +```bash +bazel build --config=openssl //source/exe:envoy-static +``` + +This automatically: +- Sets `--define=ssl=openssl` to select the OpenSSL backend +- Adds `-DENVOY_SSL_OPENSSL` compiler flag +- Disables QUIC/HTTP3 support +- Restricts tests to IPv4 only + +Alternatively, you can use just the define flag (not recommended as it doesn't apply other OpenSSL-specific settings): + +```bash +bazel build --define=ssl=openssl //source/exe:envoy-static +``` + +## Implementation Details + +### Build System Changes + +1. **Config Settings** (`bazel/BUILD`): + - Added `ssl_openssl` config_setting for `--define=ssl=openssl` + - Added `ssl_boringssl` config_setting for `--define=ssl=boringssl` + +2. **Aliases** (`bazel/BUILD`): + - `//bazel:boringssl` now conditionally points to either `@boringssl//:ssl` or `@bssl-compat//:ssl` + - `//bazel:boringcrypto` now conditionally points to either `@boringssl//:crypto` or `@bssl-compat//:crypto` + +3. **Dependencies** (`bazel/repositories.bzl`): + - Both BoringSSL and OpenSSL (via bssl-compat) are loaded + - Selection happens at build time via the aliases + +4. **Helper Function** (`bazel/envoy_select.bzl`): + - Added `envoy_select_ssl()` for conditional compilation based on SSL backend + - Example: `envoy_select_ssl(if_openssl = [...], if_boringssl = [...])` + +5. **Preprocessor Defines**: + - When `ssl=openssl` is set, `-DENVOY_SSL_OPENSSL` is added to compilation flags + - This allows source code to conditionally compile OpenSSL-specific code + +### Source Code Changes + +OpenSSL-specific code is wrapped with `#ifdef ENVOY_SSL_OPENSSL`: + +1. **SSL Socket** (`source/common/tls/ssl_socket.cc`): + - EAGAIN handling in `SSL_ERROR_SSL` cases + +2. **Context Implementation** (`source/common/tls/context_impl.cc`): + - Disabled `SSL_CTX_set_reverify_on_resume()` (not in bssl-compat) + - Disabled `SSL_was_key_usage_invalid()` (not in bssl-compat) + +3. **BIO Handling** (`source/common/tls/io_handle_bio.cc`): + - Added `io_handle_new()` and `io_handle_free()` for OpenSSL + - Added BIO control commands for OpenSSL + +4. **Version Reporting** (`source/common/version/BUILD`): + - Reports "OpenSSL" or "BoringSSL" based on build configuration + +### Configuration Files + +The `openssl/bazelrc` file automatically: +- Sets `--define=ssl=openssl` +- Adds `-DENVOY_SSL_OPENSSL` compiler flag +- Disables QUIC/HTTP3 support +- Restricts tests to IPv4 only + +## Test Considerations + +Some tests have different expectations for OpenSSL vs BoringSSL: +- TLS fingerprints may differ +- Cipher suite ordering may differ +- Alert codes may differ + +Tests should use `#ifdef ENVOY_SSL_OPENSSL` to adjust expectations accordingly. + +## Migration Guide + +### For Users + +- To use BoringSSL: No changes needed (default behavior) +- To use OpenSSL: Add `--define=ssl=openssl` to your build commands + +### For Developers + +When adding SSL-related code: + +1. **If the code works with both backends**: No special handling needed + +2. **If the code is OpenSSL-specific**: Wrap it with: + ```cpp + #ifdef ENVOY_SSL_OPENSSL + // OpenSSL-specific code here + #endif + ``` + +3. **If the code is BoringSSL-specific**: Wrap it with: + ```cpp + #ifndef ENVOY_SSL_OPENSSL + // BoringSSL-specific code here + #endif + ``` + +4. **For conditional build dependencies**: Use `envoy_select_ssl()` in BUILD files: + ```python + deps = [...] + envoy_select_ssl( + if_openssl = ["//openssl/specific:dep"], + if_boringssl = ["//boringssl/specific:dep"], + ) + ``` + +## Limitations + +When building with OpenSSL: +- QUIC/HTTP3 support is disabled (OpenSSL doesn't provide QUIC implementation) +- Some BoringSSL-specific APIs are not available +- Test coverage may differ from BoringSSL builds diff --git a/WORKSPACE b/WORKSPACE index 885864c985f..e6d8513af90 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,5 +1,10 @@ workspace(name = "envoy") +local_repository( + name = "bssl-compat", + path = "bssl-compat", +) + load("//bazel:api_binding.bzl", "envoy_api_binding") envoy_api_binding() diff --git a/bazel/BUILD b/bazel/BUILD index 6c74443dcac..90af3978635 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -492,6 +492,16 @@ config_setting( values = {"define": "boringssl=disabled"}, ) +config_setting( + name = "ssl_openssl", + values = {"define": "ssl=openssl"}, +) + +config_setting( + name = "ssl_boringssl", + values = {"define": "ssl=boringssl"}, +) + selects.config_setting_group( name = "boringssl_fips_x86", match_all = [ @@ -554,15 +564,11 @@ config_setting( values = {"define": "uhv=enabled"}, ) -# Alias pointing to the selected version of BoringSSL: -# - BoringSSL FIPS from @boringssl_fips//:ssl, -# - non-FIPS BoringSSL from @boringssl//:ssl. -# - aws-lc from @aws_lc//:ssl +# Alias pointing to the selected SSL implementation (BoringSSL or OpenSSL via bssl-compat): alias( name = "boringssl", actual = select({ - "//bazel:boringssl_fips_ppc": "@aws_lc//:ssl", - "//bazel:boringssl_fips_not_ppc": "@boringssl_fips//:ssl", + ":ssl_openssl": "@bssl-compat//:ssl", "//conditions:default": "@boringssl//:ssl", }), ) @@ -570,8 +576,7 @@ alias( alias( name = "boringcrypto", actual = select({ - "//bazel:boringssl_fips_ppc": "@aws_lc//:crypto", - "//bazel:boringssl_fips_not_ppc": "@boringssl_fips//:crypto", + ":ssl_openssl": "@bssl-compat//:crypto", "//conditions:default": "@boringssl//:crypto", }), ) diff --git a/bazel/boringssl-bssl-compat.patch b/bazel/boringssl-bssl-compat.patch new file mode 100644 index 00000000000..eecda7bc835 --- /dev/null +++ b/bazel/boringssl-bssl-compat.patch @@ -0,0 +1,25 @@ +diff --git a/BUILD.bazel b/BUILD.bazel +index b7dc359..cd87639 100644 +--- a/BUILD.bazel ++++ b/BUILD.bazel +@@ -66,6 +66,20 @@ license( + + exports_files(["LICENSE"]) + ++# Export additional files for bssl-compat layer ++exports_files(glob(["include/**/*"])) ++exports_files(glob(["crypto/**/*"])) ++exports_files(glob(["ssl/**/*"])) ++ ++filegroup( ++ name = "test_data", ++ srcs = glob([ ++ "crypto/x509/test/*.pem", ++ "crypto/pkcs8/test/*.p12", ++ ]), ++ visibility = ["//visibility:public"], ++) ++ + bssl_cc_library( + name = "crypto", + srcs = bcm_sources + crypto_sources, diff --git a/bazel/boringssl-s390x-ppc64le.patch b/bazel/boringssl-s390x-ppc64le.patch new file mode 100644 index 00000000000..aa18b790120 --- /dev/null +++ b/bazel/boringssl-s390x-ppc64le.patch @@ -0,0 +1,15 @@ +diff --git a/include/openssl/target.h b/include/openssl/target.h +index 8d4763d..79f52ba 100644 +--- a/include/openssl/target.h ++++ b/include/openssl/target.h +@@ -54,6 +54,10 @@ + #define OPENSSL_32_BIT + #elif defined(__myriad2__) + #define OPENSSL_32_BIT ++#elif defined(__s390__) || defined(__s390x__) || defined(__zarch__) ++#define OPENSSL_64_BIT ++#elif defined(__ppc64le__) || defined(__ARCH_PPC64LE__) || defined(_ARCH_PPC64) ++#define OPENSSL_64_BIT + #else + // The list above enumerates the platforms that BoringSSL supports. For these + // platforms we keep a reasonable bar of not breaking them: automated test diff --git a/bazel/envoy_build_system.bzl b/bazel/envoy_build_system.bzl index 5714d6a89a9..32b093bef20 100644 --- a/bazel/envoy_build_system.bzl +++ b/bazel/envoy_build_system.bzl @@ -45,6 +45,7 @@ load( _envoy_select_hot_restart = "envoy_select_hot_restart", _envoy_select_nghttp2 = "envoy_select_nghttp2", _envoy_select_signal_trace = "envoy_select_signal_trace", + _envoy_select_ssl = "envoy_select_ssl", _envoy_select_static_extension_registration = "envoy_select_static_extension_registration", _envoy_select_wasm_cpp_tests = "envoy_select_wasm_cpp_tests", _envoy_select_wasm_rust_tests = "envoy_select_wasm_rust_tests", @@ -93,11 +94,14 @@ def envoy_contrib_package(): def _envoy_directory_genrule_impl(ctx): tree = ctx.actions.declare_directory(ctx.attr.name + ".outputs") ctx.actions.run_shell( - inputs = ctx.files.srcs, + inputs = ctx.files.srcs + ctx.files._openssl_libs, tools = ctx.files.tools, outputs = [tree], command = "mkdir -p " + tree.path + " && " + ctx.expand_location(ctx.attr.cmd), - env = {"GENRULE_OUTPUT_DIR": tree.path}, + env = { + "GENRULE_OUTPUT_DIR": tree.path, + "LD_LIBRARY_PATH": ":".join([f.dirname for f in ctx.files._openssl_libs]), + }, use_default_shell_env = True, toolchain = None, ) @@ -109,6 +113,10 @@ envoy_directory_genrule = rule( "srcs": attr.label_list(), "cmd": attr.string(), "tools": attr.label_list(), + "_openssl_libs": attr.label( + default = Label("@openssl//:libs"), + allow_files = True, + ), }, ) @@ -255,6 +263,7 @@ envoy_select_hot_restart = _envoy_select_hot_restart envoy_select_nghttp2 = _envoy_select_nghttp2 envoy_select_enable_http_datagrams = _envoy_select_enable_http_datagrams envoy_select_signal_trace = _envoy_select_signal_trace +envoy_select_ssl = _envoy_select_ssl envoy_select_wasm_cpp_tests = _envoy_select_wasm_cpp_tests envoy_select_wasm_rust_tests = _envoy_select_wasm_rust_tests envoy_select_wasm_v8 = _envoy_select_wasm_v8 diff --git a/bazel/envoy_select.bzl b/bazel/envoy_select.bzl index 11da16641e4..b5308c8cde8 100644 --- a/bazel/envoy_select.bzl +++ b/bazel/envoy_select.bzl @@ -11,13 +11,22 @@ def envoy_cc_platform_dep(name): "//conditions:default": [name + "_posix"], }) +# When building on bssl-compat, ignore whether we are building with BoringSSL +# in FIPS or non FIPS mode, and just pretend it's in the default non-FIPS mode. def envoy_select_boringssl(if_fips, default = None, if_disabled = None): return select({ - "@envoy//bazel:boringssl_fips": if_fips, + "@envoy//bazel:boringssl_fips": default or [], "@envoy//bazel:boringssl_disabled": if_disabled or [], "//conditions:default": default or [], }) +# Selects the given values based on the SSL backend (BoringSSL or OpenSSL). +def envoy_select_ssl(if_openssl, if_boringssl = None, repository = ""): + return select({ + repository + "//bazel:ssl_openssl": if_openssl, + "//conditions:default": if_boringssl or [], + }) + # Selects the given values if Google gRPC is enabled in the current build. def envoy_select_google_grpc(xs, repository = ""): return select({ diff --git a/bazel/external/openssl.BUILD b/bazel/external/openssl.BUILD new file mode 100644 index 00000000000..a875c4aa151 --- /dev/null +++ b/bazel/external/openssl.BUILD @@ -0,0 +1,60 @@ +load("@rules_foreign_cc//foreign_cc:configure.bzl", "configure_make") + +licenses(["notice"]) # Apache 2 + +filegroup( + name = "all", + srcs = glob(["**"]), + visibility = ["//visibility:public"], +) + +configure_make( + name = "openssl", + lib_source = ":all", + configure_in_place = True, + configure_command = "Configure", + configure_options = ["--libdir=lib"], + targets = ["build_sw", "install_sw"], + args = ["-j"], + out_lib_dir = "lib", + out_shared_libs = [ + "libssl.so.3", + "libcrypto.so.3", + "ossl-modules/legacy.so" + ], + visibility = ["//visibility:public"], +) + +filegroup( + name = "include", + srcs = [":openssl"], + output_group = "include", + visibility = ["//visibility:public"], +) + +filegroup( + name = "libssl", + srcs = [":openssl"], + output_group = "libssl.so.3", + visibility = ["//visibility:private"], +) + +filegroup( + name = "libcrypto", + srcs = [":openssl"], + output_group = "libcrypto.so.3", + visibility = ["//visibility:private"], +) + +filegroup( + name = "legacy", + srcs = [":openssl"], + output_group = "legacy.so", + visibility = ["//visibility:private"], +) + +filegroup( + name = "libs", + srcs = [":libssl", ":libcrypto", ":legacy"], + visibility = ["//visibility:public"], +) diff --git a/bazel/external/quiche-s390x.patch b/bazel/external/quiche-s390x.patch new file mode 100644 index 00000000000..e62e44a1021 --- /dev/null +++ b/bazel/external/quiche-s390x.patch @@ -0,0 +1,956 @@ +diff --git a/quiche/common/internet_checksum.cc b/quiche/common/internet_checksum.cc +index 668d54676..8de8924d0 100644 +--- a/quiche/common/internet_checksum.cc ++++ b/quiche/common/internet_checksum.cc +@@ -10,6 +10,8 @@ + #include "absl/strings/string_view.h" + #include "absl/types/span.h" + ++#include "quiche/common/quiche_endian.h" ++ + namespace quiche { + + void InternetChecksum::Update(const char* data, size_t size) { +@@ -20,7 +22,9 @@ void InternetChecksum::Update(const char* data, size_t size) { + accumulator_ += v; + } + if (current < data + size) { +- accumulator_ += *reinterpret_cast(current); ++ uint16_t v = *reinterpret_cast(current); ++ v = quiche::QuicheEndian::HostToLittleEndian16(v); ++ accumulator_ += v; + } + } + +diff --git a/quiche/common/quiche_data_reader.cc b/quiche/common/quiche_data_reader.cc +index 8f5bf8eee..7e5359d3c 100644 +--- a/quiche/common/quiche_data_reader.cc ++++ b/quiche/common/quiche_data_reader.cc +@@ -38,6 +38,9 @@ bool QuicheDataReader::ReadUInt16(uint16_t* result) { + } + if (endianness_ == quiche::NETWORK_BYTE_ORDER) { + *result = quiche::QuicheEndian::NetToHost16(*result); ++ } else if (endianness_ == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ *result = quiche::QuicheEndian::ByteSwap16(*result); + } + return true; + } +@@ -63,6 +66,9 @@ bool QuicheDataReader::ReadUInt32(uint32_t* result) { + } + if (endianness_ == quiche::NETWORK_BYTE_ORDER) { + *result = quiche::QuicheEndian::NetToHost32(*result); ++ } else if (endianness_ == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ *result = quiche::QuicheEndian::ByteSwap32(*result); + } + return true; + } +@@ -73,6 +79,9 @@ bool QuicheDataReader::ReadUInt64(uint64_t* result) { + } + if (endianness_ == quiche::NETWORK_BYTE_ORDER) { + *result = quiche::QuicheEndian::NetToHost64(*result); ++ } else if (endianness_ == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ *result = quiche::QuicheEndian::ByteSwap64(*result); + } + return true; + } +@@ -83,7 +92,13 @@ bool QuicheDataReader::ReadBytesToUInt64(size_t num_bytes, uint64_t* result) { + return false; + } + if (endianness_ == quiche::HOST_BYTE_ORDER) { +- return ReadBytes(result, num_bytes); ++ if (!ReadBytes(result, num_bytes)) { ++ return false; ++ } ++ if (quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ *result = quiche::QuicheEndian::ByteSwap64(*result); ++ } ++ return true; + } + + if (!ReadBytes(reinterpret_cast(result) + sizeof(*result) - num_bytes, +diff --git a/quiche/common/quiche_data_writer.cc b/quiche/common/quiche_data_writer.cc +index bf49f596d..6be993b34 100644 +--- a/quiche/common/quiche_data_writer.cc ++++ b/quiche/common/quiche_data_writer.cc +@@ -33,6 +33,9 @@ bool QuicheDataWriter::WriteUInt8(uint8_t value) { + bool QuicheDataWriter::WriteUInt16(uint16_t value) { + if (endianness_ == quiche::NETWORK_BYTE_ORDER) { + value = quiche::QuicheEndian::HostToNet16(value); ++ } else if (endianness_ == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ value = quiche::QuicheEndian::ByteSwap16(value); + } + return WriteBytes(&value, sizeof(value)); + } +@@ -40,6 +43,9 @@ bool QuicheDataWriter::WriteUInt16(uint16_t value) { + bool QuicheDataWriter::WriteUInt32(uint32_t value) { + if (endianness_ == quiche::NETWORK_BYTE_ORDER) { + value = quiche::QuicheEndian::HostToNet32(value); ++ } else if (endianness_ == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ value = quiche::QuicheEndian::ByteSwap32(value); + } + return WriteBytes(&value, sizeof(value)); + } +@@ -47,6 +53,9 @@ bool QuicheDataWriter::WriteUInt32(uint32_t value) { + bool QuicheDataWriter::WriteUInt64(uint64_t value) { + if (endianness_ == quiche::NETWORK_BYTE_ORDER) { + value = quiche::QuicheEndian::HostToNet64(value); ++ } else if (endianness_ == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ value = quiche::QuicheEndian::ByteSwap64(value); + } + return WriteBytes(&value, sizeof(value)); + } +@@ -56,6 +65,9 @@ bool QuicheDataWriter::WriteBytesToUInt64(size_t num_bytes, uint64_t value) { + return false; + } + if (endianness_ == quiche::HOST_BYTE_ORDER) { ++ if (quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ value = quiche::QuicheEndian::ByteSwap64(value); ++ } + return WriteBytes(&value, num_bytes); + } + +diff --git a/quiche/common/quiche_endian.h b/quiche/common/quiche_endian.h +index 2aaa47831..9ab3eecf7 100644 +--- a/quiche/common/quiche_endian.h ++++ b/quiche/common/quiche_endian.h +@@ -18,28 +18,65 @@ enum Endianness { + HOST_BYTE_ORDER // little endian + }; + ++enum HostEndianness { ++ BIG, ++ LITTLE ++}; ++ + // Provide utility functions that convert from/to network order (big endian) + // to/from host order (little endian). + class QUICHE_EXPORT QuicheEndian { + public: +- // Convert |x| from host order (little endian) to network order (big endian). +-#if defined(__clang__) || \ ++ // Get host machine endianness ++#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ ++ __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ++ static const quiche::HostEndianness HostEndianness = quiche::BIG; ++#else ++ static const quiche::HostEndianness HostEndianness = quiche::LITTLE; ++#endif ++ ++ // Convert byte order of |x|. ++ #if defined(__clang__) || \ + (defined(__GNUC__) && \ + ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5)) +- static uint16_t HostToNet16(uint16_t x) { return __builtin_bswap16(x); } +- static uint32_t HostToNet32(uint32_t x) { return __builtin_bswap32(x); } +- static uint64_t HostToNet64(uint64_t x) { return __builtin_bswap64(x); } ++ static uint16_t ByteSwap16(uint16_t x) { return __builtin_bswap16(x); } ++ static uint32_t ByteSwap32(uint32_t x) { return __builtin_bswap32(x); } ++ static uint64_t ByteSwap64(uint64_t x) { return __builtin_bswap64(x); } + #else +- static uint16_t HostToNet16(uint16_t x) { return PortableByteSwap(x); } +- static uint32_t HostToNet32(uint32_t x) { return PortableByteSwap(x); } +- static uint64_t HostToNet64(uint64_t x) { return PortableByteSwap(x); } ++ static uint16_t ByteSwap16(uint16_t x) { return PortableByteSwap(x); } ++ static uint32_t ByteSwap32(uint32_t x) { return PortableByteSwap(x); } ++ static uint64_t ByteSwap64(uint64_t x) { return PortableByteSwap(x); } + #endif + +- // Convert |x| from network order (big endian) to host order (little endian). ++ // Convert |x| from host order to network order (big endian). ++#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ ++ __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ++ static uint16_t HostToNet16(uint16_t x) { return x; } ++ static uint32_t HostToNet32(uint32_t x) { return x; } ++ static uint64_t HostToNet64(uint64_t x) { return x; } ++#else ++ static uint16_t HostToNet16(uint16_t x) { return ByteSwap16(x); } ++ static uint32_t HostToNet32(uint32_t x) { return ByteSwap32(x); } ++ static uint64_t HostToNet64(uint64_t x) { return ByteSwap64(x); } ++#endif ++ ++ // Convert |x| from network order (big endian) to host order. + static uint16_t NetToHost16(uint16_t x) { return HostToNet16(x); } + static uint32_t NetToHost32(uint32_t x) { return HostToNet32(x); } + static uint64_t NetToHost64(uint64_t x) { return HostToNet64(x); } + ++ // Convert |x| from host order to little endian order. ++#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ ++ __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ++ static uint16_t HostToLittleEndian16(uint16_t x) { return ByteSwap16(x); } ++ static uint32_t HostToLittleEndian32(uint32_t x) { return ByteSwap32(x); } ++ static uint64_t HostToLittleEndian64(uint64_t x) { return ByteSwap64(x); } ++#else ++ static uint16_t HostToLittleEndian16(uint16_t x) { return x; } ++ static uint32_t HostToLittleEndian32(uint32_t x) { return x; } ++ static uint64_t HostToLittleEndian64(uint64_t x) { return x; } ++#endif ++ + // Left public for tests. + template + static T PortableByteSwap(T input) { +diff --git a/quiche/common/quiche_endian_test.cc b/quiche/common/quiche_endian_test.cc +index 66527a9a9..04590c29a 100644 +--- a/quiche/common/quiche_endian_test.cc ++++ b/quiche/common/quiche_endian_test.cc +@@ -31,20 +31,20 @@ TEST_F(QuicheEndianTest, Portable) { + } + + TEST_F(QuicheEndianTest, HostToNet) { +- EXPECT_EQ(k16BitSwappedTestData, ++ EXPECT_EQ(quiche::QuicheEndian::HostEndianness == quiche::BIG ? k16BitTestData : k16BitSwappedTestData, + quiche::QuicheEndian::HostToNet16(k16BitTestData)); +- EXPECT_EQ(k32BitSwappedTestData, ++ EXPECT_EQ(quiche::QuicheEndian::HostEndianness == quiche::BIG ? k32BitTestData : k32BitSwappedTestData, + quiche::QuicheEndian::HostToNet32(k32BitTestData)); +- EXPECT_EQ(k64BitSwappedTestData, ++ EXPECT_EQ(quiche::QuicheEndian::HostEndianness == quiche::BIG ? k64BitTestData : k64BitSwappedTestData, + quiche::QuicheEndian::HostToNet64(k64BitTestData)); + } + + TEST_F(QuicheEndianTest, NetToHost) { +- EXPECT_EQ(k16BitTestData, ++ EXPECT_EQ(quiche::QuicheEndian::HostEndianness == quiche::BIG ? k16BitSwappedTestData : k16BitTestData, + quiche::QuicheEndian::NetToHost16(k16BitSwappedTestData)); +- EXPECT_EQ(k32BitTestData, ++ EXPECT_EQ(quiche::QuicheEndian::HostEndianness == quiche::BIG ? k32BitSwappedTestData : k32BitTestData, + quiche::QuicheEndian::NetToHost32(k32BitSwappedTestData)); +- EXPECT_EQ(k64BitTestData, ++ EXPECT_EQ(quiche::QuicheEndian::HostEndianness == quiche::BIG ? k64BitSwappedTestData : k64BitTestData, + quiche::QuicheEndian::NetToHost64(k64BitSwappedTestData)); + } + +diff --git a/quiche/common/quiche_ip_address_test.cc b/quiche/common/quiche_ip_address_test.cc +index 609b6b250..7e201338c 100644 +--- a/quiche/common/quiche_ip_address_test.cc ++++ b/quiche/common/quiche_ip_address_test.cc +@@ -47,16 +47,24 @@ TEST(QuicheIpAddressTest, IPv6) { + + EXPECT_EQ("fe80::1ff:fe23:4567", ip_address.ToString()); + const in6_addr v6_address = ip_address.GetIPv6(); +- const uint16_t* const v6_address_ptr = +- reinterpret_cast(&v6_address); +- EXPECT_EQ(0x80feu, *(v6_address_ptr + 0)); +- EXPECT_EQ(0x0000u, *(v6_address_ptr + 1)); +- EXPECT_EQ(0x0000u, *(v6_address_ptr + 2)); +- EXPECT_EQ(0x0000u, *(v6_address_ptr + 3)); +- EXPECT_EQ(0x0000u, *(v6_address_ptr + 4)); +- EXPECT_EQ(0xff01u, *(v6_address_ptr + 5)); +- EXPECT_EQ(0x23feu, *(v6_address_ptr + 6)); +- EXPECT_EQ(0x6745u, *(v6_address_ptr + 7)); ++ const uint8_t* const v6_address_ptr = ++ reinterpret_cast(&v6_address); ++ EXPECT_EQ(0xfeu, *(v6_address_ptr + 0)); ++ EXPECT_EQ(0x80u, *(v6_address_ptr + 1)); ++ EXPECT_EQ(0x00u, *(v6_address_ptr + 2)); ++ EXPECT_EQ(0x00u, *(v6_address_ptr + 3)); ++ EXPECT_EQ(0x00u, *(v6_address_ptr + 4)); ++ EXPECT_EQ(0x00u, *(v6_address_ptr + 5)); ++ EXPECT_EQ(0x00u, *(v6_address_ptr + 6)); ++ EXPECT_EQ(0x00u, *(v6_address_ptr + 7)); ++ EXPECT_EQ(0x00u, *(v6_address_ptr + 8)); ++ EXPECT_EQ(0x00u, *(v6_address_ptr + 9)); ++ EXPECT_EQ(0x01u, *(v6_address_ptr + 10)); ++ EXPECT_EQ(0xffu, *(v6_address_ptr + 11)); ++ EXPECT_EQ(0xfeu, *(v6_address_ptr + 12)); ++ EXPECT_EQ(0x23u, *(v6_address_ptr + 13)); ++ EXPECT_EQ(0x45u, *(v6_address_ptr + 14)); ++ EXPECT_EQ(0x67u, *(v6_address_ptr + 15)); + + EXPECT_EQ(ip_address, ip_address.Normalized()); + EXPECT_EQ(ip_address, ip_address.DualStacked()); +diff --git a/quiche/quic/core/crypto/crypto_framer.cc b/quiche/quic/core/crypto/crypto_framer.cc +index 1fbe19e90..e7ac3589a 100644 +--- a/quiche/quic/core/crypto/crypto_framer.cc ++++ b/quiche/quic/core/crypto/crypto_framer.cc +@@ -46,6 +46,11 @@ class OneShotVisitor : public CryptoFramerVisitorInterface { + bool error_; + }; + ++bool TagGreater(QuicTag first, QuicTag second) { ++ return quiche::QuicheEndian::HostToLittleEndian32(first) ++ > quiche::QuicheEndian::HostToLittleEndian32(second); ++} ++ + } // namespace + + CryptoFramer::CryptoFramer() +@@ -180,7 +185,7 @@ std::unique_ptr CryptoFramer::ConstructHandshakeMessage( + return nullptr; + } + +- if (it->first > kPAD && need_pad_tag) { ++ if (TagGreater(it->first, kPAD) && need_pad_tag) { + need_pad_tag = false; + if (!WritePadTag(&writer, pad_length, &end_offset)) { + return nullptr; +@@ -207,7 +212,7 @@ std::unique_ptr CryptoFramer::ConstructHandshakeMessage( + // Values + for (auto it = message.tag_value_map().begin(); + it != message.tag_value_map().end(); ++it) { +- if (it->first > kPAD && need_pad_value) { ++ if (TagGreater(it->first, kPAD) && need_pad_value) { + need_pad_value = false; + if (!writer.WriteRepeatedByte('-', pad_length)) { + QUICHE_DCHECK(false) << "Failed to write padding."; +@@ -281,7 +286,7 @@ QuicErrorCode CryptoFramer::Process(absl::string_view input) { + for (unsigned i = 0; i < num_entries_; ++i) { + QuicTag tag; + reader.ReadTag(&tag); +- if (i > 0 && tag <= tags_and_lengths_[i - 1].first) { ++ if (i > 0 && !TagGreater(tag, tags_and_lengths_[i - 1].first)) { + if (tag == tags_and_lengths_[i - 1].first) { + error_detail_ = absl::StrCat("Duplicate tag:", tag); + return QUIC_CRYPTO_DUPLICATE_TAG; +diff --git a/quiche/quic/core/crypto/crypto_framer_test.cc b/quiche/quic/core/crypto/crypto_framer_test.cc +index 5f79f640b..2eef69ee4 100644 +--- a/quiche/quic/core/crypto/crypto_framer_test.cc ++++ b/quiche/quic/core/crypto/crypto_framer_test.cc +@@ -13,6 +13,7 @@ + #include "quiche/quic/core/crypto/crypto_handshake.h" + #include "quiche/quic/core/crypto/crypto_protocol.h" + #include "quiche/quic/core/quic_packets.h" ++#include "quiche/quic/core/quic_tag.h" + #include "quiche/quic/platform/api/quic_logging.h" + #include "quiche/quic/platform/api/quic_test.h" + #include "quiche/quic/test_tools/crypto_test_utils.h" +@@ -46,10 +47,10 @@ class TestCryptoVisitor : public CryptoFramerVisitorInterface { + + TEST(CryptoFramerTest, ConstructHandshakeMessage) { + CryptoHandshakeMessage message; +- message.set_tag(0xFFAA7733); +- message.SetStringPiece(0x12345678, "abcdef"); +- message.SetStringPiece(0x12345679, "ghijk"); +- message.SetStringPiece(0x1234567A, "lmnopqr"); ++ message.set_tag(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF)); ++ message.SetStringPiece(MakeQuicTag(0x78, 0x56, 0x34, 0x12), "abcdef"); ++ message.SetStringPiece(MakeQuicTag(0x79, 0x56, 0x34, 0x12), "ghijk"); ++ message.SetStringPiece(MakeQuicTag(0x7A, 0x56, 0x34, 0x12), "lmnopqr"); + + unsigned char packet[] = {// tag + 0x33, 0x77, 0xAA, 0xFF, +@@ -86,9 +87,9 @@ TEST(CryptoFramerTest, ConstructHandshakeMessage) { + + TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) { + CryptoHandshakeMessage message; +- message.set_tag(0xFFAA7733); +- message.SetStringPiece(0x12345678, "abcdef"); +- message.SetStringPiece(0x12345679, "ghijk"); ++ message.set_tag(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF)); ++ message.SetStringPiece(MakeQuicTag(0x78, 0x56, 0x34, 0x12), "abcdef"); ++ message.SetStringPiece(MakeQuicTag(0x79, 0x56, 0x34, 0x12), "ghijk"); + + unsigned char packet[] = {// tag + 0x33, 0x77, 0xAA, 0xFF, +@@ -120,8 +121,8 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) { + + TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) { + CryptoHandshakeMessage message; +- message.set_tag(0xFFAA7733); +- message.SetStringPiece(0x12345678, ""); ++ message.set_tag(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF)); ++ message.SetStringPiece(MakeQuicTag(0x78, 0x56, 0x34, 0x12), ""); + + unsigned char packet[] = {// tag + 0x33, 0x77, 0xAA, 0xFF, +@@ -145,7 +146,7 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) { + + TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) { + CryptoHandshakeMessage message; +- message.set_tag(0xFFAA7733); ++ message.set_tag(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF)); + for (uint32_t key = 1; key <= kMaxEntries + 1; ++key) { + message.SetStringPiece(key, "abcdef"); + } +@@ -157,8 +158,8 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) { + + TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) { + CryptoHandshakeMessage message; +- message.set_tag(0xFFAA7733); +- message.SetStringPiece(0x01020304, "test"); ++ message.set_tag(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF)); ++ message.SetStringPiece(MakeQuicTag(0x04, 0x03, 0x02, 0x01), "test"); + message.set_minimum_size(64); + + unsigned char packet[] = {// tag +@@ -194,8 +195,8 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) { + + TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) { + CryptoHandshakeMessage message; +- message.set_tag(0xFFAA7733); +- message.SetStringPiece(1, ""); ++ message.set_tag(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF)); ++ message.SetStringPiece(MakeQuicTag(0x01, 0x00, 0x00, 0x00), ""); + message.set_minimum_size(64); + + unsigned char packet[] = {// tag +@@ -257,10 +258,10 @@ TEST(CryptoFramerTest, ProcessInput) { + EXPECT_EQ(0, visitor.error_count_); + ASSERT_EQ(1u, visitor.messages_.size()); + const CryptoHandshakeMessage& message = visitor.messages_[0]; +- EXPECT_EQ(0xFFAA7733, message.tag()); ++ EXPECT_EQ(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF), message.tag()); + EXPECT_EQ(2u, message.tag_value_map().size()); +- EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678)); +- EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679)); ++ EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x78, 0x56, 0x34, 0x12))); ++ EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x79, 0x56, 0x34, 0x12))); + } + + TEST(CryptoFramerTest, ProcessInputWithThreeKeys) { +@@ -299,11 +300,11 @@ TEST(CryptoFramerTest, ProcessInputWithThreeKeys) { + EXPECT_EQ(0, visitor.error_count_); + ASSERT_EQ(1u, visitor.messages_.size()); + const CryptoHandshakeMessage& message = visitor.messages_[0]; +- EXPECT_EQ(0xFFAA7733, message.tag()); ++ EXPECT_EQ(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF), message.tag()); + EXPECT_EQ(3u, message.tag_value_map().size()); +- EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678)); +- EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679)); +- EXPECT_EQ("lmnopqr", crypto_test_utils::GetValueForTag(message, 0x1234567A)); ++ EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x78, 0x56, 0x34, 0x12))); ++ EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x79, 0x56, 0x34, 0x12))); ++ EXPECT_EQ("lmnopqr", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x7A, 0x56, 0x34, 0x12))); + } + + TEST(CryptoFramerTest, ProcessInputIncrementally) { +@@ -336,10 +337,10 @@ TEST(CryptoFramerTest, ProcessInputIncrementally) { + EXPECT_EQ(0u, framer.InputBytesRemaining()); + ASSERT_EQ(1u, visitor.messages_.size()); + const CryptoHandshakeMessage& message = visitor.messages_[0]; +- EXPECT_EQ(0xFFAA7733, message.tag()); ++ EXPECT_EQ(MakeQuicTag(0x33, 0x77, 0xAA, 0xFF), message.tag()); + EXPECT_EQ(2u, message.tag_value_map().size()); +- EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678)); +- EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679)); ++ EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x78, 0x56, 0x34, 0x12))); ++ EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x79, 0x56, 0x34, 0x12))); + } + + TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) { +diff --git a/quiche/quic/core/crypto/crypto_protocol.h b/quiche/quic/core/crypto/crypto_protocol.h +index c1bf0dbc4..0f88c02ef 100644 +--- a/quiche/quic/core/crypto/crypto_protocol.h ++++ b/quiche/quic/core/crypto/crypto_protocol.h +@@ -30,8 +30,14 @@ namespace internal { + // because of the trailing null byte. + constexpr QuicTag MakeStaticQuicTag(const char (&input)[5]) { + constexpr auto u8 = [](char c) { return static_cast(c); }; ++#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ ++ __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ++ return static_cast((u8(input[0]) << 24) | (u8(input[1]) << 16) | ++ (u8(input[2]) << 8) | u8(input[3])); ++#else + return static_cast((u8(input[3]) << 24) | (u8(input[2]) << 16) | + (u8(input[1]) << 8) | u8(input[0])); ++#endif + } + + // A variant for three-character QUIC tags. Pads the end with null bytes. +diff --git a/quiche/quic/core/crypto/crypto_server_test.cc b/quiche/quic/core/crypto/crypto_server_test.cc +index 1bcd97cee..2f63732cd 100644 +--- a/quiche/quic/core/crypto/crypto_server_test.cc ++++ b/quiche/quic/core/crypto/crypto_server_test.cc +@@ -482,7 +482,7 @@ TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) { + {"KEXS", "C255"}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PDMD", "X509"}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); +@@ -555,7 +555,7 @@ TEST_P(CryptoServerTest, BadClientNonce) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", kBadNonces[i]}, + {"NONP", kBadNonces[i]}, +@@ -593,7 +593,7 @@ TEST_P(CryptoServerTest, NoClientNonce) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"XLCT", XlctHexString()}, + {"VER\0", client_version_string_}}, +@@ -632,7 +632,7 @@ TEST_P(CryptoServerTest, CorruptServerConfig) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", (std::string(1, 'X') + scid_hex_)}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}}, +@@ -652,7 +652,7 @@ TEST_P(CryptoServerTest, CorruptSourceAddressToken) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", (std::string(1, 'X') + srct_hex_)}, ++ {"STK\0", (std::string(1, 'X') + srct_hex_)}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"XLCT", XlctHexString()}, +@@ -680,7 +680,7 @@ TEST_P(CryptoServerTest, CorruptSourceAddressTokenIsStillAccepted) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", (std::string(1, 'X') + srct_hex_)}, ++ {"STK\0", (std::string(1, 'X') + srct_hex_)}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"XLCT", XlctHexString()}, +@@ -710,7 +710,7 @@ TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", (std::string(1, 'X') + srct_hex_)}, ++ {"STK\0", (std::string(1, 'X') + srct_hex_)}, + {"PUBS", pub_hex_}, + {"NONC", (std::string(1, 'X') + nonce_hex_)}, + {"XLCT", XlctHexString()}, +@@ -739,7 +739,7 @@ TEST_P(CryptoServerTest, CorruptMultipleTags) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", (std::string(1, 'X') + srct_hex_)}, ++ {"STK\0", (std::string(1, 'X') + srct_hex_)}, + {"PUBS", pub_hex_}, + {"NONC", (std::string(1, 'X') + nonce_hex_)}, + {"NONP", (std::string(1, 'X') + nonce_hex_)}, +@@ -763,7 +763,7 @@ TEST_P(CryptoServerTest, NoServerNonce) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"NONP", nonce_hex_}, +@@ -791,7 +791,7 @@ TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) { + {"KEXS", "C255"}, + {"PDMD", "X509"}, + {"SCID", kOldConfigId}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"NONP", "123456789012345678901234567890"}, +@@ -856,7 +856,7 @@ TEST_P(CryptoServerTest, RejectInvalidXlct) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}, +@@ -895,7 +895,7 @@ TEST_P(CryptoServerTest, ValidXlct) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}, +@@ -931,7 +931,7 @@ TEST_P(CryptoServerTest, NonceInSHLO) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}, +@@ -1159,7 +1159,7 @@ TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}, +@@ -1181,7 +1181,7 @@ TEST_P(CryptoServerTestOldVersion, XlctNotRequired) { + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, +- {"#004b5453", srct_hex_}, ++ {"STK\0", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}}, +diff --git a/quiche/quic/core/quic_crypto_stream_test.cc b/quiche/quic/core/quic_crypto_stream_test.cc +index 27232b468..8571a2395 100644 +--- a/quiche/quic/core/quic_crypto_stream_test.cc ++++ b/quiche/quic/core/quic_crypto_stream_test.cc +@@ -140,8 +140,8 @@ class QuicCryptoStreamTest : public QuicTest { + session_.SetCryptoStream(stream_); + session_.Initialize(); + message_.set_tag(kSHLO); +- message_.SetStringPiece(1, "abc"); +- message_.SetStringPiece(2, "def"); ++ message_.SetStringPiece(MakeQuicTag(0x01, 0x00, 0x00, 0x00), "abc"); ++ message_.SetStringPiece(MakeQuicTag(0x02, 0x00, 0x00, 0x00), "def"); + ConstructHandshakeMessage(); + } + QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete; +@@ -181,8 +181,8 @@ TEST_F(QuicCryptoStreamTest, ProcessRawData) { + const CryptoHandshakeMessage& message = (*stream_->messages())[0]; + EXPECT_EQ(kSHLO, message.tag()); + EXPECT_EQ(2u, message.tag_value_map().size()); +- EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1)); +- EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2)); ++ EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x01, 0x00, 0x00, 0x00))); ++ EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, MakeQuicTag(0x02, 0x00, 0x00, 0x00))); + } + + TEST_F(QuicCryptoStreamTest, ProcessBadData) { +diff --git a/quiche/quic/core/quic_data_writer.cc b/quiche/quic/core/quic_data_writer.cc +index 09f192305..911938400 100644 +--- a/quiche/quic/core/quic_data_writer.cc ++++ b/quiche/quic/core/quic_data_writer.cc +@@ -63,6 +63,9 @@ bool QuicDataWriter::WriteUFloat16(uint64_t value) { + + if (endianness() == quiche::NETWORK_BYTE_ORDER) { + result = quiche::QuicheEndian::HostToNet16(result); ++ } else if (endianness() == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ result = quiche::QuicheEndian::ByteSwap16(result); + } + return WriteBytes(&result, sizeof(result)); + } +diff --git a/quiche/quic/core/quic_data_writer_test.cc b/quiche/quic/core/quic_data_writer_test.cc +index 40262d0d9..0b0e9520e 100644 +--- a/quiche/quic/core/quic_data_writer_test.cc ++++ b/quiche/quic/core/quic_data_writer_test.cc +@@ -143,6 +143,9 @@ TEST_P(QuicDataWriterTest, WriteUFloat16) { + uint16_t result = *reinterpret_cast(writer.data()); + if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) { + result = quiche::QuicheEndian::HostToNet16(result); ++ } else if (GetParam().endianness == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ result = quiche::QuicheEndian::ByteSwap16(result); + } + EXPECT_EQ(test_cases[i].encoded, result); + } +@@ -204,6 +207,9 @@ TEST_P(QuicDataWriterTest, ReadUFloat16) { + uint16_t encoded_ufloat = test_cases[i].encoded; + if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) { + encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat); ++ } else if (GetParam().endianness == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ encoded_ufloat = quiche::QuicheEndian::ByteSwap16(encoded_ufloat); + } + QuicDataReader reader(reinterpret_cast(&encoded_ufloat), 2, + GetParam().endianness); +@@ -221,6 +227,9 @@ TEST_P(QuicDataWriterTest, RoundTripUFloat16) { + uint16_t read_number = i; + if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) { + read_number = quiche::QuicheEndian::HostToNet16(read_number); ++ } else if (GetParam().endianness == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ read_number = quiche::QuicheEndian::ByteSwap16(read_number); + } + QuicDataReader reader(reinterpret_cast(&read_number), 2, + GetParam().endianness); +@@ -253,6 +262,11 @@ TEST_P(QuicDataWriterTest, RoundTripUFloat16) { + encoded1 = quiche::QuicheEndian::NetToHost16(encoded1); + encoded2 = quiche::QuicheEndian::NetToHost16(encoded2); + encoded3 = quiche::QuicheEndian::NetToHost16(encoded3); ++ } else if (GetParam().endianness == quiche::HOST_BYTE_ORDER ++ && quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ encoded1 = quiche::QuicheEndian::ByteSwap16(encoded1); ++ encoded2 = quiche::QuicheEndian::ByteSwap16(encoded2); ++ encoded3 = quiche::QuicheEndian::ByteSwap16(encoded3); + } + EXPECT_EQ(i - 1, encoded1); + // Check roundtrip. +diff --git a/quiche/quic/core/quic_framer.cc b/quiche/quic/core/quic_framer.cc +index a727cada5..563fdc848 100644 +--- a/quiche/quic/core/quic_framer.cc ++++ b/quiche/quic/core/quic_framer.cc +@@ -56,6 +56,7 @@ + #include "quiche/quic/platform/api/quic_flags.h" + #include "quiche/quic/platform/api/quic_ip_address_family.h" + #include "quiche/quic/platform/api/quic_logging.h" ++#include "quiche/common/quiche_endian.h" + #include "quiche/common/quiche_text_utils.h" + #include "quiche/common/wire_serialization.h" + +@@ -1243,7 +1244,7 @@ std::unique_ptr QuicFramer::BuildPublicResetPacket( + const QuicPublicResetPacket& packet) { + CryptoHandshakeMessage reset; + reset.set_tag(kPRST); +- reset.SetValue(kRNON, packet.nonce_proof); ++ reset.SetValue(kRNON, quiche::QuicheEndian::HostToLittleEndian64(packet.nonce_proof)); + if (packet.client_address.host().address_family() != + IpAddressFamily::IP_UNSPEC) { + // packet.client_address is non-empty. +@@ -5348,7 +5349,8 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame, + } + + if (num_ack_blocks > 0) { +- if (!writer->WriteBytes(&num_ack_blocks, 1)) { ++ uint8_t num_ack_blocks_serialized = static_cast(num_ack_blocks); ++ if (!writer->WriteBytes(&num_ack_blocks_serialized, 1)) { + return false; + } + } +diff --git a/quiche/quic/core/quic_socket_address_coder.cc b/quiche/quic/core/quic_socket_address_coder.cc +index 9bf85b2ea..c98021df2 100644 +--- a/quiche/quic/core/quic_socket_address_coder.cc ++++ b/quiche/quic/core/quic_socket_address_coder.cc +@@ -9,6 +9,7 @@ + #include + + #include "quiche/quic/platform/api/quic_ip_address_family.h" ++#include "quiche/common/quiche_endian.h" + + namespace quic { + +@@ -33,10 +34,10 @@ std::string QuicSocketAddressCoder::Encode() const { + uint16_t address_family; + switch (address_.host().address_family()) { + case IpAddressFamily::IP_V4: +- address_family = kIPv4; ++ address_family = quiche::QuicheEndian::HostToLittleEndian16(kIPv4); + break; + case IpAddressFamily::IP_V6: +- address_family = kIPv6; ++ address_family = quiche::QuicheEndian::HostToLittleEndian16(kIPv6); + break; + default: + return serialized; +@@ -44,7 +45,7 @@ std::string QuicSocketAddressCoder::Encode() const { + serialized.append(reinterpret_cast(&address_family), + sizeof(address_family)); + serialized.append(address_.host().ToPackedString()); +- uint16_t port = address_.port(); ++ uint16_t port = quiche::QuicheEndian::HostToLittleEndian16(address_.port()); + serialized.append(reinterpret_cast(&port), sizeof(port)); + return serialized; + } +@@ -57,6 +58,9 @@ bool QuicSocketAddressCoder::Decode(const char* data, size_t length) { + memcpy(&address_family, data, sizeof(address_family)); + data += sizeof(address_family); + length -= sizeof(address_family); ++ if (quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ address_family = quiche::QuicheEndian::ByteSwap16(address_family); ++ } + + size_t ip_length; + switch (address_family) { +@@ -82,6 +86,9 @@ bool QuicSocketAddressCoder::Decode(const char* data, size_t length) { + return false; + } + memcpy(&port, data, length); ++ if (quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ port = quiche::QuicheEndian::ByteSwap16(port); ++ } + + QuicIpAddress ip_address; + ip_address.FromPackedString(reinterpret_cast(&ip[0]), ip_length); +diff --git a/quiche/quic/core/quic_tag.cc b/quiche/quic/core/quic_tag.cc +index 27a71e495..bce4cf32c 100644 +--- a/quiche/quic/core/quic_tag.cc ++++ b/quiche/quic/core/quic_tag.cc +@@ -15,10 +15,16 @@ + #include "absl/strings/escaping.h" + #include "absl/strings/str_split.h" + #include "absl/strings/string_view.h" ++#include "quiche/common/quiche_endian.h" + #include "quiche/common/quiche_text_utils.h" + + namespace quic { + ++bool QuicTagLess::operator()(const QuicTag& a, const QuicTag& b) const { ++ return quiche::QuicheEndian::HostToLittleEndian32(a) ++ < quiche::QuicheEndian::HostToLittleEndian32(b); ++} ++ + bool FindMutualQuicTag(const QuicTagVector& our_tags, + const QuicTagVector& their_tags, QuicTag* out_result, + size_t* out_index) { +@@ -47,17 +53,31 @@ std::string QuicTagToString(QuicTag tag) { + bool ascii = true; + const QuicTag orig_tag = tag; + +- for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) { +- chars[i] = static_cast(tag); +- if ((chars[i] == 0 || chars[i] == '\xff') && +- i == ABSL_ARRAYSIZE(chars) - 1) { +- chars[i] = ' '; ++ if (quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ memcpy(&chars, &tag, sizeof tag); ++ for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) { ++ if ((chars[i] == 0 || chars[i] == '\xff') && ++ i == ABSL_ARRAYSIZE(chars) - 1) { ++ chars[i] = ' '; ++ } ++ if (!absl::ascii_isprint(static_cast(chars[i]))) { ++ ascii = false; ++ break; ++ } + } +- if (!absl::ascii_isprint(static_cast(chars[i]))) { +- ascii = false; +- break; ++ } else { ++ for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) { ++ chars[i] = static_cast(tag); ++ if ((chars[i] == 0 || chars[i] == '\xff') && ++ i == ABSL_ARRAYSIZE(chars) - 1) { ++ chars[i] = ' '; ++ } ++ if (!absl::ascii_isprint(static_cast(chars[i]))) { ++ ascii = false; ++ break; ++ } ++ tag >>= 8; + } +- tag >>= 8; + } + + if (ascii) { +@@ -69,8 +89,13 @@ std::string QuicTagToString(QuicTag tag) { + } + + uint32_t MakeQuicTag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { +- return static_cast(a) | static_cast(b) << 8 | +- static_cast(c) << 16 | static_cast(d) << 24; ++ if (quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ return static_cast(d) | static_cast(c) << 8 | ++ static_cast(b) << 16 | static_cast(a) << 24; ++ } else { ++ return static_cast(a) | static_cast(b) << 8 | ++ static_cast(c) << 16 | static_cast(d) << 24; ++ } + } + + bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) { +@@ -86,12 +111,18 @@ QuicTag ParseQuicTag(absl::string_view tag_string) { + tag_string = tag_bytes; + } + QuicTag tag = 0; +- // Iterate over every character from right to left. +- for (auto it = tag_string.rbegin(); it != tag_string.rend(); ++it) { +- // The cast here is required on platforms where char is signed. +- unsigned char token_char = static_cast(*it); +- tag <<= 8; +- tag |= token_char; ++ if (quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ size_t len = tag_string.length() < sizeof tag ++ ? tag_string.length() : sizeof tag; ++ memcpy(&tag, tag_string.data(), len); ++ } else { ++ // Iterate over every character from right to left. ++ for (auto it = tag_string.rbegin(); it != tag_string.rend(); ++it) { ++ // The cast here is required on platforms where char is signed. ++ unsigned char token_char = static_cast(*it); ++ tag <<= 8; ++ tag |= token_char; ++ } + } + return tag; + } +diff --git a/quiche/quic/core/quic_tag.h b/quiche/quic/core/quic_tag.h +index 2736aac8a..aa3be6c94 100644 +--- a/quiche/quic/core/quic_tag.h ++++ b/quiche/quic/core/quic_tag.h +@@ -24,7 +24,10 @@ namespace quic { + // just a mnemonic for the value 0x504d5845 (little-endian version of the ASCII + // string E X M P). + using QuicTag = uint32_t; +-using QuicTagValueMap = std::map; ++struct QUICHE_NO_EXPORT QuicTagLess { ++ bool operator()(const QuicTag& a, const QuicTag& b) const; ++}; ++using QuicTagValueMap = std::map; + using QuicTagVector = std::vector; + + // MakeQuicTag returns a value given the four bytes. For example: +diff --git a/quiche/quic/core/quic_utils.cc b/quiche/quic/core/quic_utils.cc +index 1bdf10834..9fab7a2e3 100644 +--- a/quiche/quic/core/quic_utils.cc ++++ b/quiche/quic/core/quic_utils.cc +@@ -137,8 +137,8 @@ absl::uint128 QuicUtils::FNV1a_128_Hash_Three(absl::string_view data1, + + // static + void QuicUtils::SerializeUint128Short(absl::uint128 v, uint8_t* out) { +- const uint64_t lo = absl::Uint128Low64(v); +- const uint64_t hi = absl::Uint128High64(v); ++ const uint64_t lo = quiche::QuicheEndian::HostToLittleEndian64(absl::Uint128Low64(v)); ++ const uint64_t hi = quiche::QuicheEndian::HostToLittleEndian64(absl::Uint128High64(v)); + // This assumes that the system is little-endian. + memcpy(out, &lo, sizeof(lo)); + memcpy(out + sizeof(lo), &hi, sizeof(hi) / 2); +diff --git a/quiche/quic/core/quic_versions.cc b/quiche/quic/core/quic_versions.cc +index f40cc334a..9f3a12b92 100644 +--- a/quiche/quic/core/quic_versions.cc ++++ b/quiche/quic/core/quic_versions.cc +@@ -196,7 +196,11 @@ std::ostream& operator<<(std::ostream& os, + } + + QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { +- return MakeQuicTag(d, c, b, a); ++ if (quiche::QuicheEndian::HostEndianness == quiche::BIG) { ++ return MakeQuicTag(a, b, c, d); ++ } else { ++ return MakeQuicTag(d, c, b, a); ++ } + } + + std::ostream& operator<<(std::ostream& os, +diff --git a/quiche/quic/test_tools/crypto_test_utils.cc b/quiche/quic/test_tools/crypto_test_utils.cc +index f062ef200..7307f2e73 100644 +--- a/quiche/quic/test_tools/crypto_test_utils.cc ++++ b/quiche/quic/test_tools/crypto_test_utils.cc +@@ -46,6 +46,7 @@ + #include "quiche/quic/test_tools/simple_quic_framer.h" + #include "quiche/quic/test_tools/test_certificates.h" + #include "quiche/common/platform/api/quiche_logging.h" ++#include "quiche/common/quiche_endian.h" + #include "quiche/common/quiche_callbacks.h" + #include "quiche/common/test_tools/quiche_test_utils.h" + +@@ -786,6 +787,7 @@ QuicTag ParseTag(const char* tagstr) { + tag |= static_cast(tagstr[i]) << 24; + } + } ++ tag = quiche::QuicheEndian::HostToLittleEndian32(tag); + + return tag; + } +diff --git a/quiche/quic/test_tools/quic_test_utils.cc b/quiche/quic/test_tools/quic_test_utils.cc +index 2b49ce27a..6c4e8566a 100644 +--- a/quiche/quic/test_tools/quic_test_utils.cc ++++ b/quiche/quic/test_tools/quic_test_utils.cc +@@ -218,7 +218,7 @@ bool ClearControlFrameWithTransmissionType(const QuicFrame& frame, + uint64_t SimpleRandom::RandUint64() { + uint64_t result; + RandBytes(&result, sizeof(result)); +- return result; ++ return quiche::QuicheEndian::HostToLittleEndian64(result);; + } + + void SimpleRandom::RandBytes(void* data, size_t len) { +@@ -252,6 +252,7 @@ void SimpleRandom::FillBuffer() { + + void SimpleRandom::set_seed(uint64_t seed) { + static_assert(sizeof(key_) == SHA256_DIGEST_LENGTH, "Key has to be 256 bits"); ++ seed = quiche::QuicheEndian::HostToLittleEndian64(seed); + SHA256(reinterpret_cast(&seed), sizeof(seed), key_); + + memset(buffer_, 0, sizeof(buffer_)); diff --git a/bazel/foreign_cc/BUILD b/bazel/foreign_cc/BUILD index bc9c7d27d80..6c3c2b05c98 100644 --- a/bazel/foreign_cc/BUILD +++ b/bazel/foreign_cc/BUILD @@ -258,6 +258,24 @@ envoy_cmake( deps = ["//bazel:boringssl"], ) +configure_make( + name = "luajit2", + configure_command = "build.py", + env = select({ + # This shouldn't be needed! See + # https://github.com/envoyproxy/envoy/issues/6084 + # TODO(htuch): Remove when #6084 is fixed + "//bazel:asan_build": {"ENVOY_CONFIG_ASAN": "1"}, + "//bazel:msan_build": {"ENVOY_CONFIG_MSAN": "1"}, + "//conditions:default": {}, + }), + lib_source = "@com_github_luajit2_luajit2//:all", + out_include_dir = "include/luajit-2.1", + out_static_libs = ["libluajit-5.1.a"], + tags = ["skip_on_windows"], + targets = [], +) + envoy_cmake( name = "ares", build_args = select({ @@ -478,12 +496,12 @@ envoy_cmake( tags = ["skip_on_windows"], ) + envoy_cc_library( - name = "maxmind_linux_darwin", + name = "maxmind_linux", srcs = [], deps = select({ "//bazel:linux": [":maxmind"], - "//bazel:darwin_any": [":maxmind"], "//conditions:default": [], }), ) diff --git a/bazel/foreign_cc/luajit2.patch b/bazel/foreign_cc/luajit2.patch new file mode 100644 index 00000000000..e1263febc6f --- /dev/null +++ b/bazel/foreign_cc/luajit2.patch @@ -0,0 +1,99 @@ +diff --git a/build.py b/build.py +new file mode 100644 +index 00000000..dab3606c +--- /dev/null ++++ b/build.py +@@ -0,0 +1,49 @@ ++#!/usr/bin/env python3 ++ ++import argparse ++import os ++import shutil ++import subprocess ++ ++def main(): ++ parser = argparse.ArgumentParser() ++ parser.add_argument("--prefix") ++ args = parser.parse_args() ++ src_dir = os.path.dirname(os.path.realpath(__file__)) ++ shutil.copytree(src_dir, os.path.basename(src_dir)) ++ os.chdir(os.path.basename(src_dir)) ++ ++ os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.6" ++ os.environ["DEFAULT_CC"] = os.environ.get("CC", "") ++ os.environ["TARGET_CFLAGS"] = os.environ.get("CFLAGS", "") + " -fno-function-sections -fno-data-sections" ++ os.environ["TARGET_LDFLAGS"] = os.environ.get("CFLAGS", "") + " -fno-function-sections -fno-data-sections" ++ os.environ["CFLAGS"] = "" ++ # LuaJIT compile process build a tool `buildvm` and use it, building `buildvm` with ASAN ++ # will cause LSAN detect its leak and fail the build, set exitcode to 0 to make LSAN doesn't ++ # fail on it. ++ os.environ["LSAN_OPTIONS"] = "exitcode=0" ++ ++ if "ENVOY_MSAN" in os.environ: ++ os.environ["HOST_CFLAGS"] = "-fno-sanitize=memory" ++ os.environ["HOST_LDFLAGS"] = "-fno-sanitize=memory" ++ ++ arch = subprocess.check_output(["uname","-m"]).decode("utf-8").strip() ++ compiler = os.environ.get("CC", "") ++ if "clang" in compiler and arch in ["s390x","ppc64le"]: ++ extra_clang_cflags = " -fgnuc-version=10 -fno-integrated-as -Wno-implicit-function-declaration -D_Float32=float -D_Float64=double -D_Float128=double -D_Float32x=double -D_Float64x=double" ++ os.environ["TARGET_CFLAGS"] += extra_clang_cflags ++ os.environ["TARGET_LDFLAGS"] += " -fgnuc-version=10" ++ os.environ["HOST_CFLAGS"] = os.environ.get("HOST_CFLAGS", "") + extra_clang_cflags ++ os.environ["HOST_LDFLAGS"] = os.environ.get("HOST_LDFLAGS", "") + " -fgnuc-version=10" ++ ++ # Remove LuaJIT from ASAN for now. ++ # TODO(htuch): Remove this when https://github.com/envoyproxy/envoy/issues/6084 is resolved. ++ if "ENVOY_CONFIG_ASAN" in os.environ or "ENVOY_CONFIG_MSAN" in os.environ: ++ os.environ["TARGET_CFLAGS"] += " -fsanitize-blacklist=%s/com_github_luajit_luajit/clang-asan-blocklist.txt" % os.environ["PWD"] ++ with open("clang-asan-blocklist.txt", "w") as f: ++ f.write("fun:*\n") ++ ++ os.system('make -j{} V=1 PREFIX="{}" install'.format(os.cpu_count(), args.prefix)) ++ ++main() ++ +diff --git a/src/Makefile b/src/Makefile +index acbe0ca7..313a7e44 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -27,7 +27,7 @@ NODOTABIVER= 51 + DEFAULT_CC = gcc + # + # LuaJIT builds as a native 32 or 64 bit binary by default. +-CC= $(DEFAULT_CC) ++CC ?= $(DEFAULT_CC) + # + # Use this if you want to force a 32 bit build on a 64 bit multilib OS. + #CC= $(DEFAULT_CC) -m32 +@@ -71,10 +71,10 @@ CCWARN= -Wall + # as dynamic mode. + # + # Mixed mode creates a static + dynamic library and a statically linked luajit. +-BUILDMODE= mixed ++#BUILDMODE= mixed + # + # Static mode creates a static library and a statically linked luajit. +-#BUILDMODE= static ++BUILDMODE= static + # + # Dynamic mode creates a dynamic library and a dynamically linked luajit. + # Note: this executable will only run when the library is installed! +@@ -99,7 +99,7 @@ XCFLAGS= + # enabled by default. Some other features that *might* break some existing + # code (e.g. __pairs or os.execute() return values) can be enabled here. + # Note: this does not provide full compatibility with Lua 5.2 at this time. +-#XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT ++XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT + # + # Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter. + #XCFLAGS+= -DLUAJIT_DISABLE_JIT +@@ -617,7 +617,7 @@ endif + + Q= @ + E= @echo +-#Q= ++Q= + #E= @: + + ############################################################################## diff --git a/bazel/jwt_verify_lib.patch b/bazel/jwt_verify_lib.patch index b16db530d6f..a6ce11bcbee 100644 --- a/bazel/jwt_verify_lib.patch +++ b/bazel/jwt_verify_lib.patch @@ -184,3 +184,48 @@ index 28247dd..e35142b 100644 + "@com_google_googletest//:gtest_main", ], ) +diff --git a/src/jwt.cc b/src/jwt.cc +index 2c22eb4..f2cbf5e 100644 +--- a/src/jwt.cc ++++ b/src/jwt.cc +@@ -48,7 +48,11 @@ Jwt& Jwt::operator=(const Jwt& rhs) { + } + + Status Jwt::parseFromString(const std::string& jwt) { +- // jwt must have exactly 2 dots with 3 sections. ++ // jwt must have exactly 2 dots... ++ if (std::count(jwt.begin(), jwt.end(), '.') != 2) { ++ return Status::JwtBadFormat; ++ } ++ // ...and 3 sections + jwt_ = jwt; + std::vector jwt_split = + absl::StrSplit(jwt, '.', absl::SkipEmpty()); +diff --git a/src/verify.cc b/src/verify.cc +index 70eb817..1fcd235 100644 +--- a/src/verify.cc ++++ b/src/verify.cc +@@ -132,12 +132,20 @@ bool verifySignatureEC(EC_KEY* key, const EVP_MD* md, const uint8_t* signature, + return false; + } + +- if (BN_bin2bn(signature, signature_len / 2, ecdsa_sig->r) == nullptr || +- BN_bin2bn(signature + (signature_len / 2), signature_len / 2, +- ecdsa_sig->s) == nullptr) { ++ bssl::UniquePtr ecdsa_sig_r {BN_bin2bn(signature, signature_len / 2, nullptr)}; ++ bssl::UniquePtr ecdsa_sig_s {BN_bin2bn(signature + (signature_len / 2), signature_len / 2, nullptr)}; ++ ++ if (ecdsa_sig_r.get() == nullptr || ecdsa_sig_s.get() == nullptr) { + return false; + } + ++ if (ECDSA_SIG_set0(ecdsa_sig.get(), ecdsa_sig_r.get(), ecdsa_sig_s.get()) == 0) { ++ return false; ++ } ++ ++ ecdsa_sig_r.release(); ++ ecdsa_sig_s.release(); ++ + if (ECDSA_do_verify(digest.data(), digest_len, ecdsa_sig.get(), key) == 1) { + return true; + } diff --git a/bazel/proxy_wasm_cpp_host-s390x.patch b/bazel/proxy_wasm_cpp_host-s390x.patch new file mode 100644 index 00000000000..0b6af223c0f --- /dev/null +++ b/bazel/proxy_wasm_cpp_host-s390x.patch @@ -0,0 +1,55 @@ +diff --git a/src/exports.cc b/src/exports.cc +index 25ca06c..f952880 100644 +--- a/src/exports.cc ++++ b/src/exports.cc +@@ -266,7 +266,7 @@ Word register_shared_queue(Word queue_name_ptr, Word queue_name_size, Word token + if (result != WasmResult::Ok) { + return result; + } +- if (!context->wasm()->setDatatype(token_ptr, token)) { ++ if (!context->wasm()->setDatatype(token_ptr, htowasm(token, context->wasmVm()->usesWasmByteOrder()))) { + return WasmResult::InvalidMemoryAccess; + } + return WasmResult::Ok; +@@ -298,7 +298,7 @@ Word resolve_shared_queue(Word vm_id_ptr, Word vm_id_size, Word queue_name_ptr, + if (result != WasmResult::Ok) { + return result; + } +- if (!context->wasm()->setDatatype(token_ptr, token)) { ++ if (!context->wasm()->setDatatype(token_ptr, htowasm(token, context->wasmVm()->usesWasmByteOrder()))) { + return WasmResult::InvalidMemoryAccess; + } + return WasmResult::Ok; +@@ -524,12 +524,12 @@ Word http_call(Word uri_ptr, Word uri_size, Word header_pairs_ptr, Word header_p + uint32_t token = 0; + // NB: try to write the token to verify the memory before starting the async + // operation. +- if (!context->wasm()->setDatatype(token_ptr, token)) { ++ if (!context->wasm()->setDatatype(token_ptr, htowasm(token, context->wasmVm()->usesWasmByteOrder()))) { + return WasmResult::InvalidMemoryAccess; + } + auto result = + context->httpCall(uri.value(), headers, body.value(), trailers, timeout_milliseconds, &token); +- context->wasm()->setDatatype(token_ptr, token); ++ context->wasm()->setDatatype(token_ptr, htowasm(token, context->wasmVm()->usesWasmByteOrder())); + return result; + } + +@@ -596,7 +596,7 @@ Word grpc_call(Word service_ptr, Word service_size, Word service_name_ptr, Word + if (result != WasmResult::Ok) { + return result; + } +- if (!context->wasm()->setDatatype(token_ptr, token)) { ++ if (!context->wasm()->setDatatype(token_ptr, htowasm(token, context->wasmVm()->usesWasmByteOrder()))) { + return WasmResult::InvalidMemoryAccess; + } + return WasmResult::Ok; +@@ -621,7 +621,7 @@ Word grpc_stream(Word service_ptr, Word service_size, Word service_name_ptr, Wor + if (result != WasmResult::Ok) { + return result; + } +- if (!context->wasm()->setDatatype(token_ptr, token)) { ++ if (!context->wasm()->setDatatype(token_ptr, htowasm(token, context->wasmVm()->usesWasmByteOrder()))) { + return WasmResult::InvalidMemoryAccess; + } + return WasmResult::Ok; diff --git a/bazel/proxy_wasm_cpp_host.patch b/bazel/proxy_wasm_cpp_host.patch index 5d069c5bfea..6ba711044cf 100644 --- a/bazel/proxy_wasm_cpp_host.patch +++ b/bazel/proxy_wasm_cpp_host.patch @@ -364,3 +364,28 @@ index aaf7bd2..b1234567 100644 -- 2.50.0.727.gbf7dc18ff4-goog +diff --git a/bazel/BUILD b/bazel/BUILD +index 650fa29..733c975 100644 +--- a/bazel/BUILD ++++ b/bazel/BUILD +@@ -57,19 +57,6 @@ config_setting( + ) + + config_setting( +- name = "requested_crypto_system", +- values = {"define": "crypto=system"}, +-) +- +-config_setting( +- name = "linux_s390x", +- values = {"cpu": "s390x"}, +-) +- +-selects.config_setting_group( + name = "crypto_system", +- match_any = [ +- ":requested_crypto_system", +- ":linux_s390x", +- ], ++ values = {"define": "crypto=system"}, + ) diff --git a/bazel/rbe/toolchains/configs/linux/clang_libcxx/config/BUILD b/bazel/rbe/toolchains/configs/linux/clang_libcxx/config/BUILD new file mode 100755 index 00000000000..ba42a15f230 --- /dev/null +++ b/bazel/rbe/toolchains/configs/linux/clang_libcxx/config/BUILD @@ -0,0 +1,81 @@ +licenses(["notice"]) # Apache 2 + +# Copyright 2020 The Bazel Authors. All rights reserved. +# +# 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. + +# This file is auto-generated by github.com/bazelbuild/bazel-toolchains/pkg/rbeconfigsgen +# and should not be modified directly. + +package(default_visibility = ["//visibility:public"]) + +CACHE_SILO_KEY = "llvm-18" + +toolchain( + name = "cc-toolchain", + exec_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + "@bazel_tools//tools/cpp:clang", + ], + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + toolchain = "//bazel/rbe/toolchains/configs/linux/clang_libcxx/cc:cc-compiler-k8", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +platform( + name = "platform", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + "@bazel_tools//tools/cpp:clang", + ], + exec_properties = { + "container-image": "docker://gcr.io/envoy-ci/envoy-build@sha256:95d7afdea0f0f8881e88fa5e581db4f50907d0745ac8d90e00357ac1a316abe5", + "OSFamily": "Linux", + }, + parents = ["@local_config_platform//:host"], +) + +toolchain( + name = "cc-toolchain-arm64", + exec_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + "@bazel_tools//tools/cpp:clang", + ], + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], + toolchain = "//bazel/rbe/toolchains/configs/linux/clang_libcxx/cc:cc-compiler-aarch64", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +platform( + name = "platform-arm64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + "@bazel_tools//tools/cpp:clang", + ], + exec_properties = { + "container-image": "docker://gcr.io/envoy-ci/envoy-build@sha256:56b66cc84065c88a141963cedbbe4198850ffae0dacad769f516d0e9081439da", + "OSFamily": "Linux", + "Pool": "arm", + }, + parents = ["@local_config_platform//:host"], +) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index da7e6ae25de..0a5bf320bbf 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -3,7 +3,8 @@ load("@envoy_api//bazel:envoy_http_archive.bzl", "envoy_http_archive") load("@envoy_api//bazel:external_deps.bzl", "load_repository_locations") load(":repository_locations.bzl", "PROTOC_VERSIONS", "REPOSITORY_LOCATIONS_SPEC") -PPC_SKIP_TARGETS = ["envoy.string_matcher.lua", "envoy.filters.http.lua", "envoy.router.cluster_specifier_plugin.lua"] +# ppc64le uses luajit2 so http.lua can be built +PPC_SKIP_TARGETS = [] WINDOWS_SKIP_TARGETS = [ "envoy.extensions.http.cache.file_system_http_cache", @@ -129,13 +130,21 @@ def envoy_dependencies(skip_targets = []): # Setup external Bazel rules _foreign_cc_dependencies() - # BoringSSL: - # - BoringSSL FIPS from @boringssl_fips//:ssl, - # - non-FIPS BoringSSL from @boringssl//:ssl. - # SSL/crypto dependencies are resolved via EXTERNAL_DEPS_MAP in envoy_internal.bzl + # Load both SSL backends - the actual one used is selected via --define=ssl= _boringssl() _boringssl_fips() - _aws_lc() + _openssl() + + # Binding to an alias that selects between BoringSSL and OpenSSL via bssl-compat + # The selection is made in //bazel:boringssl and //bazel:boringcrypto aliases + native.bind( + name = "ssl", + actual = "@envoy//bazel:boringssl", + ) + native.bind( + name = "crypto", + actual = "@envoy//bazel:boringcrypto", + ) # The long repo names (`com_github_fmtlib_fmt` instead of `fmtlib`) are # semi-standard in the Bazel community, intended to avoid both duplicate @@ -170,6 +179,7 @@ def envoy_dependencies(skip_targets = []): _com_github_jbeder_yaml_cpp() _com_github_libevent_libevent() _com_github_luajit_luajit() + _com_github_luajit2_luajit2() _com_github_nghttp2_nghttp2() _com_github_msgpack_cpp() _com_github_skyapm_cpp2sky() @@ -249,7 +259,14 @@ def envoy_dependencies(skip_targets = []): ) def _boringssl(): - external_http_archive(name = "boringssl") + external_http_archive( + name = "boringssl", + patches = [ + "@envoy//bazel:boringssl-bssl-compat.patch", + "@envoy//bazel:boringssl-s390x-ppc64le.patch", + ], + patch_args = ["-p1"], + ) def _boringssl_fips(): external_http_archive( @@ -290,6 +307,12 @@ def _aws_lc(): build_file = "@envoy//bazel/external:aws_lc.BUILD", ) +def _openssl(): + external_http_archive( + name = "openssl", + build_file = "@envoy//bazel/external:openssl.BUILD", + ) + def _com_github_openhistogram_libcircllhist(): external_http_archive( name = "com_github_openhistogram_libcircllhist", @@ -729,6 +752,8 @@ def _com_github_google_quiche(): name = "com_github_google_quiche", patch_cmds = ["find quiche/ -type f -name \"*.bazel\" -delete"], build_file = "@envoy//bazel/external:quiche.BUILD", + patches = ["@envoy//bazel/external:quiche-s390x.patch"], + patch_args = ["-p1"], ) def _googleurl(): @@ -749,7 +774,6 @@ def _com_github_grpc_grpc(): name = "com_github_grpc_grpc", patch_args = ["-p1"], patches = ["@envoy//bazel:grpc.patch"], - repo_mapping = {"@openssl": "@boringssl"}, ) external_http_archive( "build_bazel_rules_apple", @@ -781,6 +805,7 @@ def _proxy_wasm_cpp_host(): patch_args = ["-p1"], patches = [ "@envoy//bazel:proxy_wasm_cpp_host.patch", + "@envoy//bazel:proxy_wasm_cpp_host-s390x.patch", ], ) @@ -806,6 +831,25 @@ def _com_github_luajit_luajit(): patch_args = ["-p1"], ) + native.bind( + name = "luajit", + actual = "@envoy//bazel/foreign_cc:luajit", + ) + +def _com_github_luajit2_luajit2(): + external_http_archive( + name = "com_github_luajit2_luajit2", + build_file_content = BUILD_ALL_CONTENT, + patches = ["@envoy//bazel/foreign_cc:luajit2.patch"], + patch_args = ["-p1"], + patch_cmds = ["chmod u+x build.py"], + ) + + native.bind( + name = "luajit2", + actual = "@envoy//bazel/foreign_cc:luajit2", + ) + def _com_github_google_tcmalloc(): external_http_archive( name = "com_github_google_tcmalloc", @@ -911,8 +955,11 @@ def _rules_ruby(): def _foreign_cc_dependencies(): external_http_archive( name = "rules_foreign_cc", - patches = ["@envoy//bazel:rules_foreign_cc.patch"], patch_args = ["-p1"], + patches = [ + "@envoy//bazel:rules_foreign_cc.patch", + "@envoy//bazel:rules_foreign_cc-s390x.patch", + ], ) def _com_github_maxmind_libmaxminddb(): @@ -920,3 +967,8 @@ def _com_github_maxmind_libmaxminddb(): name = "com_github_maxmind_libmaxminddb", build_file_content = BUILD_ALL_CONTENT, ) + native.bind( + name = "maxmind", + actual = "@envoy//bazel/foreign_cc:maxmind_linux", + ) + diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index bd869f8b5d5..b7da3ee2cb9 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -174,6 +174,20 @@ REPOSITORY_LOCATIONS_SPEC = dict( release_date = "2025-12-01", cpe = "cpe:2.3:a:google:boringssl:*", ), + openssl = dict( + project_name = "OpenSSL", + project_desc = "TLS/SSL and crypto library", + project_url = "https://github.com/openssl/openssl", + version = "3.0.16", + sha256 = "57e03c50feab5d31b152af2b764f10379aecd8ee92f16c985983ce4a99f7ef86", + strip_prefix = "openssl-{version}", + urls = ["https://github.com/openssl/openssl/releases/download/openssl-{version}/openssl-{version}.tar.gz"], + use_category = ["controlplane", "dataplane_core"], + release_date = "2025-02-11", + cpe = "cpe:2.3:a:openssl:openssl:*", + license = "Apache-2.0", + license_url = "https://github.com/openssl/openssl/blob/openssl-{version}/LICENSE.txt", + ), aspect_bazel_lib = dict( project_name = "Aspect Bazel helpers", project_desc = "Base Starlark libraries and basic Bazel rules which are useful for constructing rulesets and BUILD files", @@ -578,6 +592,19 @@ REPOSITORY_LOCATIONS_SPEC = dict( license = "MIT", license_url = "https://github.com/LuaJIT/LuaJIT/blob/{version}/COPYRIGHT", ), + com_github_luajit2_luajit2 = dict( + project_name = "Luajit2", + project_desc = "Openresty/luajit2 - OpenResty's maintained branch of LuaJIT", + project_url = "https://github.com/openresty/luajit2", + version = "1085a4d562b449e7be9e4508b52a19651bdf04a6", + sha256 = "2f6931ecac967e8fafffe934a8445593deff9f4c6ece1684fea1277edd0931ee", + strip_prefix = "luajit2-{version}", + urls = ["https://github.com/openresty/luajit2/archive/{version}.tar.gz"], + use_category = ["dataplane_ext"], + extensions = ["envoy.filters.http.lua"], + release_date = "2021-11-17", + cpe = "cpe:2.3:a:luajit2:luajit2:*", + ), com_github_nghttp2_nghttp2 = dict( project_name = "Nghttp2", project_desc = "Implementation of HTTP/2 and its header compression algorithm HPACK in C", diff --git a/bazel/rules_foreign_cc-s390x.patch b/bazel/rules_foreign_cc-s390x.patch new file mode 100644 index 00000000000..283f3032ad8 --- /dev/null +++ b/bazel/rules_foreign_cc-s390x.patch @@ -0,0 +1,31 @@ +t a/toolchains/built_toolchains.bzl b/toolchains/built_toolchains.bzl +index e2b5e5e..9613308 100644 +--- a/toolchains/built_toolchains.bzl ++++ b/toolchains/built_toolchains.bzl +@@ -343,6 +343,9 @@ cc_import( + + # This patch fixes explicit integer conversion which causes errors in clang >= 15 and gcc >= 14 + Label("//toolchains/patches:pkgconfig-builtin-glib-int-conversion.patch"), ++ ++ # This patch is required to overcome type mismatch error ++ Label("//toolchains/patches:pkgconfig-valgrind.patch"), + ], + urls = [ + "https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz", +diff --git a/toolchains/patches/pkgconfig-valgrind.patch b/toolchains/patches/pkgconfig-valgrind.patch +new file mode 100644 +index 0000000..d376dfb +--- /dev/null ++++ b/toolchains/patches/pkgconfig-valgrind.patch +@@ -0,0 +1,11 @@ ++--- glib/glib/valgrind.h +++++ glib/glib/valgrind.h.new ++@@ -643,7 +643,7 @@ ++ /* results = r3 */ \ ++ "lgr %0, 3\n\t" \ ++ : "=d" (_zzq_result) \ ++- : "a" (&_zzq_args[0]), "0" (_zzq_default) \ +++ : "a" (&_zzq_args[0]), "0" ((unsigned long long int)(_zzq_default)) \ ++ : "cc", "2", "3", "memory" \ ++ ); \ ++ _zzq_result; \ diff --git a/bazel/rules_foreign_cc.patch b/bazel/rules_foreign_cc.patch index 147ea52e349..76e33134960 100644 --- a/bazel/rules_foreign_cc.patch +++ b/bazel/rules_foreign_cc.patch @@ -1,4 +1,4 @@ -diff --git a/toolchains/private/BUILD.bazel b/toolchains/private/BUILD.bazel +t a/toolchains/private/BUILD.bazel b/toolchains/private/BUILD.bazel index 4ccdeef..25658e9 100644 --- a/toolchains/private/BUILD.bazel +++ b/toolchains/private/BUILD.bazel diff --git a/bssl-compat/BUILD b/bssl-compat/BUILD new file mode 100644 index 00000000000..d4a87578737 --- /dev/null +++ b/bssl-compat/BUILD @@ -0,0 +1,912 @@ +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") +load("//:bazel/rules.bzl", "patched_bssl_filegroup", "mapping_func_filegroup") + +licenses(["notice"]) # Apache 2 + +# This genrule runs the prefixer tool to process OpenSSL headers. +# It generates: +# - source/ossl.c: Forwarding functions that call OpenSSL via dlopen/dlsym +# - include/ossl.h: Header declaring the ossl struct with function pointers +# - include/ossl/openssl/*.h: Prefixed OpenSSL headers with ossl_ prefix +genrule( + name = "prefixed_ossl_source", + srcs = [ + "@openssl//:include", + "@llvm_toolchain_llvm//:include", + ], + outs = [ + "source/ossl.c", + "include/ossl.h", + "include/ossl/openssl/aes.h", + "include/ossl/openssl/asn1.h", + "include/ossl/openssl/asn1err.h", + "include/ossl/openssl/asn1t.h", + "include/ossl/openssl/async.h", + "include/ossl/openssl/asyncerr.h", + "include/ossl/openssl/bio.h", + "include/ossl/openssl/bioerr.h", + "include/ossl/openssl/blowfish.h", + "include/ossl/openssl/bn.h", + "include/ossl/openssl/bnerr.h", + "include/ossl/openssl/buffer.h", + "include/ossl/openssl/buffererr.h", + "include/ossl/openssl/camellia.h", + "include/ossl/openssl/cast.h", + "include/ossl/openssl/cmac.h", + "include/ossl/openssl/cmp.h", + "include/ossl/openssl/cmp_util.h", + "include/ossl/openssl/cmperr.h", + "include/ossl/openssl/cms.h", + "include/ossl/openssl/cmserr.h", + "include/ossl/openssl/comp.h", + "include/ossl/openssl/comperr.h", + "include/ossl/openssl/conf.h", + "include/ossl/openssl/conf_api.h", + "include/ossl/openssl/conferr.h", + "include/ossl/openssl/configuration.h", + "include/ossl/openssl/conftypes.h", + "include/ossl/openssl/core.h", + "include/ossl/openssl/core_dispatch.h", + "include/ossl/openssl/core_names.h", + "include/ossl/openssl/core_object.h", + "include/ossl/openssl/crmf.h", + "include/ossl/openssl/crmferr.h", + "include/ossl/openssl/crypto.h", + "include/ossl/openssl/cryptoerr.h", + "include/ossl/openssl/cryptoerr_legacy.h", + "include/ossl/openssl/ct.h", + "include/ossl/openssl/cterr.h", + "include/ossl/openssl/decoder.h", + "include/ossl/openssl/decodererr.h", + "include/ossl/openssl/des.h", + "include/ossl/openssl/dh.h", + "include/ossl/openssl/dherr.h", + "include/ossl/openssl/dsa.h", + "include/ossl/openssl/dsaerr.h", + "include/ossl/openssl/dtls1.h", + "include/ossl/openssl/e_os2.h", + "include/ossl/openssl/ebcdic.h", + "include/ossl/openssl/ec.h", + "include/ossl/openssl/ecdh.h", + "include/ossl/openssl/ecdsa.h", + "include/ossl/openssl/ecerr.h", + "include/ossl/openssl/encoder.h", + "include/ossl/openssl/encodererr.h", + "include/ossl/openssl/engine.h", + "include/ossl/openssl/engineerr.h", + "include/ossl/openssl/err.h", + "include/ossl/openssl/ess.h", + "include/ossl/openssl/esserr.h", + "include/ossl/openssl/evp.h", + "include/ossl/openssl/evperr.h", + "include/ossl/openssl/fips_names.h", + "include/ossl/openssl/fipskey.h", + "include/ossl/openssl/hmac.h", + "include/ossl/openssl/http.h", + "include/ossl/openssl/httperr.h", + "include/ossl/openssl/idea.h", + "include/ossl/openssl/kdf.h", + "include/ossl/openssl/kdferr.h", + "include/ossl/openssl/lhash.h", + "include/ossl/openssl/macros.h", + "include/ossl/openssl/md2.h", + "include/ossl/openssl/md4.h", + "include/ossl/openssl/md5.h", + "include/ossl/openssl/mdc2.h", + "include/ossl/openssl/modes.h", + "include/ossl/openssl/obj_mac.h", + "include/ossl/openssl/objects.h", + "include/ossl/openssl/objectserr.h", + "include/ossl/openssl/ocsp.h", + "include/ossl/openssl/ocsperr.h", + "include/ossl/openssl/opensslconf.h", + "include/ossl/openssl/opensslv.h", + "include/ossl/openssl/ossl_typ.h", + "include/ossl/openssl/param_build.h", + "include/ossl/openssl/params.h", + "include/ossl/openssl/pem.h", + "include/ossl/openssl/pem2.h", + "include/ossl/openssl/pemerr.h", + "include/ossl/openssl/pkcs12.h", + "include/ossl/openssl/pkcs12err.h", + "include/ossl/openssl/pkcs7.h", + "include/ossl/openssl/pkcs7err.h", + "include/ossl/openssl/prov_ssl.h", + "include/ossl/openssl/proverr.h", + "include/ossl/openssl/provider.h", + "include/ossl/openssl/rand.h", + "include/ossl/openssl/randerr.h", + "include/ossl/openssl/rc2.h", + "include/ossl/openssl/rc4.h", + "include/ossl/openssl/rc5.h", + "include/ossl/openssl/ripemd.h", + "include/ossl/openssl/rsa.h", + "include/ossl/openssl/rsaerr.h", + "include/ossl/openssl/safestack.h", + "include/ossl/openssl/seed.h", + "include/ossl/openssl/self_test.h", + "include/ossl/openssl/sha.h", + "include/ossl/openssl/srp.h", + "include/ossl/openssl/srtp.h", + "include/ossl/openssl/ssl.h", + "include/ossl/openssl/ssl2.h", + "include/ossl/openssl/ssl3.h", + "include/ossl/openssl/sslerr.h", + "include/ossl/openssl/sslerr_legacy.h", + "include/ossl/openssl/stack.h", + "include/ossl/openssl/store.h", + "include/ossl/openssl/storeerr.h", + "include/ossl/openssl/symhacks.h", + "include/ossl/openssl/tls1.h", + "include/ossl/openssl/trace.h", + "include/ossl/openssl/ts.h", + "include/ossl/openssl/tserr.h", + "include/ossl/openssl/txt_db.h", + "include/ossl/openssl/types.h", + "include/ossl/openssl/ui.h", + "include/ossl/openssl/uierr.h", + "include/ossl/openssl/whrlpool.h", + "include/ossl/openssl/x509.h", + "include/ossl/openssl/x509_vfy.h", + "include/ossl/openssl/x509err.h", + "include/ossl/openssl/x509v3.h", + "include/ossl/openssl/x509v3err.h", + ], + cmd = """ + # The @llvm//:clang-headers target provides the include directory for + # the Clang compiler headers that are required to satisfy #includes in + # the OpenSSL headers (limits.h, stddef.h etc) + CLANG_INCLUDE_DIR="" + # Find the clang builtin include directory (contains stddef.h, stdarg.h, etc.) + # We need the path under lib/clang/*/include/, not the libc++ stddef.h + for f in $(locations @llvm_toolchain_llvm//:include); do + if [[ "$$f" == */clang/*/include/stddef.h ]]; then + CLANG_INCLUDE_DIR="$$(cd "$$(dirname "$$f")" && pwd)" + break + fi + done + + # Set up LD_LIBRARY_PATH for libclang-cpp.so + LLVM_LIB_DIR=$$(dirname $(location @llvm_toolchain_llvm//:lib/libclang-cpp.so.18.1)) + export LD_LIBRARY_PATH="$$LLVM_LIB_DIR$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}" + + # Run the prefixer with absolute source path and relative output path + $(location //prefixer:prefixer) \ + --src-path "$(location @openssl//:include)" \ + --src-incl "openssl/*.h" \ + --src-skip "openssl/asn1_mac.h" \ + --src-skip "openssl/opensslconf-*.h" \ + --include "$$CLANG_INCLUDE_DIR" \ + --output $(RULEDIR) \ + --prefix ossl 2>&1 + """, + tools = [ + "//prefixer:prefixer", + "@llvm_toolchain_llvm//:lib/libclang-cpp.so.18.1", + ], + visibility = ["//visibility:private"], +) + +# Create rules for processing all BoringSSL headers. This creates one genrule +# per header file, which copies that header from BoringSSL, applying any +# necessary patches. This also creates a filegroup called :patched_bssl_headers +# which contains all the resulting copied & patched headers. +patched_bssl_filegroup( + name = "patched_bssl_headers", + srcs = [ + "include/openssl/aead.h", + "include/openssl/aes.h", + "include/openssl/asm_base.h", + "include/openssl/arm_arch.h", + "include/openssl/asn1.h", + "include/openssl/asn1_mac.h", + "include/openssl/asn1t.h", + "include/openssl/base.h", + "include/openssl/base64.h", + "include/openssl/bcm_public.h", + "include/openssl/bio.h", + "include/openssl/blake2.h", + "include/openssl/blowfish.h", + "include/openssl/bn.h", + "include/openssl/buf.h", + "include/openssl/buffer.h", + "include/openssl/bytestring.h", + "include/openssl/cast.h", + "include/openssl/chacha.h", + "include/openssl/cipher.h", + "include/openssl/cmac.h", + "include/openssl/conf.h", + "include/openssl/cpu.h", + "include/openssl/crypto.h", + "include/openssl/curve25519.h", + "include/openssl/des.h", + "include/openssl/dh.h", + "include/openssl/digest.h", + "include/openssl/dsa.h", + "include/openssl/dtls1.h", + "include/openssl/e_os2.h", + "include/openssl/ec.h", + "include/openssl/ec_key.h", + "include/openssl/ecdh.h", + "include/openssl/ecdsa.h", + "include/openssl/engine.h", + "include/openssl/err.h", + "include/openssl/evp.h", + "include/openssl/evp_errors.h", + "include/openssl/ex_data.h", + "include/openssl/experimental/kyber.h", + "include/openssl/hkdf.h", + "include/openssl/hmac.h", + "include/openssl/hpke.h", + "include/openssl/hrss.h", + "include/openssl/is_boringssl.h", + "include/openssl/kdf.h", + "include/openssl/lhash.h", + "include/openssl/md4.h", + "include/openssl/md5.h", + "include/openssl/mem.h", + "include/openssl/mlkem.h", + "include/openssl/nid.h", + "include/openssl/obj.h", + "include/openssl/obj_mac.h", + "include/openssl/objects.h", + "include/openssl/opensslconf.h", + "include/openssl/opensslv.h", + "include/openssl/ossl_typ.h", + "include/openssl/pem.h", + "include/openssl/pkcs12.h", + "include/openssl/pkcs7.h", + "include/openssl/pkcs8.h", + "include/openssl/pki/certificate.h", + "include/openssl/pki/signature_verify_cache.h", + "include/openssl/pki/verify.h", + "include/openssl/pki/verify_error.h", + "include/openssl/poly1305.h", + "include/openssl/pool.h", + "include/openssl/posix_time.h", + "include/openssl/rand.h", + "include/openssl/rc4.h", + "include/openssl/ripemd.h", + "include/openssl/rsa.h", + "include/openssl/safestack.h", + "include/openssl/service_indicator.h", + "include/openssl/sha.h", + "include/openssl/siphash.h", + "include/openssl/slhdsa.h", + "include/openssl/span.h", + "include/openssl/srtp.h", + "include/openssl/ssl.h", + "include/openssl/ssl3.h", + "include/openssl/stack.h", + "include/openssl/target.h", + "include/openssl/thread.h", + "include/openssl/tls1.h", + "include/openssl/trust_token.h", + "include/openssl/type_check.h", + "include/openssl/x509.h", + "include/openssl/x509_vfy.h", + "include/openssl/x509v3.h", + "include/openssl/x509v3_errors.h", + ] +) + +# Create rules for processing all BoringSSL sources that we need. This creates +# one genrule per source file, which copies that source from BoringSSL, applying +# any necessary patches. This also creates a filegroup called +# :patched_bssl_sources which contains all the copied & patched sources. +patched_bssl_filegroup( + name = "patched_bssl_sources", + srcs = [ + "crypto/internal.h", + "crypto/mem.cc", + "crypto/bytestring/cbs.cc", + "crypto/bytestring/cbb.cc", + "ssl/ssl_x509.cc", + ], +) + +# List of mapping functions. For each listed mapping function, either a +# handwritten source file exists in source/{function}.c/.cc, or a genrule is +# created that generates a source file which implements simple direct call +# forwarding. This also creates a filegroup called :mapping_function_sources +# which contains all the source files. +mapping_func_filegroup( + name = "mapping_function_sources", + funcs = [ + "ASN1_ENUMERATED_to_BN", + "ASN1_BMPSTRING_new", + "ASN1_UNIVERSALSTRING_new", + "ASN1_IA5STRING_free", + "ASN1_IA5STRING_new", + "ASN1_INTEGER_free", + "ASN1_INTEGER_new", + "ASN1_INTEGER_to_BN", + "ASN1_OBJECT_free", + "ASN1_STRING_data", + "ASN1_STRING_free", + "ASN1_STRING_get0_data", + "ASN1_STRING_length", + "ASN1_STRING_set", + "ASN1_STRING_to_UTF8", + "ASN1_TIME_adj", + "ASN1_TIME_diff", + "ASN1_TIME_free", + "ASN1_TIME_new", + "ASN1_TIME_set", + "ASN1_TYPE_new", + "ASN1_TYPE_set", + "BASIC_CONSTRAINTS_free", + "BASIC_CONSTRAINTS_new", + "BIO_clear_flags", + "BIO_clear_retry_flags", + "BIO_ctrl_get_read_request", + "BIO_ctrl_get_write_guarantee", + "BIO_ctrl", + "BIO_eof", + "BIO_free_all", + "BIO_free", + "BIO_get_data", + "BIO_get_init", + "BIO_get_mem_data", + "BIO_get_mem_ptr", + "BIO_get_shutdown", + "BIO_gets", + "BIO_mem_contents", + "BIO_meth_new", + "BIO_meth_set_create", + "BIO_meth_set_ctrl", + "BIO_meth_set_destroy", + "BIO_meth_set_read", + "BIO_meth_set_write", + "BIO_new_bio_pair", + "BIO_new_connect", + "BIO_new_fd", + "BIO_new_file", + "BIO_new_fp", + "BIO_new_mem_buf", + "BIO_new_socket", + "BIO_new", + "BIO_pending", + "BIO_printf", + "BIO_puts", + "BIO_read_asn1", + "BIO_read_filename", + "BIO_read", + "BIO_reset", + "BIO_s_file", + "BIO_s_mem", + "BIO_s_socket", + "BIO_set_data", + "BIO_set_init", + "BIO_set_mem_eof_return", + "BIO_set_retry_read", + "BIO_set_retry_write", + "BIO_set_shutdown", + "BIO_should_read", + "BIO_should_retry", + "BIO_should_write", + "BIO_shutdown_wr", + "BIO_snprintf", + "BIO_up_ref", + "BIO_vfree", + "BIO_wpending", + "BIO_write", + "BN_add_word", + "BN_bin2bn", + "BN_bn2dec", + "BN_bn2hex", + "BN_cmp_word", + "BN_dup", + "BN_free", + "BN_hex2bn", + "BN_new", + "BN_num_bits", + "BN_set_word", + "BN_ucmp", + "c2i_ASN1_INTEGER", + "CRYPTO_BUFFER_free", + "CRYPTO_BUFFER_new", + "CRYPTO_memcmp", + "d2i_GENERAL_NAME", + "d2i_PKCS12_bio", + "d2i_SSL_SESSION", + "d2i_X509", + "DTLS_method", + "EC_GROUP_get_curve_name", + "EC_GROUP_get_degree", + "EC_GROUP_get0_order", + "EC_KEY_check_fips", + "EC_KEY_free", + "EC_KEY_get0_group", + "EC_KEY_get0_private_key", + "EC_KEY_new_by_curve_name", + "EC_KEY_parse_private_key", + "EC_KEY_set_private_key", + "EC_KEY_set_public_key_affine_coordinates", + "EC_KEY_set_public_key", + "EC_POINT_free", + "EC_POINT_mul", + "EC_POINT_new", + "ECDSA_do_verify", + "ECDSA_SIG_free", + "ECDSA_SIG_get0", + "ECDSA_SIG_new", + "ECDSA_SIG_set0", + "ECDSA_sign", + "ECDSA_size", + "ECDSA_verify", + "ED25519_verify", + "ERR_clear_error", + "ERR_print_errors_fp", + "ERR_print_errors", + "ERR_put_error", + "EVP_aes_128_gcm", + "EVP_aes_256_cbc", + "EVP_aes_256_gcm", + "EVP_CIPHER_block_size", + "EVP_CIPHER_CTX_ctrl", + "EVP_CIPHER_CTX_free", + "EVP_CIPHER_CTX_new", + "EVP_CIPHER_iv_length", + "EVP_CIPHER_key_length", + "EVP_DecodeBase64", + "EVP_DecodedLength", + "EVP_DecryptFinal_ex", + "EVP_DecryptInit_ex", + "EVP_DecryptUpdate", + "EVP_Digest", + "EVP_DigestFinal_ex", + "EVP_DigestFinal", + "EVP_DigestInit_ex", + "EVP_DigestInit", + "EVP_DigestSign", + "EVP_DigestSignFinal", + "EVP_DigestSignInit", + "EVP_DigestSignUpdate", + "EVP_DigestUpdate", + "EVP_DigestVerify", + "EVP_DigestVerifyFinal", + "EVP_DigestVerifyInit", + "EVP_DigestVerifyUpdate", + "EVP_EncryptFinal_ex", + "EVP_EncryptInit_ex", + "EVP_EncryptUpdate", + "EVP_get_digestbyname", + "EVP_MD_CTX_copy_ex", + "EVP_MD_CTX_create", + "EVP_MD_CTX_destroy", + "EVP_MD_CTX_free", + "EVP_MD_CTX_init", + "EVP_MD_CTX_move", + "EVP_MD_CTX_new", + "EVP_MD_nid", + "EVP_MD_size", + "EVP_MD_type", + "EVP_md4", + "EVP_md5_sha1", + "EVP_md5", + "EVP_parse_private_key", + "EVP_parse_public_key", + "EVP_PKEY_assign_EC_KEY", + "EVP_PKEY_assign_RSA", + "EVP_PKEY_bits", + "EVP_PKEY_cmp", + "EVP_PKEY_CTX_set_rsa_mgf1_md", + "EVP_PKEY_CTX_set_rsa_padding", + "EVP_PKEY_free", + "EVP_PKEY_get_raw_public_key", + "EVP_PKEY_get0_EC_KEY", + "EVP_PKEY_get0_RSA", + "EVP_PKEY_get1_EC_KEY", + "EVP_PKEY_get1_RSA", + "EVP_PKEY_id", + "EVP_PKEY_new", + "EVP_PKEY_set1_RSA", + "EVP_PKEY_size", + "EVP_PKEY_up_ref", + "EVP_sha1", + "EVP_sha224", + "EVP_sha256", + "EVP_sha384", + "EVP_sha512", + "EVP_SignFinal", + "EVP_SignInit_ex", + "EVP_SignUpdate", + "FIPS_mode", + "GENERAL_NAME_free", + "GENERAL_NAME_new", + "GENERAL_NAME_set0_value", + "GENERAL_NAME_set0_othername", + "GENERAL_NAMES_free", + "GENERAL_NAMES_new", + "GENERAL_SUBTREE_free", + "GENERAL_SUBTREE_new", + "HMAC_CTX_free", + "HMAC_CTX_new", + "HMAC_Final", + "HMAC_Init_ex", + "HMAC_Update", + "HMAC", + "i2d_ASN1_OCTET_STRING", + "i2d_SSL_SESSION", + "i2d_X509_NAME", + "i2d_X509_PUBKEY", + "i2d_X509", + "MD5", + "NAME_CONSTRAINTS_free", + "NAME_CONSTRAINTS_new", + "OBJ_cmp", + "OBJ_obj2nid", + "OBJ_obj2txt", + "OBJ_txt2obj", + "OPENSSL_free", + "OPENSSL_init_ssl", + "OPENSSL_malloc", + "OPENSSL_memdup", + "OPENSSL_realloc", + "OPENSSL_sk_free", + "OPENSSL_sk_new_null", + "OPENSSL_sk_num", + "OPENSSL_sk_pop", + "OPENSSL_sk_push", + "OPENSSL_sk_value", + "PEM_bytes_read_bio", + "PEM_read_bio_PrivateKey", + "PEM_read_bio_PUBKEY", + "PEM_read_bio_RSAPrivateKey", + "PEM_read_bio_X509_AUX", + "PEM_read_bio_X509_CRL", + "PEM_read_bio_X509", + "PEM_write_bio_X509", + "PEM_X509_INFO_read_bio", + "PKCS12_free", + "PKCS12_get_key_and_certs", + "PKCS12_parse", + "PKCS12_verify_mac", + "RAND_bytes", + "RAND_enable_fork_unsafe_buffering", + "RSA_bits", + "RSA_check_fips", + "RSA_check_key", + "RSA_decrypt", + "RSA_encrypt", + "RSA_free", + "RSA_generate_key_ex", + "RSA_get0_crt_params", + "RSA_get0_d", + "RSA_get0_dmp1", + "RSA_get0_dmq1", + "RSA_get0_e", + "RSA_get0_factors", + "RSA_get0_iqmp", + "RSA_get0_key", + "RSA_get0_n", + "RSA_get0_p", + "RSA_get0_q", + "RSA_new", + "RSA_private_key_from_bytes", + "RSA_public_key_from_bytes", + "RSA_set0_crt_params", + "RSA_set0_factors", + "RSA_set0_key", + "RSA_sign_pss_mgf1", + "RSA_sign", + "RSA_size", + "RSA_verify", + "SHA1", + "SHA224", + "SHA256_Final", + "SHA256_Init", + "SHA256_Update", + "SHA256", + "SHA384", + "SHA512", + "SSL_accept", + "SSL_add_file_cert_subjects_to_stack", + "SSL_alert_desc_string_long", + "SSL_CIPHER_get_auth_nid", + "SSL_CIPHER_get_cipher_nid", + "SSL_CIPHER_get_digest_nid", + "SSL_CIPHER_get_handshake_digest", + "SSL_CIPHER_get_id", + "SSL_CIPHER_get_kx_nid", + "SSL_CIPHER_get_min_version", + "SSL_CIPHER_get_name", + "SSL_CIPHER_get_prf_nid", + "SSL_CIPHER_get_version", + "SSL_CIPHER_standard_name", + "SSL_clear", + "SSL_connect", + "SSL_CTX_add_extra_chain_cert", + "SSL_CTX_check_private_key", + "SSL_CTX_free", + "SSL_CTX_get_cert_store", + "SSL_CTX_get_ciphers", + "SSL_CTX_get_client_CA_list", + "SSL_CTX_get_ex_data", + "SSL_CTX_get_ex_new_index", + "SSL_CTX_get_max_proto_version", + "SSL_CTX_get_min_proto_version", + "SSL_CTX_get_options", + "SSL_CTX_get_session_cache_mode", + "SSL_CTX_get_verify_mode", + "SSL_CTX_get0_certificate", + "SSL_CTX_get0_param", + "SSL_CTX_load_verify_locations", + "SSL_CTX_new", + "SSL_CTX_sess_set_new_cb", + "SSL_CTX_set_alpn_protos", + "SSL_CTX_set_alpn_select_cb", + "SSL_CTX_set_cert_store", + "SSL_CTX_set_cert_verify_callback", + "SSL_CTX_set_cipher_list", + "SSL_CTX_set_client_CA_list", + "SSL_CTX_set_compliance_policy", + "SSL_CTX_set_custom_verify", + "SSL_CTX_set_ex_data", + "SSL_CTX_set_keylog_callback", + "SSL_CTX_set_max_proto_version", + "SSL_CTX_set_min_proto_version", + "SSL_CTX_set_next_proto_select_cb", + "SSL_CTX_set_next_protos_advertised_cb", + "SSL_CTX_set_options", + "SSL_CTX_set_private_key_method", + "SSL_CTX_set_select_certificate_cb", + "SSL_CTX_set_session_cache_mode", + "SSL_CTX_set_session_id_context", + "SSL_CTX_set_strict_cipher_list", + "SSL_CTX_set_timeout", + "SSL_CTX_set_tlsext_servername_arg", + "SSL_CTX_set_tlsext_servername_callback", + "SSL_CTX_set_tlsext_status_cb", + "SSL_CTX_set_tlsext_ticket_key_cb", + "SSL_CTX_set_tlsext_ticket_keys", + "SSL_CTX_set_tmp_ecdh", + "SSL_CTX_set_verify_algorithm_prefs", + "SSL_CTX_set_verify_depth", + "SSL_CTX_set_verify", + "SSL_CTX_set1_curves_list", + "SSL_CTX_set1_sigalgs_list", + "SSL_CTX_use_certificate_chain_file", + "SSL_CTX_use_certificate_file", + "SSL_CTX_use_certificate", + "SSL_CTX_use_PrivateKey_file", + "SSL_CTX_use_PrivateKey", + "SSL_do_handshake", + "SSL_early_callback_ctx_extension_get", + "SSL_enable_ocsp_stapling", + "SSL_error_description", + "SSL_free", + "SSL_get_all_cipher_names", + "SSL_get_all_signature_algorithm_names", + "SSL_get_all_version_names", + "SSL_get_certificate", + "SSL_get_cipher_by_value", + "SSL_get_ciphers", + "SSL_get_client_CA_list", + "SSL_get_current_cipher", + "SSL_get_curve_id", + "SSL_get_error", + "SSL_get_ex_data_X509_STORE_CTX_idx", + "SSL_get_ex_data", + "SSL_get_ex_new_index", + "SSL_get_peer_cert_chain", + "SSL_get_peer_certificate", + "SSL_get_peer_full_cert_chain", + "SSL_get_peer_signature_algorithm", + "SSL_get_quiet_shutdown", + "SSL_get_rbio", + "SSL_get_servername", + "SSL_get_session", + "SSL_get_signature_algorithm_digest", + "SSL_get_signature_algorithm_key_type", + "SSL_get_signature_algorithm_name", + "SSL_get_SSL_CTX", + "SSL_get_verify_result", + "SSL_get_version", + "SSL_get_wbio", + "SSL_get0_alpn_selected", + "SSL_get0_next_proto_negotiated", + "SSL_get0_ocsp_response", + "SSL_get0_peer_certificates", + "SSL_get0_peer_verify_algorithms", + "SSL_get1_session", + "SSL_is_init_finished", + "SSL_is_server", + "SSL_is_signature_algorithm_rsa_pss", + "SSL_new", + "SSL_read", + "SSL_select_next_proto", + "SSL_send_fatal_alert", + "SSL_SESSION_free", + "SSL_SESSION_from_bytes", + "SSL_SESSION_get_id", + "SSL_SESSION_get_ticket_lifetime_hint", + "SSL_SESSION_get_version", + "SSL_SESSION_is_resumable", + "SSL_SESSION_new", + "SSL_session_reused", + "SSL_SESSION_set_protocol_version", + "SSL_SESSION_should_be_single_use", + "SSL_SESSION_to_bytes", + "SSL_SESSION_up_ref", + "SSL_set_accept_state", + "SSL_set_alpn_protos", + "SSL_set_bio", + "SSL_set_cert_cb", + "SSL_set_chain_and_key", + "SSL_set_cipher_list", + "SSL_set_client_CA_list", + "SSL_set_connect_state", + "SSL_set_ex_data", + "SSL_set_fd", + "SSL_set_info_callback", + "SSL_set_ocsp_response", + "SSL_set_quiet_shutdown", + "SSL_set_renegotiate_mode", + "SSL_set_session_id_context", + "SSL_set_session", + "SSL_set_SSL_CTX", + "SSL_set_tlsext_host_name", + "SSL_set_verify", + "SSL_set0_CA_names", + "SSL_set0_rbio", + "SSL_set0_wbio", + "SSL_set1_curves_list", + "SSL_shutdown", + "SSL_state_string_long", + "SSL_state_string", + "SSL_version", + "SSL_write", + "TLS_client_method", + "TLS_method", + "TLS_server_method", + "TLS_VERSION_to_string", + "TLS_with_buffers_method", + "X509_add1_ext_i2d", + "X509_alias_get0", + "X509_cmp", + "X509_CRL_cmp", + "X509_CRL_dup", + "X509_CRL_free", + "X509_CRL_get_ext_by_NID", + "X509_CRL_get_ext", + "X509_CRL_get_issuer", + "X509_CRL_get0_by_cert", + "X509_CRL_up_ref", + "X509_CRL_verify", + "X509_digest", + "X509_EXTENSION_get_data", + "X509_EXTENSION_get_object", + "X509_free", + "X509_get_ext_by_NID", + "X509_get_ext_by_OBJ", + "X509_get_ext_count", + "X509_get_ext_d2i", + "X509_get_ext", + "X509_get_extension_flags", + "X509_get_issuer_name", + "X509_get_key_usage", + "X509_get_pathlen", + "X509_get_pubkey", + "X509_get_serialNumber", + "X509_get_subject_name", + "X509_get_X509_PUBKEY", + "X509_get0_notAfter", + "X509_get0_notBefore", + "X509_getm_notAfter", + "X509_getm_notBefore", + "X509_INFO_free", + "X509_NAME_add_entry_by_txt", + "X509_NAME_cmp", + "X509_NAME_digest", + "X509_NAME_dup", + "X509_NAME_entry_count", + "X509_NAME_ENTRY_get_data", + "X509_NAME_ENTRY_get_object", + "X509_NAME_ENTRY_set", + "X509_NAME_free", + "X509_NAME_get_entry", + "X509_NAME_get_index_by_NID", + "X509_NAME_new", + "X509_NAME_oneline", + "X509_NAME_print_ex", + "X509_new", + "X509_PUBKEY_get", + "X509_PUBKEY_get0_param", + "X509_set_issuer_name", + "X509_set_pubkey", + "X509_set_subject_name", + "X509_set_version", + "X509_sign", + "X509_STORE_add_cert", + "X509_STORE_add_crl", + "X509_STORE_CTX_free", + "X509_STORE_CTX_get_current_cert", + "X509_STORE_CTX_get_error_depth", + "X509_STORE_CTX_get_error", + "X509_STORE_CTX_get_ex_data", + "X509_STORE_CTX_get0_cert", + "X509_STORE_CTX_get0_chain", + "X509_STORE_CTX_get0_param", + "X509_STORE_CTX_get0_untrusted", + "X509_STORE_CTX_init", + "X509_STORE_CTX_new", + "X509_STORE_CTX_set_default", + "X509_STORE_CTX_set_error", + "X509_STORE_CTX_set_flags", + "X509_STORE_CTX_set_verify_cb", + "X509_STORE_CTX_set0_crls", + "X509_STORE_CTX_set0_trusted_stack", + "X509_STORE_free", + "X509_STORE_get0_param", + "X509_STORE_load_locations", + "X509_STORE_new", + "X509_STORE_set_flags", + "X509_STORE_set_verify_cb", + "X509_STORE_up_ref", + "X509_up_ref", + "X509_verify_cert_error_string", + "X509_verify_cert", + "X509_VERIFY_PARAM_clear_flags", + "X509_VERIFY_PARAM_get_flags", + "X509_VERIFY_PARAM_set_depth", + "X509_VERIFY_PARAM_set_flags", + "X509_VERIFY_PARAM_set_time_posix", + "X509_VERIFY_PARAM_set1", + "X509_verify", + ], +) + +# Full bssl-compat library +cc_library( + name = "bssl-compat", + linkstatic = True, + srcs = [ + ":prefixed_ossl_source", + ":patched_bssl_headers", + ":patched_bssl_sources", + ":mapping_function_sources", + ] + [ + "include/ext/openssl/ssl.h", + "source/CRYPTO_BUFFER.h", + "source/err.cc", + "source/ext_SSL_get_all_async_fds.c", + "source/iana_2_ossl_names.cc", + "source/iana_2_ossl_names.h", + "source/internal.h", + "source/log.c", + "source/log.h", + "source/ossl_dlutil.c", + "source/ossl_dlutil.h", + "source/override.cc", + "source/override.h", + "source/SSL_CTX_set_select_certificate_cb.h", + "source/SSL_get_curve_name.cc", + "source/stack.c", + ], + includes = [ + "include", + "source", + ], + linkopts = ["-ldl"], + visibility = ["//visibility:public"], + + # Add the OpenSSL shared libraries as a *data* dependency, so they get + # propagated to dependant targets, and made available in their runfiles + # directory when they run, so libbssl-compat.a can dlopen() them. + data = ["@openssl//:libs"], +) + +# Aliases for compatibility +alias( + name = "ssl", + actual = ":bssl-compat", + visibility = ["//visibility:public"], +) + +alias( + name = "crypto", + actual = ":bssl-compat", + visibility = ["//visibility:public"], +) diff --git a/bssl-compat/README.md b/bssl-compat/README.md new file mode 100644 index 00000000000..d46fddab753 --- /dev/null +++ b/bssl-compat/README.md @@ -0,0 +1,303 @@ +# Summary + +Compatibility layer for BoringSSL to OpenSSL. + +This builds on the work of the original Maistra bssl_wrapper code, providing an +inplementation of the BoringSSL API in terms of calls onto OpenSSL. + +The overall goal of the `bssl-compat` library is to provide an implementation of +the BoringSSL API for Envoy to be built against it while reducing the +refactoring needed to use OpenSSL on new releases of Envoy. + +The library is intended to be delivered as a static library with a C ABI profile +(i.e. no name mangling from c++). + +# Building + +The bssl-compat layer builds via bazel, as `@bssl-compat//:bssl-compat`, and +produces the following: +- `include/openssl/*.h` The patched BoringSSL headers +- `include/ossl/openssl/*.h` The prefixed OpenSSL headers +- `lib/libbssl-compat.a` The compatibility layer implementation. + +The `bssl-compat/BUILD` file also includes `ssl` and `crypto` aliases to the +`bssl-compat` library for convenience. + +Note that the `cc_library` rule for `libbssl-compat.a` also has a *data* +dependency on the `@openssl//:libs` target. This is because `libbssl-compat.a` +needs to dynamically load the OpenSSL shared libraries at runtime, and making +them a *data* dependency of `libbssl-compat.a` ensures that Bazel will put them +in the `runfiles` directory of the sanbox, when running executables that link +with `libbssl-compat.a`. Note that this is delibrately a *data* dependency +rather than the more usual *link* dependency because we do *not* want clients of +`libbssl-compat.a` to link with the OpenSSL libraries. + +# Testing + +The bssl-compat build currently produces two unit test executables, +`@bssl-compat//test:utests-bssl-compat` and +`@bssl-compat//test:utests-boringssl`. Each executable runs the _identical_ set +of unit tests, the only difference being that one of the executables is linked +against the `@bssl-compat` library, and the other one, which acts as a sanity +check, is linked against the real `@boringssl` libraries. + +# Structure + +The overall goal of the `bssl-compat` library is to provide an implementation of +the BoringSSL API, sufficient enough that Envoy can be built against it in place +of the real BoringSSL. To provide that implementation, the `bssl-compat` library +makes use of OpenSSL. Given this, it's clear that most code in the library will +have to include headers from BoringSSL, to provide the API, and from OpenSSL, to +provided the implementation. However, since the two sets of headers look +extremely similar, they clash horribly when included in the same compilation +unit. This leads to the `prefixer` tool, which gets built and run quite early in +the build. + +The `prefixer` tool copies the stock OpenSSL headers and then adds the `ossl_` +prefix to the name of every type, function, macro, effectively scoping the whole +API. Prefixing the OpenSSL headers like this, enables us to write mapping code +that includes headers from both BoringSSL and OpenSSL in the same compilation +unit. The files in the `include/openssl` folder are the mapped BoringSSL header +files. + +Since all of the OpenSSL identifiers are prefixed, the two sets of headers can +coexist without clashing. However, such code will not link because it uses the +prefixed symbols when making OpenSSL calls. To satisfy the prefixed symbols, the +`prefixer` tool also generates the implementations of the prefixed functions +into `bssl-compat/source/ossl.c`. Do not edit the generated files `ossl.c` or +`ossl.h`. + +These generated functions simply make a forward call onto the real +(non-prefixed) OpenSSL function, via a function pointer, which is set up by the +generated `ossl_init()` library constructor function. This function is marked +with the `__attribute__ ((constructor))` attribute, which ensures that it is +called early, when the `bssl-compat` library is loaded. It uses `dlopen()` to +load OpenSSL's `libcrypto.so` and `libssl.so`, and then uses `dlsym()` to lookup +the address of each OpenSSL function and store it's address into the appropriate +member of the generated `ossl_functions` struct. + +The functions that appear in the `ossl` mapping `struct` in `ossl.h` are a +reference for mapping into the OpenSSL libraries. This mapping does not itself +provide API functionality. The explicit mapping functions are found in the +`source` folder and these tie the BoringSSL functions to their OpenSSL +functional equivalent. These can be a simple 1-1 mappings, argument adjustments +and can include OpenSSL API calls to provide BoringSSL functional equivalence +where simple 1-1 function mappings do not exist. + +![bssl-compat-build](bssl-compat-build.jpg) + +## OpenSSL Opaque Data Structures +OpenSSL has some opaque data structures (e.g. `rsa_st`) with members that can +not be accessed (this was changed in the OpenSSL code after 1.0). + +Some of these changes have not been matched with the BoringSSL code. + +This implies BoringSSL related code can access structure members directly but +OpenSSL code requires the use of `EVP` functions. + +In these cases there is no alternative but to write a patch file to modify +dependent library code as this library **does not** include code from the +OpenSSL API. + +Consider this example from `jwt_verify_lib`: + +BoringSSL: +```c++ + bssl::UniquePtr createRsaFromJwk(const std::string& n, + const std::string& e) { + bssl::UniquePtr rsa(RSA_new()); + rsa->n = createBigNumFromBase64UrlString(n).release(); + rsa->e = createBigNumFromBase64UrlString(e).release(); + if (rsa->n == nullptr || rsa->e == nullptr) { + // RSA public key field is missing or has parse error. + updateStatus(Status::JwksRsaParseError); + return nullptr; + } + if (BN_cmp_word(rsa->e, 3) != 0 && BN_cmp_word(rsa->e, 65537) != 0) { + // non-standard key; reject it early. + updateStatus(Status::JwksRsaParseError); + return nullptr; + } + return rsa; + } +``` +OpenSSL +```c++ + bssl::UniquePtr createRsaFromJwk(const std::string& n, + const std::string& e) { + bssl::UniquePtr rsa(RSA_new()); + bssl::UniquePtr bn_n = createBigNumFromBase64UrlString(n); + bssl::UniquePtr bn_e = createBigNumFromBase64UrlString(e); + + if (bn_n == nullptr || bn_e == nullptr) { + // RSA public key field is missing or has parse error. + updateStatus(Status::JwksRsaParseError); + return nullptr; + } + + if (BN_cmp_word(bn_e.get(), 3) != 0 && BN_cmp_word(bn_e.get(), 65537) != 0) { + // non-standard key; reject it early. + updateStatus(Status::JwksRsaParseError); + return nullptr; + } + + RSA_set0_key(rsa.get(), bn_n.release(), bn_e.release(), NULL); + return rsa; + } +``` +In this case a patch file is needed to replace the code that accesses opaque +data structures as a mapping function can not access the `static` data objects +in the OpenSSL code. + +## Structure Compatibility and Functional Isomorphism + +### Mapping Functions + +Each BoringSSL function provided by the bssl-compat library must be mapped from +its declaration in the BoringSSL header, to actual function implementation(s) in +the OpenSSL shared libraries. This is done via _mapping functions_ which are +listed in the `mapping_func_filegroup(...)` in the `bssl-compat/BUILD` file. + +In cases where the BoringSSL function, and the equivalent OpenSSL function are +_identical_, in both signature _and_ functionality, the bssl-compat build system +will generate an implementation for it automatically, by inspecting the +declaration and generating the appropriate mapping code. + +However, if for a particular function some actual mapping implementation is +required, because of mismatches of its signature and/or semantics, then a +handwritten implementation for the mapping function should be placed in +`source/.cc`. The bssl-compat build system will spot the handwritten +mapping function and use that rather than generating an implemtation. + +### Structure Definitions and `typedefs` + +#### Opaque Types + +Structure declaration/definition locations vary between BoringSSL and OpenSSL this can lead to "symbol not found" compilation errors: + +BoringSSL defines the `ecdsa_sig_st` `struct` in `include/openssl/ecdsa.h` +```C +struct ecdsa_sig_st { + BIGNUM *r; + BIGNUM *s; +}; +``` +whereas in the OpenSSL source, the definition appears in `include/crypto/ec/ec_local.h` (`include/ossl` in the `bssl-compat` source tree.) + +```c +struct ECDSA_SIG_st { +BIGNUM *r; +BIGNUM *s; +}; +``` + +In this case the Prefixer will include the following in the converted `base.h` + +```C +ossl_ecdsa_sig_st { + ... +}; +``` +and as `ECDSA_SIG_st` definition is not available (it's in a `crypto` include file) a compile error is generated. + +To work around this problem, the patch shell script `base.h.sh` has the inclusion: + +```bash +--uncomment-typedef-redef ECDSA_SIG --sed 's/ossl_ecdsa_sig_st/ossl_ECDSA_SIG_st/' \ +``` +which instructs the Prefixer to: +- make ECDSA_SIG typedef available and +- maps it directly to the OpenSSL type `ECDSA_SIG_st` bypassing any extra aliasing. + +#### Non opaque, fully qualified types + +The `SHA256_CTX` structure is defined in the OpenSSL source `openssl/sha.h` as + +```c +typedef struct SHA256state_st { + ossl_SHA_LONG h[8]; + ossl_SHA_LONG Nl, Nh; + ossl_SHA_LONG data[ossl_SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; +``` + +The BoringSSL source has the same structure byte layout also in `openssl/sha.h'` + +```c +struct sha256_state_st { + uint32_t h[8]; + uint32_t Nl, Nh; + uint8_t data[SHA256_CBLOCK]; + unsigned num, md_len; +}; +``` + +Client applications using the API, in most cases, use pointers to structs and +the content of the struct is opaque and accessed via getters/setters. However +code as in the following case: + +```c + uint8_t sha256[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha_ctx; + SHA256_Init(&sha_ctx); + for (auto part : parts) { + SHA256_Update(&sha_ctx, part.data(), part.size()); + } + SHA256_Final(sha256, &sha_ctx); + return std::vector(std::begin(sha256), std::end(sha256)); +} +``` +uses an instance of a `SHA256_CTX` on the stack. The compiler in this case +_must_ know what the structure layout is. To achieve this, an edit is made to +the patch script `base.h.sh` to adjust the definition of `SHA256_CTX` to use the +OpenSSL definition directly. + +```bash + --uncomment-typedef-redef SHA256_CTX --sed 's/struct ossl_sha256_state_st/struct ossl_SHA256state_st/' \ +``` +Additionally `#include ` is added to the `extraincs` +definition at the top of the script to ensure that the definition of the OpenSSL +type is made available. + +With these two changes, the patching process then emits a file `base.h` with the following line: + +```c +typedef struct ossl_SHA256state_st SHA256_CTX; +``` + +then any reference to `SHA256_CTX` will use the OpenSSL type definition +directly, rather than the one from BoringSSL. This avoids having to map between +the two different types. + +## Macro Redefinition + +Presented with a set of value definitions that may vary between API's: + +```c++ +#define SSL_CB_LOOP 0x01 +#define SSL_CB_HANDSHAKE_START 0x10 +#define SSL_CB_HANDSHAKE_DONE 0x20 +``` + +Specifying the following in the patch script `ssl.h.sh` + +```sh + --uncomment-macro-redef SSL_CB_LOOP \ + --uncomment-macro-redef SSL_CB_HANDSHAKE_START \ + --uncomment-macro-redef SSL_CB_HANDSHAKE_DONE \ +``` + +Produces the following mapping in the BoringSSL header `include/openssl/ssl.h`: + +```c +#ifdef ossl_SSL_CB_LOOP +#define SSL_CB_LOOP ossl_SSL_CB_LOOP +#endif +#ifdef ossl_SSL_CB_HANDSHAKE_START +#define SSL_CB_HANDSHAKE_START ossl_SSL_CB_HANDSHAKE_START +#endif +#ifdef ossl_SSL_CB_HANDSHAKE_DONE +#define SSL_CB_HANDSHAKE_DONE ossl_SSL_CB_HANDSHAKE_DONE +#endif +``` diff --git a/bssl-compat/WORKSPACE b/bssl-compat/WORKSPACE new file mode 100644 index 00000000000..a71497f5092 --- /dev/null +++ b/bssl-compat/WORKSPACE @@ -0,0 +1 @@ +workspace(name = "bssl-compat") diff --git a/bssl-compat/bazel/rules.bzl b/bssl-compat/bazel/rules.bzl new file mode 100644 index 00000000000..ddc2718ccf8 --- /dev/null +++ b/bssl-compat/bazel/rules.bzl @@ -0,0 +1,114 @@ +"""Bazel macros for bssl-compat library.""" + +def patched_bssl_filegroup(name, srcs): + """Copy BoringSSL files from @boringssl into bssl-compat, applying patches. + + Args: + name: The name of the filegroup, containing the copied & patched files + srcs: List of source files relative to @boringssl e.g. ssl/ssl_x509.cc + """ + targets = [] + for file in srcs: + target_name = name + "_" + file.replace("/", "_").replace(".", "_") + targets.append(":" + target_name) + src_file = "@boringssl//:" + file + dst_file = file + native.genrule( + name = target_name, + srcs = [src_file, "//patch:all"], + outs = [dst_file], + cmd = """ + # Set up paths - all paths need to be relative to bssl-compat package + SRC_FILE="$(location {src_file})" + DST_FILE="$(location {dst_file})" + # Patch files are in the package, so use relative paths from execroot + PATCH_SCRIPT="external/bssl-compat/patch/{dst_file}.sh" + PATCH_FILE="external/bssl-compat/patch/{dst_file}.patch" + + # Create output directory + mkdir -p "$$(dirname $$DST_FILE)" + + # Create temporary directory + TMP_DIR="$$DST_FILE.tmp" + mkdir -p "$$TMP_DIR" + trap 'rm -rf $$TMP_DIR' EXIT + + # Copy source file to working file + WORKING="$$TMP_DIR/working.h" + cp "$$SRC_FILE" "$$WORKING" + chmod +w "$$WORKING" + + # Apply patch file if it exists + if [ -f "$$PATCH_FILE" ]; then + patch -s -f "$$WORKING" "$$PATCH_FILE" -o "$$TMP_DIR/applied.patch.h" + cp "$$TMP_DIR/applied.patch.h" "$$WORKING" + fi + + # Apply patch script if it exists, otherwise comment out the whole file + if [ -f "$$PATCH_SCRIPT" ]; then + TOOLS_DIR="$$(dirname "$(location //tools:uncomment.sh)")" + PATH="$$TOOLS_DIR:$$PATH" bash "$$PATCH_SCRIPT" "$$WORKING" + cp "$$WORKING" "$$TMP_DIR/applied.script.h" + else + bash $(location //tools:uncomment.sh) "$$WORKING" --comment + fi + + # Copy result to destination + cp "$$WORKING" "$$DST_FILE" + """.format(src_file = src_file, dst_file = dst_file), + tools = ["//tools:uncomment.sh"], + ) + # Create a filegroup containing the copied & patched files + native.filegroup( + name = name, + srcs = targets, + visibility = ["//visibility:private"], + ) + +def mapping_func_filegroup(name, funcs): + """Find or generate mapping functions for BoringSSL API. + + For each function name, this either: + 1. Uses an existing handwritten source/function.c or source/function.cc if it exists, OR + 2. Creates a genrule that searches BoringSSL headers for the function signature + and generates a .c file with a forwarding function that calls ossl_ + + Args: + name: The name of the filegroup, containing the mapping function source files + funcs: List of function names (e.g., ["BIO_new", "BIO_free", "SSL_new"]) + """ + targets = [] + for func in funcs: # Check for handwritten implementation (.c or .cc) + handwritten = native.glob(["source/" + func + ".c", "source/" + func + ".cc"]) + if handwritten: + target_name = "handwritten_" + func + targets.append(":" + target_name) + native.filegroup( + name = target_name, + srcs = [handwritten[0]], + ) + else: # Else generate an implementation using generate.c.sh + target_name = "generated_" + func + targets.append(":" + target_name) + out = "source/" + func + ".c" + native.genrule( + name = target_name, + srcs = [":patched_bssl_headers"], + tools = ["//tools:generate.c.sh"], + outs = [out], + cmd = """ + mkdir -p "$$(dirname $(location {out}))" + + # Deduce the include directory from the first include file + FIRST_INCLUDE="$$(echo $(SRCS) | awk '{{print $$1}}')" + PATCHED_BSSL_INCLUDE_DIR="$$(dirname "$$(dirname "$$FIRST_INCLUDE")")" + + # Run generate.c.sh with the patched BoringSSL include directory + $(location //tools:generate.c.sh) "{func}" "$(location {out})" "$$PATCHED_BSSL_INCLUDE_DIR" + """.format(func = func, out = out), + ) + # Create a filegroup containing all function implementations (both handwritten and generated) + native.filegroup( + name = name, + srcs = targets, + ) diff --git a/bssl-compat/bssl-compat-build.drawio b/bssl-compat/bssl-compat-build.drawio new file mode 100644 index 00000000000..72a4ed5b980 --- /dev/null +++ b/bssl-compat/bssl-compat-build.drawio @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bssl-compat/bssl-compat-build.jpg b/bssl-compat/bssl-compat-build.jpg new file mode 100644 index 00000000000..d9f71aacca5 Binary files /dev/null and b/bssl-compat/bssl-compat-build.jpg differ diff --git a/bssl-compat/doc/bio.md b/bssl-compat/doc/bio.md new file mode 100644 index 00000000000..8219d13a0b3 --- /dev/null +++ b/bssl-compat/doc/bio.md @@ -0,0 +1,27 @@ +# Implementation of BIO Functions + +## BIO_METHOD + +The `BIO_METHOD` type is used to represent a ”type” of BIO e.g. socket, file, memory etc. A number of builtin `BIO_METHOD` instances are provided by default, and the user can also create their own custom instances. + +In BoringSSL, `BIO_METHOD` is defined as a struct containing a `type`, a `name`, and a number of function pointers for `bread`, `bwrite`, `gets`, `puts` etc. Instances of this structure may be created and initialised by client code, and then used in subsequent `BIO_new()` calls. + +In OpenSSL, `BIO_METHOD` is an opaque type, meaning that users cannot directly create instances and initialise them, in the same way as in BoringSSL. Instead, the user must call `BIO_meth_new()` to create one, and then set up it’s “members” by using the `BIO_meth_set_*()` functions. + +The only occurrence of direct access to the fields in a `BIO_METHOD` in the Envoy codebase, is the initialisation of a static instance in `extensions/transport_sockets/tls/io_handle_bio.cc`. Furthermore, that `BIO_METHOD` instance is only referenced by the "accessor" function `BIO_s_io_handle()`, which in turn is only called from `BIO_new_io_handle()`. + +The obvious solution to mapping between `ossl_BIO_METHOD` and `BIO_METHOD` objects would be to use the integer `type` value, which should act as a unique identifier. However, OpenSSL provides no `BIO_meth_get_type()` function to access the type. Also, the custom `BIO_METHOD` that envoy creates reuses the `BIO_TYPE_SOCKET` type. + +Therefore, the bssl-compat layer will assume that these objects are singletons (which currently is the case) and simply use their addresses to map between them. + +## BIO + +In BoringSSL, `BIO` is defined as a struct containing a number of fields (`method`, `init`, `shutdown`, `flags`, etc). Although the `BIO` type isn't opaque, so theoretically _could_ be instantiated directly, client code must actually create instances via the `BIO_new()` call. + +In OpenSSL, `BIO` is an opaque type, meaning that client code cannot directly create instances and therefore must create instances via the `BIO_new()` call. + +Analysis of the Envoy codebase (1.24) shows minimal use of direct `BIO` field access, all of which occurs in just one source file (`extensions/transport_sockets/tls/io_handle_bio.cc`). Since each field access can be trivially replaced with the appropriate `BIO_get/set_()` method, we can just typedef the BoringSSL `BIO` type to be the OpenSSL `ossl_BIO` type, thus making the mapping of calls much simpler by not having to maintain separate `BIO` & `ossl_BIO` structures and copy back and forth. + +## Functions + +Details of how each BIO function has been implemented/mapped can be found in the comments in the code. \ No newline at end of file diff --git a/bssl-compat/include/ext/openssl/ssl.h b/bssl-compat/include/ext/openssl/ssl.h new file mode 100644 index 00000000000..13c8e310aed --- /dev/null +++ b/bssl-compat/include/ext/openssl/ssl.h @@ -0,0 +1,11 @@ +#ifndef __EXT_OPENSSL_SSL_H__ +#define __EXT_OPENSSL_SSL_H__ + +#include +#include + +#define OSSL_ASYNC_FD ossl_OSSL_ASYNC_FD + +OPENSSL_EXPORT int ext_SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds); + +#endif diff --git a/bssl-compat/patch/BUILD b/bssl-compat/patch/BUILD new file mode 100644 index 00000000000..81bbd8f2fa0 --- /dev/null +++ b/bssl-compat/patch/BUILD @@ -0,0 +1,8 @@ +licenses(["notice"]) # Apache 2 + +filegroup( + name = "all", + srcs = glob(["**/*"]), + visibility = ["//visibility:public"], +) + diff --git a/bssl-compat/patch/crypto/bio/bio_test.cc.sh b/bssl-compat/patch/crypto/bio/bio_test.cc.sh new file mode 100755 index 00000000000..e13e6157e83 --- /dev/null +++ b/bssl-compat/patch/crypto/bio/bio_test.cc.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Do nothing here so the file just gets copied +# without commenting or uncommenting anything \ No newline at end of file diff --git a/bssl-compat/patch/crypto/bytestring/cbb.cc.sh b/bssl-compat/patch/crypto/bytestring/cbb.cc.sh new file mode 100755 index 00000000000..e92a02cca23 --- /dev/null +++ b/bssl-compat/patch/crypto/bytestring/cbb.cc.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-regex '#include' \ + --uncomment-func-impl CBB_zero \ + --uncomment-func-impl cbb_init \ + --uncomment-func-impl CBB_init \ + --uncomment-func-impl CBB_cleanup \ + --uncomment-static-func-impl cbb_buffer_reserve \ + --uncomment-static-func-impl cbb_buffer_add \ + --uncomment-func-impl CBB_finish \ + --uncomment-func-impl cbb_get_base \ + --uncomment-func-impl CBB_flush \ + --uncomment-func-impl CBB_data \ + --uncomment-func-impl CBB_len \ + --uncomment-static-func-impl cbb_add_child \ + --uncomment-func-impl add_base128_integer \ + --uncomment-func-impl CBB_add_asn1 \ + --uncomment-func-impl CBB_add_bytes \ + --uncomment-func-impl CBB_add_space \ + --uncomment-func-impl cbb_add_u \ + --uncomment-func-impl CBB_add_u8 \ + --uncomment-func-impl CBB_add_u16 \ + --uncomment-func-impl CBB_add_asn1_uint64 \ + --uncomment-func-impl CBB_add_asn1_uint64_with_tag \ + --uncomment-func-impl parse_dotted_decimal \ + --uncomment-func-impl CBB_add_asn1_oid_from_text \ + --uncomment-func-impl cbb_on_error \ + diff --git a/bssl-compat/patch/crypto/bytestring/cbs.cc.sh b/bssl-compat/patch/crypto/bytestring/cbs.cc.sh new file mode 100755 index 00000000000..2c838c0bbc0 --- /dev/null +++ b/bssl-compat/patch/crypto/bytestring/cbs.cc.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-regex '\#include <' \ + --uncomment-func-impl cbs_get \ + --uncomment-func-impl CBS_get_bytes \ + --uncomment-func-impl CBS_skip \ + --uncomment-func-impl cbs_get_u \ + --uncomment-func-impl CBS_get_u8 \ + --uncomment-func-impl CBS_get_u16 \ + --uncomment-func-impl CBS_get_u64_decimal \ + --uncomment-func-impl cbs_get_length_prefixed \ + --uncomment-func-impl CBS_get_u16_length_prefixed \ + --uncomment-func-impl parse_base128_integer \ + --uncomment-func-impl parse_asn1_tag \ + --uncomment-func-impl cbs_get_any_asn1_element \ + --uncomment-static-func-impl cbs_get_asn1 \ + --uncomment-static-func-impl add_decimal \ + --uncomment-func-impl CBS_get_u8_length_prefixed \ + --uncomment-func-impl CBS_get_asn1 \ + --uncomment-func-impl CBS_get_asn1_element \ + --uncomment-func-impl CBS_get_optional_asn1 \ + --uncomment-func-impl CBS_asn1_oid_to_text \ + --uncomment-func-impl CBS_get_any_asn1_element \ + --uncomment-func-impl CBS_peek_asn1_tag \ + --uncomment-func-impl CBS_get_asn1_bool + \ No newline at end of file diff --git a/bssl-compat/patch/crypto/digest_extra/digest_test.cc.patch b/bssl-compat/patch/crypto/digest_extra/digest_test.cc.patch new file mode 100644 index 00000000000..631a1a1ba60 --- /dev/null +++ b/bssl-compat/patch/crypto/digest_extra/digest_test.cc.patch @@ -0,0 +1,26 @@ +--- a/source/crypto/digest_extra/digest_test.cc ++++ b/source/crypto/digest_extra/digest_test.cc +@@ -71,14 +71,15 @@ + static const DigestTestVector kTestVectors[] = { + // MD4 tests, from RFC 1320. (crypto/md4 does not provide a + // one-shot MD4 function.) +- {md4, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0"}, +- {md4, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24"}, +- {md4, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d"}, +- {md4, "message digest", 1, "d9130a8164549fe818874806e1c7014b"}, +- {md4, "abcdefghijklmnopqrstuvwxyz", 1, "d79e1c308aa5bbcdeea8ed63df412da9"}, +- {md4, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1, +- "043f8582f241db351ce627e153e7f0e4"}, +- {md4, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536"}, ++ // OpenSSL does not support MD4, so these tests are commented out. ++ // {md4, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0"}, ++ // {md4, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24"}, ++ // {md4, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d"}, ++ // {md4, "message digest", 1, "d9130a8164549fe818874806e1c7014b"}, ++ // {md4, "abcdefghijklmnopqrstuvwxyz", 1, "d79e1c308aa5bbcdeea8ed63df412da9"}, ++ // {md4, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1, ++ // "043f8582f241db351ce627e153e7f0e4"}, ++ // {md4, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536"}, + + // MD5 tests, from RFC 1321. + {md5, "", 1, "d41d8cd98f00b204e9800998ecf8427e"}, diff --git a/bssl-compat/patch/crypto/digest_extra/digest_test.cc.sh b/bssl-compat/patch/crypto/digest_extra/digest_test.cc.sh new file mode 100755 index 00000000000..83b20123343 --- /dev/null +++ b/bssl-compat/patch/crypto/digest_extra/digest_test.cc.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" \ + --comment-regex '^static const MD sha512_256' \ + --comment-regex '^static const MD blake2b256' \ + --comment-regex-range '^\s*// SHA-512-256 tests' '^$' \ + --comment-regex-range '^\s*// BLAKE2b-256 tests' '},\s*$' \ + --comment-gtest-func DigestTest Getters \ + --comment-gtest-func DigestTest ASN1 \ + --comment-gtest-func DigestTest TransformBlocks \ diff --git a/bssl-compat/patch/crypto/err/err_test.cc.sh b/bssl-compat/patch/crypto/err/err_test.cc.sh new file mode 100755 index 00000000000..9c2838f041e --- /dev/null +++ b/bssl-compat/patch/crypto/err/err_test.cc.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-regex '#include' \ + --comment-regex '#include\s*"./internal.h"' \ + --uncomment-regex-range '#if defined(OPENSSL_WINDOWS)' '#endif' \ + --uncomment-gtest-func ErrTest Overflow \ + --uncomment-gtest-func ErrTest ClearError \ + --uncomment-gtest-func ErrTest PreservesErrno \ + --uncomment-gtest-func ErrTest UnknownError \ \ No newline at end of file diff --git a/bssl-compat/patch/crypto/hmac_extra/hmac_test.cc.sh b/bssl-compat/patch/crypto/hmac_extra/hmac_test.cc.sh new file mode 100755 index 00000000000..dcad5aa4843 --- /dev/null +++ b/bssl-compat/patch/crypto/hmac_extra/hmac_test.cc.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-regex '#include' \ + --comment-regex '#include\s*"\.\./test/wycheproof_util\.h"' \ + --uncomment-func-impl GetDigest \ + --uncomment-gtest-func HMACTest TestVectors \ No newline at end of file diff --git a/bssl-compat/patch/crypto/internal.h.sh b/bssl-compat/patch/crypto/internal.h.sh new file mode 100755 index 00000000000..7657d654990 --- /dev/null +++ b/bssl-compat/patch/crypto/internal.h.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-regex '#\(ifndef\|define\|endif\).*OPENSSL_HEADER_CRYPTO_INTERNAL_H' \ + --uncomment-regex '#include\s* constructed(RSA_new_private_key( +- RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()), +- RSA_get0_d(parsed.get()), RSA_get0_p(parsed.get()), +- RSA_get0_q(parsed.get()), RSA_get0_dmp1(parsed.get()), +- RSA_get0_dmq1(parsed.get()), RSA_get0_iqmp(parsed.get()))); +- ASSERT_TRUE(constructed); +- EXPECT_TRUE(RSA_get0_e(constructed.get())); +- EXPECT_TRUE(RSA_get0_d(constructed.get())); +- +- bssl::UniquePtr no_crt(RSA_new_private_key_no_crt( +- RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()), +- RSA_get0_d(parsed.get()))); +- ASSERT_TRUE(no_crt); +- EXPECT_TRUE(RSA_get0_e(no_crt.get())); +- EXPECT_TRUE(RSA_get0_d(no_crt.get())); +- +- bssl::UniquePtr no_e(RSA_new_private_key_no_e(RSA_get0_n(parsed.get()), +- RSA_get0_d(parsed.get()))); +- ASSERT_TRUE(no_e); +- EXPECT_FALSE(RSA_get0_e(no_e.get())); +- EXPECT_TRUE(RSA_get0_d(no_e.get())); +- +- bssl::UniquePtr pub( +- RSA_new_public_key(RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()))); +- ASSERT_TRUE(pub); +- EXPECT_TRUE(RSA_get0_e(pub.get())); +- EXPECT_FALSE(RSA_get0_d(pub.get())); ++ // bssl::UniquePtr constructed(RSA_new_private_key( ++ // RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()), ++ // RSA_get0_d(parsed.get()), RSA_get0_p(parsed.get()), ++ // RSA_get0_q(parsed.get()), RSA_get0_dmp1(parsed.get()), ++ // RSA_get0_dmq1(parsed.get()), RSA_get0_iqmp(parsed.get()))); ++ // ASSERT_TRUE(constructed); ++ // EXPECT_TRUE(RSA_get0_e(constructed.get())); ++ // EXPECT_TRUE(RSA_get0_d(constructed.get())); ++ ++ // bssl::UniquePtr no_crt(RSA_new_private_key_no_crt( ++ // RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()), ++ // RSA_get0_d(parsed.get()))); ++ // ASSERT_TRUE(no_crt); ++ // EXPECT_TRUE(RSA_get0_e(no_crt.get())); ++ // EXPECT_TRUE(RSA_get0_d(no_crt.get())); ++ ++ // bssl::UniquePtr no_e(RSA_new_private_key_no_e(RSA_get0_n(parsed.get()), ++ // RSA_get0_d(parsed.get()))); ++ // ASSERT_TRUE(no_e); ++ // EXPECT_FALSE(RSA_get0_e(no_e.get())); ++ // EXPECT_TRUE(RSA_get0_d(no_e.get())); ++ ++ // bssl::UniquePtr pub( ++ // RSA_new_public_key(RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()))); ++ // ASSERT_TRUE(pub); ++ // EXPECT_TRUE(RSA_get0_e(pub.get())); ++ // EXPECT_FALSE(RSA_get0_d(pub.get())); + + for (RSA *key : +- {parsed.get(), constructed.get(), no_crt.get(), no_e.get(), pub.get()}) { ++ {parsed.get()}) { + EXPECT_TRUE(RSA_check_key(key)); + + std::vector ciphertext(RSA_size(key)), plaintext(RSA_size(key)); diff --git a/bssl-compat/patch/crypto/rsa_extra/rsa_test.cc.sh b/bssl-compat/patch/crypto/rsa_extra/rsa_test.cc.sh new file mode 100755 index 00000000000..ea46b6222d4 --- /dev/null +++ b/bssl-compat/patch/crypto/rsa_extra/rsa_test.cc.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-regex '#include' \ + --comment-regex '#include "../fipsmodule' \ + --uncomment-struct RSAEncryptParam \ + --uncomment-regex 'class\s*RSAEncryptTest\s*:' \ + --uncomment-gtest-func RSAEncryptTest TestKey \ + --uncomment-regex-range 'INSTANTIATE_TEST_SUITE_P(All, RSAEncryptTest' '.*);$' \ + --uncomment-gtest-func RSATest TestDecrypt \ + --uncomment-gtest-func RSATest GenerateSmallKey \ + --uncomment-regex-range 'static const uint8_t kPKCS1Ciphertext2.*' '.*};' + +for VAR in kKey1 kPlaintext kOAEPCiphertext1 kKey2 kOAEPCiphertext2 kKey3 kOAEPCiphertext3 ; do + uncomment.sh "$1" --uncomment-regex-range 'static\s*const\s*.*\<'$VAR'\[\]\s*=' '[^;]*;\s*$' +done diff --git a/bssl-compat/patch/crypto/stack/stack_test.cc.sh b/bssl-compat/patch/crypto/stack/stack_test.cc.sh new file mode 100755 index 00000000000..35ae348739b --- /dev/null +++ b/bssl-compat/patch/crypto/stack/stack_test.cc.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" \ + --comment-gtest-func StackTest DeleteIf \ \ No newline at end of file diff --git a/bssl-compat/patch/crypto/test/file_test.cc.sh b/bssl-compat/patch/crypto/test/file_test.cc.sh new file mode 100755 index 00000000000..000e648fe3b --- /dev/null +++ b/bssl-compat/patch/crypto/test/file_test.cc.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Do nothing here so the file just gets copied +# without commenting or uncommenting anything diff --git a/bssl-compat/patch/crypto/test/file_test.h.sh b/bssl-compat/patch/crypto/test/file_test.h.sh new file mode 100755 index 00000000000..000e648fe3b --- /dev/null +++ b/bssl-compat/patch/crypto/test/file_test.h.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Do nothing here so the file just gets copied +# without commenting or uncommenting anything diff --git a/bssl-compat/patch/crypto/test/file_test_gtest.cc.sh b/bssl-compat/patch/crypto/test/file_test_gtest.cc.sh new file mode 100755 index 00000000000..000e648fe3b --- /dev/null +++ b/bssl-compat/patch/crypto/test/file_test_gtest.cc.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Do nothing here so the file just gets copied +# without commenting or uncommenting anything diff --git a/bssl-compat/patch/crypto/test/file_util.cc.sh b/bssl-compat/patch/crypto/test/file_util.cc.sh new file mode 100755 index 00000000000..f2d7bc30b60 --- /dev/null +++ b/bssl-compat/patch/crypto/test/file_util.cc.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-impl SkipTempFileTests \ + --uncomment-func-impl GetTempDir \ + --uncomment-func-impl TemporaryFile::Init \ + --uncomment-func-impl TemporaryFile::Open \ + --uncomment-func-impl TemporaryFile::OpenFD \ + --uncomment-regex-range 'TemporaryFile::~TemporaryFile.*' '}' diff --git a/bssl-compat/patch/crypto/test/file_util.h.sh b/bssl-compat/patch/crypto/test/file_util.h.sh new file mode 100755 index 00000000000..e9396cf61c4 --- /dev/null +++ b/bssl-compat/patch/crypto/test/file_util.h.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-class TemporaryFile \ + --uncomment-class TemporaryDirectory \ + --uncomment-class ScopedFD \ + --uncomment-regex 'using ScopedFILE.*' \ + --uncomment-struct 'FileDeleter' \ + --uncomment-regex 'bool SkipTempFileTests();' \ + diff --git a/bssl-compat/patch/crypto/test/test_data.cc.sh b/bssl-compat/patch/crypto/test/test_data.cc.sh new file mode 100755 index 00000000000..cc7d9668f46 --- /dev/null +++ b/bssl-compat/patch/crypto/test/test_data.cc.sh @@ -0,0 +1,2 @@ +#!/bin/bash +# empty file \ No newline at end of file diff --git a/bssl-compat/patch/crypto/test/test_data.h.sh b/bssl-compat/patch/crypto/test/test_data.h.sh new file mode 100755 index 00000000000..44ce58d3ca9 --- /dev/null +++ b/bssl-compat/patch/crypto/test/test_data.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ +--uncomment-regex 'std::string\s*GetTestData\s*(.*);' \ diff --git a/bssl-compat/patch/crypto/test/test_util.cc.sh b/bssl-compat/patch/crypto/test/test_util.cc.sh new file mode 100755 index 00000000000..0630fab4ebc --- /dev/null +++ b/bssl-compat/patch/crypto/test/test_util.cc.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-impl 'operator<<' \ + --uncomment-func-impl DecodeHex \ + --uncomment-func-impl EncodeHex \ + --uncomment-func-impl ErrorEquals \ \ No newline at end of file diff --git a/bssl-compat/patch/crypto/test/test_util.h.sh b/bssl-compat/patch/crypto/test/test_util.h.sh new file mode 100755 index 00000000000..fc134f80f62 --- /dev/null +++ b/bssl-compat/patch/crypto/test/test_util.h.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-struct Bytes \ + --uncomment-regex-range 'inline bool operator==(' '}' \ + --uncomment-regex 'inline bool operator!=(' \ + --uncomment-regex 'std::ostream &operator<<(' \ + --uncomment-regex 'bool DecodeHex(' \ + --uncomment-regex 'std::string EncodeHex(' \ + --uncomment-regex 'testing::AssertionResult ErrorEquals.*' \ + diff --git a/bssl-compat/patch/crypto/x509/x509_test.cc.patch b/bssl-compat/patch/crypto/x509/x509_test.cc.patch new file mode 100644 index 00000000000..76765e06c64 --- /dev/null +++ b/bssl-compat/patch/crypto/x509/x509_test.cc.patch @@ -0,0 +1,113 @@ +--- a/source/crypto/x509/x509_test.cc ++++ b/source/crypto/x509/x509_test.cc +@@ -1275,6 +1275,9 @@ + Verify(root_cross_signed.get(), {cross_signing_root.get()}, {}, + /*crls=*/{}, /*flags=*/0, configure_callback)); + ++#ifdef BSSL_COMPAT // This next check fails for negative depths on OpenSSL ++ if (depth < 0) continue; ++#endif + // An explicitly trusted self-signed certificate is unaffected by depth + // checks. + EXPECT_EQ(X509_V_OK, +@@ -1987,14 +1990,23 @@ + + bssl::UniquePtr nc(NAME_CONSTRAINTS_new()); + ASSERT_TRUE(nc); +- nc->permittedSubtrees = sk_GENERAL_SUBTREE_new_null(); ++#ifdef BSSL_COMPAT // FIXME: See StackTest.test4 ++ nc->permittedSubtrees = reinterpret_cast(sk_GENERAL_SUBTREE_new_null()); ++#else ++ nc->permittedSubtrees = sk_GENERAL_SUBTREE_new_null(); ++#endif + ASSERT_TRUE(nc->permittedSubtrees); + bssl::UniquePtr subtree(GENERAL_SUBTREE_new()); + ASSERT_TRUE(subtree); + GENERAL_NAME_free(subtree->base); + subtree->base = MakeGeneralName(t.type, t.constraint).release(); + ASSERT_TRUE(subtree->base); +- ASSERT_TRUE(bssl::PushToStack(nc->permittedSubtrees, std::move(subtree))); ++#ifdef BSSL_COMPAT // FIXME: ++ ASSERT_TRUE(bssl::PushToStack(reinterpret_cast(nc->permittedSubtrees), std::move(subtree))); ++#else ++ ASSERT_TRUE(bssl::PushToStack(nc->permittedSubtrees, std::move(subtree))); ++#endif ++ + + bssl::UniquePtr root = + MakeTestCert("Root", "Root", key.get(), /*is_ca=*/true); +@@ -2936,11 +2948,13 @@ + // |X509_check_purpose| with |X509_PURPOSE_ANY| and purpose -1 do not check + // basicConstraints, but other purpose types do. (This is redundant with the + // actual basicConstraints check, but |X509_check_purpose| is public API.) ++#ifndef BSSL_COMPAT + EXPECT_TRUE(X509_check_purpose(intermediate.get(), -1, /*ca=*/1)); + EXPECT_TRUE( + X509_check_purpose(intermediate.get(), X509_PURPOSE_ANY, /*ca=*/1)); + EXPECT_FALSE(X509_check_purpose(intermediate.get(), X509_PURPOSE_SSL_SERVER, + /*ca=*/1)); ++#endif // BSSL_COMPAT + } + + TEST(X509Test, NoBasicConstraintsNetscapeCA) { +@@ -3767,6 +3781,7 @@ + t6uPxHrmpUY= + -----END CERTIFICATE----- + )"; ++#ifndef BSSL_COMPAT + static const char kP256InvalidParam[] = R"( + -----BEGIN CERTIFICATE----- + MIIBMTCBz6ADAgECAgIE0jATBggqhkjOPQQDAgQHZ2FyYmFnZTAPMQ0wCwYDVQQD +@@ -3778,6 +3793,7 @@ + fLULTZnynuQUULQkRcF7S7T2WpIL + -----END CERTIFICATE----- + )"; ++#endif + static const char kRSANoParam[] = R"( + -----BEGIN CERTIFICATE----- + MIIBWzCBx6ADAgECAgIE0jALBgkqhkiG9w0BAQswDzENMAsGA1UEAxMEVGVzdDAg +@@ -3802,6 +3818,7 @@ + SwmQUz4bRpckRBj+sIyp1We+pg== + -----END CERTIFICATE----- + )"; ++#ifndef BSSL_COMPAT + static const char kRSAInvalidParam[] = R"( + -----BEGIN CERTIFICATE----- + MIIBbTCB0KADAgECAgIE0jAUBgkqhkiG9w0BAQsEB2dhcmJhZ2UwDzENMAsGA1UE +@@ -3814,7 +3831,7 @@ + 5OMNZ/ajVwOssw61GcAlScRqEHkZFBoGp7e+QpgB2tf9 + -----END CERTIFICATE----- + )"; +- ++#endif + TEST(X509Test, AlgorithmParameters) { + // P-256 parameters should be omitted, but we accept NULL ones. + bssl::UniquePtr key = PrivateKeyFromPEM(kP256Key); +@@ -3828,11 +3845,13 @@ + ASSERT_TRUE(cert); + EXPECT_TRUE(X509_verify(cert.get(), key.get())); + ++#ifndef BSSL_COMPAT + cert = CertFromPEM(kP256InvalidParam); + ASSERT_TRUE(cert); + EXPECT_FALSE(X509_verify(cert.get(), key.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_PARAMETER)); ++#endif + + // RSA parameters should be NULL, but we accept omitted ones. + key = PrivateKeyFromPEM(kRSAKey); +@@ -3846,11 +3865,13 @@ + ASSERT_TRUE(cert); + EXPECT_TRUE(X509_verify(cert.get(), key.get())); + ++#ifndef BSSL_COMPAT + cert = CertFromPEM(kRSAInvalidParam); + ASSERT_TRUE(cert); + EXPECT_FALSE(X509_verify(cert.get(), key.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_PARAMETER)); ++#endif + } + + // TEST(X509Test, GeneralName) { diff --git a/bssl-compat/patch/crypto/x509/x509_test.cc.sh b/bssl-compat/patch/crypto/x509/x509_test.cc.sh new file mode 100755 index 00000000000..2d44255b5b3 --- /dev/null +++ b/bssl-compat/patch/crypto/x509/x509_test.cc.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-regex '#include' \ + --comment-regex '#include\s*"internal\.h"' \ + --uncomment-func-impl CertFromPEM \ + --uncomment-func-impl CRLFromPEM \ + --uncomment-func-impl PrivateKeyFromPEM \ + --uncomment-static-func-impl CertsToStack \ + --uncomment-static-func-impl CRLsToStack \ + --uncomment-regex 'static const .* kReferenceTime =' \ + --uncomment-static-func-impl Verify \ + --uncomment-gtest-func X509Test TestVerify \ + --uncomment-gtest-func X509Test VerifyThreads \ + --uncomment-gtest-func X509Test ManyNamesAndConstraints \ + --uncomment-static-func-impl MakeGeneralName \ + --uncomment-static-func-impl MakeTestCert \ + --uncomment-gtest-func X509Test NameConstraints \ + --uncomment-gtest-func X509Test TestPSSBadParameters \ + --uncomment-gtest-func X509Test TestEd25519 \ + --uncomment-gtest-func X509Test X509NameSet \ + --uncomment-gtest-func X509Test NoBasicConstraintsCertSign \ + --uncomment-gtest-func X509Test NoBasicConstraintsNetscapeCA \ + --uncomment-gtest-func X509Test PEMX509Info \ + --uncomment-gtest-func-skip X509Test InvalidExtensions \ + --uncomment-gtest-func X509Test NullStore \ + --uncomment-gtest-func X509Test BasicConstraints \ + --uncomment-gtest-func X509Test AlgorithmParameters \ + --uncomment-gtest-func X509Test TrustedFirst \ + --uncomment-gtest-func-skip X509Test BER \ + --uncomment-func-impl MakeTestName \ + +for VAR in kCrossSigningRootPEM kRootCAPEM kRootCrossSignedPEM kIntermediatePEM kIntermediateSelfSignedPEM kLeafPEM kLeafNoKeyUsagePEM kForgeryPEM kBadPSSCertPEM kRSAKey kP256Key kBasicCRL kEd25519Cert kSANTypesRoot kNoBasicConstraintsCertSignIntermediate kNoBasicConstraintsCertSignLeaf kNoBasicConstraintsNetscapeCAIntermediate kNoBasicConstraintsNetscapeCALeaf kP256NoParam kP256NullParam kP256InvalidParam kRSANoParam kRSANullParam kRSAInvalidParam kConstructedBitString kConstructedOctetString kIndefiniteLength kNonZeroPadding kHighTagNumber kNonMinimalLengthSerial kNonMinimalLengthOuter kNonMinimalLengthSignature; do + uncomment.sh "$1" --uncomment-regex-range 'static\s*const\s*.*\<'$VAR'\[\]\s*=' '[^;]*;\s*$' +done diff --git a/bssl-compat/patch/crypto/x509v3/internal.h.sh b/bssl-compat/patch/crypto/x509v3/internal.h.sh new file mode 100755 index 00000000000..848310fe001 --- /dev/null +++ b/bssl-compat/patch/crypto/x509v3/internal.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --comment-regex '#include\s*"\.\./x509/internal\.h"' \ No newline at end of file diff --git a/bssl-compat/patch/include/openssl/asn1.h.sh b/bssl-compat/patch/include/openssl/asn1.h.sh new file mode 100755 index 00000000000..8f0f153eef7 --- /dev/null +++ b/bssl-compat/patch/include/openssl/asn1.h.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro-redef 'V_ASN1_[a-zA-Z0-9_]*' \ + --uncomment-macro-redef 'ASN1_R_[a-zA-Z0-9_]*' \ + --uncomment-macro-redef 'MBSTRING_[a-zA-Z0-9_]*' \ + --uncomment-macro-redef 'ASN1_STRFLGS_[A-Z0-9_]*' \ + --uncomment-macro 'DECLARE_ASN1_ITEM' \ + --uncomment-func-decl ASN1_STRING_free \ + --uncomment-func-decl ASN1_STRING_to_UTF8 \ + --uncomment-func-decl ASN1_STRING_get0_data \ + --uncomment-func-decl ASN1_STRING_data \ + --uncomment-func-decl ASN1_STRING_length \ + --uncomment-func-decl ASN1_STRING_set \ + --uncomment-func-decl ASN1_BMPSTRING_new \ + --uncomment-func-decl ASN1_IA5STRING_new \ + --uncomment-func-decl ASN1_UNIVERSALSTRING_new \ + --uncomment-func-decl ASN1_IA5STRING_free \ + --uncomment-func-decl ASN1_INTEGER_new \ + --uncomment-func-decl ASN1_INTEGER_free \ + --uncomment-func-decl c2i_ASN1_INTEGER \ + --uncomment-func-decl ASN1_INTEGER_to_BN \ + --uncomment-func-decl ASN1_TIME_new \ + --uncomment-func-decl ASN1_TIME_free \ + --uncomment-func-decl ASN1_TIME_diff \ + --uncomment-func-decl ASN1_TIME_set \ + --uncomment-func-decl ASN1_TIME_adj \ + --uncomment-func-decl ASN1_TYPE_new \ + --uncomment-func-decl ASN1_TYPE_set \ + --uncomment-func-decl ASN1_OBJECT_free \ + --uncomment-func-decl ASN1_ENUMERATED_to_BN \ + --uncomment-func-decl i2d_ASN1_OCTET_STRING \ + --uncomment-macro DECLARE_ASN1_FUNCTIONS \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(ASN1_OBJECT' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(ASN1_STRING' \ + --uncomment-macro DECLARE_ASN1_ALLOC_FUNCTIONS \ + --uncomment-macro DECLARE_ASN1_FUNCTIONS_name \ + --uncomment-macro DECLARE_ASN1_ENCODE_FUNCTIONS \ + --uncomment-macro DECLARE_ASN1_ENCODE_FUNCTIONS_const \ + --uncomment-macro DECLARE_ASN1_FUNCTIONS_const \ + --uncomment-macro DECLARE_ASN1_ALLOC_FUNCTIONS_name \ + --uncomment-macro ASN1_BOOLEAN_TRUE \ + --uncomment-macro ASN1_BOOLEAN_FALSE \ + diff --git a/bssl-compat/patch/include/openssl/asn1t.h.sh b/bssl-compat/patch/include/openssl/asn1t.h.sh new file mode 100755 index 00000000000..30a3b7b6b01 --- /dev/null +++ b/bssl-compat/patch/include/openssl/asn1t.h.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h diff --git a/bssl-compat/patch/include/openssl/base.h.sh b/bssl-compat/patch/include/openssl/base.h.sh new file mode 100755 index 00000000000..3585042940c --- /dev/null +++ b/bssl-compat/patch/include/openssl/base.h.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +set -euo pipefail + +MYTMPDIR="$(mktemp -d)" +trap 'rm -rf -- "$MYTMPDIR"' EXIT + +cat > "$MYTMPDIR/extraincs" < +#include +#include +#include +EOF + +uncomment.sh "$1" --comment -h \ + --sed "/#include\s/ e cat $MYTMPDIR/extraincs" \ + --uncomment-typedef CRYPTO_THREADID \ + --uncomment-typedef CBB \ + --uncomment-typedef CBS \ + --uncomment-typedef CRYPTO_BUFFER_POOL \ + --uncomment-typedef CRYPTO_BUFFER \ + --uncomment-typedef SSL_CLIENT_HELLO \ + --uncomment-typedef SSL_PRIVATE_KEY_METHOD \ + --uncomment-typedef ossl_ssize_t \ + --uncomment-typedef CBS_ASN1_TAG \ + --uncomment-typedef-redef ASN1_TYPE \ + --uncomment-typedef-redef ASN1_BIT_STRING \ + --uncomment-typedef-redef ASN1_PRINTABLESTRING \ + --uncomment-typedef-redef ASN1_T61STRING \ + --uncomment-typedef-redef ASN1_GENERALSTRING \ + --uncomment-typedef-redef ASN1_UTCTIME \ + --uncomment-typedef-redef ASN1_GENERALIZEDTIME \ + --uncomment-typedef-redef ASN1_VISIBLESTRING \ + --uncomment-typedef-redef ASN1_UTF8STRING \ + --uncomment-typedef-redef ASN1_TIME \ + --uncomment-typedef-redef ASN1_ITEM \ + --uncomment-typedef-redef ASN1_OBJECT \ + --uncomment-typedef-redef ASN1_BMPSTRING \ + --uncomment-typedef-redef ASN1_IA5STRING \ + --uncomment-typedef-redef ASN1_UNIVERSALSTRING \ + --uncomment-typedef-redef ASN1_INTEGER \ + --uncomment-typedef-redef ASN1_OCTET_STRING \ + --uncomment-typedef-redef ASN1_STRING \ + --uncomment-typedef-redef ASN1_ENUMERATED \ + --uncomment-typedef-redef BASIC_CONSTRAINTS \ + --uncomment-typedef-redef NAME_CONSTRAINTS \ + --uncomment-typedef-redef OPENSSL_INIT_SETTINGS \ + --uncomment-typedef-redef X509_VERIFY_PARAM \ + --uncomment-typedef-redef X509_CRL \ + --uncomment-typedef-redef X509_EXTENSION \ + --uncomment-typedef-redef X509_INFO \ + --uncomment-typedef-redef X509_NAME_ENTRY \ + --uncomment-typedef-redef X509_NAME \ + --uncomment-typedef-redef X509_PUBKEY \ + --uncomment-typedef-redef BIGNUM \ + --uncomment-typedef-redef BUF_MEM \ + --uncomment-typedef-redef BIO \ + --uncomment-typedef-redef BN_CTX \ + --uncomment-typedef-redef BN_GENCB \ + --uncomment-typedef-redef EC_GROUP \ + --uncomment-typedef-redef EC_KEY \ + --uncomment-typedef-redef EC_POINT \ + --uncomment-typedef-redef ENGINE \ + --uncomment-typedef-redef EVP_MD_CTX --sed 's/ossl_env_md_ctx_st/ossl_evp_md_ctx_st/' \ + --uncomment-typedef-redef EVP_MD --sed 's/ossl_env_md_st/ossl_evp_md_st/' \ + --uncomment-typedef-redef EVP_CIPHER_CTX \ + --uncomment-typedef-redef EVP_CIPHER \ + --uncomment-typedef-redef EVP_PKEY_CTX \ + --uncomment-typedef-redef EVP_PKEY \ + --uncomment-typedef-redef HMAC_CTX \ + --uncomment-typedef-redef RSA \ + --uncomment-typedef-redef PKCS12 --sed 's/ossl_pkcs12_st/ossl_PKCS12_st/' \ + --uncomment-typedef-redef SHA256_CTX --sed 's/struct ossl_sha256_state_st/struct ossl_SHA256state_st/' \ + --uncomment-typedef-redef SSL_CIPHER \ + --uncomment-typedef-redef SSL_CTX \ + --uncomment-typedef-redef SSL_METHOD \ + --uncomment-typedef-redef SSL_SESSION \ + --uncomment-typedef-redef SSL \ + --uncomment-typedef-redef X509 \ + --uncomment-typedef-redef X509_REVOKED \ + --uncomment-typedef-redef X509_STORE \ + --uncomment-typedef-redef ECDSA_SIG --sed 's/ossl_ecdsa_sig_st/ossl_ECDSA_SIG_st/' \ + --uncomment-typedef-redef BIO_METHOD \ + --uncomment-macro BORINGSSL_API_VERSION \ + --uncomment-macro OPENSSL_EXPORT \ + --uncomment-macro OPENSSL_MSVC_PRAGMA \ + --uncomment-macro OPENSSL_UNUSED \ + --uncomment-macro OPENSSL_INLINE \ + --uncomment-macro BORINGSSL_ENUM_INT \ + --uncomment-macro BORINGSSL_NO_CXX \ + --uncomment-macro 'OPENSSL_\(THREADS\|IS_BORINGSSL\|VERSION_NUMBER\|\)' \ + --uncomment-regex 'enum\s*.*\s*BORINGSSL_ENUM_INT' \ + --uncomment-regex 'namespace\s*internal\s*{' \ + --uncomment-regex '}\s*//\s*namespace\s*internal' \ + --uncomment-macro BORINGSSL_MAKE_DELETER \ + --uncomment-macro BORINGSSL_MAKE_UP_REF \ + --uncomment-macro OPENSSL_PRINTF_FORMAT_FUNC \ + --uncomment-macro BSSL_NAMESPACE_BEGIN \ + --uncomment-macro BSSL_NAMESPACE_END \ + --uncomment-regex-range 'template\s*' 'struct\s*DeleterImpl\s*{};' \ + --uncomment-struct Deleter \ + --uncomment-regex-range 'template\s*' \ + --uncomment-macro-redef 'BN_R_[a-zA-Z0-9_]*' \ + --uncomment-typedef BN_ULONG \ + --uncomment-macro BN_BITS2 \ + --uncomment-macro 'BN_\(DEC\|HEX\)_FMT[12]' \ + --uncomment-func-decl BN_new \ + --uncomment-func-decl BN_free \ + --uncomment-func-decl BN_dup \ + --uncomment-func-decl BN_num_bits \ + --uncomment-func-decl BN_set_word \ + --uncomment-func-decl BN_bn2hex \ + --uncomment-func-decl BN_hex2bn \ + --uncomment-func-decl BN_bn2dec \ + --uncomment-func-decl BN_add_word \ + --uncomment-func-decl BN_cmp_word \ + --uncomment-func-decl BN_ucmp \ + --uncomment-func-decl BN_bin2bn \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(BIGNUM' \ diff --git a/bssl-compat/patch/include/openssl/buf.h.sh b/bssl-compat/patch/include/openssl/buf.h.sh new file mode 100755 index 00000000000..78af45552a8 --- /dev/null +++ b/bssl-compat/patch/include/openssl/buf.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h + diff --git a/bssl-compat/patch/include/openssl/bytestring.h.sh b/bssl-compat/patch/include/openssl/bytestring.h.sh new file mode 100755 index 00000000000..0760c1310bc --- /dev/null +++ b/bssl-compat/patch/include/openssl/bytestring.h.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-struct cbs_st \ + --uncomment-func-impl CBS_init \ + --uncomment-func-decl CBS_skip \ + --uncomment-func-impl CBS_data \ + --uncomment-func-impl CBS_len \ + --uncomment-func-decl CBS_get_u8 \ + --uncomment-func-decl CBS_get_u16 \ + --uncomment-func-decl CBS_get_u8_length_prefixed \ + --uncomment-func-decl CBS_get_u16_length_prefixed \ + --uncomment-macro CBS_ASN1_TAG_SHIFT \ + --uncomment-macro CBS_ASN1_CONSTRUCTED \ + --uncomment-macro CBS_ASN1_CONTEXT_SPECIFIC \ + --uncomment-macro CBS_ASN1_TAG_NUMBER_MASK \ + --uncomment-macro CBS_ASN1_INTEGER \ + --uncomment-macro CBS_ASN1_OCTETSTRING \ + --uncomment-macro CBS_ASN1_OBJECT \ + --uncomment-macro CBS_ASN1_ENUMERATED \ + --uncomment-macro CBS_ASN1_SEQUENCE \ + --uncomment-macro CBS_ASN1_GENERALIZEDTIME \ + --uncomment-func-decl CBS_get_asn1 \ + --uncomment-func-decl CBS_peek_asn1_tag \ + --uncomment-func-decl CBS_get_any_asn1_element \ + --uncomment-func-decl CBS_get_optional_asn1 \ + --uncomment-func-decl CBS_asn1_oid_to_text \ + --uncomment-struct cbb_buffer_st \ + --uncomment-struct cbb_child_st \ + --uncomment-struct cbb_st \ + --uncomment-func-decl CBB_zero \ + --uncomment-func-decl CBB_init \ + --uncomment-func-decl CBB_cleanup \ + --uncomment-func-decl CBB_finish \ + --uncomment-func-decl CBB_flush \ + --uncomment-func-decl CBB_data \ + --uncomment-func-decl CBB_len \ + --uncomment-func-decl CBB_add_asn1 \ + --uncomment-func-decl CBB_add_bytes \ + --uncomment-func-decl CBB_add_space \ + --uncomment-func-decl CBB_add_u8 \ + --uncomment-func-decl CBB_add_u16 \ + --uncomment-using ScopedCBB \ + --uncomment-func-decl CBS_get_u64_decimal \ + --uncomment-macro CBS_ASN1_BOOLEAN \ + --uncomment-func-decl CBS_get_asn1_bool \ + --uncomment-func-decl CBB_add_asn1_oid_from_text \ + --uncomment-func-decl CBB_add_asn1_uint64 \ + --uncomment-func-decl CBB_add_asn1_uint64_with_tag \ + --uncomment-func-decl CBS_get_bytes \ + \ No newline at end of file diff --git a/bssl-compat/patch/include/openssl/cipher.h.sh b/bssl-compat/patch/include/openssl/cipher.h.sh new file mode 100755 index 00000000000..b43e7eed7a6 --- /dev/null +++ b/bssl-compat/patch/include/openssl/cipher.h.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl EVP_aes_128_gcm \ + --uncomment-func-decl EVP_aes_256_gcm \ + --uncomment-func-decl EVP_aes_256_cbc \ + --uncomment-func-decl EVP_CIPHER_CTX_new \ + --uncomment-func-decl EVP_CIPHER_CTX_free \ + --uncomment-macro-redef EVP_CTRL_AEAD_GET_TAG \ + --uncomment-macro-redef EVP_CTRL_GCM_SET_IVLEN \ + --uncomment-macro-redef EVP_CTRL_GCM_GET_TAG \ + --uncomment-macro-redef EVP_CTRL_GCM_SET_TAG \ + --uncomment-func-decl EVP_EncryptInit_ex \ + --uncomment-func-decl EVP_DecryptInit_ex \ + --uncomment-func-decl EVP_EncryptUpdate \ + --uncomment-func-decl EVP_EncryptFinal_ex \ + --uncomment-func-decl EVP_DecryptUpdate \ + --uncomment-func-decl EVP_DecryptFinal_ex \ + --uncomment-func-decl EVP_CIPHER_block_size \ + --uncomment-func-decl EVP_CIPHER_key_length \ + --uncomment-func-decl EVP_CIPHER_iv_length \ + --uncomment-func-decl EVP_CIPHER_CTX_ctrl \ + --uncomment-macro-redef 'EVP_MAX_[A-Z0-9_]*_LENGTH' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(EVP_CIPHER_CTX' \ + --uncomment-macro-redef 'CIPHER_R_[[:alnum:]_]*' diff --git a/bssl-compat/patch/include/openssl/conf.h.sh b/bssl-compat/patch/include/openssl/conf.h.sh new file mode 100755 index 00000000000..242a7ef46ed --- /dev/null +++ b/bssl-compat/patch/include/openssl/conf.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-macro-redef 'CONF_R_[a-zA-Z0-9_]*' \ diff --git a/bssl-compat/patch/include/openssl/crypto.h.sh b/bssl-compat/patch/include/openssl/crypto.h.sh new file mode 100755 index 00000000000..51a8e3ddf36 --- /dev/null +++ b/bssl-compat/patch/include/openssl/crypto.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl FIPS_mode diff --git a/bssl-compat/patch/include/openssl/curve25519.h.sh b/bssl-compat/patch/include/openssl/curve25519.h.sh new file mode 100755 index 00000000000..eccbee61e81 --- /dev/null +++ b/bssl-compat/patch/include/openssl/curve25519.h.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro ED25519_PRIVATE_KEY_LEN \ + --uncomment-macro ED25519_PUBLIC_KEY_LEN \ + --uncomment-macro ED25519_SIGNATURE_LEN \ + --uncomment-func-decl ED25519_verify \ diff --git a/bssl-compat/patch/include/openssl/dh.h.sh b/bssl-compat/patch/include/openssl/dh.h.sh new file mode 100755 index 00000000000..841a181f7eb --- /dev/null +++ b/bssl-compat/patch/include/openssl/dh.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-macro-redef 'DH_R_[a-zA-Z0-9_]*' \ diff --git a/bssl-compat/patch/include/openssl/digest.h.sh b/bssl-compat/patch/include/openssl/digest.h.sh new file mode 100755 index 00000000000..845aed9888b --- /dev/null +++ b/bssl-compat/patch/include/openssl/digest.h.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +set -euo pipefail + +MYTMPDIR="$(mktemp -d)" +trap 'rm -rf -- "$MYTMPDIR"' EXIT + +cat > "$MYTMPDIR/ScopedEVP_MD_CTX.h" <() { return ctx_; } + const EVP_MD_CTX *operator->() const { return ctx_; } + + void Reset() { + EVP_MD_CTX_reset(ctx_); + } + private: + EVP_MD_CTX *ctx_; +}; +EOF + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl EVP_md4 \ + --uncomment-func-decl EVP_md5 \ + --uncomment-func-decl EVP_sha1 \ + --uncomment-func-decl EVP_sha224 \ + --uncomment-func-decl EVP_sha256 \ + --uncomment-func-decl EVP_sha384 \ + --uncomment-func-decl EVP_sha512 \ + --uncomment-func-decl EVP_sha512_256 \ + --uncomment-func-decl EVP_md5_sha1 \ + --uncomment-func-decl EVP_MD_CTX_new \ + --uncomment-func-decl EVP_MD_CTX_free \ + --uncomment-func-decl EVP_MD_CTX_copy_ex \ + --uncomment-func-decl EVP_MD_CTX_move \ + --uncomment-func-decl EVP_MD_CTX_reset \ + --uncomment-func-decl EVP_MD_CTX_destroy \ + --uncomment-func-decl EVP_DigestInit_ex \ + --uncomment-func-decl EVP_DigestInit \ + --uncomment-func-decl EVP_DigestUpdate \ + --uncomment-macro-redef EVP_MAX_MD_SIZE \ + --uncomment-func-decl EVP_DigestFinal_ex \ + --uncomment-func-decl EVP_DigestFinal \ + --uncomment-func-decl EVP_MD_type \ + --uncomment-func-decl EVP_MD_size \ + --uncomment-func-decl EVP_MD_CTX_create \ + --uncomment-macro-redef 'DIGEST_R_[[:alnum:]_]*' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(EVP_MD_CTX' \ + --sed "/^\/\/ using ScopedEVP_MD_CTX/ e cat $MYTMPDIR/ScopedEVP_MD_CTX.h" \ + --uncomment-func-decl EVP_MD_nid \ + --uncomment-func-decl EVP_Digest \ + --uncomment-func-decl EVP_MD_CTX_init \ + --uncomment-func-decl EVP_get_digestbyname diff --git a/bssl-compat/patch/include/openssl/dsa.h.sh b/bssl-compat/patch/include/openssl/dsa.h.sh new file mode 100755 index 00000000000..9918e33f2e9 --- /dev/null +++ b/bssl-compat/patch/include/openssl/dsa.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-macro-redef 'DSA_R_[a-zA-Z0-9_]*' \ diff --git a/bssl-compat/patch/include/openssl/ec.h.sh b/bssl-compat/patch/include/openssl/ec.h.sh new file mode 100755 index 00000000000..ff9dc795e06 --- /dev/null +++ b/bssl-compat/patch/include/openssl/ec.h.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl EC_GROUP_get0_order \ + --uncomment-func-decl EC_GROUP_get_curve_name \ + --uncomment-func-decl EC_GROUP_get_degree \ + --uncomment-func-decl EC_POINT_free \ + --uncomment-func-decl EC_POINT_new \ + --uncomment-func-decl EC_POINT_mul \ + --uncomment-macro-redef 'EC_R_[[:alnum:]_]*' diff --git a/bssl-compat/patch/include/openssl/ec_key.h.sh b/bssl-compat/patch/include/openssl/ec_key.h.sh new file mode 100755 index 00000000000..56eeb198f77 --- /dev/null +++ b/bssl-compat/patch/include/openssl/ec_key.h.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl EC_KEY_free \ + --uncomment-func-decl EC_KEY_get0_group \ + --uncomment-func-decl EC_KEY_parse_private_key \ + --uncomment-func-decl EC_KEY_new_by_curve_name \ + --uncomment-func-decl EC_KEY_check_fips \ + --uncomment-func-decl EC_KEY_set_public_key \ + --uncomment-func-decl EC_KEY_set_public_key_affine_coordinates \ + --uncomment-func-decl EC_KEY_set_private_key \ + --uncomment-func-decl EC_KEY_get0_private_key \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(EC_KEY' diff --git a/bssl-compat/patch/include/openssl/ecdh.h.sh b/bssl-compat/patch/include/openssl/ecdh.h.sh new file mode 100755 index 00000000000..66db36ed1e3 --- /dev/null +++ b/bssl-compat/patch/include/openssl/ecdh.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-macro-redef 'ECDH_R_[a-zA-Z0-9_]*' \ diff --git a/bssl-compat/patch/include/openssl/ecdsa.h.sh b/bssl-compat/patch/include/openssl/ecdsa.h.sh new file mode 100755 index 00000000000..bc609e355ce --- /dev/null +++ b/bssl-compat/patch/include/openssl/ecdsa.h.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl ECDSA_sign \ + --uncomment-func-decl ECDSA_size \ + --uncomment-func-decl ECDSA_SIG_new \ + --uncomment-func-decl ECDSA_SIG_free \ + --uncomment-func-decl ECDSA_SIG_get0 \ + --uncomment-func-decl ECDSA_SIG_set0 \ + --uncomment-func-decl ECDSA_do_verify \ + --uncomment-func-decl ECDSA_verify \ + --uncomment-struct ecdsa_sig_st \ + --uncomment-macro-redef 'ECDSA_R_[[:alnum:]_]*' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(ECDSA_SIG,' diff --git a/bssl-compat/patch/include/openssl/engine.h.sh b/bssl-compat/patch/include/openssl/engine.h.sh new file mode 100755 index 00000000000..f3d04738edd --- /dev/null +++ b/bssl-compat/patch/include/openssl/engine.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-macro-redef 'ENGINE_R_[a-zA-Z0-9_]*' diff --git a/bssl-compat/patch/include/openssl/err.h.sh b/bssl-compat/patch/include/openssl/err.h.sh new file mode 100755 index 00000000000..2f85f416b7c --- /dev/null +++ b/bssl-compat/patch/include/openssl/err.h.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --sed '/base\.h/a#include ' \ + --sed '/OPENSSL_INLINE int ERR_GET_LIB/i#define ERR_GET_LIB(packed_error) ossl_ERR_GET_LIB(packed_error)' \ + --sed '/OPENSSL_INLINE int ERR_GET_REASON/i#define ERR_GET_REASON(packed_error) ossl_ERR_GET_REASON(packed_error)' \ + --uncomment-func-decl ERR_get_error \ + --uncomment-func-decl ERR_peek_error \ + --uncomment-func-decl ERR_peek_error_line_data \ + --uncomment-func-decl ERR_peek_last_error \ + --uncomment-func-decl ERR_error_string_n \ + --uncomment-func-decl ERR_lib_error_string \ + --uncomment-func-decl ERR_reason_error_string \ + --uncomment-func-decl ERR_print_errors_fp \ + --uncomment-func-decl ERR_clear_error \ + --uncomment-regex 'enum\s{' \ + --sed 's|^// \([ \t]*\)\(ERR_LIB_[a-zA-Z0-9_]*\)[^a-zA-Z0-9_].*$|#ifdef ossl_\2\n\1\2 = ossl_\2,\n#endif|g' \ + --uncomment-regex '\s\sERR_NUM_LIBS' '};' \ + --uncomment-macro 'ERR_R_[A-Z0-9_]*_LIB' \ + --uncomment-macro-redef 'ERR_R_[[:alnum:]_]*' \ + --sed 's|ossl_ERR_R_OVERFLOW|ossl_ERR_R_INTERNAL_ERROR|' \ + --uncomment-func-decl ERR_func_error_string \ + --uncomment-func-decl ERR_error_string \ + --uncomment-macro ERR_ERROR_STRING_BUF_LEN \ + --sed '/OPENSSL_INLINE int ERR_GET_FUNC/i#define ERR_GET_FUNC(packed_error) ossl_ERR_GET_FUNC(packed_error)' \ + --uncomment-macro OPENSSL_PUT_ERROR \ + --uncomment-func-decl ERR_put_error \ + --uncomment-macro-redef ERR_NUM_ERRORS \ + --sed '/#define ERR_PACK/i#define ERR_PACK(lib, reason) ossl_ERR_PACK(lib, 0, reason)' diff --git a/bssl-compat/patch/include/openssl/evp.h.sh b/bssl-compat/patch/include/openssl/evp.h.sh new file mode 100755 index 00000000000..0d87a225c63 --- /dev/null +++ b/bssl-compat/patch/include/openssl/evp.h.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl EVP_PKEY_new \ + --uncomment-func-decl EVP_PKEY_free \ + --uncomment-func-decl EVP_PKEY_up_ref \ + --uncomment-func-decl EVP_PKEY_cmp \ + --uncomment-func-decl EVP_PKEY_id \ + --uncomment-func-decl EVP_PKEY_assign_RSA \ + --uncomment-func-decl EVP_PKEY_get0_RSA \ + --uncomment-func-decl EVP_PKEY_get1_RSA \ + --uncomment-func-decl EVP_PKEY_assign_EC_KEY \ + --uncomment-func-decl EVP_PKEY_get0_EC_KEY \ + --uncomment-func-decl EVP_PKEY_get1_EC_KEY \ + --uncomment-macro-redef 'EVP_PKEY_[A-Z0-9_]*' \ + --uncomment-func-decl EVP_parse_public_key \ + --uncomment-func-decl EVP_parse_private_key \ + --uncomment-func-decl EVP_DigestVerifyInit \ + --uncomment-func-decl EVP_DigestVerify \ + --uncomment-func-decl EVP_PKEY_set1_RSA \ + --uncomment-func-decl EVP_PKEY_get_raw_public_key \ + --uncomment-func-decl EVP_DigestSign \ + --uncomment-func-decl EVP_DigestSignInit \ + --uncomment-func-decl EVP_DigestSignUpdate \ + --uncomment-func-decl EVP_DigestSignFinal \ + --uncomment-func-decl EVP_DigestVerifyUpdate \ + --uncomment-func-decl EVP_DigestVerifyFinal \ + --uncomment-func-decl EVP_PKEY_CTX_set_rsa_padding \ + --uncomment-func-decl EVP_PKEY_CTX_set_rsa_mgf1_md \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(EVP_PKEY,' \ + --uncomment-regex 'BORINGSSL_MAKE_UP_REF(EVP_PKEY,' \ + --uncomment-func-decl EVP_PKEY_size \ + --uncomment-func-decl EVP_PKEY_bits \ + --uncomment-func-decl EVP_SignInit_ex \ + --uncomment-func-decl EVP_SignUpdate \ + --uncomment-func-decl EVP_SignFinal + diff --git a/bssl-compat/patch/include/openssl/ex_data.h.sh b/bssl-compat/patch/include/openssl/ex_data.h.sh new file mode 100755 index 00000000000..3ea13d2d027 --- /dev/null +++ b/bssl-compat/patch/include/openssl/ex_data.h.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-typedef-redef CRYPTO_EX_DATA \ + --uncomment-typedef CRYPTO_EX_free \ + --uncomment-typedef CRYPTO_EX_dup \ + --uncomment-typedef CRYPTO_EX_unused diff --git a/bssl-compat/patch/include/openssl/hkdf.h.sh b/bssl-compat/patch/include/openssl/hkdf.h.sh new file mode 100755 index 00000000000..3e63af85a1b --- /dev/null +++ b/bssl-compat/patch/include/openssl/hkdf.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro-redef 'HKDF_R_[a-zA-Z0-9_]*' diff --git a/bssl-compat/patch/include/openssl/hmac.h.sh b/bssl-compat/patch/include/openssl/hmac.h.sh new file mode 100755 index 00000000000..792e2c99c4d --- /dev/null +++ b/bssl-compat/patch/include/openssl/hmac.h.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +set -euo pipefail + +MYTMPDIR="$(mktemp -d)" +trap 'rm -rf -- "$MYTMPDIR"' EXIT + +cat > "$MYTMPDIR/ScopedHMAC_CTX.h" <() { return ctx_; } + const HMAC_CTX *operator->() const { return ctx_; } + + void Reset() { + HMAC_CTX_free(ctx_); + ctx_ = HMAC_CTX_new(); + } + + private: + HMAC_CTX *ctx_; +}; +EOF + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl HMAC \ + --uncomment-func-decl HMAC_CTX_new \ + --uncomment-func-decl HMAC_CTX_free \ + --uncomment-func-decl HMAC_Init_ex \ + --uncomment-func-decl HMAC_Update \ + --uncomment-func-decl HMAC_Final \ + --sed "/^\/\/ using ScopedHMAC_CTX/ e cat $MYTMPDIR/ScopedHMAC_CTX.h" diff --git a/bssl-compat/patch/include/openssl/md5.h.sh b/bssl-compat/patch/include/openssl/md5.h.sh new file mode 100755 index 00000000000..eaee19a40a5 --- /dev/null +++ b/bssl-compat/patch/include/openssl/md5.h.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro MD5_DIGEST_LENGTH \ + --uncomment-func-decl MD5 diff --git a/bssl-compat/patch/include/openssl/mem.h.sh b/bssl-compat/patch/include/openssl/mem.h.sh new file mode 100755 index 00000000000..c703c71c358 --- /dev/null +++ b/bssl-compat/patch/include/openssl/mem.h.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl OPENSSL_malloc \ + --uncomment-func-decl OPENSSL_free \ + --uncomment-func-decl OPENSSL_realloc \ + --uncomment-func-decl CRYPTO_memcmp \ + --uncomment-func-decl OPENSSL_isdigit \ + --uncomment-func-decl OPENSSL_fromxdigit \ + --uncomment-func-decl OPENSSL_isspace \ + --uncomment-macro DECIMAL_SIZE \ + --uncomment-func-decl BIO_snprintf \ + --uncomment-func-decl OPENSSL_memdup \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(char,' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(uint8_t,' diff --git a/bssl-compat/patch/include/openssl/nid.h.sh b/bssl-compat/patch/include/openssl/nid.h.sh new file mode 100755 index 00000000000..8c5c986db09 --- /dev/null +++ b/bssl-compat/patch/include/openssl/nid.h.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro-redef 'SN_[a-zA-Z0-9_]*' \ + --uncomment-macro-redef 'LN_[a-zA-Z0-9_]*' \ + --uncomment-macro-redef 'NID_[a-zA-Z0-9_]*' \ + --uncomment-macro-redef 'OBJ_[a-zA-Z0-9_]*' \ + --sed 's|^// \s*1L, .*$||g' \ + --sed 's|^// \s*"[^"]*"$||g' diff --git a/bssl-compat/patch/include/openssl/obj.h.sh b/bssl-compat/patch/include/openssl/obj.h.sh new file mode 100755 index 00000000000..ca7e8632c3c --- /dev/null +++ b/bssl-compat/patch/include/openssl/obj.h.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl OBJ_txt2obj \ + --uncomment-func-decl OBJ_obj2txt \ + --uncomment-func-decl OBJ_cmp \ + --uncomment-func-decl OBJ_obj2nid \ + --uncomment-macro-redef 'OBJ_R_[[:alnum:]_]*' + diff --git a/bssl-compat/patch/include/openssl/pem.h.sh b/bssl-compat/patch/include/openssl/pem.h.sh new file mode 100755 index 00000000000..b208150fc9d --- /dev/null +++ b/bssl-compat/patch/include/openssl/pem.h.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro 'PEM_STRING_[[:alnum:]_]*' \ + --uncomment-macro DECLARE_PEM_read_fp \ + --uncomment-macro DECLARE_PEM_write_fp \ + --uncomment-macro DECLARE_PEM_write_cb_fp \ + --uncomment-macro DECLARE_PEM_read_bio \ + --uncomment-macro DECLARE_PEM_write_bio \ + --uncomment-macro DECLARE_PEM_write_cb_bio \ + --uncomment-macro DECLARE_PEM_write \ + --uncomment-macro DECLARE_PEM_write_cb \ + --uncomment-macro DECLARE_PEM_read \ + --uncomment-macro DECLARE_PEM_rw \ + --uncomment-macro DECLARE_PEM_rw_cb \ + --uncomment-typedef pem_password_cb \ + --uncomment-func-decl PEM_bytes_read_bio \ + --uncomment-func-decl PEM_X509_INFO_read_bio \ + --uncomment-regex 'DECLARE_PEM_rw(X509,' \ + --uncomment-regex 'DECLARE_PEM_rw(X509_CRL,' \ + --uncomment-regex 'DECLARE_PEM_rw(X509_AUX,' \ + --uncomment-regex 'DECLARE_PEM_rw_cb(RSAPrivateKey,' \ + --uncomment-regex 'DECLARE_PEM_rw_cb(PrivateKey,' \ + --uncomment-regex 'DECLARE_PEM_rw(PUBKEY,' \ + --uncomment-macro-redef 'PEM_R_[[:alnum:]_]*' diff --git a/bssl-compat/patch/include/openssl/pkcs12.h.sh b/bssl-compat/patch/include/openssl/pkcs12.h.sh new file mode 100755 index 00000000000..30a3b7b6b01 --- /dev/null +++ b/bssl-compat/patch/include/openssl/pkcs12.h.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h diff --git a/bssl-compat/patch/include/openssl/pkcs7.h.sh b/bssl-compat/patch/include/openssl/pkcs7.h.sh new file mode 100755 index 00000000000..74d50a7d0c2 --- /dev/null +++ b/bssl-compat/patch/include/openssl/pkcs7.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment \ + --uncomment-macro-redef 'PKCS7_R_[a-zA-Z0-9_]*' diff --git a/bssl-compat/patch/include/openssl/pkcs8.h.sh b/bssl-compat/patch/include/openssl/pkcs8.h.sh new file mode 100755 index 00000000000..5aed0aa21f9 --- /dev/null +++ b/bssl-compat/patch/include/openssl/pkcs8.h.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl PKCS12_get_key_and_certs \ + --uncomment-func-decl d2i_PKCS12_bio \ + --uncomment-func-decl PKCS12_parse \ + --uncomment-func-decl PKCS12_verify_mac \ + --uncomment-func-decl PKCS12_free \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(PKCS12,' \ + --uncomment-macro-redef 'PKCS8_R_[[:alnum:]_]*' diff --git a/bssl-compat/patch/include/openssl/pool.h.sh b/bssl-compat/patch/include/openssl/pool.h.sh new file mode 100755 index 00000000000..961485c199f --- /dev/null +++ b/bssl-compat/patch/include/openssl/pool.h.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl 'CRYPTO_BUFFER_new' \ + --uncomment-func-decl 'CRYPTO_BUFFER_free' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER,' \ + --uncomment-regex 'DEFINE_STACK_OF(CRYPTO_BUFFER)' diff --git a/bssl-compat/patch/include/openssl/rand.h.sh b/bssl-compat/patch/include/openssl/rand.h.sh new file mode 100755 index 00000000000..0d64906cab5 --- /dev/null +++ b/bssl-compat/patch/include/openssl/rand.h.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl RAND_bytes \ + --uncomment-func-decl RAND_enable_fork_unsafe_buffering diff --git a/bssl-compat/patch/include/openssl/rsa.h.sh b/bssl-compat/patch/include/openssl/rsa.h.sh new file mode 100755 index 00000000000..673eb5e8ac0 --- /dev/null +++ b/bssl-compat/patch/include/openssl/rsa.h.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ +--uncomment-func-decl RSA_new \ +--uncomment-func-decl RSA_free \ +--uncomment-func-decl RSA_bits \ +--uncomment-func-decl RSA_get0_key \ +--uncomment-func-decl RSA_get0_factors \ +--uncomment-func-decl RSA_get0_crt_params \ +--uncomment-func-decl RSA_set0_key \ +--uncomment-func-decl RSA_set0_factors \ +--uncomment-func-decl RSA_set0_crt_params \ +--uncomment-func-decl RSA_generate_key_ex \ +--uncomment-func-decl RSA_encrypt \ +--uncomment-func-decl RSA_decrypt \ +--uncomment-func-decl RSA_sign \ +--uncomment-func-decl RSA_sign_pss_mgf1 \ +--uncomment-func-decl RSA_verify \ +--uncomment-func-decl RSA_size \ +--uncomment-func-decl RSA_check_key \ +--uncomment-func-decl RSA_check_fips \ +--uncomment-func-decl RSA_add_pkcs1_prefix \ +--uncomment-func-decl RSA_public_key_from_bytes \ +--uncomment-func-decl RSA_private_key_from_bytes \ +--uncomment-macro-redef 'RSA_R_[a-zA-Z0-9_]*' \ +--uncomment-macro-redef 'RSA_[a-zA-Z0-9_]*_PADDING' \ +--uncomment-macro-redef RSA_F4 \ +--uncomment-regex 'BORINGSSL_MAKE_DELETER(RSA' \ +--uncomment-func-decl RSA_get0_e \ +--uncomment-func-decl RSA_get0_d \ +--uncomment-func-decl RSA_get0_n \ +--uncomment-func-decl RSA_get0_q \ +--uncomment-func-decl RSA_get0_dmp1 \ +--uncomment-func-decl RSA_get0_dmq1 \ +--uncomment-func-decl RSA_get0_p \ +--uncomment-func-decl RSA_get0_iqmp \ +--uncomment-macro RSA_FLAG_NO_PUBLIC_EXPONENT diff --git a/bssl-compat/patch/include/openssl/sha.h.sh b/bssl-compat/patch/include/openssl/sha.h.sh new file mode 100755 index 00000000000..86e127d8d38 --- /dev/null +++ b/bssl-compat/patch/include/openssl/sha.h.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro 'SHA[0-9_]*_DIGEST_LENGTH' \ + --uncomment-func-decl SHA1 \ + --uncomment-func-decl SHA224 \ + --uncomment-func-decl SHA256 \ + --uncomment-func-decl SHA384 \ + --uncomment-func-decl SHA512 \ + --uncomment-func-decl SHA512_256 \ + --uncomment-func-decl SHA256_Init \ + --uncomment-func-decl SHA256_Update \ + --uncomment-func-decl SHA256_Final \ + diff --git a/bssl-compat/patch/include/openssl/span.h.sh b/bssl-compat/patch/include/openssl/span.h.sh new file mode 100755 index 00000000000..6936070ea17 --- /dev/null +++ b/bssl-compat/patch/include/openssl/span.h.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-regex 'template ' \ + --uncomment-regex 'template ' \ + --uncomment-regex 'template <' \ + --uncomment-regex 'inline constexpr.*' \ + --uncomment-regex ' typename\s[TC=].*' \ + --uncomment-class-fwd Span \ + --uncomment-regex-range 'namespace internal {' '};'\ + --uncomment-regex-range 'using EnableIfContainer' '.\s\s..\snamespace\sinternal'\ + --uncomment-class Span \ + --uncomment-regex 'Span(.*' \ + --uncomment-regex '.*Span::npos' \ + --uncomment-func-impl MakeSpan \ + --uncomment-func-impl MakeSpan \ + --uncomment-func-impl MakeSpan \ + --uncomment-func-impl MakeConstSpan \ + --uncomment-func-impl MakeConstSpan \ + --uncomment-func-impl MakeConstSpan \ + --uncomment-func-impl StringAsBytes \ + --uncomment-func-impl BytesAsStringView \ diff --git a/bssl-compat/patch/include/openssl/ssl.h.sh b/bssl-compat/patch/include/openssl/ssl.h.sh new file mode 100755 index 00000000000..cfbdee7f25f --- /dev/null +++ b/bssl-compat/patch/include/openssl/ssl.h.sh @@ -0,0 +1,219 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-func-decl TLS_method \ + --uncomment-func-decl OPENSSL_init_ssl \ + --uncomment-func-decl DTLS_method \ + --uncomment-func-decl SSL_write \ + --uncomment-func-decl SSL_version \ + --uncomment-func-decl SSL_shutdown \ + --uncomment-func-decl SSL_set1_curves_list \ + --uncomment-func-decl SSL_set0_wbio \ + --uncomment-func-decl SSL_set0_rbio \ + --uncomment-func-decl SSL_set_verify \ + --uncomment-func-decl SSL_set_tlsext_host_name \ + --uncomment-func-decl SSL_set_session \ + --uncomment-func-decl SSL_set_quiet_shutdown \ + --uncomment-func-decl SSL_get_quiet_shutdown \ + --uncomment-func-decl SSL_set_fd \ + --uncomment-func-decl SSL_set_ex_data \ + --uncomment-func-decl SSL_set_connect_state \ + --uncomment-func-decl SSL_set_cipher_list \ + --uncomment-func-decl SSL_set_cert_cb \ + --uncomment-func-decl SSL_get0_peer_verify_algorithms \ + --uncomment-func-decl SSL_set_bio \ + --uncomment-macro SSL_set_app_data \ + --uncomment-func-decl SSL_set_alpn_protos \ + --uncomment-func-decl SSL_set_accept_state \ + --uncomment-func-decl SSL_session_reused \ + --uncomment-func-decl SSL_SESSION_is_resumable \ + --uncomment-func-decl SSL_SESSION_get_ticket_lifetime_hint \ + --uncomment-func-decl SSL_SESSION_get_id \ + --uncomment-func-decl SSL_SESSION_free \ + --uncomment-func-decl SSL_SESSION_up_ref \ + --uncomment-func-decl SSL_select_next_proto \ + --uncomment-func-decl SSL_read \ + --uncomment-func-decl SSL_new \ + --uncomment-func-decl SSL_get1_session \ + --uncomment-func-decl SSL_get0_alpn_selected \ + --uncomment-func-decl SSL_get_version \ + --uncomment-func-decl SSL_get_SSL_CTX \ + --uncomment-func-decl SSL_get_session \ + --uncomment-func-decl SSL_get_servername \ + --uncomment-func-decl SSL_get_peer_certificate \ + --uncomment-func-decl SSL_get_ex_new_index \ + --uncomment-func-decl SSL_get_ex_data \ + --uncomment-func-decl SSL_alert_from_verify_result \ + --uncomment-func-decl SSL_get_ex_data_X509_STORE_CTX_idx \ + --uncomment-func-decl SSL_get_error \ + --uncomment-func-decl SSL_get_current_cipher \ + --uncomment-func-decl SSL_get_client_CA_list \ + --uncomment-macro SSL_get_cipher_name \ + --uncomment-func-decl SSL_get_certificate \ + --uncomment-macro SSL_get_app_data \ + --uncomment-func-decl SSL_do_handshake \ + --uncomment-func-decl SSL_CTX_check_private_key \ + --uncomment-func-decl SSL_CTX_set_tmp_ecdh \ + --uncomment-func-decl SSL_get0_next_proto_negotiated \ + --uncomment-func-decl SSL_CTX_use_PrivateKey \ + --uncomment-func-decl SSL_CTX_use_PrivateKey_file \ + --uncomment-func-decl SSL_CTX_use_certificate \ + --uncomment-func-decl SSL_CTX_use_certificate_file \ + --uncomment-func-decl SSL_CTX_set1_curves_list \ + --uncomment-func-decl SSL_CTX_set_verify \ + --uncomment-func-decl SSL_CTX_set_verify_depth \ + --uncomment-func-decl SSL_CTX_set_tlsext_ticket_key_cb \ + --uncomment-func-decl SSL_CTX_set_tlsext_servername_callback \ + --uncomment-func-decl SSL_CTX_set_timeout \ + --uncomment-func-decl SSL_CTX_set_session_id_context \ + --uncomment-func-decl SSL_CTX_set_session_cache_mode \ + --uncomment-func-decl SSL_CTX_set_options \ + --uncomment-func-decl SSL_CTX_set_min_proto_version \ + --uncomment-func-decl SSL_CTX_set_max_proto_version \ + --uncomment-func-decl SSL_CTX_set_client_CA_list \ + --uncomment-func-decl SSL_CTX_set_cert_verify_callback \ + --uncomment-macro SSL_CTX_set_app_data \ + --uncomment-func-decl SSL_CTX_set_alpn_select_cb \ + --uncomment-func-decl SSL_CTX_set_alpn_protos \ + --uncomment-func-decl SSL_CTX_sess_set_new_cb \ + --uncomment-func-decl SSL_CTX_new \ + --uncomment-func-decl SSL_CTX_up_ref \ + --uncomment-func-decl SSL_CTX_get0_param \ + --uncomment-func-decl SSL_CTX_get_verify_mode \ + --uncomment-func-decl SSL_CTX_get_options \ + --uncomment-func-decl SSL_CTX_get_client_CA_list \ + --uncomment-func-decl SSL_CTX_get_ciphers \ + --uncomment-func-decl SSL_CTX_get_cert_store \ + --uncomment-func-decl SSL_CTX_set_cert_store \ + --uncomment-func-decl SSL_CTX_get_ex_new_index \ + --uncomment-macro SSL_CTX_get_app_data \ + --uncomment-func-decl SSL_CTX_free \ + --uncomment-func-decl SSL_CTX_add_extra_chain_cert \ + --uncomment-func-decl SSL_CIPHER_get_name \ + --uncomment-func-decl SSL_CIPHER_get_id \ + --uncomment-func-decl SSL_CIPHER_get_auth_nid \ + --uncomment-func-decl SSL_CTX_set_select_certificate_cb \ + --uncomment-func-decl SSL_CTX_set_keylog_callback \ + --uncomment-func-decl SSL_CIPHER_get_min_version \ + --uncomment-func-decl SSL_get_peer_full_cert_chain \ + --uncomment-func-decl SSL_set_ocsp_response \ + --uncomment-func-decl SSL_set_renegotiate_mode \ + --uncomment-func-decl SSL_CTX_get0_certificate \ + --uncomment-func-decl SSL_enable_ocsp_stapling \ + --uncomment-func-decl SSL_error_description \ + --uncomment-func-decl SSL_SESSION_should_be_single_use \ + --uncomment-func-decl SSL_set_SSL_CTX \ + --uncomment-func-decl SSL_set_info_callback \ + --uncomment-func-decl SSL_state_string_long \ + --uncomment-func-decl SSL_state_string \ + --uncomment-func-decl TLS_with_buffers_method \ + --uncomment-func-decl SSL_get_signature_algorithm_digest \ + --uncomment-func-decl SSL_get_signature_algorithm_key_type \ + --uncomment-func-decl SSL_is_signature_algorithm_rsa_pss \ + --uncomment-func-decl SSL_CTX_set_next_proto_select_cb \ + --uncomment-func-decl SSL_CTX_set_strict_cipher_list \ + --uncomment-func-decl SSL_CTX_set_verify_algorithm_prefs \ + --uncomment-func-decl SSL_CTX_set_next_protos_advertised_cb \ + --uncomment-func-decl SSL_early_callback_ctx_extension_get \ + --uncomment-func-decl SSL_get_cipher_by_value \ + --uncomment-func-decl SSL_get_curve_id \ + --uncomment-func-decl SSL_get_curve_name \ + --uncomment-func-decl SSL_get_peer_signature_algorithm \ + --uncomment-func-decl SSL_get_signature_algorithm_name \ + --uncomment-func-decl SSL_get0_ocsp_response \ + --uncomment-func-decl SSL_set_chain_and_key \ + --uncomment-func-decl SSL_SESSION_from_bytes \ + --uncomment-func-decl SSL_is_server \ + --uncomment-func-decl SSL_is_init_finished \ + --uncomment-func-decl SSL_get_wbio \ + --uncomment-func-decl SSL_get_rbio \ + --uncomment-func-decl SSL_connect \ + --uncomment-func-decl SSL_accept \ + --uncomment-func-decl SSL_free \ + --uncomment-macro-redef 'SSL_ERROR_[[:alnum:]_]*' \ + --uncomment-macro-redef '\(DTLS1\|DTLS1_2\|SSL3\|TLS1\|TLS1_1\|TLS1_2\|TLS1_3\)_VERSION' \ + --uncomment-macro-redef '\(DTLS1\|SSL3\)_VERSION_MAJOR' \ + --uncomment-func-decl SSL_CTX_get_min_proto_version \ + --uncomment-func-decl SSL_CTX_get_max_proto_version \ + --uncomment-macro-redef 'SSL_OP_[[:alnum:]_]*' \ + --uncomment-macro-redef 'SSL_MODE_[[:alnum:]_]*' \ + --uncomment-macro 'SSL_SIGN_[[:alnum:]_]*' \ + --uncomment-macro-redef 'SSL_FILETYPE_[[:alnum:]_]*' \ + --uncomment-func-decl SSL_CTX_use_certificate_chain_file \ + --uncomment-enum ssl_private_key_result_t \ + --uncomment-struct ssl_private_key_method_st \ + --uncomment-regex 'DEFINE_CONST_STACK_OF(SSL_CIPHER)' \ + --uncomment-func-decl SSL_CIPHER_get_cipher_nid \ + --uncomment-func-decl SSL_CIPHER_get_digest_nid \ + --uncomment-func-decl SSL_CIPHER_get_kx_nid \ + --uncomment-func-decl SSL_CIPHER_get_prf_nid \ + --uncomment-func-decl SSL_CIPHER_standard_name \ + --uncomment-func-decl SSL_CTX_set_cipher_list \ + --uncomment-func-decl SSL_get_ciphers \ + --uncomment-func-decl SSL_get_peer_cert_chain \ + --uncomment-func-decl SSL_SESSION_new \ + --uncomment-func-decl SSL_SESSION_to_bytes \ + --uncomment-func-decl SSL_SESSION_get_version \ + --uncomment-func-decl SSL_SESSION_set_protocol_version \ + --uncomment-macro-redef 'SSL_SESS_[[:alnum:]_]*' \ + --uncomment-func-decl SSL_set_session_id_context \ + --uncomment-func-decl SSL_CTX_set_tlsext_ticket_keys \ + --uncomment-macro 'SSL_CURVE_SECP[0-9]*R1' \ + --uncomment-macro 'SSL_CURVE_X25519' \ + --uncomment-macro-redef 'SSL_VERIFY_[[:alnum:]_]*' \ + --uncomment-func-decl SSL_CTX_load_verify_locations \ + --uncomment-func-decl SSL_set_client_CA_list \ + --uncomment-func-decl SSL_add_file_cert_subjects_to_stack \ + --uncomment-macro TLSEXT_NAMETYPE_host_name \ + --uncomment-func-decl SSL_CTX_set_tlsext_servername_arg \ + --uncomment-macro-redef 'SSL_TLSEXT_ERR_[[:alnum:]_]*' \ + --uncomment-macro-redef 'OPENSSL_NPN_[[:alnum:]_]*' \ + --uncomment-macro-redef 'SSL_AD_[[:alnum:]_]*' \ + --uncomment-func-decl SSL_CTX_set_ex_data \ + --uncomment-func-decl SSL_CTX_get_ex_data \ + --uncomment-enum ssl_renegotiate_mode_t \ + --uncomment-struct ssl_early_callback_ctx \ + --uncomment-enum ssl_select_cert_result_t \ + --uncomment-func-decl TLS_server_method \ + --uncomment-func-decl TLS_client_method \ + --uncomment-func-decl i2d_SSL_SESSION \ + --uncomment-func-decl d2i_SSL_SESSION \ + --uncomment-func-decl SSL_CTX_set1_sigalgs_list \ + --uncomment-func-decl SSL_CTX_set_tlsext_status_cb \ + --uncomment-macro-redef 'SSL_R_[[:alnum:]_]*' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(SSL,' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(SSL_CTX,' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(SSL_SESSION,' \ + --uncomment-macro-redef SSL_CB_LOOP \ + --uncomment-macro-redef SSL_CB_HANDSHAKE_START \ + --uncomment-macro-redef SSL_CB_HANDSHAKE_DONE \ + --uncomment-macro-redef SSL_MAX_SSL_SESSION_ID_LENGTH \ + --uncomment-macro SSL_TICKET_KEY_NAME_LEN \ + --uncomment-enum ssl_verify_result_t \ + --uncomment-func-decl SSL_CTX_set_custom_verify \ + --uncomment-func-decl SSL_CTX_set_private_key_method \ + --uncomment-func-decl SSL_send_fatal_alert \ + --uncomment-func-decl SSL_alert_desc_string_long \ + --uncomment-func-decl SSL_CTX_get_session_cache_mode \ + --uncomment-func-decl SSL_get0_peer_certificates \ + --uncomment-func-decl SSL_get_all_cipher_names \ + --uncomment-func-decl SSL_get_all_signature_algorithm_names \ + --uncomment-func-decl SSL_get_all_version_names \ + --uncomment-func-decl SSL_get_all_curve_names \ + --uncomment-macro SSL_GROUP_SECP224R1 \ + --uncomment-macro SSL_GROUP_SECP256R1 \ + --uncomment-macro SSL_GROUP_SECP384R1 \ + --uncomment-macro SSL_GROUP_SECP521R1 \ + --uncomment-macro SSL_GROUP_X25519 \ + --uncomment-macro SSL_GROUP_X25519_MLKEM768 \ + --uncomment-macro SSL_GROUP_X25519_KYBER768_DRAFT00 \ + --uncomment-func-decl SSL_CIPHER_get_handshake_digest \ + --uncomment-enum ssl_compliance_policy_t \ + --uncomment-func-decl SSL_CTX_set_compliance_policy \ + --uncomment-func-decl SSL_get_verify_result \ + --uncomment-func-decl SSL_CIPHER_get_version \ + --uncomment-func-decl SSL_set0_CA_names \ + --uncomment-func-decl SSL_clear \ + --uncomment-macro DTLS1_3_VERSION \ diff --git a/bssl-compat/patch/include/openssl/ssl3.h.sh b/bssl-compat/patch/include/openssl/ssl3.h.sh new file mode 100755 index 00000000000..3411295ded2 --- /dev/null +++ b/bssl-compat/patch/include/openssl/ssl3.h.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro SSL3_RT_MAX_PLAIN_LENGTH \ + diff --git a/bssl-compat/patch/include/openssl/stack.h.patch b/bssl-compat/patch/include/openssl/stack.h.patch new file mode 100644 index 00000000000..16b17d2afc7 --- /dev/null +++ b/bssl-compat/patch/include/openssl/stack.h.patch @@ -0,0 +1,92 @@ +--- a/source/include/openssl/stack.h 2025-08-28 17:41:22.808667240 +0200 ++++ b/source/include/openssl/stack.h 2025-08-29 10:24:58.150108167 +0200 +@@ -248,6 +248,7 @@ + // An OPENSSL_STACK contains an array of pointers. It is not designed to be used + // directly, rather the wrapper macros should be used. + typedef struct stack_st OPENSSL_STACK; ++#define OPENSSL_STACK ossl_OPENSSL_STACK + + // The following are raw stack functions. They implement the corresponding typed + // |sk_SAMPLE_*| functions generated by |DEFINE_STACK_OF|. Callers shouldn't be +@@ -295,7 +296,7 @@ + // TODO(b/290792019, b/290785937): Ideally these would at least be inline + // functions, so we do not squat the symbols. + +-typedef OPENSSL_STACK _STACK; ++#define _STACK ossl_OPENSSL_STACK + + // The following functions call the corresponding |OPENSSL_sk_*| function. + OPENSSL_EXPORT OPENSSL_DEPRECATED OPENSSL_STACK *sk_new_null(void); +@@ -360,9 +361,6 @@ + * positive warning. */ \ + OPENSSL_MSVC_PRAGMA(warning(push)) \ + OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ +- OPENSSL_CLANG_PRAGMA("clang diagnostic push") \ +- OPENSSL_CLANG_PRAGMA("clang diagnostic ignored \"-Wunknown-warning-option\"") \ +- OPENSSL_CLANG_PRAGMA("clang diagnostic ignored \"-Wcast-function-type-strict\"") \ + \ + DECLARE_STACK_OF(name) \ + \ +@@ -389,11 +387,7 @@ + /* |cmp_func| expects an extra layer of pointers to match qsort. */ \ + return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ + } \ +- \ +- OPENSSL_INLINE int sk_##name##_call_delete_if_func( \ +- OPENSSL_sk_delete_if_func func, void *obj, void *data) { \ +- return ((sk_##name##_delete_if_func)func)((ptrtype)obj, data); \ +- } \ ++ \ + \ + OPENSSL_INLINE STACK_OF(name) *sk_##name##_new(sk_##name##_cmp_func comp) { \ + return (STACK_OF(name) *)OPENSSL_sk_new((OPENSSL_sk_cmp_func)comp); \ +@@ -446,12 +440,7 @@ + return (ptrtype)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ + (const void *)p); \ + } \ +- \ +- OPENSSL_INLINE void sk_##name##_delete_if( \ +- STACK_OF(name) *sk, sk_##name##_delete_if_func func, void *data) { \ +- OPENSSL_sk_delete_if((OPENSSL_STACK *)sk, sk_##name##_call_delete_if_func, \ +- (OPENSSL_sk_delete_if_func)func, data); \ +- } \ ++ \ + \ + OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ + size_t *out_index, constptrtype p) { \ +@@ -496,10 +485,8 @@ + (const OPENSSL_STACK *)sk, sk_##name##_call_copy_func, \ + (OPENSSL_sk_copy_func)copy_func, sk_##name##_call_free_func, \ + (OPENSSL_sk_free_func)free_func); \ +- } \ +- \ +- OPENSSL_CLANG_PRAGMA("clang diagnostic pop") \ +- OPENSSL_MSVC_PRAGMA(warning(pop)) ++ } ++ + + + // Built-in stacks. +@@ -539,12 +526,8 @@ + // sk_FOO_pop_free is defined by macros and bound by name, so we cannot + // access it from C++ here. + using Type = typename StackTraits::Type; +- OPENSSL_sk_pop_free_ex( +- reinterpret_cast(sk), +- [](OPENSSL_sk_free_func /* unused */, void *ptr) { +- DeleterImpl::Free(reinterpret_cast(ptr)); +- }, +- nullptr); ++ ossl_OPENSSL_sk_pop_free(reinterpret_cast(sk), ++ reinterpret_cast(DeleterImpl::Free)); + } + }; + +@@ -606,7 +589,6 @@ + + BSSL_NAMESPACE_END + +-// Define begin() and end() for stack types so C++ range for loops work. + template + inline bssl::internal::StackIterator begin(const Stack *sk) { + return bssl::internal::StackIterator(sk, 0); diff --git a/bssl-compat/patch/include/openssl/stack.h.sh b/bssl-compat/patch/include/openssl/stack.h.sh new file mode 100755 index 00000000000..389dffce92b --- /dev/null +++ b/bssl-compat/patch/include/openssl/stack.h.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --sed '/#include /a#include ' \ + --uncomment-macro STACK_OF \ + --uncomment-macro DECLARE_STACK_OF \ + --uncomment-macro DEFINE_NAMED_STACK_OF \ + --uncomment-macro DEFINE_STACK_OF \ + --uncomment-macro DEFINE_CONST_STACK_OF \ + --uncomment-regex 'template '\ + --uncomment-regex 'namespace internal {' 'template ' 'struct StackTraits \{\};' '}' \ + --uncomment-macro BORINGSSL_DEFINE_STACK_TRAITS \ + --uncomment-macro BORINGSSL_DEFINE_STACK_OF_IMPL \ + --uncomment-struct DeleterImpl \ + --uncomment-struct DeleterImpl \ + --uncomment-class StackIteratorImpl \ + --uncomment-using StackIterator \ + --uncomment-regex-range 'inline std::enable_if_t.*' '}' \ + --uncomment-regex-range 'inline .*StackIterator.*begin' '}' \ + --uncomment-regex-range 'inline .*StackIterator.*end' '}' \ + --uncomment-regex '}$' \ + --uncomment-regex 'namespace internal {' \ + --uncomment-regex '} // namespace internal' \ + --uncomment-typedef OPENSSL_sk_free_func \ + --uncomment-typedef OPENSSL_sk_copy_func \ + --uncomment-typedef OPENSSL_sk_cmp_func \ + --uncomment-typedef OPENSSL_sk_call_free_func \ + --uncomment-typedef OPENSSL_sk_call_copy_func \ + --uncomment-typedef OPENSSL_sk_call_cmp_func \ + --uncomment-typedef OPENSSL_sk_delete_if_func \ + --uncomment-func-decl OPENSSL_sk_deep_copy \ + --uncomment-func-decl OPENSSL_sk_num \ + --uncomment-func-decl OPENSSL_sk_pop_free_ex \ + --uncomment-func-decl OPENSSL_sk_push \ + --uncomment-func-decl OPENSSL_sk_pop \ + --uncomment-func-decl OPENSSL_sk_new_null \ + --uncomment-func-decl OPENSSL_sk_value \ + --uncomment-func-decl OPENSSL_sk_set \ + --uncomment-func-decl OPENSSL_sk_free \ + --uncomment-func-decl OPENSSL_sk_delete \ + --uncomment-func-decl OPENSSL_sk_delete_ptr \ + --uncomment-func-decl OPENSSL_sk_new \ + --uncomment-func-decl OPENSSL_sk_insert \ + --uncomment-func-decl OPENSSL_sk_is_sorted \ + --uncomment-func-decl OPENSSL_sk_dup \ + --uncomment-func-decl OPENSSL_sk_find \ + --uncomment-func-decl OPENSSL_sk_set_cmp_func \ + --uncomment-func-decl OPENSSL_sk_shift \ + --uncomment-func-decl OPENSSL_sk_sort \ + --uncomment-func-decl OPENSSL_sk_zero \ + --uncomment-func-decl sk_new_null \ + --uncomment-func-decl sk_num \ + --uncomment-func-decl sk_value \ + --uncomment-func-decl sk_free \ + --uncomment-macro OPENSSL_STACK \ + --uncomment-macro _STACK \ diff --git a/bssl-compat/patch/include/openssl/target.h.sh b/bssl-compat/patch/include/openssl/target.h.sh new file mode 100755 index 00000000000..57e300d6b29 --- /dev/null +++ b/bssl-compat/patch/include/openssl/target.h.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ +--uncomment-macro OPENSSL_ASM_INCOMPATIBLE \ +--uncomment-macro OPENSSL_NO_ASM \ +--uncomment-macro OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED \ +--uncomment-macro 'OPENSSL_\(X86_64\|X86\|AARCH64\|ARM\|MIPS\|MIPS64\|RISCV64\|PNACL\)' \ +--uncomment-macro 'OPENSSL_\(APPLE\|MACOS\|IOS\)' \ +--uncomment-macro 'OPENSSL_\(WINDOWS\|LINUX\|FUCHSIA\|TRUSTY\|ANDROID\|FREEBSD\)' \ +--uncomment-macro 'OPENSSL_[ATM]SAN' \ +--uncomment-macro OPENSSL_64_BIT \ +--uncomment-macro OPENSSL_32_BIT diff --git a/bssl-compat/patch/include/openssl/tls1.h.sh b/bssl-compat/patch/include/openssl/tls1.h.sh new file mode 100755 index 00000000000..1e1791c558e --- /dev/null +++ b/bssl-compat/patch/include/openssl/tls1.h.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro-redef 'TLSEXT_TYPE_[[:alnum:]_]*' \ + --sed 's/ossl_TLSEXT_TYPE_psk_key_exchange_modes/ossl_TLSEXT_TYPE_psk_kex_modes/' \ + --uncomment-macro TLS1_CK_PSK_WITH_AES_128_CBC_SHA \ + --uncomment-macro TLS1_CK_PSK_WITH_AES_256_CBC_SHA \ + --uncomment-macro TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA \ + --uncomment-macro TLS1_CK_RSA_WITH_AES_128_SHA \ + --uncomment-macro TLS1_CK_RSA_WITH_AES_256_SHA \ + --uncomment-macro TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 \ + --uncomment-macro TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 \ + --uncomment-macro TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA \ + --uncomment-macro TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA \ + --uncomment-macro TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA \ + --uncomment-macro TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA \ + --uncomment-macro TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 \ + --uncomment-macro TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 \ + --uncomment-macro TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 \ + --uncomment-macro TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 \ + --uncomment-macro TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 \ + --uncomment-macro TLS1_3_CK_AES_128_GCM_SHA256 \ + --uncomment-macro TLS1_3_CK_AES_256_GCM_SHA384 \ + --uncomment-macro TLS1_3_CK_CHACHA20_POLY1305_SHA256 diff --git a/bssl-compat/patch/include/openssl/trust_token.h.sh b/bssl-compat/patch/include/openssl/trust_token.h.sh new file mode 100755 index 00000000000..b9522aff3ca --- /dev/null +++ b/bssl-compat/patch/include/openssl/trust_token.h.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-macro-redef 'TRUST_TOKEN_R_[a-zA-Z0-9_]*' diff --git a/bssl-compat/patch/include/openssl/x509.h.sh b/bssl-compat/patch/include/openssl/x509.h.sh new file mode 100755 index 00000000000..6014b608288 --- /dev/null +++ b/bssl-compat/patch/include/openssl/x509.h.sh @@ -0,0 +1,145 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --uncomment-regex 'DEFINE_STACK_OF(X509)' \ + --uncomment-func-decl X509_up_ref \ + --uncomment-func-decl X509_free \ + --uncomment-func-decl d2i_X509 \ + --uncomment-func-decl i2d_X509 \ + --uncomment-func-decl i2d_X509_NAME \ + --uncomment-macro-redef 'X509_VERSION_[123]' \ + --uncomment-func-decl X509_get0_notBefore \ + --uncomment-func-decl X509_get0_notAfter \ + --uncomment-func-decl X509_get_issuer_name \ + --uncomment-func-decl X509_get_subject_name \ + --uncomment-func-decl X509_get_X509_PUBKEY \ + --uncomment-func-decl X509_get_pubkey \ + --uncomment-func-decl X509_get_ext_by_OBJ \ + --uncomment-func-decl X509_get_ext \ + --uncomment-func-decl X509_new \ + --uncomment-func-decl X509_set_version \ + --uncomment-func-decl X509_getm_notBefore \ + --uncomment-func-decl X509_getm_notAfter \ + --uncomment-func-decl X509_set_pubkey \ + --uncomment-func-decl X509_sign \ + --uncomment-func-decl X509_alias_get0 \ + --uncomment-regex 'DEFINE_STACK_OF(X509_CRL)' \ + --uncomment-func-decl X509_CRL_up_ref \ + --uncomment-func-decl X509_CRL_free \ + --uncomment-regex 'DEFINE_STACK_OF(X509_NAME_ENTRY)' \ + --uncomment-regex 'DEFINE_STACK_OF(X509_NAME)' \ + --uncomment-func-decl X509_NAME_new \ + --uncomment-func-decl X509_NAME_free \ + --uncomment-func-decl X509_NAME_dup \ + --uncomment-func-decl X509_NAME_entry_count \ + --uncomment-func-decl X509_NAME_get_index_by_NID \ + --uncomment-func-decl X509_NAME_get_entry \ + --uncomment-func-decl X509_NAME_add_entry_by_txt \ + --uncomment-func-decl X509_NAME_ENTRY_set \ + --uncomment-func-decl X509_EXTENSION_get_data \ + --uncomment-func-decl X509_digest \ + --uncomment-func-decl X509_NAME_digest \ + --uncomment-func-decl X509_STORE_CTX_set_flags \ + --uncomment-func-decl X509_STORE_CTX_get_ex_data \ + --uncomment-func-decl X509_get_serialNumber \ + --uncomment-macro-redef 'XN_FLAG_[[:alnum:]_]*' \ + --uncomment-regex 'DEFINE_STACK_OF(X509_INFO)' \ + --uncomment-func-decl X509_get_pathlen \ + --uncomment-func-decl X509_verify_cert_error_string \ + --uncomment-func-decl X509_verify \ + --uncomment-func-decl X509_PUBKEY_get \ + --uncomment-func-decl X509_INFO_free \ + --uncomment-func-decl X509_cmp \ + --uncomment-func-decl X509_NAME_cmp \ + --uncomment-func-decl X509_CRL_cmp \ + --uncomment-func-decl X509_NAME_print_ex \ + --uncomment-func-decl X509_NAME_ENTRY_get_data \ + --uncomment-func-decl X509_get_ext_d2i \ + --uncomment-func-decl X509_add1_ext_i2d \ + --uncomment-func-decl X509_verify_cert \ + --uncomment-typedef X509_STORE_CTX_verify_cb \ + --uncomment-macro-redef 'X509_V_[[:alnum:]_]*' \ + --uncomment-func-decl X509_STORE_new \ + --uncomment-func-decl X509_STORE_free \ + --uncomment-func-decl X509_STORE_get0_param \ + --uncomment-func-decl X509_STORE_set_flags \ + --uncomment-func-decl X509_STORE_set_verify_cb \ + --uncomment-func-decl X509_STORE_load_locations \ + --uncomment-func-decl X509_STORE_up_ref \ + --uncomment-func-decl X509_STORE_CTX_new \ + --uncomment-func-decl X509_STORE_CTX_free \ + --uncomment-func-decl X509_STORE_CTX_init \ + --uncomment-func-decl X509_STORE_CTX_set0_trusted_stack \ + --uncomment-func-decl X509_STORE_add_cert \ + --uncomment-func-decl X509_STORE_add_crl \ + --uncomment-func-decl X509_STORE_CTX_get_current_cert \ + --uncomment-func-decl X509_STORE_CTX_get_error \ + --uncomment-func-decl X509_STORE_CTX_set_error \ + --uncomment-func-decl X509_STORE_CTX_get_error_depth \ + --uncomment-func-decl X509_STORE_CTX_get0_cert \ + --uncomment-func-decl X509_STORE_CTX_get0_untrusted \ + --uncomment-func-decl X509_STORE_CTX_set0_crls \ + --uncomment-func-decl X509_STORE_CTX_set_verify_cb \ + --uncomment-func-decl X509_STORE_CTX_get0_param \ + --uncomment-func-decl X509_STORE_CTX_set_default \ + --uncomment-func-decl X509_VERIFY_PARAM_set1 \ + --uncomment-func-decl X509_VERIFY_PARAM_set_flags \ + --uncomment-func-decl X509_VERIFY_PARAM_clear_flags \ + --uncomment-func-decl X509_VERIFY_PARAM_set_depth \ + --uncomment-func-decl X509_VERIFY_PARAM_set_time_posix \ + --uncomment-func-decl X509_NAME_ENTRY_get_object \ + --uncomment-func-decl X509_NAME_oneline \ + --uncomment-func-decl X509_CRL_get_issuer \ + --uncomment-func-decl X509_VERIFY_PARAM_get_flags \ + --uncomment-func-decl X509_STORE_CTX_get0_chain \ + --uncomment-func-decl X509_CRL_dup \ + --uncomment-func-decl X509_get_ext_count \ + --uncomment-func-decl X509_EXTENSION_get_object \ + --uncomment-func-decl X509_CRL_verify \ + --uncomment-func-decl X509_CRL_get0_by_cert \ + --uncomment-func-decl X509_CRL_get_ext \ + --uncomment-func-decl X509_get_ext_by_NID \ + --uncomment-func-decl X509_CRL_get_ext_by_NID \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(X509,' \ + --uncomment-regex 'BORINGSSL_MAKE_UP_REF(X509,' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(X509_CRL,' \ + --uncomment-regex 'BORINGSSL_MAKE_UP_REF(X509_CRL,' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(X509_INFO,' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(X509_NAME,' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(X509_STORE,' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(X509_STORE_CTX,' \ + --uncomment-macro-redef 'X509_R_[[:alnum:]_]*' \ + --uncomment-macro-redef 'GEN_[[:alnum:]_]*' \ + --uncomment-typedef GENERAL_NAMES \ + --uncomment-regex 'DEFINE_STACK_OF(GENERAL_NAME)' \ + --sed '/typedef struct GENERAL_SUBTREE_st {/itypedef struct ossl_GENERAL_SUBTREE_st GENERAL_SUBTREE;' \ + --uncomment-regex 'DEFINE_STACK_OF(GENERAL_SUBTREE)' \ + --uncomment-macro-redef 'EXFLAG_[[:alnum:]_]*' \ + --uncomment-func-decl GENERAL_NAME_set0_value \ + --uncomment-func-decl GENERAL_NAME_set0_othername \ + --uncomment-func-decl X509_get_extension_flags \ + --uncomment-func-decl X509_get_key_usage \ + --uncomment-func-decl GENERAL_NAME_free \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(BASIC_CONSTRAINTS, BASIC_CONSTRAINTS_free)' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(GENERAL_NAME, GENERAL_NAME_free)' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(GENERAL_SUBTREE, GENERAL_SUBTREE_free)' \ + --uncomment-regex 'BORINGSSL_MAKE_DELETER(NAME_CONSTRAINTS, NAME_CONSTRAINTS_free)' \ + --uncomment-macro-redef 'X509V3_ADD_[[:alnum:]_]*' \ + --uncomment-func-decl BASIC_CONSTRAINTS_free \ + --uncomment-func-decl NAME_CONSTRAINTS_free \ + --uncomment-func-decl GENERAL_SUBTREE_free \ + --uncomment-func-decl GENERAL_NAMES_new \ + --uncomment-func-decl GENERAL_NAMES_free \ + --uncomment-func-decl GENERAL_NAME_new \ + --uncomment-func-decl X509_set_issuer_name \ + --uncomment-func-decl X509_set_subject_name \ + --uncomment-func-decl BASIC_CONSTRAINTS_new \ + --uncomment-func-decl i2d_X509_PUBKEY \ + --uncomment-struct GENERAL_NAME_st \ + --uncomment-func-decl GENERAL_SUBTREE_new \ + --uncomment-regex-range 'typedef struct otherName_st.*' '.*OTHERNAME;' \ + --uncomment-regex-range 'typedef struct EDIPartyName_st.*' '.*EDIPARTYNAME;' \ + --uncomment-func-decl NAME_CONSTRAINTS_new \ + --uncomment-func-decl X509_PUBKEY_get0_param \ No newline at end of file diff --git a/bssl-compat/patch/include/openssl/x509v3.h.sh b/bssl-compat/patch/include/openssl/x509v3.h.sh new file mode 100755 index 00000000000..4a298d309b8 --- /dev/null +++ b/bssl-compat/patch/include/openssl/x509v3.h.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --sed '/openssl\/x509\.h/a#include ' \ + --uncomment-macro-redef 'KU_[[:alnum:]_]*' + # --uncomment-macro-redef 'X509V3_R_[[:alnum:]_]*' \ + diff --git a/bssl-compat/patch/ssl/ssl_c_test.c.sh b/bssl-compat/patch/ssl/ssl_c_test.c.sh new file mode 100755 index 00000000000..000e648fe3b --- /dev/null +++ b/bssl-compat/patch/ssl/ssl_c_test.c.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Do nothing here so the file just gets copied +# without commenting or uncommenting anything diff --git a/bssl-compat/patch/ssl/ssl_test.cc.patch b/bssl-compat/patch/ssl/ssl_test.cc.patch new file mode 100644 index 00000000000..9a1babb193a --- /dev/null +++ b/bssl-compat/patch/ssl/ssl_test.cc.patch @@ -0,0 +1,153 @@ +--- a/source/ssl/ssl_test.cc ++++ b/source/ssl/ssl_test.cc +@@ -23,7 +23,6 @@ + #include + #include + +-#include + #include + + #include +@@ -84,13 +83,19 @@ + static const size_t kTicketKeyLen = 48; + + static const VersionParam kAllVersions[] = { ++#ifndef BSSL_COMPAT // OpenSSL 3.0.x no longer supports TLS 1.0 or TLS1.1 + {TLS1_VERSION, VersionParam::is_tls, "TLS1"}, + {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"}, ++#endif + {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"}, + {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"}, ++#ifndef BSSL_COMPAT // OpenSSL 3.0.x no longer supports DTLS 1.0 + {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"}, ++#endif + {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"}, ++#ifdef DTLS1_3_EXPERIMENTAL_VERSION + {DTLS1_3_VERSION, VersionParam::is_dtls, "DTLS1_3"}, ++#endif // DTLS1_3_EXPERIMENTAL_VERSION + }; + + struct ExpectedCipher { +@@ -984,6 +989,7 @@ + int auth_nid; + int prf_nid; + } kTests[] = { ++#ifdef SSL3_CK_RSA_DES_192_CBC3_SHA + { + SSL3_CK_RSA_DES_192_CBC3_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", +@@ -993,6 +999,7 @@ + NID_auth_rsa, + NID_md5_sha1, + }, ++#endif + { + TLS1_CK_RSA_WITH_AES_128_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA", +@@ -1540,7 +1547,11 @@ + if (client_err != SSL_ERROR_NONE && // + client_err != SSL_ERROR_WANT_READ && // + client_err != SSL_ERROR_WANT_WRITE && // ++#ifdef SSL_ERROR_PENDING_TICKET + client_err != SSL_ERROR_PENDING_TICKET) { ++#else ++ true) { ++#endif + fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err)); + return false; + } +@@ -1550,7 +1561,11 @@ + if (server_err != SSL_ERROR_NONE && // + server_err != SSL_ERROR_WANT_READ && // + server_err != SSL_ERROR_WANT_WRITE && // ++#ifdef SSL_ERROR_PENDING_TICKET + server_err != SSL_ERROR_PENDING_TICKET) { ++#else ++ true) { ++#endif + fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err)); + return false; + } +@@ -1639,7 +1654,12 @@ + return false; + } + if (config.early_data) { ++#ifndef BSSL_COMPAT + SSL_set_early_data_enabled(client.get(), 1); ++#else ++ std::cout << "WARNING: Skipped SSL_set_early_data_enabled()" << std::endl; ++ return false; ++#endif + } + if (config.session) { + SSL_set_session(client.get(), config.session); +@@ -1649,18 +1669,29 @@ + return false; + } + if (!config.verify_hostname.empty()) { ++#ifndef BSSL_COMPAT + if (!SSL_set1_host(client.get(), config.verify_hostname.c_str())) { + return false; + } + SSL_set_hostflags(client.get(), config.hostflags); ++#else ++ std::cout << "WARNING: Skipped SSL_set1_host() & SSL_set_hostflags()" << std::endl; ++ return false; ++#endif + } + + if (config.ca_names) { + SSL_set0_CA_names(client.get(), config.ca_names); + } + ++#ifndef BSSL_COMPAT + SSL_set_shed_handshake_config(client.get(), shed_handshake_config); + SSL_set_shed_handshake_config(server.get(), shed_handshake_config); ++#else ++ if(shed_handshake_config) { ++ std::cout << "WARNING: Skipped SSL_set_shed_handshake_config()" << std::endl; ++ } ++#endif + + if (!CompleteHandshakes(client.get(), server.get())) { + return false; +@@ -3518,12 +3549,15 @@ + // However, for historical reasons, the X509 chain includes the leaf on the + // client, but does not on the server. + EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u); ++#ifndef BSSL_COMPAT // Envoy doesn't need SSL_get0_peer_certificates() so skip this + EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())), + 1u); +- ++#endif + EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u); ++#ifndef BSSL_COMPAT // Envoy doesn't need SSL_get0_peer_certificates() so skip this + EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())), + 1u); ++#endif + } + + TEST_P(SSLVersionTest, NoPeerCertificate) { +@@ -3536,7 +3570,9 @@ + // Server should not see a peer certificate. + bssl::UniquePtr peer(SSL_get_peer_certificate(server_.get())); + ASSERT_FALSE(peer); ++#ifndef BSSL_COMPAT // Envoy doesn't need SSL_get0_peer_certificates() so skip this + ASSERT_FALSE(SSL_get0_peer_certificates(server_.get())); ++#endif + } + + TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) { +@@ -4228,7 +4264,11 @@ + ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(), + server_ctx_.get())); + // Before the handshake, |SSL_version| reports some placeholder value. +- const uint16_t placeholder = is_dtls() ? DTLS1_2_VERSION : TLS1_2_VERSION; ++#ifdef BSSL_COMPAT // Default versions are different when running on OpenSSL ++ const uint16_t placeholder = is_dtls() ? DTLS1_2_VERSION : TLS1_3_VERSION; ++#else ++ const uint16_t placeholder = is_dtls() ? DTLS1_2_VERSION : TLS1_2_VERSION; ++#endif + EXPECT_EQ(SSL_version(client_.get()), placeholder); + EXPECT_EQ(SSL_version(server_.get()), placeholder); + diff --git a/bssl-compat/patch/ssl/ssl_test.cc.sh b/bssl-compat/patch/ssl/ssl_test.cc.sh new file mode 100755 index 00000000000..8c6aeff2137 --- /dev/null +++ b/bssl-compat/patch/ssl/ssl_test.cc.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --comment-regex '#include\s*".*internal\.h' \ + --uncomment-regex 'namespace\s*{\s*$' \ + --uncomment-macro TRACED_CALL \ + --uncomment-struct VersionParam \ + --uncomment-regex-range 'static\s*const\s*VersionParam\s*kAllVersions\[\]\s*=' '};' \ + --uncomment-regex 'template\s*' \ + --uncomment-class UnownedSSLExData \ + --uncomment-gtest-func SSLTest CipherProperties \ + --uncomment-static-func-impl CertFromPEM \ + --uncomment-static-func-impl KeyFromPEM \ + --uncomment-static-func-impl GetTestCertificate \ + --uncomment-static-func-impl GetTestKey \ + --uncomment-static-func-impl CompleteHandshakes \ + --uncomment-static-func-impl FlushNewSessionTickets \ + --uncomment-static-func-impl CreateClientAndServer \ + --uncomment-struct ClientConfig \ + --uncomment-static-func-impl ConnectClientAndServer \ + --uncomment-regex 'static\s*.*\bg_last_session;\s*$' \ + --uncomment-static-func-impl SaveLastSession \ + --uncomment-static-func-impl CreateClientSession \ + --uncomment-gtest-func SSLTest ClientCAList \ + --uncomment-class SSLVersionTest \ + --uncomment-regex-range 'INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest' '.*);' \ + --uncomment-gtest-func SSLVersionTest OneSidedShutdown \ + --uncomment-gtest-func SSLVersionTest WriteAfterShutdown \ + --uncomment-gtest-func SSLVersionTest WriteAfterReadSentFatalAlert \ + --uncomment-gtest-func SSLTest SetBIO \ + --uncomment-static-func-impl VerifySucceed \ + --uncomment-gtest-func SSLVersionTest GetPeerCertificate \ + --uncomment-gtest-func SSLVersionTest NoPeerCertificate \ + --uncomment-static-func-impl ExpectSessionReused \ + --uncomment-static-func-impl SwitchSessionIDContextSNI \ + --uncomment-gtest-func-skip SSLVersionTest SessionIDContext \ + --uncomment-static-func-impl GetVersionName \ + --uncomment-gtest-func SSLVersionTest Version \ + --uncomment-gtest-func SSLVersionTest GetServerName \ + --uncomment-gtest-func SSLTest GetCertificate \ + --uncomment-gtest-func SSLTest NoCiphersAvailable \ + --uncomment-gtest-func SSLTest GetCertificateThreads \ + --uncomment-regex 'int BORINGSSL_enum_c_type_test' '}' \ + --uncomment-gtest-func SSLTest EnumTypes \ + --uncomment-gtest-func-skip SSLVersionTest SameKeyResume \ + --uncomment-regex '}\s*//\s*namespace\s*$' \ No newline at end of file diff --git a/bssl-compat/patch/ssl/ssl_x509.cc.sh b/bssl-compat/patch/ssl/ssl_x509.cc.sh new file mode 100755 index 00000000000..bcc26de34bc --- /dev/null +++ b/bssl-compat/patch/ssl/ssl_x509.cc.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -euo pipefail + +uncomment.sh "$1" --comment -h \ + --comment-regex '^#include.*internal' \ + --uncomment-func-impl SSL_alert_from_verify_result diff --git a/bssl-compat/prefixer/BUILD b/bssl-compat/prefixer/BUILD new file mode 100644 index 00000000000..b8cd34612e7 --- /dev/null +++ b/bssl-compat/prefixer/BUILD @@ -0,0 +1,37 @@ +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") + +licenses(["notice"]) # Apache 2 + +# Create a cc_library with LLVM headers +cc_library( + name = "llvm_headers", + hdrs = ["@llvm_toolchain_llvm//:all_includes"], +) + +cc_binary( + name = "prefixer", + srcs = ["prefixer.cpp"], + additional_linker_inputs = [ + "@llvm_toolchain_llvm//:lib/libclang-cpp.so.18.1", + ], + copts = [ + "-fno-rtti", # Required by libclang-cpp + "-isystem external/llvm_toolchain_llvm/include", + # Use libstdc++ for ABI compatibility with libclang-cpp + "-stdlib=libstdc++", + # Add libstdc++ include path from sysroot + "-isystem external/sysroot_linux_amd64/usr/include/c++/13", + "-isystem external/sysroot_linux_amd64/usr/include/x86_64-linux-gnu/c++/13", + ], + linkopts = [ + # Directly link to the versioned shared library + "$(location @llvm_toolchain_llvm//:lib/libclang-cpp.so.18.1)", + "-Wl,-rpath,$$ORIGIN/../lib", + # Use libstdc++ for ABI compatibility with libclang-cpp + "-stdlib=libstdc++", + # Explicitly link libstdc++ runtime (needed since toolchain defaults to libc++) + "-lstdc++", + ], + visibility = ["//visibility:public"], + deps = [":llvm_headers"], +) diff --git a/bssl-compat/prefixer/prefixer.cpp b/bssl-compat/prefixer/prefixer.cpp new file mode 100644 index 00000000000..532cc26c7e2 --- /dev/null +++ b/bssl-compat/prefixer/prefixer.cpp @@ -0,0 +1,748 @@ +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendAction.h" +#include "clang/Tooling/Tooling.h" +#include "clang/Tooling/Execution.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Signals.h" +#include "llvm/ADT/Statistic.h" +#include +#include +#include +#include +#include +#include +#include + + +namespace opt { + static std::set srcpaths; + static std::set srcincl; + static std::set srcskip; + static std::set includes; + static std::filesystem::path output = std::filesystem::current_path(); + static std::string prefix = "ossl"; + static bool verbose = false; + + static std::vector extraIdentifiers = { + std::regex("^OPENSSL_.*", std::regex::basic | std::regex::optimize), + std::regex("^AES_.*", std::regex::basic | std::regex::optimize), + std::regex("^ASN1_.*", std::regex::basic | std::regex::optimize), + std::regex("^sk_$", std::regex::basic | std::regex::optimize), + std::regex("^d2i_", std::regex::basic | std::regex::optimize), + std::regex("^i2d_", std::regex::basic | std::regex::optimize), + std::regex("^DIRECTORYSTRING$", std::regex::basic | std::regex::optimize), + std::regex("^DISPLAYTEXT$", std::regex::basic | std::regex::optimize), + std::regex("^RSAPublicKey$", std::regex::basic | std::regex::optimize), + std::regex("^RSAPrivateKey$", std::regex::basic | std::regex::optimize), + std::regex("^DHparams$", std::regex::basic | std::regex::optimize), + std::regex("^PKCS7_ATTR_", std::regex::basic | std::regex::optimize), + std::regex("^PEM_read_", std::regex::basic | std::regex::optimize), + std::regex("^PEM_write_", std::regex::basic | std::regex::optimize), + std::regex("^PEM_", std::regex::basic | std::regex::optimize), + std::regex("^ossl_check_$", std::regex::basic | std::regex::optimize), + std::regex("^ossl_check_const_$", std::regex::basic | std::regex::optimize), + }; + + static std::map>>> extraInsertions = { + { + "openssl/asn1.h", { + { + "attr type *name##_dup(const type *a);", + { + "attr type *", + "##_##name##_dup(const type *a);" + } + }, + } + } + }; + + static std::map headers; // Relative to srcpath e.g. "openssl/x509.h" + + static llvm::raw_ostream &vstr() { return verbose ? llvm::outs() : llvm::nulls(); } + + static std::filesystem::path incdir() { return opt::output / "include"; } + static std::filesystem::path srcdir() { return opt::output / "source"; } + static std::filesystem::path hfile() { return opt::incdir() / (opt::prefix + ".h"); } + static std::filesystem::path cfile() { return opt::srcdir() / (opt::prefix + ".c"); } +}; + + + +static bool isAnonymousFunctionPointerType(const clang::QualType &qt) { + if (qt->isFunctionPointerType()) { + if (qt->getAs() == nullptr) { + return true; + } + } + return false; +} + +clang::SourceLocation getFileLoc(const clang::SourceManager &srcmgr, clang::SourceLocation sloc) { + if (sloc.isFileID()) { + return sloc; + } + + do { + if (srcmgr.isMacroArgExpansion(sloc)) { + sloc = srcmgr.getImmediateSpellingLoc(sloc); + } + else { + sloc = srcmgr.getImmediateExpansionRange(sloc).getBegin(); + } + } while (!sloc.isFileID()); + + return sloc; +} + + +class Function { + public: + + Function(clang::FunctionDecl *node) : m_node(node) { + } + + bool hasBody() const { + return m_node->doesThisDeclarationHaveABody(); + } + + std::string getHeader(const clang::SourceManager &srcmgr) const { + clang::SourceLocation sloc = getFileLoc(srcmgr, m_node->getLocation()); + const clang::OptionalFileEntryRef declfile = srcmgr.getFileEntryRefForID(srcmgr.getFileID(sloc)); + return declfile->getName().str(); + } + + std::string getName(bool prefixed) const { + return (prefixed ? (opt::prefix + "_") : "") + m_node->getName().str(); + } + + std::string getTypedefName() const { + return getName(false) + "_t"; + } + + std::string getReturnTypeTypedefName() const { + return getName(false) + "_ret_t"; + } + + std::string getReturnType() const { + clang::QualType rtype = m_node->getDeclaredReturnType(); + + if (isAnonymousFunctionPointerType(rtype)) { + return getReturnTypeTypedefName(); + } + else { + return fixTypeName(rtype.getAsString()); + } + } + + std::string getTypedef(clang::ASTContext &ctx) const { + std::ostringstream str; + clang::QualType rtype = m_node->getDeclaredReturnType(); + std::string rtypestr = rtype.getAsString(); + + if (isAnonymousFunctionPointerType(rtype)) { + std::string s; + llvm::raw_string_ostream sstr(s); + rtypestr = getReturnTypeTypedefName(); + ctx.buildImplicitTypedef(rtype, rtypestr)->print(sstr, ctx.getPrintingPolicy()); + sstr << ";\n"; + sstr.flush(); + str << s; + } + + str << "typedef " << getReturnType() << " (*" << getTypedefName() << ")" << getParameters(true, true); + + return str.str(); + } + + std::string getStructMember() const { + return getTypedefName() + " " + getName(false); + } + + std::string getParameters(bool types, bool names) const { + std::ostringstream str; + + str << "("; + for (int i = 0, max = m_node->getNumParams(); i < max; i++) { + std::string pstr; + if (names) { + clang::IdentifierInfo *ident = m_node->getParamDecl(i)->getIdentifier(); + if (ident == NULL) { + std::string name = "_p" + std::to_string(i); + ident = &m_node->getASTContext().Idents.getOwn(name); + m_node->getParamDecl(i)->setDeclName(clang::DeclarationName(ident)); + } + } + if(types && names) { + llvm::raw_string_ostream sstr(pstr); + m_node->getParamDecl(i)->print(sstr); + } + else if (types) { + pstr = m_node->getParamDecl(i)->getType().getAsString(); + } + else if (names) { + pstr = m_node->getParamDecl(i)->getNameAsString(); + } + if (types) { + pstr = fixTypeName(pstr); + } + str << (i ? ", " : "") << pstr; + } + if (m_node->isVariadic()) { + str << ", ..."; + } + str << ")"; + + return str.str(); + } + + void writeImplementation(std::ostream &str) const { + if (!m_node->isVariadic()) { + str << getReturnType() << " " << getName(true) << getParameters(true, true) << " {" << std::endl; + str << " assert(" << opt::prefix << "." << getName(true) << ");" << std::endl; + str << " " << ((getReturnType() != "void") ? "return " : ""); + str << opt::prefix << "." << getName(true) << getParameters(false, true) << ";" << std::endl; + if(m_node->isNoReturn()) { + str << " exit(1);" << std::endl; + } + str << "}" << std::endl; + } + } + + private: + + std::string fixTypeName(std::string type) const { + static std::regex restackof("struct stack_st_([a-zA-Z0-9_]*)"); + static std::regex relhashof("struct lhash_st_([a-zA-Z0-9_]*)"); + + std::smatch smatch; + + if (std::regex_search(type, smatch, restackof)) { + type = smatch.prefix().str() + "STACK_OF(" + smatch[1].str() + ")" + smatch.suffix().str(); + } + else if (std::regex_search(type, smatch, relhashof)) { + type = smatch.prefix().str() + "LHASH_OF(" + smatch[1].str() + ")" + smatch.suffix().str(); + } + + return type; + } + + private: + + clang::FunctionDecl *m_node; +}; + + +class MyFrontendAction: public clang::ASTFrontendAction { + + public: + + std::unique_ptr CreateASTConsumer(clang::CompilerInstance &compiler, llvm::StringRef InFile) override; + + bool BeginSourceFileAction(clang::CompilerInstance &compiler) override; + void EndSourceFileAction() override; + + bool prefixable(const std::string &path) { + std::filesystem::path p = std::filesystem::proximate(path, opt::incdir() / opt::prefix); + return (opt::headers.find(p) != opt::headers.end()); + } + + bool prefixable(clang::SourceLocation sloc) { + const clang::SourceManager &srcmgr = getCompilerInstance().getSourceManager(); + clang::FileID fileid = srcmgr.getFileID(getFileLoc(srcmgr, sloc)); + if(const clang::OptionalFileEntryRef declfile = srcmgr.getFileEntryRefForID(fileid)) { + return prefixable (declfile->getName().str()); + } + + return false; + } + + void MacroDefined(clang::Preprocessor &pp, const clang::Token &token, const clang::MacroDirective *directive) { + if (prefixable(token.getLocation())) { + std::string name = pp.getSpelling(token); + m_identifiers.insert(name); + if (name == "OPENSSL_VERSION_MAJOR") { + const auto &token = directive->getMacroInfo()->getReplacementToken(0); + m_version_major = std::string(token.getLiteralData(), token.getLength()); + } + if (name == "OPENSSL_VERSION_MINOR") { + const auto &token = directive->getMacroInfo()->getReplacementToken(0); + m_version_minor = std::string(token.getLiteralData(), token.getLength()); + } + } + } + + void MacroUndefined(clang::Preprocessor &pp, const clang::Token &token, const clang::MacroDefinition &definition, const clang::MacroDirective *undef) { + if (prefixable(token.getLocation())) { + m_identifiers.insert(pp.getSpelling(token)); + } + } + + void MacroExpands(clang::Preprocessor &pp, const clang::Token &token, const clang::MacroDefinition &definition, clang::SourceRange srange, const clang::MacroArgs *args) { + if (prefixable(definition.getMacroInfo()->getDefinitionLoc())) { + m_identifiers.insert(pp.getSpelling(token)); + } + } + + bool VisitFunctionDecl(clang::FunctionDecl *node) { + if ((node->getName().size() > 0) && prefixable(node->getLocation())) { + m_identifiers.insert(node->getName().str()); + m_functions.push_back(node); + } + + return true; + } + + bool VisitRecordDecl(clang::RecordDecl *node) { + if ((node->getName().size() > 0) && prefixable(node->getLocation())) { + m_identifiers.insert(node->getName().str()); + } + return true; + } + + bool VisitTypedefDecl(clang::TypedefDecl *node) { + if (prefixable(node->getLocation())) { + m_identifiers.insert(node->getName().str()); + } + return true; + } + + bool VisitEnumDecl(clang::EnumDecl *node) { + if (prefixable(node->getLocation())) { + m_identifiers.insert(node->getName().str()); + } + return true; + } + + bool VisitEnumConstantDecl(clang::EnumConstantDecl *node) { + if (prefixable(node->getLocation())) { + m_identifiers.insert(node->getName().str()); + } + return true; + } + + private: + + std::set m_identifiers; // To be prefixed + std::vector m_functions; + std::string m_version_major; // Parsed from OPENSSL_VERSION_MAJOR macro + std::string m_version_minor; // Parsed from OPENSSL_VERSION_MINOR macro +}; + + +class MyASTConsumer: public clang::ASTConsumer, public clang::RecursiveASTVisitor { + public: + explicit MyASTConsumer(MyFrontendAction &frontend) : + m_frontend(frontend) { + } + + void HandleTranslationUnit(clang::ASTContext &context) { + TraverseDecl(context.getTranslationUnitDecl()); + } + + bool VisitFunctionDecl(clang::FunctionDecl *node) { + return m_frontend.VisitFunctionDecl(node); + } + + bool VisitRecordDecl(clang::RecordDecl *node) { + return m_frontend.VisitRecordDecl(node); + } + + bool VisitTypedefDecl(clang::TypedefDecl *node) { + return m_frontend.VisitTypedefDecl(node); + } + + bool VisitEnumDecl(clang::EnumDecl *node) { + return m_frontend.VisitEnumDecl(node); + } + + bool VisitEnumConstantDecl(clang::EnumConstantDecl *node) { + return m_frontend.VisitEnumConstantDecl(node); + } + + private: + + MyFrontendAction &m_frontend; +}; + + +class MyPPCallbacks: public clang::PPCallbacks { + public: + + explicit MyPPCallbacks(MyFrontendAction &frontend, clang::Preprocessor &preprocessor) : + m_frontend(frontend), + m_preprocessor(preprocessor) { + } + + void MacroDefined(const clang::Token &token, const clang::MacroDirective *directive) override { + m_frontend.MacroDefined(m_preprocessor, token, directive); + } + + void MacroUndefined(const clang::Token &token, const clang::MacroDefinition &definition, const clang::MacroDirective *undef) override { + m_frontend.MacroUndefined(m_preprocessor, token, definition, undef); + } + + void MacroExpands(const clang::Token &token, const clang::MacroDefinition &definition, clang::SourceRange srange, const clang::MacroArgs *args) override { + m_frontend.MacroExpands(m_preprocessor, token, definition, srange, args); + } + + private: + + MyFrontendAction &m_frontend; + clang::Preprocessor &m_preprocessor; +}; + + +class CompilationDatabase : public clang::tooling::CompilationDatabase +{ + public: + + std::vector getCompileCommands(llvm::StringRef file) const override { + std::vector cmdline = { + "dummy", + std::string("-I") + opt::incdir().string(), + }; + for (const auto &inc : opt::includes) { + cmdline.push_back(std::string("-I") + inc); + } + cmdline.push_back(file.str()); + return { clang::tooling::CompileCommand(".", file, cmdline, "") }; + } +}; + + + +std::unique_ptr MyFrontendAction::CreateASTConsumer(clang::CompilerInstance &compiler, llvm::StringRef InFile) { + return std::make_unique(*this); +} + +bool MyFrontendAction::BeginSourceFileAction(clang::CompilerInstance &compiler) { + auto &preprocessor = compiler.getPreprocessor(); + std::unique_ptr ppcallbacks(new MyPPCallbacks(*this, preprocessor)); + preprocessor.addPPCallbacks(std::move(ppcallbacks)); + return true; +} + +void MyFrontendAction::EndSourceFileAction() { + // Write a typedef and extern variable for each function pointer + { + std::filesystem::create_directories(opt::hfile().parent_path()); + std::ofstream hstr (opt::hfile()); // writes header file + const auto &srcmgr = getCompilerInstance().getSourceManager(); + + hstr << "//" << std::endl << "// THIS FILE IS GENERATED BY THE PREFIXER TOOL DO NOT EDIT" << std::endl << "//" << std::endl; + hstr << "#ifndef _" << opt::prefix << "_H_\n"; + hstr << "#define _" << opt::prefix << "_H_\n"; + std::map> funcmap; + + for(const auto &f : m_functions) { + std::filesystem::path header = f.getHeader(srcmgr); + header = header.lexically_relative(opt::incdir()); + if(funcmap.find(header) == funcmap.end()) { + hstr << "#include \"" << header.string() <<"\"" << std::endl; + } + funcmap[header].push_back(f); + } + hstr << std::endl; + + for(const auto &f : m_functions) { + if (!f.hasBody()) { + hstr << f.getTypedef(getCompilerInstance().getASTContext()) << ";" << std::endl; + } + m_identifiers.insert(f.getTypedefName()); // Ensure it gets prefixed + } + hstr << std::endl; + + hstr << "struct " << opt::prefix + "_functions {" << std::endl; + for (const auto &function : m_functions) { + if (!function.hasBody()) { + hstr << " " << function.getStructMember() << ";" << std::endl; + } + } + hstr << "};" << std::endl + << std::endl + << "extern struct " << opt::prefix << "_functions " << opt::prefix << ";" << std::endl + << std::endl + << "#endif" << std::endl; + } + + { + std::filesystem::create_directories(opt::cfile().parent_path()); + std::ofstream cstr (opt::cfile()); + + cstr << "//" << std::endl << "// THIS FILE IS GENERATED BY THE PREFIXER TOOL DO NOT EDIT" << std::endl << "//" << std::endl + << "#define _GNU_SOURCE" << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#include \"ossl_dlutil.h\"" << std::endl + << "#include \"" << opt::prefix << ".h\"" << std::endl + << std::endl + << "struct " << opt::prefix << "_functions " << opt::prefix << ";" << std::endl + << std::endl + << "static void " << opt::prefix << "_init(void) __attribute__ ((constructor));" << std::endl + << "static void " << opt::prefix << "_fini(void) __attribute__ ((destructor));" << std::endl + << std::endl + << "static void " << opt::prefix << "_init(void) {" << std::endl + << std::endl + << " ossl_dlopen(" << m_version_major << ", " << m_version_minor << ");" << std::endl; + + for(const auto &function : m_functions) { + if (!function.hasBody()) { + cstr << " " << opt::prefix << "." << function.getName(true) << " = (" << function.getTypedefName() << ")ossl_dlsym(\"" << function.getName(false) << "\");" << std::endl; + } + } + + cstr << std::endl + << " ossl.ossl_ERR_load_crypto_strings();" << std::endl + << " ossl.ossl_SSL_load_error_strings();" << std::endl + << "}" << std::endl + << std::endl + << "static void " << opt::prefix << "_fini(void) {" << std::endl + << " ossl_dlclose();" << std::endl + << "}" << std::endl + << std::endl; + + for(const auto &function : m_functions) { + if (!function.hasBody()) { + function.writeImplementation(cstr); + } + } + } + + auto files(opt::headers); + files[opt::hfile()] = false; + files[opt::cfile()] = false; + std::regex regex("[a-zA-Z_][a-zA-Z0-9_]*", std::regex::basic | std::regex::optimize); + opt::vstr() << "Processing " << files.size() << " files...\n"; + for (auto [header, incl] : files) { + auto path = opt::incdir() / opt::prefix / header; + std::string buffer; + + opt::vstr() << " - " << path << "\n"; + + // Read the source header + { + std::ifstream ifstr(path); + std::stringstream isstr; + isstr << ifstr.rdbuf(); + buffer = isstr.str(); + } + + // Add the prefix to all identifiers in m_identifiers + { + std::ostringstream osstr; + std::smatch match; + std::string::const_iterator searchStart = buffer.cbegin(); + std::string suffix; + + while (std::regex_search(searchStart, buffer.cend(), match, regex)) { + bool matched = false; + const std::string &matchstr = match[0]; + + if ((matched = (m_identifiers.find(matchstr) != m_identifiers.end())) == false) { + for (std::regex pattern : opt::extraIdentifiers) { + if ((matched = (std::regex_search(matchstr, pattern)))) { + break; + } + } + } + osstr << match.prefix() << (matched ? (opt::prefix + "_") : "") << matchstr; + + searchStart = match.suffix().first; + suffix = match.suffix(); + } + osstr << suffix; + buffer = osstr.str(); + } + + // Do extra prefix insertions, listed in opt::extraInsertions + if (opt::extraInsertions.find(header) != opt::extraInsertions.end()) { + for (auto entry : opt::extraInsertions[header]) { + std::string search = entry.first; + std::string replace = entry.second.first + opt::prefix + entry.second.second; + + for(auto next = buffer.find(search); next != std::string::npos; next = buffer.find(search, next)) { + buffer.replace(next, search.length(), replace); + next += replace.length(); + } + } + } + + // Write the file back + { + std::ofstream ofstr(path); + ofstr << buffer; + } + } +} + + + + +static bool usage(int exitcode) { + std::cerr << std::endl + << "USAGE: prefixer [options]" << std::endl + << std::endl + << "OPTIONS:" << std::endl + << std::endl + << " --src-path Directory containing the openssl headers e.g. /usr/include" << std::endl + << " --src-incl Header files to be prefixed e.g. openssl/*.h" << std::endl + << " --src-skip Header files to be skipped e.g. openssl/asn1_mac.h" << std::endl + << " --include Directory to search for #includes" << std::endl + << " --prefix The prefix to be applied to functions, types & macros" << std::endl + << " --output Output directory for generated files" << std::endl + << " --verbose Print more info about what's being done" << std::endl + << std::endl + << "All files will be generated under the output directory as follows:" << std::endl + << std::endl + << " /" << std::endl + << " ├── source/" << std::endl + << " | └── .c" << std::endl + << " └── include/" << std::endl + << " └── .h" << std::endl + << " └── /" << std::endl + << " └── openssl/" << std::endl + << " ├── aes.h" << std::endl + << " ├── asn1.h" << std::endl + << " ├── ...." << std::endl + << " ├── x509v3.h" << std::endl + << " └── x509_vfy.h" << std::endl + << std::endl; + + if (exitcode) { + exit(exitcode); + } + + return true; +} + + +int main(int argc, const char **argv) { + + llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); + + for (int i = 1; i < argc; i++) { + std::string arg = argv[i]; + if ((arg == "--src-path") && ((++i < argc) || usage(-1))) { + opt::srcpaths.insert (std::filesystem::canonical(argv[i])); + } + else if ((arg == "--src-incl") && ((++i < argc) || usage(-1))) { + opt::srcincl.insert(argv[i]); + } + else if ((arg == "--src-skip") && ((++i < argc) || usage(-1))) { + opt::srcskip.insert(argv[i]); + } + else if ((arg == "--include") && ((++i < argc) || usage(-1))) { + opt::includes.insert(argv[i]); + } + else if ((arg == "--prefix") && ((++i < argc) || usage(-1))) { + opt::prefix = argv[i]; + } + else if ((arg == "--output") && ((++i < argc) || usage(-1))) { + opt::output = std::filesystem::absolute(argv[i]); + } + else if (arg == "--verbose") { + opt::verbose = true; + } + else if (arg == "--help") { + usage(0); + exit(0); + } + else { + llvm::errs() << "Unrecognised option : " << arg << "\n"; + exit(-1); + } + } + + // Build the list of header files to be processed + for (std::filesystem::path srcpath : opt::srcpaths) { + if (!std::filesystem::is_directory(srcpath)) { + llvm::errs() << "Source directory " << srcpath << " does not exist\n"; + return -1; + } + else { + opt::vstr() << "Finding source headers in " << srcpath << "\n"; + { + glob_t globbuf; + int globflags = GLOB_MARK; + for (auto i : opt::srcincl) { + auto pattern = srcpath / i; + glob(pattern.c_str(), globflags, 0, &globbuf); + globflags |= GLOB_APPEND; + } + for (size_t i = 0; i < globbuf.gl_pathc; i++) { + auto p = std::filesystem::path(globbuf.gl_pathv[i]).lexically_relative(srcpath); + opt::headers[p] = true; + } + globfree (&globbuf); + } + { + glob_t globbuf = { .gl_pathc = 0 }; + int globflags = GLOB_MARK; + for (auto i : opt::srcskip) { + auto pattern = srcpath / i; + glob(pattern.c_str(), globflags, 0, &globbuf); + globflags |= GLOB_APPEND; + } + for (size_t i = 0; i < globbuf.gl_pathc; i++) { + auto p = std::filesystem::path(globbuf.gl_pathv[i]).lexically_relative(srcpath); + opt::headers[p] = false; + } + globfree (&globbuf); + } + } + } + if (opt::verbose) { + for(auto [path, incl] : opt::headers) { + opt::vstr() << " " << incl << " " << path << "\n"; + } + } + + opt::vstr() << "Creating output directory " << opt::incdir() / opt::prefix << "\n"; + std::filesystem::create_directories (opt::incdir() / opt::prefix); + std::filesystem::path tmpfile = (opt::incdir() / opt::prefix).string() + ".c"; + { + std::ostringstream subts; + std::ostringstream files; + std::ofstream str (tmpfile); + for (auto [hdr, incl] : opt::headers) { + auto dsthdr = opt::incdir() / opt::prefix / hdr; + + std::filesystem::create_directories(dsthdr.parent_path()); + for (std::filesystem::path srcpath : opt::srcpaths) { + std::filesystem::path srchdr = srcpath / hdr; + if (std::filesystem::is_regular_file(srchdr)) { + if (std::filesystem::exists(dsthdr)) { + std::filesystem::remove(dsthdr); + } + std::filesystem::copy_file(srcpath / hdr, dsthdr); + std::filesystem::permissions(dsthdr, std::filesystem::perms::owner_write | + std::filesystem::perms::owner_read); + } + } + + subts << " -e 's!<" << hdr << ">!\"" << opt::prefix << "/" << hdr << "\"!g'"; + files << " " << opt::incdir() / opt::prefix << "/" << hdr; + + if (incl) { + str << "#include \"" << opt::prefix << "/" << hdr << "\"" << std::endl; + } + } + std::system((std::string("sed -i ") + subts.str() + files.str()).c_str()); + } + + clang::tooling::ClangTool tool(CompilationDatabase(), { tmpfile }); + int ret = tool.run(clang::tooling::newFrontendActionFactory().get()); + + std::filesystem::remove(tmpfile); + + return ret; +} + diff --git a/bssl-compat/source/ASN1_TIME_free.cc b/bssl-compat/source/ASN1_TIME_free.cc new file mode 100644 index 00000000000..99b27ae0e71 --- /dev/null +++ b/bssl-compat/source/ASN1_TIME_free.cc @@ -0,0 +1,7 @@ +#include +#include + + +void ASN1_TIME_free(ASN1_TIME *s) { + ossl.ossl_ASN1_TIME_free(s); +} diff --git a/bssl-compat/source/BASIC_CONSTRAINTS_free.cc b/bssl-compat/source/BASIC_CONSTRAINTS_free.cc new file mode 100644 index 00000000000..1412e199484 --- /dev/null +++ b/bssl-compat/source/BASIC_CONSTRAINTS_free.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/cd0b767492199a82c7e362d1a117e8c3fef6b943/include/openssl/x509v3.h#L464 + * https://www.openssl.org/docs/man3.0/man3/BASIC_CONSTRAINTS_free.html + */ +extern "C" void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a) { + ossl.ossl_BASIC_CONSTRAINTS_free(a); +} diff --git a/bssl-compat/source/BASIC_CONSTRAINTS_new.cc b/bssl-compat/source/BASIC_CONSTRAINTS_new.cc new file mode 100644 index 00000000000..003af6803a8 --- /dev/null +++ b/bssl-compat/source/BASIC_CONSTRAINTS_new.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/cd0b767492199a82c7e362d1a117e8c3fef6b943/include/openssl/x509v3.h#L464 + * https://www.openssl.org/docs/man3.0/man3/BASIC_CONSTRAINTS_new.html + */ +extern "C" BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new() { + return ossl.ossl_BASIC_CONSTRAINTS_new(); +} diff --git a/bssl-compat/source/BIO_free.cc b/bssl-compat/source/BIO_free.cc new file mode 100644 index 00000000000..4e5606bae6a --- /dev/null +++ b/bssl-compat/source/BIO_free.cc @@ -0,0 +1,14 @@ +#include +#include + + +/* + * OSSL: https://www.openssl.org/docs/man1.1.1/man3/BIO_free.html + * BSSL: https://github.com/google/boringssl/blob/cacb5526268191ab52e3a8b2d71f686115776646/src/include/openssl/bio.h#L86-L92 + */ +extern "C" int BIO_free(BIO *bio) { + // In BoringSSL, the BIO_free() call frees the whole chain, + // whereas in OpenSSL, it just frees the single bio. + ossl.ossl_BIO_free_all(bio); + return 1; +} diff --git a/bssl-compat/source/BIO_gets.c b/bssl-compat/source/BIO_gets.c new file mode 100644 index 00000000000..78f1cf4792c --- /dev/null +++ b/bssl-compat/source/BIO_gets.c @@ -0,0 +1,31 @@ +#include +#include + + +// I could not find any BoringSSL documentation for BIO_gets() behaviour when +// reading null characters. However, the BoringSSL unit tests for BIO_gets() +// explicitly check that it does not stop reading at null characters, but +// instead reads them the same as any other characters. + +// The OpenSSL documentation for BIO_gets() doesn't explicitly state how it +// deals with null characters. However, it does say "On binary input there may +// be NUL characters within the string; in this case the return value (if +// nonnegative) may give an incorrect length". + +// Looking at the OpenSSL code, and tracing through it, it appears that +// BIO_gets() on a memory bio reads null characters and returns the number of +// bytes read, the same as BoringSSL. However, on a file BIO, it also reads null +// characters, but returns the result of strlen() on the bytes that were read +// i.e. it doesn't return the number of bytes read, but instead returns the +// length only up to the first null character. + +// In order to provide exactly the same behaviour as BoringSSL, we use OpenSSL's +// BIO_get_line() function, which offers the same semantics as BoringSSL's and +// returns the correct number of bytes read, including null characters. + +int BIO_gets(BIO *bio, char *buf, int size) { + if (size <= 0) { + return 0; // Return 0 for size<=0 to match BoringSSL behavior + } + return ossl.ossl_BIO_get_line(bio, buf, size); +} diff --git a/bssl-compat/source/BIO_mem_contents.cc b/bssl-compat/source/BIO_mem_contents.cc new file mode 100644 index 00000000000..f52ef692cda --- /dev/null +++ b/bssl-compat/source/BIO_mem_contents.cc @@ -0,0 +1,20 @@ +#include +#include + + +/* + * OSSL: Doesn't exist + * BSSL: https://github.com/google/boringssl/blob/cacb5526268191ab52e3a8b2d71f686115776646/src/include/openssl/bio.h#L391 + */ +extern "C" int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents, size_t *out_len) { + auto len = ossl.ossl_BIO_get_mem_data(const_cast(bio), out_contents); + + if (len == 0) { // A 0 return means either error or empty + if (ossl.ossl_BIO_ctrl_pending(const_cast(bio)) != 0) { + return 0; // Not empty so must be error + } + } + + *out_len = len; + return 1; +} diff --git a/bssl-compat/source/BIO_meth_set_create.cc b/bssl-compat/source/BIO_meth_set_create.cc new file mode 100644 index 00000000000..ddb6a70024f --- /dev/null +++ b/bssl-compat/source/BIO_meth_set_create.cc @@ -0,0 +1,11 @@ +#include +#include + +/* + * Simple hand-crafted wrapper that our scripts were not able to generate + * because its signature contains a function pointer. + * TODO: extend generation scripts to support function pointers + */ +extern "C" int BIO_meth_set_create(BIO_METHOD *biom, int (*create)(BIO *)) { + return ossl.ossl_BIO_meth_set_create(biom, create); +} diff --git a/bssl-compat/source/BIO_meth_set_ctrl.cc b/bssl-compat/source/BIO_meth_set_ctrl.cc new file mode 100644 index 00000000000..df8a316c585 --- /dev/null +++ b/bssl-compat/source/BIO_meth_set_ctrl.cc @@ -0,0 +1,12 @@ +#include +#include + +/* + * Simple hand-crafted wrapper that our scripts were not able to generate + * because its signature contains a function pointer. + * TODO: extend generation scripts to support function pointers + */ +extern "C" int BIO_meth_set_ctrl(BIO_METHOD *biom, + long (*ctrl)(BIO *, int, long, void *)) { + return ossl.ossl_BIO_meth_set_ctrl(biom, ctrl); +} diff --git a/bssl-compat/source/BIO_meth_set_destroy.cc b/bssl-compat/source/BIO_meth_set_destroy.cc new file mode 100644 index 00000000000..e74ca97644d --- /dev/null +++ b/bssl-compat/source/BIO_meth_set_destroy.cc @@ -0,0 +1,11 @@ +#include +#include + +/* + * Simple hand-crafted wrapper that our scripts were not able to generate + * because its signature contains a function pointer. + * TODO: extend generation scripts to support function pointers + */ +extern "C" int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy)(BIO *)) { + return ossl.ossl_BIO_meth_set_destroy(biom, destroy); +} diff --git a/bssl-compat/source/BIO_meth_set_read.cc b/bssl-compat/source/BIO_meth_set_read.cc new file mode 100644 index 00000000000..a4106a03648 --- /dev/null +++ b/bssl-compat/source/BIO_meth_set_read.cc @@ -0,0 +1,11 @@ +#include +#include + +/* + * Simple hand-crafted wrapper that our scripts were not able to generate + * because its signature contains a function pointer. + * TODO: extend generation scripts to support function pointers + */ +extern "C" int BIO_meth_set_read(BIO_METHOD *biom, int (*read)(BIO *, char *, int)) { + return ossl.ossl_BIO_meth_set_read(biom, read); +} diff --git a/bssl-compat/source/BIO_meth_set_write.cc b/bssl-compat/source/BIO_meth_set_write.cc new file mode 100644 index 00000000000..42554ba6c2f --- /dev/null +++ b/bssl-compat/source/BIO_meth_set_write.cc @@ -0,0 +1,12 @@ +#include +#include + +/* + * Simple hand-crafted wrapper that our scripts were not able to generate + * because its signature contains a function pointer. + * TODO: extend generation scripts to support function pointers + */ +extern "C" int BIO_meth_set_write(BIO_METHOD *biom, + int (*write)(BIO *, const char *, int)) { + return ossl.ossl_BIO_meth_set_write(biom, write); +} diff --git a/bssl-compat/source/BIO_new_bio_pair.cc b/bssl-compat/source/BIO_new_bio_pair.cc new file mode 100644 index 00000000000..607b0fc79ce --- /dev/null +++ b/bssl-compat/source/BIO_new_bio_pair.cc @@ -0,0 +1,17 @@ +#include +#include + + +/* + * OSSL: https://github.com/openssl/openssl/blob/ac3cef223a4c61d6bee34527b6d4c8c6432494a7/include/openssl/bio.h#L721 + * OSSL: https://www.openssl.org/docs/man1.1.1/man3/BIO_new_bio_pair.html + * BSSL: https://github.com/google/boringssl/blob/cacb5526268191ab52e3a8b2d71f686115776646/src/include/openssl/bio.h#L616 + */ +extern "C" int BIO_new_bio_pair(BIO **out1, size_t writebuf1, BIO **out2, size_t writebuf2) { + int rc = ossl.ossl_BIO_new_bio_pair(out1, writebuf1, out2, writebuf2); + if (rc == 0) { + *out1 = nullptr; + *out2 = nullptr; + } + return rc; +} diff --git a/bssl-compat/source/BIO_pending.cc b/bssl-compat/source/BIO_pending.cc new file mode 100644 index 00000000000..ac849a4ba2c --- /dev/null +++ b/bssl-compat/source/BIO_pending.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" size_t BIO_pending(const BIO *bio) { + return ossl_BIO_pending(const_cast(bio)); +} diff --git a/bssl-compat/source/BIO_printf.cc b/bssl-compat/source/BIO_printf.cc new file mode 100644 index 00000000000..bc9f57ddf7e --- /dev/null +++ b/bssl-compat/source/BIO_printf.cc @@ -0,0 +1,11 @@ +#include +#include + + +extern "C" int BIO_printf(BIO *bio, const char *format, ...) { + va_list args; + va_start(args, format); + int ret = ossl.ossl_BIO_vprintf(bio, format, args); + va_end(args); + return ret; +} diff --git a/bssl-compat/source/BIO_read.cc b/bssl-compat/source/BIO_read.cc new file mode 100644 index 00000000000..de84556814e --- /dev/null +++ b/bssl-compat/source/BIO_read.cc @@ -0,0 +1,15 @@ +#include +#include + + +int BIO_read(BIO *bio, void *data, int len) { + int result = ossl.ossl_BIO_read(bio, data, len); + if (result == -1) { + unsigned long err = ossl.ossl_ERR_peek_last_error(); + if (ossl_ERR_GET_LIB(err) == ossl_ERR_LIB_BIO && + ossl_ERR_GET_REASON(err) == ossl_BIO_R_UNINITIALIZED) { + result = -2; + } + } + return result; +} diff --git a/bssl-compat/source/BIO_read_asn1.c b/bssl-compat/source/BIO_read_asn1.c new file mode 100644 index 00000000000..d39f1023e06 --- /dev/null +++ b/bssl-compat/source/BIO_read_asn1.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include "crypto/internal.h" + + +// bio_read_full reads |len| bytes |bio| and writes them into |out|. It +// tolerates partial reads from |bio| and returns one on success or zero if a +// read fails before |len| bytes are read. On failure, it additionally sets +// |*out_eof_on_first_read| to whether the error was due to |bio| returning zero +// on the first read. |out_eof_on_first_read| may be NULL to discard the value. +static int bio_read_full(BIO *bio, uint8_t *out, int *out_eof_on_first_read, + size_t len) { + int first_read = 1; + while (len > 0) { + int todo = len <= INT_MAX ? (int)len : INT_MAX; + int ret = BIO_read(bio, out, todo); + if (ret <= 0) { + if (out_eof_on_first_read != NULL) { + *out_eof_on_first_read = first_read && ret == 0; + } + return 0; + } + out += ret; + len -= (size_t)ret; + first_read = 0; + } + + return 1; +} + +// bio_read_all reads everything from |bio| and prepends |prefix| to it. On +// success, |*out| is set to an allocated buffer (which should be freed with +// |OPENSSL_free|), |*out_len| is set to its length and one is returned. The +// buffer will contain |prefix| followed by the contents of |bio|. On failure, +// zero is returned. +// +// The function will fail if the size of the output would equal or exceed +// |max_len|. +static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len, + const uint8_t *prefix, size_t prefix_len, + size_t max_len) { + static const size_t kChunkSize = 4096; + + size_t len = prefix_len + kChunkSize; + if (len > max_len) { + len = max_len; + } + if (len < prefix_len) { + return 0; + } + *out = OPENSSL_malloc(len); + if (*out == NULL) { + return 0; + } + OPENSSL_memcpy(*out, prefix, prefix_len); + size_t done = prefix_len; + + for (;;) { + if (done == len) { + OPENSSL_free(*out); + return 0; + } + const size_t todo = len - done; + assert(todo < INT_MAX); + const int n = BIO_read(bio, *out + done, todo); + if (n == 0) { + *out_len = done; + return 1; + } else if (n == -1) { + OPENSSL_free(*out); + return 0; + } + + done += n; + if (len < max_len && len - done < kChunkSize / 2) { + len += kChunkSize; + if (len < kChunkSize || len > max_len) { + len = max_len; + } + uint8_t *new_buf = OPENSSL_realloc(*out, len); + if (new_buf == NULL) { + OPENSSL_free(*out); + return 0; + } + *out = new_buf; + } + } +} + +// BIO_read_asn1 reads a single ASN.1 object from |bio|. If successful it sets +// |*out| to be an allocated buffer (that should be freed with |OPENSSL_free|), +// |*out_size| to the length, in bytes, of that buffer and returns one. +// Otherwise it returns zero. +// +// If the length of the object is greater than |max_len| or 2^32 then the +// function will fail. Long-form tags are not supported. If the length of the +// object is indefinite the full contents of |bio| are read, unless it would be +// greater than |max_len|, in which case the function fails. +// +// If the function fails then some unknown amount of data may have been read +// from |bio|. +int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) { + uint8_t header[6]; + + static const size_t kInitialHeaderLen = 2; + int eof_on_first_read; + if (!bio_read_full(bio, header, &eof_on_first_read, kInitialHeaderLen)) { + if (eof_on_first_read) { + // Historically, OpenSSL returned |ASN1_R_HEADER_TOO_LONG| when + // |d2i_*_bio| could not read anything. CPython conditions on this to + // determine if |bio| was empty. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG); + } else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + } + return 0; + } + + const uint8_t tag = header[0]; + const uint8_t length_byte = header[1]; + + if ((tag & 0x1f) == 0x1f) { + // Long form tags are not supported. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + size_t len, header_len; + if ((length_byte & 0x80) == 0) { + // Short form length. + len = length_byte; + header_len = kInitialHeaderLen; + } else { + const size_t num_bytes = length_byte & 0x7f; + + if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) { + // indefinite length. + if (!bio_read_all(bio, out, out_len, header, kInitialHeaderLen, + max_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + return 0; + } + return 1; + } + + if (num_bytes == 0 || num_bytes > 4) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + if (!bio_read_full(bio, header + kInitialHeaderLen, NULL, num_bytes)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + return 0; + } + header_len = kInitialHeaderLen + num_bytes; + + uint32_t len32 = 0; + for (unsigned i = 0; i < num_bytes; i++) { + len32 <<= 8; + len32 |= header[kInitialHeaderLen + i]; + } + + if (len32 < 128) { + // Length should have used short-form encoding. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + if ((len32 >> ((num_bytes-1)*8)) == 0) { + // Length should have been at least one byte shorter. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + len = len32; + } + + if (len + header_len < len || + len + header_len > max_len || + len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + return 0; + } + len += header_len; + *out_len = len; + + *out = OPENSSL_malloc(len); + if (*out == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_memcpy(*out, header, header_len); + if (!bio_read_full(bio, (*out) + header_len, NULL, len - header_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + OPENSSL_free(*out); + return 0; + } + + return 1; +} diff --git a/bssl-compat/source/BIO_snprintf.cc b/bssl-compat/source/BIO_snprintf.cc new file mode 100644 index 00000000000..aaccd96abb8 --- /dev/null +++ b/bssl-compat/source/BIO_snprintf.cc @@ -0,0 +1,11 @@ +#include +#include + + +extern "C" int BIO_snprintf(char *buf, size_t n, const char *format, ...) { + va_list args; + va_start(args, format); + int ret = ossl.ossl_BIO_vsnprintf(buf, n, format, args); + va_end(args); + return ret; +} diff --git a/bssl-compat/source/BIO_vfree.cc b/bssl-compat/source/BIO_vfree.cc new file mode 100644 index 00000000000..e3875f99ec2 --- /dev/null +++ b/bssl-compat/source/BIO_vfree.cc @@ -0,0 +1,12 @@ +#include +#include + + +/* + * OSSL: https://www.openssl.org/docs/man1.1.1/man3/BIO_vfree.html + * BSSL: https://github.com/google/boringssl/blob/cacb5526268191ab52e3a8b2d71f686115776646/src/include/openssl/bio.h#L98 + */ +extern "C" void BIO_vfree(BIO *bio) { + ossl.ossl_BIO_free(bio); +} + diff --git a/bssl-compat/source/BIO_wpending.c b/bssl-compat/source/BIO_wpending.c new file mode 100644 index 00000000000..8a32e940a12 --- /dev/null +++ b/bssl-compat/source/BIO_wpending.c @@ -0,0 +1,15 @@ +#include +#include +#include + + + +size_t BIO_wpending(const BIO *bio) { + const long r = BIO_ctrl((BIO *)bio, BIO_CTRL_WPENDING, 0, NULL); + assert(r >= 0); + + if (r < 0) { + return 0; + } + return r; +} diff --git a/bssl-compat/source/BIO_write.cc b/bssl-compat/source/BIO_write.cc new file mode 100644 index 00000000000..ce091b98492 --- /dev/null +++ b/bssl-compat/source/BIO_write.cc @@ -0,0 +1,15 @@ +#include +#include + + +int BIO_write(BIO *bio, const void *data, int len) { + int result = ossl.ossl_BIO_write(bio, data, len); + if (result == -1) { + unsigned long err = ossl.ossl_ERR_peek_last_error(); + if (ossl_ERR_GET_LIB(err) == ossl_ERR_LIB_BIO && + ossl_ERR_GET_REASON(err) == ossl_BIO_R_UNINITIALIZED) { + result = -2; + } + } + return result; +} diff --git a/bssl-compat/source/BN_bin2bn.cc b/bssl-compat/source/BN_bin2bn.cc new file mode 100644 index 00000000000..7c69a9f9e66 --- /dev/null +++ b/bssl-compat/source/BN_bin2bn.cc @@ -0,0 +1,12 @@ +#include +#include +#include + +extern "C" BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) { + + // OPENSSL_EXPORT BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret); + + + BIGNUM *n = ossl.ossl_BN_bin2bn(reinterpret_cast(in), static_cast(len), ret); + return n; +} diff --git a/bssl-compat/source/BN_bn2hex.cc b/bssl-compat/source/BN_bn2hex.cc new file mode 100644 index 00000000000..61debe90959 --- /dev/null +++ b/bssl-compat/source/BN_bn2hex.cc @@ -0,0 +1,24 @@ +#include +#include +#include + + +/* + * BSSL: https://github.com/google/boringssl/blob/cacb5526268191ab52e3a8b2d71f686115776646/src/include/openssl/bn.h#L267 + * OSSL: https://www.openssl.org/docs/man1.1.1/man3/BN_bn2hex.html + * + * While the BoringSSL description doesn't mention how to free the resulting string, + * looking at the source shows that it is allocated with OPENSSL_malloc(), so it + * should be freed with OPENSSL_free(), consistent with what OpenSSL says. + */ +extern "C" char *BN_bn2hex(const BIGNUM *bn) { + char *s = ossl.ossl_BN_bn2hex(bn); + + if (s) { + for(int i = 0; s[i]; i++) { + s[i] = tolower(s[i]); + } + } + + return s; +} diff --git a/bssl-compat/source/BN_cmp_word.cc b/bssl-compat/source/BN_cmp_word.cc new file mode 100644 index 00000000000..f5b891fcb80 --- /dev/null +++ b/bssl-compat/source/BN_cmp_word.cc @@ -0,0 +1,10 @@ +#include +#include + + +extern "C" int BN_cmp_word(const BIGNUM *a, BN_ULONG b) { + bssl::UniquePtr b_bn {BN_new()}; + ossl.ossl_BN_set_word(b_bn.get(), b); + + return ossl.ossl_BN_cmp(a, b_bn.get()); +} diff --git a/bssl-compat/source/CRYPTO_BUFFER.h b/bssl-compat/source/CRYPTO_BUFFER.h new file mode 100644 index 00000000000..46c7f3d409e --- /dev/null +++ b/bssl-compat/source/CRYPTO_BUFFER.h @@ -0,0 +1,13 @@ +#ifndef BSSL_COMPAT_CRYPTO_BUFFER_H +#define BSSL_COMPAT_CRYPTO_BUFFER_H + +/* + * This is a minimal/trivial implementation of CRYPTO_BUFFER + */ +struct crypto_buffer_st { + uint8_t *data; + size_t len; +}; + +#endif // BSSL_COMPAT_CRYPTO_BUFFER_H + diff --git a/bssl-compat/source/CRYPTO_BUFFER_free.c b/bssl-compat/source/CRYPTO_BUFFER_free.c new file mode 100644 index 00000000000..ca1a1f2c87b --- /dev/null +++ b/bssl-compat/source/CRYPTO_BUFFER_free.c @@ -0,0 +1,16 @@ +#include +#include +#include "CRYPTO_BUFFER.h" + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/pool.h#L74 + */ +void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf) { + if (buf == NULL) { + return; + } + + OPENSSL_free(buf->data); + OPENSSL_free(buf); +} diff --git a/bssl-compat/source/CRYPTO_BUFFER_new.c b/bssl-compat/source/CRYPTO_BUFFER_new.c new file mode 100644 index 00000000000..42b96249afb --- /dev/null +++ b/bssl-compat/source/CRYPTO_BUFFER_new.c @@ -0,0 +1,32 @@ +#include +#include +#include "crypto/internal.h" +#include "CRYPTO_BUFFER.h" +#include "log.h" + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/pool.h#L48 + */ +CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, CRYPTO_BUFFER_POOL *pool) { + if(pool) { + bssl_compat_fatal("%s() with non-null pool not implemented", __func__); + } + + CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER)); + if(buf == NULL) { + return NULL; + } + + OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER)); + + buf->data = OPENSSL_memdup(data, len); + if(len != 0 && buf->data == NULL) { + OPENSSL_free(buf); + return NULL; + } + + buf->len = len; + + return buf; +} diff --git a/bssl-compat/source/ECDSA_do_verify.cc b/bssl-compat/source/ECDSA_do_verify.cc new file mode 100644 index 00000000000..03be0c7b694 --- /dev/null +++ b/bssl-compat/source/ECDSA_do_verify.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, const ECDSA_SIG *sig, const EC_KEY *key) { + return ossl.ossl_ECDSA_do_verify(digest, digest_len, sig, const_cast(key)); +} diff --git a/bssl-compat/source/ECDSA_sign.cc b/bssl-compat/source/ECDSA_sign.cc new file mode 100644 index 00000000000..86c8bbe0b15 --- /dev/null +++ b/bssl-compat/source/ECDSA_sign.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/cfafcd454fd01ebc40f1a7f43537dd306b7b64c3/include/openssl/ecdsa.h#L79 + * https://www.openssl.org/docs/man3.0/man3/ECDSA_sign.html + */ +extern "C" int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, const EC_KEY *key) { + return ossl.ossl_ECDSA_sign(type, digest, digest_len, sig, sig_len, const_cast(key)); +} diff --git a/bssl-compat/source/ECDSA_verify.cc b/bssl-compat/source/ECDSA_verify.cc new file mode 100644 index 00000000000..31a267d3ffb --- /dev/null +++ b/bssl-compat/source/ECDSA_verify.cc @@ -0,0 +1,7 @@ +#include +#include + +extern "C" int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) { + return ossl.ossl_ECDSA_verify(type, digest, digest_len, sig, sig_len, (EC_KEY *)eckey); +} diff --git a/bssl-compat/source/EC_KEY_check_fips.cc b/bssl-compat/source/EC_KEY_check_fips.cc new file mode 100644 index 00000000000..51301e6057f --- /dev/null +++ b/bssl-compat/source/EC_KEY_check_fips.cc @@ -0,0 +1,8 @@ +#include +#include "log.h" + + +extern "C" int EC_KEY_check_fips(const EC_KEY *key) { + bssl_compat_fatal("%s() NYI", __func__); + return 0; +} diff --git a/bssl-compat/source/EC_KEY_parse_private_key.cc b/bssl-compat/source/EC_KEY_parse_private_key.cc new file mode 100644 index 00000000000..552dbcaee24 --- /dev/null +++ b/bssl-compat/source/EC_KEY_parse_private_key.cc @@ -0,0 +1,30 @@ +#include +#include +#include +#include "log.h" + + +/* + * https://github.com/google/boringssl/blob/8bbefbfeee609b17622deedd100163c12f5c95dc/include/openssl/ec_key.h#L225 + * https://www.openssl.org/docs/man3.0/man3/d2i_ECPrivateKey.html + */ +extern "C" EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { + if (group != nullptr) { + bssl_compat_fatal("%s() with non-null group not implemented", __func__); + } + + auto data1 {CBS_data(cbs)}; // save so we can work out the skip + auto data2 {data1}; // gets advanced by d2i_ECPrivateKey() + auto length {CBS_len(cbs)}; + + EC_KEY *key = ossl.ossl_d2i_ECPrivateKey(nullptr, &data2, length); + + if (key) { + if (!CBS_skip(cbs, data2 - data1)) { + ossl.ossl_EC_KEY_free(key); + key = nullptr; + } + } + + return key; +} diff --git a/bssl-compat/source/EC_KEY_set_public_key_affine_coordinate.cc b/bssl-compat/source/EC_KEY_set_public_key_affine_coordinate.cc new file mode 100644 index 00000000000..42bb73b64c6 --- /dev/null +++ b/bssl-compat/source/EC_KEY_set_public_key_affine_coordinate.cc @@ -0,0 +1,15 @@ +#include +#include +#include +#include "log.h" + + +extern "C" int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, + const BIGNUM *x, + const BIGNUM *y) { + // NOTE: BoringSSL and OpenSSL as of version 3.0 have binary compatability sharing BIGNUM + // so no conversion need be performed apart from removing 'const'. + return ossl.ossl_EC_KEY_set_public_key_affine_coordinates(key, + const_cast(x), + const_cast(y)); +} diff --git a/bssl-compat/source/ED25519_verify.cc b/bssl-compat/source/ED25519_verify.cc new file mode 100644 index 00000000000..bad97993fc6 --- /dev/null +++ b/bssl-compat/source/ED25519_verify.cc @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +/* + * bssl: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/curve25519.h#L90 + * ossl: None + * + * https://wiki.openssl.org/index.php/EVP_Signing_and_Verifying + * https://datatracker.ietf.org/doc/html/rfc8032 + */ +extern "C" int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], + const uint8_t public_key[32]) { + + // https://www.openssl.org/docs/man3.0/man3/ECDSA_SIG_new.html + ossl_EVP_MD_CTX *ctx = ossl.ossl_EVP_MD_CTX_new(); + // The original openssl patch for jwt_verify_lib used length of absl::string_view. + // bssl::UniquePtr pkey(EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, castToUChar(key), key.length())); + // + // https://github.com/maistra/jwt_verify_lib/blob/d602507895f21fdc22325f0466861ff5eac73bb8/src/verify.cc#L205 + // The public key size for EdDSA Ed25519 is 256 bits, so it seems logical to default to 32 here + // + // https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_new_raw_public_key.html + + ossl_EVP_PKEY *pkey = ossl.ossl_EVP_PKEY_new_raw_public_key(ossl_EVP_PKEY_ED25519, + NULL, reinterpret_cast(public_key), + 32); + int res = ossl.ossl_EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey); + + if (res == 1) { + // for ED25519 signature length are 64 bytes + // https://www.openssl.org/docs/man3.0/man3/EVP_DigestVerify.html + res = ossl.ossl_EVP_DigestVerify(ctx, reinterpret_cast(signature), + 64, + reinterpret_cast(message), + message_len); + } + + return res; +} \ No newline at end of file diff --git a/bssl-compat/source/EVP_DecodeBase64.c b/bssl-compat/source/EVP_DecodeBase64.c new file mode 100644 index 00000000000..96d633fa67b --- /dev/null +++ b/bssl-compat/source/EVP_DecodeBase64.c @@ -0,0 +1,22 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/base64.h#L103 + */ +int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out, const uint8_t *in, size_t in_len) { + size_t decoded_len; + + if(EVP_DecodedLength(&decoded_len, in_len)) { + if(decoded_len <= max_out) { + decoded_len = ossl.ossl_EVP_DecodeBlock(out, in, in_len); + if(decoded_len >= 0) { + *out_len = decoded_len; + return 1; + } + } + } + + return 0; +} \ No newline at end of file diff --git a/bssl-compat/source/EVP_DecodedLength.c b/bssl-compat/source/EVP_DecodedLength.c new file mode 100644 index 00000000000..c004312a975 --- /dev/null +++ b/bssl-compat/source/EVP_DecodedLength.c @@ -0,0 +1,15 @@ +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/base64.h#L97 + */ +int EVP_DecodedLength(size_t *out_len, size_t len) { + if (len % 4 != 0) { + return 0; + } + + *out_len = (len / 4) * 3; + + return 1; +} \ No newline at end of file diff --git a/bssl-compat/source/EVP_DigestSignFinal.cc b/bssl-compat/source/EVP_DigestSignFinal.cc new file mode 100644 index 00000000000..32bc1fd6dff --- /dev/null +++ b/bssl-compat/source/EVP_DigestSignFinal.cc @@ -0,0 +1,13 @@ +#include +#include + +extern "C" { + +// EVP_DigestSignFinal and EVP_DigestSignUdpate have identical arity and types and are auto-mapped + +OPENSSL_EXPORT int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len) { + return ossl.ossl_EVP_DigestSignFinal(ctx, reinterpret_cast(out_sig), out_sig_len); +} + +} diff --git a/bssl-compat/source/EVP_DigestVerifyFinal.cc b/bssl-compat/source/EVP_DigestVerifyFinal.cc new file mode 100644 index 00000000000..48e33307bcd --- /dev/null +++ b/bssl-compat/source/EVP_DigestVerifyFinal.cc @@ -0,0 +1,11 @@ +#include +#include + +/* + * bssl: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/evp.h#L373C27-L373C27 + * ossl: https://www.openssl.org/docs/man3.0/man3/EVP_DigestVerifyFinal.html + */ +extern "C" int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len) { + return ossl.ossl_EVP_DigestVerifyFinal(ctx, reinterpret_cast(sig), sig_len); +} \ No newline at end of file diff --git a/bssl-compat/source/EVP_MD_CTX_init.cc b/bssl-compat/source/EVP_MD_CTX_init.cc new file mode 100644 index 00000000000..50eba4c02b5 --- /dev/null +++ b/bssl-compat/source/EVP_MD_CTX_init.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { + ossl.ossl_EVP_MD_CTX_init(ctx); +} diff --git a/bssl-compat/source/EVP_MD_CTX_move.cc b/bssl-compat/source/EVP_MD_CTX_move.cc new file mode 100644 index 00000000000..6efd5851a33 --- /dev/null +++ b/bssl-compat/source/EVP_MD_CTX_move.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void EVP_MD_CTX_move(EVP_MD_CTX *out, EVP_MD_CTX *in) { + ossl.ossl_EVP_MD_CTX_copy_ex(out, in); +} diff --git a/bssl-compat/source/EVP_PKEY_get0_EC_KEY.cc b/bssl-compat/source/EVP_PKEY_get0_EC_KEY.cc new file mode 100644 index 00000000000..07e378e7543 --- /dev/null +++ b/bssl-compat/source/EVP_PKEY_get0_EC_KEY.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * BSSL: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/evp.h#L171 + * OSSL: https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_get0_EC_KEY.html + */ +extern "C" EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { + return (EC_KEY*)ossl.ossl_EVP_PKEY_get0_EC_KEY(pkey); +} diff --git a/bssl-compat/source/EVP_PKEY_get0_RSA.cc b/bssl-compat/source/EVP_PKEY_get0_RSA.cc new file mode 100644 index 00000000000..7ff6d5d7129 --- /dev/null +++ b/bssl-compat/source/EVP_PKEY_get0_RSA.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * BSSL: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/evp.h#L161 + * OSSL: https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_get0_RSA.html + */ +extern "C" RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { + return (RSA*)ossl.ossl_EVP_PKEY_get0_RSA(pkey); +} diff --git a/bssl-compat/source/EVP_PKEY_get1_EC_KEY.cc b/bssl-compat/source/EVP_PKEY_get1_EC_KEY.cc new file mode 100644 index 00000000000..cba06464e4a --- /dev/null +++ b/bssl-compat/source/EVP_PKEY_get1_EC_KEY.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * BSSL: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/evp.h#L172 + * OSSL: https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_get1_EC_KEY.html + */ +extern "C" EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey) { + return ossl.ossl_EVP_PKEY_get1_EC_KEY((EVP_PKEY*)pkey); +} diff --git a/bssl-compat/source/EVP_PKEY_get1_RSA.cc b/bssl-compat/source/EVP_PKEY_get1_RSA.cc new file mode 100644 index 00000000000..c5381fb601a --- /dev/null +++ b/bssl-compat/source/EVP_PKEY_get1_RSA.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * BSSL: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/evp.h#L162 + * OSSL: https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_get1_RSA.html + */ +extern "C" RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey) { + return ossl.ossl_EVP_PKEY_get1_RSA((EVP_PKEY*)pkey); +} diff --git a/bssl-compat/source/EVP_PKEY_id.cc b/bssl-compat/source/EVP_PKEY_id.cc new file mode 100644 index 00000000000..ce6d66336f1 --- /dev/null +++ b/bssl-compat/source/EVP_PKEY_id.cc @@ -0,0 +1,46 @@ +#include +#include +#include "log.h" + + +/* + * BSSL: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/evp.h#L135-L137 + * OSSL: https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_id.html + */ +extern "C" int EVP_PKEY_id(const EVP_PKEY *pkey) { + int ossl_id = ossl.ossl_EVP_PKEY_base_id(pkey); + switch(ossl_id) { + case ossl_EVP_PKEY_DSA: return EVP_PKEY_DSA; + case ossl_EVP_PKEY_EC: return EVP_PKEY_EC; + case ossl_EVP_PKEY_ED25519: return EVP_PKEY_ED25519; + case ossl_EVP_PKEY_HKDF: return EVP_PKEY_HKDF; + case ossl_EVP_PKEY_NONE: return EVP_PKEY_NONE; + case ossl_EVP_PKEY_RSA: return EVP_PKEY_RSA; + case ossl_EVP_PKEY_RSA_PSS: return EVP_PKEY_RSA_PSS; + case ossl_EVP_PKEY_X25519: return EVP_PKEY_X25519; + + case ossl_EVP_PKEY_RSA2: + case ossl_EVP_PKEY_DSA1: + case ossl_EVP_PKEY_DSA2: + case ossl_EVP_PKEY_DSA3: + case ossl_EVP_PKEY_DSA4: + case ossl_EVP_PKEY_DH: + case ossl_EVP_PKEY_DHX: + case ossl_EVP_PKEY_SM2: + case ossl_EVP_PKEY_HMAC: + case ossl_EVP_PKEY_CMAC: + case ossl_EVP_PKEY_SCRYPT: + case ossl_EVP_PKEY_TLS1_PRF: + case ossl_EVP_PKEY_POLY1305: + case ossl_EVP_PKEY_SIPHASH: + case ossl_EVP_PKEY_X448: + case ossl_EVP_PKEY_ED448: { + bssl_compat_error("Cannot convert ossl_EVP_PKEY_base_id() value %d", ossl_id); + return EVP_PKEY_NONE; + } + default: { + bssl_compat_error("Unknown ossl_EVP_PKEY_base_id() value %d", ossl_id); + return EVP_PKEY_NONE; + } + } +} diff --git a/bssl-compat/source/EVP_get_digestbyname.cc b/bssl-compat/source/EVP_get_digestbyname.cc new file mode 100644 index 00000000000..d2f5eb0110e --- /dev/null +++ b/bssl-compat/source/EVP_get_digestbyname.cc @@ -0,0 +1,13 @@ +#include +#include + +extern "C" { + +const EVP_MD *EVP_get_digestbyname(const char *name) { +#ifdef ossl_EVP_get_digestbyname + return ossl_EVP_get_digestbyname(name); +#else + return ossl.ossl_EVP_get_digestbyname(name); +#endif +} +} diff --git a/bssl-compat/source/EVP_parse_private_key.cc b/bssl-compat/source/EVP_parse_private_key.cc new file mode 100644 index 00000000000..73ae332b2b4 --- /dev/null +++ b/bssl-compat/source/EVP_parse_private_key.cc @@ -0,0 +1,13 @@ +#include +#include +#include + + +/* + * BSSL: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/evp.h#L218-L231 + * OSSL: N/A + */ +extern "C" EVP_PKEY *EVP_parse_private_key(CBS *cbs) { + const unsigned char* tmp = cbs->data; + return ossl.ossl_d2i_AutoPrivateKey_ex(NULL, &tmp, cbs->len, NULL, NULL); +} diff --git a/bssl-compat/source/EVP_parse_public_key.cc b/bssl-compat/source/EVP_parse_public_key.cc new file mode 100644 index 00000000000..24ea94b711c --- /dev/null +++ b/bssl-compat/source/EVP_parse_public_key.cc @@ -0,0 +1,13 @@ +#include +#include +#include + + +/* + * BSSL: https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/evp.h#L203-L211 + * OSSL: N/A + */ +extern "C" EVP_PKEY *EVP_parse_public_key(CBS *cbs) { + const unsigned char* tmp = cbs->data; + return ossl.ossl_d2i_PUBKEY_ex(NULL, &tmp, cbs->len, NULL, NULL); +} diff --git a/bssl-compat/source/FIPS_mode.cc b/bssl-compat/source/FIPS_mode.cc new file mode 100644 index 00000000000..093f28d87db --- /dev/null +++ b/bssl-compat/source/FIPS_mode.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" int FIPS_mode(void) { + return ossl.ossl_EVP_default_properties_is_fips_enabled(NULL); +} diff --git a/bssl-compat/source/GENERAL_NAMES_free.cc b/bssl-compat/source/GENERAL_NAMES_free.cc new file mode 100644 index 00000000000..586bfe04d06 --- /dev/null +++ b/bssl-compat/source/GENERAL_NAMES_free.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void GENERAL_NAMES_free(GENERAL_NAMES *a) { + ossl.ossl_GENERAL_NAMES_free(reinterpret_cast(a)); +} diff --git a/bssl-compat/source/GENERAL_NAMES_new.cc b/bssl-compat/source/GENERAL_NAMES_new.cc new file mode 100644 index 00000000000..d572c078293 --- /dev/null +++ b/bssl-compat/source/GENERAL_NAMES_new.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" GENERAL_NAMES * GENERAL_NAMES_new(void) { + return reinterpret_cast(ossl.ossl_GENERAL_NAMES_new()); +} diff --git a/bssl-compat/source/GENERAL_NAME_free.cc b/bssl-compat/source/GENERAL_NAME_free.cc new file mode 100644 index 00000000000..6aa72305609 --- /dev/null +++ b/bssl-compat/source/GENERAL_NAME_free.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void GENERAL_NAME_free(GENERAL_NAME *n) { + ossl.ossl_GENERAL_NAME_free(n); +} diff --git a/bssl-compat/source/GENERAL_NAME_new.cc b/bssl-compat/source/GENERAL_NAME_new.cc new file mode 100644 index 00000000000..e442334de87 --- /dev/null +++ b/bssl-compat/source/GENERAL_NAME_new.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" GENERAL_NAME * GENERAL_NAME_new(void) { + return ossl.ossl_GENERAL_NAME_new(); +} diff --git a/bssl-compat/source/GENERAL_SUBTREE_free.cc b/bssl-compat/source/GENERAL_SUBTREE_free.cc new file mode 100644 index 00000000000..6637b76d524 --- /dev/null +++ b/bssl-compat/source/GENERAL_SUBTREE_free.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void GENERAL_SUBTREE_free(GENERAL_SUBTREE *n) { + ossl.ossl_GENERAL_SUBTREE_free(n); +} diff --git a/bssl-compat/source/GENERAL_SUBTREE_new.cc b/bssl-compat/source/GENERAL_SUBTREE_new.cc new file mode 100644 index 00000000000..47985ae2507 --- /dev/null +++ b/bssl-compat/source/GENERAL_SUBTREE_new.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" GENERAL_SUBTREE * GENERAL_SUBTREE_new(void) { + return ossl.ossl_GENERAL_SUBTREE_new(); +} diff --git a/bssl-compat/source/HMAC_Init_ex.cc b/bssl-compat/source/HMAC_Init_ex.cc new file mode 100644 index 00000000000..87fe28afd12 --- /dev/null +++ b/bssl-compat/source/HMAC_Init_ex.cc @@ -0,0 +1,32 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/ec476ef0441f32fbcab558127412461617516336/include/openssl/hmac.h#L117 + * https://www.openssl.org/docs/man3.0/man3/HMAC_Init_ex.html + */ +extern "C" int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, const EVP_MD *md, ENGINE *impl) { + if (md == nullptr) { + // For a non-initial call, |md| may be NULL, in which + // case the previous hash function will be used. + md = ossl.ossl_HMAC_CTX_get_md(ctx); + if (md == nullptr) { + return 0; + } + } + + if (key == nullptr) { + // A null key can be interpreted as either a blank key, if this is an + // initial call, or alternatively as an indication to reuse the previous + // key, if this is a non-initial call. + if (ossl.ossl_HMAC_CTX_get_md(ctx) == nullptr) { + // OpenSSL doesn't like a null key in initial + // calls, so pass a blank instead. + key = ""; + key_len = 0; + } + } + + return ossl.ossl_HMAC_Init_ex(ctx, key, key_len, md, impl); +} diff --git a/bssl-compat/source/NAME_CONSTRAINTS_free.cc b/bssl-compat/source/NAME_CONSTRAINTS_free.cc new file mode 100644 index 00000000000..669982b9146 --- /dev/null +++ b/bssl-compat/source/NAME_CONSTRAINTS_free.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *n) { + ossl.ossl_NAME_CONSTRAINTS_free(n); +} diff --git a/bssl-compat/source/NAME_CONSTRAINTS_new.cc b/bssl-compat/source/NAME_CONSTRAINTS_new.cc new file mode 100644 index 00000000000..f03b2e16024 --- /dev/null +++ b/bssl-compat/source/NAME_CONSTRAINTS_new.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" NAME_CONSTRAINTS * NAME_CONSTRAINTS_new(void) { + return ossl.ossl_NAME_CONSTRAINTS_new(); +} diff --git a/bssl-compat/source/OPENSSL_sk_num.c b/bssl-compat/source/OPENSSL_sk_num.c new file mode 100644 index 00000000000..61dc8d5779b --- /dev/null +++ b/bssl-compat/source/OPENSSL_sk_num.c @@ -0,0 +1,10 @@ +#include +#include + + +size_t OPENSSL_sk_num(const OPENSSL_STACK *sk) { + if (sk == NULL) { + return 0; // OpenSSL returns -1, but BoringSSL returns 0 + } + return ossl.ossl_OPENSSL_sk_num(sk); +} diff --git a/bssl-compat/source/PEM_X509_INFO_read_bio.cc b/bssl-compat/source/PEM_X509_INFO_read_bio.cc new file mode 100644 index 00000000000..5e0d7176232 --- /dev/null +++ b/bssl-compat/source/PEM_X509_INFO_read_bio.cc @@ -0,0 +1,28 @@ +#include +#include +#include "log.h" + + +/* + * https://github.com/google/boringssl/blob/b9ec9dee569854ac3dee909b9dfe8c1909a6c751/include/openssl/pem.h#L350 + * https://www.openssl.org/docs/man3.0/man3/PEM_X509_INFO_read_bio.html + * + * Note that the BoringSSL and OpenSSL versions of PEM_X509_INFO_read_bio() have + * slightly different behaviour in the case where an error occurs *and* a non-null + * |sk| value was passed in. + */ +extern "C" STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u) { + STACK_OF(X509_INFO) *saved {sk}; + + auto ret {reinterpret_cast(ossl.ossl_PEM_X509_INFO_read_bio(bp, nullptr, cb, u))}; + + if ((ret != nullptr) && (saved != nullptr)) { + for (size_t i = 0, max = sk_X509_INFO_num(ret); i < max; i++) { + sk_X509_INFO_push(saved, sk_X509_INFO_value(ret, i)); + } + sk_X509_INFO_free(ret); + ret = saved; + } + + return ret; +} diff --git a/bssl-compat/source/PEM_read_bio_PUBKEY.cc b/bssl-compat/source/PEM_read_bio_PUBKEY.cc new file mode 100644 index 00000000000..8d2dd06e139 --- /dev/null +++ b/bssl-compat/source/PEM_read_bio_PUBKEY.cc @@ -0,0 +1,9 @@ +#include +#include +#include + +// BoringSSL function decl is described in pem.h as *PEM_read_bio_##name +extern "C" EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { + // OpenSSL function is in crypto/pem/pem_pkey.c for comparison + return ossl.ossl_PEM_read_bio_PUBKEY(bp, x, cb, u); +} diff --git a/bssl-compat/source/PEM_read_bio_PrivateKey.cc b/bssl-compat/source/PEM_read_bio_PrivateKey.cc new file mode 100644 index 00000000000..4fd4a17cb2d --- /dev/null +++ b/bssl-compat/source/PEM_read_bio_PrivateKey.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { + return ossl.ossl_PEM_read_bio_PrivateKey(bp, x, cb, u); +} \ No newline at end of file diff --git a/bssl-compat/source/PEM_read_bio_RSAPrivateKey.c b/bssl-compat/source/PEM_read_bio_RSAPrivateKey.c new file mode 100644 index 00000000000..2c8924be94a --- /dev/null +++ b/bssl-compat/source/PEM_read_bio_RSAPrivateKey.c @@ -0,0 +1,8 @@ +#include +#include + + +RSA *PEM_read_bio_RSAPrivateKey(BIO *out, RSA **x, pem_password_cb *cb, void *u) { + // FIXME: Reimplement with: https://www.openssl.org/docs/man3.0/man3/OSSL_DECODER_from_bio.html + return ossl.ossl_PEM_read_bio_RSAPrivateKey(out, x, cb, u); +} \ No newline at end of file diff --git a/bssl-compat/source/PEM_read_bio_X509.cc b/bssl-compat/source/PEM_read_bio_X509.cc new file mode 100644 index 00000000000..9df33d48ace --- /dev/null +++ b/bssl-compat/source/PEM_read_bio_X509.cc @@ -0,0 +1,8 @@ +#include +#include +#include + + +X509 *PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u) { + return ossl.ossl_PEM_read_bio_X509(bp, x, cb, u); +} diff --git a/bssl-compat/source/PEM_read_bio_X509_AUX.cc b/bssl-compat/source/PEM_read_bio_X509_AUX.cc new file mode 100644 index 00000000000..ba28e8cc1b1 --- /dev/null +++ b/bssl-compat/source/PEM_read_bio_X509_AUX.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" X509 *PEM_read_bio_X509_AUX(BIO *out, X509 **x, pem_password_cb *cb, void *u) { + return ossl.ossl_PEM_read_bio_X509_AUX(out, x, cb, u); +} diff --git a/bssl-compat/source/PEM_read_bio_X509_CRL.cc b/bssl-compat/source/PEM_read_bio_X509_CRL.cc new file mode 100644 index 00000000000..58f38f8b3d0 --- /dev/null +++ b/bssl-compat/source/PEM_read_bio_X509_CRL.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" X509_CRL *PEM_read_bio_X509_CRL(BIO *out, X509_CRL **x, pem_password_cb *cb, void *u) { + return ossl.ossl_PEM_read_bio_X509_CRL(out, x, cb, u); +} diff --git a/bssl-compat/source/PEM_write_bio_X509.cc b/bssl-compat/source/PEM_write_bio_X509.cc new file mode 100644 index 00000000000..3d54407ebed --- /dev/null +++ b/bssl-compat/source/PEM_write_bio_X509.cc @@ -0,0 +1,8 @@ +#include +#include +#include + + +extern "C" int PEM_write_bio_X509(BIO *bp, X509 *x) { + return ossl.ossl_PEM_write_bio_X509(bp, x); +} diff --git a/bssl-compat/source/PKCS12_get_key_and_certs.cc b/bssl-compat/source/PKCS12_get_key_and_certs.cc new file mode 100644 index 00000000000..c9b93f460e4 --- /dev/null +++ b/bssl-compat/source/PKCS12_get_key_and_certs.cc @@ -0,0 +1,34 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/225e8d39b50757af56e61cd0aa7958c56c487d54/include/openssl/pkcs8.h#L127 + * https://www.openssl.org/docs/man3.0/man3/PKCS12_get_key_and_certs.html + */ +extern "C" int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs, CBS *in, const char *password) { + bssl::UniquePtr bio {BIO_new_mem_buf(CBS_data(in), CBS_len(in))}; + if (!bio) { + return 0; + } + + bssl::UniquePtr p12 {d2i_PKCS12_bio(bio.get(), nullptr)}; + if (!p12) { + return 0; + } + + X509 *tmp_cert; + + if (!PKCS12_parse(p12.get(), password, out_key, &tmp_cert, &out_certs)) { + return 0; + } + + if (tmp_cert) { + if (sk_X509_push(out_certs, tmp_cert) == 0) { + X509_free(tmp_cert); + return 0; + } + } + + return 1; +} diff --git a/bssl-compat/source/PKCS12_parse.cc b/bssl-compat/source/PKCS12_parse.cc new file mode 100644 index 00000000000..978e73a37a8 --- /dev/null +++ b/bssl-compat/source/PKCS12_parse.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/225e8d39b50757af56e61cd0aa7958c56c487d54/include/openssl/pkcs8.h#L187 + * https://www.openssl.org/docs/man3.0/man3/PKCS12_parse.html + */ +extern "C" int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey, X509 **out_cert, STACK_OF(X509) **out_ca_certs) { + return ossl.ossl_PKCS12_parse(const_cast(p12), password, out_pkey, out_cert, reinterpret_cast(out_ca_certs)); +} diff --git a/bssl-compat/source/PKCS12_verify_mac.cc b/bssl-compat/source/PKCS12_verify_mac.cc new file mode 100644 index 00000000000..51185e4b028 --- /dev/null +++ b/bssl-compat/source/PKCS12_verify_mac.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/225e8d39b50757af56e61cd0aa7958c56c487d54/include/openssl/pkcs8.h#L199 + * https://www.openssl.org/docs/man3.0/man3/PKCS12_verify_mac.html + */ +extern "C" int PKCS12_verify_mac(const PKCS12 *p12, const char *password, int password_len) { + return ossl.ossl_PKCS12_verify_mac(const_cast(p12), password, password_len); +} diff --git a/bssl-compat/source/RAND_bytes.cc b/bssl-compat/source/RAND_bytes.cc new file mode 100644 index 00000000000..8005be573b4 --- /dev/null +++ b/bssl-compat/source/RAND_bytes.cc @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +extern "C" int RAND_bytes(uint8_t *buf, size_t len) { + + if (ossl.ossl_RAND_bytes((unsigned char *)buf, (int)len) <= 0) + return 0; + + return 1; +} diff --git a/bssl-compat/source/RAND_enable_fork_unsafe_buffering.c b/bssl-compat/source/RAND_enable_fork_unsafe_buffering.c new file mode 100644 index 00000000000..c209be37dee --- /dev/null +++ b/bssl-compat/source/RAND_enable_fork_unsafe_buffering.c @@ -0,0 +1,9 @@ +#include +#include + + +void RAND_enable_fork_unsafe_buffering(int fd) { + // Starting from version 1.1.1, OpenSSL uses a pthread_atfork() handler + // to always ensure that child processes always reseed their random number + // generation after forking. Therefore, this function can just be left completely empty. +} diff --git a/bssl-compat/source/RSA_check_fips.cc b/bssl-compat/source/RSA_check_fips.cc new file mode 100644 index 00000000000..65fe66d5768 --- /dev/null +++ b/bssl-compat/source/RSA_check_fips.cc @@ -0,0 +1,8 @@ +#include +#include "log.h" + + +extern "C" int RSA_check_fips(RSA *key) { + bssl_compat_fatal("%s() NYI", __func__); + return 0; +} diff --git a/bssl-compat/source/RSA_check_key.cc b/bssl-compat/source/RSA_check_key.cc new file mode 100644 index 00000000000..2739809cbf4 --- /dev/null +++ b/bssl-compat/source/RSA_check_key.cc @@ -0,0 +1,18 @@ +#include +#include + + +extern "C" int RSA_check_key(const RSA *key) { + + BIGNUM *p=NULL, *q=NULL, *d=NULL, *e=NULL, *n=NULL; + ossl.ossl_RSA_get0_key(key, (const BIGNUM **)&n, (const BIGNUM **)&e, (const BIGNUM **)&d); + ossl.ossl_RSA_get0_factors(key, (const BIGNUM **)&p, (const BIGNUM **)&q); + if((p == NULL || q == NULL || d == NULL) && + (n != NULL && e != NULL)) { + // Workaround for a mismatch with BoringSSL + // in case of Public Key + return 1; + } + + return ossl.ossl_RSA_check_key( key ); +} diff --git a/bssl-compat/source/RSA_decrypt.cc b/bssl-compat/source/RSA_decrypt.cc new file mode 100644 index 00000000000..d8e15c32030 --- /dev/null +++ b/bssl-compat/source/RSA_decrypt.cc @@ -0,0 +1,22 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/cd0b767492199a82c7e362d1a117e8c3fef6b943/include/openssl/rsa.h#L259 + * https://www.openssl.org/docs/man3.0/man3/RSA_private_decrypt.html + */ +extern "C" int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { + if (max_out < RSA_size(rsa)) { + return 0; // out buffer too small + } + + int ret = ossl.ossl_RSA_private_decrypt(in_len, in, out, rsa, padding); + if (ret == -1) { + return 0; + } + + *out_len = ret; + + return 1; +} diff --git a/bssl-compat/source/RSA_encrypt.cc b/bssl-compat/source/RSA_encrypt.cc new file mode 100644 index 00000000000..469e61cc5cf --- /dev/null +++ b/bssl-compat/source/RSA_encrypt.cc @@ -0,0 +1,26 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/cd0b767492199a82c7e362d1a117e8c3fef6b943/include/openssl/rsa.h#L240 + * https://www.openssl.org/docs/man3.0/man3/RSA_public_encrypt.html + */ +extern "C" int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { + if (max_out < RSA_size(rsa)) { + return 0; + } + + if (out_len == nullptr) { + return 0; + } + + int ret = ossl.ossl_RSA_public_encrypt(in_len, in, out, rsa, padding); + if (ret == -1) { + return 0; + } + + *out_len = ret; + + return 1; +} diff --git a/bssl-compat/source/RSA_generate_key_ex.cc b/bssl-compat/source/RSA_generate_key_ex.cc new file mode 100644 index 00000000000..ccb84605888 --- /dev/null +++ b/bssl-compat/source/RSA_generate_key_ex.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/cd0b767492199a82c7e362d1a117e8c3fef6b943/include/openssl/rsa.h#L194 + * https://www.openssl.org/docs/man3.0/man3/RSA_generate_key_ex.html + */ +extern "C" int RSA_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb) { + return ossl.ossl_RSA_generate_key_ex(rsa, bits, const_cast(e), cb); +} diff --git a/bssl-compat/source/RSA_private_key_from_bytes.cc b/bssl-compat/source/RSA_private_key_from_bytes.cc new file mode 100644 index 00000000000..26f0e6d7ae3 --- /dev/null +++ b/bssl-compat/source/RSA_private_key_from_bytes.cc @@ -0,0 +1,13 @@ +#include +#include +#include + + +/* + * https://github.com/google/boringssl/blob/cd0b767492199a82c7e362d1a117e8c3fef6b943/include/openssl/rsa.h#L557 + * https://www.openssl.org/docs/man3.0/man3/d2i_RSAPrivateKey_bio.html + */ +extern "C" RSA *RSA_private_key_from_bytes(const uint8_t *in, size_t in_len) { + bssl::UniquePtr bio {ossl.ossl_BIO_new_mem_buf(in, in_len)}; + return ossl.ossl_d2i_RSAPrivateKey_bio(bio.get(), nullptr); +} diff --git a/bssl-compat/source/RSA_public_key_from_bytes.cc b/bssl-compat/source/RSA_public_key_from_bytes.cc new file mode 100644 index 00000000000..94957d8eb26 --- /dev/null +++ b/bssl-compat/source/RSA_public_key_from_bytes.cc @@ -0,0 +1,13 @@ +#include +#include +#include + + +/* + * https://github.com/google/boringssl/blob/cd0b767492199a82c7e362d1a117e8c3fef6b943/include/openssl/rsa.h#L544 + * https://www.openssl.org/docs/man3.0/man3/RSA_public_key_from_bytes.html + */ +extern "C" RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len) { + bssl::UniquePtr bio {ossl.ossl_BIO_new_mem_buf(in, in_len)}; + return ossl.ossl_d2i_RSAPublicKey_bio(bio.get(), nullptr); +} diff --git a/bssl-compat/source/RSA_sign_pss_mgf1.cc b/bssl-compat/source/RSA_sign_pss_mgf1.cc new file mode 100644 index 00000000000..be5bfe5ed09 --- /dev/null +++ b/bssl-compat/source/RSA_sign_pss_mgf1.cc @@ -0,0 +1,11 @@ +#include +#include "log.h" + + +extern "C" int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *digest, + size_t digest_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len) { + bssl_compat_fatal("%s() NYI", __func__); + return 0; +} diff --git a/bssl-compat/source/SSL_CIPHER_get_kx_nid.cc b/bssl-compat/source/SSL_CIPHER_get_kx_nid.cc new file mode 100644 index 00000000000..837bb7984e8 --- /dev/null +++ b/bssl-compat/source/SSL_CIPHER_get_kx_nid.cc @@ -0,0 +1,19 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L1451 + * https://www.openssl.org/docs/man3.0/man3/SSL_CIPHER_get_kx_nid.html + */ +extern "C" int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher) { + int nid {ossl.ossl_SSL_CIPHER_get_kx_nid(cipher)}; + +#ifndef NID_kx_ecdhe_psk + if (nid == ossl_NID_kx_ecdhe_psk) { + return NID_kx_ecdhe; + } +#endif + + return nid; +} diff --git a/bssl-compat/source/SSL_CIPHER_get_min_version.cc b/bssl-compat/source/SSL_CIPHER_get_min_version.cc new file mode 100644 index 00000000000..45a73e08869 --- /dev/null +++ b/bssl-compat/source/SSL_CIPHER_get_min_version.cc @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + + +/* + * BoringSSL only returns: TLS1_3_VERSION, TLS1_2_VERSION, or SSL3_VERSION + */ +extern "C" uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) { + // This logic was copied from BoringSSL's ssl_cipher.cc + + if ((ossl.ossl_SSL_CIPHER_get_kx_nid(cipher) == ossl_NID_kx_any) || + (ossl.ossl_SSL_CIPHER_get_auth_nid(cipher) == ossl_NID_auth_any)) { + return TLS1_3_VERSION; + } + + const EVP_MD *digest = ossl.ossl_SSL_CIPHER_get_handshake_digest(cipher); + if ((digest == nullptr) || (ossl.ossl_EVP_MD_get_type(digest) != NID_md5_sha1)) { + return TLS1_2_VERSION; + } + + return SSL3_VERSION; +} diff --git a/bssl-compat/source/SSL_CIPHER_get_prf_nid.cc b/bssl-compat/source/SSL_CIPHER_get_prf_nid.cc new file mode 100644 index 00000000000..0bca760440b --- /dev/null +++ b/bssl-compat/source/SSL_CIPHER_get_prf_nid.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L1372 + * https://www.openssl.org/docs/man3.0/man3/SSL_CIPHER_get_handshake_digest.html + */ +extern "C" int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher) { + return ossl.ossl_EVP_MD_get_type(ossl.ossl_SSL_CIPHER_get_handshake_digest(cipher)); +} diff --git a/bssl-compat/source/SSL_CTX_get_ciphers.cc b/bssl-compat/source/SSL_CTX_get_ciphers.cc new file mode 100644 index 00000000000..29ccf26eb5e --- /dev/null +++ b/bssl-compat/source/SSL_CTX_get_ciphers.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) { + return (STACK_OF(SSL_CIPHER)*)ossl.ossl_SSL_CTX_get_ciphers(ctx); +} diff --git a/bssl-compat/source/SSL_CTX_get_client_CA_list.cc b/bssl-compat/source/SSL_CTX_get_client_CA_list.cc new file mode 100644 index 00000000000..5168eaf8c6e --- /dev/null +++ b/bssl-compat/source/SSL_CTX_get_client_CA_list.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L2706 + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_get_client_CA_list.html + */ +extern "C" STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) { + return reinterpret_cast(ossl.ossl_SSL_CTX_get_client_CA_list(ctx)); +} diff --git a/bssl-compat/source/SSL_CTX_get_ex_new_index.cc b/bssl-compat/source/SSL_CTX_get_ex_new_index.cc new file mode 100644 index 00000000000..36150ef6fdd --- /dev/null +++ b/bssl-compat/source/SSL_CTX_get_ex_new_index.cc @@ -0,0 +1,22 @@ +#include +#include + +extern "C" { +int SSL_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + + /** + * OpenSSL has the following macro definition + * #define SSL_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + * CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, l, p, newf, dupf, freef) + * + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_get_ex_new_index.html + */ + return ossl.ossl_CRYPTO_get_ex_new_index(ossl_CRYPTO_EX_INDEX_SSL_CTX,argl, argp, + reinterpret_cast(unused), + dup_unused, + free_func ); +} +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_CTX_get_max_proto_version.cc b/bssl-compat/source/SSL_CTX_get_max_proto_version.cc new file mode 100644 index 00000000000..eb101e3aa7d --- /dev/null +++ b/bssl-compat/source/SSL_CTX_get_max_proto_version.cc @@ -0,0 +1,8 @@ +#include +#include + + +extern "C" uint16_t SSL_CTX_get_max_proto_version(const SSL_CTX *ctx) { + return ossl.ossl_SSL_CTX_get_max_proto_version((SSL_CTX*)ctx); +} + diff --git a/bssl-compat/source/SSL_CTX_get_min_proto_version.cc b/bssl-compat/source/SSL_CTX_get_min_proto_version.cc new file mode 100644 index 00000000000..8ab28c6b05b --- /dev/null +++ b/bssl-compat/source/SSL_CTX_get_min_proto_version.cc @@ -0,0 +1,8 @@ +#include +#include + + +extern "C" uint16_t SSL_CTX_get_min_proto_version(const SSL_CTX *ctx) { + return ossl.ossl_SSL_CTX_get_min_proto_version((SSL_CTX*)ctx); +} + diff --git a/bssl-compat/source/SSL_CTX_get_session_cache_mode.cc b/bssl-compat/source/SSL_CTX_get_session_cache_mode.cc new file mode 100644 index 00000000000..88431fd9316 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_get_session_cache_mode.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) { + return ossl_SSL_CTX_get_session_cache_mode(const_cast(ctx)); +} diff --git a/bssl-compat/source/SSL_CTX_sess_set_new_cb.cc b/bssl-compat/source/SSL_CTX_sess_set_new_cb.cc new file mode 100644 index 00000000000..4815fb91445 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_sess_set_new_cb.cc @@ -0,0 +1,8 @@ +#include +#include + + +extern "C" void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session)) { + ossl.ossl_SSL_CTX_sess_set_new_cb(ctx, new_session_cb); +} + diff --git a/bssl-compat/source/SSL_CTX_set_alpn_select_cb.cc b/bssl-compat/source/SSL_CTX_set_alpn_select_cb.cc new file mode 100644 index 00000000000..987c230d37d --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_alpn_select_cb.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in, unsigned in_len, void *arg), void *arg) { + ossl.ossl_SSL_CTX_set_alpn_select_cb(ctx, cb, arg); +} diff --git a/bssl-compat/source/SSL_CTX_set_cert_verify_callback.cc b/bssl-compat/source/SSL_CTX_set_cert_verify_callback.cc new file mode 100644 index 00000000000..5356476a89f --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_cert_verify_callback.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg), void *arg) { + ossl.ossl_SSL_CTX_set_cert_verify_callback(ctx, callback, arg); +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_CTX_set_client_CA_list.cc b/bssl-compat/source/SSL_CTX_set_client_CA_list.cc new file mode 100644 index 00000000000..ea7beac7824 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_client_CA_list.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) { + ossl.ossl_SSL_CTX_set_client_CA_list(ctx, (ossl_STACK_OF(ossl_X509_NAME)*)name_list); +} diff --git a/bssl-compat/source/SSL_CTX_set_compliance_policy.cc b/bssl-compat/source/SSL_CTX_set_compliance_policy.cc new file mode 100644 index 00000000000..32e8def6fc8 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_compliance_policy.cc @@ -0,0 +1,75 @@ +#include +#include +#include "iana_2_ossl_names.h" + + +#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + + +namespace fips202205 { + +// (References are to SP 800-52r2): + +// Section 3.4.2.2 +// "at least one of the NIST-approved curves, P-256 (secp256r1) and P384 +// (secp384r1), shall be supported as described in RFC 8422." +// +// Section 3.3.1 +// "The server shall be configured to only use cipher suites that are +// composed entirely of NIST approved algorithms" +// NID_secp256r1 not available in OpenSSL +//static const int kGroups[] = {SSL_GROUP_SECP256R1, SSL_GROUP_SECP384R1}; +static const int kGroups[] = { NID_secp384r1}; + +static const char *kSigAlgs = { + "rsa_pkcs1_sha256" // SSL_SIGN_RSA_PKCS1_SHA256, + ":rsa_pkcs1_sha384" // SSL_SIGN_RSA_PKCS1_SHA384, + ":rsa_pkcs1_sha512" // SSL_SIGN_RSA_PKCS1_SHA512, + // Table 4.1: + // "The curve should be P-256 or P-384" + ":ecdsa_secp256r1_sha256" // SSL_SIGN_ECDSA_SECP256R1_SHA256, + ":ecdsa_secp384r1_sha384" // SSL_SIGN_ECDSA_SECP384R1_SHA384, + ":rsa_pss_rsae_sha256" // SSL_SIGN_RSA_PSS_RSAE_SHA256, + ":rsa_pss_rsae_sha384" // SSL_SIGN_RSA_PSS_RSAE_SHA384, + ":rsa_pss_rsae_sha512" // SSL_SIGN_RSA_PSS_RSAE_SHA512, +}; + +static const char kTLS12Ciphers[] = + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:" + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:" + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:" + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + +static int Configure(SSL_CTX *ctx) { + // tls13_cipher_policy field not present in OpenSSL + // ctx->tls13_cipher_policy = ssl_compliance_policy_fips_202205; + + return + // Section 3.1: + // "Servers that support government-only applications shall be + // configured to use TLS 1.2 and should be configured to use TLS 1.3 + // as well. These servers should not be configured to use TLS 1.1 and + // shall not use TLS 1.0, SSL 3.0, or SSL 2.0. + ossl.ossl_SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION) && + ossl.ossl_SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION) && + // Sections 3.3.1.1.1 and 3.3.1.1.2 are ambiguous about whether + // HMAC-SHA-1 cipher suites are permitted with TLS 1.2. However, later the + // Encrypt-then-MAC extension is required for all CBC cipher suites and so + // it's easier to drop them. + SSL_CTX_set_strict_cipher_list(ctx, kTLS12Ciphers) && + ossl.ossl_SSL_CTX_set1_groups (ctx, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && + ossl.ossl_SSL_CTX_set1_sigalgs_list(ctx, kSigAlgs); +} + +} // namespace fips202205 + + +int SSL_CTX_set_compliance_policy(SSL_CTX *ctx, + enum ssl_compliance_policy_t policy) { + switch (policy) { + case ssl_compliance_policy_fips_202205: + return fips202205::Configure(ctx); + default: + return 0; + } +} diff --git a/bssl-compat/source/SSL_CTX_set_custom_verify.cc b/bssl-compat/source/SSL_CTX_set_custom_verify.cc new file mode 100644 index 00000000000..3e738aac46c --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_custom_verify.cc @@ -0,0 +1,115 @@ +#include +#include +#include "log.h" +#include "override.h" + + +/* + * This function maps from TLS alert codes (SSL_AD_* constants) to X509 error + * codes (X509_V_ERR_* constants). + * + * Because the set of TLS alerts and X509 errors are not equal, this is not a + * lossless mapping. However, to achieve the best mapping, this function is + * written using some knowledge of OpenSSL's internals. Specifically, the + * "x509table" array (in ssl/statem/statem_lic.c) was used to derive the switch + * statement. + * + * Each TLS alert case returns a corresponding X509 error that OpenSSL will map + * back to the same TLS alert. If a TLS alert is not explicitly handled in the + * switch, it is because OpenSSL doesn't have a mapping from any X509 value to + * that TLS alert. In these cases, the default case will return + * X509_V_ERR_APPLICATION_VERIFICATION which OpenSSL will map to + * SSL_AD_HANDSHAKE_FAILURE + * + * https://github.com/openssl/openssl/blob/9cff14fd97814baf8a9a07d8447960a64d616ada/ssl/statem/statem_lib.c#L1351-L1395 + */ +static int tls_alert_to_x590_err(int alert) +{ + switch(alert) { + case SSL_AD_BAD_CERTIFICATE: + return X509_V_ERR_CERT_REJECTED; + case SSL_AD_CERTIFICATE_EXPIRED: + return X509_V_ERR_CERT_HAS_EXPIRED; + case SSL_AD_CERTIFICATE_REVOKED: + return X509_V_ERR_CERT_REVOKED; + case SSL_AD_CERTIFICATE_UNKNOWN: + return X509_V_ERR_INVALID_NON_CA; + case SSL_AD_DECRYPT_ERROR: + return X509_V_ERR_CERT_SIGNATURE_FAILURE; + case SSL_AD_HANDSHAKE_FAILURE: + return X509_V_ERR_APPLICATION_VERIFICATION; + case SSL_AD_INTERNAL_ERROR: + return X509_V_ERR_UNSPECIFIED; + case SSL_AD_UNKNOWN_CA: + return X509_V_ERR_INVALID_CA; + case SSL_AD_UNSUPPORTED_CERTIFICATE: + return X509_V_ERR_INVALID_PURPOSE; + default: + return X509_V_ERR_APPLICATION_VERIFICATION; + } +} + + + +/** + * This is the OpenSSL callback which invokes the BoringSSL callback. + * Return 1 to indicate verification success and 0 to indicate verification failure + */ +static int ossl_cert_verify_callback(X509_STORE_CTX *ctx, void *arg) { + int idx {ossl_SSL_get_ex_data_X509_STORE_CTX_idx()}; + SSL *ssl {static_cast(ossl_X509_STORE_CTX_get_ex_data(ctx, idx))}; + + // Get the SSL object from the X509_STORE_CTX + if (ssl == nullptr) { + bssl_compat_error("Failed to get SSL object from X509_STORE_CTX"); + return 0; + } + + // Get correctly typed ptr to the actual SSL_CTX_set_custom_verify() callback + auto callback {reinterpret_cast(arg)}; + if (callback == nullptr) { + bssl_compat_error("NULL BoringSSL callback"); + return 0; + } + + uint8_t alert {SSL_AD_INTERNAL_ERROR}; + enum ssl_verify_result_t verify_result; + { + // X509_STORE_CTX_get0_untrusted() retrieves an internal pointer to the stack of untrusted + // certificates associated with ctx, including the peer's leaf certificate at index 0. + // This is exactly what BoringSSL's SSL_get_peer_full_cert_chain() should return. However, + // on OpenSSL, there is no way (that I could find) of getting that cert chain from the SSL. + // Therefore, we use an OverrideResult to hold that cert chain, so that our implementation + // of SSL_get_peer_full_cert_chain() can pick it up and return it when called. + auto chain {reinterpret_cast(ossl_X509_STORE_CTX_get0_untrusted(ctx))}; + OverrideResult override {ssl, chain}; + verify_result = callback(ssl, &alert); + } + + switch (verify_result) { + case ssl_verify_ok: { + return 1; + } + case ssl_verify_invalid: { + // Translate the TLS alert value, received from the BoringSSL callback, to an X509 error, and + // set it on the X509_STORE_CTX. OpenSSL will ultimately translate the X509 error back into a + // TLS alert value which it will send to the peer. + ossl_X509_STORE_CTX_set_error(ctx, tls_alert_to_x590_err(alert)); + return 0; + } + case ssl_verify_retry: { + // TODO: Use ossl_SSL_set_retry_verify() for client side + // TODO: Use ossl_ASYNC_pause/start_job() for server side (or both sides) + bssl_compat_error("Async certificate validation not supported"); + ossl_X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CALL); + return 0; + } + } +} + +extern "C" void SSL_CTX_set_custom_verify(SSL_CTX *ctx, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) { + ossl_SSL_CTX_set_verify(ctx, mode, nullptr); + ossl_SSL_CTX_set_cert_verify_callback(ctx, ossl_cert_verify_callback, + reinterpret_cast(callback)); +} diff --git a/bssl-compat/source/SSL_CTX_set_keylog_callback.cc b/bssl-compat/source/SSL_CTX_set_keylog_callback.cc new file mode 100644 index 00000000000..75a50a3f835 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_keylog_callback.cc @@ -0,0 +1,10 @@ +#include +#include + +void SSL_CTX_set_keylog_callback( SSL_CTX *ctx, void (*cb)(const SSL *ssl, const char *line)) { +#ifdef ossl_SSL_CTX_set_keylog_callback + return ossl_SSL_CTX_set_keylog_callback(ctxa, cb); +#else + return ossl.ossl_SSL_CTX_set_keylog_callback(ctx, cb); +#endif +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_CTX_set_next_proto_select_cb.cc b/bssl-compat/source/SSL_CTX_set_next_proto_select_cb.cc new file mode 100644 index 00000000000..51d9bf7c8a4 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_next_proto_select_cb.cc @@ -0,0 +1,11 @@ +#include "openssl/ssl.h" +#include "ossl.h" + + +void SSL_CTX_set_next_proto_select_cb( SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, const uint8_t *in, unsigned in_len, void *arg), void *arg) { +#ifdef ossl_SSL_CTX_set_next_proto_select_cb + return ossl_SSL_CTX_set_next_proto_select_cb(ctx, cb, arg); +#else + return ossl.ossl_SSL_CTX_set_next_proto_select_cb(ctx, cb, arg); +#endif +} diff --git a/bssl-compat/source/SSL_CTX_set_next_protos_advertised_cb.cc b/bssl-compat/source/SSL_CTX_set_next_protos_advertised_cb.cc new file mode 100644 index 00000000000..4cbc8a11001 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_next_protos_advertised_cb.cc @@ -0,0 +1,12 @@ +#include "openssl/ssl.h" +#include "ossl.h" + +extern "C" { +void SSL_CTX_set_next_protos_advertised_cb( SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg), void *arg) { +#ifdef ossl_SSL_CTX_set_next_protos_advertised_cb + return ossl_SSL_CTX_set_next_protos_advertised_cb(ctx, cb, arg); +#else + return ossl.ossl_SSL_CTX_set_next_protos_advertised_cb(ctx, cb, arg); +#endif +} +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_CTX_set_private_key_method.cc b/bssl-compat/source/SSL_CTX_set_private_key_method.cc new file mode 100644 index 00000000000..87ee65d5d06 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_private_key_method.cc @@ -0,0 +1,7 @@ +#include +#include "log.h" + + +extern "C" void SSL_CTX_set_private_key_method(SSL_CTX *ctx, const SSL_PRIVATE_KEY_METHOD *key_method) { + bssl_compat_fatal("SSL_CTX_set_private_key_method() is not implemented"); +} diff --git a/bssl-compat/source/SSL_CTX_set_select_certificate_cb.cc b/bssl-compat/source/SSL_CTX_set_select_certificate_cb.cc new file mode 100644 index 00000000000..f3b7e1a87e4 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_select_certificate_cb.cc @@ -0,0 +1,127 @@ +#include +#include +#include "log.h" + + +/** + * This is the callback type for BoringSSL's SSL_CTX_set_select_certificate_cb() + */ +typedef enum ssl_select_cert_result_t (*select_certificate_cb_t)(const SSL_CLIENT_HELLO *); + + +/** + * We construct an instance of this class on the stack in a scope that surrounds + * the invocation of the user's callback. It is then possible to use the + * in_select_certificate_cb(ssl) function to query whether or not we are + * executing within a SSL_CTX_set_select_certificate_cb() callback for that SSL + * object, or not. + * + * This mechanism is used by the SSL_get_servername() function to provide a + * different implementation depending on it's invocation context. + */ +class ActiveSelectCertificateCb { + public: + ActiveSelectCertificateCb(SSL *ssl) : ssl_(ssl) { + SSL_set_ex_data(ssl_, index(), this); + } + ~ActiveSelectCertificateCb() { + SSL_set_ex_data(ssl_, index(), nullptr); + } + static int index() { + static int index = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, + +[](void *, void *ptr, CRYPTO_EX_DATA *, int, long, void*) { + if (ptr) ossl_OPENSSL_free(ptr); + }); + return index; + } + private: + SSL *ssl_; +}; + +/** + * Returns true if we are currently in a SSL_CTX_set_select_certificate_cb() + * callback invocation for the specified SSL object. + */ +bool in_select_certificate_cb(const SSL *ssl) { + return SSL_get_ex_data(ssl, ActiveSelectCertificateCb::index()) != nullptr; +} + + +/* + * This callback function is plugged into OpenSSL using + * ossl_SSL_CTX_set_client_hello_cb(). When it is invoked, we create an instance + * of BoringSSL's SSL_CLIENT_HELLO struct, and fill it in the best we can, and + * then invoke the caller's actual BoringSSL style callback function (arg), + * passing it the SSL_CLIENT_HELLO. + */ +static int ssl_ctx_client_hello_cb(SSL *ssl, int *alert, void *arg) { + select_certificate_cb_t callback {reinterpret_cast(arg)}; + + SSL_CLIENT_HELLO client_hello; + memset(&client_hello, 0, sizeof(client_hello)); + + client_hello.ssl = ssl; + client_hello.version = ossl.ossl_SSL_client_hello_get0_legacy_version(ssl); + client_hello.random_len = ossl.ossl_SSL_client_hello_get0_random(ssl, &client_hello.random); + client_hello.session_id_len = ossl.ossl_SSL_client_hello_get0_session_id(ssl, &client_hello.session_id); + client_hello.cipher_suites_len = ossl.ossl_SSL_client_hello_get0_ciphers(ssl, &client_hello.cipher_suites); + client_hello.compression_methods_len = ossl.ossl_SSL_client_hello_get0_compression_methods(ssl, &client_hello.compression_methods); + + int *extension_ids; + size_t extension_ids_len; + + if (!ossl.ossl_SSL_client_hello_get1_extensions_present(ssl, &extension_ids, &extension_ids_len)) { + *alert = SSL_AD_INTERNAL_ERROR; + return ossl_SSL_CLIENT_HELLO_ERROR; + } + + CBB extensions; + CBB_init(&extensions, 1024); + + for (size_t i = 0; i < extension_ids_len; i++) { + const unsigned char *extension_data; + size_t extension_len; + + if (!ossl.ossl_SSL_client_hello_get0_ext(ssl, extension_ids[i], &extension_data, &extension_len) || + !CBB_add_u16(&extensions, extension_ids[i]) || + !CBB_add_u16(&extensions, extension_len) || + !CBB_add_bytes(&extensions, extension_data, extension_len)) { + OPENSSL_free(extension_ids); + CBB_cleanup(&extensions); + *alert = SSL_AD_INTERNAL_ERROR; + return ossl_SSL_CLIENT_HELLO_ERROR; + } + } + + OPENSSL_free(extension_ids); + + if (!CBB_finish(&extensions, (uint8_t**)&client_hello.extensions, &client_hello.extensions_len)) { + CBB_cleanup(&extensions); + *alert = SSL_AD_INTERNAL_ERROR; + return ossl_SSL_CLIENT_HELLO_ERROR; + } + + enum ssl_select_cert_result_t result; + + { + ActiveSelectCertificateCb active(ssl); + result = callback(&client_hello); + } + + OPENSSL_free((void*)client_hello.extensions); + + switch (result) { + case ssl_select_cert_success: return ossl_SSL_CLIENT_HELLO_SUCCESS; + case ssl_select_cert_retry: return ossl_SSL_CLIENT_HELLO_RETRY; + case ssl_select_cert_error: return ossl_SSL_CLIENT_HELLO_ERROR; + case ssl_select_cert_disable_ech: { + // None of the Envoy code ever returns the new ssl_select_cert_disable_ech enumerator + bssl_compat_error("Unexpected ssl_select_cert_disable_ech result from callback"); + return ossl_SSL_CLIENT_HELLO_ERROR; + } + }; +} + +extern "C" void SSL_CTX_set_select_certificate_cb(SSL_CTX *ctx, select_certificate_cb_t cb) { + ossl_SSL_CTX_set_client_hello_cb(ctx, ssl_ctx_client_hello_cb, reinterpret_cast(cb)); +} diff --git a/bssl-compat/source/SSL_CTX_set_select_certificate_cb.h b/bssl-compat/source/SSL_CTX_set_select_certificate_cb.h new file mode 100644 index 00000000000..9706efecdc3 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_select_certificate_cb.h @@ -0,0 +1,13 @@ +#ifndef _SSL_CTX_SET_SELECT_CERTIFICATE_CB_H_ +#define _SSL_CTX_SET_SELECT_CERTIFICATE_CB_H_ + +#include + + +/* + * Returns true if called from within a SSL_CTX_set_select_certificate_cb() + * callback that is currently being invoked for the specified SSL object. + */ +bool in_select_certificate_cb(const SSL *ssl); + +#endif /*_SSL_CTX_SET_SELECT_CERTIFICATE_CB_H_*/ diff --git a/bssl-compat/source/SSL_CTX_set_strict_cipher_list.cc b/bssl-compat/source/SSL_CTX_set_strict_cipher_list.cc new file mode 100644 index 00000000000..c4ff311bcb1 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_strict_cipher_list.cc @@ -0,0 +1,48 @@ +#include +#include +#include "iana_2_ossl_names.h" + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L1508 + * + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_cipher_list.html + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_get_ciphers.html + * https://www.openssl.org/docs/man3.0/man3/SSL_CIPHER_get_name.html + */ +extern "C" int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str) { + std::string osslstr {iana_2_ossl_names(str)}; + + // OpenSSL's SSL_CTX_set_cipher_list() performs virtually no checking on str. + // It only returns 0 (fail) if no cipher could be selected from the list at + // all. Otherwise it returns 1 (pass) even if there is only one cipher in the + // string that makes sense, and the rest are unsupported or even just rubbish. + if (ossl.ossl_SSL_CTX_set_cipher_list(ctx, osslstr.c_str()) == 0) { + return 0; + } + + STACK_OF(SSL_CIPHER)* ciphers = reinterpret_cast(ossl.ossl_SSL_CTX_get_ciphers(ctx)); + char* dup = strdup(osslstr.c_str()); + char* token = strtok(dup, ":+![|]"); + while (token != NULL) { + std::string str1(token); + bool found = false; + for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i); + std::string str2(SSL_CIPHER_get_name(cipher)); + if (str1.compare(str2) == 0) { + found = true; + } + } + + if (!found && str1.compare("-ALL") && str1.compare("ALL")) { + free(dup); + return 0; + } + + token = strtok(NULL, ":[]|"); + } + + free(dup); + return 1; +} diff --git a/bssl-compat/source/SSL_CTX_set_tlsext_servername_callback.cc b/bssl-compat/source/SSL_CTX_set_tlsext_servername_callback.cc new file mode 100644 index 00000000000..d243aaf50ee --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_tlsext_servername_callback.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#LL2773C20-L2773C58 + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_tlsext_servername_callback.html + */ +extern "C" int SSL_CTX_set_tlsext_servername_callback(SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg)) { + return ossl.ossl_SSL_CTX_set_tlsext_servername_callback(ctx, callback); +} diff --git a/bssl-compat/source/SSL_CTX_set_tlsext_status_cb.c b/bssl-compat/source/SSL_CTX_set_tlsext_status_cb.c new file mode 100644 index 00000000000..d029cbefe0e --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_tlsext_status_cb.c @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L5079 + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_tlsext_status_cb.html + */ +int SSL_CTX_set_tlsext_status_cb(SSL_CTX *ctx, int (*callback)(SSL *ssl, void *arg)) { + return ossl.ossl_SSL_CTX_set_tlsext_status_cb(ctx, callback); +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_CTX_set_tlsext_ticket_key_cb.cc b/bssl-compat/source/SSL_CTX_set_tlsext_ticket_key_cb.cc new file mode 100644 index 00000000000..24b687b42d8 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_tlsext_ticket_key_cb.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L2216 + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_tlsext_ticket_key_cb.html + */ +extern "C" int SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, int encrypt)) { + return ossl.ossl_SSL_CTX_set_tlsext_ticket_key_cb(ctx, callback); +} diff --git a/bssl-compat/source/SSL_CTX_set_tlsext_ticket_keys.cc b/bssl-compat/source/SSL_CTX_set_tlsext_ticket_keys.cc new file mode 100644 index 00000000000..da266ffaad1 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_tlsext_ticket_keys.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, size_t len) { + return ossl.ossl_SSL_CTX_set_tlsext_ticket_keys(ctx, (void*)in, len); +} diff --git a/bssl-compat/source/SSL_CTX_set_verify.cc b/bssl-compat/source/SSL_CTX_set_verify.cc new file mode 100644 index 00000000000..54f39da6481 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_verify.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx)) { + ossl.ossl_SSL_CTX_set_verify(ctx, mode, callback); +} diff --git a/bssl-compat/source/SSL_CTX_set_verify_algorithm_prefs.cc b/bssl-compat/source/SSL_CTX_set_verify_algorithm_prefs.cc new file mode 100644 index 00000000000..372618d9d5a --- /dev/null +++ b/bssl-compat/source/SSL_CTX_set_verify_algorithm_prefs.cc @@ -0,0 +1,52 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L2639 + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set1_sigalgs.html + */ +extern "C" int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, size_t num_prefs) { + static const struct { // Copied from boringssl/ssl/ssl_privkey.cc + int pkey_type; + int hash_nid; + uint16_t signature_algorithm; + } kSignatureAlgorithmsMapping[] = { + {EVP_PKEY_RSA, NID_sha1, SSL_SIGN_RSA_PKCS1_SHA1}, + {EVP_PKEY_RSA, NID_sha256, SSL_SIGN_RSA_PKCS1_SHA256}, + {EVP_PKEY_RSA, NID_sha384, SSL_SIGN_RSA_PKCS1_SHA384}, + {EVP_PKEY_RSA, NID_sha512, SSL_SIGN_RSA_PKCS1_SHA512}, + {EVP_PKEY_RSA_PSS, NID_sha256, SSL_SIGN_RSA_PSS_RSAE_SHA256}, + {EVP_PKEY_RSA_PSS, NID_sha384, SSL_SIGN_RSA_PSS_RSAE_SHA384}, + {EVP_PKEY_RSA_PSS, NID_sha512, SSL_SIGN_RSA_PSS_RSAE_SHA512}, + {EVP_PKEY_EC, NID_sha1, SSL_SIGN_ECDSA_SHA1}, + {EVP_PKEY_EC, NID_sha256, SSL_SIGN_ECDSA_SECP256R1_SHA256}, + {EVP_PKEY_EC, NID_sha384, SSL_SIGN_ECDSA_SECP384R1_SHA384}, + {EVP_PKEY_EC, NID_sha512, SSL_SIGN_ECDSA_SECP521R1_SHA512}, + {EVP_PKEY_ED25519, NID_undef, SSL_SIGN_ED25519}, + }; + static const int mmax = sizeof(kSignatureAlgorithmsMapping) / + sizeof(kSignatureAlgorithmsMapping[0]); + + int sigalgs[num_prefs * 2]; + + for(size_t pi = 0; pi < num_prefs; pi++) { + int mi; + + for(mi = 0; mi < mmax; mi++) { + if(kSignatureAlgorithmsMapping[mi].signature_algorithm == prefs[pi]) { + sigalgs[pi * 2] = kSignatureAlgorithmsMapping[mi].hash_nid; + sigalgs[pi * 2 + 1] = kSignatureAlgorithmsMapping[mi].pkey_type; + break; + } + } + + if(mi == mmax) { + ossl_ERR_raise_data(ossl_ERR_LIB_SSL, ossl_ERR_R_INTERNAL_ERROR, + "unknown signature algorithm : %d", prefs[pi]); + return 0; + } + } + + return ossl.ossl_SSL_CTX_set1_sigalgs(ctx, sigalgs, num_prefs * 2); +} diff --git a/bssl-compat/source/SSL_CTX_use_PrivateKey.cc b/bssl-compat/source/SSL_CTX_use_PrivateKey.cc new file mode 100644 index 00000000000..c169c555fc3 --- /dev/null +++ b/bssl-compat/source/SSL_CTX_use_PrivateKey.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L867 + * https://www.openssl.org/docs/man3.0/man3/SSL_CTX_use_PrivateKey.html + */ +extern "C" int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { + return (ossl.ossl_SSL_CTX_use_PrivateKey(ctx, pkey) == 1) ? 1 : 0; +} diff --git a/bssl-compat/source/SSL_CTX_use_certificate.cc b/bssl-compat/source/SSL_CTX_use_certificate.cc new file mode 100644 index 00000000000..e1b6a5c679d --- /dev/null +++ b/bssl-compat/source/SSL_CTX_use_certificate.cc @@ -0,0 +1,8 @@ +#include +#include + + +extern "C" int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x509) { + int ret = ossl.ossl_SSL_CTX_use_certificate(ctx, x509); + return (ret == 1) ? 1 : 0; +} diff --git a/bssl-compat/source/SSL_SESSION_from_bytes.c b/bssl-compat/source/SSL_SESSION_from_bytes.c new file mode 100644 index 00000000000..980f31f9422 --- /dev/null +++ b/bssl-compat/source/SSL_SESSION_from_bytes.c @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L1709 + * https://www.openssl.org/docs/man3.0/man3/d2i_SSL_SESSION.html + */ +SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len, const SSL_CTX *ctx) { + return ossl.ossl_d2i_SSL_SESSION(NULL, &in, in_len); +} diff --git a/bssl-compat/source/SSL_SESSION_get_ticket_lifetime_hint.cc b/bssl-compat/source/SSL_SESSION_get_ticket_lifetime_hint.cc new file mode 100644 index 00000000000..2d6c3ca01f3 --- /dev/null +++ b/bssl-compat/source/SSL_SESSION_get_ticket_lifetime_hint.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" uint32_t SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session) { + return ossl.ossl_SSL_SESSION_get_ticket_lifetime_hint(session); +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_SESSION_get_version.cc b/bssl-compat/source/SSL_SESSION_get_version.cc new file mode 100644 index 00000000000..44819f404d1 --- /dev/null +++ b/bssl-compat/source/SSL_SESSION_get_version.cc @@ -0,0 +1,12 @@ +#include +#include +#include "internal.h" + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L1714 + * https://www.openssl.org/docs/man3.0/man3/SSL_SESSION_get_protocol_version.html + */ +extern "C" const char *SSL_SESSION_get_version(const SSL_SESSION *session) { + return TLS_VERSION_to_string(ossl.ossl_SSL_SESSION_get_protocol_version(session)); +} diff --git a/bssl-compat/source/SSL_SESSION_new.cc b/bssl-compat/source/SSL_SESSION_new.cc new file mode 100644 index 00000000000..fb8e211a760 --- /dev/null +++ b/bssl-compat/source/SSL_SESSION_new.cc @@ -0,0 +1,11 @@ +#include +#include +#include "log.h" + + +SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) { + if(ctx) { + bssl_compat_warn("%s() with non-null ctx not implemented", __func__); + } + return ossl.ossl_SSL_SESSION_new(); +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_SESSION_should_be_single_use.cc b/bssl-compat/source/SSL_SESSION_should_be_single_use.cc new file mode 100644 index 00000000000..e642c663344 --- /dev/null +++ b/bssl-compat/source/SSL_SESSION_should_be_single_use.cc @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + + +extern "C" int SSL_SESSION_should_be_single_use(const SSL_SESSION *session) { + return (ossl.ossl_SSL_SESSION_get_protocol_version(session) >= ossl_TLS1_3_VERSION); +} diff --git a/bssl-compat/source/SSL_SESSION_to_bytes.c b/bssl-compat/source/SSL_SESSION_to_bytes.c new file mode 100644 index 00000000000..4da9307d127 --- /dev/null +++ b/bssl-compat/source/SSL_SESSION_to_bytes.c @@ -0,0 +1,33 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L1698 + * https://www.openssl.org/docs/man3.0/man3/i2d_SSL_SESSION.html + */ +int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data, size_t *out_len) { + if(in == NULL || out_data == NULL || out_len == NULL) { + return 0; + } + + int buflen = ossl.ossl_i2d_SSL_SESSION(in, NULL); + if(buflen == 0) { + return 0; + } + + unsigned char *buf = OPENSSL_malloc(buflen); + if(buf == NULL) { + return 0; + } + + buflen = ossl.ossl_i2d_SSL_SESSION(in, &buf); + if(buflen == 0) { + return 0; + } + + *out_data = buf - buflen; + *out_len = buflen; + + return 1; +} diff --git a/bssl-compat/source/SSL_add_file_cert_subjects_to_stack.cc b/bssl-compat/source/SSL_add_file_cert_subjects_to_stack.cc new file mode 100644 index 00000000000..1649bdef0fa --- /dev/null +++ b/bssl-compat/source/SSL_add_file_cert_subjects_to_stack.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, const char *file) { + return ossl.ossl_SSL_add_file_cert_subjects_to_stack(reinterpret_cast(out), file); +} diff --git a/bssl-compat/source/SSL_early_callback_ctx_extension_get.c b/bssl-compat/source/SSL_early_callback_ctx_extension_get.c new file mode 100644 index 00000000000..577729eef04 --- /dev/null +++ b/bssl-compat/source/SSL_early_callback_ctx_extension_get.c @@ -0,0 +1,32 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L4254 + */ +int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello, uint16_t extension_type, const uint8_t **out_data, size_t *out_len) { + CBS extensions; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + + while(CBS_len(&extensions)) { + CBS extension; + uint16_t type; + + if (!CBS_get_u16(&extensions, &type)) { + return 0; // Failed to get extension type + } + + if (!CBS_get_u16_length_prefixed(&extensions, &extension)) { + return 0; // Failed to get extension bytes + } + + if (type == extension_type) { + *out_data = CBS_data(&extension); + *out_len = CBS_len(&extension); + return 1; // Success + } + } + + return 0; // Failed to find extension +} diff --git a/bssl-compat/source/SSL_enable_ocsp_stapling.cc b/bssl-compat/source/SSL_enable_ocsp_stapling.cc new file mode 100644 index 00000000000..5967a0ab3db --- /dev/null +++ b/bssl-compat/source/SSL_enable_ocsp_stapling.cc @@ -0,0 +1,8 @@ +#include +#include + + +extern "C" void SSL_enable_ocsp_stapling(SSL *ssl) { + ossl.ossl_SSL_set_tlsext_status_type(ssl, ossl_TLSEXT_STATUSTYPE_ocsp); +} + diff --git a/bssl-compat/source/SSL_error_description.cc b/bssl-compat/source/SSL_error_description.cc new file mode 100644 index 00000000000..94aea59ad94 --- /dev/null +++ b/bssl-compat/source/SSL_error_description.cc @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + + +extern "C" const char *SSL_error_description(int err) { + switch (err) { +#ifdef SSL_ERROR_NONE + case SSL_ERROR_NONE: return "NONE"; +#endif +#ifdef SSL_ERROR_SSL + case SSL_ERROR_SSL: return "SSL"; +#endif +#ifdef SSL_ERROR_WANT_READ + case SSL_ERROR_WANT_READ: return "WANT_READ"; +#endif +#ifdef SSL_ERROR_WANT_WRITE + case SSL_ERROR_WANT_WRITE: return "WANT_WRITE"; +#endif +#ifdef SSL_ERROR_WANT_X509_LOOKUP + case SSL_ERROR_WANT_X509_LOOKUP: return "WANT_X509_LOOKUP"; +#endif +#ifdef SSL_ERROR_SYSCALL + case SSL_ERROR_SYSCALL: return "SYSCALL"; +#endif +#ifdef SSL_ERROR_ZERO_RETURN + case SSL_ERROR_ZERO_RETURN: return "ZERO_RETURN"; +#endif +#ifdef SSL_ERROR_WANT_CONNECT + case SSL_ERROR_WANT_CONNECT: return "WANT_CONNECT"; +#endif +#ifdef SSL_ERROR_WANT_ACCEPT + case SSL_ERROR_WANT_ACCEPT: return "WANT_ACCEPT"; +#endif +#ifdef SSL_ERROR_PENDING_SESSION + case SSL_ERROR_PENDING_SESSION: return "PENDING_SESSION"; +#endif +#ifdef SSL_ERROR_PENDING_CERTIFICATE + case SSL_ERROR_PENDING_CERTIFICATE: return "PENDING_CERTIFICATE"; +#endif +#ifdef SSL_ERROR_WANT_PRIVATE_KEY_OPERATION + case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION: return "WANT_PRIVATE_KEY_OPERATION"; +#endif +#ifdef SSL_ERROR_PENDING_TICKET + case SSL_ERROR_PENDING_TICKET: return "PENDING_TICKET"; +#endif +#ifdef SSL_ERROR_EARLY_DATA_REJECTED + case SSL_ERROR_EARLY_DATA_REJECTED: return "EARLY_DATA_REJECTED"; +#endif +#ifdef SSL_ERROR_WANT_CERTIFICATE_VERIFY + case SSL_ERROR_WANT_CERTIFICATE_VERIFY: return "WANT_CERTIFICATE_VERIFY"; +#endif +#ifdef SSL_ERROR_HANDOFF + case SSL_ERROR_HANDOFF: return "HANDOFF"; +#endif +#ifdef SSL_ERROR_HANDBACK + case SSL_ERROR_HANDBACK: return "HANDBACK"; +#endif +#ifdef SSL_ERROR_WANT_RENEGOTIATE + case SSL_ERROR_WANT_RENEGOTIATE: return "WANT_RENEGOTIATE"; +#endif +#ifdef SSL_ERROR_HANDSHAKE_HINTS_READY + case SSL_ERROR_HANDSHAKE_HINTS_READY: return "HANDSHAKE_HINTS_READY"; +#endif + default: + return NULL; + } +} diff --git a/bssl-compat/source/SSL_get0_ocsp_response.c b/bssl-compat/source/SSL_get0_ocsp_response.c new file mode 100644 index 00000000000..888fffb4bf8 --- /dev/null +++ b/bssl-compat/source/SSL_get0_ocsp_response.c @@ -0,0 +1,21 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L1614 + * https://www.openssl.org/docs/man3.0/man3/SSL_get_tlsext_status_ocsp_resp.html + */ +void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, size_t *out_len) { + unsigned char *data; + long len = ossl.ossl_SSL_get_tlsext_status_ocsp_resp((SSL*)ssl, &data); + + if(len == -1) { + *out = NULL; + *out_len = 0; + return; + } + + *out = data; + *out_len = len; +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_get0_peer_certificates.cc b/bssl-compat/source/SSL_get0_peer_certificates.cc new file mode 100644 index 00000000000..ee90fdc5865 --- /dev/null +++ b/bssl-compat/source/SSL_get0_peer_certificates.cc @@ -0,0 +1,15 @@ +#include +#include + + + +const STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) { + X509 *x509Temp = SSL_get_peer_certificate(ssl); + if(x509Temp == NULL) + return NULL; + else { + // Dummy buffer just to return a non null value + static STACK_OF(CRYPTO_BUFFER) *criptoBuffer = sk_CRYPTO_BUFFER_new_null(); + return criptoBuffer; + } +} diff --git a/bssl-compat/source/SSL_get0_peer_verify_algorithms.cc b/bssl-compat/source/SSL_get0_peer_verify_algorithms.cc new file mode 100644 index 00000000000..33d15b734e8 --- /dev/null +++ b/bssl-compat/source/SSL_get0_peer_verify_algorithms.cc @@ -0,0 +1,92 @@ +#include +#include +#include "log.h" + + +static void freefunc(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp) { + delete[] static_cast(ptr); +} + +// Allocate a new "exdata" index for holding on to return arrays +static const int exindex = ossl_CRYPTO_get_ex_new_index(ossl_CRYPTO_EX_INDEX_SSL, 0, nullptr, + nullptr, nullptr, freefunc); + + +// SSL_get0_peer_verify_algorithms sets |*out_sigalgs| to an array containing +// the signature algorithms the peer is able to verify. It returns the length of +// the array. Note these values are only sent starting TLS 1.2 and only +// mandatory starting TLS 1.3. If not sent, the empty array is returned. For the +// historical client certificate types list, see |SSL_get0_certificate_types|. +// +// The behavior of this function is undefined except during the callbacks set by +// by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the +// handshake is paused because of them. +// +// Each value returned in out_sigalgs is one of BoringSSL's SSL_SIGN_* +// constants, defined in : +// + +// At the time of writing, this function is only used in testing, and the only +// sigalg values it is expected to report are: +// SSL_SIGN_RSA_PSS_RSAE_SHA256 +// SSL_SIGN_RSA_PKCS1_SHA256 +// SSL_SIGN_ECDSA_SECP256R1_SHA256 +// +// In order to return an array, via the out_sigalsgs parameter, without it +// leaking, we associate it the SSL object via the extdata mechanism. That way, +// it either gets deleted in this function when replacing it with a new value, +// or when the SSL object gets freed, via the freefunc callback. +OPENSSL_EXPORT size_t SSL_get0_peer_verify_algorithms(const SSL *ssl, const uint16_t **out_sigalgs) { + + // Delete the previous sigalgs array if there is one from a previous call + uint16_t *oldsigalgs = static_cast(ossl_SSL_get_ex_data(const_cast(ssl), exindex)); + if (oldsigalgs) { + if(ossl_SSL_set_ex_data(const_cast(ssl), exindex, nullptr) == 0) { + return 0; + } + delete[] oldsigalgs; + } + + // Calling with a zero idx and nulls will return the count + int nsigalgs = ossl.ossl_SSL_get_sigalgs(const_cast(ssl), 0, nullptr, nullptr, nullptr, nullptr, nullptr); + + // Allocate the result array + uint16_t *sigalgs = new uint16_t[nsigalgs]; + + // Put the array into the SSL's exdata so it won't leak + if(ossl_SSL_set_ex_data(const_cast(ssl), exindex, sigalgs) == 0) { + delete[] sigalgs; + return 0; + } + + for (int i = 0; i < nsigalgs; i++) { + int sign{-1}; + int hash{-1}; + int signhash{-1}; + unsigned char rsign{0}; + unsigned char rhash{0}; + + if (ossl_SSL_get_sigalgs(const_cast(ssl), i, &sign, &hash, &signhash, &rsign, &rhash) == 0) { + return 0; + } + + if (signhash == NID_ecdsa_with_SHA256) { + sigalgs[i] = SSL_SIGN_ECDSA_SECP256R1_SHA256; + } + else if (signhash == NID_sha256WithRSAEncryption) { + sigalgs[i] = SSL_SIGN_RSA_PKCS1_SHA256; + } + else if ((sign == ossl_NID_rsassaPss) && (hash == ossl_NID_sha256)) { + sigalgs[i] = SSL_SIGN_RSA_PSS_RSAE_SHA256; + } + else { + bssl_compat_error("Unhandled sigalg : sign=%d, hash=%d, signhash=%d, rsign=%d, rhash=%d", + sign, hash, signhash, (int)rsign, (int)rhash); + sigalgs[i] = 0; + } + } + + *out_sigalgs = sigalgs; + + return nsigalgs; +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_get_all_cipher_names.cc b/bssl-compat/source/SSL_get_all_cipher_names.cc new file mode 100644 index 00000000000..9dc4551c5bd --- /dev/null +++ b/bssl-compat/source/SSL_get_all_cipher_names.cc @@ -0,0 +1,41 @@ +#include +#include +#include + + +static std::vector init_all_cipher_names() { + static std::vector names; + + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + if (ctx) { + bssl::UniquePtr ssl(SSL_new(ctx.get())); + if (ssl) { + if (STACK_OF(SSL_CIPHER)* cipherStack = SSL_get_ciphers(ssl.get())) { + size_t sslCipherNum = sk_SSL_CIPHER_num(cipherStack); + for (int i = 0; i < sslCipherNum; i++) { + if (const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(cipherStack, i)) { + if (const char* cipherName = SSL_CIPHER_get_name(cipher)) { + names.push_back(cipherName); + } + } + } + } + } + } + + return names; +} + +size_t SSL_get_all_cipher_names(const char **out, size_t max_out) { + static std::vector validCiphers = init_all_cipher_names(); + + if (max_out == 0 || out == nullptr) { + return validCiphers.size(); + } + + for (size_t i = 0; i < validCiphers.size() && i < max_out; i++) { + out[i] = validCiphers[i].c_str(); + } + + return validCiphers.size(); +} diff --git a/bssl-compat/source/SSL_get_all_signature_algorithm_names.cc b/bssl-compat/source/SSL_get_all_signature_algorithm_names.cc new file mode 100644 index 00000000000..10848c8b2ec --- /dev/null +++ b/bssl-compat/source/SSL_get_all_signature_algorithm_names.cc @@ -0,0 +1,78 @@ +#include +#include +#include +#include + +static const char* kSigAlgCandidates[] = { + "ecdsa_secp256r1_sha256", + "ecdsa_secp384r1_sha384", + "ecdsa_secp521r1_sha512", + "ed25519", + "ed448", + "rsa_pss_pss_sha256", + "rsa_pss_pss_sha384", + "rsa_pss_pss_sha512", + "rsa_pss_rsae_sha256", + "rsa_pss_rsae_sha384", + "rsa_pss_rsae_sha512", + "rsa_pkcs1_sha256", + "rsa_pkcs1_sha384", + "rsa_pkcs1_sha512", + "ecdsa_sha224", + "ecdsa_sha256", + "ecdsa_sha384", + "ecdsa_sha512", + "ecdsa_sha1", + "rsa_pkcs1_sha224", + "rsa_pkcs1_sha1", + "dsa_sha224", + "dsa_sha1", + "dsa_sha256", + "dsa_sha384", + "dsa_sha512", + "gostr34102012_256_intrinsic", + "gostr34102012_512_intrinsic", + "gostr34102012_256_gostr34112012_256", + "gostr34102012_512_gostr34112012_512", + "gostr34102001_gostr3411", + "rsa_pkcs1_md5_sha1", + "rsa_pkcs1_sha256_legacy" +}; + +#define CANDIDATES_SIZE (sizeof(kSigAlgCandidates) / sizeof(kSigAlgCandidates[0])) + +static std::vector init_all_signature_algorithm_names() { + std::vector names; + + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + if (ctx) { + bssl::UniquePtr ssl(SSL_new(ctx.get())); + if (ssl) { + for (size_t i = 0; i < CANDIDATES_SIZE; ++i) { + const char* candidate = kSigAlgCandidates[i]; + if (ossl.ossl_SSL_set1_sigalgs_list(ssl.get(), candidate)) { + names.push_back(candidate); + } + } + } + } + + return names; +} + + +size_t SSL_get_all_signature_algorithm_names(const char **out, size_t max_out) { + static std::vector validSigAlgs = init_all_signature_algorithm_names(); + + if (max_out == 0 || out == nullptr) { + return validSigAlgs.size(); + } + + for (size_t i = 0; i < validSigAlgs.size() && i < max_out; i++) { + out[i] = validSigAlgs[i].c_str(); + } + + return validSigAlgs.size(); +} + + diff --git a/bssl-compat/source/SSL_get_all_version_names.c b/bssl-compat/source/SSL_get_all_version_names.c new file mode 100644 index 00000000000..30358312920 --- /dev/null +++ b/bssl-compat/source/SSL_get_all_version_names.c @@ -0,0 +1,32 @@ +#include +#include + + +static const char *kUnknownVersion = "unknown"; + +struct VersionInfo { + uint16_t version; + const char *name; +}; + +static const struct VersionInfo kVersionNames[] = { + {TLS1_3_VERSION, "TLSv1.3"}, + {TLS1_2_VERSION, "TLSv1.2"}, + {TLS1_1_VERSION, "TLSv1.1"}, + {TLS1_VERSION, "TLSv1"}, + {DTLS1_VERSION, "DTLSv1"}, + {DTLS1_2_VERSION, "DTLSv1.2"}, +}; + +size_t SSL_get_all_version_names(const char **out, size_t max_out) { + size_t versionSize = (sizeof(kVersionNames) / sizeof(kVersionNames[0])); + if(max_out != 0) { + *out++ = kUnknownVersion; + for(int i = 0; i < versionSize; i++) { + *out++ = kVersionNames[i].name; + } + } + return 1+versionSize; +} + + diff --git a/bssl-compat/source/SSL_get_cipher_by_value.c b/bssl-compat/source/SSL_get_cipher_by_value.c new file mode 100644 index 00000000000..9a1d810cae9 --- /dev/null +++ b/bssl-compat/source/SSL_get_cipher_by_value.c @@ -0,0 +1,20 @@ +#include +#include +#include + + +const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { + const SSL_CIPHER *result = NULL; + SSL_CTX *ctx = SSL_CTX_new(TLS_method()); + if(ctx) { + SSL *ssl = SSL_new(ctx); + if(ssl) { + uint16_t nvalue = htons(value); + result = ossl.ossl_SSL_CIPHER_find(ssl, (const unsigned char*)&nvalue); + SSL_free(ssl); + } + SSL_CTX_free(ctx); + } + + return result; +} diff --git a/bssl-compat/source/SSL_get_ciphers.cc b/bssl-compat/source/SSL_get_ciphers.cc new file mode 100644 index 00000000000..84d5a5ee678 --- /dev/null +++ b/bssl-compat/source/SSL_get_ciphers.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) { + return reinterpret_cast(ossl.ossl_SSL_get_ciphers(ssl)); +} diff --git a/bssl-compat/source/SSL_get_client_CA_list.cc b/bssl-compat/source/SSL_get_client_CA_list.cc new file mode 100644 index 00000000000..7693a52b04d --- /dev/null +++ b/bssl-compat/source/SSL_get_client_CA_list.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L2693 + * https://www.openssl.org/docs/man3.0/man3/SSL_get_client_CA_list.html + */ +extern "C" STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) { + return reinterpret_cast(ossl.ossl_SSL_get_client_CA_list(ssl)); +} diff --git a/bssl-compat/source/SSL_get_curve_id.c b/bssl-compat/source/SSL_get_curve_id.c new file mode 100644 index 00000000000..18fb250db44 --- /dev/null +++ b/bssl-compat/source/SSL_get_curve_id.c @@ -0,0 +1,85 @@ +#include +#include +#include "log.h" + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L2345 + * https://www.openssl.org/docs/man3.0/man3/SSL_get_negotiated_group.html + */ +uint16_t SSL_get_curve_id(const SSL *ssl) { + int nid = ossl.ossl_SSL_get_negotiated_group((SSL*)ssl); +/* + * The data was obtained by: + * wget https://www.iana.org/assignments/tls-parameters/tls-parameters-8.csv + * cat tls-parameters-8.csv | grep -v Unassigned | grep -v Reserved | awk -F ',' '{ print "case ossl_NID_"$2": return "$1";"}' |sed -e 's/ (OBSOLETE)//' + * Plus some additional manual adjustments, + * as NID to GROUP ID mapping is not always based on the exactly same names. In general I was trying to + * state here all groups from ssl/t1_trce.c, see `static const ssl_trace_tbl ssl_groups_tbl[]` + */ + switch(nid) { + case ossl_NID_sect163k1: return 1; + case ossl_NID_sect163r1: return 2; + case ossl_NID_sect163r2: return 3; + case ossl_NID_sect193r1: return 4; + case ossl_NID_sect193r2: return 5; + case ossl_NID_sect233k1: return 6; + case ossl_NID_sect233r1: return 7; + case ossl_NID_sect239k1: return 8; + case ossl_NID_sect283k1: return 9; + case ossl_NID_sect283r1: return 10; + case ossl_NID_sect409k1: return 11; + case ossl_NID_sect409r1: return 12; + case ossl_NID_sect571k1: return 13; + case ossl_NID_sect571r1: return 14; + case ossl_NID_secp160k1: return 15; + case ossl_NID_secp160r1: return 16; + case ossl_NID_secp160r2: return 17; + case ossl_NID_secp192k1: return 18; + case ossl_NID_X9_62_prime192v1: return 19; + case ossl_NID_secp224k1: return 20; + case ossl_NID_secp224r1: return 21; + case ossl_NID_secp256k1: return 22; + case ossl_NID_X9_62_prime256v1: return 23; + case ossl_NID_secp384r1: return 24; + case ossl_NID_secp521r1: return 25; + case ossl_NID_brainpoolP256r1: return 26; + case ossl_NID_brainpoolP384r1: return 27; + case ossl_NID_brainpoolP512r1: return 28; + case ossl_NID_X25519: return 29; + case ossl_NID_X448: return 30; + //case ossl_NID_brainpoolP256r1tls13: return 31; + //case ossl_NID_brainpoolP384r1tls13: return 32; + //case ossl_NID_brainpoolP512r1tls13: return 33; + //case ossl_NID_GC256A: return 34; + //case ossl_NID_GC256B: return 35; + //case ossl_NID_GC256C: return 36; + //case ossl_NID_GC256D: return 37; + //case ossl_NID_GC512A: return 38; + //case ossl_NID_GC512B: return 39; + //case ossl_NID_GC512C: return 40; + //case ossl_NID_curveSM2: return 41; + case ossl_NID_ffdhe2048: return 256; + case ossl_NID_ffdhe3072: return 257; + case ossl_NID_ffdhe4096: return 258; + case ossl_NID_ffdhe6144: return 259; + case ossl_NID_ffdhe8192: return 260; + //case ossl_NID_MLKEM512: return 512; + //case ossl_NID_MLKEM768: return 513; + //case ossl_NID_MLKEM1024: return 514; + //case ossl_NID_SecP256r1MLKEM768: return 4587; + //case ossl_NID_X25519MLKEM768: return 4588; + //case ossl_NID_SecP384r1MLKEM1024: return 4589; + //case ossl_NID_X25519Kyber768Draft00: return 25497; + //case ossl_NID_SecP256r1Kyber768Draft00: return 25498; + //case ossl_NID_arbitrary_explicit_prime_curves: return 65281; + //case ossl_NID_arbitrary_explicit_char2_curves: return 65282; + default: { + if (nid | ossl_TLSEXT_nid_unknown) { + return 0; + } + bssl_compat_error("Unknown negotiated group nid : %d", nid); + return 0; + } + } +} diff --git a/bssl-compat/source/SSL_get_curve_name.cc b/bssl-compat/source/SSL_get_curve_name.cc new file mode 100644 index 00000000000..2c048f8cf79 --- /dev/null +++ b/bssl-compat/source/SSL_get_curve_name.cc @@ -0,0 +1,98 @@ +#include +#include +#include +#include + +struct KnownCurveCandidate { + int nid; // The OpenSSL specific NID value for the curve + uint16_t group_id; // TLS group ID for the curve. Defined by TLS protocol + const char name[22]; // The human-readable name for the curve +}; + +static const struct KnownCurveCandidate kCurveCandidates[] = { + {ossl_NID_sect163k1, 1, "K-163"}, + {ossl_NID_sect163r1, 2, ""}, + {ossl_NID_sect163r2, 3, "B-163"}, + {ossl_NID_sect193r1, 4, ""}, + {ossl_NID_sect193r2, 5, ""}, + {ossl_NID_sect233k1, 6, "K-233"}, + {ossl_NID_sect233r1, 7, "B-233"}, + {ossl_NID_sect239k1, 8, ""}, + {ossl_NID_sect283k1, 9, "K-283"}, + {ossl_NID_sect283r1, 10, "B-283"}, + {ossl_NID_sect409k1, 11, "K-409"}, + {ossl_NID_sect409r1, 12, "B-409"}, + {ossl_NID_sect571k1, 13, "K-571"}, + {ossl_NID_sect571r1, 14, "B-571"}, + {ossl_NID_secp160k1, 15, ""}, + {ossl_NID_secp160r1, 16, ""}, + {ossl_NID_secp160r2, 17, ""}, + {ossl_NID_secp192k1, 18, ""}, + {ossl_NID_X9_62_prime192v1, 19, "P-192"}, + {ossl_NID_secp224k1, 20, ""}, + {ossl_NID_secp224r1, SSL_GROUP_SECP224R1, "P-224"}, + {ossl_NID_secp256k1, 22, ""}, + {ossl_NID_X9_62_prime256v1, SSL_GROUP_SECP256R1, "P-256"}, + {ossl_NID_secp384r1, SSL_GROUP_SECP384R1, "P-384"}, + {ossl_NID_secp521r1, SSL_GROUP_SECP521R1, "P-521"}, + {ossl_NID_brainpoolP256r1, 26, ""}, + {ossl_NID_brainpoolP384r1, 27, ""}, + {ossl_NID_brainpoolP512r1, 28, ""}, + {ossl_NID_X25519, SSL_GROUP_X25519, "X25519"}, + {ossl_NID_X448, 30, ""}, + {ossl_NID_ffdhe2048, 256, ""}, + {ossl_NID_ffdhe3072, 257, ""}, + {ossl_NID_ffdhe4096, 258, ""}, + {ossl_NID_ffdhe6144, 259, ""}, + {ossl_NID_ffdhe8192, 260, ""}, + {ossl_NID_undef, SSL_GROUP_X25519_MLKEM768, "X25519MLKEM768"}, + {ossl_NID_undef, SSL_GROUP_X25519_KYBER768_DRAFT00, "X25519Kyber768Draft00"}, + }; + +#define CANDIDATES_SIZE (sizeof(kCurveCandidates) / sizeof(kCurveCandidates[0])) + + +static std::vector init_all_curve_names() { + std::vector names; + + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + if (ctx) { + bssl::UniquePtr ssl(SSL_new(ctx.get())); + if (ssl) { + for (size_t i = 0; i < CANDIDATES_SIZE; ++i) { + if (ossl.ossl_SSL_set1_groups_list(ssl.get(), kCurveCandidates[i].name)) { + // Success: OpenSSL knows this curve and can handle it. + names.push_back(kCurveCandidates[i].name); + } + } + } + } + + return names; +} + + +size_t SSL_get_all_curve_names(const char **out, size_t max_out) { + static std::vector names = init_all_curve_names(); + + if (out && max_out) { + for(int i = 0; i < max_out && i < names.size(); i++) { + out[i] = names[i].c_str(); + } + } + + return names.size(); // Return number of curves found, not written +} + +/* + * https://boringssl.googlesource.com/boringssl/+/master/ssl/ssl_key_share.cc#451 + */ +const char *SSL_get_curve_name(uint16_t curve_id) { + for(int i = 0; i < (sizeof(kCurveCandidates) / sizeof(kCurveCandidates[0])); i++) { + if(kCurveCandidates[i].group_id == curve_id) { + return kCurveCandidates[i].name; + } + } + return NULL; +} + diff --git a/bssl-compat/source/SSL_get_ex_new_index.cc b/bssl-compat/source/SSL_get_ex_new_index.cc new file mode 100644 index 00000000000..e9595b0ca4c --- /dev/null +++ b/bssl-compat/source/SSL_get_ex_new_index.cc @@ -0,0 +1,16 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#LL3882C20-L3882C40 + * https://www.openssl.org/docs/man3.0/man3/SSL_get_ex_new_index.html + * + * Out of the three callback function pointers, BoringSSL only makes use of the + * free_func. The new & dup callbacks are completely ignored, and therefore + * never called, even if a real function pointer is passed, which is why we + * pass them as nullptr to OpenSSL. + */ +extern "C" int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { + return ossl.ossl_SSL_get_ex_new_index(argl, argp, nullptr, nullptr, free_func); +} diff --git a/bssl-compat/source/SSL_get_peer_cert_chain.cc b/bssl-compat/source/SSL_get_peer_cert_chain.cc new file mode 100644 index 00000000000..3ae30d0e39a --- /dev/null +++ b/bssl-compat/source/SSL_get_peer_cert_chain.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) { + return (STACK_OF(X509)*)ossl.ossl_SSL_get_peer_cert_chain(ssl); +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_get_peer_full_cert_chain.cc b/bssl-compat/source/SSL_get_peer_full_cert_chain.cc new file mode 100644 index 00000000000..895ade5814c --- /dev/null +++ b/bssl-compat/source/SSL_get_peer_full_cert_chain.cc @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "override.h" + + +/* + * BoringSSL + * ========= + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L1586 + * + * SSL_get_peer_full_cert_chain returns the peer's certificate chain, or NULL + * if unavailable or the peer did not use certificates. This is the unverified + * list of certificates as sent by the peer, not the final chain built during + * verification. The caller does not take ownership of the result. + * + * This is the same as |SSL_get_peer_cert_chain| except that this function + * always returns the full chain, i.e. the first element of the return value + * (if any) will be the leaf certificate. In constrast, + * |SSL_get_peer_cert_chain| returns only the intermediate certificates if the + * |ssl| is a server. + * + * OpenSSL + * ======= + * + * SSL_get_peer_cert_chain() returns a pointer to STACK_OF(X509) certificates + * forming the certificate chain sent by the peer. If called on the client side, + * the stack also contains the peer's certificate; if called on the server side, + * the peer's certificate must be obtained separately using + * SSL_get_peer_certificate(3). If the peer did not present a certificate, NULL + * is returned. + * + * SSL_get0_peer_certificate() & SSL_get1_peer_certificate() return a pointer to + * the X509 certificate the peer presented. If the peer did not present a + * certificate, NULL is returned. + * + * SSL_get1_peer_certificate() The reference count of the X509 object returned + * is incremented by one, so that it will not be destroyed when the session + * containing the peer certificate is freed. The X509 object must be explicitly + * freed using X509_free(). + * + * SSL_get0_peer_certificate() The reference count of the X509 object returned + * is not incremented, and must not be freed. + */ +extern "C" STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) { + // If someone has provided us with an override result, just return that + if (auto r = OverrideResult::get(ssl)) { + return r->value(); + } + + // For a client, SSL_get_peer_cert_chain() gives us exactly what we want in + // terms of the content and ownership semantics so just return the result. + if (!ossl_SSL_is_server(ssl)) { + return reinterpret_cast(ossl_SSL_get_peer_cert_chain(ssl)); + } + + // For a server we have to concatenate the client's leaf + intermediate + // certificates (if any), and we also need to return the correct ownership + if (X509* leaf = ossl_SSL_get0_peer_certificate(ssl)) { + STACK_OF(X509) *result {nullptr}; + + if (STACK_OF(X509) *chain = reinterpret_cast(ossl_SSL_get_peer_cert_chain(ssl))) { + result = sk_X509_dup(chain); + sk_X509_insert(result, leaf, 0); + } + else { + result = sk_X509_new_null(); + sk_X509_push(result, leaf); + } + + // Now squirrel away the STACK_OF(X509) so that we can return it without + // returning ownership to the caller, also ensuring that it doesn't leak + static int index {SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, + +[](void *, void *ptr, CRYPTO_EX_DATA *, int, long, void*) { + if (ptr) sk_X509_free(reinterpret_cast(ptr)); + })}; + if (void *old = ossl_SSL_get_ex_data(const_cast(ssl), index)) { + sk_X509_free(reinterpret_cast(old)); + } + ossl_SSL_set_ex_data(const_cast(ssl), index, result); + + return result; + } + + return nullptr; +} diff --git a/bssl-compat/source/SSL_get_peer_signature_algorithm.c b/bssl-compat/source/SSL_get_peer_signature_algorithm.c new file mode 100644 index 00000000000..8003849d8e9 --- /dev/null +++ b/bssl-compat/source/SSL_get_peer_signature_algorithm.c @@ -0,0 +1,59 @@ +#include +#include +#include "log.h" + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L4390 + * + * https://www.openssl.org/docs/man3.0/man3/SSL_get_peer_signature_nid.html + * https://www.openssl.org/docs/man3.0/man3/SSL_get_peer_signature_type_nid.html + */ +uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl) { + int peer_sig_dgst_nid; + int peer_sig_pkey_nid; + + if(!ossl.ossl_SSL_get_peer_signature_nid((SSL*)ssl, &peer_sig_dgst_nid)) { + return 0; + } + + if(!ossl.ossl_SSL_get_peer_signature_type_nid((SSL*)ssl, &peer_sig_pkey_nid)) { + return 0; + } + + static const struct { + int pkey_nid; + int dgst_nid; + uint16_t sigalg; + } + sigalgs[] = { + { NID_rsaEncryption, NID_sha1, SSL_SIGN_RSA_PKCS1_SHA1 }, + { NID_rsaEncryption, NID_sha256, SSL_SIGN_RSA_PKCS1_SHA256 }, + { NID_rsaEncryption, NID_sha384, SSL_SIGN_RSA_PKCS1_SHA384 }, + { NID_rsaEncryption, NID_sha512, SSL_SIGN_RSA_PKCS1_SHA512 }, + + { NID_rsassaPss, NID_sha256, SSL_SIGN_RSA_PSS_RSAE_SHA256 }, + { NID_rsassaPss, NID_sha384, SSL_SIGN_RSA_PSS_RSAE_SHA384 }, + { NID_rsassaPss, NID_sha512, SSL_SIGN_RSA_PSS_RSAE_SHA512 }, + + { NID_X9_62_id_ecPublicKey, NID_sha1, SSL_SIGN_ECDSA_SHA1 }, + { NID_X9_62_id_ecPublicKey, NID_sha256, SSL_SIGN_ECDSA_SECP256R1_SHA256 }, + { NID_X9_62_id_ecPublicKey, NID_sha384, SSL_SIGN_ECDSA_SECP384R1_SHA384 }, + { NID_X9_62_id_ecPublicKey, NID_sha512, SSL_SIGN_ECDSA_SECP521R1_SHA512 }, + + { NID_ED25519, NID_undef, SSL_SIGN_ED25519 }, + }; + + for(int i = 0; i < (sizeof(sigalgs) / sizeof(sigalgs[0])); i++) { + if ((sigalgs[i].dgst_nid == peer_sig_dgst_nid)) { + if ((sigalgs[i].pkey_nid == NID_undef) || (sigalgs[i].pkey_nid == peer_sig_pkey_nid)) { + return sigalgs[i].sigalg; + } + } + } + + bssl_compat_warn("%s() : peer_sig_dgst_nid=%04x, peer_sig_pkey_nid=0x%04x", + __func__, peer_sig_dgst_nid, peer_sig_pkey_nid); + + return 0; +} diff --git a/bssl-compat/source/SSL_get_servername.cc b/bssl-compat/source/SSL_get_servername.cc new file mode 100644 index 00000000000..145ec039846 --- /dev/null +++ b/bssl-compat/source/SSL_get_servername.cc @@ -0,0 +1,83 @@ +#include +#include "SSL_CTX_set_select_certificate_cb.h" + + +static const unsigned char* extract_ext_str_value(const unsigned char *data, size_t& data_len, unsigned int type) { + // https://github.com/openssl/openssl/blob/12a765a5235f181c2f4992b615eb5f892c368e88/test/handshake_helper.c#L150 + unsigned int len, remaining = data_len; + const unsigned char *p = data; + if ( p && remaining > 2 ) { + // ntohs? + len = (*(p++) << 8); + len += *(p++); + if (len + 2 == remaining) { + remaining = len; + if (remaining > 0 && *p++ == type) { + remaining--; + /* Now we can finally pull out the byte array with the actual extn value. */ + if (remaining > 2) { + len = (*(p++) << 8); + len += *(p++); + if (len + 2 == remaining) { + data_len = len; + return p; + } + } + } + } + } + + data_len = 0; + return nullptr; +} + +/* + * This function effectively has two separate implementations, chosen depending + * on the invocation context. + * + * If invoked from within a SSL_CTX_set_select_certificate_cb() callback + * function (as indincated by the in_select_certificate_cb(ssl) query) then the + * OpenSSL implementation doesn't work for us. Instead we have to extract the + * servername host name bytes from the appropriate client hello extension. In + * all other cases we simply call the OpenSSL implementation. + */ +const char *SSL_get_servername(const SSL *ssl, const int type) { + if (in_select_certificate_cb(ssl)) { + // Allocate an ext data index for us to use, and plug in a free func + static int index {SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, + +[](void *, void *ptr, CRYPTO_EX_DATA *, int, long, void*) { + if (ptr) ossl_OPENSSL_free(ptr); + })}; + + const unsigned char* p; + size_t len; + + // Extract the bytes from the client hello SNI extension, if present. + if (ossl_SSL_client_hello_get0_ext(const_cast(ssl), type, &p, &len)) { + if ((p = extract_ext_str_value(p, len, type)) != nullptr) { + // The string pointed to by p is len bytes long but NOT null-terminated. + // Therefore, we have to make a null-terminated copy of it for returning. + char *copy {ossl_OPENSSL_strndup(reinterpret_cast(p), len)}; + + // The free func (registered with SSL_get_ex_new_index() above) is only + // called when the SSL object is finally freed. Therefore, we need to + // explicitly free any ex data value that may in the slot from previous + // calls on the same SSL object. + ossl_OPENSSL_free(SSL_get_ex_data(ssl, index)); + + // Squirel away the copy in the SSL object's ext data so it won't leak. + if (SSL_set_ex_data(const_cast(ssl), index, copy) == 0) { + ossl_OPENSSL_free(copy); + return nullptr; + } + + return copy; + } + } + + return nullptr; + } + else { + return ossl_SSL_get_servername(ssl, type); + } +} diff --git a/bssl-compat/source/SSL_get_signature_algorithm_digest.cc b/bssl-compat/source/SSL_get_signature_algorithm_digest.cc new file mode 100644 index 00000000000..dfdf8980cf2 --- /dev/null +++ b/bssl-compat/source/SSL_get_signature_algorithm_digest.cc @@ -0,0 +1,25 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L1095 + */ +extern "C" const EVP_MD *SSL_get_signature_algorithm_digest(uint16_t sigalg) { + switch (sigalg) { + case SSL_SIGN_RSA_PKCS1_SHA1: return EVP_sha1(); + case SSL_SIGN_RSA_PKCS1_SHA256: return EVP_sha256(); + case SSL_SIGN_RSA_PKCS1_SHA384: return EVP_sha384(); + case SSL_SIGN_RSA_PKCS1_SHA512: return EVP_sha512(); + case SSL_SIGN_ECDSA_SHA1: return EVP_sha1(); + case SSL_SIGN_ECDSA_SECP256R1_SHA256: return EVP_sha256(); + case SSL_SIGN_ECDSA_SECP384R1_SHA384: return EVP_sha384(); + case SSL_SIGN_ECDSA_SECP521R1_SHA512: return EVP_sha512(); + case SSL_SIGN_RSA_PSS_RSAE_SHA256: return EVP_sha256(); + case SSL_SIGN_RSA_PSS_RSAE_SHA384: return EVP_sha384(); + case SSL_SIGN_RSA_PSS_RSAE_SHA512: return EVP_sha512(); + case SSL_SIGN_ED25519: return nullptr; + } + + return nullptr; +} diff --git a/bssl-compat/source/SSL_get_signature_algorithm_key_type.cc b/bssl-compat/source/SSL_get_signature_algorithm_key_type.cc new file mode 100644 index 00000000000..f0fa248f3b4 --- /dev/null +++ b/bssl-compat/source/SSL_get_signature_algorithm_key_type.cc @@ -0,0 +1,25 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L1091 + */ +extern "C" int SSL_get_signature_algorithm_key_type(uint16_t sigalg) { + switch (sigalg) { + case SSL_SIGN_RSA_PKCS1_SHA1: return EVP_PKEY_RSA; + case SSL_SIGN_RSA_PKCS1_SHA256: return EVP_PKEY_RSA; + case SSL_SIGN_RSA_PKCS1_SHA384: return EVP_PKEY_RSA; + case SSL_SIGN_RSA_PKCS1_SHA512: return EVP_PKEY_RSA; + case SSL_SIGN_ECDSA_SHA1: return EVP_PKEY_EC; + case SSL_SIGN_ECDSA_SECP256R1_SHA256: return EVP_PKEY_EC; + case SSL_SIGN_ECDSA_SECP384R1_SHA384: return EVP_PKEY_EC; + case SSL_SIGN_ECDSA_SECP521R1_SHA512: return EVP_PKEY_EC; + case SSL_SIGN_RSA_PSS_RSAE_SHA256: return EVP_PKEY_RSA; + case SSL_SIGN_RSA_PSS_RSAE_SHA384: return EVP_PKEY_RSA; + case SSL_SIGN_RSA_PSS_RSAE_SHA512: return EVP_PKEY_RSA; + case SSL_SIGN_ED25519: return EVP_PKEY_ED25519; + } + + return EVP_PKEY_NONE; +} diff --git a/bssl-compat/source/SSL_get_signature_algorithm_name.c b/bssl-compat/source/SSL_get_signature_algorithm_name.c new file mode 100644 index 00000000000..e095db286dd --- /dev/null +++ b/bssl-compat/source/SSL_get_signature_algorithm_name.c @@ -0,0 +1,24 @@ +#include + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#LL1086C16-L1087C80 + */ +const char *SSL_get_signature_algorithm_name(uint16_t sigalg, int include_curve) { + switch (sigalg) { + case SSL_SIGN_RSA_PKCS1_SHA1: return "rsa_pkcs1_sha1"; + case SSL_SIGN_RSA_PKCS1_SHA256: return "rsa_pkcs1_sha256"; + case SSL_SIGN_RSA_PKCS1_SHA384: return "rsa_pkcs1_sha384"; + case SSL_SIGN_RSA_PKCS1_SHA512: return "rsa_pkcs1_sha512"; + case SSL_SIGN_ECDSA_SHA1: return "ecdsa_sha1"; + case SSL_SIGN_ECDSA_SECP256R1_SHA256: return include_curve ? "ecdsa_secp256r1_sha256" : "ecdsa_sha256"; + case SSL_SIGN_ECDSA_SECP384R1_SHA384: return include_curve ? "ecdsa_secp384r1_sha384" : "ecdsa_sha384"; + case SSL_SIGN_ECDSA_SECP521R1_SHA512: return include_curve ? "ecdsa_secp521r1_sha512" : "ecdsa_sha512"; + case SSL_SIGN_RSA_PSS_RSAE_SHA256: return "rsa_pss_rsae_sha256"; + case SSL_SIGN_RSA_PSS_RSAE_SHA384: return "rsa_pss_rsae_sha384"; + case SSL_SIGN_RSA_PSS_RSAE_SHA512: return "rsa_pss_rsae_sha512"; + case SSL_SIGN_ED25519: return "ed25519"; + } + + return NULL; +} diff --git a/bssl-compat/source/SSL_is_signature_algorithm_rsa_pss.cc b/bssl-compat/source/SSL_is_signature_algorithm_rsa_pss.cc new file mode 100644 index 00000000000..e10346afbbc --- /dev/null +++ b/bssl-compat/source/SSL_is_signature_algorithm_rsa_pss.cc @@ -0,0 +1,16 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L1100 + */ +extern "C" int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) { + switch (sigalg) { + case SSL_SIGN_RSA_PSS_RSAE_SHA256: return 1; + case SSL_SIGN_RSA_PSS_RSAE_SHA384: return 1; + case SSL_SIGN_RSA_PSS_RSAE_SHA512: return 1; + } + + return 0; +} diff --git a/bssl-compat/source/SSL_send_fatal_alert.cc b/bssl-compat/source/SSL_send_fatal_alert.cc new file mode 100644 index 00000000000..d061faa5dfc --- /dev/null +++ b/bssl-compat/source/SSL_send_fatal_alert.cc @@ -0,0 +1,8 @@ +#include +#include "log.h" + + +extern "C" int SSL_send_fatal_alert(SSL *ssl, uint8_t alert) { + bssl_compat_fatal("SSL_send_fatal_alert() is not implemented"); + return -1; +} diff --git a/bssl-compat/source/SSL_set0_CA_names.cc b/bssl-compat/source/SSL_set0_CA_names.cc new file mode 100644 index 00000000000..92806473aa2 --- /dev/null +++ b/bssl-compat/source/SSL_set0_CA_names.cc @@ -0,0 +1,15 @@ +#include +#include + + +void SSL_set0_CA_names(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) { + // BoringSSL code + // if (!ssl->config) { + // return; + // } + // ssl->config->CA_names.reset(name_list); + + // TODO + // perhaps using: + ///SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) +} diff --git a/bssl-compat/source/SSL_set_cert_cb.cc b/bssl-compat/source/SSL_set_cert_cb.cc new file mode 100644 index 00000000000..2200122efc7 --- /dev/null +++ b/bssl-compat/source/SSL_set_cert_cb.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) { + ossl.ossl_SSL_set_cert_cb(ssl, cb, arg); +} \ No newline at end of file diff --git a/bssl-compat/source/SSL_set_chain_and_key.cc b/bssl-compat/source/SSL_set_chain_and_key.cc new file mode 100644 index 00000000000..2216fc7a4bf --- /dev/null +++ b/bssl-compat/source/SSL_set_chain_and_key.cc @@ -0,0 +1,47 @@ +#include +#include "CRYPTO_BUFFER.h" +#include +#include "log.h" + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L1133 + * https://www.openssl.org/docs/man3.0/man3/SSL_use_cert_and_key.html + */ +extern "C" int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs, size_t num_certs, EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) { + if(privkey_method) { + bssl_compat_fatal("%s() : privkey_method parameter is not supported"); + } + + bssl::UniquePtr leaf; + bssl::UniquePtr chain {sk_X509_new_null()}; + + for(size_t i = 0; i < num_certs; i++) { + bssl::UniquePtr bio {BIO_new_mem_buf(certs[i]->data, certs[i]->len)}; + if (!bio) { + return 0; + } + + bssl::UniquePtr cert {ossl.ossl_d2i_X509_bio(bio.get(), nullptr)}; + if (!cert) { + return 0; + } + + if(i == 0) { + leaf = std::move(cert); + } + else { + if(sk_X509_push(chain.get(), cert.get()) <= 0) { + return 0; + } + } + + cert.release(); + } + + if (!ossl.ossl_SSL_use_cert_and_key(ssl, leaf.get(), privkey, reinterpret_cast(chain.get()), 1)) { + return 0; + } + + return 1; +} diff --git a/bssl-compat/source/SSL_set_client_CA_list.cc b/bssl-compat/source/SSL_set_client_CA_list.cc new file mode 100644 index 00000000000..a0e32b41945 --- /dev/null +++ b/bssl-compat/source/SSL_set_client_CA_list.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/955ef7991e41ac6c0ea5114b4b9abb98cc5fd614/include/openssl/ssl.h#L2665 + * https://www.openssl.org/docs/man3.0/man3/SSL_set_client_CA_list.html + */ +extern "C" void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) { + ossl.ossl_SSL_set_client_CA_list(ssl, reinterpret_cast(name_list)); +} diff --git a/bssl-compat/source/SSL_set_info_callback.cc b/bssl-compat/source/SSL_set_info_callback.cc new file mode 100644 index 00000000000..cac1eb5b004 --- /dev/null +++ b/bssl-compat/source/SSL_set_info_callback.cc @@ -0,0 +1,11 @@ +#include +#include + + +void SSL_set_info_callback( SSL *ssl, void (*cb)(const SSL *ssl, int type, int value)) { +#ifdef ossl_SSL_set_info_callback + return ossl_SSL_set_info_callback(ssl, ssl, cb); +#else + return ossl.ossl_SSL_set_info_callback(ssl, cb); +#endif +} diff --git a/bssl-compat/source/SSL_set_ocsp_response.cc b/bssl-compat/source/SSL_set_ocsp_response.cc new file mode 100644 index 00000000000..299716e8a25 --- /dev/null +++ b/bssl-compat/source/SSL_set_ocsp_response.cc @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "SSL_CTX_set_select_certificate_cb.h" + + +typedef std::pair OcspResponse; + +static int index() { + static int index {ossl.ossl_SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, + +[](void *, void *ptr, CRYPTO_EX_DATA *, int, long, void*) { + if(ptr) { + OcspResponse *resp {reinterpret_cast(ptr)}; + ossl.ossl_OPENSSL_free(resp->first); + delete resp; + } + })}; + return index; +} + +/** + * This callback gets installed via SSL_CTX_set_tlsext_status_cb(...) in order to deal + * with the deferred OCSP response that may have been set via SSL_set_ocsp_response() + */ +static int ssl_apply_deferred_ocsp_response_cb(SSL *ssl, void *arg) { + std::unique_ptr resp {reinterpret_cast(ossl.ossl_SSL_get_ex_data(ssl, index()))}; + + if (resp) { + ossl.ossl_SSL_set_ex_data(ssl, index(), nullptr); + if (ossl.ossl_SSL_set_tlsext_status_ocsp_resp(ssl, resp->first, resp->second) == 0) { + return ossl_SSL_TLSEXT_ERR_ALERT_FATAL; + } + return ossl_SSL_TLSEXT_ERR_OK; + } + + return ossl_SSL_TLSEXT_ERR_NOACK; +} + +/** + * If this is called from within the select certificate callback, then we don't call + * ossl_SSL_CTX_set_tlsext_status_cb() directly because it doesn't work from within that + * callback. Instead, we squirel away the OCSP response bytes to be applied later on via + * ossl_SSL_CTX_set_tlsext_status_cb() later on. + */ +extern "C" int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response, size_t response_len) { + if (void *response_copy {ossl.ossl_OPENSSL_memdup(response, response_len)}) { + if (in_select_certificate_cb(ssl)) { + + SSL_CTX *ctx {ossl.ossl_SSL_get_SSL_CTX(ssl)}; + int (*callback)(SSL *, void *) {nullptr}; + + // Check that we are not overwriting another existing callback + if (ossl_SSL_CTX_get_tlsext_status_cb(ctx, &callback) == 0) { + return 0; + } + if (callback && (callback != ssl_apply_deferred_ocsp_response_cb)) { + return 0; + } + + // Install our callback to call the real SSL_set_ex_data() function later + if (ossl_SSL_CTX_set_tlsext_status_cb(ctx, ssl_apply_deferred_ocsp_response_cb) == 0) { + return 0; + } + + // If we have been called previously, from within the same select + // certificate callback invocation, there will be an OcspReponse object + // squirreled away already. If so, delete it first, so we don't just + // overwrite it and create a leak. + if(OcspResponse *prev = reinterpret_cast(ossl.ossl_SSL_get_ex_data(ssl, index()))) { + ossl.ossl_OPENSSL_free(prev->first); + delete prev; + } + + // Store the OCSP response bytes for the callback to pick up later + return ossl.ossl_SSL_set_ex_data(ssl, index(), new OcspResponse(response_copy, response_len)); + } + else { + return ossl.ossl_SSL_set_tlsext_status_ocsp_resp(ssl, response_copy, response_len); + } + } + + return response ? 0 : 1; +} diff --git a/bssl-compat/source/SSL_set_renegotiate_mode.cc b/bssl-compat/source/SSL_set_renegotiate_mode.cc new file mode 100644 index 00000000000..c0a00606280 --- /dev/null +++ b/bssl-compat/source/SSL_set_renegotiate_mode.cc @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "log.h" + + +extern "C" void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) { + switch(mode) { + case ssl_renegotiate_never: { + ossl.ossl_SSL_clear_options(ssl,ossl_SSL_OP_ALLOW_CLIENT_RENEGOTIATION); + break; + } + case ssl_renegotiate_freely: { + ossl.ossl_SSL_set_options(ssl,ossl_SSL_OP_ALLOW_CLIENT_RENEGOTIATION); + break; + } + case ssl_renegotiate_once: { + bssl_compat_fatal("%s(ssl_renegotiate_once) NYI", __func__); + break; + } + case ssl_renegotiate_ignore: { + bssl_compat_fatal("%s(ssl_renegotiate_ignore) NYI", __func__); + break; + } + case ssl_renegotiate_explicit: { + bssl_compat_fatal("%s(ssl_renegotiate_explicit) NYI", __func__); + break; + } + } +} diff --git a/bssl-compat/source/SSL_set_verify.cc b/bssl-compat/source/SSL_set_verify.cc new file mode 100644 index 00000000000..d8436807f67 --- /dev/null +++ b/bssl-compat/source/SSL_set_verify.cc @@ -0,0 +1,16 @@ +#include +#include +#include "log.h" + + +/* + * https://github.com/google/boringssl/blob/098695591f3a2665fccef83a3732ecfc99acdcdd/src/include/openssl/ssl.h#L2414 + * https://www.openssl.org/docs/man3.0/man3/SSL_set_verify.html + */ +extern "C" void SSL_set_verify(SSL *ssl, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx)) { + if(callback) { + bssl_compat_fatal("%s() : non-null callback is not supported", __func__); + } + ossl.ossl_SSL_set_verify(ssl, mode, callback); +} + diff --git a/bssl-compat/source/TLS_VERSION_to_string.cc b/bssl-compat/source/TLS_VERSION_to_string.cc new file mode 100644 index 00000000000..12249720f61 --- /dev/null +++ b/bssl-compat/source/TLS_VERSION_to_string.cc @@ -0,0 +1,14 @@ +#include + + +const char *TLS_VERSION_to_string(int version) { + switch (version) { + case TLS1_VERSION: return "TLSv1"; + case TLS1_1_VERSION: return "TLSv1.1"; + case TLS1_2_VERSION: return "TLSv1.2"; + case TLS1_3_VERSION: return "TLSv1.3"; + case DTLS1_VERSION: return "DTLSv1"; + case DTLS1_2_VERSION: return "DTLSv1.2"; + default: return "???"; + } +} diff --git a/bssl-compat/source/TLS_with_buffers_method.cc b/bssl-compat/source/TLS_with_buffers_method.cc new file mode 100644 index 00000000000..c6c80f67501 --- /dev/null +++ b/bssl-compat/source/TLS_with_buffers_method.cc @@ -0,0 +1,8 @@ +#include +#include + + +extern "C" const SSL_METHOD *TLS_with_buffers_method(void) { + return ossl.ossl_TLS_method(); +} + diff --git a/bssl-compat/source/X509_EXTENSION_get_data.cc b/bssl-compat/source/X509_EXTENSION_get_data.cc new file mode 100644 index 00000000000..033c80a417d --- /dev/null +++ b/bssl-compat/source/X509_EXTENSION_get_data.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" ASN1_OCTET_STRING *X509_EXTENSION_get_data( const X509_EXTENSION *ne) { + return ossl.ossl_X509_EXTENSION_get_data(const_cast(ne)); +} diff --git a/bssl-compat/source/X509_EXTENSION_get_object.cc b/bssl-compat/source/X509_EXTENSION_get_object.cc new file mode 100644 index 00000000000..9857bb01ef8 --- /dev/null +++ b/bssl-compat/source/X509_EXTENSION_get_object.cc @@ -0,0 +1,7 @@ +#include +#include + + +ASN1_OBJECT *X509_EXTENSION_get_object(const X509_EXTENSION *ex) { + return ossl.ossl_X509_EXTENSION_get_object(const_cast(ex)); +} diff --git a/bssl-compat/source/X509_STORE_CTX_get0_chain.cc b/bssl-compat/source/X509_STORE_CTX_get0_chain.cc new file mode 100644 index 00000000000..283615575a4 --- /dev/null +++ b/bssl-compat/source/X509_STORE_CTX_get0_chain.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" STACK_OF(X509) *X509_STORE_CTX_get0_chain(const X509_STORE_CTX *ctx) { + return reinterpret_cast(ossl_X509_STORE_CTX_get0_chain(ctx)); +} diff --git a/bssl-compat/source/X509_STORE_CTX_get0_untrusted.cc b/bssl-compat/source/X509_STORE_CTX_get0_untrusted.cc new file mode 100644 index 00000000000..faed8b24802 --- /dev/null +++ b/bssl-compat/source/X509_STORE_CTX_get0_untrusted.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(const X509_STORE_CTX *ctx) { + return reinterpret_cast(ossl.ossl_X509_STORE_CTX_get0_untrusted(ctx)); +} diff --git a/bssl-compat/source/X509_STORE_CTX_init.cc b/bssl-compat/source/X509_STORE_CTX_init.cc new file mode 100644 index 00000000000..20a328e197f --- /dev/null +++ b/bssl-compat/source/X509_STORE_CTX_init.cc @@ -0,0 +1,14 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/557b80f1a3e599459367391540488c132a000d55/include/openssl/x509.h#L2841 + * https://www.openssl.org/docs/man3.0/man3/X509_STORE_CTX_init.html + */ +extern "C" int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain) { + if (store == nullptr) { + return 0; // BoringSSL requires a non-null store + } + return ossl.ossl_X509_STORE_CTX_init(ctx, store, x509, reinterpret_cast(chain)); +} diff --git a/bssl-compat/source/X509_STORE_CTX_set0_crls.cc b/bssl-compat/source/X509_STORE_CTX_set0_crls.cc new file mode 100644 index 00000000000..84d41bd49b3 --- /dev/null +++ b/bssl-compat/source/X509_STORE_CTX_set0_crls.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/557b80f1a3e599459367391540488c132a000d55/include/openssl/x509.h#L2911 + * https://www.openssl.org/docs/man3.0/man3/X509_STORE_CTX_set0_crls.html + */ +extern "C" void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk) { + ossl.ossl_X509_STORE_CTX_set0_crls(c, reinterpret_cast(sk)); +} diff --git a/bssl-compat/source/X509_STORE_CTX_set0_trusted_stack.cc b/bssl-compat/source/X509_STORE_CTX_set0_trusted_stack.cc new file mode 100644 index 00000000000..876a36609ed --- /dev/null +++ b/bssl-compat/source/X509_STORE_CTX_set0_trusted_stack.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { + ossl.ossl_X509_STORE_CTX_set0_trusted_stack(ctx, reinterpret_cast(sk)); +} diff --git a/bssl-compat/source/X509_STORE_CTX_set_verify_cb.cc b/bssl-compat/source/X509_STORE_CTX_set_verify_cb.cc new file mode 100644 index 00000000000..2f3ca2d605e --- /dev/null +++ b/bssl-compat/source/X509_STORE_CTX_set_verify_cb.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/557b80f1a3e599459367391540488c132a000d55/include/openssl/x509.h#L2922 + * https://www.openssl.org/docs/man3.0/man3/X509_STORE_CTX_set_verify_cb.html + */ +extern "C" void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, int (*verify_cb)(int, X509_STORE_CTX *)) { + ossl.ossl_X509_STORE_CTX_set_verify_cb(ctx, verify_cb); +} diff --git a/bssl-compat/source/X509_VERIFY_PARAM_set_time_posix.cc b/bssl-compat/source/X509_VERIFY_PARAM_set_time_posix.cc new file mode 100644 index 00000000000..82c3f6f6151 --- /dev/null +++ b/bssl-compat/source/X509_VERIFY_PARAM_set_time_posix.cc @@ -0,0 +1,7 @@ +#include +#include + + +void X509_VERIFY_PARAM_set_time_posix(X509_VERIFY_PARAM *param, int64_t t) { + return ossl.ossl_X509_VERIFY_PARAM_set_time(param, t); +} \ No newline at end of file diff --git a/bssl-compat/source/X509_alias_get0.cc b/bssl-compat/source/X509_alias_get0.cc new file mode 100644 index 00000000000..b2547a0b4de --- /dev/null +++ b/bssl-compat/source/X509_alias_get0.cc @@ -0,0 +1,7 @@ +#include +#include + + +const uint8_t *X509_alias_get0(const X509 *x509, int *out_len) { + return ossl.ossl_X509_alias_get0(const_cast(x509), out_len); +} diff --git a/bssl-compat/source/X509_get_pubkey.cc b/bssl-compat/source/X509_get_pubkey.cc new file mode 100644 index 00000000000..fbc32b9ad10 --- /dev/null +++ b/bssl-compat/source/X509_get_pubkey.cc @@ -0,0 +1,7 @@ +#include +#include + + +EVP_PKEY *X509_get_pubkey(const X509 *x509) { + return ossl.ossl_X509_get_pubkey(const_cast(x509)); +} diff --git a/bssl-compat/source/X509_sign.cc b/bssl-compat/source/X509_sign.cc new file mode 100644 index 00000000000..0e5d764e2f2 --- /dev/null +++ b/bssl-compat/source/X509_sign.cc @@ -0,0 +1,11 @@ +#include +#include + + +/* + * https://github.com/google/boringssl/blob/557b80f1a3e599459367391540488c132a000d55/include/openssl/x509.h#L348 + * https://www.openssl.org/docs/man3.0/man3/X509_sign.html + */ +extern "C" int X509_sign(X509 *x509, EVP_PKEY *pkey, const EVP_MD *md) { + return (ossl.ossl_X509_sign(x509, pkey, md) == 0) ? 0 : 1; +} diff --git a/bssl-compat/source/X509_verify_cert.c b/bssl-compat/source/X509_verify_cert.c new file mode 100644 index 00000000000..98eeed5d682 --- /dev/null +++ b/bssl-compat/source/X509_verify_cert.c @@ -0,0 +1,15 @@ +#include +#include + + +int X509_verify_cert(X509_STORE_CTX *ctx) { + int result = ossl.ossl_X509_verify_cert(ctx); + + if (result != 1) { + if (ossl.ossl_X509_STORE_CTX_get_error(ctx) == ossl_X509_V_ERR_CERT_CHAIN_TOO_LONG) { + ossl.ossl_X509_STORE_CTX_set_error(ctx, ossl_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); + } + } + + return result; +} diff --git a/bssl-compat/source/X509_verify_cert_error_string.cc b/bssl-compat/source/X509_verify_cert_error_string.cc new file mode 100644 index 00000000000..2d84931810a --- /dev/null +++ b/bssl-compat/source/X509_verify_cert_error_string.cc @@ -0,0 +1,17 @@ +#include +#include + + +/** + * This implementats some mappings only where necessary to support Envoy + */ +const char *X509_verify_cert_error_string(long err) { + switch(err) { + case X509_V_ERR_UNSPECIFIED: { + return "unknown certificate verification error"; + } + default: { + return ossl.ossl_X509_verify_cert_error_string(err); + } + } +} diff --git a/bssl-compat/source/c2i_ASN1_INTEGER.cc b/bssl-compat/source/c2i_ASN1_INTEGER.cc new file mode 100644 index 00000000000..4179e9e325b --- /dev/null +++ b/bssl-compat/source/c2i_ASN1_INTEGER.cc @@ -0,0 +1,26 @@ +#include +#include +#include +#include + + +extern "C" ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, long len) { + ASN1_INTEGER *result = NULL; + CBB cbb; + + if (CBB_init(&cbb, len + 2)) { + CBB child; + + if (CBB_add_asn1(&cbb, &child, CBS_ASN1_INTEGER) && CBB_add_bytes(&child, *inp, len) && CBB_flush(&cbb)) { + const uint8_t *data = CBB_data(&cbb); + + if ((result = ossl.ossl_d2i_ASN1_INTEGER(out, &data, CBB_len(&cbb))) != NULL) { + *inp += len; + } + } + + CBB_cleanup(&cbb); + } + + return result; +} diff --git a/bssl-compat/source/d2i_GENERAL_NAME.cc b/bssl-compat/source/d2i_GENERAL_NAME.cc new file mode 100644 index 00000000000..da4dff2a43a --- /dev/null +++ b/bssl-compat/source/d2i_GENERAL_NAME.cc @@ -0,0 +1,7 @@ +#include +#include + + +extern "C" GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len) { + return ossl.ossl_d2i_GENERAL_NAME(a, in, len); +} \ No newline at end of file diff --git a/bssl-compat/source/err.cc b/bssl-compat/source/err.cc new file mode 100644 index 00000000000..ef9eac063d4 --- /dev/null +++ b/bssl-compat/source/err.cc @@ -0,0 +1,136 @@ +#include +#include +#include +#include + + +uint64_t o2b(uint64_t e) { + switch (e) { + case 0x0A0000C1: return 0x100000B8; + case 0x0A0C0100: return 0x10000041; + case 0x0A000076: return 0x100000FD; + case 0x0A000102: return 0x100000F0; + case 0x0A000086: return 0x1000007D; + } + return e; +} + +uint64_t b2o(uint64_t e) { + switch (e) { + case 0x100000B8: return 0x0A0000C1; + case 0x10000041: return 0x0A0C0100; + case 0x100000FD: return 0x0A000076; + case 0x100000F0: return 0x0A000102; + case 0x1000007D: return 0x0A000086; + } + return e; +} + + +extern "C" char *ERR_error_string(uint32_t packed_error, char *buf) { + return ossl.ossl_ERR_error_string(b2o(packed_error), buf); +} + + +extern "C" char *ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) { + /** + * For test code that checks for error *text* we put an entry in this map so + * that we get exactly the same text that BoringSSL would produce for the same + * error. This is needed because OpenSSL and BoringSSL packed error codes aren't + * numerically the same, and BoringSSL always puts "OPENSSL_internal" as the + * function name. + */ + static const std::map ERRORMAP { + { 0x10000041, "error:10000041:SSL routines:OPENSSL_internal:malloc failure" }, + { 0x100000fd, "error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS" }, + { 0x1e08010c, "error:0900006e:PEM routines:OPENSSL_internal:NO_START_LINE" }, + { 0x05800074, "error:0b000074:X.509 certificate routines:OPENSSL_internal:KEY_VALUES_MISMATCH" }, + { 0x100000F0, "TLS_error:|268435696:SSL routines:OPENSSL_internal:UNSUPPORTED_PROTOCOL:TLS_error_end" }, + { 0x1000007D, "TLS_error:|268435581:SSL routines:OPENSSL_internal:UNSUPPORTED_PROTOCOL:TLS_error_end" }, + }; + + auto i = ERRORMAP.find(packed_error); + if (i != ERRORMAP.end()) { + strncpy(buf, i->second, len); + buf[len - 1] = '\0'; + return buf; + } + + return ossl.ossl_ERR_error_string_n(b2o(packed_error), buf, len), buf; +} + + +extern "C" const char *ERR_func_error_string(uint32_t packed_error) { + return "OPENSSL_internal"; +} + + +extern "C" uint32_t ERR_get_error(void) { + return o2b(ossl.ossl_ERR_get_error()); +} + + +extern "C" const char *ERR_lib_error_string(uint32_t packed_error) { + const char *ret = ossl.ossl_ERR_lib_error_string(b2o(packed_error)); + return (ret ? ret : "unknown library"); +} + + +extern "C" uint32_t ERR_peek_error(void) { + return o2b(ossl.ossl_ERR_peek_error()); +} + + +extern "C" uint32_t ERR_peek_error_line_data(const char **file, int *line, const char **data, int *flags) { + return o2b(ossl.ossl_ERR_peek_error_line_data(file, line, data, flags)); +} + + +extern "C" uint32_t ERR_peek_last_error(void) { + return o2b(ossl.ossl_ERR_peek_last_error()); +} + + +extern "C" const char *ERR_reason_error_string(uint32_t packed_error) { + /** + * This is not an exhaustive list of errors; rather it is just the ones that + * need to be translated for the Envoy tests to pass (yes some of the tests do + * check for specific error *text*). + */ + static const std::map ossl_2_bssl_error_string_map { + { "sslv3 alert certificate expired", "SSLV3_ALERT_CERTIFICATE_EXPIRED" }, + { "sslv3 alert handshake failure", "SSLV3_ALERT_HANDSHAKE_FAILURE" }, + { "tlsv1 alert protocol version", "TLSV1_ALERT_PROTOCOL_VERSION" }, + { "tlsv1 alert unknown ca", "TLSV1_ALERT_UNKNOWN_CA" }, + { "unsupported protocol", "UNSUPPORTED_PROTOCOL" }, + { "no shared cipher", "NO_SHARED_CIPHER" }, + { "no suitable signature algorithm", "NO_COMMON_SIGNATURE_ALGORITHMS" }, + { "certificate verify failed", "CERTIFICATE_VERIFY_FAILED" }, + }; + + const char *result = ossl.ossl_ERR_reason_error_string(b2o(packed_error)); + + if (result == nullptr) { + result = "unknown error"; + } + else { + auto i = ossl_2_bssl_error_string_map.find(result); + if (i != ossl_2_bssl_error_string_map.end()) { + result = i->second.c_str(); + } + } + + return result; +} + + +/* + * This function doesn't get automatically generated into ossl.c by + * the prefixer because it doesn't understand how to deal with the varargs. + */ +void ossl_ERR_set_error(int lib, int reason, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + ossl.ossl_ERR_vset_error(lib, reason, fmt, args); + va_end(args); +} diff --git a/bssl-compat/source/ext_SSL_get_all_async_fds.c b/bssl-compat/source/ext_SSL_get_all_async_fds.c new file mode 100644 index 00000000000..57c087d6303 --- /dev/null +++ b/bssl-compat/source/ext_SSL_get_all_async_fds.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + + +int ext_SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds) { + return ossl.ossl_SSL_get_all_async_fds(s, fds, numfds); +} diff --git a/bssl-compat/source/i2d_X509.c b/bssl-compat/source/i2d_X509.c new file mode 100644 index 00000000000..7640529355a --- /dev/null +++ b/bssl-compat/source/i2d_X509.c @@ -0,0 +1,41 @@ +#include +#include + + +/* + * On error, it returns a negative value. On success, it returns the length of + * the result and outputs it via outp as follows: + * + * If outp is NULL, the function writes nothing. This mode can be used to size + * buffers. + * + * If outp is non-NULL but *outp is NULL, the function sets *outp to a newly + * allocated buffer containing the result. The caller is responsible for + * releasing *outp with OPENSSL_free. This mode is recommended for most callers. + * + * If outp and *outp are non-NULL, the function writes the result to *outp, + * which must have enough space available, and advances *outp just past the + * output. + */ +int i2d_X509(X509 *x509, uint8_t **outp) { + ossl_BIO *bio = ossl.ossl_BIO_new(ossl.ossl_BIO_s_mem()); + int length = -1; + + if (ossl.ossl_i2d_X509_bio(bio, x509)) { // 1=success,0=failure + char *buf = NULL; + length = ossl.ossl_BIO_get_mem_data(bio, &buf); + + if (outp) { + if (*outp == NULL) { + *outp = ossl.ossl_OPENSSL_memdup(buf, length); + } + else { + ossl.ossl_OPENSSL_strlcpy((char*)*outp, buf, length); + } + } + } + + ossl.ossl_BIO_free(bio); + + return length; +} diff --git a/bssl-compat/source/i2d_X509_PUBKEY.cc b/bssl-compat/source/i2d_X509_PUBKEY.cc new file mode 100644 index 00000000000..186967eeb11 --- /dev/null +++ b/bssl-compat/source/i2d_X509_PUBKEY.cc @@ -0,0 +1,8 @@ +#include +#include +#include + + +int i2d_X509_PUBKEY(const X509_PUBKEY *a, unsigned char **out) { + return ossl.ossl_i2d_X509_PUBKEY(a, out); +} \ No newline at end of file diff --git a/bssl-compat/source/iana_2_ossl_names.cc b/bssl-compat/source/iana_2_ossl_names.cc new file mode 100644 index 00000000000..fe4e1159482 --- /dev/null +++ b/bssl-compat/source/iana_2_ossl_names.cc @@ -0,0 +1,268 @@ +#include "iana_2_ossl_names.h" +#include + + +/** + * Mapping from IANA names to the equivalent OpenSSL names, taken from + * https://github.com/drwetter/testssl.sh/blob/3.2/openssl-iana.mapping.html + */ +static const struct { + const char *iana; + const char *ossl; +} IANA_2_OSSL_NAMES[] { + { "TLS_RSA_WITH_NULL_MD5", "NULL-MD5" }, + { "TLS_RSA_WITH_NULL_SHA", "NULL-SHA" }, + { "TLS_RSA_EXPORT_WITH_RC4_40_MD5", "EXP-RC4-MD5" }, + { "TLS_RSA_WITH_RC4_128_MD5", "RC4-MD5" }, + { "TLS_RSA_WITH_RC4_128_SHA", "RC4-SHA" }, + { "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-RC2-CBC-MD5" }, + { "TLS_RSA_WITH_IDEA_CBC_SHA", "IDEA-CBC-SHA" }, + { "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-DES-CBC-SHA" }, + { "TLS_RSA_WITH_DES_CBC_SHA", "DES-CBC-SHA" }, + { "TLS_RSA_WITH_3DES_EDE_CBC_SHA", "DES-CBC3-SHA" }, + { "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", "EXP-DH-DSS-DES-CBC-SHA" }, + { "TLS_DH_DSS_WITH_DES_CBC_SHA", "DH-DSS-DES-CBC-SHA" }, + { "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", "DH-DSS-DES-CBC3-SHA" }, + { "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-DH-RSA-DES-CBC-SHA" }, + { "TLS_DH_RSA_WITH_DES_CBC_SHA", "DH-RSA-DES-CBC-SHA" }, + { "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", "DH-RSA-DES-CBC3-SHA" }, + { "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-DSS-DES-CBC-SHA" }, + { "TLS_DHE_DSS_WITH_DES_CBC_SHA", "EDH-DSS-DES-CBC-SHA" }, + { "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "EDH-DSS-DES-CBC3-SHA" }, + { "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-RSA-DES-CBC-SHA" }, + { "TLS_DHE_RSA_WITH_DES_CBC_SHA", "EDH-RSA-DES-CBC-SHA" }, + { "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "EDH-RSA-DES-CBC3-SHA" }, + { "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", "EXP-ADH-RC4-MD5" }, + { "TLS_DH_anon_WITH_RC4_128_MD5", "ADH-RC4-MD5" }, + { "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", "EXP-ADH-DES-CBC-SHA" }, + { "TLS_DH_anon_WITH_DES_CBC_SHA", "ADH-DES-CBC-SHA" }, + { "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", "ADH-DES-CBC3-SHA" }, + { "TLS_KRB5_WITH_DES_CBC_SHA", "KRB5-DES-CBC-SHA" }, + { "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", "KRB5-DES-CBC3-SHA" }, + { "TLS_KRB5_WITH_RC4_128_SHA", "KRB5-RC4-SHA" }, + { "TLS_KRB5_WITH_IDEA_CBC_SHA", "KRB5-IDEA-CBC-SHA" }, + { "TLS_KRB5_WITH_DES_CBC_MD5", "KRB5-DES-CBC-MD5" }, + { "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", "KRB5-DES-CBC3-MD5" }, + { "TLS_KRB5_WITH_RC4_128_MD5", "KRB5-RC4-MD5" }, + { "TLS_KRB5_WITH_IDEA_CBC_MD5", "KRB5-IDEA-CBC-MD5" }, + { "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "EXP-KRB5-DES-CBC-SHA" }, + { "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", "EXP-KRB5-RC2-CBC-SHA" }, + { "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", "EXP-KRB5-RC4-SHA" }, + { "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", "EXP-KRB5-DES-CBC-MD5" }, + { "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-KRB5-RC2-CBC-MD5" }, + { "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "EXP-KRB5-RC4-MD5" }, + { "TLS_PSK_WITH_NULL_SHA", "PSK-NULL-SHA" }, + { "TLS_DHE_PSK_WITH_NULL_SHA", "DHE-PSK-NULL-SHA" }, + { "TLS_RSA_PSK_WITH_NULL_SHA", "RSA-PSK-NULL-SHA" }, + { "TLS_RSA_WITH_AES_128_CBC_SHA", "AES128-SHA" }, + { "TLS_DH_DSS_WITH_AES_128_CBC_SHA", "DH-DSS-AES128-SHA" }, + { "TLS_DH_RSA_WITH_AES_128_CBC_SHA", "DH-RSA-AES128-SHA" }, + { "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "DHE-DSS-AES128-SHA" }, + { "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "DHE-RSA-AES128-SHA" }, + { "TLS_DH_anon_WITH_AES_128_CBC_SHA", "ADH-AES128-SHA" }, + { "TLS_RSA_WITH_AES_256_CBC_SHA", "AES256-SHA" }, + { "TLS_DH_DSS_WITH_AES_256_CBC_SHA", "DH-DSS-AES256-SHA" }, + { "TLS_DH_RSA_WITH_AES_256_CBC_SHA", "DH-RSA-AES256-SHA" }, + { "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "DHE-DSS-AES256-SHA" }, + { "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "DHE-RSA-AES256-SHA" }, + { "TLS_DH_anon_WITH_AES_256_CBC_SHA", "ADH-AES256-SHA" }, + { "TLS_RSA_WITH_NULL_SHA256", "NULL-SHA256" }, + { "TLS_RSA_WITH_AES_128_CBC_SHA256", "AES128-SHA256" }, + { "TLS_RSA_WITH_AES_256_CBC_SHA256", "AES256-SHA256" }, + { "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", "DH-DSS-AES128-SHA256" }, + { "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", "DH-RSA-AES128-SHA256" }, + { "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "DHE-DSS-AES128-SHA256" }, + { "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", "CAMELLIA128-SHA" }, + { "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", "DH-DSS-CAMELLIA128-SHA" }, + { "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", "DH-RSA-CAMELLIA128-SHA" }, + { "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", "DHE-DSS-CAMELLIA128-SHA" }, + { "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", "DHE-RSA-CAMELLIA128-SHA" }, + { "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", "ADH-CAMELLIA128-SHA" }, + { "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5", "EXP1024-RC4-MD5" }, + { "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5", "EXP1024-RC2-CBC-MD5" }, + { "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA", "EXP1024-DES-CBC-SHA" }, + { "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", "EXP1024-DHE-DSS-DES-CBC-SHA" }, + { "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA", "EXP1024-RC4-SHA" }, + { "TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", "EXP1024-DHE-DSS-RC4-SHA" }, + { "TLS_DHE_DSS_WITH_RC4_128_SHA", "DHE-DSS-RC4-SHA" }, + { "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "DHE-RSA-AES128-SHA256" }, + { "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", "DH-DSS-AES256-SHA256" }, + { "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", "DH-RSA-AES256-SHA256" }, + { "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "DHE-DSS-AES256-SHA256" }, + { "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "DHE-RSA-AES256-SHA256" }, + { "TLS_DH_anon_WITH_AES_128_CBC_SHA256", "ADH-AES128-SHA256" }, + { "TLS_DH_anon_WITH_AES_256_CBC_SHA256", "ADH-AES256-SHA256" }, + { "TLS_GOSTR341094_WITH_28147_CNT_IMIT", "GOST94-GOST89-GOST89" }, + { "TLS_GOSTR341001_WITH_28147_CNT_IMIT", "GOST2001-GOST89-GOST89" }, + { "TLS_GOSTR341001_WITH_NULL_GOSTR3411", "GOST94-NULL-GOST94" }, + { "TLS_GOSTR341094_WITH_NULL_GOSTR3411", "GOST2001-GOST89-GOST89" }, + { "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", "CAMELLIA256-SHA" }, + { "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", "DH-DSS-CAMELLIA256-SHA" }, + { "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", "DH-RSA-CAMELLIA256-SHA" }, + { "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", "DHE-DSS-CAMELLIA256-SHA" }, + { "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", "DHE-RSA-CAMELLIA256-SHA" }, + { "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", "ADH-CAMELLIA256-SHA" }, + { "TLS_PSK_WITH_RC4_128_SHA", "PSK-RC4-SHA" }, + { "TLS_PSK_WITH_3DES_EDE_CBC_SHA", "PSK-3DES-EDE-CBC-SHA" }, + { "TLS_PSK_WITH_AES_128_CBC_SHA", "PSK-AES128-CBC-SHA" }, + { "TLS_PSK_WITH_AES_256_CBC_SHA", "PSK-AES256-CBC-SHA" }, + { "TLS_RSA_WITH_SEED_CBC_SHA", "SEED-SHA" }, + { "TLS_DH_DSS_WITH_SEED_CBC_SHA", "DH-DSS-SEED-SHA" }, + { "TLS_DH_RSA_WITH_SEED_CBC_SHA", "DH-RSA-SEED-SHA" }, + { "TLS_DHE_DSS_WITH_SEED_CBC_SHA", "DHE-DSS-SEED-SHA" }, + { "TLS_DHE_RSA_WITH_SEED_CBC_SHA", "DHE-RSA-SEED-SHA" }, + { "TLS_DH_anon_WITH_SEED_CBC_SHA", "ADH-SEED-SHA" }, + { "TLS_RSA_WITH_AES_128_GCM_SHA256", "AES128-GCM-SHA256" }, + { "TLS_RSA_WITH_AES_256_GCM_SHA384", "AES256-GCM-SHA384" }, + { "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "DHE-RSA-AES128-GCM-SHA256" }, + { "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "DHE-RSA-AES256-GCM-SHA384" }, + { "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", "DH-RSA-AES128-GCM-SHA256" }, + { "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", "DH-RSA-AES256-GCM-SHA384" }, + { "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "DHE-DSS-AES128-GCM-SHA256" }, + { "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "DHE-DSS-AES256-GCM-SHA384" }, + { "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", "DH-DSS-AES128-GCM-SHA256" }, + { "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", "DH-DSS-AES256-GCM-SHA384" }, + { "TLS_DH_anon_WITH_AES_128_GCM_SHA256", "ADH-AES128-GCM-SHA256" }, + { "TLS_DH_anon_WITH_AES_256_GCM_SHA384", "ADH-AES256-GCM-SHA384" }, + { "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", "CAMELLIA128-SHA256" }, + { "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", "DH-DSS-CAMELLIA128-SHA256" }, + { "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", "DH-RSA-CAMELLIA128-SHA256" }, + { "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", "DHE-DSS-CAMELLIA128-SHA256" }, + { "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", "DHE-RSA-CAMELLIA128-SHA256" }, + { "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", "ADH-CAMELLIA128-SHA256" }, + { "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", "TLS_FALLBACK_SCSV" }, + { "TLS_ECDH_ECDSA_WITH_NULL_SHA", "ECDH-ECDSA-NULL-SHA" }, + { "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "ECDH-ECDSA-RC4-SHA" }, + { "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDH-ECDSA-DES-CBC3-SHA" }, + { "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "ECDH-ECDSA-AES128-SHA" }, + { "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "ECDH-ECDSA-AES256-SHA" }, + { "TLS_ECDHE_ECDSA_WITH_NULL_SHA", "ECDHE-ECDSA-NULL-SHA" }, + { "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "ECDHE-ECDSA-RC4-SHA" }, + { "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-ECDSA-DES-CBC3-SHA" }, + { "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDHE-ECDSA-AES128-SHA" }, + { "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDHE-ECDSA-AES256-SHA" }, + { "TLS_ECDH_RSA_WITH_NULL_SHA", "ECDH-RSA-NULL-SHA" }, + { "TLS_ECDH_RSA_WITH_RC4_128_SHA", "ECDH-RSA-RC4-SHA" }, + { "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "ECDH-RSA-DES-CBC3-SHA" }, + { "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "ECDH-RSA-AES128-SHA" }, + { "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "ECDH-RSA-AES256-SHA" }, + { "TLS_ECDHE_RSA_WITH_NULL_SHA", "ECDHE-RSA-NULL-SHA" }, + { "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "ECDHE-RSA-RC4-SHA" }, + { "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-RSA-DES-CBC3-SHA" }, + { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "ECDHE-RSA-AES128-SHA" }, + { "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "ECDHE-RSA-AES256-SHA" }, + { "TLS_ECDH_anon_WITH_NULL_SHA", "AECDH-NULL-SHA" }, + { "TLS_ECDH_anon_WITH_RC4_128_SHA", "AECDH-RC4-SHA" }, + { "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", "AECDH-DES-CBC3-SHA" }, + { "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", "AECDH-AES128-SHA" }, + { "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", "AECDH-AES256-SHA" }, + { "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", "SRP-3DES-EDE-CBC-SHA" }, + { "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", "SRP-RSA-3DES-EDE-CBC-SHA" }, + { "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", "SRP-DSS-3DES-EDE-CBC-SHA" }, + { "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", "SRP-AES-128-CBC-SHA" }, + { "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", "SRP-RSA-AES-128-CBC-SHA" }, + { "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", "SRP-DSS-AES-128-CBC-SHA" }, + { "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", "SRP-AES-256-CBC-SHA" }, + { "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", "SRP-RSA-AES-256-CBC-SHA" }, + { "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", "SRP-DSS-AES-256-CBC-SHA" }, + { "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "ECDHE-ECDSA-AES128-SHA256" }, + { "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "ECDHE-ECDSA-AES256-SHA384" }, + { "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "ECDH-ECDSA-AES128-SHA256" }, + { "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "ECDH-ECDSA-AES256-SHA384" }, + { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "ECDHE-RSA-AES128-SHA256" }, + { "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "ECDHE-RSA-AES256-SHA384" }, + { "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "ECDH-RSA-AES128-SHA256" }, + { "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "ECDH-RSA-AES256-SHA384" }, + { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256" }, + { "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "ECDHE-ECDSA-AES256-GCM-SHA384" }, + { "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "ECDH-ECDSA-AES128-GCM-SHA256" }, + { "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "ECDH-ECDSA-AES256-GCM-SHA384" }, + { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "ECDHE-RSA-AES128-GCM-SHA256" }, + { "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "ECDHE-RSA-AES256-GCM-SHA384" }, + { "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "ECDH-RSA-AES128-GCM-SHA256" }, + { "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "ECDH-RSA-AES256-GCM-SHA384" }, + { "TLS_ECDHE_PSK_WITH_RC4_128_SHA", "ECDHE-PSK-RC4-SHA" }, + { "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", "ECDHE-PSK-3DES-EDE-CBC-SHA" }, + { "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", "ECDHE-PSK-AES128-CBC-SHA" }, + { "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", "ECDHE-PSK-AES256-CBC-SHA" }, + { "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", "ECDHE-PSK-AES128-CBC-SHA256" }, + { "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", "ECDHE-PSK-AES256-CBC-SHA384" }, + { "TLS_ECDHE_PSK_WITH_NULL_SHA", "ECDHE-PSK-NULL-SHA" }, + { "TLS_ECDHE_PSK_WITH_NULL_SHA256", "ECDHE-PSK-NULL-SHA256" }, + { "TLS_ECDHE_PSK_WITH_NULL_SHA384", "ECDHE-PSK-NULL-SHA384" }, + { "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", "ECDHE-ECDSA-CAMELLIA128-SHA256" }, + { "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", "ECDHE-ECDSA-CAMELLIA256-SHA38" }, + { "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", "ECDH-ECDSA-CAMELLIA128-SHA256" }, + { "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", "ECDH-ECDSA-CAMELLIA256-SHA384" }, + { "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", "ECDHE-RSA-CAMELLIA128-SHA256" }, + { "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", "ECDHE-RSA-CAMELLIA256-SHA384" }, + { "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", "ECDH-RSA-CAMELLIA128-SHA256" }, + { "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", "ECDH-RSA-CAMELLIA256-SHA384" }, + { "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", "PSK-CAMELLIA128-SHA256" }, + { "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", "PSK-CAMELLIA256-SHA384" }, + { "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", "DHE-PSK-CAMELLIA128-SHA256" }, + { "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", "DHE-PSK-CAMELLIA256-SHA384" }, + { "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", "RSA-PSK-CAMELLIA128-SHA256" }, + { "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", "RSA-PSK-CAMELLIA256-SHA384" }, + { "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", "ECDHE-PSK-CAMELLIA128-SHA256" }, + { "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", "ECDHE-PSK-CAMELLIA256-SHA384" }, + { "TLS_RSA_WITH_AES_128_CCM", "AES128-CCM" }, + { "TLS_RSA_WITH_AES_256_CCM", "AES256-CCM" }, + { "TLS_DHE_RSA_WITH_AES_128_CCM", "DHE-RSA-AES128-CCM" }, + { "TLS_DHE_RSA_WITH_AES_256_CCM", "DHE-RSA-AES256-CCM" }, + { "TLS_RSA_WITH_AES_128_CCM_8", "AES128-CCM8" }, + { "TLS_RSA_WITH_AES_256_CCM_8", "AES256-CCM8" }, + { "TLS_DHE_RSA_WITH_AES_128_CCM_8", "DHE-RSA-AES128-CCM8" }, + { "TLS_DHE_RSA_WITH_AES_256_CCM_8", "DHE-RSA-AES256-CCM8" }, + { "TLS_PSK_WITH_AES_128_CCM", "PSK-AES128-CCM" }, + { "TLS_PSK_WITH_AES_256_CCM", "PSK-AES256-CCM" }, + { "TLS_DHE_PSK_WITH_AES_128_CCM", "DHE-PSK-AES128-CCM" }, + { "TLS_DHE_PSK_WITH_AES_256_CCM", "DHE-PSK-AES256-CCM" }, + { "TLS_PSK_WITH_AES_128_CCM_8", "PSK-AES128-CCM8" }, + { "TLS_PSK_WITH_AES_256_CCM_8", "PSK-AES256-CCM8" }, + { "TLS_PSK_DHE_WITH_AES_128_CCM_8", "DHE-PSK-AES128-CCM8" }, + { "TLS_PSK_DHE_WITH_AES_256_CCM_8", "DHE-PSK-AES256-CCM8" }, + { "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", "ECDHE-ECDSA-AES128-CCM" }, + { "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", "ECDHE-ECDSA-AES256-CCM" }, + { "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", "ECDHE-ECDSA-AES128-CCM8" }, + { "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", "ECDHE-ECDSA-AES256-CCM8" }, + { "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD", "ECDHE-RSA-CHACHA20-POLY1305-OLD" }, + { "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD", "ECDHE-ECDSA-CHACHA20-POLY1305-OLD" }, + { "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD", "DHE-RSA-CHACHA20-POLY1305-OLD" }, + { "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-RSA-CHACHA20-POLY1305" }, + { "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-ECDSA-CHACHA20-POLY1305" }, + { "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "DHE-RSA-CHACHA20-POLY1305" }, + { "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", "PSK-CHACHA20-POLY1305" }, + { "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-PSK-CHACHA20-POLY1305" }, + { "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "DHE-PSK-CHACHA20-POLY1305" }, + { "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", "RSA-PSK-CHACHA20-POLY1305" }, + { "TLS_GOSTR341094_RSA_WITH_28147_CNT_MD5", "GOST-MD5" }, + { "TLS_RSA_WITH_28147_CNT_GOST94", "GOST-GOST94" }, + { "SSL_CK_RC4_128_WITH_MD5", "RC4-MD5" }, + { "SSL_CK_RC4_128_EXPORT40_WITH_MD5", "EXP-RC4-MD5" }, + { "SSL_CK_RC2_128_CBC_WITH_MD5", "RC2-CBC-MD5" }, + { "SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5", "EXP-RC2-CBC-MD5" }, + { "SSL_CK_IDEA_128_CBC_WITH_MD5", "IDEA-CBC-MD5" }, + { "SSL_CK_DES_64_CBC_WITH_MD5", "DES-CBC-MD5" }, + { "SSL_CK_DES_64_CBC_WITH_SHA", "DES-CBC-SHA" }, + { "SSL_CK_DES_192_EDE3_CBC_WITH_MD5", "DES-CBC3-MD5" }, + { "SSL_CK_DES_192_EDE3_CBC_WITH_SHA", "DES-CBC3-SHA" }, + { "SSL_CK_RC4_64_WITH_MD5", "RC4-64-MD5" }, + { "SSL_CK_DES_64_CFB64_WITH_MD5_1", "DES-CFB-M1" }, + { "SSL_CK_NULL", "NULL" }, +}; + + +std::string iana_2_ossl_names(const char *str) { + std::string result {str}; + + for (auto const &mapping : IANA_2_OSSL_NAMES) { + std::string::size_type i {0}; + while ((i = result.find(mapping.iana, i)) != std::string::npos) { + result.replace(i, strlen(mapping.iana), mapping.ossl); + i += strlen(mapping.ossl); + } + } + + return result; +} diff --git a/bssl-compat/source/iana_2_ossl_names.h b/bssl-compat/source/iana_2_ossl_names.h new file mode 100644 index 00000000000..fa4d3874c8d --- /dev/null +++ b/bssl-compat/source/iana_2_ossl_names.h @@ -0,0 +1,13 @@ +#ifndef _IANA_2_OSSL_NAMES_H_ +#define _IANA_2_OSSL_NAMES_H_ + +#include + + +/** + * Replaces all IANA cipher suite names with the equivalent OpenSSL names. + * Anything that is not recognised as an IANA name is left unchanged. + */ +std::string iana_2_ossl_names(const char *str); + +#endif //IANA_2_OSSL_NAMES_H_ diff --git a/bssl-compat/source/internal.h b/bssl-compat/source/internal.h new file mode 100644 index 00000000000..ec1f3a4f6dc --- /dev/null +++ b/bssl-compat/source/internal.h @@ -0,0 +1,6 @@ +#ifndef _BSSL_COMPAT_INTERNAL_H_ +#define _BSSL_COMPAT_INTERNAL_H_ + +const char *TLS_VERSION_to_string(int version); + +#endif // _BSSL_COMPAT_INTERNAL_H_ diff --git a/bssl-compat/source/log.c b/bssl-compat/source/log.c new file mode 100644 index 00000000000..871b9ee0d40 --- /dev/null +++ b/bssl-compat/source/log.c @@ -0,0 +1,18 @@ +/* Placeholder for a proper logging implementation */ +#include "log.h" +#include +#include +#include + + +void bssl_compat_log(int level, const char *file, int line, const char *fmt, ...) { + fprintf(stderr, "%s:%d ", file, line); + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + if (level == BSSL_COMPAT_LOG_FATAL) { + exit(-1); + } +} diff --git a/bssl-compat/source/log.h b/bssl-compat/source/log.h new file mode 100644 index 00000000000..1f2180047fd --- /dev/null +++ b/bssl-compat/source/log.h @@ -0,0 +1,29 @@ +/* Placeholder for a proper logging implementation */ +#ifndef _BSSL_COMPAT_LOG_H_ +#define _BSSL_COMPAT_LOG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + BSSL_COMPAT_LOG_DEBUG, + BSSL_COMPAT_LOG_INFO, + BSSL_COMPAT_LOG_WARN, + BSSL_COMPAT_LOG_ERROR, + BSSL_COMPAT_LOG_FATAL +}; + +void bssl_compat_log(int level, const char *file, int line, const char *fmt, ...); + +#define bssl_compat_debug(...) bssl_compat_log(BSSL_COMPAT_LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__) +#define bssl_compat_info(...) bssl_compat_log(BSSL_COMPAT_LOG_INFO, __FILE__, __LINE__, __VA_ARGS__) +#define bssl_compat_warn(...) bssl_compat_log(BSSL_COMPAT_LOG_WARN, __FILE__, __LINE__, __VA_ARGS__) +#define bssl_compat_error(...) bssl_compat_log(BSSL_COMPAT_LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__) +#define bssl_compat_fatal(...) bssl_compat_log(BSSL_COMPAT_LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bssl-compat/source/ossl_dlutil.c b/bssl-compat/source/ossl_dlutil.c new file mode 100755 index 00000000000..c9f485b3df3 --- /dev/null +++ b/bssl-compat/source/ossl_dlutil.c @@ -0,0 +1,123 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include "log.h" +#include "ossl_dlutil.h" + + +static void *libcrypto; +static void *libssl; + + +void ossl_dlopen(int expected_major, int expected_minor) { + // First, a sanity check to see if OpenSSL shared libs are already linked in. + // They shouldn't be, but it can easily happen (and has) if there's a bazel + // change that causes them to be a proper link dependency, rather than just a + // data dependency. We check by looking up a symbol that we know is only in + // OpenSSL's libcrypto.so, and therefore shouldn't be loaded yet. + if (dlsym(RTLD_DEFAULT, "OPENSSL_version_major") != NULL) { + bssl_compat_error("libcrypto.so is already linked in\n"); + exit(ELIBACC); + } + + char libcrypto_path[PATH_MAX]; + char libssl_path[PATH_MAX]; + + snprintf(libcrypto_path, sizeof(libcrypto_path), "libcrypto.so.%d", expected_major); + snprintf(libssl_path, sizeof(libssl_path), "libssl.so.%d", expected_major); + + // If we are running in a bazel test environment (as indicated by the presence + // of the RUNFILES_DIR & TEST_WORKSPACE environment variables) then we need to + // load the shared libraries from the bazel runfiles directory, which will + // contain the correct OpenSSL libraries, built and placed there by bazel. We + // do this by passing absolute paths to dlopen() based on those env vars. + const char* runfiles_dir = getenv("RUNFILES_DIR"); + const char* test_workspace = getenv("TEST_WORKSPACE"); + if (runfiles_dir && test_workspace) { + char ossl_path[PATH_MAX]; + char temp_path[PATH_MAX]; + + // Prefix libcrypto_path and libssl_path with the absolute path to the + // OpenSSL shared library directory under bazel's runfiles directory. + snprintf(ossl_path, sizeof(ossl_path), "%s/%s/external/openssl/openssl/lib", + runfiles_dir, test_workspace); + strcpy(temp_path, libcrypto_path); + snprintf(libcrypto_path, sizeof(libcrypto_path), "%s/%s", ossl_path, temp_path); + + strcpy(temp_path, libssl_path); + snprintf(libssl_path, sizeof(libssl_path), "%s/%s", ossl_path, temp_path); + + // When running under bazel, we also need to set the OPENSSL_MODULES + // environment variable, so that OpenSSL can find its modules at runtime, + // This is needed by some tests that load the legacy provider. + char ossl_modules_path[PATH_MAX]; + snprintf(ossl_modules_path, sizeof(ossl_modules_path), "%s/ossl-modules", ossl_path); + setenv("OPENSSL_MODULES", ossl_modules_path, 1); + } + + // Load libcrypto.so first, because libssl.so depends on it. + if ((libcrypto = dlopen(libcrypto_path, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND)) == NULL) { + bssl_compat_error("dlopen(%s) : %s\n", libcrypto_path, dlerror()); + exit(ELIBACC); + } + + // Load libssl.so second, so that its dependency on libcrypto.so is resolved. + if ((libssl = dlopen(libssl_path, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND)) == NULL) { + bssl_compat_error("dlopen(%s) : %s\n", libssl_path, dlerror()); + exit(ELIBACC); + } + + // Now check the OpenSSL version of the loaded libraries to ensure they match + // what we expect to load i.e. the version we were built against. We do this + // by looking up and then invoking the OpenSSL_version_num() function from the + // libcrypto.so that we just loaded. + void *OpenSSL_version_num_fp = dlsym(libcrypto,"OpenSSL_version_num"); + if (OpenSSL_version_num_fp == NULL) { + bssl_compat_error("dlsym(libcrypto, \"OpenSSL_version_num\") : %s\n", dlerror()); + exit(ELIBACC); + } + + // Call the loaded OpenSSL_version_num() function to get the version number + unsigned long loaded_version = ((unsigned long (*)())OpenSSL_version_num_fp)(); + int loaded_major = (loaded_version & 0xF0000000) >> 28; + int loaded_minor = (loaded_version & 0x0FF00000) >> 20; + int loaded_patch = (loaded_version & 0x00000FF0) >> 4; + + // Check the loaded version against the expected version. We require an exact + // match on major version, and at least the expected minor version. + if ((loaded_major != expected_major) || (loaded_minor < expected_minor)) { + bssl_compat_error("Expecting to load OpenSSL version at least %d.%d.x but got %d.%d.%d\n", + expected_major, expected_minor, loaded_major, loaded_minor, loaded_patch); + exit(ELIBACC); + } +} + +void ossl_dlclose() { + if (libssl) { + dlclose(libssl); + libssl = NULL; + } + if (libcrypto) { + dlclose(libcrypto); + libcrypto = NULL; + } +} + +void *ossl_dlsym(const char *symbol) { + void *result; + const char *s = symbol + 5; + + if ((result = dlsym(libcrypto, s)) != NULL) { + return result; + } + + if((result = dlsym(libssl, s)) != NULL) { + return result; + } + + return NULL; +} diff --git a/bssl-compat/source/ossl_dlutil.h b/bssl-compat/source/ossl_dlutil.h new file mode 100755 index 00000000000..15c42334596 --- /dev/null +++ b/bssl-compat/source/ossl_dlutil.h @@ -0,0 +1,44 @@ +#ifndef _OSSL_DLUTIL_H_ +#define _OSSL_DLUTIL_H_ + +/** + * @brief Dynamically loads OpenSSL shared libraries with environment-specific path resolution. + * + * This function is called by ossl_init() to load OpenSSL's libcrypto.so and libssl.so at runtime. + * It handles two different execution environments: + * + * 1. **Bazel build/test environment** (When RUNFILES_DIR & TEST_WORKSPACE are set): + * - OpenSSL libraries are built by Bazel and put in the runfiles directory as data dependencies + * - Libraries are loaded from: $RUNFILES_DIR/$TEST_WORKSPACE/external/openssl/openssl/lib/ + * - Ensures the tests always use the correct Bazel-built libs, rather than libs from elsewhere + * + * 2. **Production/system environment** (When RUNFILES_DIR & TEST_WORKSPACE are not set): + * - Standard dlopen() behavior with LD_LIBRARY_PATH search + * - Expects OpenSSL libraries to be available in system paths + * + * In both cases, we use RTLD_DEEPBIND to ensure symbols are resolved from the loaded OpenSSL + * library. Without this, bssl-compat will end up finding its own symbols instead of the loaded + * OpenSSL ones. + * + * @param major The expected OpenSSL major version number + * @param minor The expected OpenSSL minor version number + */ +void ossl_dlopen(int major, int minor); + +/** + * @brief Closes the OpenSSL shared libraries loaded by ossl_dlopen(). + */ +void ossl_dlclose(); + +/** + * @brief Looks up a symbol in the loaded OpenSSL shared libraries. + * + * This function searches for the given symbol name (with "ossl_" prefix stripped) + * in both the libcrypto and libssl libraries that were loaded by ossl_dlopen(). + * + * @param symbol The symbol name to look up (with "ossl_" prefix) + * @return void* Pointer to the symbol, or NULL if not found + */ +void *ossl_dlsym(const char *symbol); + +#endif // _OSSL_DLUTIL_H_ diff --git a/bssl-compat/source/override.cc b/bssl-compat/source/override.cc new file mode 100644 index 00000000000..482179179f6 --- /dev/null +++ b/bssl-compat/source/override.cc @@ -0,0 +1,20 @@ +#include "override.h" +#include + + +// OverrideResultBase specializations for + +template<> +int OverrideResultBase::index() { + return SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); +} + +template<> +void *OverrideResultBase::get_ex_data(const SSL *ssl, int index) { + return SSL_get_ex_data(const_cast(ssl), index); +} + +template<> +void OverrideResultBase::set_ex_data(const SSL *ssl, int index, void *data) { + SSL_set_ex_data(const_cast(ssl), index, data); +} \ No newline at end of file diff --git a/bssl-compat/source/override.h b/bssl-compat/source/override.h new file mode 100644 index 00000000000..9721a12aa14 --- /dev/null +++ b/bssl-compat/source/override.h @@ -0,0 +1,54 @@ +#ifndef _BSSL_COMPAT_OVERRIDE_H_ +#define _BSSL_COMPAT_OVERRIDE_H_ + +#include + + +struct OverrideResultBase { + template + static int index(); + + template + static void *get_ex_data(CTX ctx, int index); + + template + static void set_ex_data(CTX ctx, int index, void *data); +}; + + +template class OverrideResult; +template +class OverrideResult : private OverrideResultBase { + public: + + using ret_type = RET; + using ctx_type = typename std::tuple_element<0, std::tuple>::type; + + OverrideResult(ctx_type ctx, ret_type ret) : ctx_{ctx}, ret_{ret} { + set_ex_data(ctx_, index(), this); + } + + ~OverrideResult() { + set_ex_data(ctx_, index(), nullptr); + } + + static OverrideResult *get(ctx_type ctx) { + return reinterpret_cast*>(get_ex_data(ctx, index())); + } + + ret_type value() const { + return ret_; + } + + private: + + static int index() { + static int index = OverrideResultBase::index(); + return index; + } + + const ctx_type ctx_; + const ret_type ret_; +}; + +#endif // _BSSL_COMPAT_OVERRIDE_H_ diff --git a/bssl-compat/source/stack.c b/bssl-compat/source/stack.c new file mode 100644 index 00000000000..08656c6ff5b --- /dev/null +++ b/bssl-compat/source/stack.c @@ -0,0 +1,417 @@ +#include +#include + +/* + * In OpenSSL the stack type is ossl_OPENSSL_STACK*, and in BoringSSL the stack + * type is _STACK*. In both cases the types are effectively opaque so we can + * simply use the OpenSSL stack directly by just casting back and forth between + * it and the BoringSSL type. + * + * We do this by patching BoringSSL's so that it's _STACK + * type is redefined to be the underlying ossl_OPENSSL_STACK type from OpenSSL. + */ + + +/* + * BoringSSL + * ========= + * sk_deep_copy performs a copy of |sk| and of each of the non-NULL elements in + * |sk| by using |copy_func|. If an error occurs, |free_func| is used to free + * any copies already made and NULL is returned. + * + * OpenSSL + * ======= + * sk_TYPE_deep_copy() returns a new stack where each element has been copied + * or an empty stack if the passed stack is NULL. Copying is performed by the + * supplied copyfunc() and freeing by freefunc(). The function freefunc() is + * only called if an error occurs. + */ +_STACK *OPENSSL_sk_deep_copy(const _STACK *sk, + OPENSSL_sk_call_copy_func call_copy_func, + OPENSSL_sk_copy_func copy_func, + OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func) { + return ossl.ossl_OPENSSL_sk_deep_copy(sk, (ossl_OPENSSL_sk_copyfunc)copy_func, free_func); +} + +/* + * BoringSSL + * ========= + * sk_delete removes the pointer at index |where|, moving other elements down + * if needed. It returns the removed pointer, or NULL if |where| is out of + * range. + * + * OpenSSL + * ======= + * sk_TYPE_delete() deletes element i from sk. It returns the deleted element + * or NULL if i is out of range. + * It is not an error to call sk_TYPE_delete() on a NULL stack, empty stack, or + * with an invalid index. An error is not raised in these conditions. + * sk_TYPE_delete() returns pointer to the deleted element or NULL on error. + */ +void *OPENSSL_sk_delete(_STACK *sk, size_t where) { + return ossl.ossl_OPENSSL_sk_delete(sk, where); +} + +/* + * BoringSSL + * ========= + * sk_delete_ptr removes, at most, one instance of |p| from the stack based on + * pointer equality. If an instance of |p| is found then |p| is returned, + * otherwise it returns NULL. + * + * OpenSSL + * ======= + * sk_TYPE_delete_ptr() deletes element matching ptr from sk. It returns the + * deleted element or NULL if no element matching ptr was found. + */ +void *OPENSSL_sk_delete_ptr(_STACK *sk, const void *p) { + return ossl.ossl_OPENSSL_sk_delete_ptr(sk, p); +} + +/* + * BoringSSL + * ========= + * sk_dup performs a shallow copy of a stack and returns the new stack, or NULL + * on error. + * + * OpenSSL + * ======= + * sk_TYPE_dup() returns a shallow copy of sk or an empty stack if the passed + * stack is NULL. Note the pointers in the copy are identical to the original. + */ +_STACK *OPENSSL_sk_dup(const _STACK *sk) { + return ossl.ossl_OPENSSL_sk_dup(sk); +} + +/* + * BoringSSL + * ========= + * sk_find returns the first value in the stack equal to |p|. If a comparison + * function has been set on the stack, equality is defined by it, otherwise + * pointer equality is used. If the stack is sorted, then a binary search is + * used, otherwise a linear search is performed. If a matching element is + * found, its index is written to |*out_index| (if |out_index| is not NULL) and + * one is returned. Otherwise zero is returned. + * + * Note this differs from OpenSSL. The type signature is slightly different, + * and OpenSSL's sk_find will implicitly sort |sk| if it has a comparison + * function defined. + * + * OpenSSL + * ======= + * sk_TYPE_find() searches sk for the element ptr. In the case where no + * comparison function has been specified, the function performs a linear + * search for a pointer equal to ptr. The index of the first matching element + * is returned or -1 if there is no match. In the case where a comparison + * function has been specified, sk is sorted and sk_TYPE_find() returns the + * index of a matching element or -1 if there is no match. Note that, in this + * case the comparison function will usually compare the values pointed to + * rather than the pointers themselves and the order of elements in sk can + * change. + */ +int OPENSSL_sk_find(const _STACK *sk, size_t *out_index, const void *p, OPENSSL_sk_call_cmp_func call_cmp_func) { + (void)call_cmp_func; + + int idx = -1; + + // Find out if the stack is sorted. We have to do this before setting the + // compare function to NULL, because doing so makes the set not sorted, even + // if it was already sorted, and the elements are actually in sorted order. + int sorted = ossl.ossl_OPENSSL_sk_is_sorted(sk); + + if (sorted) { + // If the stack says it's sorted then it must have a compare function. In + // this case the OpenSSL call does the same as the BoringSSL call, so we + // just call it. + idx = ossl.ossl_OPENSSL_sk_find((_STACK*)sk, p); + } + else { + // The stack says that it's not sorted, in which case it may or may not have + // a compare function. + ossl_OPENSSL_sk_compfunc compfunc = ossl.ossl_OPENSSL_sk_set_cmp_func((_STACK*)sk, NULL); + + if (compfunc) { + // The stack is not sorted but it does have a compare function, in which + // case, OpenSSLs ossl.ossl_OPENSSL_sk_sort() call will first sort the stack + // and then perform the search. This is NOT the behaviour we want because + // BoringSSL never does a sort before find. Instead, if the stack is not + // sorted, BoringSSL does a linear search instead, leaving the order + // unchanged, so we must also do our own linear search, using the compare + // function that we've temporarily removed from the stack. + const int num = ossl.ossl_OPENSSL_sk_num(sk); + for (int i = 0; i < num; i++) { + void *value = ossl.ossl_OPENSSL_sk_value(sk, i); + if (compfunc(&value, &p) == 0) { + idx = i; + break; + } + } + + // Restore the compare function + ossl.ossl_OPENSSL_sk_set_cmp_func((_STACK*)sk, compfunc); + + // Unfortunately, restoring the compare function makes the stack not + // sorted, even if the elements are actually in sorted order. Therefore, + // if the stack was initially, we have to call ossl.ossl_OPENSSL_sk_sort() to + // "sort" it again. + if (sorted) { + ossl.ossl_OPENSSL_sk_sort((_STACK*)sk); + } + } + else { + // The stack is not sorted and has no compare function, in which case we + // can just call OpenSSL's ossl.ossl_OPENSSL_sk_find(). + idx = ossl.ossl_OPENSSL_sk_find((_STACK*)sk, p); + } + } + + if (idx == -1) { + return 0; + } + + if (out_index) { + *out_index = idx; + } + + return 1; +} + +/* + * BoringSSL + * ========= + * sk_free frees the given stack and array of pointers, but does nothing to + * free the individual elements. + * + * OpenSSL + * ======= + * sk_TYPE_free() frees up the sk structure. It does not free up any elements + * of sk. After this call sk is no longer valid. + */ +void sk_free(_STACK *sk) { + ossl.ossl_OPENSSL_sk_free(sk); +} + + +/* + * BoringSSL + * ========= + * sk_insert inserts |p| into the stack at index |where|, moving existing + * elements if needed. It returns the length of the new stack, or zero on + * error. + * + * OpenSSL + * ======= + * sk_TYPE_insert() inserts ptr into sk at position idx. Any existing elements + * at or after idx are moved downwards. If idx is out of range the new element + * is appended to sk. sk_TYPE_insert() either returns the number of elements in + * sk after the new element is inserted or zero if an error (such as memory + * allocation failure) occurred. + */ +size_t OPENSSL_sk_insert(_STACK *sk, void *p, size_t where) { + return ossl.ossl_OPENSSL_sk_insert(sk, p, where); +} + +/* + * BoringSSL + * ========= + * sk_is_sorted returns one if |sk| is known to be sorted and zero otherwise. + * + * OpenSSL + * ======= + * sk_TYPE_is_sorted() returns 1 if sk is sorted and 0 otherwise + */ +int OPENSSL_sk_is_sorted(const _STACK *sk) { + int sorted = ossl.ossl_OPENSSL_sk_is_sorted(sk); + + if (!sorted) { + // BoringSSL also considers a stack to be sorted if + // it has a comparison function and a size of 0 or 1 + ossl_OPENSSL_sk_compfunc compfunc = ossl.ossl_OPENSSL_sk_set_cmp_func((_STACK*)sk, NULL); + if (compfunc) { + sorted = (sk_num(sk) < 2); + ossl.ossl_OPENSSL_sk_set_cmp_func((_STACK*)sk, compfunc); + } + } + + return sorted; +} + +/* + * BoringSSL + * ========= + * sk_num returns the number of elements in |s|. + * + * OpenSSL + * ======= + * sk_TYPE_num() returns the number of elements in sk or -1 if sk is NULL. + */ +size_t sk_num(const _STACK *sk) { + int ret = ossl.ossl_OPENSSL_sk_num(sk); + return (ret == -1) ? 0 : ret; +} + +/* + * BoringSSL + * ========= + * sk_new creates a new, empty stack with the given comparison function, which + * may be zero. It returns the new stack or NULL on allocation failure. + * + * OpenSSL + * ======= + * sk_TYPE_new() allocates a new empty stack using comparison function compare. + * If compare is NULL then no comparison function is used. This function is + * equivalent to sk_TYPE_new_reserve(compare, 0). sk_TYPE_new() return an + * empty stack or NULL if an error occurs. + */ +_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp) { + return ossl.ossl_OPENSSL_sk_new((ossl_OPENSSL_sk_compfunc)comp); +} + +/* + * BoringSSL + * ========= + * sk_new_null creates a new, empty stack. It returns the new stack or NULL on + * allocation failure. + * + * OpenSSL + * ======= + * sk_TYPE_new_null() allocates a new empty stack with no comparison function. + * This function is equivalent to sk_TYPE_new_reserve(NULL, 0). + */ +_STACK *sk_new_null(void) { + return ossl.ossl_OPENSSL_sk_new_null(); +} + +/* + * BoringSSL + * ========= + * sk_pop returns and removes the last element on the stack, or NULL if the + * stack is empty. + * + * OpenSSL + * ======= + * sk_TYPE_pop() returns and removes the last element from sk. + */ +void *sk_pop(_STACK *sk) { + return ossl.ossl_OPENSSL_sk_pop(sk); +} + +/* + * BoringSSL + * ========= + * sk_pop_free_ex calls |free_func| on each element in the stack and then frees + * the stack itself. Note this corresponds to |sk_FOO_pop_free|. It is named + * |sk_pop_free_ex| as a workaround for existing code calling an older version + * of |sk_pop_free|. + * + * OpenSSL + * ======= + * sk_TYPE_pop_free() frees up all elements of sk and sk itself. The free + * function freefunc() is called on each element to free it. + */ +OPENSSL_EXPORT void OPENSSL_sk_pop_free_ex(_STACK *sk, + OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func) { + (void)call_free_func; + ossl.ossl_OPENSSL_sk_pop_free(sk, free_func); +} + +/* + * BoringSSL + * ========= + * sk_push appends |p| to the stack and returns the length of the new stack, or + * 0 on allocation failure. + * + * OpenSSL + * ======= + * sk_TYPE_push() appends ptr to sk. + * sk_TYPE_push() further returns -1 if sk is NULL. + */ +size_t sk_push(_STACK *sk, void *p) { + int ret = ossl.ossl_OPENSSL_sk_push(sk, p); + return (ret == -1) ? 0 : ret; +} + +/* + * BoringSSL + * ========= + * sk_set_cmp_func sets the comparison function to be used by |sk| and returns + * the previous one. + * + * OpenSSL + * ======= + * sk_TYPE_set_cmp_func() sets the comparison function of sk to compare. The + * previous comparison function is returned or NULL if there was no previous + * comparison function. + */ +OPENSSL_sk_cmp_func OPENSSL_sk_set_cmp_func(_STACK *sk, OPENSSL_sk_cmp_func comp) { + return (OPENSSL_sk_cmp_func)ossl.ossl_OPENSSL_sk_set_cmp_func(sk, (ossl_OPENSSL_sk_compfunc)comp); +} + +/* + * BoringSSL + * ========= + * sk_shift removes and returns the first element in the stack, or returns NULL + * if the stack is empty. + * + * OpenSSL + * ======= + * sk_TYPE_shift() returns and removes the first element from sk. + * It is not an error to call sk_TYPE_shift() on a NULL stack, empty stack, or + * with an invalid index. An error is not raised in these conditions. + * sk_TYPE_shift() return a pointer to the deleted element or NULL on error. + */ +void *OPENSSL_sk_shift(_STACK *sk) { + return ossl.ossl_OPENSSL_sk_shift(sk); +} + +/* + * BoringSSL + * ========= + * sk_sort sorts the elements of |sk| into ascending order based on the + * comparison function. The stack maintains a |sorted| flag and sorting an + * already sorted stack is a no-op. + * + * OpenSSL + * ======= + * sk_TYPE_sort() sorts sk using the supplied comparison function. + */ +void OPENSSL_sk_sort(_STACK *sk, OPENSSL_sk_call_cmp_func call_cmp_func) { + (void)call_cmp_func; + ossl.ossl_OPENSSL_sk_sort(sk); +} + +/* + * BoringSSL + * ========= + * sk_value returns the |i|th pointer in |sk|, or NULL if |i| is out of range. + * + * OpenSSL + * ======= + * sk_TYPE_value() returns element idx in sk, where idx starts at zero. If idx + * is out of range then NULL is returned. It is not an error to call + * sk_TYPE_zero() on a NULL stack, empty stack, or with an invalid index. An + * error is not raised in these conditions. sk_TYPE_value() returns a pointer + * to a stack element or NULL if the index is out of range. + */ +void *sk_value(const _STACK *sk, size_t i) { + return ossl.ossl_OPENSSL_sk_value(sk, i); +} + +/* + * BoringSSL + * ========= + * sk_zero resets |sk| to the empty state but does nothing to free the + * individual elements themselves. + * + * OpenSSL + * ======= + * sk_TYPE_zero() sets the number of elements in sk to zero. It does not free + * sk so after this call sk is still valid. It is not an error to call + * sk_TYPE_zero() on a NULL stack, empty stack, or with an invalid index. An + * error is not raised in these conditions. + */ +void OPENSSL_sk_zero(_STACK *sk) { + ossl.ossl_OPENSSL_sk_zero(sk); +} diff --git a/bssl-compat/test/BUILD b/bssl-compat/test/BUILD new file mode 100644 index 00000000000..843d7070b2c --- /dev/null +++ b/bssl-compat/test/BUILD @@ -0,0 +1,115 @@ +load("@rules_cc//cc:defs.bzl", "cc_test") +load("//:bazel/rules.bzl", "patched_bssl_filegroup") + +licenses(["notice"]) # Apache 2 + +# Create rules for processing BoringSSL test files. This creates one genrule +# per test file, which copies that file from BoringSSL, applying any necessary +# patches. This also creates a filegroup called :patched_bssl_tests which +# contains all the resulting copied & patched test files. +patched_bssl_filegroup( + name = "patched_bssl_tests", + srcs = [ + "crypto/bio/bio_test.cc", + "crypto/digest/digest_test.cc", + "crypto/err/err_test.cc", + "crypto/hmac/hmac_test.cc", + "crypto/pkcs8/pkcs12_test.cc", + "crypto/rand/rand_test.cc", + "crypto/rsa/rsa_test.cc", + "crypto/stack/stack_test.cc", + "crypto/test/file_test_gtest.cc", + "crypto/test/file_test.cc", + "crypto/test/file_test.h", + "crypto/test/file_util.cc", + "crypto/test/file_util.h", + "crypto/test/test_data.cc", + "crypto/test/test_data.h", + "crypto/bcm_support.h", + "crypto/test/test_util.cc", + "crypto/test/test_util.h", + "crypto/x509/x509_test.cc", + "crypto/internal.h", + "ssl/ssl_c_test.c", + "ssl/ssl_test.cc", + ], +) + +filegroup( + name = "handwritten_tests", + srcs = [ + "test_asn1.cc", + "test_bn.cc", + "test_cipher.cc", + "test_crypto.cc", + "test_ec_key.cc", + "test_err.cc", + "test_evp.cc", + "test_hmac.cc", + "test_misc.cc", + "test_pem.cc", + "test_rsa.cc", + "test_sha256.cc", + "test_ssl.cc", + "test_stack.cc", + "test_x509.cc", + "test_x509v3.cc", + ] + glob([ + "certs/*.h", + ]), +) + +# Main unit test target for bssl-compat +# This test suite validates the bssl-compat layer by running both: +# 1. Hand-written tests that exercise the BoringSSL API mappings to OpenSSL +# 2. Selected BoringSSL tests to ensure compatibility +cc_test( + name = "utests-bssl-compat", + srcs = [ + "main.cc", + ":handwritten_tests", + ":patched_bssl_tests", + ], + data = [ + "@boringssl//:test_data" + ], + env = { + "BORINGSSL_TEST_DATA_ROOT" : "./external/boringssl" + }, + includes = [ + ".", + ], + deps = [ + "@bssl-compat//:ssl", + "@bssl-compat//:crypto", + "@com_google_googletest//:gtest", + ], + visibility = ["//visibility:public"], +) + +# The same unit tests as above, but linked against BoringSSL proper, rather than +# bssl-compat. This test acts as a sanity check, ensuring that the bssl-compat +# utests also pass when running them against the real BoringSSL. +cc_test( + name = "utests-boringssl", + srcs = [ + "main.cc", + ":handwritten_tests", + ":patched_bssl_tests", + ], + data = [ + "@boringssl//:test_data" + ], + env = { + "BORINGSSL_TEST_DATA_ROOT" : "./external/boringssl" + }, + includes = [ + ".", + ], + deps = [ + "@boringssl//:ssl", + "@boringssl//:crypto", + "@com_google_googletest//:gtest", + ], + visibility = ["//visibility:public"], +) diff --git a/bssl-compat/test/certs/certs.sh b/bssl-compat/test/certs/certs.sh new file mode 100755 index 00000000000..2dbe0c055b5 --- /dev/null +++ b/bssl-compat/test/certs/certs.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +set -e + +generate_ca() { # $1= $2=[issuer name] + local extra_args=() + if [[ -n "$2" ]]; then + extra_args=(-CA "${2}_cert.pem" -CAkey "${2}_key.pem" -CAcreateserial); + else + extra_args=(-signkey "${1}_key.pem"); + fi + openssl genrsa -out "${1}_key.pem" 2048 + openssl req -new -key "${1}_key.pem" -out "${1}_cert.csr" -config "${1}_cert.cfg" -batch -sha256 + openssl x509 -req -days 730 -in "${1}_cert.csr" -out "${1}_cert.pem" -extensions v3_ca -extfile "${1}_cert.cfg" "${extra_args[@]}" +} + +generate_rsa_key() { # $1= + openssl genrsa -out "${1}_key.pem" 2048 +} + +generate_x509_cert() { # $1= $2= $3=[days] + local days="${3:-730}" + openssl req -new -key "${1}_key.pem" -out "${1}_cert.csr" -config "${1}_cert.cfg" -batch -sha256 + openssl x509 -req -days "${days}" -in "${1}_cert.csr" -sha256 -CA "${2}_cert.pem" -CAkey "${2}_key.pem" -CAcreateserial -out "${1}_cert.pem" -extensions v3_ca -extfile "${1}_cert.cfg" +} + + +cd "$(dirname "$0")" + +generate_ca root_ca +generate_ca intermediate_ca_1 root_ca +generate_ca intermediate_ca_2 intermediate_ca_1 + +generate_rsa_key server_1 +generate_x509_cert server_1 root_ca + +generate_rsa_key server_2 +generate_x509_cert server_2 intermediate_ca_2 + +generate_rsa_key client_1 +generate_x509_cert client_1 root_ca + +generate_rsa_key client_2 +generate_x509_cert client_2 intermediate_ca_2 + +cat server_1_cert.pem root_ca_cert.pem > server_1_cert_chain.pem +cat client_1_cert.pem root_ca_cert.pem > client_1_cert_chain.pem +cat server_2_cert.pem intermediate_ca_2_cert.pem intermediate_ca_1_cert.pem root_ca_cert.pem > server_2_cert_chain.pem +cat client_2_cert.pem intermediate_ca_2_cert.pem intermediate_ca_1_cert.pem root_ca_cert.pem > client_2_cert_chain.pem + +for PEM in $(ls *.pem) +do + echo -n "static const char $(echo $PEM | sed 's/\./_/g')_str[] = R\"\"\"(" > $PEM.h + cat $PEM >> $PEM.h + echo ")\"\"\";" >> $PEM.h +done + +rm *.csr *.srl diff --git a/bssl-compat/test/certs/client_1_cert.cfg b/bssl-compat/test/certs/client_1_cert.cfg new file mode 100644 index 00000000000..7ace095d03f --- /dev/null +++ b/bssl-compat/test/certs/client_1_cert.cfg @@ -0,0 +1,39 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = GB +countryName_default = GB +stateOrProvinceName = Tyne and Wear +stateOrProvinceName_default = Tyne and Wear +localityName = Newcastle upon Tyne +localityName_default = Newcastle upon Tyne +organizationName = Red Hat +organizationName_default = Red Hat +organizationalUnitName = Red Hat Engineering +organizationalUnitName_default = Red Hat Engineering +commonName = Test Client 1 +commonName_default = Test Client 1 +commonName_max = 64 + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always + +[alt_names] +URI.1 = spiffe://redhat.com/test-client-1 +URI.2 = http://test-client-1.redhat.com +DNS.1 = redhat.com +DNS.2 = www.redhat.com diff --git a/bssl-compat/test/certs/client_1_cert.pem b/bssl-compat/test/certs/client_1_cert.pem new file mode 100644 index 00000000000..5bedccd7b4a --- /dev/null +++ b/bssl-compat/test/certs/client_1_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjjCCA3agAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5QwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBizELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFjAUBgNVBAMMDVRlc3QgQ2xpZW50IDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCucbnL68qjJwwJih6SvrPxsxu5ffIVoaIohu+xfSoK0oQX +YxtZKVLtM4Bac0ZPcjI6BGMCxHmQ69rHm531RfAm+2UrXXgElvUfchHIVI8vqzxE +0TmOOTtzbrGD+3TDzVYdX7F/AhXcjfVm/dGbTyVPWkzeSrEaIVVjxx+z8yRaIPov +jOFj47liT9LVUyqJF9TcXNHi1vPtDdNHTy7388vbGuoLl5F+e0ralQi/Gj8P7ddD +i16Nq5U6ZXl9YeHonr7lJG6MtaGD5KyVJqcF3St+wHfMYeXAW6VWfCPyGHRjWSvH +3lUYBQ+9C+wyXq8oXrhXd44gmJ76qBHHM2wGSFqtAgMBAAGjgegwgeUwDAYDVR0T +AQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMGkGA1UdEQRiMGCGIXNwaWZmZTovL3JlZGhhdC5jb20vdGVzdC1jbGllbnQt +MYYfaHR0cDovL3Rlc3QtY2xpZW50LTEucmVkaGF0LmNvbYIKcmVkaGF0LmNvbYIO +d3d3LnJlZGhhdC5jb20wHQYDVR0OBBYEFMtOlNy+vxPb1Li498LdA0I9XFuvMB8G +A1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3DQEBCwUAA4IB +AQBITaOy/OVug93Cr6SleJPTP4QZrfytSR0eF7hNjywyUDLB07+qBvPfwJLL0E5e +mBKjuC7r0ASMNKDFODFMwHcwK1Sw0Cx3xBGUJG8OzNAi0HV6eJaU09nrtEMdAZiH +9L4Gq2cpAosSTI5UYAh0D8i1ja+t4wwzzu+MM74gxLwyr7DnSTYQWL3RiNpHC1fd +FQhBs8MVPI1EcCB9/WYeeC4UFT/coNQI0apgozYoeDIyJlNREBYFcj7RppJpuXx5 +zFdhKG9faRjOumaMKOtfunAMk9kYqZz5cYnmVLr2SwphhHQo2ztJ/kn8NkMgmdLA +uwZAwiWgyVJDkCrlUP2N8Oa/ +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/client_1_cert.pem.h b/bssl-compat/test/certs/client_1_cert.pem.h new file mode 100644 index 00000000000..846aee56113 --- /dev/null +++ b/bssl-compat/test/certs/client_1_cert.pem.h @@ -0,0 +1,28 @@ +static const char client_1_cert_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEjjCCA3agAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5QwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBizELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFjAUBgNVBAMMDVRlc3QgQ2xpZW50IDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCucbnL68qjJwwJih6SvrPxsxu5ffIVoaIohu+xfSoK0oQX +YxtZKVLtM4Bac0ZPcjI6BGMCxHmQ69rHm531RfAm+2UrXXgElvUfchHIVI8vqzxE +0TmOOTtzbrGD+3TDzVYdX7F/AhXcjfVm/dGbTyVPWkzeSrEaIVVjxx+z8yRaIPov +jOFj47liT9LVUyqJF9TcXNHi1vPtDdNHTy7388vbGuoLl5F+e0ralQi/Gj8P7ddD +i16Nq5U6ZXl9YeHonr7lJG6MtaGD5KyVJqcF3St+wHfMYeXAW6VWfCPyGHRjWSvH +3lUYBQ+9C+wyXq8oXrhXd44gmJ76qBHHM2wGSFqtAgMBAAGjgegwgeUwDAYDVR0T +AQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMGkGA1UdEQRiMGCGIXNwaWZmZTovL3JlZGhhdC5jb20vdGVzdC1jbGllbnQt +MYYfaHR0cDovL3Rlc3QtY2xpZW50LTEucmVkaGF0LmNvbYIKcmVkaGF0LmNvbYIO +d3d3LnJlZGhhdC5jb20wHQYDVR0OBBYEFMtOlNy+vxPb1Li498LdA0I9XFuvMB8G +A1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3DQEBCwUAA4IB +AQBITaOy/OVug93Cr6SleJPTP4QZrfytSR0eF7hNjywyUDLB07+qBvPfwJLL0E5e +mBKjuC7r0ASMNKDFODFMwHcwK1Sw0Cx3xBGUJG8OzNAi0HV6eJaU09nrtEMdAZiH +9L4Gq2cpAosSTI5UYAh0D8i1ja+t4wwzzu+MM74gxLwyr7DnSTYQWL3RiNpHC1fd +FQhBs8MVPI1EcCB9/WYeeC4UFT/coNQI0apgozYoeDIyJlNREBYFcj7RppJpuXx5 +zFdhKG9faRjOumaMKOtfunAMk9kYqZz5cYnmVLr2SwphhHQo2ztJ/kn8NkMgmdLA +uwZAwiWgyVJDkCrlUP2N8Oa/ +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/client_1_cert_chain.pem b/bssl-compat/test/certs/client_1_cert_chain.pem new file mode 100644 index 00000000000..f4a407a3311 --- /dev/null +++ b/bssl-compat/test/certs/client_1_cert_chain.pem @@ -0,0 +1,51 @@ +-----BEGIN CERTIFICATE----- +MIIEjjCCA3agAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5QwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBizELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFjAUBgNVBAMMDVRlc3QgQ2xpZW50IDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCucbnL68qjJwwJih6SvrPxsxu5ffIVoaIohu+xfSoK0oQX +YxtZKVLtM4Bac0ZPcjI6BGMCxHmQ69rHm531RfAm+2UrXXgElvUfchHIVI8vqzxE +0TmOOTtzbrGD+3TDzVYdX7F/AhXcjfVm/dGbTyVPWkzeSrEaIVVjxx+z8yRaIPov +jOFj47liT9LVUyqJF9TcXNHi1vPtDdNHTy7388vbGuoLl5F+e0ralQi/Gj8P7ddD +i16Nq5U6ZXl9YeHonr7lJG6MtaGD5KyVJqcF3St+wHfMYeXAW6VWfCPyGHRjWSvH +3lUYBQ+9C+wyXq8oXrhXd44gmJ76qBHHM2wGSFqtAgMBAAGjgegwgeUwDAYDVR0T +AQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMGkGA1UdEQRiMGCGIXNwaWZmZTovL3JlZGhhdC5jb20vdGVzdC1jbGllbnQt +MYYfaHR0cDovL3Rlc3QtY2xpZW50LTEucmVkaGF0LmNvbYIKcmVkaGF0LmNvbYIO +d3d3LnJlZGhhdC5jb20wHQYDVR0OBBYEFMtOlNy+vxPb1Li498LdA0I9XFuvMB8G +A1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3DQEBCwUAA4IB +AQBITaOy/OVug93Cr6SleJPTP4QZrfytSR0eF7hNjywyUDLB07+qBvPfwJLL0E5e +mBKjuC7r0ASMNKDFODFMwHcwK1Sw0Cx3xBGUJG8OzNAi0HV6eJaU09nrtEMdAZiH +9L4Gq2cpAosSTI5UYAh0D8i1ja+t4wwzzu+MM74gxLwyr7DnSTYQWL3RiNpHC1fd +FQhBs8MVPI1EcCB9/WYeeC4UFT/coNQI0apgozYoeDIyJlNREBYFcj7RppJpuXx5 +zFdhKG9faRjOumaMKOtfunAMk9kYqZz5cYnmVLr2SwphhHQo2ztJ/kn8NkMgmdLA +uwZAwiWgyVJDkCrlUP2N8Oa/ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/client_1_cert_chain.pem.h b/bssl-compat/test/certs/client_1_cert_chain.pem.h new file mode 100644 index 00000000000..55329ec9eb2 --- /dev/null +++ b/bssl-compat/test/certs/client_1_cert_chain.pem.h @@ -0,0 +1,52 @@ +static const char client_1_cert_chain_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEjjCCA3agAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5QwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBizELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFjAUBgNVBAMMDVRlc3QgQ2xpZW50IDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCucbnL68qjJwwJih6SvrPxsxu5ffIVoaIohu+xfSoK0oQX +YxtZKVLtM4Bac0ZPcjI6BGMCxHmQ69rHm531RfAm+2UrXXgElvUfchHIVI8vqzxE +0TmOOTtzbrGD+3TDzVYdX7F/AhXcjfVm/dGbTyVPWkzeSrEaIVVjxx+z8yRaIPov +jOFj47liT9LVUyqJF9TcXNHi1vPtDdNHTy7388vbGuoLl5F+e0ralQi/Gj8P7ddD +i16Nq5U6ZXl9YeHonr7lJG6MtaGD5KyVJqcF3St+wHfMYeXAW6VWfCPyGHRjWSvH +3lUYBQ+9C+wyXq8oXrhXd44gmJ76qBHHM2wGSFqtAgMBAAGjgegwgeUwDAYDVR0T +AQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMGkGA1UdEQRiMGCGIXNwaWZmZTovL3JlZGhhdC5jb20vdGVzdC1jbGllbnQt +MYYfaHR0cDovL3Rlc3QtY2xpZW50LTEucmVkaGF0LmNvbYIKcmVkaGF0LmNvbYIO +d3d3LnJlZGhhdC5jb20wHQYDVR0OBBYEFMtOlNy+vxPb1Li498LdA0I9XFuvMB8G +A1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3DQEBCwUAA4IB +AQBITaOy/OVug93Cr6SleJPTP4QZrfytSR0eF7hNjywyUDLB07+qBvPfwJLL0E5e +mBKjuC7r0ASMNKDFODFMwHcwK1Sw0Cx3xBGUJG8OzNAi0HV6eJaU09nrtEMdAZiH +9L4Gq2cpAosSTI5UYAh0D8i1ja+t4wwzzu+MM74gxLwyr7DnSTYQWL3RiNpHC1fd +FQhBs8MVPI1EcCB9/WYeeC4UFT/coNQI0apgozYoeDIyJlNREBYFcj7RppJpuXx5 +zFdhKG9faRjOumaMKOtfunAMk9kYqZz5cYnmVLr2SwphhHQo2ztJ/kn8NkMgmdLA +uwZAwiWgyVJDkCrlUP2N8Oa/ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/client_1_key.pem b/bssl-compat/test/certs/client_1_key.pem new file mode 100644 index 00000000000..732b6d66abe --- /dev/null +++ b/bssl-compat/test/certs/client_1_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEArnG5y+vKoycMCYoekr6z8bMbuX3yFaGiKIbvsX0qCtKEF2Mb +WSlS7TOAWnNGT3IyOgRjAsR5kOvax5ud9UXwJvtlK114BJb1H3IRyFSPL6s8RNE5 +jjk7c26xg/t0w81WHV+xfwIV3I31Zv3Rm08lT1pM3kqxGiFVY8cfs/MkWiD6L4zh +Y+O5Yk/S1VMqiRfU3FzR4tbz7Q3TR08u9/PL2xrqC5eRfntK2pUIvxo/D+3XQ4te +jauVOmV5fWHh6J6+5SRujLWhg+SslSanBd0rfsB3zGHlwFulVnwj8hh0Y1krx95V +GAUPvQvsMl6vKF64V3eOIJie+qgRxzNsBkharQIDAQABAoIBAQCU+qc0kqEyiUxs +cTr/FELVbqOE3Rz8gFfeyK64JC7do0AQQSHAGdyqm0tI9B3eB6cBiXGNkYJI1ES6 +KBrUt/ALOrQCPwca1Flvi5nIPv8yNMl59D11S0eMo8KS9xOXjSu4VlteHsfQ3qPw +W2DBhOxWQsZXKe7qZAFq/0oCAurO1OVa+eob5g1zHVZtl0hokpapu/2FzoqPYGj0 +t3cwPZdl4TqYWqCF1JbKcqq7h/KtbLMbin6XEWKVrfxAVJYcPVCg/vSKDLQav+N+ +5Bc6uX6w2GDYxWCjHp9PEtikcdj2KFF2yWPSbfsNQz1qn+cmNiSPM4HM8urRpjPX +fOiYLZoBAoGBAOGhXTHjkYBiZ53IIJXA0SktfwFdzgzu7a7amRSsTOcY+I14avej +J+livrBi3BZ6l0SnT1IBpCwaxutkzuNUhfWvfkMfT+XQpiMC31z+VzXCfgt9j19d +FIUGud0tvVcYmxXDcNBDRqi8F5zY6uFupgHqvm6qn5TtVjRHSMOWGsnBAoGBAMXs +nzXF3Jg48umF/rtQN2ELh78mJRELmIQfk1UgR2ItMARdb0i90bCsfofKYPJNrW/3 +dTQfR8/8NK3iDLsVI0GVX4YMsNXpN1GVY/6J0hTA/jyynT3xxp3Wpqkgf8EADeuT +Z0JPMlDjThxCg00LHxvsDOvBcENXgzg/MVxQklPtAoGBAL8qHnG0Y4So2y1db+4x +TYVb3K1lsrxWet6YqvZO/WEXUQ9bpRVnENu2I+YB/IK3Hw61yoiqh1Qu47Zw1LDa +3hzIsWthTipiW0ByoJiDjZQo0u4dVanwjQAgML1qkW8Hk+4ehqiNN4KiykbDqk2R +l+kr4GiW+1oMs+rbMpUzykKBAoGADqWuOpqD8rf0Mhf6e/45uvLRfvHhuFs1VEHJ +83jKD5fsf8YyYB28EOkTDBWMCyJ4fVrAz7So6dluRJf//TBZRZc6VH9H7uytbVoy +5jlo1KRbrD5DqLvlyPSDrOx8x9mrLg3gjGW0AYxw0WKSuPbjvHtBkYjlN/aX/Wef +zYcg7RkCgYAsV79AK0UcLnWdkglTgeR/KjRVNrV/Se9Kjn9Jf4geSYXqLYrxRaL9 +2/NYvhBfcu3jyZb7s5+AUajr3IHuSA/MlENv1uSTshCHmdBd2mRtn2/xA0T5PMjC +nn6wlTs44nBLqjWocLJGJZESHTf9Ri5O4GyBneoh+R9huLE7GwWjag== +-----END RSA PRIVATE KEY----- diff --git a/bssl-compat/test/certs/client_1_key.pem.h b/bssl-compat/test/certs/client_1_key.pem.h new file mode 100644 index 00000000000..a98d4ffdf94 --- /dev/null +++ b/bssl-compat/test/certs/client_1_key.pem.h @@ -0,0 +1,28 @@ +static const char client_1_key_pem_str[] = R"""(-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEArnG5y+vKoycMCYoekr6z8bMbuX3yFaGiKIbvsX0qCtKEF2Mb +WSlS7TOAWnNGT3IyOgRjAsR5kOvax5ud9UXwJvtlK114BJb1H3IRyFSPL6s8RNE5 +jjk7c26xg/t0w81WHV+xfwIV3I31Zv3Rm08lT1pM3kqxGiFVY8cfs/MkWiD6L4zh +Y+O5Yk/S1VMqiRfU3FzR4tbz7Q3TR08u9/PL2xrqC5eRfntK2pUIvxo/D+3XQ4te +jauVOmV5fWHh6J6+5SRujLWhg+SslSanBd0rfsB3zGHlwFulVnwj8hh0Y1krx95V +GAUPvQvsMl6vKF64V3eOIJie+qgRxzNsBkharQIDAQABAoIBAQCU+qc0kqEyiUxs +cTr/FELVbqOE3Rz8gFfeyK64JC7do0AQQSHAGdyqm0tI9B3eB6cBiXGNkYJI1ES6 +KBrUt/ALOrQCPwca1Flvi5nIPv8yNMl59D11S0eMo8KS9xOXjSu4VlteHsfQ3qPw +W2DBhOxWQsZXKe7qZAFq/0oCAurO1OVa+eob5g1zHVZtl0hokpapu/2FzoqPYGj0 +t3cwPZdl4TqYWqCF1JbKcqq7h/KtbLMbin6XEWKVrfxAVJYcPVCg/vSKDLQav+N+ +5Bc6uX6w2GDYxWCjHp9PEtikcdj2KFF2yWPSbfsNQz1qn+cmNiSPM4HM8urRpjPX +fOiYLZoBAoGBAOGhXTHjkYBiZ53IIJXA0SktfwFdzgzu7a7amRSsTOcY+I14avej +J+livrBi3BZ6l0SnT1IBpCwaxutkzuNUhfWvfkMfT+XQpiMC31z+VzXCfgt9j19d +FIUGud0tvVcYmxXDcNBDRqi8F5zY6uFupgHqvm6qn5TtVjRHSMOWGsnBAoGBAMXs +nzXF3Jg48umF/rtQN2ELh78mJRELmIQfk1UgR2ItMARdb0i90bCsfofKYPJNrW/3 +dTQfR8/8NK3iDLsVI0GVX4YMsNXpN1GVY/6J0hTA/jyynT3xxp3Wpqkgf8EADeuT +Z0JPMlDjThxCg00LHxvsDOvBcENXgzg/MVxQklPtAoGBAL8qHnG0Y4So2y1db+4x +TYVb3K1lsrxWet6YqvZO/WEXUQ9bpRVnENu2I+YB/IK3Hw61yoiqh1Qu47Zw1LDa +3hzIsWthTipiW0ByoJiDjZQo0u4dVanwjQAgML1qkW8Hk+4ehqiNN4KiykbDqk2R +l+kr4GiW+1oMs+rbMpUzykKBAoGADqWuOpqD8rf0Mhf6e/45uvLRfvHhuFs1VEHJ +83jKD5fsf8YyYB28EOkTDBWMCyJ4fVrAz7So6dluRJf//TBZRZc6VH9H7uytbVoy +5jlo1KRbrD5DqLvlyPSDrOx8x9mrLg3gjGW0AYxw0WKSuPbjvHtBkYjlN/aX/Wef +zYcg7RkCgYAsV79AK0UcLnWdkglTgeR/KjRVNrV/Se9Kjn9Jf4geSYXqLYrxRaL9 +2/NYvhBfcu3jyZb7s5+AUajr3IHuSA/MlENv1uSTshCHmdBd2mRtn2/xA0T5PMjC +nn6wlTs44nBLqjWocLJGJZESHTf9Ri5O4GyBneoh+R9huLE7GwWjag== +-----END RSA PRIVATE KEY----- +)"""; diff --git a/bssl-compat/test/certs/client_2_cert.cfg b/bssl-compat/test/certs/client_2_cert.cfg new file mode 100644 index 00000000000..6f1dd173cec --- /dev/null +++ b/bssl-compat/test/certs/client_2_cert.cfg @@ -0,0 +1,39 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = GB +countryName_default = GB +stateOrProvinceName = Tyne and Wear +stateOrProvinceName_default = Tyne and Wear +localityName = Newcastle upon Tyne +localityName_default = Newcastle upon Tyne +organizationName = Red Hat +organizationName_default = Red Hat +organizationalUnitName = Red Hat Engineering +organizationalUnitName_default = Red Hat Engineering +commonName = Test Client 2 +commonName_default = Test Client 2 +commonName_max = 64 + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always + +[alt_names] +URI.1 = spiffe://redhat.com/test-client-2 +URI.2 = http://test-client-2.redhat.com +DNS.1 = redhat.com +DNS.2 = www.redhat.com diff --git a/bssl-compat/test/certs/client_2_cert.pem b/bssl-compat/test/certs/client_2_cert.pem new file mode 100644 index 00000000000..7be65fc7372 --- /dev/null +++ b/bssl-compat/test/certs/client_2_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUBoUluQH6OOPGQnR5dk8UsMFxFQ4wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAyMB4XDTI1MDYxNjEyMTY0M1oXDTI3MDYxNjEyMTY0M1owgYsxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMRYwFAYDVQQDDA1UZXN0IENsaWVudCAyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA739gPNoJ5z9Hr7r8bieS8JeHaTvFKouv +cmG3fVaX+a/dEr2kqE8xn3tCH1394tdPjmOEhuMTlXlkv9U/WxAKMiLk5Hkw6VW2 +8txAEbyJU1BJGOjT3TGNi29lAvBsYdDCkCcp/kefpkD6ixNDSlLpvXC+aRmn22ZB +q4HDmnumGCVybTQal8UwXXwXD0piI5M5FvGhahueUJF48vQo+U/hWfimYNxiLquy +dNG/t4M9xqly6gdjBp7y1nq0yZxiK9b2eWZqYq2wrHIxYeT0RElWghL79MDgifw9 +WI8nZ1vMUqvz9J/+hm3VuYhvDfN2iy1c+TIkCAVh130K8jeA6PMLDQIDAQABo4Ho +MIHlMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDATBpBgNVHREEYjBghiFzcGlmZmU6Ly9yZWRoYXQuY29tL3Rl +c3QtY2xpZW50LTKGH2h0dHA6Ly90ZXN0LWNsaWVudC0yLnJlZGhhdC5jb22CCnJl +ZGhhdC5jb22CDnd3dy5yZWRoYXQuY29tMB0GA1UdDgQWBBQQ9t/5P6gX3I/XGuTG +MkVbZrwMKzAfBgNVHSMEGDAWgBRrpT9Z/fUrm+puOgrTSv9HmZZkdTANBgkqhkiG +9w0BAQsFAAOCAQEAhY8MuBK4b6mhU9EQlttgggQVDisExosHCyvbXvEvvr0q4ELe +0EWGd35bYBSzpOMEhOkv/QQx7qAGvwBe8i2zNH2PkPx3JftY2ZMWdYTQVCsmLXK8 +OmcAN+oXhqk6J8ZJcdWxm/aVC9b1cYWaOJ6GLS+BsBWSWqTsqc05EAXjxc+22YW7 +ziQNZBIGltXE1Ecu93Uy22Ak+HSh4vNs0JhXWNnaehe37JDvXVo0tZYsdNe2lC8Q +MzZEzLLvRhHhpiNbW+1P4X+LpTK7XtoPDYt2occa9Rp/psIaImd53AcQgptyVa0e +Tc+QY+0Qem4TQBr5bu8Gzpp1fbyhMh7edqZ2XA== +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/client_2_cert.pem.h b/bssl-compat/test/certs/client_2_cert.pem.h new file mode 100644 index 00000000000..b6e20c6b59f --- /dev/null +++ b/bssl-compat/test/certs/client_2_cert.pem.h @@ -0,0 +1,28 @@ +static const char client_2_cert_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUBoUluQH6OOPGQnR5dk8UsMFxFQ4wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAyMB4XDTI1MDYxNjEyMTY0M1oXDTI3MDYxNjEyMTY0M1owgYsxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMRYwFAYDVQQDDA1UZXN0IENsaWVudCAyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA739gPNoJ5z9Hr7r8bieS8JeHaTvFKouv +cmG3fVaX+a/dEr2kqE8xn3tCH1394tdPjmOEhuMTlXlkv9U/WxAKMiLk5Hkw6VW2 +8txAEbyJU1BJGOjT3TGNi29lAvBsYdDCkCcp/kefpkD6ixNDSlLpvXC+aRmn22ZB +q4HDmnumGCVybTQal8UwXXwXD0piI5M5FvGhahueUJF48vQo+U/hWfimYNxiLquy +dNG/t4M9xqly6gdjBp7y1nq0yZxiK9b2eWZqYq2wrHIxYeT0RElWghL79MDgifw9 +WI8nZ1vMUqvz9J/+hm3VuYhvDfN2iy1c+TIkCAVh130K8jeA6PMLDQIDAQABo4Ho +MIHlMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDATBpBgNVHREEYjBghiFzcGlmZmU6Ly9yZWRoYXQuY29tL3Rl +c3QtY2xpZW50LTKGH2h0dHA6Ly90ZXN0LWNsaWVudC0yLnJlZGhhdC5jb22CCnJl +ZGhhdC5jb22CDnd3dy5yZWRoYXQuY29tMB0GA1UdDgQWBBQQ9t/5P6gX3I/XGuTG +MkVbZrwMKzAfBgNVHSMEGDAWgBRrpT9Z/fUrm+puOgrTSv9HmZZkdTANBgkqhkiG +9w0BAQsFAAOCAQEAhY8MuBK4b6mhU9EQlttgggQVDisExosHCyvbXvEvvr0q4ELe +0EWGd35bYBSzpOMEhOkv/QQx7qAGvwBe8i2zNH2PkPx3JftY2ZMWdYTQVCsmLXK8 +OmcAN+oXhqk6J8ZJcdWxm/aVC9b1cYWaOJ6GLS+BsBWSWqTsqc05EAXjxc+22YW7 +ziQNZBIGltXE1Ecu93Uy22Ak+HSh4vNs0JhXWNnaehe37JDvXVo0tZYsdNe2lC8Q +MzZEzLLvRhHhpiNbW+1P4X+LpTK7XtoPDYt2occa9Rp/psIaImd53AcQgptyVa0e +Tc+QY+0Qem4TQBr5bu8Gzpp1fbyhMh7edqZ2XA== +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/client_2_cert_chain.pem b/bssl-compat/test/certs/client_2_cert_chain.pem new file mode 100644 index 00000000000..28d6d962d76 --- /dev/null +++ b/bssl-compat/test/certs/client_2_cert_chain.pem @@ -0,0 +1,100 @@ +-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUBoUluQH6OOPGQnR5dk8UsMFxFQ4wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAyMB4XDTI1MDYxNjEyMTY0M1oXDTI3MDYxNjEyMTY0M1owgYsxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMRYwFAYDVQQDDA1UZXN0IENsaWVudCAyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA739gPNoJ5z9Hr7r8bieS8JeHaTvFKouv +cmG3fVaX+a/dEr2kqE8xn3tCH1394tdPjmOEhuMTlXlkv9U/WxAKMiLk5Hkw6VW2 +8txAEbyJU1BJGOjT3TGNi29lAvBsYdDCkCcp/kefpkD6ixNDSlLpvXC+aRmn22ZB +q4HDmnumGCVybTQal8UwXXwXD0piI5M5FvGhahueUJF48vQo+U/hWfimYNxiLquy +dNG/t4M9xqly6gdjBp7y1nq0yZxiK9b2eWZqYq2wrHIxYeT0RElWghL79MDgifw9 +WI8nZ1vMUqvz9J/+hm3VuYhvDfN2iy1c+TIkCAVh130K8jeA6PMLDQIDAQABo4Ho +MIHlMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDATBpBgNVHREEYjBghiFzcGlmZmU6Ly9yZWRoYXQuY29tL3Rl +c3QtY2xpZW50LTKGH2h0dHA6Ly90ZXN0LWNsaWVudC0yLnJlZGhhdC5jb22CCnJl +ZGhhdC5jb22CDnd3dy5yZWRoYXQuY29tMB0GA1UdDgQWBBQQ9t/5P6gX3I/XGuTG +MkVbZrwMKzAfBgNVHSMEGDAWgBRrpT9Z/fUrm+puOgrTSv9HmZZkdTANBgkqhkiG +9w0BAQsFAAOCAQEAhY8MuBK4b6mhU9EQlttgggQVDisExosHCyvbXvEvvr0q4ELe +0EWGd35bYBSzpOMEhOkv/QQx7qAGvwBe8i2zNH2PkPx3JftY2ZMWdYTQVCsmLXK8 +OmcAN+oXhqk6J8ZJcdWxm/aVC9b1cYWaOJ6GLS+BsBWSWqTsqc05EAXjxc+22YW7 +ziQNZBIGltXE1Ecu93Uy22Ak+HSh4vNs0JhXWNnaehe37JDvXVo0tZYsdNe2lC8Q +MzZEzLLvRhHhpiNbW+1P4X+LpTK7XtoPDYt2occa9Rp/psIaImd53AcQgptyVa0e +Tc+QY+0Qem4TQBr5bu8Gzpp1fbyhMh7edqZ2XA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIUJw9xyu/apN+kGfmdUr6EQIFeGC0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAxMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgZQxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVkaWF0ZSBDQSAy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZH42SM4VN66Kw8nWkJR +0Wx4Cy2tiByacJAjGfiBju9XL8DsebfLmuXDq0P6xWWVO2kBWtAvpMhX0xlnvR/U +9pdBileZo00j2RB7uMEipRtvgp1IpMUmfchrF7Iq3LW3TObxBN7dSwFo7KHGuS2c +seoeje/yV653Np72flSkou9ap3nbLVZdG5hGNbRPa5S8Ngb5h0LZTIyfyCAl7VUx +uAdeqmZpxeJ3A8RGcQuFJPu5Lu/A0YoHwZFYnqqisdiL5NWnkKKIYFXzf5T2Cll6 +zu3ScRS6z3Ow83aWqiHqDZallfZ7delvJBGRLWlLebd5PQ9sfVX72O7q3ku+yL34 +BwIDAQABo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQUa6U/Wf31K5vqbjoK00r/R5mWZHUwHwYDVR0jBBgwFoAUvS2Uhxvq +EMjaPLBAGV9N9FURKlkwDQYJKoZIhvcNAQELBQADggEBAIXga6Hu21UWcPq0KYHI +nRtzj1pqEieilEsHbGYpDobXC69ODvGqADHJ9C9UqoKH2t5MZLNnWgU++wygCTRX +HaP/5/gcpfRd9CnVV+ZCtZaL4k/Be/rBelanPWZcFHl2SO17brGSypi1WBjHwi6O +hUG9iPeWAk/TZGR6vTpLMEMwFj0naEcrqFi21C2prVdcFPjwYyT1nkquuOdBDPtR +naV+9dq5ot7SUz3ATgGAWJ5LZuV3p43JE+9FMVupmcTYSmfa7Fr5yeYpenPp09Hj +UgvGE782eT70rKwGlyvBJD9L2M1t86rMsZOkoeeHXbnC6GqLBUmnPQ6CiViwHoq4 +Ysc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFDCCAvygAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5IwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBlDELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxHzAdBgNVBAMMFlRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIS4A1yARtOZ/kZGzYZiqa2bf5GIBvz8gn +L+kcgXHyJ30HuSYLEqsxPmYu9RIwmtZPaUsFhdEzv0v3zniaP3trLzTrlQk47OW4 +CH3r/ALTYNDUFeDX3Hr7JKtq2ieBmsCCZ+Tt8OPqcUGA430ts0LoH7X3xyRm5lYf +176hzgFGUWWB8mhdLNaL5SSp0cphiaCBXg0xYOzQiMZ7UUunVoFg9rN4pZIj8Zb8 +CjBMgFjuFNIYYK9gvzCss3yx4DM3oFksEFtlGQ579gnmaTJhZ6YzdUYCFwpEoQ7S +ZHBLhhd6rKd/TVSGHNw3gGrkuFAv9Ncw1vOwtSCQr9eXTY8R/yU9AgMBAAGjZjBk +MBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS9 +LZSHG+oQyNo8sEAZX030VREqWTAfBgNVHSMEGDAWgBSpfVEfX7nS79lbrcwaH9i3 +e43AaDANBgkqhkiG9w0BAQsFAAOCAQEAbIR+iwnxg7pRYk4QMT9VCRS/WiuEFM5r +H5SUvwm4IdU69hdwoKxRtOXkaBEaVAh7sQdLokBPT9IA3f3fp0iQki9hxgZW9WVr +PzwFH15+t1OnJo5HyNOTl78yzvucVuiWu6BEjSY1YMfYwlmvRFqkwdeINAhpYFjW +KOGjeuzfXVtmoY9W4a7hgBi08J5WxX41uiTcPjebuhzZGrsmF5qOYp+m4FP5sZSx +aV3o+W5si7LFMpVq2nA/A0yyibEZnt1jcQRosExm6VphHGFT3qIc/pfwuxxlK/cz +dcc5AFWRITQD7Xmj43GxLg4JtB+kW1uf7yC9I087CBsfx4JCHtoAeQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/client_2_cert_chain.pem.h b/bssl-compat/test/certs/client_2_cert_chain.pem.h new file mode 100644 index 00000000000..d805b72b9bb --- /dev/null +++ b/bssl-compat/test/certs/client_2_cert_chain.pem.h @@ -0,0 +1,101 @@ +static const char client_2_cert_chain_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUBoUluQH6OOPGQnR5dk8UsMFxFQ4wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAyMB4XDTI1MDYxNjEyMTY0M1oXDTI3MDYxNjEyMTY0M1owgYsxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMRYwFAYDVQQDDA1UZXN0IENsaWVudCAyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA739gPNoJ5z9Hr7r8bieS8JeHaTvFKouv +cmG3fVaX+a/dEr2kqE8xn3tCH1394tdPjmOEhuMTlXlkv9U/WxAKMiLk5Hkw6VW2 +8txAEbyJU1BJGOjT3TGNi29lAvBsYdDCkCcp/kefpkD6ixNDSlLpvXC+aRmn22ZB +q4HDmnumGCVybTQal8UwXXwXD0piI5M5FvGhahueUJF48vQo+U/hWfimYNxiLquy +dNG/t4M9xqly6gdjBp7y1nq0yZxiK9b2eWZqYq2wrHIxYeT0RElWghL79MDgifw9 +WI8nZ1vMUqvz9J/+hm3VuYhvDfN2iy1c+TIkCAVh130K8jeA6PMLDQIDAQABo4Ho +MIHlMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDATBpBgNVHREEYjBghiFzcGlmZmU6Ly9yZWRoYXQuY29tL3Rl +c3QtY2xpZW50LTKGH2h0dHA6Ly90ZXN0LWNsaWVudC0yLnJlZGhhdC5jb22CCnJl +ZGhhdC5jb22CDnd3dy5yZWRoYXQuY29tMB0GA1UdDgQWBBQQ9t/5P6gX3I/XGuTG +MkVbZrwMKzAfBgNVHSMEGDAWgBRrpT9Z/fUrm+puOgrTSv9HmZZkdTANBgkqhkiG +9w0BAQsFAAOCAQEAhY8MuBK4b6mhU9EQlttgggQVDisExosHCyvbXvEvvr0q4ELe +0EWGd35bYBSzpOMEhOkv/QQx7qAGvwBe8i2zNH2PkPx3JftY2ZMWdYTQVCsmLXK8 +OmcAN+oXhqk6J8ZJcdWxm/aVC9b1cYWaOJ6GLS+BsBWSWqTsqc05EAXjxc+22YW7 +ziQNZBIGltXE1Ecu93Uy22Ak+HSh4vNs0JhXWNnaehe37JDvXVo0tZYsdNe2lC8Q +MzZEzLLvRhHhpiNbW+1P4X+LpTK7XtoPDYt2occa9Rp/psIaImd53AcQgptyVa0e +Tc+QY+0Qem4TQBr5bu8Gzpp1fbyhMh7edqZ2XA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIUJw9xyu/apN+kGfmdUr6EQIFeGC0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAxMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgZQxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVkaWF0ZSBDQSAy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZH42SM4VN66Kw8nWkJR +0Wx4Cy2tiByacJAjGfiBju9XL8DsebfLmuXDq0P6xWWVO2kBWtAvpMhX0xlnvR/U +9pdBileZo00j2RB7uMEipRtvgp1IpMUmfchrF7Iq3LW3TObxBN7dSwFo7KHGuS2c +seoeje/yV653Np72flSkou9ap3nbLVZdG5hGNbRPa5S8Ngb5h0LZTIyfyCAl7VUx +uAdeqmZpxeJ3A8RGcQuFJPu5Lu/A0YoHwZFYnqqisdiL5NWnkKKIYFXzf5T2Cll6 +zu3ScRS6z3Ow83aWqiHqDZallfZ7delvJBGRLWlLebd5PQ9sfVX72O7q3ku+yL34 +BwIDAQABo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQUa6U/Wf31K5vqbjoK00r/R5mWZHUwHwYDVR0jBBgwFoAUvS2Uhxvq +EMjaPLBAGV9N9FURKlkwDQYJKoZIhvcNAQELBQADggEBAIXga6Hu21UWcPq0KYHI +nRtzj1pqEieilEsHbGYpDobXC69ODvGqADHJ9C9UqoKH2t5MZLNnWgU++wygCTRX +HaP/5/gcpfRd9CnVV+ZCtZaL4k/Be/rBelanPWZcFHl2SO17brGSypi1WBjHwi6O +hUG9iPeWAk/TZGR6vTpLMEMwFj0naEcrqFi21C2prVdcFPjwYyT1nkquuOdBDPtR +naV+9dq5ot7SUz3ATgGAWJ5LZuV3p43JE+9FMVupmcTYSmfa7Fr5yeYpenPp09Hj +UgvGE782eT70rKwGlyvBJD9L2M1t86rMsZOkoeeHXbnC6GqLBUmnPQ6CiViwHoq4 +Ysc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFDCCAvygAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5IwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBlDELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxHzAdBgNVBAMMFlRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIS4A1yARtOZ/kZGzYZiqa2bf5GIBvz8gn +L+kcgXHyJ30HuSYLEqsxPmYu9RIwmtZPaUsFhdEzv0v3zniaP3trLzTrlQk47OW4 +CH3r/ALTYNDUFeDX3Hr7JKtq2ieBmsCCZ+Tt8OPqcUGA430ts0LoH7X3xyRm5lYf +176hzgFGUWWB8mhdLNaL5SSp0cphiaCBXg0xYOzQiMZ7UUunVoFg9rN4pZIj8Zb8 +CjBMgFjuFNIYYK9gvzCss3yx4DM3oFksEFtlGQ579gnmaTJhZ6YzdUYCFwpEoQ7S +ZHBLhhd6rKd/TVSGHNw3gGrkuFAv9Ncw1vOwtSCQr9eXTY8R/yU9AgMBAAGjZjBk +MBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS9 +LZSHG+oQyNo8sEAZX030VREqWTAfBgNVHSMEGDAWgBSpfVEfX7nS79lbrcwaH9i3 +e43AaDANBgkqhkiG9w0BAQsFAAOCAQEAbIR+iwnxg7pRYk4QMT9VCRS/WiuEFM5r +H5SUvwm4IdU69hdwoKxRtOXkaBEaVAh7sQdLokBPT9IA3f3fp0iQki9hxgZW9WVr +PzwFH15+t1OnJo5HyNOTl78yzvucVuiWu6BEjSY1YMfYwlmvRFqkwdeINAhpYFjW +KOGjeuzfXVtmoY9W4a7hgBi08J5WxX41uiTcPjebuhzZGrsmF5qOYp+m4FP5sZSx +aV3o+W5si7LFMpVq2nA/A0yyibEZnt1jcQRosExm6VphHGFT3qIc/pfwuxxlK/cz +dcc5AFWRITQD7Xmj43GxLg4JtB+kW1uf7yC9I087CBsfx4JCHtoAeQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/client_2_key.pem b/bssl-compat/test/certs/client_2_key.pem new file mode 100644 index 00000000000..8ce9375be5c --- /dev/null +++ b/bssl-compat/test/certs/client_2_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA739gPNoJ5z9Hr7r8bieS8JeHaTvFKouvcmG3fVaX+a/dEr2k +qE8xn3tCH1394tdPjmOEhuMTlXlkv9U/WxAKMiLk5Hkw6VW28txAEbyJU1BJGOjT +3TGNi29lAvBsYdDCkCcp/kefpkD6ixNDSlLpvXC+aRmn22ZBq4HDmnumGCVybTQa +l8UwXXwXD0piI5M5FvGhahueUJF48vQo+U/hWfimYNxiLquydNG/t4M9xqly6gdj +Bp7y1nq0yZxiK9b2eWZqYq2wrHIxYeT0RElWghL79MDgifw9WI8nZ1vMUqvz9J/+ +hm3VuYhvDfN2iy1c+TIkCAVh130K8jeA6PMLDQIDAQABAoIBAENmyaLWiir2eCpQ +qXIm2Qe03XsUQyzyGvJJ5eX0VNkEUWdQz+I+R2zmt3k0bptElTMxdr6vcXeDroL+ +dNIf9X6eq2RRZx6D7PT0X2Oed9dmpOvJurZpl7hCJV9qYlY09kyzePIDHj8f0mMJ +jMqCAx45eJ0Dh2YLpTerUW1MlzX76IJ8bczwuscgZbmI5DaZ6Pk41XfHJQ3nOlTu +dRwpX/peNBY5ZE0dDHMH8QC1h+AA1KbbY/t6NUJoxmgcLQov7VRn2dQ7i9+uoB44 +kTpA/x4ukop/Se1dNSBKxlW2Pz+4VBDAMNCllS0bkPFnZilmlSxgKtFxKkMyTLyi +GDhsdwECgYEA/7NKf6K8mVAN3WkzDDBS3rkFrHJezTMAWqqgkgwj4tymJaVr27Ne +Xh38teMVRAwnBBDLBQWYu2w18fUUAzXuKQmgags77xvHnzLDHAbz15qDl2GPo+bd +pRFmr2VkQ+/piNQR1zhUG5OLUUEMQUZ+/yj26SVDjGz5t7a36QCmLbECgYEA78c5 +YfmpfTzpPpAuIUTyTHGM7QUb9y/wm8ER/if86WVOv72jykql+OXKC4q4XQgPcXZa +60LXA8YDkefDGDIwprwm2ggy9lG6ZZccTOb4bRgdvA8H3neas6DSxBABWKrUWq2u +nFQQNUDLV7GVNkGsOJMHxlQEWZpOsZMfz4C/Ph0CgYBTuI6B7/S0dgO0JQezy/a2 +Ofpjlib4JOTOyuM8LoFpfDliRiFkk/wn8MWXgDysRRZZPG5cvJJfe3TGPipJStUp +1p8RWZBMH9pig6pieNxKEatYW3c+gQ69R09Jynbjz5+1T0pwH19akBqjhhrPHJfk +T7NYbv0I831n64mX3sCKYQKBgQDHv6vqFtY/YrLcT7heNtWzIRVJjuwRLHrBBkI6 +/I0Q0jicOxtrtmw1wRhkLRgRSFm1J+ft/SyqFBd9QRmh2o31GOE02Ye687LYVt5Y +okFqgKCkvdDMX88cvWlXtA2rFAT71ZyU1uL5uhSr5WBsZqFWMAZWDj/hdU8BV5M0 +hgjLcQKBgGEc0n3zjfSE5GVmi9IPC13NOzODvMF9aluXJyn8QzFfpL9L2KN5vsPL +FSq6D5T2e0mdHipz0E5unL9RVRL2FhGQ8a0PzNoaxH58lP6v3w7PSz98YlYsNaqN +czaau9W5Z8EYIPbaVk4sccy6mpv+QVlWDaJTx01qoTrx+TNS17Mo +-----END RSA PRIVATE KEY----- diff --git a/bssl-compat/test/certs/client_2_key.pem.h b/bssl-compat/test/certs/client_2_key.pem.h new file mode 100644 index 00000000000..b94dfa5ffc3 --- /dev/null +++ b/bssl-compat/test/certs/client_2_key.pem.h @@ -0,0 +1,28 @@ +static const char client_2_key_pem_str[] = R"""(-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA739gPNoJ5z9Hr7r8bieS8JeHaTvFKouvcmG3fVaX+a/dEr2k +qE8xn3tCH1394tdPjmOEhuMTlXlkv9U/WxAKMiLk5Hkw6VW28txAEbyJU1BJGOjT +3TGNi29lAvBsYdDCkCcp/kefpkD6ixNDSlLpvXC+aRmn22ZBq4HDmnumGCVybTQa +l8UwXXwXD0piI5M5FvGhahueUJF48vQo+U/hWfimYNxiLquydNG/t4M9xqly6gdj +Bp7y1nq0yZxiK9b2eWZqYq2wrHIxYeT0RElWghL79MDgifw9WI8nZ1vMUqvz9J/+ +hm3VuYhvDfN2iy1c+TIkCAVh130K8jeA6PMLDQIDAQABAoIBAENmyaLWiir2eCpQ +qXIm2Qe03XsUQyzyGvJJ5eX0VNkEUWdQz+I+R2zmt3k0bptElTMxdr6vcXeDroL+ +dNIf9X6eq2RRZx6D7PT0X2Oed9dmpOvJurZpl7hCJV9qYlY09kyzePIDHj8f0mMJ +jMqCAx45eJ0Dh2YLpTerUW1MlzX76IJ8bczwuscgZbmI5DaZ6Pk41XfHJQ3nOlTu +dRwpX/peNBY5ZE0dDHMH8QC1h+AA1KbbY/t6NUJoxmgcLQov7VRn2dQ7i9+uoB44 +kTpA/x4ukop/Se1dNSBKxlW2Pz+4VBDAMNCllS0bkPFnZilmlSxgKtFxKkMyTLyi +GDhsdwECgYEA/7NKf6K8mVAN3WkzDDBS3rkFrHJezTMAWqqgkgwj4tymJaVr27Ne +Xh38teMVRAwnBBDLBQWYu2w18fUUAzXuKQmgags77xvHnzLDHAbz15qDl2GPo+bd +pRFmr2VkQ+/piNQR1zhUG5OLUUEMQUZ+/yj26SVDjGz5t7a36QCmLbECgYEA78c5 +YfmpfTzpPpAuIUTyTHGM7QUb9y/wm8ER/if86WVOv72jykql+OXKC4q4XQgPcXZa +60LXA8YDkefDGDIwprwm2ggy9lG6ZZccTOb4bRgdvA8H3neas6DSxBABWKrUWq2u +nFQQNUDLV7GVNkGsOJMHxlQEWZpOsZMfz4C/Ph0CgYBTuI6B7/S0dgO0JQezy/a2 +Ofpjlib4JOTOyuM8LoFpfDliRiFkk/wn8MWXgDysRRZZPG5cvJJfe3TGPipJStUp +1p8RWZBMH9pig6pieNxKEatYW3c+gQ69R09Jynbjz5+1T0pwH19akBqjhhrPHJfk +T7NYbv0I831n64mX3sCKYQKBgQDHv6vqFtY/YrLcT7heNtWzIRVJjuwRLHrBBkI6 +/I0Q0jicOxtrtmw1wRhkLRgRSFm1J+ft/SyqFBd9QRmh2o31GOE02Ye687LYVt5Y +okFqgKCkvdDMX88cvWlXtA2rFAT71ZyU1uL5uhSr5WBsZqFWMAZWDj/hdU8BV5M0 +hgjLcQKBgGEc0n3zjfSE5GVmi9IPC13NOzODvMF9aluXJyn8QzFfpL9L2KN5vsPL +FSq6D5T2e0mdHipz0E5unL9RVRL2FhGQ8a0PzNoaxH58lP6v3w7PSz98YlYsNaqN +czaau9W5Z8EYIPbaVk4sccy6mpv+QVlWDaJTx01qoTrx+TNS17Mo +-----END RSA PRIVATE KEY----- +)"""; diff --git a/bssl-compat/test/certs/intermediate_ca_1_cert.cfg b/bssl-compat/test/certs/intermediate_ca_1_cert.cfg new file mode 100644 index 00000000000..dcddf6641d2 --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_1_cert.cfg @@ -0,0 +1,45 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = GB +countryName_default = GB +stateOrProvinceName = Tyne and Wear +stateOrProvinceName_default = Tyne and Wear +localityName = Newcastle upon Tyne +localityName_default = Newcastle upon Tyne +organizationName = Red Hat +organizationName_default = Red Hat +organizationalUnitName = Red Hat Engineering +organizationalUnitName_default = Red Hat Engineering +commonName = Test Intermediate CA 1 +commonName_default = Test Intermediate CA 1 +commonName_max = 64 + +[v3_req] +basicConstraints = CA:TRUE, pathlen:1 +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:TRUE, pathlen:1 +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always + +[ca] +default_ca = CA_default + +[CA_default] +database = intermediate_crl_index.txt +crlnumber = intermediate_crl_number + +default_days = 3650 +default_crl_days = 3650 +default_md = sha256 +preserve = no +unique_subject = no + +[crl_ext] +authorityKeyIdentifier = keyid:always,issuer:always diff --git a/bssl-compat/test/certs/intermediate_ca_1_cert.pem b/bssl-compat/test/certs/intermediate_ca_1_cert.pem new file mode 100644 index 00000000000..1f4da9cd778 --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_1_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEFDCCAvygAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5IwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBlDELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxHzAdBgNVBAMMFlRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIS4A1yARtOZ/kZGzYZiqa2bf5GIBvz8gn +L+kcgXHyJ30HuSYLEqsxPmYu9RIwmtZPaUsFhdEzv0v3zniaP3trLzTrlQk47OW4 +CH3r/ALTYNDUFeDX3Hr7JKtq2ieBmsCCZ+Tt8OPqcUGA430ts0LoH7X3xyRm5lYf +176hzgFGUWWB8mhdLNaL5SSp0cphiaCBXg0xYOzQiMZ7UUunVoFg9rN4pZIj8Zb8 +CjBMgFjuFNIYYK9gvzCss3yx4DM3oFksEFtlGQ579gnmaTJhZ6YzdUYCFwpEoQ7S +ZHBLhhd6rKd/TVSGHNw3gGrkuFAv9Ncw1vOwtSCQr9eXTY8R/yU9AgMBAAGjZjBk +MBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS9 +LZSHG+oQyNo8sEAZX030VREqWTAfBgNVHSMEGDAWgBSpfVEfX7nS79lbrcwaH9i3 +e43AaDANBgkqhkiG9w0BAQsFAAOCAQEAbIR+iwnxg7pRYk4QMT9VCRS/WiuEFM5r +H5SUvwm4IdU69hdwoKxRtOXkaBEaVAh7sQdLokBPT9IA3f3fp0iQki9hxgZW9WVr +PzwFH15+t1OnJo5HyNOTl78yzvucVuiWu6BEjSY1YMfYwlmvRFqkwdeINAhpYFjW +KOGjeuzfXVtmoY9W4a7hgBi08J5WxX41uiTcPjebuhzZGrsmF5qOYp+m4FP5sZSx +aV3o+W5si7LFMpVq2nA/A0yyibEZnt1jcQRosExm6VphHGFT3qIc/pfwuxxlK/cz +dcc5AFWRITQD7Xmj43GxLg4JtB+kW1uf7yC9I087CBsfx4JCHtoAeQ== +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/intermediate_ca_1_cert.pem.h b/bssl-compat/test/certs/intermediate_ca_1_cert.pem.h new file mode 100644 index 00000000000..c2f67fcb513 --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_1_cert.pem.h @@ -0,0 +1,25 @@ +static const char intermediate_ca_1_cert_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEFDCCAvygAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5IwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBlDELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxHzAdBgNVBAMMFlRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIS4A1yARtOZ/kZGzYZiqa2bf5GIBvz8gn +L+kcgXHyJ30HuSYLEqsxPmYu9RIwmtZPaUsFhdEzv0v3zniaP3trLzTrlQk47OW4 +CH3r/ALTYNDUFeDX3Hr7JKtq2ieBmsCCZ+Tt8OPqcUGA430ts0LoH7X3xyRm5lYf +176hzgFGUWWB8mhdLNaL5SSp0cphiaCBXg0xYOzQiMZ7UUunVoFg9rN4pZIj8Zb8 +CjBMgFjuFNIYYK9gvzCss3yx4DM3oFksEFtlGQ579gnmaTJhZ6YzdUYCFwpEoQ7S +ZHBLhhd6rKd/TVSGHNw3gGrkuFAv9Ncw1vOwtSCQr9eXTY8R/yU9AgMBAAGjZjBk +MBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS9 +LZSHG+oQyNo8sEAZX030VREqWTAfBgNVHSMEGDAWgBSpfVEfX7nS79lbrcwaH9i3 +e43AaDANBgkqhkiG9w0BAQsFAAOCAQEAbIR+iwnxg7pRYk4QMT9VCRS/WiuEFM5r +H5SUvwm4IdU69hdwoKxRtOXkaBEaVAh7sQdLokBPT9IA3f3fp0iQki9hxgZW9WVr +PzwFH15+t1OnJo5HyNOTl78yzvucVuiWu6BEjSY1YMfYwlmvRFqkwdeINAhpYFjW +KOGjeuzfXVtmoY9W4a7hgBi08J5WxX41uiTcPjebuhzZGrsmF5qOYp+m4FP5sZSx +aV3o+W5si7LFMpVq2nA/A0yyibEZnt1jcQRosExm6VphHGFT3qIc/pfwuxxlK/cz +dcc5AFWRITQD7Xmj43GxLg4JtB+kW1uf7yC9I087CBsfx4JCHtoAeQ== +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/intermediate_ca_1_key.pem b/bssl-compat/test/certs/intermediate_ca_1_key.pem new file mode 100644 index 00000000000..3f086cd83de --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_1_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyEuANcgEbTmf5GRs2GYqmtm3+RiAb8/IJy/pHIFx8id9B7km +CxKrMT5mLvUSMJrWT2lLBYXRM79L9854mj97ay8065UJOOzluAh96/wC02DQ1BXg +19x6+ySratongZrAgmfk7fDj6nFBgON9LbNC6B+198ckZuZWH9e+oc4BRlFlgfJo +XSzWi+UkqdHKYYmggV4NMWDs0IjGe1FLp1aBYPazeKWSI/GW/AowTIBY7hTSGGCv +YL8wrLN8seAzN6BZLBBbZRkOe/YJ5mkyYWemM3VGAhcKRKEO0mRwS4YXeqynf01U +hhzcN4Bq5LhQL/TXMNbzsLUgkK/Xl02PEf8lPQIDAQABAoIBAFCr+CuxL/c+KmQ2 +/o/6NlbAMhUmBTUDnz4JUf6lNFuwA+/EZso27rSayVVIZ9cjxgWeBxVmXGhXOCXL +B1A5GWCGVu47zMccwzloUi9mBU1VxUZmuXS33OCiWFhlHVxaFAdyCQa8609V5mgf +OB/b/6q2evgdQVAgnbedka5h5qmHEHnWFT4PYzjdrC71N8ou46irhAHvbku3IbYN +F/jcBBgRdnJbKrFPHZJoQ+5uNe1IEwGr4UuSR6aMb9MdSb+fIeXte36GvHkXABBt +z5divEE5fMA5f+ek4TDAqUXm1Duh5B44ZmhbA8WEQG7lf2OouuoAGs56lWSP5ukO +zvdqNBECgYEA8Ig0YQREVajjuNrf0rVc4mbENIwWQ6ppYL45sOcqFkrIyAw3QXXL +5oULJF0oepvFx63TBTrIKs1zTS0vx9AkGQCNLih2JqFVzhvudxNiAgZBP/5QYOeT +Qi+OMQMXh+OSp/uynxWetjxw0MlkVCjVWb4NKVDJ6wyP0CZXmZ9DMqsCgYEA1Szi +7jUiXw5eSH/8fiM08vH97Xa+nO/p9u6kt3Bp5ayRUtl26s2hVfunMeNL4LFfcplt +Uhd/vVvHIEbXUkHO3ds3II0cnISp/5ar7ASj9k2oHTJiYOK6xcrklMxeUwxQ0Ov0 +WuMxLik5rJ6gTvUpDBEJmTKr+fnaAu6O7B25x7cCgYBFq744R8sfYL8tYUCpwNy5 +u3ijm9wrF2ZUnmUJh7vaHylPQLKUpHE+QVU74DwEX7CHKSNRhXhLZZ07QpZvcyux +jkZWk2O9xsea3t5Q4W1nFra5uYlAuHMgHbQ7ICElvFZTkAVqLRH+yT0ITP1hnz5F +M1aOnBcQnV/es+x10/rb5wKBgHSyEbgc1if7EZnWlj3mwAGOf1cS/d2jaAyJLxpM +K2xTP2p/KR34Wy1aiXhB2TOzZXCylKmvu3nJWARPQ2gAJmJEsrTbCqKT7QvBS3P0 +Rl16vWDeSASJmXzVSLQ7/BayUztLL4ThgfanEq9wVolio4m7eemnV4WMRM/+D7cp +vp2ZAoGBAOkneeqtzI3+bJuLtC/s6+C/zRSvIFAbmoapRvkyyX3pSYn61JpWNJ5N +/8u4xp0hFkSRTR1vwIrDznUowl39vcEV55PTZskWVyPiYZSN9O3YlvSrx3eqBC4M +obv4feB/8Ujhx5Gc9m41MbkyvQRPx21RSGVUY+dXE6gLi7Z5Kv9e +-----END RSA PRIVATE KEY----- diff --git a/bssl-compat/test/certs/intermediate_ca_1_key.pem.h b/bssl-compat/test/certs/intermediate_ca_1_key.pem.h new file mode 100644 index 00000000000..72af8837863 --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_1_key.pem.h @@ -0,0 +1,28 @@ +static const char intermediate_ca_1_key_pem_str[] = R"""(-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyEuANcgEbTmf5GRs2GYqmtm3+RiAb8/IJy/pHIFx8id9B7km +CxKrMT5mLvUSMJrWT2lLBYXRM79L9854mj97ay8065UJOOzluAh96/wC02DQ1BXg +19x6+ySratongZrAgmfk7fDj6nFBgON9LbNC6B+198ckZuZWH9e+oc4BRlFlgfJo +XSzWi+UkqdHKYYmggV4NMWDs0IjGe1FLp1aBYPazeKWSI/GW/AowTIBY7hTSGGCv +YL8wrLN8seAzN6BZLBBbZRkOe/YJ5mkyYWemM3VGAhcKRKEO0mRwS4YXeqynf01U +hhzcN4Bq5LhQL/TXMNbzsLUgkK/Xl02PEf8lPQIDAQABAoIBAFCr+CuxL/c+KmQ2 +/o/6NlbAMhUmBTUDnz4JUf6lNFuwA+/EZso27rSayVVIZ9cjxgWeBxVmXGhXOCXL +B1A5GWCGVu47zMccwzloUi9mBU1VxUZmuXS33OCiWFhlHVxaFAdyCQa8609V5mgf +OB/b/6q2evgdQVAgnbedka5h5qmHEHnWFT4PYzjdrC71N8ou46irhAHvbku3IbYN +F/jcBBgRdnJbKrFPHZJoQ+5uNe1IEwGr4UuSR6aMb9MdSb+fIeXte36GvHkXABBt +z5divEE5fMA5f+ek4TDAqUXm1Duh5B44ZmhbA8WEQG7lf2OouuoAGs56lWSP5ukO +zvdqNBECgYEA8Ig0YQREVajjuNrf0rVc4mbENIwWQ6ppYL45sOcqFkrIyAw3QXXL +5oULJF0oepvFx63TBTrIKs1zTS0vx9AkGQCNLih2JqFVzhvudxNiAgZBP/5QYOeT +Qi+OMQMXh+OSp/uynxWetjxw0MlkVCjVWb4NKVDJ6wyP0CZXmZ9DMqsCgYEA1Szi +7jUiXw5eSH/8fiM08vH97Xa+nO/p9u6kt3Bp5ayRUtl26s2hVfunMeNL4LFfcplt +Uhd/vVvHIEbXUkHO3ds3II0cnISp/5ar7ASj9k2oHTJiYOK6xcrklMxeUwxQ0Ov0 +WuMxLik5rJ6gTvUpDBEJmTKr+fnaAu6O7B25x7cCgYBFq744R8sfYL8tYUCpwNy5 +u3ijm9wrF2ZUnmUJh7vaHylPQLKUpHE+QVU74DwEX7CHKSNRhXhLZZ07QpZvcyux +jkZWk2O9xsea3t5Q4W1nFra5uYlAuHMgHbQ7ICElvFZTkAVqLRH+yT0ITP1hnz5F +M1aOnBcQnV/es+x10/rb5wKBgHSyEbgc1if7EZnWlj3mwAGOf1cS/d2jaAyJLxpM +K2xTP2p/KR34Wy1aiXhB2TOzZXCylKmvu3nJWARPQ2gAJmJEsrTbCqKT7QvBS3P0 +Rl16vWDeSASJmXzVSLQ7/BayUztLL4ThgfanEq9wVolio4m7eemnV4WMRM/+D7cp +vp2ZAoGBAOkneeqtzI3+bJuLtC/s6+C/zRSvIFAbmoapRvkyyX3pSYn61JpWNJ5N +/8u4xp0hFkSRTR1vwIrDznUowl39vcEV55PTZskWVyPiYZSN9O3YlvSrx3eqBC4M +obv4feB/8Ujhx5Gc9m41MbkyvQRPx21RSGVUY+dXE6gLi7Z5Kv9e +-----END RSA PRIVATE KEY----- +)"""; diff --git a/bssl-compat/test/certs/intermediate_ca_2_cert.cfg b/bssl-compat/test/certs/intermediate_ca_2_cert.cfg new file mode 100644 index 00000000000..968e621872b --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_2_cert.cfg @@ -0,0 +1,45 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = GB +countryName_default = GB +stateOrProvinceName = Tyne and Wear +stateOrProvinceName_default = Tyne and Wear +localityName = Newcastle upon Tyne +localityName_default = Newcastle upon Tyne +organizationName = Red Hat +organizationName_default = Red Hat +organizationalUnitName = Red Hat Engineering +organizationalUnitName_default = Red Hat Engineering +commonName = Test Intermediate CA 2 +commonName_default = Test Intermediate CA 2 +commonName_max = 64 + +[v3_req] +basicConstraints = CA:TRUE, pathlen:0 +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:TRUE, pathlen:0 +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always + +[ca] +default_ca = CA_default + +[CA_default] +database = intermediate_crl_index.txt +crlnumber = intermediate_crl_number + +default_days = 3650 +default_crl_days = 3650 +default_md = sha256 +preserve = no +unique_subject = no + +[crl_ext] +authorityKeyIdentifier = keyid:always,issuer:always diff --git a/bssl-compat/test/certs/intermediate_ca_2_cert.pem b/bssl-compat/test/certs/intermediate_ca_2_cert.pem new file mode 100644 index 00000000000..e06d918fe59 --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_2_cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIUJw9xyu/apN+kGfmdUr6EQIFeGC0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAxMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgZQxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVkaWF0ZSBDQSAy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZH42SM4VN66Kw8nWkJR +0Wx4Cy2tiByacJAjGfiBju9XL8DsebfLmuXDq0P6xWWVO2kBWtAvpMhX0xlnvR/U +9pdBileZo00j2RB7uMEipRtvgp1IpMUmfchrF7Iq3LW3TObxBN7dSwFo7KHGuS2c +seoeje/yV653Np72flSkou9ap3nbLVZdG5hGNbRPa5S8Ngb5h0LZTIyfyCAl7VUx +uAdeqmZpxeJ3A8RGcQuFJPu5Lu/A0YoHwZFYnqqisdiL5NWnkKKIYFXzf5T2Cll6 +zu3ScRS6z3Ow83aWqiHqDZallfZ7delvJBGRLWlLebd5PQ9sfVX72O7q3ku+yL34 +BwIDAQABo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQUa6U/Wf31K5vqbjoK00r/R5mWZHUwHwYDVR0jBBgwFoAUvS2Uhxvq +EMjaPLBAGV9N9FURKlkwDQYJKoZIhvcNAQELBQADggEBAIXga6Hu21UWcPq0KYHI +nRtzj1pqEieilEsHbGYpDobXC69ODvGqADHJ9C9UqoKH2t5MZLNnWgU++wygCTRX +HaP/5/gcpfRd9CnVV+ZCtZaL4k/Be/rBelanPWZcFHl2SO17brGSypi1WBjHwi6O +hUG9iPeWAk/TZGR6vTpLMEMwFj0naEcrqFi21C2prVdcFPjwYyT1nkquuOdBDPtR +naV+9dq5ot7SUz3ATgGAWJ5LZuV3p43JE+9FMVupmcTYSmfa7Fr5yeYpenPp09Hj +UgvGE782eT70rKwGlyvBJD9L2M1t86rMsZOkoeeHXbnC6GqLBUmnPQ6CiViwHoq4 +Ysc= +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/intermediate_ca_2_cert.pem.h b/bssl-compat/test/certs/intermediate_ca_2_cert.pem.h new file mode 100644 index 00000000000..8582eca18f9 --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_2_cert.pem.h @@ -0,0 +1,26 @@ +static const char intermediate_ca_2_cert_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIUJw9xyu/apN+kGfmdUr6EQIFeGC0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAxMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgZQxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVkaWF0ZSBDQSAy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZH42SM4VN66Kw8nWkJR +0Wx4Cy2tiByacJAjGfiBju9XL8DsebfLmuXDq0P6xWWVO2kBWtAvpMhX0xlnvR/U +9pdBileZo00j2RB7uMEipRtvgp1IpMUmfchrF7Iq3LW3TObxBN7dSwFo7KHGuS2c +seoeje/yV653Np72flSkou9ap3nbLVZdG5hGNbRPa5S8Ngb5h0LZTIyfyCAl7VUx +uAdeqmZpxeJ3A8RGcQuFJPu5Lu/A0YoHwZFYnqqisdiL5NWnkKKIYFXzf5T2Cll6 +zu3ScRS6z3Ow83aWqiHqDZallfZ7delvJBGRLWlLebd5PQ9sfVX72O7q3ku+yL34 +BwIDAQABo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQUa6U/Wf31K5vqbjoK00r/R5mWZHUwHwYDVR0jBBgwFoAUvS2Uhxvq +EMjaPLBAGV9N9FURKlkwDQYJKoZIhvcNAQELBQADggEBAIXga6Hu21UWcPq0KYHI +nRtzj1pqEieilEsHbGYpDobXC69ODvGqADHJ9C9UqoKH2t5MZLNnWgU++wygCTRX +HaP/5/gcpfRd9CnVV+ZCtZaL4k/Be/rBelanPWZcFHl2SO17brGSypi1WBjHwi6O +hUG9iPeWAk/TZGR6vTpLMEMwFj0naEcrqFi21C2prVdcFPjwYyT1nkquuOdBDPtR +naV+9dq5ot7SUz3ATgGAWJ5LZuV3p43JE+9FMVupmcTYSmfa7Fr5yeYpenPp09Hj +UgvGE782eT70rKwGlyvBJD9L2M1t86rMsZOkoeeHXbnC6GqLBUmnPQ6CiViwHoq4 +Ysc= +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/intermediate_ca_2_key.pem b/bssl-compat/test/certs/intermediate_ca_2_key.pem new file mode 100644 index 00000000000..4e4355fa5de --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_2_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAqZH42SM4VN66Kw8nWkJR0Wx4Cy2tiByacJAjGfiBju9XL8Ds +ebfLmuXDq0P6xWWVO2kBWtAvpMhX0xlnvR/U9pdBileZo00j2RB7uMEipRtvgp1I +pMUmfchrF7Iq3LW3TObxBN7dSwFo7KHGuS2cseoeje/yV653Np72flSkou9ap3nb +LVZdG5hGNbRPa5S8Ngb5h0LZTIyfyCAl7VUxuAdeqmZpxeJ3A8RGcQuFJPu5Lu/A +0YoHwZFYnqqisdiL5NWnkKKIYFXzf5T2Cll6zu3ScRS6z3Ow83aWqiHqDZallfZ7 +delvJBGRLWlLebd5PQ9sfVX72O7q3ku+yL34BwIDAQABAoIBABxW+hkIKtz8UG7r +3G7YUKZIk5OCsdLivOj9HfC0OKrz00V2387D6fJcXiRceyfMf3Frbj+INb47gXoV +b+IK1OPVia2eUF4bgVdAyvyowqqHeE6DDOYE0RcKjONr8n/qmtTub++Zc7CabrfF +ndnLBroxX6PnK0B+NwxY6udYLB/SzTx8jMCqktf6vcG+eO7WiBbhuTH1S+k9+LDD +W9uQZtquca9KAS7QIEGkhxKUGHjpvbyRLItp+X5PjwlXpGWw7RtB9NBzTcYjSD7x +Q0GWAzDV+7uivH/skgaR4rU287Eh1lztUcmejg5iRg8Gh4tmgVyfOcVlBXbUEIzZ +LtYbEgkCgYEA29ntfxdFU6vHVq/8MFLXnZs8fKwaVDLfkGnzQUPKIlp64lih6XEX +5oPvgGFOmR8klxJcvv2S/jvDGUk01Y8aYXOajojcWq/kOkyFKluQcgylNtXixQfe +HBJNiuEqUT0YDSJkMsNSSHLYrbxM2Hbq64YDGNH3/JwRQmYsyX/Oi9UCgYEAxXOX +mKm0Hm+RmiGD/BnBm9lFMSjiT8xWvyLOzdQ9Jj7IkWhgSr377P12wJz5gKYf5nse +VBvwwIv5jHc3utPCYKmUqO0IezSvXxHKZdQa4+dlLeF9K39udP78X+CU2ZPydxqx +YE4sfHibKOvrnE/beIlXTAMW4KWEFeDcGLYEbmsCgYBPWL77oIV35kaChe+J7Uw+ +aLmS8XZrLxU7BNIzmujIL0msiXqeSx/qJXH6LqR0ZSYKlCj/EXvM3/rRFHfKH+TQ +iS2eBc0pudOwKs/g8r0WPHQgb19x5x4FmaF83zkrqtYUX3Y0UARRe4myYoSFl52/ +tVVGzvkmpZkhEslVTBhapQKBgQCD62jbfHZ050G2YrIV2vd5sr4BzDj366QBa7YT +2rtINCY40C2Vgj0w519R7Q7dnyAtExD+TPSbEGoYKQa48gYqIuLJwiQqfNa2g+Jg +Ckg1AEKfVsoUJ72auUnQnPGWNLyISvM7Tr92IfY4bvcppkkRzWDfziiYyrznCSbD +88geJQKBgHyIdomykKPpn8LU2qP4FcQ2H6P7MbClti9OeXmlTPPlu6jigpwA0UeI +EIc1CRFErzUiCVwzwG+atE5Gt82S1VgFlJ6VYYZwObexmrzOO40qxttHtV9qJz0G +c2csNq5igYxtMxvVZn2QNubQrhY3aFkRHBPPRzyLU2W/+DCRadW8 +-----END RSA PRIVATE KEY----- diff --git a/bssl-compat/test/certs/intermediate_ca_2_key.pem.h b/bssl-compat/test/certs/intermediate_ca_2_key.pem.h new file mode 100644 index 00000000000..cc65eac9357 --- /dev/null +++ b/bssl-compat/test/certs/intermediate_ca_2_key.pem.h @@ -0,0 +1,28 @@ +static const char intermediate_ca_2_key_pem_str[] = R"""(-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAqZH42SM4VN66Kw8nWkJR0Wx4Cy2tiByacJAjGfiBju9XL8Ds +ebfLmuXDq0P6xWWVO2kBWtAvpMhX0xlnvR/U9pdBileZo00j2RB7uMEipRtvgp1I +pMUmfchrF7Iq3LW3TObxBN7dSwFo7KHGuS2cseoeje/yV653Np72flSkou9ap3nb +LVZdG5hGNbRPa5S8Ngb5h0LZTIyfyCAl7VUxuAdeqmZpxeJ3A8RGcQuFJPu5Lu/A +0YoHwZFYnqqisdiL5NWnkKKIYFXzf5T2Cll6zu3ScRS6z3Ow83aWqiHqDZallfZ7 +delvJBGRLWlLebd5PQ9sfVX72O7q3ku+yL34BwIDAQABAoIBABxW+hkIKtz8UG7r +3G7YUKZIk5OCsdLivOj9HfC0OKrz00V2387D6fJcXiRceyfMf3Frbj+INb47gXoV +b+IK1OPVia2eUF4bgVdAyvyowqqHeE6DDOYE0RcKjONr8n/qmtTub++Zc7CabrfF +ndnLBroxX6PnK0B+NwxY6udYLB/SzTx8jMCqktf6vcG+eO7WiBbhuTH1S+k9+LDD +W9uQZtquca9KAS7QIEGkhxKUGHjpvbyRLItp+X5PjwlXpGWw7RtB9NBzTcYjSD7x +Q0GWAzDV+7uivH/skgaR4rU287Eh1lztUcmejg5iRg8Gh4tmgVyfOcVlBXbUEIzZ +LtYbEgkCgYEA29ntfxdFU6vHVq/8MFLXnZs8fKwaVDLfkGnzQUPKIlp64lih6XEX +5oPvgGFOmR8klxJcvv2S/jvDGUk01Y8aYXOajojcWq/kOkyFKluQcgylNtXixQfe +HBJNiuEqUT0YDSJkMsNSSHLYrbxM2Hbq64YDGNH3/JwRQmYsyX/Oi9UCgYEAxXOX +mKm0Hm+RmiGD/BnBm9lFMSjiT8xWvyLOzdQ9Jj7IkWhgSr377P12wJz5gKYf5nse +VBvwwIv5jHc3utPCYKmUqO0IezSvXxHKZdQa4+dlLeF9K39udP78X+CU2ZPydxqx +YE4sfHibKOvrnE/beIlXTAMW4KWEFeDcGLYEbmsCgYBPWL77oIV35kaChe+J7Uw+ +aLmS8XZrLxU7BNIzmujIL0msiXqeSx/qJXH6LqR0ZSYKlCj/EXvM3/rRFHfKH+TQ +iS2eBc0pudOwKs/g8r0WPHQgb19x5x4FmaF83zkrqtYUX3Y0UARRe4myYoSFl52/ +tVVGzvkmpZkhEslVTBhapQKBgQCD62jbfHZ050G2YrIV2vd5sr4BzDj366QBa7YT +2rtINCY40C2Vgj0w519R7Q7dnyAtExD+TPSbEGoYKQa48gYqIuLJwiQqfNa2g+Jg +Ckg1AEKfVsoUJ72auUnQnPGWNLyISvM7Tr92IfY4bvcppkkRzWDfziiYyrznCSbD +88geJQKBgHyIdomykKPpn8LU2qP4FcQ2H6P7MbClti9OeXmlTPPlu6jigpwA0UeI +EIc1CRFErzUiCVwzwG+atE5Gt82S1VgFlJ6VYYZwObexmrzOO40qxttHtV9qJz0G +c2csNq5igYxtMxvVZn2QNubQrhY3aFkRHBPPRzyLU2W/+DCRadW8 +-----END RSA PRIVATE KEY----- +)"""; diff --git a/bssl-compat/test/certs/root_ca_cert.cfg b/bssl-compat/test/certs/root_ca_cert.cfg new file mode 100644 index 00000000000..3f4422c1af7 --- /dev/null +++ b/bssl-compat/test/certs/root_ca_cert.cfg @@ -0,0 +1,29 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = GB +countryName_default = GB +stateOrProvinceName = Tyne and Wear +stateOrProvinceName_default = Tyne and Wear +localityName = Newcastle upon Tyne +localityName_default = Newcastle upon Tyne +organizationName = Red Hat +organizationName_default = Red Hat +organizationalUnitName = Red Hat Engineering +organizationalUnitName_default = Red Hat Engineering +commonName = Test Root CA +commonName_default = Test Root CA +commonName_max = 64 + +[v3_req] +basicConstraints = CA:TRUE +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:TRUE +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always diff --git a/bssl-compat/test/certs/root_ca_cert.pem b/bssl-compat/test/certs/root_ca_cert.pem new file mode 100644 index 00000000000..78b7eba8cbe --- /dev/null +++ b/bssl-compat/test/certs/root_ca_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/root_ca_cert.pem.h b/bssl-compat/test/certs/root_ca_cert.pem.h new file mode 100644 index 00000000000..5281685183f --- /dev/null +++ b/bssl-compat/test/certs/root_ca_cert.pem.h @@ -0,0 +1,25 @@ +static const char root_ca_cert_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/root_ca_key.pem b/bssl-compat/test/certs/root_ca_key.pem new file mode 100644 index 00000000000..172bf1ba47b --- /dev/null +++ b/bssl-compat/test/certs/root_ca_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA2qHTWLZndNVk4/j87BNzijSwiSheu4ruXk0WbQVVKB0Jt1Hi ++lY+cjkJe5ua5Bv5LZrag3xG5MSLR7lmsTaDzbyc1Pca/qmEvAv04qKS+MJmL30Q +/vsq0g4jE+++y2WCKwksEl0nIFYR0UIFpnLliId8xm1vTcrQgajvQ9JPMYkfn629 +graGcfWvTM3NTULILOTXRZEnktT7hhjwarqe5hte+fmi5THXh9/i/d8C8oMLrrOd +pNAGS5KR9YaBgrBbj/DJVQ3SKj0OdcaiAsnIi3RwZNtDntFbuplblpUiCK34oH8O +vWK2fKCgdlow+kV3ngAhrz+hBQZ+6vWqKzqoMQIDAQABAoIBADxD2S8d8HybCdlx +W75zSijxhyv3jc1iaXxjAWiBzMxm3LPEha19sm7n2/5PkS2JrHDuu4b87cnHh6D4 +sR7uKPzAHfbyOmWyMp1nKlSCfcLGS0aR0eqHL3GBZhfrwQrt6yiTuatCNDPMpdKp +wUb1auHsfu9vYPvviPQErhdi1GORpyd/fKLXfyD/1hEP17ZSYuIDoLv+SDNtpN2T +06aRSRPKPdzz9DlSIPNBC2KwhJs2c4DEMiwdf5rAljqzNCYvCLoTyFF3fwiODFqr +ta3Uf4QT2l9DTdqhX7EXZ4xblOJQGn6XynvKwqHEQDHJ1+Nn5nDta04bGC/mOPpT +PbgQ/PECgYEA+Mq82WQYhrMYI4LT0oYekXrP9NtK1BHyxZTCn/yIVutIjKzmKuCu +hzOw+lAvG9+IpS8Y+nfjcc5AeK5a4DMPAGKEJtrAvlWyA7Ictfkck84wd5XsOCVp +iRabSobb/g1yXDPSghSqdznIIXs2LTZOMd+F9Pl3gZn6BuqzmW7AduUCgYEA4Pdl +WMyiwsnymnF6xPCTgpqxLjUP67gC3u3pgXFJXu+RM0VTu2WmhmZvhRLtLI8AmN+a +XnhGud6EZ/5+wnc//Pd7bHREUArUzbvMRIdCBoT1bfkRontboZLmmsAt5HQ9V7ag +8TkFIhqSvyWf/NUSx9YzmXrIMH6OcoXx1AmLK10CgYBuqsAWc0/1mvTB1xAiNUaj +r92RLXq7msBC40kvoUWEZGSBLuezav43ZebzcXeDDovZ7nlN8MZbeUN0axpBYHTr +1uax4dyazcPBoRjkWUs89BrbFvVchEfNkyDApfx1pcWY/fRFqKurHSjIu+X9doqR +5LvRnKZsH/H34a7CMWGrgQKBgGjVYLj8w2waR5+I+jkEEvlttNtfhsfFvDC+lW3o +qNRAt105FUfimrNO0PEmXLfC+/hBWuJjEjJTa0g65D8i6wKrISztEVhrc7dbqFjW +3wHCu8w/oOQisBSfLC85Fym6sUtKo71FYQr/bxr8IY3kjRfqzajb+qX+k8ryeDrj +J6NRAoGBAJlyacEkgb3su1lj6g7xN51niWDw0lBVApSX/C9a8nh5IJ85GQJ9H7zL +kNPnc+W6BZ0BV9WvSx0gVURcGTG84sCygsLJyaomrl8ylXHpz2+hHHWHnJojEAAK +b5PbZwnA03iD69nzTK4FaGkmUscnYYY8v9Tpp0icM606MZlh8TQe +-----END RSA PRIVATE KEY----- diff --git a/bssl-compat/test/certs/root_ca_key.pem.h b/bssl-compat/test/certs/root_ca_key.pem.h new file mode 100644 index 00000000000..e6d1baa3135 --- /dev/null +++ b/bssl-compat/test/certs/root_ca_key.pem.h @@ -0,0 +1,28 @@ +static const char root_ca_key_pem_str[] = R"""(-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA2qHTWLZndNVk4/j87BNzijSwiSheu4ruXk0WbQVVKB0Jt1Hi ++lY+cjkJe5ua5Bv5LZrag3xG5MSLR7lmsTaDzbyc1Pca/qmEvAv04qKS+MJmL30Q +/vsq0g4jE+++y2WCKwksEl0nIFYR0UIFpnLliId8xm1vTcrQgajvQ9JPMYkfn629 +graGcfWvTM3NTULILOTXRZEnktT7hhjwarqe5hte+fmi5THXh9/i/d8C8oMLrrOd +pNAGS5KR9YaBgrBbj/DJVQ3SKj0OdcaiAsnIi3RwZNtDntFbuplblpUiCK34oH8O +vWK2fKCgdlow+kV3ngAhrz+hBQZ+6vWqKzqoMQIDAQABAoIBADxD2S8d8HybCdlx +W75zSijxhyv3jc1iaXxjAWiBzMxm3LPEha19sm7n2/5PkS2JrHDuu4b87cnHh6D4 +sR7uKPzAHfbyOmWyMp1nKlSCfcLGS0aR0eqHL3GBZhfrwQrt6yiTuatCNDPMpdKp +wUb1auHsfu9vYPvviPQErhdi1GORpyd/fKLXfyD/1hEP17ZSYuIDoLv+SDNtpN2T +06aRSRPKPdzz9DlSIPNBC2KwhJs2c4DEMiwdf5rAljqzNCYvCLoTyFF3fwiODFqr +ta3Uf4QT2l9DTdqhX7EXZ4xblOJQGn6XynvKwqHEQDHJ1+Nn5nDta04bGC/mOPpT +PbgQ/PECgYEA+Mq82WQYhrMYI4LT0oYekXrP9NtK1BHyxZTCn/yIVutIjKzmKuCu +hzOw+lAvG9+IpS8Y+nfjcc5AeK5a4DMPAGKEJtrAvlWyA7Ictfkck84wd5XsOCVp +iRabSobb/g1yXDPSghSqdznIIXs2LTZOMd+F9Pl3gZn6BuqzmW7AduUCgYEA4Pdl +WMyiwsnymnF6xPCTgpqxLjUP67gC3u3pgXFJXu+RM0VTu2WmhmZvhRLtLI8AmN+a +XnhGud6EZ/5+wnc//Pd7bHREUArUzbvMRIdCBoT1bfkRontboZLmmsAt5HQ9V7ag +8TkFIhqSvyWf/NUSx9YzmXrIMH6OcoXx1AmLK10CgYBuqsAWc0/1mvTB1xAiNUaj +r92RLXq7msBC40kvoUWEZGSBLuezav43ZebzcXeDDovZ7nlN8MZbeUN0axpBYHTr +1uax4dyazcPBoRjkWUs89BrbFvVchEfNkyDApfx1pcWY/fRFqKurHSjIu+X9doqR +5LvRnKZsH/H34a7CMWGrgQKBgGjVYLj8w2waR5+I+jkEEvlttNtfhsfFvDC+lW3o +qNRAt105FUfimrNO0PEmXLfC+/hBWuJjEjJTa0g65D8i6wKrISztEVhrc7dbqFjW +3wHCu8w/oOQisBSfLC85Fym6sUtKo71FYQr/bxr8IY3kjRfqzajb+qX+k8ryeDrj +J6NRAoGBAJlyacEkgb3su1lj6g7xN51niWDw0lBVApSX/C9a8nh5IJ85GQJ9H7zL +kNPnc+W6BZ0BV9WvSx0gVURcGTG84sCygsLJyaomrl8ylXHpz2+hHHWHnJojEAAK +b5PbZwnA03iD69nzTK4FaGkmUscnYYY8v9Tpp0icM606MZlh8TQe +-----END RSA PRIVATE KEY----- +)"""; diff --git a/bssl-compat/test/certs/server_1_cert.cfg b/bssl-compat/test/certs/server_1_cert.cfg new file mode 100644 index 00000000000..66b2a3cd182 --- /dev/null +++ b/bssl-compat/test/certs/server_1_cert.cfg @@ -0,0 +1,39 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = GB +countryName_default = GB +stateOrProvinceName = Tyne and Wear +stateOrProvinceName_default = Tyne and Wear +localityName = Newcastle upon Tyne +localityName_default = Newcastle upon Tyne +organizationName = Red Hat +organizationName_default = Red Hat +organizationalUnitName = Red Hat Engineering +organizationalUnitName_default = Red Hat Engineering +commonName = Test Server 1 +commonName_default = Test Server 1 +commonName_max = 64 + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always + +[alt_names] +URI.1 = spiffe://redhat.com/test-server-1 +URI.2 = http://test-server-1.redhat.com +DNS.1 = redhat.com +DNS.2 = www.redhat.com diff --git a/bssl-compat/test/certs/server_1_cert.pem b/bssl-compat/test/certs/server_1_cert.pem new file mode 100644 index 00000000000..42ed8b1acbd --- /dev/null +++ b/bssl-compat/test/certs/server_1_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjjCCA3agAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5MwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBizELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFjAUBgNVBAMMDVRlc3QgU2VydmVyIDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDaXgoeSMs5nlHJQHKz4UiRyhs+h+xzQk10X044gA6Yv0a9 +HV+qdUD4WojpSIlzQE2Jl03wd2PtOiGN5zy+ocKzlgf+rebOP54A2e831KX7BW2/ +buPd2BtzLblQGMfs7+7q1kBFBSwVItTPRtEzOkIr/KcYhzOCFTzvnbIq+MsKwPqY +ql+TD6Df+pNq4hCIKhP5xSOvJumVlb1bYKC2F7UT3l9Y/TOvcjUapsFhjrFjKZ3x +ScoTNTMMgUoPLX84lZesP9CMH+tlgzEPugUrSy8ssgFeTo2GeHR/qzkPK8qzW7Og +YroG9AP4RgNpR/DopJxTr4APi4v2p4ysZJ8iNQ9RAgMBAAGjgegwgeUwDAYDVR0T +AQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMGkGA1UdEQRiMGCGIXNwaWZmZTovL3JlZGhhdC5jb20vdGVzdC1zZXJ2ZXIt +MYYfaHR0cDovL3Rlc3Qtc2VydmVyLTEucmVkaGF0LmNvbYIKcmVkaGF0LmNvbYIO +d3d3LnJlZGhhdC5jb20wHQYDVR0OBBYEFJz4D1Xqot9Z2mHJEZrKmTtaNxnGMB8G +A1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3DQEBCwUAA4IB +AQCAQFMQ7TNxV4dNNTAaayVMjhLgrIGRV2wovwacWMA4ovyiE172ZYwZdneAbJpl ++SXsUksdhiFEhg0kqVOAoDJwn7evH3e3/1yotiam6EE1aHWaP7Cd92OpwA79Ouj5 +Ztv5cJndy41tqZdrCG017QFaoTlikZuaeBDvExaPFVjJGJXvicryD1SHHl1PY5M6 +HGZRB7fgd0hPIgdkamw44wqohPz05+KA+EMXbIGtRTUvTGt4cnSVC7u/nR6mjPk/ +Q9wGiURGSyiwrDVn9ToB5Kg2RZgzRlqXzvr5AI8SwqIqBjUf1rj93naQejVTh6xX +eBDWSmr1HYYpSOZoZlc+xalo +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/server_1_cert.pem.h b/bssl-compat/test/certs/server_1_cert.pem.h new file mode 100644 index 00000000000..34f6ebf6dae --- /dev/null +++ b/bssl-compat/test/certs/server_1_cert.pem.h @@ -0,0 +1,28 @@ +static const char server_1_cert_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEjjCCA3agAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5MwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBizELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFjAUBgNVBAMMDVRlc3QgU2VydmVyIDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDaXgoeSMs5nlHJQHKz4UiRyhs+h+xzQk10X044gA6Yv0a9 +HV+qdUD4WojpSIlzQE2Jl03wd2PtOiGN5zy+ocKzlgf+rebOP54A2e831KX7BW2/ +buPd2BtzLblQGMfs7+7q1kBFBSwVItTPRtEzOkIr/KcYhzOCFTzvnbIq+MsKwPqY +ql+TD6Df+pNq4hCIKhP5xSOvJumVlb1bYKC2F7UT3l9Y/TOvcjUapsFhjrFjKZ3x +ScoTNTMMgUoPLX84lZesP9CMH+tlgzEPugUrSy8ssgFeTo2GeHR/qzkPK8qzW7Og +YroG9AP4RgNpR/DopJxTr4APi4v2p4ysZJ8iNQ9RAgMBAAGjgegwgeUwDAYDVR0T +AQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMGkGA1UdEQRiMGCGIXNwaWZmZTovL3JlZGhhdC5jb20vdGVzdC1zZXJ2ZXIt +MYYfaHR0cDovL3Rlc3Qtc2VydmVyLTEucmVkaGF0LmNvbYIKcmVkaGF0LmNvbYIO +d3d3LnJlZGhhdC5jb20wHQYDVR0OBBYEFJz4D1Xqot9Z2mHJEZrKmTtaNxnGMB8G +A1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3DQEBCwUAA4IB +AQCAQFMQ7TNxV4dNNTAaayVMjhLgrIGRV2wovwacWMA4ovyiE172ZYwZdneAbJpl ++SXsUksdhiFEhg0kqVOAoDJwn7evH3e3/1yotiam6EE1aHWaP7Cd92OpwA79Ouj5 +Ztv5cJndy41tqZdrCG017QFaoTlikZuaeBDvExaPFVjJGJXvicryD1SHHl1PY5M6 +HGZRB7fgd0hPIgdkamw44wqohPz05+KA+EMXbIGtRTUvTGt4cnSVC7u/nR6mjPk/ +Q9wGiURGSyiwrDVn9ToB5Kg2RZgzRlqXzvr5AI8SwqIqBjUf1rj93naQejVTh6xX +eBDWSmr1HYYpSOZoZlc+xalo +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/server_1_cert_chain.pem b/bssl-compat/test/certs/server_1_cert_chain.pem new file mode 100644 index 00000000000..a508cbf08cf --- /dev/null +++ b/bssl-compat/test/certs/server_1_cert_chain.pem @@ -0,0 +1,51 @@ +-----BEGIN CERTIFICATE----- +MIIEjjCCA3agAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5MwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBizELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFjAUBgNVBAMMDVRlc3QgU2VydmVyIDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDaXgoeSMs5nlHJQHKz4UiRyhs+h+xzQk10X044gA6Yv0a9 +HV+qdUD4WojpSIlzQE2Jl03wd2PtOiGN5zy+ocKzlgf+rebOP54A2e831KX7BW2/ +buPd2BtzLblQGMfs7+7q1kBFBSwVItTPRtEzOkIr/KcYhzOCFTzvnbIq+MsKwPqY +ql+TD6Df+pNq4hCIKhP5xSOvJumVlb1bYKC2F7UT3l9Y/TOvcjUapsFhjrFjKZ3x +ScoTNTMMgUoPLX84lZesP9CMH+tlgzEPugUrSy8ssgFeTo2GeHR/qzkPK8qzW7Og +YroG9AP4RgNpR/DopJxTr4APi4v2p4ysZJ8iNQ9RAgMBAAGjgegwgeUwDAYDVR0T +AQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMGkGA1UdEQRiMGCGIXNwaWZmZTovL3JlZGhhdC5jb20vdGVzdC1zZXJ2ZXIt +MYYfaHR0cDovL3Rlc3Qtc2VydmVyLTEucmVkaGF0LmNvbYIKcmVkaGF0LmNvbYIO +d3d3LnJlZGhhdC5jb20wHQYDVR0OBBYEFJz4D1Xqot9Z2mHJEZrKmTtaNxnGMB8G +A1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3DQEBCwUAA4IB +AQCAQFMQ7TNxV4dNNTAaayVMjhLgrIGRV2wovwacWMA4ovyiE172ZYwZdneAbJpl ++SXsUksdhiFEhg0kqVOAoDJwn7evH3e3/1yotiam6EE1aHWaP7Cd92OpwA79Ouj5 +Ztv5cJndy41tqZdrCG017QFaoTlikZuaeBDvExaPFVjJGJXvicryD1SHHl1PY5M6 +HGZRB7fgd0hPIgdkamw44wqohPz05+KA+EMXbIGtRTUvTGt4cnSVC7u/nR6mjPk/ +Q9wGiURGSyiwrDVn9ToB5Kg2RZgzRlqXzvr5AI8SwqIqBjUf1rj93naQejVTh6xX +eBDWSmr1HYYpSOZoZlc+xalo +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/server_1_cert_chain.pem.h b/bssl-compat/test/certs/server_1_cert_chain.pem.h new file mode 100644 index 00000000000..6eb30a819ac --- /dev/null +++ b/bssl-compat/test/certs/server_1_cert_chain.pem.h @@ -0,0 +1,52 @@ +static const char server_1_cert_chain_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEjjCCA3agAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5MwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBizELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFjAUBgNVBAMMDVRlc3QgU2VydmVyIDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDaXgoeSMs5nlHJQHKz4UiRyhs+h+xzQk10X044gA6Yv0a9 +HV+qdUD4WojpSIlzQE2Jl03wd2PtOiGN5zy+ocKzlgf+rebOP54A2e831KX7BW2/ +buPd2BtzLblQGMfs7+7q1kBFBSwVItTPRtEzOkIr/KcYhzOCFTzvnbIq+MsKwPqY +ql+TD6Df+pNq4hCIKhP5xSOvJumVlb1bYKC2F7UT3l9Y/TOvcjUapsFhjrFjKZ3x +ScoTNTMMgUoPLX84lZesP9CMH+tlgzEPugUrSy8ssgFeTo2GeHR/qzkPK8qzW7Og +YroG9AP4RgNpR/DopJxTr4APi4v2p4ysZJ8iNQ9RAgMBAAGjgegwgeUwDAYDVR0T +AQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMGkGA1UdEQRiMGCGIXNwaWZmZTovL3JlZGhhdC5jb20vdGVzdC1zZXJ2ZXIt +MYYfaHR0cDovL3Rlc3Qtc2VydmVyLTEucmVkaGF0LmNvbYIKcmVkaGF0LmNvbYIO +d3d3LnJlZGhhdC5jb20wHQYDVR0OBBYEFJz4D1Xqot9Z2mHJEZrKmTtaNxnGMB8G +A1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3DQEBCwUAA4IB +AQCAQFMQ7TNxV4dNNTAaayVMjhLgrIGRV2wovwacWMA4ovyiE172ZYwZdneAbJpl ++SXsUksdhiFEhg0kqVOAoDJwn7evH3e3/1yotiam6EE1aHWaP7Cd92OpwA79Ouj5 +Ztv5cJndy41tqZdrCG017QFaoTlikZuaeBDvExaPFVjJGJXvicryD1SHHl1PY5M6 +HGZRB7fgd0hPIgdkamw44wqohPz05+KA+EMXbIGtRTUvTGt4cnSVC7u/nR6mjPk/ +Q9wGiURGSyiwrDVn9ToB5Kg2RZgzRlqXzvr5AI8SwqIqBjUf1rj93naQejVTh6xX +eBDWSmr1HYYpSOZoZlc+xalo +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/server_1_key.pem b/bssl-compat/test/certs/server_1_key.pem new file mode 100644 index 00000000000..e7d470bafe9 --- /dev/null +++ b/bssl-compat/test/certs/server_1_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA2l4KHkjLOZ5RyUBys+FIkcobPofsc0JNdF9OOIAOmL9GvR1f +qnVA+FqI6UiJc0BNiZdN8Hdj7Tohjec8vqHCs5YH/q3mzj+eANnvN9Sl+wVtv27j +3dgbcy25UBjH7O/u6tZARQUsFSLUz0bRMzpCK/ynGIczghU8752yKvjLCsD6mKpf +kw+g3/qTauIQiCoT+cUjrybplZW9W2Cgthe1E95fWP0zr3I1GqbBYY6xYymd8UnK +EzUzDIFKDy1/OJWXrD/QjB/rZYMxD7oFK0svLLIBXk6Nhnh0f6s5DyvKs1uzoGK6 +BvQD+EYDaUfw6KScU6+AD4uL9qeMrGSfIjUPUQIDAQABAoIBAG5a2AI2B3425F4w +k8cUMvh6iwou5u/Ysgv9niovjTDkeXtZPN+IIi1gk5BReCUmegjuzhSYQYfBuPNd +yPUOCrd3OtMaT2or/E2x1ZMBhGA3fh8gi0exzy2GDgDMhTzYhIVpgVFgK8cCs0mN +IGwjJQ3VwRxEN2OmGAWATGorEXF85h2nXyHzz+fZMabvEx4LM6uDnsRA2W8JuERc +PtDmPQk0uTT67VUGZjmkZ1m5bmWdsJo+OXvxpdtoyaV8naGXyYBflRA9BKFwsfWa +I+Lh5kSWlrsGE7PGNUiDKPwlTe4EYF1te1yDBNehiv5Q12sHy1eBXxCVuciz6SqE +pGJQoYECgYEA8f3+LaX9jquXObclhmOssDzgN0YSff/DYX0o1p5y5zFO/befzR9v +Oh0zFZzrd1yuTYXGkNm/xeSwctFIrek8DdxF/o2vC0TDXlqn5RIk6SRJPERcub9t +G30FuOyctQRmafJBbpqPLMS0i2N0nAeHHxY+4u/ofepEzqzNJeJFEj8CgYEA5wH1 +L6C+FXQh2tBsMvn1tW7NGV20eBOx5oTEwBjXZt71w0F8y5o/Xmvul79v9sFhK+Ak +1VfLvDRRLDepbmL4vdClzilWvkD8hP4w2KOd6raQIjapPe9ohqeuw6o9YjXdrdcU ++7OkJmR+J+J810LSXxHPK/L0Wb9bLwvaJBwoWm8CgYEAxU9PvHCneXi3aTvHwPfs +ihZYyzi7QzkTWZ3vem7fSVqPCZh7F4kV69B7Ipg79asAA/2blee10elRZYz3MbYG +XVbJS3DC1PFQStKoKsLMjbwkapti76EBmXQrAkkKzR21U5VPfJtROjN48l45ai9J +ITPGOstaSbCGQe3rp4QCxYkCgYEAlKAA1NzRj1IBehvAkWeau1mHYbuVIfBh9BMV +1xXkeE4YxsA6f3BFNwWwIzfK3HJ8h1MVv6FV9keethk1zEynBtDX7HVSVuPO0+4L +FUbnkhxVTX3nk26VzJTT7xV3mtlXP8JywKJKiVz8gcLJWWGnofz+UqNkrN1d2D4C +4lqvZ8cCgYBgKCouPK37A2Ryuo188kYXFJcAcGqPRxrJlnVGisWPm3LE5pqxtUef +B3s0GhR8D5pNUnBvLxylckCufV31juyOSav1+eVZU0ruh0iGe5i9q40bMaa0EPuc +f7NT93FiQwQh4MZ2tBh7xjoPiwVk7PyRLSdpAfWnrypBQyjlj7+Ghg== +-----END RSA PRIVATE KEY----- diff --git a/bssl-compat/test/certs/server_1_key.pem.h b/bssl-compat/test/certs/server_1_key.pem.h new file mode 100644 index 00000000000..83748387e24 --- /dev/null +++ b/bssl-compat/test/certs/server_1_key.pem.h @@ -0,0 +1,28 @@ +static const char server_1_key_pem_str[] = R"""(-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA2l4KHkjLOZ5RyUBys+FIkcobPofsc0JNdF9OOIAOmL9GvR1f +qnVA+FqI6UiJc0BNiZdN8Hdj7Tohjec8vqHCs5YH/q3mzj+eANnvN9Sl+wVtv27j +3dgbcy25UBjH7O/u6tZARQUsFSLUz0bRMzpCK/ynGIczghU8752yKvjLCsD6mKpf +kw+g3/qTauIQiCoT+cUjrybplZW9W2Cgthe1E95fWP0zr3I1GqbBYY6xYymd8UnK +EzUzDIFKDy1/OJWXrD/QjB/rZYMxD7oFK0svLLIBXk6Nhnh0f6s5DyvKs1uzoGK6 +BvQD+EYDaUfw6KScU6+AD4uL9qeMrGSfIjUPUQIDAQABAoIBAG5a2AI2B3425F4w +k8cUMvh6iwou5u/Ysgv9niovjTDkeXtZPN+IIi1gk5BReCUmegjuzhSYQYfBuPNd +yPUOCrd3OtMaT2or/E2x1ZMBhGA3fh8gi0exzy2GDgDMhTzYhIVpgVFgK8cCs0mN +IGwjJQ3VwRxEN2OmGAWATGorEXF85h2nXyHzz+fZMabvEx4LM6uDnsRA2W8JuERc +PtDmPQk0uTT67VUGZjmkZ1m5bmWdsJo+OXvxpdtoyaV8naGXyYBflRA9BKFwsfWa +I+Lh5kSWlrsGE7PGNUiDKPwlTe4EYF1te1yDBNehiv5Q12sHy1eBXxCVuciz6SqE +pGJQoYECgYEA8f3+LaX9jquXObclhmOssDzgN0YSff/DYX0o1p5y5zFO/befzR9v +Oh0zFZzrd1yuTYXGkNm/xeSwctFIrek8DdxF/o2vC0TDXlqn5RIk6SRJPERcub9t +G30FuOyctQRmafJBbpqPLMS0i2N0nAeHHxY+4u/ofepEzqzNJeJFEj8CgYEA5wH1 +L6C+FXQh2tBsMvn1tW7NGV20eBOx5oTEwBjXZt71w0F8y5o/Xmvul79v9sFhK+Ak +1VfLvDRRLDepbmL4vdClzilWvkD8hP4w2KOd6raQIjapPe9ohqeuw6o9YjXdrdcU ++7OkJmR+J+J810LSXxHPK/L0Wb9bLwvaJBwoWm8CgYEAxU9PvHCneXi3aTvHwPfs +ihZYyzi7QzkTWZ3vem7fSVqPCZh7F4kV69B7Ipg79asAA/2blee10elRZYz3MbYG +XVbJS3DC1PFQStKoKsLMjbwkapti76EBmXQrAkkKzR21U5VPfJtROjN48l45ai9J +ITPGOstaSbCGQe3rp4QCxYkCgYEAlKAA1NzRj1IBehvAkWeau1mHYbuVIfBh9BMV +1xXkeE4YxsA6f3BFNwWwIzfK3HJ8h1MVv6FV9keethk1zEynBtDX7HVSVuPO0+4L +FUbnkhxVTX3nk26VzJTT7xV3mtlXP8JywKJKiVz8gcLJWWGnofz+UqNkrN1d2D4C +4lqvZ8cCgYBgKCouPK37A2Ryuo188kYXFJcAcGqPRxrJlnVGisWPm3LE5pqxtUef +B3s0GhR8D5pNUnBvLxylckCufV31juyOSav1+eVZU0ruh0iGe5i9q40bMaa0EPuc +f7NT93FiQwQh4MZ2tBh7xjoPiwVk7PyRLSdpAfWnrypBQyjlj7+Ghg== +-----END RSA PRIVATE KEY----- +)"""; diff --git a/bssl-compat/test/certs/server_2_cert.cfg b/bssl-compat/test/certs/server_2_cert.cfg new file mode 100644 index 00000000000..dd8949cd93b --- /dev/null +++ b/bssl-compat/test/certs/server_2_cert.cfg @@ -0,0 +1,39 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = GB +countryName_default = GB +stateOrProvinceName = Tyne and Wear +stateOrProvinceName_default = Tyne and Wear +localityName = Newcastle upon Tyne +localityName_default = Newcastle upon Tyne +organizationName = Red Hat +organizationName_default = Red Hat +organizationalUnitName = Red Hat Engineering +organizationalUnitName_default = Red Hat Engineering +commonName = Test Server 2 +commonName_default = Test Server 2 +commonName_max = 64 + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always + +[alt_names] +URI.1 = spiffe://redhat.com/test-server-2 +URI.2 = http://test-server-2.redhat.com +DNS.1 = redhat.com +DNS.2 = www.redhat.com diff --git a/bssl-compat/test/certs/server_2_cert.pem b/bssl-compat/test/certs/server_2_cert.pem new file mode 100644 index 00000000000..4e9e8220bec --- /dev/null +++ b/bssl-compat/test/certs/server_2_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUBoUluQH6OOPGQnR5dk8UsMFxFQ0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAyMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgYsxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMRYwFAYDVQQDDA1UZXN0IFNlcnZlciAyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA97p49NC2Z4soQL4qxUAVZQTXr11dVHzy +uo5ehk1ojAUiSeBtoO4e8EOvojqGZtIQoQnDN2LSMaEjvT4DFBiEoES8OQ4lZhG7 +mjp9iK59O9aQSmXxtz3lZ8ittMW1H9nsBXtx+HEIaBMUW8VL6AT0ESGLPGgXA/Zm +b6NhvB18RaIX1vjxacpXelrfsbvUQt2b6jFla/TFqTyUbpf9eZjbf/pF4cStQKuf +bvEddnuJ4a5LALEZ4avoKRRzxPwsbntfM91+LJOLHOTqWepKkzZSFMXo3NAco02L +VJ/CMIbZ0LM5yr2+lDEMCXVQi9BwlfgQLnFGRX6rXQrXVL/hzzd3hQIDAQABo4Ho +MIHlMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDATBpBgNVHREEYjBghiFzcGlmZmU6Ly9yZWRoYXQuY29tL3Rl +c3Qtc2VydmVyLTKGH2h0dHA6Ly90ZXN0LXNlcnZlci0yLnJlZGhhdC5jb22CCnJl +ZGhhdC5jb22CDnd3dy5yZWRoYXQuY29tMB0GA1UdDgQWBBQBAPbKT7z2hHZnQzwR +FLllINQDwjAfBgNVHSMEGDAWgBRrpT9Z/fUrm+puOgrTSv9HmZZkdTANBgkqhkiG +9w0BAQsFAAOCAQEAO1r+L2sw5seBazxyrEykIYjZfMIc+9bbWhkX1VlNbKUlFLJa +xhgvp1AXnTZ0fRN/APGmx4UPmtz29oG326kAKbDgV5PQ5CQzmi6G4llNfKnT7YVV +3w96M0p1mJaJJpWykB3M3L+g47hff3o9Le867Zh4LIO2/b1gktEKEOgUiZBWDMTv +Lg5195wL4GHC87p39CwMQ89CKP2iNA2Vf7XaOns3qmS3tWPNDlppn8qWqIfw3E2W +NNsqcLxIaAVDk+q4zwoIW3sZxj0IxeHwnqa2X3RcO7MjEr05Z05eNZT/xUFrRExZ +vkbHGbQgUiUhAW/3lvK/mJ5G5hoctFF1SpHcEA== +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/server_2_cert.pem.h b/bssl-compat/test/certs/server_2_cert.pem.h new file mode 100644 index 00000000000..6cc53c95001 --- /dev/null +++ b/bssl-compat/test/certs/server_2_cert.pem.h @@ -0,0 +1,28 @@ +static const char server_2_cert_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUBoUluQH6OOPGQnR5dk8UsMFxFQ0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAyMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgYsxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMRYwFAYDVQQDDA1UZXN0IFNlcnZlciAyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA97p49NC2Z4soQL4qxUAVZQTXr11dVHzy +uo5ehk1ojAUiSeBtoO4e8EOvojqGZtIQoQnDN2LSMaEjvT4DFBiEoES8OQ4lZhG7 +mjp9iK59O9aQSmXxtz3lZ8ittMW1H9nsBXtx+HEIaBMUW8VL6AT0ESGLPGgXA/Zm +b6NhvB18RaIX1vjxacpXelrfsbvUQt2b6jFla/TFqTyUbpf9eZjbf/pF4cStQKuf +bvEddnuJ4a5LALEZ4avoKRRzxPwsbntfM91+LJOLHOTqWepKkzZSFMXo3NAco02L +VJ/CMIbZ0LM5yr2+lDEMCXVQi9BwlfgQLnFGRX6rXQrXVL/hzzd3hQIDAQABo4Ho +MIHlMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDATBpBgNVHREEYjBghiFzcGlmZmU6Ly9yZWRoYXQuY29tL3Rl +c3Qtc2VydmVyLTKGH2h0dHA6Ly90ZXN0LXNlcnZlci0yLnJlZGhhdC5jb22CCnJl +ZGhhdC5jb22CDnd3dy5yZWRoYXQuY29tMB0GA1UdDgQWBBQBAPbKT7z2hHZnQzwR +FLllINQDwjAfBgNVHSMEGDAWgBRrpT9Z/fUrm+puOgrTSv9HmZZkdTANBgkqhkiG +9w0BAQsFAAOCAQEAO1r+L2sw5seBazxyrEykIYjZfMIc+9bbWhkX1VlNbKUlFLJa +xhgvp1AXnTZ0fRN/APGmx4UPmtz29oG326kAKbDgV5PQ5CQzmi6G4llNfKnT7YVV +3w96M0p1mJaJJpWykB3M3L+g47hff3o9Le867Zh4LIO2/b1gktEKEOgUiZBWDMTv +Lg5195wL4GHC87p39CwMQ89CKP2iNA2Vf7XaOns3qmS3tWPNDlppn8qWqIfw3E2W +NNsqcLxIaAVDk+q4zwoIW3sZxj0IxeHwnqa2X3RcO7MjEr05Z05eNZT/xUFrRExZ +vkbHGbQgUiUhAW/3lvK/mJ5G5hoctFF1SpHcEA== +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/server_2_cert_chain.pem b/bssl-compat/test/certs/server_2_cert_chain.pem new file mode 100644 index 00000000000..ed2d88df4ab --- /dev/null +++ b/bssl-compat/test/certs/server_2_cert_chain.pem @@ -0,0 +1,100 @@ +-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUBoUluQH6OOPGQnR5dk8UsMFxFQ0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAyMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgYsxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMRYwFAYDVQQDDA1UZXN0IFNlcnZlciAyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA97p49NC2Z4soQL4qxUAVZQTXr11dVHzy +uo5ehk1ojAUiSeBtoO4e8EOvojqGZtIQoQnDN2LSMaEjvT4DFBiEoES8OQ4lZhG7 +mjp9iK59O9aQSmXxtz3lZ8ittMW1H9nsBXtx+HEIaBMUW8VL6AT0ESGLPGgXA/Zm +b6NhvB18RaIX1vjxacpXelrfsbvUQt2b6jFla/TFqTyUbpf9eZjbf/pF4cStQKuf +bvEddnuJ4a5LALEZ4avoKRRzxPwsbntfM91+LJOLHOTqWepKkzZSFMXo3NAco02L +VJ/CMIbZ0LM5yr2+lDEMCXVQi9BwlfgQLnFGRX6rXQrXVL/hzzd3hQIDAQABo4Ho +MIHlMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDATBpBgNVHREEYjBghiFzcGlmZmU6Ly9yZWRoYXQuY29tL3Rl +c3Qtc2VydmVyLTKGH2h0dHA6Ly90ZXN0LXNlcnZlci0yLnJlZGhhdC5jb22CCnJl +ZGhhdC5jb22CDnd3dy5yZWRoYXQuY29tMB0GA1UdDgQWBBQBAPbKT7z2hHZnQzwR +FLllINQDwjAfBgNVHSMEGDAWgBRrpT9Z/fUrm+puOgrTSv9HmZZkdTANBgkqhkiG +9w0BAQsFAAOCAQEAO1r+L2sw5seBazxyrEykIYjZfMIc+9bbWhkX1VlNbKUlFLJa +xhgvp1AXnTZ0fRN/APGmx4UPmtz29oG326kAKbDgV5PQ5CQzmi6G4llNfKnT7YVV +3w96M0p1mJaJJpWykB3M3L+g47hff3o9Le867Zh4LIO2/b1gktEKEOgUiZBWDMTv +Lg5195wL4GHC87p39CwMQ89CKP2iNA2Vf7XaOns3qmS3tWPNDlppn8qWqIfw3E2W +NNsqcLxIaAVDk+q4zwoIW3sZxj0IxeHwnqa2X3RcO7MjEr05Z05eNZT/xUFrRExZ +vkbHGbQgUiUhAW/3lvK/mJ5G5hoctFF1SpHcEA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIUJw9xyu/apN+kGfmdUr6EQIFeGC0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAxMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgZQxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVkaWF0ZSBDQSAy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZH42SM4VN66Kw8nWkJR +0Wx4Cy2tiByacJAjGfiBju9XL8DsebfLmuXDq0P6xWWVO2kBWtAvpMhX0xlnvR/U +9pdBileZo00j2RB7uMEipRtvgp1IpMUmfchrF7Iq3LW3TObxBN7dSwFo7KHGuS2c +seoeje/yV653Np72flSkou9ap3nbLVZdG5hGNbRPa5S8Ngb5h0LZTIyfyCAl7VUx +uAdeqmZpxeJ3A8RGcQuFJPu5Lu/A0YoHwZFYnqqisdiL5NWnkKKIYFXzf5T2Cll6 +zu3ScRS6z3Ow83aWqiHqDZallfZ7delvJBGRLWlLebd5PQ9sfVX72O7q3ku+yL34 +BwIDAQABo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQUa6U/Wf31K5vqbjoK00r/R5mWZHUwHwYDVR0jBBgwFoAUvS2Uhxvq +EMjaPLBAGV9N9FURKlkwDQYJKoZIhvcNAQELBQADggEBAIXga6Hu21UWcPq0KYHI +nRtzj1pqEieilEsHbGYpDobXC69ODvGqADHJ9C9UqoKH2t5MZLNnWgU++wygCTRX +HaP/5/gcpfRd9CnVV+ZCtZaL4k/Be/rBelanPWZcFHl2SO17brGSypi1WBjHwi6O +hUG9iPeWAk/TZGR6vTpLMEMwFj0naEcrqFi21C2prVdcFPjwYyT1nkquuOdBDPtR +naV+9dq5ot7SUz3ATgGAWJ5LZuV3p43JE+9FMVupmcTYSmfa7Fr5yeYpenPp09Hj +UgvGE782eT70rKwGlyvBJD9L2M1t86rMsZOkoeeHXbnC6GqLBUmnPQ6CiViwHoq4 +Ysc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFDCCAvygAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5IwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBlDELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxHzAdBgNVBAMMFlRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIS4A1yARtOZ/kZGzYZiqa2bf5GIBvz8gn +L+kcgXHyJ30HuSYLEqsxPmYu9RIwmtZPaUsFhdEzv0v3zniaP3trLzTrlQk47OW4 +CH3r/ALTYNDUFeDX3Hr7JKtq2ieBmsCCZ+Tt8OPqcUGA430ts0LoH7X3xyRm5lYf +176hzgFGUWWB8mhdLNaL5SSp0cphiaCBXg0xYOzQiMZ7UUunVoFg9rN4pZIj8Zb8 +CjBMgFjuFNIYYK9gvzCss3yx4DM3oFksEFtlGQ579gnmaTJhZ6YzdUYCFwpEoQ7S +ZHBLhhd6rKd/TVSGHNw3gGrkuFAv9Ncw1vOwtSCQr9eXTY8R/yU9AgMBAAGjZjBk +MBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS9 +LZSHG+oQyNo8sEAZX030VREqWTAfBgNVHSMEGDAWgBSpfVEfX7nS79lbrcwaH9i3 +e43AaDANBgkqhkiG9w0BAQsFAAOCAQEAbIR+iwnxg7pRYk4QMT9VCRS/WiuEFM5r +H5SUvwm4IdU69hdwoKxRtOXkaBEaVAh7sQdLokBPT9IA3f3fp0iQki9hxgZW9WVr +PzwFH15+t1OnJo5HyNOTl78yzvucVuiWu6BEjSY1YMfYwlmvRFqkwdeINAhpYFjW +KOGjeuzfXVtmoY9W4a7hgBi08J5WxX41uiTcPjebuhzZGrsmF5qOYp+m4FP5sZSx +aV3o+W5si7LFMpVq2nA/A0yyibEZnt1jcQRosExm6VphHGFT3qIc/pfwuxxlK/cz +dcc5AFWRITQD7Xmj43GxLg4JtB+kW1uf7yC9I087CBsfx4JCHtoAeQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- diff --git a/bssl-compat/test/certs/server_2_cert_chain.pem.h b/bssl-compat/test/certs/server_2_cert_chain.pem.h new file mode 100644 index 00000000000..58cef0be88c --- /dev/null +++ b/bssl-compat/test/certs/server_2_cert_chain.pem.h @@ -0,0 +1,101 @@ +static const char server_2_cert_chain_pem_str[] = R"""(-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUBoUluQH6OOPGQnR5dk8UsMFxFQ0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAyMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgYsxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMRYwFAYDVQQDDA1UZXN0IFNlcnZlciAyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA97p49NC2Z4soQL4qxUAVZQTXr11dVHzy +uo5ehk1ojAUiSeBtoO4e8EOvojqGZtIQoQnDN2LSMaEjvT4DFBiEoES8OQ4lZhG7 +mjp9iK59O9aQSmXxtz3lZ8ittMW1H9nsBXtx+HEIaBMUW8VL6AT0ESGLPGgXA/Zm +b6NhvB18RaIX1vjxacpXelrfsbvUQt2b6jFla/TFqTyUbpf9eZjbf/pF4cStQKuf +bvEddnuJ4a5LALEZ4avoKRRzxPwsbntfM91+LJOLHOTqWepKkzZSFMXo3NAco02L +VJ/CMIbZ0LM5yr2+lDEMCXVQi9BwlfgQLnFGRX6rXQrXVL/hzzd3hQIDAQABo4Ho +MIHlMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDATBpBgNVHREEYjBghiFzcGlmZmU6Ly9yZWRoYXQuY29tL3Rl +c3Qtc2VydmVyLTKGH2h0dHA6Ly90ZXN0LXNlcnZlci0yLnJlZGhhdC5jb22CCnJl +ZGhhdC5jb22CDnd3dy5yZWRoYXQuY29tMB0GA1UdDgQWBBQBAPbKT7z2hHZnQzwR +FLllINQDwjAfBgNVHSMEGDAWgBRrpT9Z/fUrm+puOgrTSv9HmZZkdTANBgkqhkiG +9w0BAQsFAAOCAQEAO1r+L2sw5seBazxyrEykIYjZfMIc+9bbWhkX1VlNbKUlFLJa +xhgvp1AXnTZ0fRN/APGmx4UPmtz29oG326kAKbDgV5PQ5CQzmi6G4llNfKnT7YVV +3w96M0p1mJaJJpWykB3M3L+g47hff3o9Le867Zh4LIO2/b1gktEKEOgUiZBWDMTv +Lg5195wL4GHC87p39CwMQ89CKP2iNA2Vf7XaOns3qmS3tWPNDlppn8qWqIfw3E2W +NNsqcLxIaAVDk+q4zwoIW3sZxj0IxeHwnqa2X3RcO7MjEr05Z05eNZT/xUFrRExZ +vkbHGbQgUiUhAW/3lvK/mJ5G5hoctFF1SpHcEA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIUJw9xyu/apN+kGfmdUr6EQIFeGC0wDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVk +aWF0ZSBDQSAxMB4XDTI1MDYxNjEyMTY0MloXDTI3MDYxNjEyMTY0MlowgZQxCzAJ +BgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYDVQQHDBNOZXdj +YXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQLDBNSZWQg +SGF0IEVuZ2luZWVyaW5nMR8wHQYDVQQDDBZUZXN0IEludGVybWVkaWF0ZSBDQSAy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZH42SM4VN66Kw8nWkJR +0Wx4Cy2tiByacJAjGfiBju9XL8DsebfLmuXDq0P6xWWVO2kBWtAvpMhX0xlnvR/U +9pdBileZo00j2RB7uMEipRtvgp1IpMUmfchrF7Iq3LW3TObxBN7dSwFo7KHGuS2c +seoeje/yV653Np72flSkou9ap3nbLVZdG5hGNbRPa5S8Ngb5h0LZTIyfyCAl7VUx +uAdeqmZpxeJ3A8RGcQuFJPu5Lu/A0YoHwZFYnqqisdiL5NWnkKKIYFXzf5T2Cll6 +zu3ScRS6z3Ow83aWqiHqDZallfZ7delvJBGRLWlLebd5PQ9sfVX72O7q3ku+yL34 +BwIDAQABo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQUa6U/Wf31K5vqbjoK00r/R5mWZHUwHwYDVR0jBBgwFoAUvS2Uhxvq +EMjaPLBAGV9N9FURKlkwDQYJKoZIhvcNAQELBQADggEBAIXga6Hu21UWcPq0KYHI +nRtzj1pqEieilEsHbGYpDobXC69ODvGqADHJ9C9UqoKH2t5MZLNnWgU++wygCTRX +HaP/5/gcpfRd9CnVV+ZCtZaL4k/Be/rBelanPWZcFHl2SO17brGSypi1WBjHwi6O +hUG9iPeWAk/TZGR6vTpLMEMwFj0naEcrqFi21C2prVdcFPjwYyT1nkquuOdBDPtR +naV+9dq5ot7SUz3ATgGAWJ5LZuV3p43JE+9FMVupmcTYSmfa7Fr5yeYpenPp09Hj +UgvGE782eT70rKwGlyvBJD9L2M1t86rMsZOkoeeHXbnC6GqLBUmnPQ6CiViwHoq4 +Ysc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFDCCAvygAwIBAgIUCTpAUdI0paiRKgPH3UKinAJAh5IwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBlDELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxHzAdBgNVBAMMFlRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIS4A1yARtOZ/kZGzYZiqa2bf5GIBvz8gn +L+kcgXHyJ30HuSYLEqsxPmYu9RIwmtZPaUsFhdEzv0v3zniaP3trLzTrlQk47OW4 +CH3r/ALTYNDUFeDX3Hr7JKtq2ieBmsCCZ+Tt8OPqcUGA430ts0LoH7X3xyRm5lYf +176hzgFGUWWB8mhdLNaL5SSp0cphiaCBXg0xYOzQiMZ7UUunVoFg9rN4pZIj8Zb8 +CjBMgFjuFNIYYK9gvzCss3yx4DM3oFksEFtlGQ579gnmaTJhZ6YzdUYCFwpEoQ7S +ZHBLhhd6rKd/TVSGHNw3gGrkuFAv9Ncw1vOwtSCQr9eXTY8R/yU9AgMBAAGjZjBk +MBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS9 +LZSHG+oQyNo8sEAZX030VREqWTAfBgNVHSMEGDAWgBSpfVEfX7nS79lbrcwaH9i3 +e43AaDANBgkqhkiG9w0BAQsFAAOCAQEAbIR+iwnxg7pRYk4QMT9VCRS/WiuEFM5r +H5SUvwm4IdU69hdwoKxRtOXkaBEaVAh7sQdLokBPT9IA3f3fp0iQki9hxgZW9WVr +PzwFH15+t1OnJo5HyNOTl78yzvucVuiWu6BEjSY1YMfYwlmvRFqkwdeINAhpYFjW +KOGjeuzfXVtmoY9W4a7hgBi08J5WxX41uiTcPjebuhzZGrsmF5qOYp+m4FP5sZSx +aV3o+W5si7LFMpVq2nA/A0yyibEZnt1jcQRosExm6VphHGFT3qIc/pfwuxxlK/cz +dcc5AFWRITQD7Xmj43GxLg4JtB+kW1uf7yC9I087CBsfx4JCHtoAeQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIUEEsMInKejPh2WwDjDt7va5eVs5cwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD +VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD +VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew +HhcNMjUwNjE2MTIxNjQyWhcNMjcwNjE2MTIxNjQyWjCBijELMAkGA1UEBhMCR0Ix +FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u +IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l +ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANqh01i2Z3TVZOP4/OwTc4o0sIkoXruK7l5NFm0FVSgdCbdR +4vpWPnI5CXubmuQb+S2a2oN8RuTEi0e5ZrE2g828nNT3Gv6phLwL9OKikvjCZi99 +EP77KtIOIxPvvstlgisJLBJdJyBWEdFCBaZy5YiHfMZtb03K0IGo70PSTzGJH5+t +vYK2hnH1r0zNzU1CyCzk10WRJ5LU+4YY8Gq6nuYbXvn5ouUx14ff4v3fAvKDC66z +naTQBkuSkfWGgYKwW4/wyVUN0io9DnXGogLJyIt0cGTbQ57RW7qZW5aVIgit+KB/ +Dr1itnygoHZaMPpFd54AIa8/oQUGfur1qis6qDECAwEAAaNjMGEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKl9UR9fudLv2VutzBof +2Ld7jcBoMB8GA1UdIwQYMBaAFKl9UR9fudLv2VutzBof2Ld7jcBoMA0GCSqGSIb3 +DQEBCwUAA4IBAQDAbbVAAD0cUmpjcg/FB4FizoV//IiTylVDd82DuX2OHVG9aBs7 +W4O2qa5jpZqlQtM95YwUHcWLJgOVOdfBU5GdwBwZHytSZF5xylJ0xw0SvoIpAJGF +J1OdXabMYSx8x/hE6/5tEZrq9Cbq2ShKiIjT2s4sZlA0S89kH03QGysMBVoi51GJ +OQjMd5q7pxDr1cFHI+MlJxQEqWpIvvVYjWCuuBRJgya6Eec27UTny92daUceOewj +RED7vb243BRctxyoZhH+oH4A8vU6G9gwxyRXit37Lh1edd+STjgu7s0QHlkdCMiN +GH4h0XeBtQ6GzViNGHVbV6oIEtQzNIY84OUl +-----END CERTIFICATE----- +)"""; diff --git a/bssl-compat/test/certs/server_2_key.pem b/bssl-compat/test/certs/server_2_key.pem new file mode 100644 index 00000000000..b1d86d99631 --- /dev/null +++ b/bssl-compat/test/certs/server_2_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA97p49NC2Z4soQL4qxUAVZQTXr11dVHzyuo5ehk1ojAUiSeBt +oO4e8EOvojqGZtIQoQnDN2LSMaEjvT4DFBiEoES8OQ4lZhG7mjp9iK59O9aQSmXx +tz3lZ8ittMW1H9nsBXtx+HEIaBMUW8VL6AT0ESGLPGgXA/Zmb6NhvB18RaIX1vjx +acpXelrfsbvUQt2b6jFla/TFqTyUbpf9eZjbf/pF4cStQKufbvEddnuJ4a5LALEZ +4avoKRRzxPwsbntfM91+LJOLHOTqWepKkzZSFMXo3NAco02LVJ/CMIbZ0LM5yr2+ +lDEMCXVQi9BwlfgQLnFGRX6rXQrXVL/hzzd3hQIDAQABAoIBAQCIjyukUPVsKMLc +xbfQGl5w3HWFPyN2spYfjuG+iSdroFzheq0UPI+jhLxp4nc6cOwnybjqbDhQkXKh +HHEX/9gEfT+A+DJXjMjs4PdYhE+Wz9WknYPcrmsqhe5zq1UIJNo9v2n5OV4X+QSM +/jq0wR5F30bg2sRtM8QOIHN8/ogF3Zo/LN7fBAb069HC4nwzfdClpAs6TygC/0kM +/QSiz2KTAEaC/bNmYfK9YGcg13/R9zKEJ8kM//JK/m8WW84THF2TQ06eJIySJzoD +uq5Wqs2Fvr1zDzp0SJL9rEqVGn5MciZZABeWegz06R3ut6TXlD//iZ4Pb87lAkNz +mzbc+hrhAoGBAPyrJVEadNdONlpeyTmXPosGiq0NHmZutMc12LkVgxnwJd7TjtMc +IJqIUIssTbE6pvH/o+pVaG1waXope2aQs05KeRx72w9BjobnHXak9IMdkzP2v9Cp +64OusUN1M98UoQvJkuFaKjiBYTmfziGk148Ixp9YaB/4NJwLP226nhaZAoGBAPr+ +puCIOqbOaL211ve9VFW4dNz9LlKSXinOj63yaM9I7yf1eKLOg+HvimGZbszNGi3c +gZvueFUmtcYQhEqpIrpfIsPZ3lcBB6ka8QmTwmJ3XNxMhFen0IHspFZJ2op/hiqq +etrpnbNjpCMcd4QLLMQ2LEKJam101D6E8USjOLfNAoGBAKAoxEDCqmmH9EAYcSkG +S+jIPsMu26RGbGUSJsw7bJzWcsrqA1CiNbB+079EWAMNkKE5UGfLt6QXa2S6QrRi +6KWp41dA0zy6a2Prv+ti6HLsHlEECdZ0vwr7gvWlpzmy09qq7WXXR4gFyuFCAOGm +odTS1URQP8B0DrUTFCOz9V2RAoGBAMHgeIjR0fRNVkzMLEvbPEymmealzuVLWF8U +xplHuTv8i3ejPlcMDIU2Yf735MVf3Mv2G0uWje7AYwKmeXmuYjvyBsmf/gXYrtEq +FWwfbbRfnSQyGrwWzZG+eEaK77uxu7IzU4jLkdwiqIPSlmMxupepfNC8krAP4W6V +hERPjB01AoGBAJ8cpZ/1GTU8onW6G83WmP4zqXHjrmjxSghCHsxcuKMIk24nAzVF +H2C3tOS8demTQ0jLbuuEXIBNefnSGRerDjIc/5Y6Ez4hpcyFfravKWbwAFgki2TO +tZo45/K/Lviim39EnSD/l3Xh2aO0qUhjpmBu1XjxvTBylyRtn2jAigps +-----END RSA PRIVATE KEY----- diff --git a/bssl-compat/test/certs/server_2_key.pem.h b/bssl-compat/test/certs/server_2_key.pem.h new file mode 100644 index 00000000000..761186807ba --- /dev/null +++ b/bssl-compat/test/certs/server_2_key.pem.h @@ -0,0 +1,28 @@ +static const char server_2_key_pem_str[] = R"""(-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA97p49NC2Z4soQL4qxUAVZQTXr11dVHzyuo5ehk1ojAUiSeBt +oO4e8EOvojqGZtIQoQnDN2LSMaEjvT4DFBiEoES8OQ4lZhG7mjp9iK59O9aQSmXx +tz3lZ8ittMW1H9nsBXtx+HEIaBMUW8VL6AT0ESGLPGgXA/Zmb6NhvB18RaIX1vjx +acpXelrfsbvUQt2b6jFla/TFqTyUbpf9eZjbf/pF4cStQKufbvEddnuJ4a5LALEZ +4avoKRRzxPwsbntfM91+LJOLHOTqWepKkzZSFMXo3NAco02LVJ/CMIbZ0LM5yr2+ +lDEMCXVQi9BwlfgQLnFGRX6rXQrXVL/hzzd3hQIDAQABAoIBAQCIjyukUPVsKMLc +xbfQGl5w3HWFPyN2spYfjuG+iSdroFzheq0UPI+jhLxp4nc6cOwnybjqbDhQkXKh +HHEX/9gEfT+A+DJXjMjs4PdYhE+Wz9WknYPcrmsqhe5zq1UIJNo9v2n5OV4X+QSM +/jq0wR5F30bg2sRtM8QOIHN8/ogF3Zo/LN7fBAb069HC4nwzfdClpAs6TygC/0kM +/QSiz2KTAEaC/bNmYfK9YGcg13/R9zKEJ8kM//JK/m8WW84THF2TQ06eJIySJzoD +uq5Wqs2Fvr1zDzp0SJL9rEqVGn5MciZZABeWegz06R3ut6TXlD//iZ4Pb87lAkNz +mzbc+hrhAoGBAPyrJVEadNdONlpeyTmXPosGiq0NHmZutMc12LkVgxnwJd7TjtMc +IJqIUIssTbE6pvH/o+pVaG1waXope2aQs05KeRx72w9BjobnHXak9IMdkzP2v9Cp +64OusUN1M98UoQvJkuFaKjiBYTmfziGk148Ixp9YaB/4NJwLP226nhaZAoGBAPr+ +puCIOqbOaL211ve9VFW4dNz9LlKSXinOj63yaM9I7yf1eKLOg+HvimGZbszNGi3c +gZvueFUmtcYQhEqpIrpfIsPZ3lcBB6ka8QmTwmJ3XNxMhFen0IHspFZJ2op/hiqq +etrpnbNjpCMcd4QLLMQ2LEKJam101D6E8USjOLfNAoGBAKAoxEDCqmmH9EAYcSkG +S+jIPsMu26RGbGUSJsw7bJzWcsrqA1CiNbB+079EWAMNkKE5UGfLt6QXa2S6QrRi +6KWp41dA0zy6a2Prv+ti6HLsHlEECdZ0vwr7gvWlpzmy09qq7WXXR4gFyuFCAOGm +odTS1URQP8B0DrUTFCOz9V2RAoGBAMHgeIjR0fRNVkzMLEvbPEymmealzuVLWF8U +xplHuTv8i3ejPlcMDIU2Yf735MVf3Mv2G0uWje7AYwKmeXmuYjvyBsmf/gXYrtEq +FWwfbbRfnSQyGrwWzZG+eEaK77uxu7IzU4jLkdwiqIPSlmMxupepfNC8krAP4W6V +hERPjB01AoGBAJ8cpZ/1GTU8onW6G83WmP4zqXHjrmjxSghCHsxcuKMIk24nAzVF +H2C3tOS8demTQ0jLbuuEXIBNefnSGRerDjIc/5Y6Ez4hpcyFfravKWbwAFgki2TO +tZo45/K/Lviim39EnSD/l3Xh2aO0qUhjpmBu1XjxvTBylyRtn2jAigps +-----END RSA PRIVATE KEY----- +)"""; diff --git a/bssl-compat/test/main.cc b/bssl-compat/test/main.cc new file mode 100644 index 00000000000..f6213ce7d3a --- /dev/null +++ b/bssl-compat/test/main.cc @@ -0,0 +1,63 @@ +#include + + +class OpenSSLConf { + public: + + OpenSSLConf(const char *config) { + int fd = mkstemp(m_path.data()); + if (fd != -1) { + FILE* file = fdopen(fd, "w"); + if (file) { + if (fwrite(config, 1, strlen(config), file) == strlen(config)) { + fclose(file); + if (setenv("OPENSSL_CONF", m_path.c_str(), 1) == 0) { + return; + } + } + } + } + throw std::runtime_error("Failed to set up OPENSSL_CONF"); + } + + ~OpenSSLConf() { + unlink(m_path.c_str()); + } + +private: + + std::string m_path { "/tmp/openssl.conf.XXXXXX" }; +}; + + +static OpenSSLConf openssl_conf(R"( + openssl_conf = openssl_init + + [openssl_init] + providers = providers_sect + ssl_conf = ssl_sect + + [providers_sect] + default = default_sect + legacy = legacy_sect + + [default_sect] + activate = 1 + + [legacy_sect] + activate = 1 + + [ssl_sect] + system_default = system_default_sect + + [system_default_sect] + CipherString = DEFAULT:@SECLEVEL=1 +)"); + + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + + // Run all tests and return the result. + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/bssl-compat/test/test_asn1.cc b/bssl-compat/test/test_asn1.cc new file mode 100644 index 00000000000..c72b2b6ebf9 --- /dev/null +++ b/bssl-compat/test/test_asn1.cc @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include + + +static const char TestString[] = { "TestString" }; +static const int TestStringLength = strlen(TestString); + +TEST(Asn1Test, asn1string) { + // Testing ASN1_IA5STRING_new + ASN1_IA5STRING *ia5TestString = ASN1_IA5STRING_new(); + EXPECT_TRUE(ia5TestString != nullptr); + // Testing ASN1_STRING_set + ASN1_STRING_set(ia5TestString, TestString, TestStringLength); + EXPECT_EQ(ASN1_STRING_length(ia5TestString), TestStringLength); + // Testing ASN1_STRING_data + EXPECT_STREQ((const char *)ASN1_STRING_data(ia5TestString), TestString); + // Testing ASN1_STRING_get0_data + EXPECT_STREQ((const char *)ASN1_STRING_get0_data(ia5TestString),TestString); + // Testing ia5TestString + ASN1_IA5STRING_free(ia5TestString); +} + + +TEST(Asn1Test, c2i_ASN1_INTEGER_to_BN_to_hex) { + // ASN.1 encoding is big endian, so we can't just pass the bytes from a C++ + // int or long, as laid out in memory, to c2i_ASN1_INTEGER() because we may + // be running on a little or big endian machine. Therefore, we use arrays + // of uint8_t bytes that are explicitly laid out in big endian order. + + std::map,const char*> values { + { { 0x00 }, "0" }, + { { 0x12 }, "12" }, + { { 0xEC }, "-14" }, + { { 0x12, 0x34 }, "1234" }, + { { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, "0102030405060708" }, + }; + + for (auto const& [bytes, hex] : values) { + const uint8_t *pbytes {bytes.data()}; + ASN1_INTEGER *asn1int {nullptr}; + + ASSERT_EQ(c2i_ASN1_INTEGER(&asn1int, &pbytes, bytes.size()), asn1int); + ASSERT_NE(nullptr, asn1int) << ERR_error_string(ERR_get_error(), nullptr); + ASSERT_EQ(bytes.data() + bytes.size(), pbytes); + + BIGNUM *bignum = ASN1_INTEGER_to_BN(asn1int, nullptr); + ASSERT_NE(nullptr, bignum); + + char *str = BN_bn2hex(bignum); + ASSERT_NE(nullptr, str); + ASSERT_STREQ(hex, str); + + OPENSSL_free(str); + BN_free(bignum); + ASN1_INTEGER_free(asn1int); + } +} + + +static const time_t SecsInAnHour=3600; +static const int HoursInADay=24; +// In this test the diff is 5 days and 17 seconds +static const int TestNumDays=5; +static const int TestNumSecs=17; + +TEST(Asn1Test, asn1time) { + // Test ASN1_TIME_new + ASN1_TIME *asn1TestTime = ASN1_TIME_new(); + EXPECT_TRUE(asn1TestTime != nullptr); + time_t from=0; + // Test ASN1_TIME_set + EXPECT_TRUE(ASN1_TIME_set(asn1TestTime,from) != nullptr); + ASN1_TIME *asn1TestTimeTo = ASN1_TIME_new(); + EXPECT_TRUE(asn1TestTimeTo != nullptr); + time_t to = SecsInAnHour * HoursInADay * TestNumDays + TestNumSecs; + EXPECT_TRUE(ASN1_TIME_set(asn1TestTimeTo,to) != nullptr); + int out_days=0, out_seconds=0; + // Test ASN1_TIME_diff + EXPECT_EQ(ASN1_TIME_diff(&out_days, &out_seconds, + asn1TestTime, asn1TestTimeTo), 1); + EXPECT_TRUE(out_days==TestNumDays && out_seconds==TestNumSecs); + // Test ASN1_TIME_free + ASN1_TIME_free(asn1TestTime); + ASN1_TIME_free(asn1TestTimeTo); +} diff --git a/bssl-compat/test/test_bn.cc b/bssl-compat/test/test_bn.cc new file mode 100644 index 00000000000..9c38f3bb298 --- /dev/null +++ b/bssl-compat/test/test_bn.cc @@ -0,0 +1,74 @@ +#include +#include +#include + +TEST(BNTest, BN) { + BN_free(nullptr); + + BIGNUM *b1 = BN_new(); + EXPECT_NE(b1, nullptr); + + EXPECT_EQ(BN_num_bits(b1), 0); + + EXPECT_EQ(BN_add_word(b1, 0x499602D2), 1); + + EXPECT_EQ(BN_num_bits(b1), 31); + + char *hex1 = BN_bn2hex(b1); + EXPECT_NE(hex1, nullptr); + EXPECT_STREQ(hex1, "499602d2"); + OPENSSL_free(hex1); + + BIGNUM *b2 = BN_dup(b1); + EXPECT_NE(b2, nullptr); + + char *hex2 = BN_bn2hex(b2); + EXPECT_NE(hex2, nullptr); + EXPECT_STREQ(hex2, "499602d2"); + OPENSSL_free(hex2); + + EXPECT_EQ(BN_add_word(b2, 0x1), 1); + + hex2 = BN_bn2hex(b2); + EXPECT_NE(hex2, nullptr); + EXPECT_STREQ(hex2, "499602d3"); + OPENSSL_free(hex2); + + hex1 = BN_bn2hex(b1); + EXPECT_NE(hex1, nullptr); + EXPECT_STREQ(hex1, "499602d2"); + OPENSSL_free(hex1); + + EXPECT_TRUE(BN_ucmp(b1, b2) < 0); + EXPECT_TRUE(BN_ucmp(b2, b1) > 0); + + BIGNUM *b3 = BN_dup(b2); + EXPECT_TRUE(BN_ucmp(b2, b3) == 0); + EXPECT_TRUE(BN_ucmp(b3, b2) == 0); + BN_free(b3); + + BN_free(b1); + BN_free(b2); +} + +TEST(BNTest, test_BN_cmp_word) { + bssl::UniquePtr zero {BN_new()}; + bssl::UniquePtr one {BN_new()}; + bssl::UniquePtr two {BN_new()}; + + ASSERT_TRUE(BN_set_word (zero.get(), 0)); + ASSERT_TRUE(BN_set_word (one.get(), 1)); + ASSERT_TRUE(BN_set_word (two.get(), 2)); + + ASSERT_EQ(0, BN_cmp_word (zero.get(), 0)); + ASSERT_EQ(0, BN_cmp_word (one.get(), 1)); + ASSERT_EQ(0, BN_cmp_word (two.get(), 2)); + + ASSERT_EQ(-1, BN_cmp_word (zero.get(), 1)); + ASSERT_EQ(-1, BN_cmp_word (zero.get(), 2)); + ASSERT_EQ(-1, BN_cmp_word (one.get(), 2)); + + ASSERT_EQ(1, BN_cmp_word (one.get(), 0)); + ASSERT_EQ(1, BN_cmp_word (two.get(), 0)); + ASSERT_EQ(1, BN_cmp_word (two.get(), 1)); +} \ No newline at end of file diff --git a/bssl-compat/test/test_cipher.cc b/bssl-compat/test/test_cipher.cc new file mode 100644 index 00000000000..c69a9a3a62f --- /dev/null +++ b/bssl-compat/test/test_cipher.cc @@ -0,0 +1,47 @@ +#include +#include +#include + + +TEST(CipherTest, cipher1) { + const EVP_CIPHER *cipher = EVP_aes_256_cbc(); + + ASSERT_TRUE(cipher); + + std::vector key(EVP_CIPHER_key_length(cipher)); + std::vector iv(EVP_CIPHER_iv_length(cipher)); + + ASSERT_EQ(1, RAND_bytes(key.data(), key.size())); + ASSERT_EQ(1, RAND_bytes(iv.data(), iv.size())); + + std::vector plaintext1 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + std::vector ciphertext; + std::vector plaintext2; + + { + int l1, l2; + bssl::UniquePtr ctx(EVP_CIPHER_CTX_new()); + + ciphertext.resize(plaintext1.size() + EVP_CIPHER_block_size(cipher)); + ASSERT_EQ(1, EVP_EncryptInit_ex(ctx.get(), cipher, nullptr, key.data(), iv.data())); + ASSERT_EQ(1, EVP_EncryptUpdate(ctx.get(), ciphertext.data(), &l1, plaintext1.data(), plaintext1.size())); + ASSERT_EQ(1, EVP_EncryptFinal_ex(ctx.get(), ciphertext.data() + l1, &l2)); + ciphertext.resize(l1 + l2); // Resize to the actual encrypted byte count + } + + { + int l1, l2; + bssl::UniquePtr ctx(EVP_CIPHER_CTX_new()); + + plaintext2.resize(plaintext1.size() + EVP_CIPHER_block_size(cipher)); + ASSERT_EQ(1, EVP_DecryptInit_ex(ctx.get(), cipher, nullptr, key.data(), iv.data())); + ASSERT_EQ(1, EVP_DecryptUpdate(ctx.get(), plaintext2.data(), &l1, ciphertext.data(), ciphertext.size())); + ASSERT_EQ(1, EVP_DecryptFinal_ex(ctx.get(), plaintext2.data() + l1, &l2)); + plaintext2.resize(l1 + l2); // Resize to the actual decrypted byte count + } + + ASSERT_EQ(plaintext1, plaintext2); +} \ No newline at end of file diff --git a/bssl-compat/test/test_crypto.cc b/bssl-compat/test/test_crypto.cc new file mode 100644 index 00000000000..e4a882154e2 --- /dev/null +++ b/bssl-compat/test/test_crypto.cc @@ -0,0 +1,7 @@ +#include +#include + +TEST(TestCrypto, test_FIPS_mode) { + ASSERT_EQ(0, FIPS_mode()); +} + diff --git a/bssl-compat/test/test_ec_key.cc b/bssl-compat/test/test_ec_key.cc new file mode 100644 index 00000000000..b28c3a24ae6 --- /dev/null +++ b/bssl-compat/test/test_ec_key.cc @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include + + +// Copied from: boringssl/crypto/fipsmodule/ec/ec_test.cc +static const uint8_t kECKeyWithoutPublic[] = { + 0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0, + 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e, + 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77, + 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, +}; + +TEST(EC_KEYTest, test_EC_KEY_parse_private_key) { + CBS cbs; + CBS_init(&cbs, kECKeyWithoutPublic, sizeof(kECKeyWithoutPublic)); + + EC_KEY *key = EC_KEY_parse_private_key(&cbs, nullptr); + ASSERT_TRUE(key); + + const EC_GROUP *group = EC_KEY_get0_group(key); + ASSERT_TRUE(group); + + ASSERT_EQ(NID_X9_62_prime256v1, EC_GROUP_get_curve_name(group)); + + const BIGNUM *order {EC_GROUP_get0_order(group)}; + ASSERT_TRUE(order); + ASSERT_EQ(256, BN_num_bits(order)); + + ASSERT_EQ(256, EC_GROUP_get_degree(group)); + + EC_KEY_free(key); +} + +TEST(EC_KEYTest, test_EC_KEY_new_by_curve_name) { + EC_KEY *myecc = nullptr; + + /* ---------------------------------------------------------- * + * Create a EC key sructure, setting the group type from NID * + * ---------------------------------------------------------- */ + myecc = EC_KEY_new_by_curve_name(NID_secp224r1); + EXPECT_NE(myecc, nullptr); + + EC_KEY_free(myecc); +} + +TEST(EC_KEYTest, test_EC_KEY_set_public_key_affine_coordinates) { + CBS cbs; + CBS_init(&cbs, kECKeyWithoutPublic, sizeof(kECKeyWithoutPublic)); + + EC_KEY *key = EC_KEY_parse_private_key(&cbs, nullptr); + ASSERT_TRUE(key); + + const EC_GROUP *group = EC_KEY_get0_group(key); + ASSERT_TRUE(group); + + const BIGNUM *x {EC_GROUP_get0_order(group)}; + const BIGNUM *y {EC_GROUP_get0_order(group)}; + + // TODO run the openssl test + // check_ec_key_field_public_range_test + // in test/ectest.c + // at this point just test compiles + EC_KEY_set_public_key_affine_coordinates(key, x, y); + + EC_KEY_free(key); +} \ No newline at end of file diff --git a/bssl-compat/test/test_err.cc b/bssl-compat/test/test_err.cc new file mode 100644 index 00000000000..db19b257d29 --- /dev/null +++ b/bssl-compat/test/test_err.cc @@ -0,0 +1,52 @@ +#include +#include +#include +#include + + +TEST(ErrTest, test_ERR_func_error_string) { + ASSERT_STREQ("OPENSSL_internal", ERR_func_error_string(0)); + ASSERT_STREQ("OPENSSL_internal", ERR_func_error_string(42)); +} + + +TEST(ErrTest, test_ERR_LIB_SSL_ERR_R_MALLOC_FAILURE) { + char buf[256]{}; + + ERR_clear_error(); + + ERR_put_error(ERR_LIB_SSL, 0, ERR_R_MALLOC_FAILURE, __FILE__, __LINE__); + + uint32_t e = ERR_get_error(); + + EXPECT_EQ(0x10000041, e); + EXPECT_STREQ("SSL routines", ERR_lib_error_string(e)); + EXPECT_STREQ("malloc failure", ERR_reason_error_string(e)); + EXPECT_STREQ("error:10000041:SSL routines:OPENSSL_internal:malloc failure", ERR_error_string_n(e, buf, sizeof(buf))); +} + + +/** + * This covers a fix for test IpVersionsClientVersions/SslCertficateIntegrationTest.ServerEcdsaClientRsaOnlyWithAccessLog/IPv4_TLSv1_3 + * which fails because of an error string mismatch between BoringSSL's string and OpenSSL's string: + * + * Expected: "DOWNSTREAM_TRANSPORT_FAILURE_REASON=TLS_error:_268435709:SSL_routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS" + * Actual: "DOWNSTREAM_TRANSPORT_FAILURE_REASON=TLS_error:_167772278:SSL_routines:OPENSSL_internal:no_suitable_signature_algorithm FILTER_CHAIN_NAME=-" + */ +TEST(ErrTest, test_SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM) { + char buf[256]{}; + ERR_clear_error(); + +#ifdef BSSL_COMPAT + ERR_put_error(ERR_LIB_SSL, 0, ossl_SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM, __FILE__, __LINE__); +#else // BoringSSL + ERR_put_error(ERR_LIB_SSL, 0, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS, __FILE__, __LINE__); +#endif + + uint32_t e = ERR_get_error(); + + EXPECT_EQ(268435709, e); + EXPECT_STREQ("SSL routines", ERR_lib_error_string(e)); + EXPECT_STREQ("NO_COMMON_SIGNATURE_ALGORITHMS", ERR_reason_error_string(e)); + EXPECT_STREQ("error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS", ERR_error_string_n(e, buf, sizeof(buf))); +} diff --git a/bssl-compat/test/test_evp.cc b/bssl-compat/test/test_evp.cc new file mode 100644 index 00000000000..673a88b9e1f --- /dev/null +++ b/bssl-compat/test/test_evp.cc @@ -0,0 +1,116 @@ +#include +#include +#include + + +TEST(EVPTest, EVP1) { + EVP_PKEY_free(nullptr); + EVP_PKEY_free(EVP_PKEY_new()); +} + +TEST(EVPTest, EVP2) { + bssl::UniquePtr k1(EVP_PKEY_new()); + EXPECT_EQ(EVP_PKEY_NONE, EVP_PKEY_id(k1.get())); +} + +TEST(EVPTest, EVP3) { + static const uint8_t keystr[] = {0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcd, 0x00, 0x81, 0xea, 0x7b, 0x2a, 0xe1, 0xea, 0x06, 0xd5, 0x9f, 0x7c, 0x73, 0xd9, 0xff, 0xb9, 0x4a, 0x09, 0x61, 0x5c, 0x2e, 0x4b, 0xa7, 0xc6, 0x36, 0xce, 0xf0, 0x8d, 0xd3, 0x53, 0x3e, 0xc3, 0x18, 0x55, 0x25, 0xb0, 0x15, 0xc7, 0x69, 0xb9, 0x9a, 0x77, 0xd6, 0x72, 0x5b, 0xf9, 0xc3, 0x53, 0x2a, 0x9b, 0x6e, 0x5f, 0x66, 0x27, 0xd5, 0xfb, 0x85, 0x16, 0x07, 0x68, 0xd3, 0xdd, 0xa9, 0xcb, 0xd3, 0x59, 0x74, 0x51, 0x17, 0x17, 0xdc, 0x3d, 0x30, 0x9d, 0x2f, 0xc4, 0x7e, 0xe4, 0x1f, 0x97, 0xe3, 0x2a, 0xdb, 0x7f, 0x9d, 0xd8, 0x64, 0xa1, 0xc4, 0x76, 0x7a, 0x66, 0x6e, 0xcd, 0x71, 0xbc, 0x1a, 0xac, 0xf5, 0xe7, 0x51, 0x7f, 0x4b, 0x38, 0x59, 0x4f, 0xea, 0x9b, 0x05, 0xe4, 0x2d, 0x5a, 0xda, 0x99, 0x12, 0x00, 0x80, 0x13, 0xe4, 0x53, 0x16, 0xa4, 0xd9, 0xbb, 0x8e, 0xd0, 0x86, 0xb8, 0x8d, 0x28, 0x75, 0x8b, 0xac, 0xaf, 0x92, 0x2d, 0x46, 0xa8, 0x68, 0xb4, 0x85, 0xd2, 0x39, 0xc9, 0xba, 0xeb, 0x0e, 0x2b, 0x64, 0x59, 0x27, 0x10, 0xf4, 0x2b, 0x2d, 0x1e, 0xa0, 0xa4, 0xb4, 0x80, 0x2c, 0x0b, 0xec, 0xab, 0x32, 0x8f, 0x8a, 0x68, 0xb0, 0x07, 0x3b, 0xdb, 0x54, 0x6f, 0xee, 0xa9, 0x80, 0x9d, 0x28, 0x49, 0x91, 0x2b, 0x39, 0x0c, 0x15, 0x32, 0xbc, 0x7e, 0x29, 0xc7, 0x65, 0x8f, 0x81, 0x75, 0xfa, 0xe4, 0x6f, 0x34, 0x33, 0x2f, 0xf8, 0x7b, 0xca, 0xb3, 0xe4, 0x06, 0x49, 0xb9, 0x85, 0x77, 0x86, 0x9d, 0xa0, 0xea, 0x71, 0x83, 0x53, 0xf0, 0x72, 0x27, 0x54, 0x88, 0x69, 0x13, 0x64, 0x87, 0x60, 0xd1, 0x22, 0xbe, 0x67, 0x6e, 0x0f, 0xc4, 0x83, 0xdd, 0x20, 0xff, 0xc3, 0x1b, 0xda, 0x96, 0xa3, 0x19, 0x66, 0xc9, 0xaa, 0x2e, 0x75, 0xad, 0x03, 0xde, 0x47, 0xe1, 0xc4, 0x4f, 0x02, 0x03, 0x01, 0x00, 0x01}; + + CBS cbs; + CBS_init(&cbs, keystr, sizeof(keystr)); + bssl::UniquePtr k1(EVP_parse_public_key(&cbs)); + EXPECT_TRUE(k1.get()); + EXPECT_EQ(EVP_PKEY_RSA, EVP_PKEY_id(k1.get())); + + RSA *rsa1 = EVP_PKEY_get0_RSA(k1.get()); + EXPECT_TRUE(rsa1); + + RSA *rsa2 = EVP_PKEY_get1_RSA(k1.get()); + EXPECT_TRUE(rsa2); + + // We have ownership of rsa2 at this point. However, we pass ownership into + // the EVP_PKEY_assign_RSA() call so that when the EVP_PKEY (k2) is freed, + // the RSA (rsa2) is also freed. + + bssl::UniquePtr k2(EVP_PKEY_new()); + EXPECT_EQ(1, EVP_PKEY_assign_RSA(k2.get(), rsa2)); + EXPECT_EQ(EVP_PKEY_RSA, EVP_PKEY_id(k2.get())); +} + +TEST(EVPTest, EVP4) { + static const uint8_t keystr[] = {0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x2c, 0x15, 0x0f, 0x42, 0x9c, 0xe7, 0x0f, 0x21, 0x6c, 0x25, 0x2c, 0xf5, 0xe0, 0x62, 0xce, 0x1f, 0x63, 0x9c, 0xd5, 0xd1, 0x65, 0xc7, 0xf8, 0x94, 0x24, 0x07, 0x2c, 0x27, 0x19, 0x7d, 0x78, 0xb3, 0x3b, 0x92, 0x0e, 0x95, 0xcd, 0xb6, 0x64, 0xe9, 0x90, 0xdc, 0xf0, 0xcf, 0xea, 0x0d, 0x94, 0xe2, 0xa8, 0xe6, 0xaf, 0x9d, 0x0e, 0x58, 0x05, 0x6e, 0x65, 0x31, 0x04, 0x92, 0x5b, 0x9f, 0xe6, 0xc9};; + + CBS cbs; + CBS_init(&cbs, keystr, sizeof(keystr)); + bssl::UniquePtr k1(EVP_parse_public_key(&cbs)); + EXPECT_TRUE(k1.get()); + EXPECT_EQ(EVP_PKEY_EC, EVP_PKEY_id(k1.get())); + + EC_KEY *ec1 = EVP_PKEY_get0_EC_KEY(k1.get()); + EXPECT_TRUE(ec1); + + EC_KEY *ec2 = EVP_PKEY_get1_EC_KEY(k1.get()); + EXPECT_TRUE(ec2); + + // We have ownership of ec2 at this point. However, we pass ownership into + // the EVP_PKEY_assign_EC_KEY() call so that when the EVP_PKEY (k2) is freed, + // the EC_KEY (ec2) is also freed. + + bssl::UniquePtr k2(EVP_PKEY_new()); + EXPECT_EQ(1, EVP_PKEY_assign_EC_KEY(k2.get(), ec2)); + EXPECT_EQ(EVP_PKEY_EC, EVP_PKEY_id(k2.get())); +} + +TEST(EVPTest, test_EVP_PKEY_get_raw_public_key_RSA) { + static const uint8_t keystr[] = {0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcd, 0x00, 0x81, 0xea, 0x7b, 0x2a, 0xe1, 0xea, 0x06, 0xd5, 0x9f, 0x7c, 0x73, 0xd9, 0xff, 0xb9, 0x4a, 0x09, 0x61, 0x5c, 0x2e, 0x4b, 0xa7, 0xc6, 0x36, 0xce, 0xf0, 0x8d, 0xd3, 0x53, 0x3e, 0xc3, 0x18, 0x55, 0x25, 0xb0, 0x15, 0xc7, 0x69, 0xb9, 0x9a, 0x77, 0xd6, 0x72, 0x5b, 0xf9, 0xc3, 0x53, 0x2a, 0x9b, 0x6e, 0x5f, 0x66, 0x27, 0xd5, 0xfb, 0x85, 0x16, 0x07, 0x68, 0xd3, 0xdd, 0xa9, 0xcb, 0xd3, 0x59, 0x74, 0x51, 0x17, 0x17, 0xdc, 0x3d, 0x30, 0x9d, 0x2f, 0xc4, 0x7e, 0xe4, 0x1f, 0x97, 0xe3, 0x2a, 0xdb, 0x7f, 0x9d, 0xd8, 0x64, 0xa1, 0xc4, 0x76, 0x7a, 0x66, 0x6e, 0xcd, 0x71, 0xbc, 0x1a, 0xac, 0xf5, 0xe7, 0x51, 0x7f, 0x4b, 0x38, 0x59, 0x4f, 0xea, 0x9b, 0x05, 0xe4, 0x2d, 0x5a, 0xda, 0x99, 0x12, 0x00, 0x80, 0x13, 0xe4, 0x53, 0x16, 0xa4, 0xd9, 0xbb, 0x8e, 0xd0, 0x86, 0xb8, 0x8d, 0x28, 0x75, 0x8b, 0xac, 0xaf, 0x92, 0x2d, 0x46, 0xa8, 0x68, 0xb4, 0x85, 0xd2, 0x39, 0xc9, 0xba, 0xeb, 0x0e, 0x2b, 0x64, 0x59, 0x27, 0x10, 0xf4, 0x2b, 0x2d, 0x1e, 0xa0, 0xa4, 0xb4, 0x80, 0x2c, 0x0b, 0xec, 0xab, 0x32, 0x8f, 0x8a, 0x68, 0xb0, 0x07, 0x3b, 0xdb, 0x54, 0x6f, 0xee, 0xa9, 0x80, 0x9d, 0x28, 0x49, 0x91, 0x2b, 0x39, 0x0c, 0x15, 0x32, 0xbc, 0x7e, 0x29, 0xc7, 0x65, 0x8f, 0x81, 0x75, 0xfa, 0xe4, 0x6f, 0x34, 0x33, 0x2f, 0xf8, 0x7b, 0xca, 0xb3, 0xe4, 0x06, 0x49, 0xb9, 0x85, 0x77, 0x86, 0x9d, 0xa0, 0xea, 0x71, 0x83, 0x53, 0xf0, 0x72, 0x27, 0x54, 0x88, 0x69, 0x13, 0x64, 0x87, 0x60, 0xd1, 0x22, 0xbe, 0x67, 0x6e, 0x0f, 0xc4, 0x83, 0xdd, 0x20, 0xff, 0xc3, 0x1b, 0xda, 0x96, 0xa3, 0x19, 0x66, 0xc9, 0xaa, 0x2e, 0x75, 0xad, 0x03, 0xde, 0x47, 0xe1, 0xc4, 0x4f, 0x02, 0x03, 0x01, 0x00, 0x01}; + + CBS cbs; + CBS_init(&cbs, keystr, sizeof(keystr)); + bssl::UniquePtr pkey {EVP_parse_public_key(&cbs)}; + EXPECT_TRUE(pkey.get()); + EXPECT_EQ(EVP_PKEY_RSA, EVP_PKEY_id(pkey.get())); + + size_t len = 999; + EXPECT_FALSE(EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &len)); + ASSERT_EQ(999, len); +} + +TEST(EVPTest, test_EVP_PKEY_get_raw_public_key_EC) { + static const uint8_t keystr[] = {0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x2c, 0x15, 0x0f, 0x42, 0x9c, 0xe7, 0x0f, 0x21, 0x6c, 0x25, 0x2c, 0xf5, 0xe0, 0x62, 0xce, 0x1f, 0x63, 0x9c, 0xd5, 0xd1, 0x65, 0xc7, 0xf8, 0x94, 0x24, 0x07, 0x2c, 0x27, 0x19, 0x7d, 0x78, 0xb3, 0x3b, 0x92, 0x0e, 0x95, 0xcd, 0xb6, 0x64, 0xe9, 0x90, 0xdc, 0xf0, 0xcf, 0xea, 0x0d, 0x94, 0xe2, 0xa8, 0xe6, 0xaf, 0x9d, 0x0e, 0x58, 0x05, 0x6e, 0x65, 0x31, 0x04, 0x92, 0x5b, 0x9f, 0xe6, 0xc9}; + + CBS cbs; + CBS_init(&cbs, keystr, sizeof(keystr)); + bssl::UniquePtr pkey {EVP_parse_public_key(&cbs)}; + EXPECT_TRUE(pkey.get()); + EXPECT_EQ(EVP_PKEY_EC, EVP_PKEY_id(pkey.get())); + + size_t len = 999; + EXPECT_FALSE(EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &len)); + ASSERT_EQ(999, len); +} + +TEST(EVPTest, test_EVP_PKEY_get_raw_public_key_X25519) { + static const uint8_t keystr[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x6e, 0x03, 0x21, 0x00, 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c}; + + CBS cbs; + CBS_init(&cbs, keystr, sizeof(keystr)); + bssl::UniquePtr pkey {EVP_parse_public_key(&cbs)}; + EXPECT_TRUE(pkey.get()); + EXPECT_EQ(EVP_PKEY_X25519, EVP_PKEY_id(pkey.get())); + + size_t len = 999; + ASSERT_TRUE(EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &len)); + ASSERT_EQ(32, len); + + unsigned char raw[32]; + len = sizeof(raw); + ASSERT_TRUE(EVP_PKEY_get_raw_public_key(pkey.get(), raw, &len)); + + static const uint8_t expected_raw[] { 0xE6, 0xDB, 0x68, 0x67, 0x58, 0x30, 0x30, 0xDB, 0x35, 0x94, 0xC1, 0xA4, 0x24, 0xB1, 0x5F, 0x7C, 0x72, 0x66, 0x24, 0xEC, 0x26, 0xB3, 0x35, 0x3B, 0x10, 0xA9, 0x03, 0xA6, 0xD0, 0xAB, 0x1C, 0x4C }; + + ASSERT_EQ(sizeof(expected_raw), len); + + for (int i = 0; i < len; i++) { + ASSERT_EQ(raw[i], expected_raw[i]); + } +} diff --git a/bssl-compat/test/test_hmac.cc b/bssl-compat/test/test_hmac.cc new file mode 100644 index 00000000000..d1db5d8bf35 --- /dev/null +++ b/bssl-compat/test/test_hmac.cc @@ -0,0 +1,23 @@ +#include +#include + + +TEST(HMACTest, test_HMAC) { + std::string key {"hello"}; + std::string data {"plain text data"}; + std::string digest {"27a8d47ded4d53080d3582dbb396ba74"}; + + uint8_t out[EVP_MAX_MD_SIZE]; + unsigned int out_len; + uint8_t *hmac = HMAC(EVP_md5(), key.data(), key.length(), (uint8_t*)data.data(), data.length(), out, &out_len); + ASSERT_TRUE(hmac); + ASSERT_EQ(digest.length() / 2, out_len); + + char hex[EVP_MAX_MD_SIZE * 2]; + for (int i = 0; i < out_len; i++) { + sprintf(&(hex[i * 2]), "%02x", hmac[i]); + } + hex[out_len * 2] = '\0'; + + EXPECT_EQ(digest, hex); +} diff --git a/bssl-compat/test/test_misc.cc b/bssl-compat/test/test_misc.cc new file mode 100644 index 00000000000..f223e061142 --- /dev/null +++ b/bssl-compat/test/test_misc.cc @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include + + +TEST(MiscTest, test_UniquePtr_ASN1_OBJECT) { + bssl::UniquePtr p; +} + +TEST(MiscTest, test_UniquePtr_EC_KEY) { + bssl::UniquePtr p; +} + +TEST(MiscTest, test_UniquePtr_EVP_MD_CTX) { + bssl::UniquePtr p; +} + +TEST(MiscTest, test_UniquePtr_ECDSA_SIG) { + bssl::UniquePtr p; +} + diff --git a/bssl-compat/test/test_pem.cc b/bssl-compat/test/test_pem.cc new file mode 100644 index 00000000000..500d3fc115a --- /dev/null +++ b/bssl-compat/test/test_pem.cc @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include "certs/root_ca_cert.pem.h" +#include "certs/root_ca_key.pem.h" + +TEST(PEMTest, testPEM_read) { + // test PEM_read_bio_PUBKEY exists + + std::string cert_data = { +"-----BEGIN CERTIFICATE-----" +"MIIEBzCCAu+gAwIBAgIUNT7DdWdpRF5GXsgldAUwg/w9ofMwDQYJKoZIhvcNAQEL" +"BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD" +"VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD" +"VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew" +"HhcNMjMwNDE5MTg0MTQ1WhcNMjUwNDE4MTg0MTQ1WjCBijELMAkGA1UEBhMCR0Ix" +"FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u" +"IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l" +"ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD" +"ggEPADCCAQoCggEBAMxXI2ABGv7MVb/vLKtgR6PJQzLIXsQHnIb80JuWAAbDujwO" +"a6YuYypjpbF5sZaxNK2KHZH7IuBRNy8asiz8xjt/BK3+xneAIWYGGYtIR+l2teho" +"eRCBdoIGruVzrHuE+FWJqt7f5eiOtbzzAeoKXMLiTwX8CF9NA0ugDjLZRlSzRS3d" +"chKdgq542sOQ0vwiDtdTovmZT/5RweGumZ1uvAUP8DynrxKdzffv0c30nEpcCbOI" +"SqSRgDUwOwCL2dXshJM3EBV0Ycn+yvvqCvDlWtqILvStw9gTHNdo+fn7g2v+/GZb" +"OnOx1Yp9JlzcN5JchKd47QwvX7Llk7WV4rniv3ECAwEAAaNjMGEwDwYDVR0TAQH/" +"BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFG0cchLrL8gNr/H1Ykr" +"XoKcRfeUMB8GA1UdIwQYMBaAFFG0cchLrL8gNr/H1YkrXoKcRfeUMA0GCSqGSIb3" +"DQEBCwUAA4IBAQBonfu+Om04XKWQU6PQlAPoz3vxYec9UYSdL32wYiMEBj8OO/Sv" +"7a9aYRpahkX27pT7J0erL9jR+p+gAtmvCWl7SYzfb0LQzUgPPImb5bcEZ/Q80+Uv" +"IffCl3ChWEqErg0JJdMSc5qj1WpTU9+Y4YXMddviYsQgVNDea7w1v+hFAp4BlyKP" +"OE8h9TQDQErkxI+3kulc2X7OSvGFUDVJpSTPdYd68uSuW4pf7E9l2SbNDaTqNKFI" +"EyhYYl6v/HUBYNiPnRUPHdkz+Ypt/9+YxkdNc680q0mGDjU1tWZX0/XVE3pETp52" +"tysI3R1cdVCam29BtNXUHfhBxjfxtH+zvhjK" +"-----END CERTIFICATE-----\n" + }; + + X509 *cert = nullptr; + + BIO *pem = BIO_new_mem_buf(cert_data.c_str(), static_cast(cert_data.length())); +// BIO *pem = BIO_new_mem_buf(root_ca_cert_pem_str, strlen(root_ca_cert_pem_str)); + ASSERT_NE(pem, nullptr); + + cert = PEM_read_bio_X509(pem, NULL, 0, NULL); + if ( cert ) { + // openssl x509 -pubkey -noout -in root_ca_cert.pem > root_pubkey.pem + EVP_PKEY *result = nullptr; + PEM_read_bio_PUBKEY(pem, &result, nullptr, nullptr); + EXPECT_NE(result, nullptr); + if ( result ) { + EVP_PKEY_free(result); + } + else { + unsigned long error = ERR_peek_last_error(); + char error_msg [256]; + ERR_error_string_n(error, error_msg, sizeof(error_msg)); + std::cout << "OpenSSL Error: " << error_msg << std::endl; + } + } + + BIO_free(pem); +} + +TEST(PEMTest, test_PEM_write_bio_X509) { + bssl::UniquePtr pem1 {BIO_new_mem_buf(root_ca_cert_pem_str, strlen(root_ca_cert_pem_str))}; + ASSERT_TRUE(pem1); + + bssl::UniquePtr cert {PEM_read_bio_X509(pem1.get(), NULL, 0, NULL)}; + ASSERT_TRUE(cert) << ERR_error_string(ERR_get_error(), nullptr); + + bssl::UniquePtr pem2 {BIO_new(BIO_s_mem())}; + ASSERT_TRUE(PEM_write_bio_X509(pem2.get(), cert.get())); + + BUF_MEM *m {nullptr}; + BIO_get_mem_ptr(pem2.get(), &m); + ASSERT_TRUE(m); + + // Check the PEM_write_bio_X509() output is the + // same as the original root_ca_cert_pem_str input + + ASSERT_EQ(m->length, strlen(root_ca_cert_pem_str)); + for(size_t i = 0; i < strlen(root_ca_cert_pem_str); i++) { + ASSERT_EQ(m->data[i], root_ca_cert_pem_str[i]); + } +} + +TEST(PEMTest, test_PEM_read_bio_X509_AUX) { + // This certificate has extra trust information (serverAuth) which is only + // processed by the "AUX" versions of the PEM_read/write_bio_X509() functions. + const char *cert_pem_str { + "-----BEGIN TRUSTED CERTIFICATE-----\n" + "MIIEBzCCAu+gAwIBAgIUNT7DdWdpRF5GXsgldAUwg/w9ofMwDQYJKoZIhvcNAQEL" + "BQAwgYoxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1UeW5lIGFuZCBXZWFyMRwwGgYD" + "VQQHDBNOZXdjYXN0bGUgdXBvbiBUeW5lMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYD" + "VQQLDBNSZWQgSGF0IEVuZ2luZWVyaW5nMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0Ew" + "HhcNMjMwNDE5MTg0MTQ1WhcNMjUwNDE4MTg0MTQ1WjCBijELMAkGA1UEBhMCR0Ix" + "FjAUBgNVBAgMDVR5bmUgYW5kIFdlYXIxHDAaBgNVBAcME05ld2Nhc3RsZSB1cG9u" + "IFR5bmUxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAsME1JlZCBIYXQgRW5naW5l" + "ZXJpbmcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD" + "ggEPADCCAQoCggEBAMxXI2ABGv7MVb/vLKtgR6PJQzLIXsQHnIb80JuWAAbDujwO" + "a6YuYypjpbF5sZaxNK2KHZH7IuBRNy8asiz8xjt/BK3+xneAIWYGGYtIR+l2teho" + "eRCBdoIGruVzrHuE+FWJqt7f5eiOtbzzAeoKXMLiTwX8CF9NA0ugDjLZRlSzRS3d" + "chKdgq542sOQ0vwiDtdTovmZT/5RweGumZ1uvAUP8DynrxKdzffv0c30nEpcCbOI" + "SqSRgDUwOwCL2dXshJM3EBV0Ycn+yvvqCvDlWtqILvStw9gTHNdo+fn7g2v+/GZb" + "OnOx1Yp9JlzcN5JchKd47QwvX7Llk7WV4rniv3ECAwEAAaNjMGEwDwYDVR0TAQH/" + "BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFG0cchLrL8gNr/H1Ykr" + "XoKcRfeUMB8GA1UdIwQYMBaAFFG0cchLrL8gNr/H1YkrXoKcRfeUMA0GCSqGSIb3" + "DQEBCwUAA4IBAQBonfu+Om04XKWQU6PQlAPoz3vxYec9UYSdL32wYiMEBj8OO/Sv" + "7a9aYRpahkX27pT7J0erL9jR+p+gAtmvCWl7SYzfb0LQzUgPPImb5bcEZ/Q80+Uv" + "IffCl3ChWEqErg0JJdMSc5qj1WpTU9+Y4YXMddviYsQgVNDea7w1v+hFAp4BlyKP" + "OE8h9TQDQErkxI+3kulc2X7OSvGFUDVJpSTPdYd68uSuW4pf7E9l2SbNDaTqNKFI" + "EyhYYl6v/HUBYNiPnRUPHdkz+Ypt/9+YxkdNc680q0mGDjU1tWZX0/XVE3pETp52" + "tysI3R1cdVCam29BtNXUHfhBxjfxtH+zvhjKMAwwCgYIKwYBBQUHAwE=\n" + "-----END TRUSTED CERTIFICATE-----\n" + }; + + bssl::UniquePtr pem1 {BIO_new_mem_buf(cert_pem_str, strlen(cert_pem_str))}; + ASSERT_TRUE(pem1); + + // Reading the certificate with the "AUX" PEM_read_bio_X509_AUX() function + // will read in the additional trust information from the PEM string. + bssl::UniquePtr cert {PEM_read_bio_X509_AUX(pem1.get(), nullptr, nullptr, nullptr)}; + ASSERT_TRUE(cert) << ERR_error_string(ERR_get_error(), nullptr); + + // Writing the certificate with the "normal" PEM_write_bio_X509() function + // will omit the additional trust information from the resulting PEM string + bssl::UniquePtr pem2 {BIO_new(BIO_s_mem())}; + ASSERT_TRUE(PEM_write_bio_X509(pem2.get(), cert.get())); + + BUF_MEM *m1 {nullptr}; + BIO_get_mem_ptr(pem2.get(), &m1); + ASSERT_TRUE(m1); + + // Check the PEM_write_bio_X509() output is shorter than the original input + ASSERT_TRUE(m1->length < strlen(cert_pem_str)); +} diff --git a/bssl-compat/test/test_rsa.cc b/bssl-compat/test/test_rsa.cc new file mode 100644 index 00000000000..11e215dc407 --- /dev/null +++ b/bssl-compat/test/test_rsa.cc @@ -0,0 +1,46 @@ +#include +#include +#include + + +TEST(RSATest, test_RSA_set0_factors) { + bssl::UniquePtr key {RSA_new()}; + BIGNUM *p {BN_new()}; + BIGNUM *q {BN_new()}; + ASSERT_EQ(1, RSA_set0_factors(key.get(), p, q)); + const BIGNUM *p2 {}; + const BIGNUM *q2 {}; + RSA_get0_factors(key.get(), &p2, &q2); + ASSERT_EQ(p, p2); + ASSERT_EQ(q, q2); +} + +TEST(RSATest, test_RSA_set0_key) { + bssl::UniquePtr key {RSA_new()}; + BIGNUM *n {BN_new()}; + BIGNUM *e {BN_new()}; + BIGNUM *d {BN_new()}; + ASSERT_EQ(1, RSA_set0_key(key.get(), n, e, d)); + const BIGNUM *n2 {}; + const BIGNUM *e2 {}; + const BIGNUM *d2 {}; + RSA_get0_key(key.get(), &n2, &e2, &d2); + ASSERT_EQ(n2, n); + ASSERT_EQ(e2, e); + ASSERT_EQ(d2, d); +} + +TEST(RSATest, test_RSA_set0_crt_params) { + bssl::UniquePtr key {RSA_new()}; + BIGNUM *dmp1 {BN_new()}; + BIGNUM *dmq1 {BN_new()}; + BIGNUM *iqmp {BN_new()}; + ASSERT_EQ(1, RSA_set0_crt_params(key.get(), dmp1, dmq1, iqmp)); + const BIGNUM *dmp12 {}; + const BIGNUM *dmq12 {}; + const BIGNUM *iqmp2 {}; + RSA_get0_crt_params(key.get(), &dmp12, &dmq12, &iqmp2); + ASSERT_EQ(dmp12, dmp1); + ASSERT_EQ(dmq12, dmq1); + ASSERT_EQ(iqmp2, iqmp); +} \ No newline at end of file diff --git a/bssl-compat/test/test_sha256.cc b/bssl-compat/test/test_sha256.cc new file mode 100644 index 00000000000..5b2782b7fff --- /dev/null +++ b/bssl-compat/test/test_sha256.cc @@ -0,0 +1,32 @@ +#include +#include +#include + +TEST(SHA256Test, test_SHA256) { + + std::string data = { +"The winters in the latitude of Sullivan’s Island are seldom very severe, and in the fall of the year it is a rare event indeed when a fire is considered necessary. About the middle of October, 18—, there occurred, however, a day of remarkable chilliness.\n" + }; + + std::string more = { + "The Gold-Bug is a short story written by Edgar Allan Poe and published in 1843.\n" + }; + + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX ctx; + int res = SHA256_Init(&ctx); + EXPECT_EQ(res, 1); + res = SHA256_Update(&ctx, data.c_str(), data.size()); + EXPECT_EQ(res, 1); + res = SHA256_Update(&ctx, more.c_str(), more.size()); + EXPECT_EQ(res, 1); + res = SHA256_Final(hash, &ctx); + EXPECT_EQ(res, 1); + std::stringstream ss; + for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { + ss << std::hex << std::setw(2) << std::setfill('0') << (int) hash[i]; + } + // Refer to https://www.openssl.org/docs/man3.0/man1/openssl-dgst.html + // openssl dgst -hex + ASSERT_EQ(ss.str(), "517c7a7916ab9909104399f050daedbfe87d57f0543105cf9f00bd5426360a33"); +} \ No newline at end of file diff --git a/bssl-compat/test/test_ssl.cc b/bssl-compat/test/test_ssl.cc new file mode 100644 index 00000000000..3605efd199c --- /dev/null +++ b/bssl-compat/test/test_ssl.cc @@ -0,0 +1,1872 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "certs/client_2_cert_chain.pem.h" +#include "certs/client_2_key.pem.h" +#include "certs/server_1_cert.pem.h" +#include "certs/server_1_key.pem.h" +#include "certs/server_2_cert.pem.h" +#include "certs/server_2_cert_chain.pem.h" +#include "certs/server_2_key.pem.h" +#include "certs/root_ca_cert.pem.h" +#include "certs/intermediate_ca_1_cert.pem.h" +#include "certs/intermediate_ca_2_cert.pem.h" + + +class TempFile { + public: + + TempFile(const char *content) : m_path { "/tmp/XXXXXX" } + { + int fd { mkstemp(m_path.data()) }; + if (fd == -1) { + perror("mkstemp()"); + } + else { + for (int n, written = 0, len = strlen(content); written < len; written += n) { + if ((n = write(fd, content + written, len - written)) < 0) { + if (errno == EINTR || errno == EAGAIN) { + continue; + } + perror("write()"); + } + } + if (close(fd) == -1) { + perror("close()"); + } + } + } + + ~TempFile() { + if (unlink(m_path.c_str()) == -1) { + perror("unlink()"); + } + } + + const char *path() const { + return m_path.c_str(); + } + + private: + + std::string m_path { "/tmp/XXXXXX" }; +}; + + + +TEST(SSLTest, test_SSL_CTX_set_select_certificate_cb) { + signal(SIGPIPE, SIG_IGN); + + std::promise server_port; + std::set received_ext_types; + + // Start a TLS server with a (SSL_CTX_set_select_certificate_cb()) callback installed. + std::thread server([&]() { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + SSL_CTX_set_ex_data(ctx.get(), 0, &received_ext_types); // So the callback can fill it in + + // Install the callback. + SSL_CTX_set_select_certificate_cb(ctx.get(), [](const SSL_CLIENT_HELLO *client_hello) -> enum ssl_select_cert_result_t { + std::set *received_ext_types = static_cast*>(SSL_CTX_get_ex_data(SSL_get_SSL_CTX(client_hello->ssl), 0)); + + CBS extensions; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + + while (CBS_len(&extensions)) { + uint16_t type, length; + CBS_get_u16(&extensions, &type); + CBS_get_u16(&extensions, &length); + CBS_skip(&extensions, length); + received_ext_types->insert(type); + } + + return ssl_select_cert_success; + }); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + socklen_t addrlen = sizeof(addr); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, bind(sock, (struct sockaddr*)&addr, sizeof(addr))); + ASSERT_EQ(0, listen(sock, 1)); + ASSERT_EQ(0, getsockname(sock, (struct sockaddr*)&addr, &addrlen)); + server_port.set_value(ntohs(addr.sin_port)); + + int client = accept(sock, nullptr, nullptr); + SSL *ssl = SSL_new(ctx.get()); + SSL_set_fd(ssl, client); + SSL_accept(ssl); + SSL_write(ssl, "test", 4); + SSL_shutdown(ssl); + SSL_free(ssl); + close(client); + close(sock); + }); + + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + bssl::UniquePtr ssl (SSL_new(ctx.get())); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(server_port.get_future().get()); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, connect(sock, (const struct sockaddr *)&addr, sizeof(addr))); + SSL_set_fd(ssl.get(), sock); + SSL_connect(ssl.get()); + + // OpenSSL and BoringSSL clients send a slightly different set of client hello + // extensions by default, but this is the common set that we should expect. + std::set expected_ext_types { + TLSEXT_TYPE_extended_master_secret, + TLSEXT_TYPE_supported_groups, + TLSEXT_TYPE_ec_point_formats, + TLSEXT_TYPE_session_ticket, + TLSEXT_TYPE_signature_algorithms, + TLSEXT_TYPE_key_share, + TLSEXT_TYPE_psk_key_exchange_modes, + TLSEXT_TYPE_supported_versions + }; + + ASSERT_TRUE (std::includes(received_ext_types.begin(), received_ext_types.end(), + expected_ext_types.begin(), expected_ext_types.end())); + + server.join(); +} + + +static const char *version_str(uint16_t version) { + switch (version) { + case SSL3_VERSION : { return "SSL3_VERSION "; break; } + case TLS1_VERSION : { return "TLS1_VERSION "; break; } + case TLS1_1_VERSION : { return "TLS1_1_VERSION"; break; } + case TLS1_2_VERSION : { return "TLS1_2_VERSION"; break; } + case TLS1_3_VERSION : { return "TLS1_3_VERSION"; break; } + default: { return " "; break; } + }; +} + +TEST(SSLTest,SSL_CIPHER_get_min_version) { + std::map boring_cipher_versions { + {"ECDHE-ECDSA-AES128-GCM-SHA256", TLS1_2_VERSION}, + {"ECDHE-RSA-AES128-GCM-SHA256", TLS1_2_VERSION}, + {"ECDHE-ECDSA-AES256-GCM-SHA384", TLS1_2_VERSION}, + {"ECDHE-RSA-AES256-GCM-SHA384", TLS1_2_VERSION}, + {"ECDHE-ECDSA-CHACHA20-POLY1305", TLS1_2_VERSION}, + {"ECDHE-RSA-CHACHA20-POLY1305", TLS1_2_VERSION}, + {"ECDHE-PSK-CHACHA20-POLY1305", TLS1_2_VERSION}, + {"ECDHE-ECDSA-AES128-SHA", SSL3_VERSION }, + {"ECDHE-RSA-AES128-SHA", SSL3_VERSION }, + {"ECDHE-PSK-AES128-CBC-SHA", SSL3_VERSION }, + {"ECDHE-ECDSA-AES256-SHA", SSL3_VERSION }, + {"ECDHE-RSA-AES256-SHA", SSL3_VERSION }, + {"ECDHE-PSK-AES256-CBC-SHA", SSL3_VERSION }, + {"AES128-GCM-SHA256", TLS1_2_VERSION}, + {"AES256-GCM-SHA384", TLS1_2_VERSION}, + {"AES128-SHA", SSL3_VERSION }, + {"PSK-AES128-CBC-SHA", SSL3_VERSION }, + {"AES256-SHA", SSL3_VERSION }, + {"PSK-AES256-CBC-SHA", SSL3_VERSION }, + {"DES-CBC3-SHA", SSL3_VERSION }, + }; + + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr ssl {SSL_new(ctx.get())}; + + STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl.get()); + for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + const SSL_CIPHER *cipher {sk_SSL_CIPHER_value(ciphers, i)}; + const char *name {SSL_CIPHER_get_name(cipher)}; + uint16_t min_version {SSL_CIPHER_get_min_version(cipher)}; + + if (boring_cipher_versions.find(name) != boring_cipher_versions.end()) { + EXPECT_STREQ(version_str(boring_cipher_versions[name]), version_str(min_version)) << " for " << name; + } + } +} + +TEST(SSLTest, SSL_error_description) { + EXPECT_STREQ("WANT_ACCEPT", SSL_error_description(SSL_ERROR_WANT_ACCEPT)); + EXPECT_EQ(nullptr, SSL_error_description(123456)); +} + +TEST(SSLTest, SSL_enable_ocsp_stapling) { + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr ssl {SSL_new(ctx.get())}; + SSL_enable_ocsp_stapling(ssl.get()); +} + +TEST(SSLTest, SSL_set_SSL_CTX) { + bssl::UniquePtr ctx1 {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr ctx2 {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr ssl {SSL_new(ctx1.get())}; + + EXPECT_EQ(ctx1.get(), SSL_get_SSL_CTX(ssl.get())); + EXPECT_EQ(ctx2.get(), SSL_set_SSL_CTX(ssl.get(), ctx2.get())); + EXPECT_EQ(ctx2.get(), SSL_get_SSL_CTX(ssl.get())); + EXPECT_EQ(ctx2.get(), SSL_set_SSL_CTX(ssl.get(), ctx2.get())); + EXPECT_EQ(ctx2.get(), SSL_get_SSL_CTX(ssl.get())); +} + +TEST(SSLTest, SSL_set_renegotiate_mode) { + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr ssl {SSL_new(ctx.get())}; + + SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_never); + SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_freely); +} + +TEST(SSLTest, SSL_set_ocsp_response) { + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr ssl {SSL_new(ctx.get())}; + + const uint8_t response1[] { 1, 2, 3, 4 }; + const uint8_t response2[] { 1, 2, 3, 4 }; + + EXPECT_TRUE(SSL_set_ocsp_response(ssl.get(), nullptr, 0)); + EXPECT_TRUE(SSL_set_ocsp_response(ssl.get(), response1, sizeof(response1))); + EXPECT_TRUE(SSL_set_ocsp_response(ssl.get(), response2, sizeof(response2))); + EXPECT_TRUE(SSL_set_ocsp_response(ssl.get(), nullptr, 0)); +} + +TEST(SSLTest, SSL_SESSION_should_be_single_use) { + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr session {SSL_SESSION_new(ctx.get())}; + + ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), TLS1_3_VERSION)); + ASSERT_EQ(1, SSL_SESSION_should_be_single_use(session.get())); + ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), TLS1_2_VERSION)); + ASSERT_EQ(0, SSL_SESSION_should_be_single_use(session.get())); +} + +TEST(SSLTest, test_SSL_get_peer_full_cert_chain) { + TempFile root_ca_cert_pem { root_ca_cert_pem_str }; + TempFile client_2_key_pem { client_2_key_pem_str }; + TempFile client_2_cert_chain_pem { client_2_cert_chain_pem_str }; + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + const char MESSAGE[] { "HELLO" }; + std::promise server_port; + + signal(SIGPIPE, SIG_IGN); + + // Start a TLS server + std::thread server([&]() { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr); + ASSERT_EQ(1, SSL_CTX_load_verify_locations(ctx.get(), root_ca_cert_pem.path(), nullptr)) << (ERR_print_errors_fp(stderr), ""); + + STACK_OF(X509_NAME) *cert_names { sk_X509_NAME_new_null() }; + ASSERT_EQ(1, SSL_add_file_cert_subjects_to_stack(cert_names, root_ca_cert_pem.path())); + SSL_CTX_set_client_CA_list(ctx.get(), cert_names); + + ASSERT_EQ(1, SSL_CTX_use_certificate_chain_file(ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_EQ(1, SSL_CTX_use_PrivateKey_file(ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + + bssl::UniquePtr ssl { SSL_new(ctx.get()) }; + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + socklen_t addrlen = sizeof(addr); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_LT(0, sock); + ASSERT_EQ(0, bind(sock, (struct sockaddr*)&addr, sizeof(addr))); + ASSERT_EQ(0, listen(sock, 1)); + ASSERT_EQ(0, getsockname(sock, (struct sockaddr*)&addr, &addrlen)); + server_port.set_value(ntohs(addr.sin_port)); // Tell the client our port number + int client = accept(sock, nullptr, nullptr); + ASSERT_LT(0, client); + + ASSERT_EQ(1, SSL_set_fd(ssl.get(), client)); + ASSERT_EQ(1, SSL_accept(ssl.get())) << (ERR_print_errors_fp(stderr), ""); + ASSERT_EQ(1, SSL_is_server(ssl.get())); + + STACK_OF(X509) *client_certs { SSL_get_peer_full_cert_chain(ssl.get()) }; + ASSERT_TRUE(client_certs); + ASSERT_EQ(4, sk_X509_num(client_certs)); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + + SSL_shutdown(ssl.get()); + close(client); + close(sock); + }); + + { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr); + ASSERT_EQ(1, SSL_CTX_load_verify_locations(ctx.get(), root_ca_cert_pem.path(), nullptr)); + + ASSERT_EQ(1, SSL_CTX_use_certificate_chain_file(ctx.get(), client_2_cert_chain_pem.path())) << (ERR_print_errors_fp(stderr), ""); + ASSERT_EQ(1, SSL_CTX_use_PrivateKey_file(ctx.get(), client_2_key_pem.path(), SSL_FILETYPE_PEM)); + + bssl::UniquePtr ssl (SSL_new(ctx.get())); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(server_port.get_future().get()); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, connect(sock, (const struct sockaddr *)&addr, sizeof(addr))); + ASSERT_EQ(1, SSL_set_fd(ssl.get(), sock)); + ASSERT_TRUE(SSL_connect(ssl.get()) > 0) << (ERR_print_errors_fp(stderr), ""); + + STACK_OF(X509) *server_certs = SSL_get_peer_full_cert_chain(ssl.get()); + ASSERT_TRUE(server_certs); + ASSERT_EQ(4, sk_X509_num(server_certs)); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + } + + server.join(); +} + +TEST(SSLTest, test_SSL_CTX_set_strict_cipher_list) { + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + STACK_OF(SSL_CIPHER) *ciphers {SSL_CTX_get_ciphers(ctx.get())}; + + std::string cipherstr; + + for(const SSL_CIPHER *cipher : ciphers) { + cipherstr += (cipherstr.size() ? ":" : ""); + cipherstr += SSL_CIPHER_get_name(cipher); + } + + ASSERT_EQ(1, SSL_CTX_set_strict_cipher_list(ctx.get(), cipherstr.c_str())); + ASSERT_EQ(0, SSL_CTX_set_strict_cipher_list(ctx.get(), "rubbish:garbage")); +} + +TEST(SSLTest, test_SSL_CTX_set_verify_algorithm_prefs) { + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + + uint16_t prefs[] { + SSL_SIGN_RSA_PSS_RSAE_SHA256, + SSL_SIGN_ECDSA_SECP256R1_SHA256 + }; + + ASSERT_EQ(1, SSL_CTX_set_verify_algorithm_prefs(ctx.get(), prefs, (sizeof(prefs) / sizeof(prefs[0])))); +} + +TEST(SSLTest, test_SSL_early_callback_ctx_extension_get) { + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + static const char MESSAGE[] { "HELLO" }; + static const char SERVERNAME[] { "www.example.com" }; + std::promise server_port; + + signal(SIGPIPE, SIG_IGN); + + // Start a TLS server + std::thread server([&]() { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + + ASSERT_EQ(1, SSL_CTX_use_certificate_chain_file(ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_EQ(1, SSL_CTX_use_PrivateKey_file(ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + + // Install a callback that will use SSL_early_callback_ctx_extension_get() + // to check the server name extension that we configured the client to send. + // The extension bytes should contain: u16->[u8, u16->[www.example.com]] + SSL_CTX_set_select_certificate_cb(ctx.get(), [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t { + const uint8_t *tlsext_data; + size_t tlsext_len; + + if(SSL_early_callback_ctx_extension_get(client_hello, TLSEXT_TYPE_server_name, &tlsext_data, &tlsext_len)) { + CBS server_name_extension; + CBS server_name_extension_bytes; + uint8_t server_name_extension_nametype; + CBS server_name_extension_name; + + CBS_init(&server_name_extension, tlsext_data, tlsext_len); + + if (CBS_len(&server_name_extension) == (2 + 1 + 2 + strlen(SERVERNAME)) && + CBS_get_u16_length_prefixed(&server_name_extension, &server_name_extension_bytes) && + CBS_len(&server_name_extension_bytes) == (1 + 2 + strlen(SERVERNAME)) && + CBS_get_u8(&server_name_extension_bytes, &server_name_extension_nametype) && + server_name_extension_nametype == TLSEXT_NAMETYPE_host_name && + CBS_len(&server_name_extension_bytes) == (2 + strlen(SERVERNAME)) && + CBS_get_u16_length_prefixed(&server_name_extension_bytes, &server_name_extension_name) && + CBS_len(&server_name_extension_name) == strlen(SERVERNAME) && + memcmp(CBS_data(&server_name_extension_name), SERVERNAME, strlen(SERVERNAME)) == 0) { + return ssl_select_cert_success; + } + } + + return ssl_select_cert_error; // Causes SSL_connect() to fail in the client + }); + + bssl::UniquePtr ssl { SSL_new(ctx.get()) }; + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + socklen_t addrlen = sizeof(addr); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_LT(0, sock); + ASSERT_EQ(0, bind(sock, (struct sockaddr*)&addr, sizeof(addr))); + ASSERT_EQ(0, listen(sock, 1)); + ASSERT_EQ(0, getsockname(sock, (struct sockaddr*)&addr, &addrlen)); + server_port.set_value(ntohs(addr.sin_port)); // Tell the client our port number + int client = accept(sock, nullptr, nullptr); + ASSERT_LT(0, client); + + ASSERT_EQ(1, SSL_set_fd(ssl.get(), client)); + ASSERT_EQ(1, SSL_accept(ssl.get())) << ERR_error_string(ERR_get_error(), nullptr); + ASSERT_EQ(1, SSL_is_server(ssl.get())); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + + SSL_shutdown(ssl.get()); + close(client); + close(sock); + }); + + { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, nullptr); + bssl::UniquePtr ssl (SSL_new(ctx.get())); + + // Send a TLSEXT_TYPE_server_name extension. The server will inspect this + // extension using SSL_early_callback_ctx_extension_get(), and fail the + // handshake if there's an error. + ASSERT_EQ(1, SSL_set_tlsext_host_name(ssl.get(), SERVERNAME)); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(server_port.get_future().get()); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, connect(sock, (const struct sockaddr *)&addr, sizeof(addr))); + ASSERT_EQ(1, SSL_set_fd(ssl.get(), sock)); + ASSERT_TRUE(SSL_connect(ssl.get()) > 0) << (ERR_print_errors_fp(stderr), ""); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + } + + server.join(); +} + +TEST(SSLTest, test_SSL_get_cipher_by_value) { + struct { + uint16_t value; // IANA number + const char *name; // IETF name + uint32_t id; // + } + ciphers[] { + { 0x1302, "TLS_AES_256_GCM_SHA384", TLS1_3_CK_AES_256_GCM_SHA384 }, + { 0x1303, "TLS_CHACHA20_POLY1305_SHA256", TLS1_3_CK_CHACHA20_POLY1305_SHA256 }, + { 0x1301, "TLS_AES_128_GCM_SHA256", TLS1_3_CK_AES_128_GCM_SHA256 }, + { 0xc02c, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 }, + { 0xcca9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 }, + { 0xc02b, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 }, + { 0xc00a, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA }, + { 0xc009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA }, + { 0x009d, "TLS_RSA_WITH_AES_256_GCM_SHA384", TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 }, + { 0x009c, "TLS_RSA_WITH_AES_128_GCM_SHA256", TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 }, + { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA", TLS1_CK_RSA_WITH_AES_256_SHA }, + { 0x002f, "TLS_RSA_WITH_AES_128_CBC_SHA", TLS1_CK_RSA_WITH_AES_128_SHA }, + { 0x008d, "TLS_PSK_WITH_AES_256_CBC_SHA", TLS1_CK_PSK_WITH_AES_256_CBC_SHA }, + { 0x008c, "TLS_PSK_WITH_AES_128_CBC_SHA", TLS1_CK_PSK_WITH_AES_128_CBC_SHA } + }; + + for(auto &c : ciphers) { + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(c.value); + ASSERT_TRUE(cipher) << "Failed to get cipher " << c.value << " (" << c.name << ")"; + EXPECT_STREQ(c.name, SSL_CIPHER_standard_name(cipher)); + EXPECT_EQ(c.id, SSL_CIPHER_get_id(cipher)); + } +} + + +struct Curves { + const char *server_curves; + const char *client_curves; + uint16_t expected_curve; +}; + +class SSLTestWithCurves : public testing::TestWithParam { +}; + +TEST_P(SSLTestWithCurves, test_SSL_get_curve_id) { + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + static const char MESSAGE[] { "HELLO" }; + std::promise server_port; + + signal(SIGPIPE, SIG_IGN); + + const auto &curves {GetParam()}; + + // Start a TLS server + std::thread server([&]() { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + + ASSERT_EQ(1, SSL_CTX_use_certificate_chain_file(ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_EQ(1, SSL_CTX_use_PrivateKey_file(ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + ASSERT_EQ(1, SSL_CTX_set1_curves_list(ctx.get(), curves.server_curves)); + + bssl::UniquePtr ssl { SSL_new(ctx.get()) }; + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + socklen_t addrlen = sizeof(addr); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_LT(0, sock); + ASSERT_EQ(0, bind(sock, (struct sockaddr*)&addr, sizeof(addr))); + ASSERT_EQ(0, listen(sock, 1)); + ASSERT_EQ(0, getsockname(sock, (struct sockaddr*)&addr, &addrlen)); + server_port.set_value(ntohs(addr.sin_port)); // Tell the client our port number + int client = accept(sock, nullptr, nullptr); + ASSERT_LT(0, client); + + ASSERT_EQ(1, SSL_set_fd(ssl.get(), client)); + ASSERT_EQ(1, SSL_accept(ssl.get())) << ERR_error_string(ERR_get_error(), nullptr); + ASSERT_EQ(1, SSL_is_server(ssl.get())); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + + SSL_shutdown(ssl.get()); + close(client); + close(sock); + }); + + { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, nullptr); + SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION); + ASSERT_EQ(1, SSL_CTX_set1_curves_list(ctx.get(), curves.client_curves)); + bssl::UniquePtr ssl (SSL_new(ctx.get())); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(server_port.get_future().get()); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, connect(sock, (const struct sockaddr *)&addr, sizeof(addr))); + ASSERT_EQ(1, SSL_set_fd(ssl.get(), sock)); + ASSERT_TRUE(SSL_connect(ssl.get()) > 0) << (ERR_print_errors_fp(stderr), ""); + + ASSERT_EQ(curves.expected_curve, SSL_get_curve_id(ssl.get())); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + } + + server.join(); +} + +INSTANTIATE_TEST_SUITE_P( + SSLTestWithCurves, + SSLTestWithCurves, + ::testing::Values( + Curves { + SN_secp224r1 ":" SN_secp384r1 ":" SN_secp521r1 ":" SN_X25519 ":" SN_X9_62_prime256v1, + SN_secp224r1, + SSL_CURVE_SECP224R1 + }, + Curves { + SN_secp224r1 ":" SN_secp384r1 ":" SN_secp521r1 ":" SN_X25519 ":" SN_X9_62_prime256v1, + SN_secp521r1, + SSL_CURVE_SECP521R1 + }, + Curves { + SN_secp224r1 ":" SN_secp384r1 ":" SN_secp521r1 ":" SN_X25519 ":" SN_X9_62_prime256v1, + SN_X9_62_prime256v1, + SSL_CURVE_SECP256R1 + } + )); + +TEST(SSLTest, test_SSL_get_curve_name) { + EXPECT_STREQ("P-224", SSL_get_curve_name(SSL_CURVE_SECP224R1)); + EXPECT_STREQ("P-256", SSL_get_curve_name(SSL_CURVE_SECP256R1)); + EXPECT_STREQ("P-384", SSL_get_curve_name(SSL_CURVE_SECP384R1)); + EXPECT_STREQ("P-521", SSL_get_curve_name(SSL_CURVE_SECP521R1)); + EXPECT_STREQ("X25519", SSL_get_curve_name(SSL_CURVE_X25519)); + EXPECT_STREQ("X25519MLKEM768", SSL_get_curve_name(SSL_GROUP_X25519_MLKEM768)); + EXPECT_STREQ("X25519Kyber768Draft00", SSL_get_curve_name(SSL_GROUP_X25519_KYBER768_DRAFT00)); +} + + +struct Sigalgs { + const char *server_sigalgs; + const char *client_sigalgs; + uint16_t expected_sigalg; +}; + +class SSLTestWithSigalgs : public testing::TestWithParam { +}; + +TEST_P(SSLTestWithSigalgs, test_SSL_get_peer_signature_algorithm) { + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + static const char MESSAGE[] { "HELLO" }; + std::promise server_port; + + signal(SIGPIPE, SIG_IGN); + + const auto &sigalgs {GetParam()}; + + // Start a TLS server + std::thread server([&]() { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + ASSERT_EQ(1, SSL_CTX_use_certificate_chain_file(ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_EQ(1, SSL_CTX_use_PrivateKey_file(ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + if(sigalgs.server_sigalgs) { + ASSERT_EQ(1, SSL_CTX_set1_sigalgs_list(ctx.get(), sigalgs.server_sigalgs)) << ERR_error_string(ERR_get_error(), nullptr); + } + bssl::UniquePtr ssl { SSL_new(ctx.get()) }; + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + socklen_t addrlen = sizeof(addr); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_LT(0, sock); + ASSERT_EQ(0, bind(sock, (struct sockaddr*)&addr, sizeof(addr))); + ASSERT_EQ(0, listen(sock, 1)); + ASSERT_EQ(0, getsockname(sock, (struct sockaddr*)&addr, &addrlen)); + server_port.set_value(ntohs(addr.sin_port)); // Tell the client our port number + int client = accept(sock, nullptr, nullptr); + ASSERT_LT(0, client); + + ASSERT_EQ(1, SSL_set_fd(ssl.get(), client)); + ASSERT_EQ(1, SSL_accept(ssl.get())) << ERR_error_string(ERR_get_error(), nullptr); + ASSERT_EQ(1, SSL_is_server(ssl.get())); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + + SSL_shutdown(ssl.get()); + close(client); + close(sock); + }); + + { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, nullptr); + if(sigalgs.client_sigalgs) { + ASSERT_EQ(1, SSL_CTX_set1_sigalgs_list(ctx.get(), sigalgs.client_sigalgs)) << ERR_error_string(ERR_get_error(), nullptr); + } + bssl::UniquePtr ssl (SSL_new(ctx.get())); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(server_port.get_future().get()); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, connect(sock, (const struct sockaddr *)&addr, sizeof(addr))); + ASSERT_EQ(1, SSL_set_fd(ssl.get(), sock)); + ASSERT_TRUE(SSL_connect(ssl.get()) > 0) << (ERR_print_errors_fp(stderr), ""); + + ASSERT_EQ(sigalgs.expected_sigalg, SSL_get_peer_signature_algorithm(ssl.get())); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + } + + server.join(); +} + +INSTANTIATE_TEST_SUITE_P( + SSLTestWithSigalgs, + SSLTestWithSigalgs, + ::testing::Values( + Sigalgs { + "rsa_pss_rsae_sha256", + "rsa_pss_rsae_sha256", + SSL_SIGN_RSA_PSS_RSAE_SHA256 + }, + Sigalgs { + "rsa_pss_rsae_sha384", + "rsa_pss_rsae_sha384", + SSL_SIGN_RSA_PSS_RSAE_SHA384 + }, + Sigalgs { + "rsa_pss_rsae_sha512", + "rsa_pss_rsae_sha512", + SSL_SIGN_RSA_PSS_RSAE_SHA512 + } + ) +); + +TEST(SSLTest, test_SSL_get_signature_algorithm_name) { + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_RSA_PKCS1_SHA1, 0), "rsa_pkcs1_sha1"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_RSA_PKCS1_SHA256, 0), "rsa_pkcs1_sha256"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_RSA_PKCS1_SHA384, 0), "rsa_pkcs1_sha384"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_RSA_PKCS1_SHA512, 0), "rsa_pkcs1_sha512"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_ECDSA_SHA1, 0), "ecdsa_sha1"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_ECDSA_SECP256R1_SHA256, 0), "ecdsa_sha256"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_ECDSA_SECP256R1_SHA256, 1), "ecdsa_secp256r1_sha256"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_ECDSA_SECP384R1_SHA384, 0), "ecdsa_sha384"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_ECDSA_SECP384R1_SHA384, 1), "ecdsa_secp384r1_sha384"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_ECDSA_SECP521R1_SHA512, 0), "ecdsa_sha512"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_ECDSA_SECP521R1_SHA512, 1), "ecdsa_secp521r1_sha512"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_RSA_PSS_RSAE_SHA256, 0), "rsa_pss_rsae_sha256"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_RSA_PSS_RSAE_SHA384, 0), "rsa_pss_rsae_sha384"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_RSA_PSS_RSAE_SHA512, 0), "rsa_pss_rsae_sha512"); + EXPECT_STREQ(SSL_get_signature_algorithm_name(SSL_SIGN_ED25519, 0), "ed25519"); +} + + +TEST(SSLTest, test_SSL_get0_ocsp_response) { + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + static const char MESSAGE[] { "HELLO" }; + static const uint8_t OCSP_RESPONSE[] { 'H', 'E', 'L', 'P' }; + std::promise server_port; + + signal(SIGPIPE, SIG_IGN); + + // Start a TLS server + std::thread server([&]() { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + ASSERT_EQ(1, SSL_CTX_use_certificate_chain_file(ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_EQ(1, SSL_CTX_use_PrivateKey_file(ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + + SSL_CTX_set_tlsext_status_cb(ctx.get(), [](SSL* ssl, void* arg) -> int { + if(!SSL_set_ocsp_response(ssl, OCSP_RESPONSE, sizeof(OCSP_RESPONSE))) { + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + return SSL_TLSEXT_ERR_OK; + }); + + bssl::UniquePtr ssl { SSL_new(ctx.get()) }; + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + socklen_t addrlen = sizeof(addr); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_LT(0, sock); + ASSERT_EQ(0, bind(sock, (struct sockaddr*)&addr, sizeof(addr))); + ASSERT_EQ(0, listen(sock, 1)); + ASSERT_EQ(0, getsockname(sock, (struct sockaddr*)&addr, &addrlen)); + server_port.set_value(ntohs(addr.sin_port)); // Tell the client our port number + int client = accept(sock, nullptr, nullptr); + ASSERT_LT(0, client); + + ASSERT_EQ(1, SSL_set_fd(ssl.get(), client)); + ASSERT_EQ(1, SSL_accept(ssl.get())) << ERR_error_string(ERR_get_error(), nullptr); + ASSERT_EQ(1, SSL_is_server(ssl.get())); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + + SSL_shutdown(ssl.get()); + close(client); + close(sock); + }); + + { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, nullptr); + bssl::UniquePtr ssl (SSL_new(ctx.get())); + SSL_enable_ocsp_stapling(ssl.get()); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(server_port.get_future().get()); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, connect(sock, (const struct sockaddr *)&addr, sizeof(addr))); + ASSERT_EQ(1, SSL_set_fd(ssl.get(), sock)); + ASSERT_TRUE(SSL_connect(ssl.get()) > 0) << (ERR_print_errors_fp(stderr), ""); + + const uint8_t *ocsp_resp_data; + size_t ocsp_resp_len; + + SSL_get0_ocsp_response(ssl.get(), &ocsp_resp_data, &ocsp_resp_len); + + ASSERT_EQ(sizeof(OCSP_RESPONSE), ocsp_resp_len); + ASSERT_EQ(0, memcmp(OCSP_RESPONSE, ocsp_resp_data, ocsp_resp_len)); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + } + + server.join(); +} + +TEST(SSLTest, test_SSL_set_chain_and_key) { + TempFile root_ca_cert_pem { root_ca_cert_pem_str }; + + static const char MESSAGE[] { "HELLO" }; + std::promise server_port; + + signal(SIGPIPE, SIG_IGN); + + // Start a TLS server + std::thread server([&]() { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + bssl::UniquePtr ssl { SSL_new(ctx.get()) }; + + bssl::UniquePtr key; + { + bssl::UniquePtr bio {BIO_new_mem_buf(server_2_key_pem_str, strlen(server_2_key_pem_str))}; + ASSERT_TRUE(bio); + bssl::UniquePtr rsa {PEM_read_bio_RSAPrivateKey(bio.get(), nullptr, nullptr, nullptr)}; + ASSERT_TRUE(rsa); + bssl::UniquePtr tmp(EVP_PKEY_new()); + ASSERT_EQ(1, EVP_PKEY_assign_RSA(tmp.get(), rsa.get())); + rsa.release(); + key = std::move(tmp); + } + + std::vector chain; + for(const char *pem_str : { server_2_cert_pem_str, intermediate_ca_2_cert_pem_str, intermediate_ca_1_cert_pem_str }) { + bssl::UniquePtr bio(BIO_new_mem_buf(pem_str, strlen(pem_str))); + long der_len = 0; + uint8_t* der_data = nullptr; + ASSERT_EQ(1, PEM_bytes_read_bio(&der_data, &der_len, nullptr, PEM_STRING_X509, bio.get(), nullptr, nullptr)); + bssl::UniquePtr tmp(der_data); // Prevents memory leak. + chain.push_back(CRYPTO_BUFFER_new(der_data, der_len, nullptr)); + } + + ASSERT_EQ(1, SSL_set_chain_and_key(ssl.get(), chain.data(), chain.size(), key.get(), nullptr)); + + while(chain.size()) { + CRYPTO_BUFFER_free(chain.back()); + chain.pop_back(); + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + socklen_t addrlen = sizeof(addr); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_LT(0, sock); + ASSERT_EQ(0, bind(sock, (struct sockaddr*)&addr, sizeof(addr))); + ASSERT_EQ(0, listen(sock, 1)); + ASSERT_EQ(0, getsockname(sock, (struct sockaddr*)&addr, &addrlen)); + server_port.set_value(ntohs(addr.sin_port)); // Tell the client our port number + int client = accept(sock, nullptr, nullptr); + ASSERT_LT(0, client); + + ASSERT_EQ(1, SSL_set_fd(ssl.get(), client)); + ASSERT_EQ(1, SSL_accept(ssl.get())) << ERR_error_string(ERR_get_error(), nullptr); + ASSERT_EQ(1, SSL_is_server(ssl.get())); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + + SSL_shutdown(ssl.get()); + close(client); + close(sock); + }); + + { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr); + ASSERT_EQ(1, SSL_CTX_load_verify_locations(ctx.get(), root_ca_cert_pem.path(), nullptr)); + bssl::UniquePtr ssl (SSL_new(ctx.get())); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(server_port.get_future().get()); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, connect(sock, (const struct sockaddr *)&addr, sizeof(addr))); + ASSERT_EQ(1, SSL_set_fd(ssl.get(), sock)); + ASSERT_TRUE(SSL_connect(ssl.get()) > 0) << ERR_error_string(ERR_get_error(), nullptr); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + } + + server.join(); +} + +TEST(SSLTest, test_SSL_SESSION_from_bytes) { + TempFile root_ca_cert_pem { root_ca_cert_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + TempFile server_2_key_pem { server_2_key_pem_str }; + + static const char MESSAGE[] { "HELLO" }; + std::promise server_port; + + signal(SIGPIPE, SIG_IGN); + + // Start a TLS server + std::thread server([&]() { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + ASSERT_EQ(1, SSL_CTX_use_certificate_chain_file(ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_EQ(1, SSL_CTX_use_PrivateKey_file(ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + bssl::UniquePtr ssl { SSL_new(ctx.get()) }; + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + socklen_t addrlen = sizeof(addr); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_LT(0, sock); + ASSERT_EQ(0, bind(sock, (struct sockaddr*)&addr, sizeof(addr))); + ASSERT_EQ(0, listen(sock, 1)); + ASSERT_EQ(0, getsockname(sock, (struct sockaddr*)&addr, &addrlen)); + server_port.set_value(ntohs(addr.sin_port)); // Tell the client our port number + int client = accept(sock, nullptr, nullptr); + ASSERT_LT(0, client); + + ASSERT_EQ(1, SSL_set_fd(ssl.get(), client)); + ASSERT_EQ(1, SSL_accept(ssl.get())) << ERR_error_string(ERR_get_error(), nullptr); + ASSERT_EQ(1, SSL_is_server(ssl.get())); + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + + SSL_shutdown(ssl.get()); + close(client); + close(sock); + }); + + { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_client_method())); + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr); + ASSERT_EQ(1, SSL_CTX_load_verify_locations(ctx.get(), root_ca_cert_pem.path(), nullptr)); + bssl::UniquePtr ssl (SSL_new(ctx.get())); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(server_port.get_future().get()); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(0, connect(sock, (const struct sockaddr *)&addr, sizeof(addr))); + ASSERT_EQ(1, SSL_set_fd(ssl.get(), sock)); + ASSERT_TRUE(SSL_connect(ssl.get()) > 0) << ERR_error_string(ERR_get_error(), nullptr); + + // Obtain the SSL_SESSION + bssl::UniquePtr session1 {SSL_get1_session(ssl.get())}; + ASSERT_TRUE(session1); + + // SSL_SESSION_to_bytes() + uint8_t *session1_buf; + size_t session1_len; + ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &session1_buf, &session1_len)); + bssl::UniquePtr tmp1 {session1_buf}; // We own the returned buffer + ASSERT_TRUE(session1_buf); + ASSERT_TRUE(session1_len); + + // SSL_SESSION_from_bytes() + bssl::UniquePtr session2 {SSL_SESSION_from_bytes(session1_buf, session1_len, ctx.get())}; + ASSERT_TRUE(session2); + + // Compare SSL_SESSION_get_id() on session1 and session2 + unsigned int session1_id_len; + const uint8_t *session1_id_buf = SSL_SESSION_get_id(session1.get(), &session1_id_len); + unsigned int session2_id_len; + const uint8_t *session2_id_buf = SSL_SESSION_get_id(session2.get(), &session2_id_len); + ASSERT_EQ(session1_id_len, session2_id_len); + for(size_t i = 0; i < session1_id_len; i++) { + ASSERT_EQ(session1_id_buf[i], session2_id_buf[i]); + } + + // Compare SSL_SESSION_is_resumable() on session1 and session2 + int session1_resumable = SSL_SESSION_is_resumable(session1.get()); + int session2_resumable = SSL_SESSION_is_resumable(session2.get()); + ASSERT_EQ(session1_resumable, session2_resumable); + + // SSL_SESSION_to_bytes() + uint8_t *session2_buf; + size_t session2_len; + ASSERT_TRUE(SSL_SESSION_to_bytes(session2.get(), &session2_buf, &session2_len)); + bssl::UniquePtr tmp2 {session2_buf}; // We own the returned buffer + ASSERT_TRUE(session2_buf); + ASSERT_TRUE(session2_len); + + // Compare session2_len/buf & session1_len/buf + ASSERT_EQ(session1_len, session2_len); + for(size_t i = 0; i < session1_len; i++) { + ASSERT_EQ(session1_buf[i], session2_buf[i]); + } + + char buf[sizeof(MESSAGE)]; + ASSERT_EQ(sizeof(MESSAGE), SSL_write(ssl.get(), MESSAGE, sizeof(MESSAGE))); + ASSERT_EQ(sizeof(MESSAGE), SSL_read(ssl.get(), buf, sizeof(buf))); + } + + server.join(); +} + +TEST(SSLTest, test_SSL_set1_curves_list) { + struct { + const char *curves; + int expected_result; + } + test_strings[] { + { SN_secp224r1 ":" SN_secp384r1 ":" SN_secp521r1 ":" SN_X25519 ":" SN_X9_62_prime256v1, 1}, + { "P-224", 1 }, + { "P-224:P-521:P-256:X25519", 1 }, + { "P-224:P-521:P-25:X25519", 0 }, + { "no:valid:curves", 0 }, + { ":", 0 }, + { ":::", 0 }, + { "", 0 } + }; + + for(const auto &test_string : test_strings) { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_server_method())); + bssl::UniquePtr ssl { SSL_new(ctx.get()) }; + ASSERT_EQ(test_string.expected_result, SSL_set1_curves_list(ssl.get(), test_string.curves)); + } +} + + + + + +static bool CompleteHandshakes(SSL *client, SSL *server) { + bool result {true}; + + while(result) { + int client_ret = SSL_do_handshake(client); + int client_err = SSL_get_error(client, client_ret); + + int server_ret = SSL_do_handshake(server); + int server_err = SSL_get_error(server, server_ret); + + if (client_err != SSL_ERROR_NONE && client_err != SSL_ERROR_WANT_READ && client_err != SSL_ERROR_WANT_WRITE) { + fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err)); + ERR_print_errors_fp(stderr); + result = false; + } + + if (server_err != SSL_ERROR_NONE && server_err != SSL_ERROR_WANT_READ && server_err != SSL_ERROR_WANT_WRITE) { + fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err)); + ERR_print_errors_fp(stderr); + result = false; + } + + if (client_ret == 1 && server_ret == 1) { + break; + } + } + + return result; +} + +class SocketCloser { + public: + SocketCloser(int socket) : m_socket{socket} {} + ~SocketCloser() { ::close(m_socket); } + private: + SocketCloser(const SocketCloser&) = default; + SocketCloser &operator=(const SocketCloser&) = default; + private: + int m_socket; +}; + +TEST(SSLTest, test_SSL_set_fd) { + TempFile root_ca_cert_pem { root_ca_cert_pem_str }; + TempFile client_2_key_pem { client_2_key_pem_str }; + TempFile client_2_cert_chain_pem { client_2_cert_chain_pem_str }; + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + + SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + ASSERT_TRUE(SSL_CTX_load_verify_locations(client_ctx.get(), root_ca_cert_pem.path(), nullptr)); + + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + SSL_set_connect_state(client_ssl.get()); + + ASSERT_TRUE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); +} + +TEST(SSLTest, test_SSL_ex_data) { + // A counter of the number of times that our free_func has been called. Since + // we cannot uninstall our new index, nor the free_func that's associated with + // it, we need to avoid side effects that may be caused by free_func + // invocations that will occur during subsequent tests. This is why this + // counter is static; if it was stack based, the free_func would corrupt the + // contents of stack at the same address when it's called from other tests. + static int free_func_calls = 0; + + auto free_func = [](void *parent, void *ptr, CRYPTO_EX_DATA *ad, int index, long argl, void *argp) { + (*reinterpret_cast(argp))++; + if (ptr) { + ASSERT_EQ(42, *reinterpret_cast(ptr)); + delete reinterpret_cast(ptr); + } + }; + + int my_int_index = SSL_get_ex_new_index(0, &free_func_calls, nullptr, nullptr, free_func); + + ASSERT_EQ(0, free_func_calls); + ASSERT_NE(-1, my_int_index); + + ASSERT_NE(my_int_index, SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr)); + + bssl::UniquePtr ctx {SSL_CTX_new(TLS_method())}; + { + bssl::UniquePtr ssl {SSL_new(ctx.get())}; + int *i {new int{42}}; + SSL_set_ex_data(ssl.get(), my_int_index, i); + ASSERT_EQ(i, SSL_get_ex_data(ssl.get(), my_int_index)); + // ssl gets deleted, so *i hould get deleted + ASSERT_EQ(0, free_func_calls); + } + ASSERT_EQ(1, free_func_calls); + { + int i {42}; + bssl::UniquePtr ssl {SSL_new(ctx.get())}; + SSL_set_ex_data(ssl.get(), my_int_index, &i); + ASSERT_EQ(&i, SSL_get_ex_data(ssl.get(), my_int_index)); + // Setting the data to nullptr should not delete the previous value + SSL_set_ex_data(ssl.get(), my_int_index, nullptr); + ASSERT_EQ(1, free_func_calls); + } + ASSERT_EQ(2, free_func_calls); +} + +TEST(SSLTest, test_SSL_set_cipher_list) { + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr ssl {SSL_new(ctx.get())}; + + ASSERT_TRUE(SSL_set_cipher_list(ssl.get(), "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4")); + ASSERT_TRUE(SSL_set_cipher_list(ssl.get(), "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4")); + ASSERT_FALSE(SSL_set_cipher_list(ssl.get(), "NO:VALID:CIPHERS")); + ASSERT_TRUE(SSL_set_cipher_list(ssl.get(), "ONE:VALID:CIPHER:PSK")); + ASSERT_TRUE(SSL_set_cipher_list(ssl.get(), "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4")); +} + +TEST(SSLTest, test_SSL_set_app_data) { + bssl::UniquePtr ctx {SSL_CTX_new(TLS_server_method())}; + bssl::UniquePtr ssl {SSL_new(ctx.get())}; + + int i {42}; + + ASSERT_TRUE(SSL_set_app_data(ssl.get(), &i)); + ASSERT_EQ(&i, SSL_get_app_data(ssl.get())); + ASSERT_TRUE(SSL_set_app_data(ssl.get(), nullptr)); + ASSERT_EQ(nullptr, SSL_get_app_data(ssl.get())); +} + +TEST(SSLTest, test_SSL_set_alpn_protos) { + TempFile root_ca_cert_pem { root_ca_cert_pem_str }; + TempFile client_2_key_pem { client_2_key_pem_str }; + TempFile client_2_cert_chain_pem { client_2_cert_chain_pem_str }; + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + + SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + ASSERT_TRUE(SSL_CTX_load_verify_locations(client_ctx.get(), root_ca_cert_pem.path(), nullptr)); + + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + SSL_set_connect_state(client_ssl.get()); + + static const uint8_t server_protos[] { + 2, 'h', '2', + 8, 'h', 't', 't', 'p', '/', '1', '.', '1', + 6, 's', 'p', 'd', 'y', '/', '1', + }; + + static const uint8_t client_protos[] { + 6, 's', 'p', 'd', 'y', '/', '1', + 8, 'h', 't', 't', 'p', '/', '1', '.', '1' + }; + + // Set up a ALPN callback on the server which checks that in == client_protos + // and then uses SSL_select_next_proto() to make it's selection + SSL_CTX_set_alpn_select_cb(server_ctx.get(), [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in, unsigned in_len, void *arg)-> int { + if (in_len != sizeof(client_protos)) { + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + if (memcmp(client_protos, in, in_len) != 0) { + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + + if (SSL_select_next_proto(const_cast(out), out_len, in, in_len, server_protos, sizeof(server_protos)) == OPENSSL_NPN_NEGOTIATED) { + return SSL_TLSEXT_ERR_OK; + } + + return SSL_TLSEXT_ERR_ALERT_FATAL; + }, nullptr); + + // Set the clients list of ALPN protocols + ASSERT_EQ(0, SSL_set_alpn_protos(client_ssl.get(), client_protos, sizeof(client_protos))); + + ASSERT_TRUE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); + + const uint8_t *selected; + unsigned selected_len; + SSL_get0_alpn_selected(client_ssl.get(), &selected, &selected_len); + // const uint8_t **out_data, unsigned *out_len + + const char *expected {"spdy/1"}; + size_t expected_len {strlen(expected)}; + ASSERT_EQ(expected_len, selected_len); + ASSERT_EQ(0, memcmp(expected, selected, expected_len)); +} + +TEST(SSLTest, test_SSL_CTX_app_data) { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); + ASSERT_EQ(1, SSL_CTX_set_app_data(ctx.get(), ctx.get())); + ASSERT_EQ(ctx.get(), SSL_CTX_get_app_data(ctx.get())); +} + +TEST(SSLTest, test_SSL_get_signature_algorithm_digest) { + EXPECT_EQ(EVP_sha1(), SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_SHA1)); + EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_SHA256)); + EXPECT_EQ(EVP_sha384(), SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_SHA384)); + EXPECT_EQ(EVP_sha512(), SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_SHA512)); + EXPECT_EQ(EVP_sha1(), SSL_get_signature_algorithm_digest(SSL_SIGN_ECDSA_SHA1)); + EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(SSL_SIGN_ECDSA_SECP256R1_SHA256)); + EXPECT_EQ(EVP_sha384(), SSL_get_signature_algorithm_digest(SSL_SIGN_ECDSA_SECP384R1_SHA384)); + EXPECT_EQ(EVP_sha512(), SSL_get_signature_algorithm_digest(SSL_SIGN_ECDSA_SECP521R1_SHA512)); + EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA256)); + EXPECT_EQ(EVP_sha384(), SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384)); + EXPECT_EQ(EVP_sha512(), SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA512)); + EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(SSL_SIGN_ED25519)); +} + +TEST(SSLTest, test_SSL_get_signature_algorithm_key_type) { + struct { + uint16_t sigalg; + int keytype; + } + keytypes[] { + { SSL_SIGN_RSA_PKCS1_SHA1, EVP_PKEY_RSA }, + { SSL_SIGN_RSA_PKCS1_SHA256, EVP_PKEY_RSA }, + { SSL_SIGN_RSA_PKCS1_SHA384, EVP_PKEY_RSA }, + { SSL_SIGN_RSA_PKCS1_SHA512, EVP_PKEY_RSA }, + { SSL_SIGN_ECDSA_SHA1, EVP_PKEY_EC }, + { SSL_SIGN_ECDSA_SECP256R1_SHA256, EVP_PKEY_EC }, + { SSL_SIGN_ECDSA_SECP384R1_SHA384, EVP_PKEY_EC }, + { SSL_SIGN_ECDSA_SECP521R1_SHA512, EVP_PKEY_EC }, + { SSL_SIGN_RSA_PSS_RSAE_SHA256, EVP_PKEY_RSA }, + { SSL_SIGN_RSA_PSS_RSAE_SHA384, EVP_PKEY_RSA }, + { SSL_SIGN_RSA_PSS_RSAE_SHA512, EVP_PKEY_RSA }, + { SSL_SIGN_ED25519, EVP_PKEY_ED25519 }, + }; + + for(int i = 0; i < (sizeof(keytypes) / sizeof(keytypes[0])); i++) { + EXPECT_EQ(keytypes[i].keytype, SSL_get_signature_algorithm_key_type(keytypes[i].sigalg)) << "keytypes[" << i << "]"; + } +} + +TEST(SSLTest, test_SSL_is_signature_algorithm_rsa_pss) { + struct { + uint16_t sigalg; + int is_rsa_pss; + } + sigalgs[] { + { SSL_SIGN_RSA_PKCS1_SHA1, 0 }, + { SSL_SIGN_RSA_PKCS1_SHA256, 0 }, + { SSL_SIGN_RSA_PKCS1_SHA384, 0 }, + { SSL_SIGN_RSA_PKCS1_SHA512, 0 }, + { SSL_SIGN_ECDSA_SHA1, 0 }, + { SSL_SIGN_ECDSA_SECP256R1_SHA256, 0 }, + { SSL_SIGN_ECDSA_SECP384R1_SHA384, 0 }, + { SSL_SIGN_ECDSA_SECP521R1_SHA512, 0 }, + { SSL_SIGN_RSA_PSS_RSAE_SHA256, 1 }, + { SSL_SIGN_RSA_PSS_RSAE_SHA384, 1 }, + { SSL_SIGN_RSA_PSS_RSAE_SHA512, 1 }, + { SSL_SIGN_ED25519, 0 }, + }; + + for(int i = 0; i < (sizeof(sigalgs) / sizeof(sigalgs[0])); i++) { + EXPECT_EQ(sigalgs[i].is_rsa_pss, SSL_is_signature_algorithm_rsa_pss(sigalgs[i].sigalg)) << "sigalgs[" << i << "]"; + } +} + +TEST(SSLTest, test_SSL_alert_from_verify_result) { + ASSERT_EQ(SSL_AD_UNKNOWN_CA, SSL_alert_from_verify_result(X509_V_ERR_INVALID_CA)); + ASSERT_EQ(SSL_AD_UNKNOWN_CA, SSL_alert_from_verify_result(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)); + + ASSERT_EQ(SSL_AD_CERTIFICATE_EXPIRED, SSL_alert_from_verify_result(X509_V_ERR_CERT_HAS_EXPIRED)); + ASSERT_EQ(SSL_AD_CERTIFICATE_EXPIRED, SSL_alert_from_verify_result(X509_V_ERR_CRL_HAS_EXPIRED)); +} + +TEST(SSLTest, test_SSL_get0_peer_verify_algorithms) { + TempFile root_ca_cert_pem { root_ca_cert_pem_str }; + TempFile client_2_key_pem { client_2_key_pem_str }; + TempFile client_2_cert_chain_pem { client_2_cert_chain_pem_str }; + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + + ASSERT_EQ(1, SSL_CTX_set1_sigalgs_list(client_ctx.get(), "rsa_pkcs1_sha256:rsa_pss_rsae_sha256:ecdsa_secp256r1_sha256")); + + SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + ASSERT_TRUE(SSL_CTX_load_verify_locations(client_ctx.get(), root_ca_cert_pem.path(), nullptr)); + + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + SSL_set_connect_state(client_ssl.get()); + + auto cert_cb = [](SSL *ssl, void *arg) -> int { + const uint16_t *sigalgs {nullptr}; + size_t nsigalgs {SSL_get0_peer_verify_algorithms(ssl, &sigalgs)}; + + EXPECT_EQ(3, nsigalgs); + EXPECT_EQ(SSL_SIGN_RSA_PKCS1_SHA256, sigalgs[0]); + EXPECT_EQ(SSL_SIGN_RSA_PSS_RSAE_SHA256, sigalgs[1]); + EXPECT_EQ(SSL_SIGN_ECDSA_SECP256R1_SHA256, sigalgs[2]); + + nsigalgs = SSL_get0_peer_verify_algorithms(ssl, &sigalgs); + + EXPECT_EQ(3, nsigalgs); + EXPECT_EQ(SSL_SIGN_RSA_PKCS1_SHA256, sigalgs[0]); + EXPECT_EQ(SSL_SIGN_RSA_PSS_RSAE_SHA256, sigalgs[1]); + EXPECT_EQ(SSL_SIGN_ECDSA_SECP256R1_SHA256, sigalgs[2]); + + return 1; + }; + + SSL_set_cert_cb(server_ssl.get(), cert_cb, reinterpret_cast(__LINE__)); + + ASSERT_TRUE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); +} + + +TEST(SSLTest, test_SSL_get_servername_inside_select_certificate_cb) { + static const char SERVERNAME[] { "www.example.com" }; + + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_server_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_client_method())); + + // Set up server with a callback which checks if SSL_get_servername() works + SSL_CTX_set_select_certificate_cb(server_ctx.get(), [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t { + const char *server_name = SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name); + if (server_name && strcmp(server_name, SERVERNAME) == 0) { + return ssl_select_cert_success; + } + return ssl_select_cert_error; // Will cause handshake failure + }); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + // Set up client + SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_NONE, nullptr); + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + ASSERT_TRUE(SSL_set_tlsext_host_name(client_ssl.get(), SERVERNAME)); + SSL_set_connect_state(client_ssl.get()); + + ASSERT_TRUE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); +} + + +/** + * @brief This test exercises a leak in SSL_get_servername() + * + * If SSL_get_servername() was invoked multiple times from the same certificate + * selection callback, it was leaking the string value that was returned from + * the previous invocation(s). + * + * Note that the string returned by the _last_ SSL_get_servername() invocation, + * inside a certificate selection callback, does _not_ leak i.e. if + * SSL_get_servername() is only called once during a callback, there is no leak. + * It only leaks when SSL_get_servername() is called more than once during the + * same callback. + */ +TEST(SSLTest, test_SSL_get_servername_leak_inside_select_certificate_cb) { + static const char SERVERNAME[] { "www.example.com" }; + + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_server_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_client_method())); + + // Set up a certificate selection callback which calls SSL_get_servername() 5 times. + // This will result in 4 leaks if the SSL_get_servername() fix is not in place. + SSL_CTX_set_select_certificate_cb(server_ctx.get(), [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t { + SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name); + SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name); + SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name); + SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name); + SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name); + return ssl_select_cert_success; + }); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + // Set up client + SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_NONE, nullptr); + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + ASSERT_TRUE(SSL_set_tlsext_host_name(client_ssl.get(), SERVERNAME)); + SSL_set_connect_state(client_ssl.get()); + + ASSERT_TRUE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); +} + + +TEST(SSLTest, test_SSL_get_servername_null_inside_select_certificate_cb) { + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_server_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_client_method())); + + // Set up server with a callback to check if SSL_get_servername() returns + // a nullptr if the client didn't send an SNI host name extension + SSL_CTX_set_select_certificate_cb(server_ctx.get(), [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t { + return SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name) ? ssl_select_cert_error : ssl_select_cert_success; + }); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + // Set up client + SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_NONE, nullptr); + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + SSL_set_connect_state(client_ssl.get()); + + ASSERT_TRUE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); +} + +#ifdef BSSL_COMPAT +// Tests for segv when calling SSL_CIPHER_get_min_version() on a cipher that is +// known to OpenSSL, but whos implementation engine is not loaded. +// The TLS_GOSTR341001_WITH_28147_CNT_IMIT cipher fits this bill because it is +// known to OpenSSL but it's implementaion is only available when the cgost +// engine is configured in. +TEST(SSLTest,SSL_CIPHER_get_min_version_on_non_loaded_cipher) { + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(0x0081); + ASSERT_TRUE(cipher); + + const char *openssl_name {SSL_CIPHER_get_name(cipher)}; + ASSERT_TRUE(openssl_name); + ASSERT_STREQ("GOST2001-GOST89-GOST89", openssl_name); + + const char *standard_name = SSL_CIPHER_standard_name(cipher); + ASSERT_TRUE(standard_name); + ASSERT_STREQ("TLS_GOSTR341001_WITH_28147_CNT_IMIT", standard_name); + + ASSERT_EQ(TLS1_2_VERSION, SSL_CIPHER_get_min_version(cipher)); +} +#endif + +TEST(SSLTest, test_SSL_set_ocsp_response_inside_select_certificate_cb) { + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + static const uint8_t OCSP_RESPONSE[] { 1, 2, 3, 4, 5 }; + + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_server_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_client_method())); + + // Set up server with a select certificate callback that calls SSL_set_ocsp_response() + SSL_CTX_set_select_certificate_cb(server_ctx.get(), [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t { + return (SSL_set_ocsp_response(client_hello->ssl, OCSP_RESPONSE, sizeof(OCSP_RESPONSE)) == 1) ? + ssl_select_cert_success : ssl_select_cert_error; + }); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + // Set up client with ocsp stapling enabled + SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_NONE, nullptr); + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + SSL_set_connect_state(client_ssl.get()); + SSL_enable_ocsp_stapling(client_ssl.get()); + + ASSERT_TRUE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); + + // Check that the client received the OCSP response ok + const uint8_t *ocsp_resp_data{}; + size_t ocsp_resp_len{}; + SSL_get0_ocsp_response(client_ssl.get(), &ocsp_resp_data, &ocsp_resp_len); + ASSERT_EQ(sizeof(OCSP_RESPONSE), ocsp_resp_len); + ASSERT_EQ(0, memcmp(OCSP_RESPONSE, ocsp_resp_data, ocsp_resp_len)); +} + + +/** + * @brief This test exercises a leak in SSL_set_ocsp_response() + * + * This test exercises a leak in SSL_set_ocsp_response() that occurs when it is + * invoked multiple times from within the same certificate selection callback + * i.e. without the fix, running this test under valgrind or similar memory + * checker tool will report the memory leak. + * + * Note that the leak does _not_ occur if SSL_set_ocsp_response() is only called + * _once_ from within the same certificate selection callback. It is only the + * additional calls that leak. + */ +TEST(SSLTest, test_SSL_set_ocsp_response_leak_inside_select_certificate_cb) { + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + static const uint8_t OCSP_RESPONSE[] { 1, 2, 3, 4, 5 }; + + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_server_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_client_method())); + + // Set up server with a select certificate callback that calls + // SSL_set_ocsp_response() 5 times. This will result in 4 leaks if the + // SSL_set_ocsp_response() fix is not in place. + SSL_CTX_set_select_certificate_cb(server_ctx.get(), [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t { + SSL_set_ocsp_response(client_hello->ssl, OCSP_RESPONSE, sizeof(OCSP_RESPONSE)); + SSL_set_ocsp_response(client_hello->ssl, OCSP_RESPONSE, sizeof(OCSP_RESPONSE)); + SSL_set_ocsp_response(client_hello->ssl, OCSP_RESPONSE, sizeof(OCSP_RESPONSE)); + SSL_set_ocsp_response(client_hello->ssl, OCSP_RESPONSE, sizeof(OCSP_RESPONSE)); + SSL_set_ocsp_response(client_hello->ssl, OCSP_RESPONSE, sizeof(OCSP_RESPONSE)); + return ssl_select_cert_success; + }); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + // Set up client with ocsp stapling enabled + SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_NONE, nullptr); + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + SSL_set_connect_state(client_ssl.get()); + SSL_enable_ocsp_stapling(client_ssl.get()); + + ASSERT_TRUE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); + + // Check that the client received the OCSP response ok + const uint8_t *ocsp_resp_data{}; + size_t ocsp_resp_len{}; + SSL_get0_ocsp_response(client_ssl.get(), &ocsp_resp_data, &ocsp_resp_len); + ASSERT_EQ(sizeof(OCSP_RESPONSE), ocsp_resp_len); + ASSERT_EQ(0, memcmp(OCSP_RESPONSE, ocsp_resp_data, ocsp_resp_len)); +} + + +/** + * Test that setting a TLS alert and returning ssl_verify_invalid, from a + * callback installed via SSL_CTX_set_custom_verify(), results in a handshake + * failure, and that same TLS alert being received by the peer (subject to our + * restrictions on mapping from TLS alert to X509 error code and back again) + */ +#ifdef BSSL_COMPAT +TEST(SSLTest, test_SSL_CTX_set_custom_verify_alert_codes) { + TempFile server_2_key_pem { server_2_key_pem_str }; + TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str }; + + static const std::map alerts { + // Alerts that we can map + { SSL_AD_HANDSHAKE_FAILURE, "handshake failure" }, + { SSL_AD_CERTIFICATE_EXPIRED, "certificate expired" }, + { SSL_AD_BAD_CERTIFICATE, "bad certificate" }, + { SSL_AD_CERTIFICATE_REVOKED, "certificate revoked" }, + { SSL_AD_DECRYPT_ERROR, "decrypt error" }, + { SSL_AD_UNKNOWN_CA, "unknown CA" }, + { SSL_AD_CERTIFICATE_UNKNOWN, "certificate unknown" }, + { SSL_AD_UNSUPPORTED_CERTIFICATE, "unsupported certificate" }, + { SSL_AD_INTERNAL_ERROR, "internal error" }, + { SSL_AD_CERTIFICATE_REVOKED, "certificate revoked" }, + // Alerts that we cannot map + { SSL_AD_ACCESS_DENIED, "handshake failure" }, + { SSL_AD_BAD_CERTIFICATE_HASH_VALUE, "handshake failure" }, + { SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE, "handshake failure" }, + { SSL_AD_BAD_RECORD_MAC, "handshake failure" }, + { SSL_AD_CERTIFICATE_REQUIRED, "handshake failure" }, + { SSL_AD_CERTIFICATE_UNOBTAINABLE, "handshake failure" }, + { SSL_AD_CLOSE_NOTIFY, "handshake failure" }, + { SSL_AD_DECODE_ERROR, "handshake failure" }, + { SSL_AD_DECOMPRESSION_FAILURE, "handshake failure" }, + // An invalid alert code + { 255, "handshake failure" }, + }; + + for (auto const& [alert_code, alert_string] : alerts) { + int sockets[2]; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets)); + SocketCloser close[] { sockets[0], sockets[1] }; + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_server_method())); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_client_method())); + + // Install an info callback on the server to check for the expected tls alert + // If the server reads a TLS alert, it stores the string description of the + // alert in the SSL object's app data so that the test code can check for it. + ossl_SSL_CTX_set_info_callback(server_ctx.get(), [](const SSL *ssl, int type, int val){ + if (type & ossl_SSL_CB_READ_ALERT) { + SSL_set_app_data(const_cast(ssl), ossl_SSL_alert_desc_string_long(val)); + } + }); + ASSERT_TRUE(SSL_CTX_use_certificate_chain_file(server_ctx.get(), server_2_cert_chain_pem.path())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey_file(server_ctx.get(), server_2_key_pem.path(), SSL_FILETYPE_PEM)); + bssl::UniquePtr server_ssl(SSL_new(server_ctx.get())); + ASSERT_TRUE(SSL_set_fd(server_ssl.get(), sockets[0])); + SSL_set_accept_state(server_ssl.get()); + + // Set up client with a custom verify callback that will set out_alert and + // return ssl_verify_invalid. This should cause the client to send the + // specified TLS alert to the server and cause a handshake failure. + SSL_CTX_set_custom_verify(client_ctx.get(), SSL_VERIFY_PEER, [](SSL *ssl, uint8_t *out_alert) -> enum ssl_verify_result_t { + *out_alert = *static_cast(SSL_get_app_data(ssl)); + return ssl_verify_invalid; + }); + bssl::UniquePtr client_ssl(SSL_new(client_ctx.get())); + ASSERT_TRUE(SSL_set_fd(client_ssl.get(), sockets[1])); + SSL_set_connect_state(client_ssl.get()); + // Setup the TLS alert code to be sent from the custom verify callback + SSL_set_app_data(client_ssl.get(), &alert_code); + + ASSERT_FALSE(CompleteHandshakes(client_ssl.get(), server_ssl.get())); + + // Check that the server received the expected TLS alert + ASSERT_STREQ(alert_string, static_cast(SSL_get_app_data(server_ssl.get()))); + } +} +#endif + + +TEST(SSLTest, test_SSL_get_all_cipher_names) { + // Get the size by passing a zero size input buffer + size_t size1 = SSL_get_all_cipher_names(nullptr, 0); + ASSERT_GT(size1, 0); + + // Allocate a buffer of the size returned above + std::unique_ptr names1(new const char*[size1]); + + // Call SSL_get_all_cipher_names() with the allocated buffer + size_t size2 = SSL_get_all_cipher_names(names1.get(), size1); + + // Check that the size returned is the same as the size we allocated + ASSERT_EQ(size2, size1); + + // Check that the names are not null and have a non-zero length + for (size_t i = 0; i < size2; i++) { + ASSERT_NE(names1.get()[i], nullptr); + ASSERT_GT(strlen(names1.get()[i]), 0); + // printf("%s\n", names1.get()[i]); + } + + // Allocate another buffer that is one element too short (size2 - 1) + std::unique_ptr names2(new const char*[size2 - 1]); + + // Call SSL_get_all_cipher_names() with the short buffer + size_t size3 = SSL_get_all_cipher_names(names2.get(), size2 - 1); + + // Check that the size returned is the number of ciphers it + // would have returned if the buffer had been big enough. + ASSERT_EQ(size3, size2); + + // Check that the names are not null and have a non-zero length + for (size_t i = 0; i < (size2 - 1); i++) { + ASSERT_NE(names2.get()[i], nullptr); + ASSERT_GT(strlen(names2.get()[i]), 0); + // printf("%s\n", names2.get()[i]); + } +} + + +TEST(SSLTest, test_SSL_get_all_signature_algorithm_names) { + // Get the size by passing a zero size input buffer + size_t size1 = SSL_get_all_signature_algorithm_names(nullptr, 0); + ASSERT_GT(size1, 0); + + // Allocate a buffer of the size returned above + std::unique_ptr names1(new const char*[size1]); + + // Call SSL_get_all_signature_algorithm_names() with the allocated buffer + size_t size2 = SSL_get_all_signature_algorithm_names(names1.get(), size1); + + // Check that the size returned is the same as the size we allocated + ASSERT_EQ(size2, size1); + + // Check that the names are not null and have a non-zero length + for (size_t i = 0; i < size2; i++) { + ASSERT_NE(names1.get()[i], nullptr); + ASSERT_GT(strlen(names1.get()[i]), 0); + // printf("%s\n", names1.get()[i]); + } + + // Allocate another buffer that is one element too short (size2 - 1) + std::unique_ptr names2(new const char*[size2 - 1]); + + // Call SSL_get_all_signature_algorithm_names() with the short buffer + size_t size3 = SSL_get_all_signature_algorithm_names(names2.get(), size2 - 1); + + // Check that the size returned is the number of ciphers it + // would have returned if the buffer had been big enough. + ASSERT_EQ(size3, size2); + + // Check that the names are not null and have a non-zero length + for (size_t i = 0; i < (size2 - 1); i++) { + ASSERT_NE(names2.get()[i], nullptr); + ASSERT_GT(strlen(names2.get()[i]), 0); + // printf("%s\n", names2.get()[i]); + } +} + + +TEST(SSLTest, test_SSL_get_all_curve_names) { + // Get the size by passing a zero size input buffer + size_t size1 = SSL_get_all_curve_names(nullptr, 0); + ASSERT_GT(size1, 0); + + // Allocate a buffer of the size returned above + std::unique_ptr names1(new const char*[size1]); + + // Call SSL_get_all_curve_names() with the allocated buffer + size_t size2 = SSL_get_all_curve_names(names1.get(), size1); + + // Check that the size returned is the same as the size we allocated + ASSERT_EQ(size2, size1); + + // Check that the names are not null and have a non-zero length + for (size_t i = 0; i < size2; i++) { + ASSERT_NE(names1.get()[i], nullptr); + // ASSERT_GT(strlen(names1.get()[i]), 0); + printf("%s\n", names1.get()[i]); + } + + // Allocate another buffer that is one element too short (size2 - 1) + std::unique_ptr names2(new const char*[size2 - 1]); + + // Call SSL_get_all_curve_names() with the short buffer + size_t size3 = SSL_get_all_curve_names(names2.get(), size2 - 1); + + // Check that the size returned is the number of ciphers it + // would have returned if the buffer had been big enough. + ASSERT_EQ(size3, size2); + + // Check that the names are not null and have a non-zero length + for (size_t i = 0; i < (size2 - 1); i++) { + ASSERT_NE(names2.get()[i], nullptr); + ASSERT_GT(strlen(names2.get()[i]), 0); + // printf("%s\n", names2.get()[i]); + } +} diff --git a/bssl-compat/test/test_stack.cc b/bssl-compat/test/test_stack.cc new file mode 100644 index 00000000000..370e0728f73 --- /dev/null +++ b/bssl-compat/test/test_stack.cc @@ -0,0 +1,112 @@ +#include +#include +#include +#include + +#ifdef BSSL_COMPAT +#include +#endif + + +using FOO = int; + +static void FOO_free(FOO *x) { OPENSSL_free(x); } + +BSSL_NAMESPACE_BEGIN +BORINGSSL_MAKE_DELETER(FOO, FOO_free) +BSSL_NAMESPACE_END + +static bssl::UniquePtr FOO_new(int x) { + bssl::UniquePtr ret( + static_cast(OPENSSL_malloc(sizeof(FOO)))); + if (!ret) { + return nullptr; + } + *ret = x; + return ret; +} + +DEFINE_STACK_OF(FOO) + + +TEST(StackTest, test1) { + STACK_OF(FOO) *s = sk_FOO_new_null(); + ASSERT_TRUE(s); + + int num = sk_FOO_num(s); + EXPECT_EQ(0, num); + + sk_FOO_free(s); +} + +TEST(StackTest, test2) { + { + bssl::UniquePtr s {sk_FOO_new_null()}; + ASSERT_TRUE(s.get()); + } + + { + bssl::UniquePtr s {sk_FOO_new_null()}; + ASSERT_TRUE(s.get()); + + auto seven = FOO_new(7); + sk_FOO_push(s.get(), seven.release()); + } +} + +TEST(StackTest, test3) { + bssl::UniquePtr sk {sk_FOO_new_null()}; + bssl::UniquePtr f1 {FOO_new(1)}; + ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(f1))); + ASSERT_TRUE(bssl::PushToStack(sk.get(), FOO_new(2))); +} + +TEST(StackTest, test4) { +#ifdef BSSL_COMPAT + GTEST_SKIP(); // TODO: Make this work on bssl-compat +#else + bssl::UniquePtr nc(NAME_CONSTRAINTS_new()); + nc->permittedSubtrees = sk_GENERAL_SUBTREE_new_null(); +#endif +} + +#ifdef BSSL_COMPAT + +using ossl_FOO = int; // Equivalent to FOO defined above +ossl_DEFINE_STACK_OF(ossl_FOO) + +ossl_FOO *ossl_FOO_new(int i) { + ossl_FOO *result {reinterpret_cast(ossl_OPENSSL_malloc(sizeof(ossl_FOO)))}; + *result = i; + return result; +} + +ossl_STACK_OF(ossl_FOO) *ossl_FOO_new_stack(std::vector values) { + ossl_STACK_OF(ossl_FOO) *result {ossl_sk_ossl_FOO_new_null()}; + for (int i = 0; i < values.size() ; i++) { + ossl_sk_ossl_FOO_push(result, ossl_FOO_new(i)); + } + return result; +} + +/* + * Show that a pointer to an OpenSSL ossl_STACK_OF(ossl_FOO) can be cast to a + * pointer to the equivalent BorisngSSL STACK_OF(FOO) (provided that the + * pointer to ossl_FOO and pointer to FOO types are also castable). + */ +TEST(StackTest, FOO) { + std::vector values { 0, 1, 2, 3, 4 }; + ossl_STACK_OF(ossl_FOO) *ostack {ossl_FOO_new_stack(values)}; + + STACK_OF(FOO) *bstack {reinterpret_cast(ostack)}; + + EXPECT_EQ(values.size(), sk_FOO_num(bstack)); + + for (int i = 0; i < values.size() ; i++) { + EXPECT_EQ(values[i], *sk_FOO_value(bstack, i)); + } + + sk_FOO_pop_free(bstack, FOO_free); +} + +#endif // BSSL_COMPAT \ No newline at end of file diff --git a/bssl-compat/test/test_x509.cc b/bssl-compat/test/test_x509.cc new file mode 100644 index 00000000000..5ac95c072e8 --- /dev/null +++ b/bssl-compat/test/test_x509.cc @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +#include "certs/server_1_cert.pem.h" +#include "crypto/test/test_util.h" + + +TEST(X509Test, test_X509_NAME_digest) { + bssl::UniquePtr bio {BIO_new_mem_buf(server_1_cert_pem_str, strlen(server_1_cert_pem_str))}; + ASSERT_TRUE(bio); + bssl::UniquePtr cert {PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)}; + ASSERT_TRUE(cert); + X509_NAME *sn {X509_get_subject_name(cert.get())}; + ASSERT_TRUE(sn); + + uint8_t buf[EVP_MAX_MD_SIZE]; + unsigned len; + + ASSERT_EQ(1, X509_NAME_digest(sn, EVP_sha256(), buf, &len)); + ASSERT_EQ(32, len); + + uint8_t expected[] {0x19,0x27,0x3b,0xb5,0x60,0x9c,0xa4,0x45,0x9e,0xa8,0x73,0x0d,0x7f,0x5f,0xb5,0xf1,0xd3,0x5c,0x06,0xad,0x3d,0x2b,0x94,0x98,0x1c,0x65,0xb8,0x76,0x8d,0xee,0x15,0xed}; + + ASSERT_EQ(Bytes(expected), Bytes(buf, len)); +} + +TEST(X509Test, test_X509_get_X509_PUBKEY) { + bssl::UniquePtr bio {BIO_new_mem_buf(server_1_cert_pem_str, strlen(server_1_cert_pem_str))}; + ASSERT_TRUE(bio); + bssl::UniquePtr cert {PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)}; + ASSERT_TRUE(cert); + X509_PUBKEY *pubkey {X509_get_X509_PUBKEY(cert.get())}; + ASSERT_TRUE(pubkey); + bssl::UniquePtr pkey {X509_PUBKEY_get(pubkey)}; + ASSERT_TRUE(pkey); + ASSERT_EQ(EVP_PKEY_RSA, EVP_PKEY_id(pkey.get())); +} + +TEST(X509Test, test_X509_digest) { + bssl::UniquePtr bio {BIO_new_mem_buf(server_1_cert_pem_str, strlen(server_1_cert_pem_str))}; + ASSERT_TRUE(bio); + bssl::UniquePtr cert {PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)}; + ASSERT_TRUE(cert); + + uint8_t buf[EVP_MAX_MD_SIZE]; + unsigned len; + + ASSERT_EQ(1, X509_digest(cert.get(), EVP_sha256(), buf, &len)); + ASSERT_EQ(32, len); + + uint8_t expected[] {0xc3,0x49,0x59,0xa8,0x3b,0x10,0xa2,0xef,0x91,0xe5,0x30,0x3f,0x63,0xdb,0xbd,0x1b,0xfd,0x63,0xc7,0xf6,0x6a,0x75,0xbb,0x9f,0x43,0x4a,0x77,0xad,0x9d,0x9a,0xfc,0x09}; + + ASSERT_EQ(Bytes(expected), Bytes(buf, len)); +} + +TEST(X509Test, test_i2d_X509_PUBKEY) { + bssl::UniquePtr bio {BIO_new_mem_buf(server_1_cert_pem_str, strlen(server_1_cert_pem_str))}; + ASSERT_TRUE(bio); + + bssl::UniquePtr cert {PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)}; + ASSERT_TRUE(cert); + + X509_PUBKEY *pubkey {X509_get_X509_PUBKEY(cert.get())}; + ASSERT_TRUE(pubkey); + + uint8_t* bytes {nullptr}; + const int len = i2d_X509_PUBKEY(pubkey, &bytes); + ASSERT_TRUE(bytes); + ASSERT_EQ(len, 294); + + OPENSSL_free(bytes); +} diff --git a/bssl-compat/test/test_x509v3.cc b/bssl-compat/test/test_x509v3.cc new file mode 100644 index 00000000000..95e169f353e --- /dev/null +++ b/bssl-compat/test/test_x509v3.cc @@ -0,0 +1,7 @@ +#include +#include + + +TEST(X509V3Test, test_GENERAL_NAMES_new_free) { + GENERAL_NAMES_free(GENERAL_NAMES_new()); +} diff --git a/bssl-compat/tools/BUILD b/bssl-compat/tools/BUILD new file mode 100644 index 00000000000..16af3e55f0d --- /dev/null +++ b/bssl-compat/tools/BUILD @@ -0,0 +1,6 @@ +licenses(["notice"]) # Apache 2 + +exports_files([ + "uncomment.sh", + "generate.c.sh", +]) diff --git a/bssl-compat/tools/generate.c.sh b/bssl-compat/tools/generate.c.sh new file mode 100755 index 00000000000..f208d3df929 --- /dev/null +++ b/bssl-compat/tools/generate.c.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +set -euo pipefail +# set -x # Echo commands + +# +# For a specified function, this script will find the signature in the relevant +# BoringSSL header, and generate an implementation for it which calls directly +# onto the equivalent OpenSSL function (via the dynamically loaded +# ossl.ossl pointer) +# +# This is a super naive implementation that doesn't work for all functions +# because it only uses simple text processing to search/process the source & +# header files. For example, simple text searching cannot find some functions in +# the BoringSSL headers because they are declared by macros that construct the +# function's name by concatination. +# +TOP_DIR="$(cd "$(dirname "$0")/.." && pwd)" +FUNC_NAME="${1?"FUNC_NAME not specified"}" +CC_FILE="${2?"CC_FILE not specified"}" + + +function error { + cmake -E cmake_echo_color --red "$1" + exit 1 +} + +# Accept third argument for include directory (for Bazel builds) +INCLUDE_DIR="${3?"INCLUDE_DIR not specified"}" +[[ -d "$INCLUDE_DIR" ]] || error "INCLUDE_DIR $INCLUDE_DIR does not exist" + +################################################################################ +# Find out which header file the function is declared in +################################################################################ +HDR_FILE=$(grep -r "OPENSSL_EXPORT.*[^A-Za-z0-9_]$FUNC_NAME[ \t]*(" $INCLUDE_DIR/openssl/* | cut -d: -f1) +if [ ! -f "$HDR_FILE" ]; then + error "Failed to determine header file for $FUNC_NAME" +fi + +################################################################################ +# Extract the function's line number(s), return type, args etc +################################################################################ +FUNC_SIG_MULTI_LINE="$(grep -Pzob "OPENSSL_EXPORT\s.*[^A-Za-z0-9_]$FUNC_NAME\s*\([^;]*\)" "$HDR_FILE" | sed -e 's/OPENSSL_EXPORT\s*//g' -e 's|^// ||' -e 's/\x0//g')" +FUNC_SIG_LINE_COUNT="$(echo "$FUNC_SIG_MULTI_LINE" | wc -l)" +FUNC_SIG_OFFSET="$(echo "$FUNC_SIG_MULTI_LINE" | grep -o '^[0-9]*:' | cut -d: -f1)" +FUNC_SIG_ONE_LINE="$(echo "$FUNC_SIG_MULTI_LINE" | tr '\n' ' ' | sed -e 's/\s\s*/ /g' -e 's/\s*$//g' | cut -d: -f2)" +FUNC_SIG_LINE_FROM=$(($(head -c+$FUNC_SIG_OFFSET "$HDR_FILE" | wc -l) + 1)) +FUNC_SIG_LINE_TO=$(($FUNC_SIG_LINE_FROM + $FUNC_SIG_LINE_COUNT - 1)) +FUNC_SIG_RET="$(echo "$FUNC_SIG_ONE_LINE" | sed -e "s/\(.*[^A-Za-z_]\)$FUNC_NAME\s*(.*)$/\1/g")" +FUNC_SIG_ARGS="$(echo "$FUNC_SIG_ONE_LINE" | sed -e "s/.*[^A-Za-z0-9_]$FUNC_NAME\s*\((.*)\)$/\1/g")" +FUNC_SIG_ARGS_NAMES="($(echo $FUNC_SIG_ARGS | sed -e 's/^(//g' -e 's/)$//g' | \ + tr ',' '\n' | \ + sed -e 's/\[.*\]$//g' -e 's/^.*[^a-zA-Z0-9_]\([a-zA-Z_][a-zA-Z0-9_]*\)/\1/g' -e 's/\[.*\]$//g' | \ + tr '\n' ',' | \ + sed -e 's/,$//g' -e 's/,/, /g' -e 's/void//g'))" + +################################################################################ +# Generate the source file +# +# Note that if the OpenSSL function that we are calling onto is a function-like +# macro then we must call it by name so that it expands correctly. Otherwise, if +# it's a proper function, then call it via the dynamically loaded function +# pointer in the ossl struct. We _could_ detect which case it is by examining +# the OpenSSL headers, but it's much easier to use an #ifdef in the generated +# code. +################################################################################ +cat <<- EOF > "$CC_FILE" +#include +#include + + +$FUNC_SIG_ONE_LINE { +#ifdef ossl_$FUNC_NAME + $([ "$FUNC_SIG_RET" != "void" ] && echo "return ")ossl_$FUNC_NAME$FUNC_SIG_ARGS_NAMES; +#else + $([ "$FUNC_SIG_RET" != "void" ] && echo "return ")ossl.ossl_$FUNC_NAME$FUNC_SIG_ARGS_NAMES; +#endif +} +EOF diff --git a/bssl-compat/tools/generate.patch.sh b/bssl-compat/tools/generate.patch.sh new file mode 100755 index 00000000000..c15aa3d7e04 --- /dev/null +++ b/bssl-compat/tools/generate.patch.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -euo pipefail + +BSSL_COMPAT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +BUILD_DIR="${1?"BUILD_DIR not specified"}" +SOURCE_FILE="${2?"SOURCE_FILE not specified"}" + +SOURCE_FILE="$(realpath --canonicalize-existing --relative-to="$BSSL_COMPAT_DIR" "$SOURCE_FILE")" +PATCH_FILE="$BSSL_COMPAT_DIR/patch/$SOURCE_FILE.patch" + +mkdir -p "$(dirname "$PATCH_FILE")" + +diff -au --label "a/$SOURCE_FILE" "$BUILD_DIR/generate/$SOURCE_FILE.1.applied.script" \ + --label "b/$SOURCE_FILE" "$BSSL_COMPAT_DIR/$SOURCE_FILE" > "$PATCH_FILE" diff --git a/bssl-compat/tools/uncomment.sh b/bssl-compat/tools/uncomment.sh new file mode 100755 index 00000000000..3c229e8586d --- /dev/null +++ b/bssl-compat/tools/uncomment.sh @@ -0,0 +1,311 @@ +#!/bin/bash + +set -euo pipefail + +TOP_DIR="$(cd "$(dirname "$0")/.." && pwd)" +HDR_FILE="${1?"HDR_FILE not specified"}" +shift + +function info { + true || echo "INFO[$HDR_FILE]: $1" +} + +function warn { + echo "WARN[$HDR_FILE]: $1" +} + +function error { + echo "ERROR[$HDR_FILE]: $1" + exit 1 +} + +cleanup() { + if [[ $? != 0 ]]; then + echo "ERROR[$HDR_FILE]: Error while processing option \"$OPTION\"" + fi +} +trap cleanup EXIT + +[[ -f "$HDR_FILE" ]] || error "HDR_FILE $HDR_FILE does not exist" + + +# This contains the current command line option being processed. It is used +# when reporting low level errors, to provide some context for the error +OPTION="" +option_start() { + OPTION=$1 +} +option_add() { + while [[ $# > 0 ]]; do + OPTION="$OPTION '$1'" + shift + done +} +option_end() { + option_add $* + info " $OPTION" +} + +run_sed_expression() { + [[ $# == 1 ]] || error "run_sed_expression(): One argument required" + local SED_EXPRESSION="$1" + sed -i.bak -e "$SED_EXPRESSION" "$HDR_FILE" + if ! cmp -s "$HDR_FILE" "$HDR_FILE.bak"; then + ((CHANGES += 1)) + if [[ -v MELD ]]; then + meld "$HDR_FILE.bak" "$HDR_FILE" + fi + fi + rm -f "$HDR_FILE.bak" +} + +uncomment_line_range() { + [[ $# == 2 ]] || error "uncomment_line_range(): Two line numbers required" + run_sed_expression "${1},${2}s%^// %%g" +} + +uncomment_regex_range() { + [[ $# == 2 ]] || error "uncomment_regex_range(): Two regexes required" + L1=$(grep -n "^// $1" "$HDR_FILE" | sed -n 1p | cut -d: -f1) + L2=$(grep -n "^// $2" "$HDR_FILE" | awk -F: '$1 > '$L1' {print $1; exit}') + [ -z "$L1" ] && error "Failed to locate first pattern '$1'" + [ -z "$L2" ] && error "Failed to locate second pattern '$2'" + uncomment_line_range $L1 $L2 +} + +uncomment_preproc_directive() { + [[ $# == 1 ]] || error "uncomment_preproc_directive(): One regex required" + for L1 in $(grep -n "^// #\s*$1" "$HDR_FILE" | cut -d: -f1); do + L2=$(awk '(NR == '$L1'),/[^\\]$/{print NR}' "$HDR_FILE" | tail -1) + uncomment_line_range $L1 $L2 + done +} + +comment_line_range() { + [[ $# == 2 ]] || error "comment_line_range(): Two line numbers required" + run_sed_expression "${1},${2}s%^%//%g" +} + +comment_regex_range() { + [[ $# == 2 ]] || error "comment_regex_range(): Two regexes required" + L1=$(grep -n "$1" "$HDR_FILE" | sed -n 1p | cut -d: -f1) + L2=$(awk '(NR == '$L1'),/'$2'/{print NR}' "$HDR_FILE" | tail -1) + [ -z "$L1" ] && error "comment_regex_range(): Failed to locate first pattern" + [ -z "$L2" ] && error "comment_regex_range(): Failed to locate second pattern" + comment_line_range $L1 $L2 +} + + +while [ $# -ne 0 ]; do + option_start "$1" + CHANGES=0 + case "$1" in + --comment) # Comment everything out + option_end + run_sed_expression 's|^|// |' + run_sed_expression 's|^// $||' + run_sed_expression 's|^// //|//|' + run_sed_expression 's|^// /\*|/*|' + run_sed_expression 's|^// \*$| *|' + run_sed_expression 's|^// \* | * |' + run_sed_expression 's|^// \*/$| */|' + ;; + "-h") # Set of general stuff like include guards, extern, and #if/else/end + option_end + for DIRECTIVE in include if ifdef ifndef else elif endif undef error warning; do + uncomment_preproc_directive "\<$DIRECTIVE\>" + done + uncomment_preproc_directive "define\s*OPENSSL_HEADER_.*" + run_sed_expression "s%^// \(extern\s*\"C+\?+\?\".*\)$%\1%g" + run_sed_expression "s%^// \(}\s*/[/\*]\s*extern\s*\"\?C+\?+\?\"\?.*\)$%\1%g" + run_sed_expression "s%^// \(BSSL_NAMESPACE_\(BEGIN\|END\)\)$%\1%g" + ;; + --uncomment-func-decl) # Function name + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end $2 + FUNC_SIG_MULTI_LINE="$(grep -Pzob "OPENSSL_EXPORT\s*[^;]*[^A-Za-z0-9_]$2\s*\([^;]*\)" "$HDR_FILE" | sed -e 's/OPENSSL_EXPORT\s*//g' -e 's%^// %%' -e 's/\x0//g')" + FUNC_SIG_LINE_COUNT="$(echo "$FUNC_SIG_MULTI_LINE" | wc -l)" + FUNC_SIG_OFFSET="$(echo "$FUNC_SIG_MULTI_LINE" | grep -o '^[0-9]*:' | cut -d: -f1)" + FUNC_SIG_LINE_FROM=$(($(head -c+$FUNC_SIG_OFFSET "$HDR_FILE" | wc -l) + 1)) + FUNC_SIG_LINE_TO=$(($FUNC_SIG_LINE_FROM + $FUNC_SIG_LINE_COUNT - 1)) + uncomment_line_range ${FUNC_SIG_LINE_FROM} ${FUNC_SIG_LINE_TO} + shift + ;; + --uncomment-regex) # Uncomment consecutive lines matching regexes + PATTERNS=() + while [[ $# > 1 ]] && [[ $2 != -* ]]; do + shift && PATTERNS[${#PATTERNS[@]}]="$1" + option_add "$1" + done + option_end + if [[ ${#PATTERNS[@]} == 1 ]]; then + run_sed_expression "s%^// \(${PATTERNS[0]}\)%\1%" + else + for L1 in $(grep -n "^// ${PATTERNS[0]}" "$HDR_FILE" | cut -d: -f1); do + for ((i=1; i < ${#PATTERNS[@]} ; i++)); do + L2=$((L1 + i)) + if grep -n "^// ${PATTERNS[i]}" "$HDR_FILE" | cut -d: -f1 | grep -q "^$L2$"; then + if (( i == ${#PATTERNS[@]} - 1 )); then + uncomment_line_range $L1 $L2 + break 2 # exit both loops + fi + fi + done + done + fi + ;; + --uncomment-macro-redef) # -d Redefine macro to be ossl_ + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + run_sed_expression "s%^//\(\s\)#\s*define\s*\<\($2\)\>.*$%#ifdef\1ossl_\2\n#define\1\2\1ossl_\2\n#endif%" + shift + ;; + --uncomment-typedef-redef) # -t Redefine "typedef struct " to be "typedef struct ossl_ " + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + run_sed_expression "s%^//\(\s*\)typedef\s*struct\s*\([[:alnum:]_]*\)\s*\(\<$2\>\);%typedef\1struct\1ossl_\2\1\3;%" + shift + ;; + --uncomment-macro) # Uncomment #define .... (including continuation lines) + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + for L1 in $(grep -n "^// #\s*define\s*$2\>" "$HDR_FILE" | cut -d: -f1); do + L2=$(awk '(NR == '$L1'),/[^\\]$/{print NR}' "$HDR_FILE" | tail -1) + uncomment_line_range $L1 $L2 + done + shift + ;; + --uncomment-regex-range) # Uncomment multi-line matching regex + [[ $3 ]] && [[ $2 != -* ]] && [[ $3 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" "$3" + uncomment_regex_range "$2" "$3" + shift 2 + ;; + --uncomment-gtest-func) + [[ $3 ]] && [[ $2 != -* ]] && [[ $3 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" "$3" + uncomment_regex_range "\s*\(TEST\|TEST_P\)\s*($2\s*,\s*$3\s*)\s*{" "}" + shift 2 + ;; + --uncomment-gtest-func-skip) + [[ $3 ]] && [[ $2 != -* ]] && [[ $3 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" "$3" + uncomment_regex_range "\(TEST\|TEST_P\)\s*($2\s*,\s*$3\s*)\s*{" "}" + run_sed_expression '/^\(TEST\|TEST_P\)\s*(\s*'$2'\s*,\s*'$3'\s*)\s*{/a #ifdef BSSL_COMPAT\nGTEST_SKIP() << "TODO: Investigate failure on BSSL_COMPAT";\n#endif' + shift 2 + ;; + --uncomment-struct) # Uncomment struct + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + uncomment_regex_range "struct\s*$2\>.*{$" "}.*;$" + shift + ;; + --uncomment-class-fwd) # Uncomment class forward decl + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + run_sed_expression "s%^// \(class\s*$2\s*;\s*\)$%\1%" + shift + ;; + --uncomment-class) # Uncomment class + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + uncomment_regex_range "class\s*\<$2\>" "};$" + shift + ;; + --uncomment-enum) # Uncomment enum + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + uncomment_regex_range "enum\s*\<$2\>" "};$" + shift + ;; + --uncomment-typedef) # Uncomment typedef + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + LINE=$(grep -n "^// \s*\.*\<$2\>.*" "$HDR_FILE" | sed -n 1p) + L1=$(echo "$LINE" | cut -d: -f1) && L2=$L1 + if [[ ! "$LINE" =~ \;$ ]]; then # multi-line + L2=$(awk '(NR == '$L1'),/^\/\/ .*;$/{print NR}' "$HDR_FILE" | tail -1) + fi + uncomment_line_range $L1 $L2 + shift + ;; + --uncomment-func-impl) + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + LINE=$(grep -n "^// [^ !].*\b$2\s*(.*[^;]$" "$HDR_FILE" | sed -n 1p) + L1=$(echo "$LINE" | cut -d: -f1) && L2=$L1 + if [[ ! "$LINE" =~ }$ ]]; then # multi-line + L2=$(awk '(NR == '$L1'),/^\/\/ }$/{print NR}' "$HDR_FILE" | tail -1) + fi + uncomment_line_range $L1 $L2 + shift + ;; + --uncomment-static-func-impl) + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + LINE=$(grep -n "^// static\s*.*\b$2\b\s*(" "$HDR_FILE" | sed -n 1p) + L1=$(echo "$LINE" | cut -d: -f1) && L2=$L1 + if [[ ! "$LINE" =~ }$ ]]; then # multi-line + L2=$(awk '(NR == '$L1'),/^\/\/ }$/{print NR}' "$HDR_FILE" | tail -1) + fi + uncomment_line_range $L1 $L2 + shift + ;; + --uncomment-using) + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + LINE=$(grep -n "^// \s*\.*\<$2\>.*" "$HDR_FILE" | sed -n 1p) + L1=$(echo "$LINE" | cut -d: -f1) && L2=$L1 + if [[ ! "$LINE" =~ \;$ ]]; then # multi-line + L2=$(awk '(NR == '$L1'),/^\/\/ .*;$/{print NR}' "$HDR_FILE" | tail -1) + fi + uncomment_line_range $L1 $L2 + shift + ;; + --comment-regex-range) # comment multi-line matching regex + [[ $3 ]] && [[ $2 != -* ]] && [[ $3 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" "$3" + comment_regex_range "$2" "$3" + shift 2 + ;; + --comment-gtest-func) + [[ $3 ]] && [[ $2 != -* ]] && [[ $3 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" "$3" + comment_regex_range "^\s*\(TEST\|TEST_P\)\s*($2\s*,\s*$3\s*)\s*{" "^}" + shift 2 + ;; + --comment-regex) + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end $2 + run_sed_expression "s%\($2\)%// \1%" + shift + ;; + "--sed") # sed expression + [[ $2 ]] && [[ $2 != -* ]] || error "Insufficient arguments for $1" + option_end "$2" + run_sed_expression "$2" + shift + ;; + --echo-on) + set -x + ;; + --echo-off) + set +x + ;; + --meld-on) + MELD=1 + ;; + --meld-off) + unset MELD + ;; + *) + error "Unknown option $1" + ;; + esac + if (( $CHANGES == 0 )); then + error "No changes were made" + fi + shift +done + + diff --git a/ci/do_ci.sh b/ci/do_ci.sh index cb523796ac7..94f38b0f2b8 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -259,7 +259,7 @@ else elif [[ "${CI_TARGET}" == "msan" ]]; then COVERAGE_TEST_TARGETS=("${COVERAGE_TEST_TARGETS[@]}" "-//test/extensions/...") fi - TEST_TARGETS=("${COVERAGE_TEST_TARGETS[@]}" "@com_github_google_quiche//:ci_tests") + TEST_TARGETS=("${COVERAGE_TEST_TARGETS[@]}") fi case $CI_TARGET in diff --git a/ci/envoy-sync-receive.sh b/ci/envoy-sync-receive.sh new file mode 100755 index 00000000000..8cf99caad7b --- /dev/null +++ b/ci/envoy-sync-receive.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +# +# Copyright Red Hat +# +# This script is invoked from .github/workflow/envoy-sync-*.yaml workflows. +# +# It merges the specified branch from the upstream envoyproxy/envoy repository +# into the current branch in the current working directory. It is assumed that +# the calling workflow has already checked out the destination repository and +# switched to the destination branch, in the current working directory before +# invoking us. +# +# - If the merge is successful, it: +# - pushes the feature branch to the repository +# - creates the associated pull request if it doesn't already exist +# - closes the associated issue if it already exists +# +# -If the merge is unsuccessful, it: +# - leaves the associated pull request untouched if it already exists +# - creates the associated issue issue if it doesn't already exist +# - adds a comment on the associated issue to describe the merge fail +# + +set -euo pipefail + +notice() { printf "::notice:: %s\n" "$1"; } + +SCRATCH="$(mktemp -d)" +cleanup() { + local savexit=$? + rm -rf -- "${SCRATCH}" + exit "${savexit}" +} +trap 'cleanup' EXIT + +SRC_REPO_URL="https://github.com/envoyproxy/envoy.git" +SRC_REPO_PATH="${SRC_REPO_URL/#*github.com?/}" +SRC_REPO_PATH="${SRC_REPO_PATH/%.git/}" +SRC_BRANCH_NAME="$1" +SRC_HEAD_SHA="$(git ls-remote "${SRC_REPO_URL}" | awk "/\srefs\/heads\/${SRC_BRANCH_NAME/\//\\\/}$/{print \$1}")" + +DST_REPO_URL=$(git remote get-url origin) +DST_REPO_PATH="${DST_REPO_URL/#*github.com?/}" +DST_REPO_PATH="${DST_REPO_PATH/%.git/}" +DST_BRANCH_NAME=$(git branch --show-current) +DST_HEAD_SHA=$(git rev-parse HEAD) + +# Add the remote upstream repo and fetch the specified branch +git remote remove upstream &> /dev/null || true +git remote add -f -t "${SRC_BRANCH_NAME}" upstream "${SRC_REPO_URL}" + +# Compose text for pull request or issue title +TITLE="auto-merge ${SRC_REPO_PATH}[${SRC_BRANCH_NAME}] " +TITLE+="into ${DST_REPO_PATH}[${DST_BRANCH_NAME}]" + +# Create a new branch name for the merge. Deliberately don't include +# any commit hash or timestamp in the name to ensure it is repeatable. +# This ensures that each time we get invoked, due to an upstream change, +# we accumulate the changes in the same branch and pull request, rather +# than creating new ones that superceed the old one(s) each time. +DST_NEW_BRANCH_NAME="auto-merge-$(echo "${SRC_BRANCH_NAME}" | tr /. -)" + +# Set the default remote for the gh command +gh repo set-default "${DST_REPO_PATH}" + +# Perform the merge using --no-ff option to force creating a merge commit +if git merge --no-ff --log=10000 --signoff -m "${TITLE}" \ + "upstream/${SRC_BRANCH_NAME}" > "${SCRATCH}/mergeout"; then + DST_NEW_HEAD_SHA="$(git rev-parse HEAD)" + if [[ "${DST_NEW_HEAD_SHA}" != "${DST_HEAD_SHA}" ]]; then + git push --force origin "HEAD:${DST_NEW_BRANCH_NAME}" + PR_COUNT=$(gh pr list --head "${DST_NEW_BRANCH_NAME}" \ + --base "${DST_BRANCH_NAME}" \ + --state open | wc -l) + if [[ "${PR_COUNT}" == "0" ]]; then + PR_URL=$(gh pr create --head "${DST_NEW_BRANCH_NAME}" \ + --base "${DST_BRANCH_NAME}" \ + --title "${TITLE}" \ + --label "auto-merge" \ + --body "Generated by $(basename "$0")") + MERGE_OUTCOME="Created ${PR_URL}" + else + PR_ID=$(gh pr list --head "${DST_NEW_BRANCH_NAME}" \ + --base "${DST_BRANCH_NAME}" \ + --state open | head -1 | cut -f1) + PR_URL="https://github.com/${DST_REPO_PATH}/pull/${PR_ID}" + MERGE_OUTCOME="Updated ${PR_URL}" + fi + else + MERGE_OUTCOME="No changes" + fi + notice "${TITLE} successful (${MERGE_OUTCOME})" + # Close any related issues with a comment describing why + for ISSUE_ID in $(gh issue list -S "${TITLE} failed" | cut -f1); do + ISSUE_URL="https://github.com/${DST_REPO_PATH}/issues/${ISSUE_ID}" + gh issue close "${ISSUE_URL}" --comment "Successful ${TITLE} (${MERGE_OUTCOME})" + notice "Closed ${ISSUE_URL}" + done +else # merge fail + notice "${TITLE} failed" + ISSUE_COUNT=$(gh issue list -S "${TITLE} failed" | wc -l) + if [[ "${ISSUE_COUNT}" == "0" ]]; then + ISSUE_URL=$(gh issue create --title "${TITLE} failed" --body "${TITLE} failed") + ISSUE_ID="$(basename "${ISSUE_URL}")" + ISSUE_OUTCOME="Created" + else + ISSUE_ID="$(gh issue list -S "${TITLE} failed sort:created-asc" | tail -1 | cut -f1)" + ISSUE_URL="https://github.com/${DST_REPO_PATH}/issues/${ISSUE_ID}" + ISSUE_OUTCOME="Updated" + fi + COMMENT_URL=$(\ + gh issue comment "${ISSUE_URL}" --body-file - <<-EOF + Failed to ${TITLE} + + Upstream : [${SRC_HEAD_SHA}](https://github.com/${SRC_REPO_PATH}/commit/${SRC_HEAD_SHA}) + Downstream : [${DST_HEAD_SHA}](https://github.com/${DST_REPO_PATH}/commit/${DST_HEAD_SHA}) + + \`\`\` + $(cat "${SCRATCH}/mergeout" || true) + \`\`\` + EOF + ) + notice "${ISSUE_OUTCOME} ISSUE#${ISSUE_ID} (${COMMENT_URL})" + exit 1 +fi diff --git a/openssl/README.md b/openssl/README.md new file mode 100644 index 00000000000..5480864b026 --- /dev/null +++ b/openssl/README.md @@ -0,0 +1 @@ +This directory contains various files which are specific to building Envoy on OpenSSL. \ No newline at end of file diff --git a/openssl/openssl.bazelrc b/openssl/openssl.bazelrc new file mode 100644 index 00000000000..bf74996f32f --- /dev/null +++ b/openssl/openssl.bazelrc @@ -0,0 +1,28 @@ +# This file is sourced from %workspace%/.bazelrc, and includes additional +# configuration specific to building envoy on openssl/bssl-compat +# Use with: bazel build --config=openssl ... + +# Select OpenSSL as the SSL backend instead of BoringSSL +common:openssl --define=ssl=openssl + +# Define ENVOY_SSL_OPENSSL for preprocessor conditionals in source code +build:openssl --copt=-DENVOY_SSL_OPENSSL +build:openssl --host_copt=-DENVOY_SSL_OPENSSL + +test:openssl --test_env=ENVOY_IP_TEST_VERSIONS=v4only + +# As of today we do not support QUIC/HTTP3, hence we exclude it from the build, always. +# Unfortunately, just setting //bazel:http3=False, is not enough to achieve this. +# Instead, we also have to use boringssl=fips define and filter on the nofips tag. +# This is based on the fact that the FIPS version of BoringSSL doesn't provide enough +# of the functions required to build the QUIC implementation provided by Quiche i.e. if +# we say that we are using the FIPS version of BoringSSL, then all the QUIC support is +# excluded from the build. +common:openssl --//bazel:http3=False +common:openssl --define=boringssl=fips +build:openssl --build_tag_filters=-nofips +test:openssl --test_tag_filters=-nofips + +# Arch-specific build flags for OpenSSL builds, triggered with --config=$ARCH in bazel build command +build:openssl:s390x --//source/extensions/filters/common/lua:luajit2=1 --copt=-DTOOLCHAIN_MISS_ASM_HWCAP_H --host_copt=-DTOOLCHAIN_MISS_ASM_HWCAP_H --action_env=BAZEL_LINKLIBS=-lstdc++ +build:openssl:ppc --//source/extensions/filters/common/lua:luajit2=1 --copt=-DTOOLCHAIN_MISS_ASM_HWCAP_H --host_copt=-DTOOLCHAIN_MISS_ASM_HWCAP_H --action_env=BAZEL_LINKLIBS=-lstdc++ diff --git a/source/common/quic/BUILD b/source/common/quic/BUILD index 745de7f9ef9..964f9738ba7 100644 --- a/source/common/quic/BUILD +++ b/source/common/quic/BUILD @@ -721,4 +721,4 @@ envoy_cc_library( "//source/common/common:logger_lib", "//source/common/runtime:runtime_lib", ]), -) +) \ No newline at end of file diff --git a/source/common/ssl/BUILD b/source/common/ssl/BUILD index 9a903309ba6..4b19edc66f6 100644 --- a/source/common/ssl/BUILD +++ b/source/common/ssl/BUILD @@ -37,3 +37,8 @@ envoy_cc_library( "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", ], ) + +envoy_cc_library( + name = "ssl_lib", + hdrs = ["ssl.h"], +) diff --git a/source/common/ssl/ssl.h b/source/common/ssl/ssl.h new file mode 100644 index 00000000000..b7fb305b28f --- /dev/null +++ b/source/common/ssl/ssl.h @@ -0,0 +1,23 @@ +#pragma once + +#ifdef ENVOY_SSL_OPENSSL +#define SSL_SELECT(BORINGSSL, OPENSSL) OPENSSL +#else +#define SSL_SELECT(BORINGSSL, OPENSSL) BORINGSSL +#endif + +#ifdef ENVOY_SSL_OPENSSL +#define BORINGSSL_TEST_P(test_suite, test_name) \ + TEST_P(test_suite, DISABLED_##test_name) +#else +#define BORINGSSL_TEST_P(test_suite, test_name) \ + TEST_P(test_suite, test_name) +#endif + +#ifdef ENVOY_SSL_OPENSSL +#define BORINGSSL_TEST_F(test_suite, test_name) \ + TEST_F(test_suite, DISABLED_##test_name) +#else +#define BORINGSSL_TEST_F(test_suite, test_name) \ + TEST_F(test_suite, test_name) +#endif diff --git a/source/common/tls/BUILD b/source/common/tls/BUILD index b4981836f9e..00e2d1a8c4c 100644 --- a/source/common/tls/BUILD +++ b/source/common/tls/BUILD @@ -151,6 +151,7 @@ envoy_cc_library( "//source/common/secret:sds_api_lib", "//source/common/ssl:certificate_validation_context_config_impl_lib", "//source/common/ssl:tls_certificate_config_impl_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", ], ) @@ -162,6 +163,7 @@ envoy_cc_library( deps = [ ":context_config_lib", ":server_context_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", ], ) diff --git a/source/common/tls/client_context_impl.cc b/source/common/tls/client_context_impl.cc index 02bc63ad293..0c82a0a3071 100644 --- a/source/common/tls/client_context_impl.cc +++ b/source/common/tls/client_context_impl.cc @@ -156,7 +156,9 @@ ClientContextImpl::newSsl(const Network::TransportSocketOptionsConstSharedPtr& o SSL_set_renegotiate_mode(ssl_con.get(), ssl_renegotiate_freely); } + #ifndef ENVOY_SSL_OPENSSL // This doesn't work on OpenSSL SSL_set_enforce_rsa_key_usage(ssl_con.get(), enforce_rsa_key_usage_); + #endif if (max_session_keys_ > 0) { if (session_keys_single_use_) { diff --git a/source/common/tls/context_config_impl.cc b/source/common/tls/context_config_impl.cc index f7cc4227857..5fc4f876503 100644 --- a/source/common/tls/context_config_impl.cc +++ b/source/common/tls/context_config_impl.cc @@ -14,11 +14,13 @@ #include "source/common/protobuf/utility.h" #include "source/common/secret/sds_api.h" #include "source/common/ssl/certificate_validation_context_config_impl.h" +#include "source/common/ssl/ssl.h" #include "source/common/tls/ssl_handshaker.h" #include "openssl/crypto.h" #include "openssl/ssl.h" + namespace Envoy { namespace Extensions { namespace TransportSockets { @@ -26,6 +28,8 @@ namespace Tls { namespace { +static const bool isFipsEnabled = ContextConfigImpl::getFipsEnabled(); + std::string generateCertificateHash(const std::string& cert_data) { Buffer::OwnedImpl buffer(cert_data); @@ -378,8 +382,8 @@ const unsigned ClientContextConfigImpl::DEFAULT_MIN_VERSION = TLS1_2_VERSION; const unsigned ClientContextConfigImpl::DEFAULT_MAX_VERSION = TLS1_2_VERSION; const std::string ClientContextConfigImpl::DEFAULT_CIPHER_SUITES = - "[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:" - "[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:" + SSL_SELECT("[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:", "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:") + SSL_SELECT("[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:", "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:") "ECDHE-ECDSA-AES256-GCM-SHA384:" "ECDHE-RSA-AES256-GCM-SHA384:"; diff --git a/source/common/tls/context_config_impl.h b/source/common/tls/context_config_impl.h index f2541f416fa..38413701014 100644 --- a/source/common/tls/context_config_impl.h +++ b/source/common/tls/context_config_impl.h @@ -83,6 +83,19 @@ class ContextConfigImpl : public virtual Ssl::ContextConfig { const envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext& dynamic_cvc, const std::string& name); + static bool getFipsEnabled() { + std::ifstream file("/proc/sys/crypto/fips_enabled"); + if (file.fail()) { + return false; + } + + std::stringstream file_string; + file_string << file.rdbuf(); + + std::string fipsEnabledText = file_string.str(); + fipsEnabledText.erase(fipsEnabledText.find_last_not_of("\n") + 1); + return fipsEnabledText.compare("1") == 0; + } protected: ContextConfigImpl(const envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& config, diff --git a/source/common/tls/context_impl.cc b/source/common/tls/context_impl.cc index 4e668a121ca..87c3caffb09 100644 --- a/source/common/tls/context_impl.cc +++ b/source/common/tls/context_impl.cc @@ -182,7 +182,10 @@ ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& c // even request client certs. So, instead, we should configure a callback to skip // validation and always supply the callback to boring SSL. SSL_CTX_set_custom_verify(ctx, verify_mode, customVerifyCallback); +#ifndef ENVOY_SSL_OPENSSL + // Not implemented in the bssl-compat layer for OpenSSL SSL_CTX_set_reverify_on_resume(ctx, /*reverify_on_resume_enabled)=*/1); +#endif } } } @@ -565,9 +568,12 @@ void ContextImpl::logHandshake(SSL* ssl) const { // Increment the `was_key_usage_invalid_` stats to indicate the given cert would have triggered an // error but is allowed because the enforcement that rsa key usage and tls usage need to be // matched has been disabled. +#ifndef ENVOY_SSL_OPENSSL + // Not implemented in the bssl-compat layer for OpenSSL if (SSL_was_key_usage_invalid(ssl)) { stats_.was_key_usage_invalid_.inc(); } +#endif } std::vector ContextImpl::getPrivateKeyMethodProviders() { diff --git a/source/common/tls/io_handle_bio.cc b/source/common/tls/io_handle_bio.cc index 5222c3143d9..6b3595bbbac 100644 --- a/source/common/tls/io_handle_bio.cc +++ b/source/common/tls/io_handle_bio.cc @@ -18,6 +18,33 @@ inline Envoy::Network::IoHandle* bio_io_handle(BIO* bio) { return reinterpret_cast(BIO_get_data(bio)); } +#ifdef ENVOY_SSL_OPENSSL +// OpenSSL requires explicit create/destroy methods for BIO +// NOLINTNEXTLINE(readability-identifier-naming) +int io_handle_new(BIO* bio) { + BIO_set_init(bio, 0); + BIO_set_data(bio, nullptr); + BIO_clear_flags(bio, ~0); + return 1; +} + +// NOLINTNEXTLINE(readability-identifier-naming) +int io_handle_free(BIO* bio) { + if (bio == nullptr) { + return 0; + } + + if (BIO_get_shutdown(bio)) { + if (BIO_get_init(bio)) { + bio_io_handle(bio)->close(); + } + BIO_set_init(bio, 0); + BIO_clear_flags(bio, ~0); + } + return 1; +} +#endif + // NOLINTNEXTLINE(readability-identifier-naming) int io_handle_read(BIO* b, char* out, int outl) { if (out == nullptr) { @@ -61,10 +88,31 @@ int io_handle_write(BIO* b, const char* in, int inl) { } // NOLINTNEXTLINE(readability-identifier-naming) -long io_handle_ctrl(BIO*, int cmd, long, void*) { +long io_handle_ctrl(BIO* b, int cmd, long num, void*) { long ret = 1; +#ifndef ENVOY_SSL_OPENSSL + // Suppress unused parameter warnings when building with BoringSSL + (void)b; + (void)num; +#endif + switch (cmd) { +#ifdef ENVOY_SSL_OPENSSL + // OpenSSL-specific BIO control commands + case BIO_C_SET_FD: + RELEASE_ASSERT(false, "should not be called"); + break; + case BIO_C_GET_FD: + RELEASE_ASSERT(false, "should not be called"); + break; + case BIO_CTRL_GET_CLOSE: + ret = BIO_get_shutdown(b); + break; + case BIO_CTRL_SET_CLOSE: + BIO_set_shutdown(b, int(num)); + break; +#endif case BIO_CTRL_FLUSH: ret = 1; break; @@ -75,6 +123,7 @@ long io_handle_ctrl(BIO*, int cmd, long, void*) { return ret; } + // NOLINTNEXTLINE(readability-identifier-naming) const BIO_METHOD* BIO_s_io_handle(void) { static const BIO_METHOD* method = [&] { @@ -83,6 +132,11 @@ const BIO_METHOD* BIO_s_io_handle(void) { RELEASE_ASSERT(BIO_meth_set_read(ret, io_handle_read), ""); RELEASE_ASSERT(BIO_meth_set_write(ret, io_handle_write), ""); RELEASE_ASSERT(BIO_meth_set_ctrl(ret, io_handle_ctrl), ""); +#ifdef ENVOY_SSL_OPENSSL + // OpenSSL requires explicit create/destroy methods + RELEASE_ASSERT(BIO_meth_set_create(ret, io_handle_new), ""); + RELEASE_ASSERT(BIO_meth_set_destroy(ret, io_handle_free), ""); +#endif return ret; }(); return method; @@ -99,6 +153,9 @@ BIO* BIO_new_io_handle(Envoy::Network::IoHandle* io_handle) { // Initialize the BIO BIO_set_data(b, io_handle); +#ifdef ENVOY_SSL_OPENSSL + BIO_set_shutdown(b, 0); +#endif BIO_set_init(b, 1); return b; diff --git a/source/common/tls/server_context_config_impl.cc b/source/common/tls/server_context_config_impl.cc index c9848cfff81..47fec7b420c 100644 --- a/source/common/tls/server_context_config_impl.cc +++ b/source/common/tls/server_context_config_impl.cc @@ -15,6 +15,7 @@ #include "source/common/ssl/certificate_validation_context_config_impl.h" #include "source/common/tls/default_tls_certificate_selector.h" #include "source/common/tls/ssl_handshaker.h" +#include "source/common/ssl/ssl.h" #include "openssl/crypto.h" #include "openssl/ssl.h" @@ -86,12 +87,15 @@ bool getStatelessSessionResumptionDisabled( } // namespace -const unsigned ServerContextConfigImpl::DEFAULT_MIN_VERSION = TLS1_2_VERSION; +static const bool isFipsEnabled = ContextConfigImpl::getFipsEnabled(); + +const unsigned ServerContextConfigImpl::DEFAULT_MIN_VERSION = SSL_SELECT(TLS1_2_VERSION, TLS1_VERSION); + const unsigned ServerContextConfigImpl::DEFAULT_MAX_VERSION = TLS1_3_VERSION; const std::string ServerContextConfigImpl::DEFAULT_CIPHER_SUITES = - "[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:" - "[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:" + SSL_SELECT("[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:", "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:") + SSL_SELECT("[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:", "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:") "ECDHE-ECDSA-AES256-GCM-SHA384:" "ECDHE-RSA-AES256-GCM-SHA384:"; @@ -101,10 +105,11 @@ const std::string ServerContextConfigImpl::DEFAULT_CIPHER_SUITES_FIPS = "ECDHE-ECDSA-AES256-GCM-SHA384:" "ECDHE-RSA-AES256-GCM-SHA384:"; -const std::string ServerContextConfigImpl::DEFAULT_CURVES = "X25519:" - "P-256"; +const std::string ServerContextConfigImpl::DEFAULT_CURVES = + "X25519:P-256"; -const std::string ServerContextConfigImpl::DEFAULT_CURVES_FIPS = "P-256"; +const std::string ServerContextConfigImpl::DEFAULT_CURVES_FIPS = + "P-256" ; absl::StatusOr> ServerContextConfigImpl::create( const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config, diff --git a/source/common/tls/ssl_handshaker.cc b/source/common/tls/ssl_handshaker.cc index 145c595f7ed..27b7ab77397 100644 --- a/source/common/tls/ssl_handshaker.cc +++ b/source/common/tls/ssl_handshaker.cc @@ -154,11 +154,13 @@ Network::PostIoAction SslHandshakerImpl::doHandshake() { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: return PostIoAction::KeepOpen; +#ifndef ENVOY_SSL_OPENSSL case SSL_ERROR_PENDING_CERTIFICATE: case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION: case SSL_ERROR_WANT_CERTIFICATE_VERIFY: state_ = Ssl::SocketState::HandshakeInProgress; return PostIoAction::KeepOpen; +#endif default: handshake_callbacks_->onFailure(); return PostIoAction::Close; diff --git a/source/common/tls/ssl_socket.cc b/source/common/tls/ssl_socket.cc index ac702074413..d0bcbd87c19 100644 --- a/source/common/tls/ssl_socket.cc +++ b/source/common/tls/ssl_socket.cc @@ -146,6 +146,17 @@ Network::IoResult SslSocket::doRead(Buffer::Instance& read_buffer) { break; } FALLTHRU; +#ifdef ENVOY_SSL_OPENSSL + case SSL_ERROR_SSL: + // If EAGAIN treat it as if it's SSL_ERROR_WANT_READ + // OpenSSL may return SSL_ERROR_SSL with errno=EAGAIN in some cases + if (errno == EAGAIN) { + ENVOY_CONN_LOG(debug, "errno:{}:{}", callbacks_->connection(), errno, + Envoy::errorDetails(errno)); + break; + } + FALLTHRU; +#endif case SSL_ERROR_WANT_WRITE: // Renegotiation has started. We don't handle renegotiation so just fall through. default: @@ -316,6 +327,18 @@ Network::IoResult SslSocket::doWrite(Buffer::Instance& write_buffer, bool end_st case SSL_ERROR_WANT_WRITE: bytes_to_retry_ = bytes_to_write; break; +#ifdef ENVOY_SSL_OPENSSL + case SSL_ERROR_SSL: + // If EAGAIN treat it as if it's SSL_ERROR_WANT_WRITE + // OpenSSL may return SSL_ERROR_SSL with errno=EAGAIN in some cases + if (errno == EAGAIN) { + ENVOY_CONN_LOG(debug, "errno:{}:{}", callbacks_->connection(), errno, + Envoy::errorDetails(errno)); + bytes_to_retry_ = bytes_to_write; + break; + } + FALLTHRU; +#endif case SSL_ERROR_WANT_READ: // Renegotiation has started. We don't handle renegotiation so just fall through. default: diff --git a/source/common/version/BUILD b/source/common/version/BUILD index da39bf367b3..a5972c8d19b 100644 --- a/source/common/version/BUILD +++ b/source/common/version/BUILD @@ -3,7 +3,11 @@ load( "envoy_basic_cc_library", "envoy_cc_library", "envoy_package", +) +load( + "//bazel:envoy_select.bzl", "envoy_select_boringssl", + "envoy_select_ssl", ) licenses(["notice"]) # Apache 2 @@ -63,9 +67,9 @@ envoy_cc_library( envoy_cc_library( name = "version_lib", srcs = ["version.cc"], - copts = envoy_select_boringssl( - ["-DENVOY_SSL_VERSION=\\\"BoringSSL-FIPS\\\""], - ["-DENVOY_SSL_VERSION=\\\"BoringSSL\\\""], + copts = envoy_select_ssl( + if_openssl = ["-DENVOY_SSL_VERSION=\\\"OpenSSL\\\""], + if_boringssl = ["-DENVOY_SSL_VERSION=\\\"BoringSSL\\\""], ), external_deps = ["ssl"], tags = ["notidy"], diff --git a/source/common/version/version.cc b/source/common/version/version.cc index cf671be1899..a9825f18cc4 100644 --- a/source/common/version/version.cc +++ b/source/common/version/version.cc @@ -37,7 +37,14 @@ const envoy::config::core::v3::BuildVersion& VersionInfo::buildVersion() { return *result; } -bool VersionInfo::sslFipsCompliant() { return FIPS_mode() == 1; } +bool VersionInfo::sslFipsCompliant() { +#ifdef ENVOY_SSL_FIPS + RELEASE_ASSERT(FIPS_mode() == 1, "FIPS mode must be enabled in Envoy FIPS configuration."); + return true; +#else + return false; +#endif +} const std::string& VersionInfo::buildType() { #ifdef NDEBUG diff --git a/source/extensions/filters/common/lua/BUILD b/source/extensions/filters/common/lua/BUILD index f248bb0996f..3b359df83b4 100644 --- a/source/extensions/filters/common/lua/BUILD +++ b/source/extensions/filters/common/lua/BUILD @@ -4,23 +4,40 @@ load( "envoy_extension_package", ) +load("//bazel:envoy_internal.bzl", "envoy_external_dep_path") +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + licenses(["notice"]) # Apache 2 envoy_extension_package() +bool_flag( + name = "luajit2", + build_setting_default = False, +) + +config_setting( + name = "with_luajit2", + flag_values = { + ":luajit2": "True", + }, +) + envoy_cc_library( name = "lua_lib", srcs = ["lua.cc"], hdrs = ["lua.h"], deps = [ - "//bazel/foreign_cc:luajit", "//envoy/thread_local:thread_local_interface", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/common/common:lock_guard_lib", "//source/common/common:thread_lib", "//source/common/protobuf", - ], + ] + select({ + ":with_luajit2": ["//bazel/foreign_cc:luajit2"], + "//conditions:default": ["//bazel/foreign_cc:luajit"], + }), ) envoy_cc_library( @@ -41,10 +58,12 @@ envoy_cc_library( hdrs = ["protobuf_converter.h"], deps = [ ":lua_lib", - "//bazel/foreign_cc:luajit", "//source/common/protobuf", "//source/common/protobuf:create_reflectable_message_lib", "//source/common/protobuf:utility_lib", "@com_google_absl//absl/strings", - ], + ] + select({ + ":with_luajit2": ["//bazel/foreign_cc:luajit2"], + "//conditions:default": ["//bazel/foreign_cc:luajit"], + }), ) diff --git a/source/extensions/filters/listener/tls_inspector/tls_inspector.cc b/source/extensions/filters/listener/tls_inspector/tls_inspector.cc index 291efb7844e..d248e51bb5e 100644 --- a/source/extensions/filters/listener/tls_inspector/tls_inspector.cc +++ b/source/extensions/filters/listener/tls_inspector/tls_inspector.cc @@ -97,7 +97,7 @@ Config::Config( // Return an error to stop the handshake; we have what we wanted already. *out_alert = SSL_AD_USER_CANCELLED; - return SSL_TLSEXT_ERR_ALERT_FATAL; + return SSL_TLSEXT_ERR_OK; }); } diff --git a/source/extensions/geoip_providers/maxmind/BUILD b/source/extensions/geoip_providers/maxmind/BUILD index 016d6ebad64..85154d20a5f 100644 --- a/source/extensions/geoip_providers/maxmind/BUILD +++ b/source/extensions/geoip_providers/maxmind/BUILD @@ -41,7 +41,7 @@ envoy_cc_library( hdrs = ["geoip_provider.h"], tags = ["skip_on_windows"], deps = [ - "//bazel/foreign_cc:maxmind_linux_darwin", + "//bazel/foreign_cc:maxmind_linux", "//envoy/geoip:geoip_provider_driver_interface", "//source/common/common:thread_synchronizer_lib", "@envoy_api//envoy/extensions/geoip_providers/maxmind/v3:pkg_cc_proto", diff --git a/test/common/network/BUILD b/test/common/network/BUILD index a0baf262e8b..a35c91afc4e 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -118,6 +118,7 @@ envoy_cc_test( "//test/test_common:test_runtime_lib", "//test/test_common:test_time_lib", "//test/test_common:threadsafe_singleton_injector_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index a207140304c..dab5c7fb542 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -39,6 +39,7 @@ #include "test/test_common/test_runtime.h" #include "test/test_common/threadsafe_singleton_injector.h" #include "test/test_common/utility.h" +#include "source/common/ssl/ssl.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -4377,7 +4378,24 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ReadBufferLimitTest, TEST_P(ReadBufferLimitTest, NoLimit) { readBufferLimitTest(0, 256 * 1024); } -TEST_P(ReadBufferLimitTest, SomeLimit) { +// OpenSSL: This test is disabled because it makes an incorrect assumption about +// what happens when a partial read occurs, followed by additional reads. +// +// The calculation of expected_chunk_size assumes that the empty space in the +// buffer, left over from the first partial read, remains empty after the +// second read (this is what the -1 is meant to account for). However, in +// reality, the second read will fill that unused space in addition to the +// extra slice that is allocated. Therefore, the calculation of +// expected_chunk_size should be the read_buffer_limit + slice size. +// +// This test should be modified so that the partial read _always_ happens +// determinitically, rather than depending on the buffering/scheduling in the +// network stack. +// +// These fixes will be done upstream on main branch, backported to 1.34, and +// eventually sync'd back here, into envoy-openssl. +// +BORINGSSL_TEST_P(ReadBufferLimitTest, SomeLimit) { const uint32_t read_buffer_limit = 32 * 1024; // Envoy has soft limits, so as long as the first read is < read_buffer_limit it will do a second // read, before presenting the data to the ReadFilter. This additional read may include allocating diff --git a/test/common/tls/BUILD b/test/common/tls/BUILD index bd5867e46ee..7ce383c6785 100644 --- a/test/common/tls/BUILD +++ b/test/common/tls/BUILD @@ -71,6 +71,7 @@ envoy_cc_test( "//test/test_common:simulated_time_system_lib", "//test/test_common:test_runtime_lib", "//test/test_common:utility_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", ], @@ -132,6 +133,7 @@ envoy_cc_test( "//test/test_common:simulated_time_system_lib", "//test/test_common:test_runtime_lib", "//test/test_common:utility_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", ], @@ -168,6 +170,7 @@ envoy_cc_test( "//test/test_common:environment_lib", "//test/test_common:simulated_time_system_lib", "//test/test_common:test_runtime_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/admin/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", diff --git a/test/common/tls/context_impl_test.cc b/test/common/tls/context_impl_test.cc index dcb677db1f3..bc0e53b64c6 100644 --- a/test/common/tls/context_impl_test.cc +++ b/test/common/tls/context_impl_test.cc @@ -32,6 +32,7 @@ #include "test/test_common/simulated_time_system.h" #include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" +#include "source/common/ssl/ssl.h" #include "gtest/gtest.h" #include "openssl/crypto.h" @@ -81,7 +82,10 @@ INSTANTIATE_TEST_SUITE_P(CipherSuites, SslLibraryCipherSuiteSupport, // Tests for whether new cipher suites are added. When they are, they must be added to // knownCipherSuites() so that this test can detect if they are removed in the future. -TEST_F(SslLibraryCipherSuiteSupport, CipherSuitesNotAdded) { +// OpenSSL: Not sure how useful this test under OpenSSL is: cipher suites +// change from version to vertsion, and also depend on the system-wide config. +// This is going to be a test-fail-fest. Disabling for now. +BORINGSSL_TEST_F(SslLibraryCipherSuiteSupport, CipherSuitesNotAdded) { bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); EXPECT_NE(0, SSL_CTX_set_strict_cipher_list(ctx.get(), "ALL")); @@ -95,7 +99,8 @@ TEST_F(SslLibraryCipherSuiteSupport, CipherSuitesNotAdded) { // Test that no previously supported cipher suites were removed from the SSL library. If a cipher // suite is removed, it must be added to the release notes as an incompatible change, because it can // cause previously loadable configurations to no longer load if they reference the cipher suite. -TEST_P(SslLibraryCipherSuiteSupport, CipherSuitesNotRemoved) { +// OpenSSL: Disabled for the same reason as the CipherSuitesNotAdded test above. +BORINGSSL_TEST_P(SslLibraryCipherSuiteSupport, CipherSuitesNotRemoved) { bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); EXPECT_NE(0, SSL_CTX_set_strict_cipher_list(ctx.get(), GetParam().c_str())); } diff --git a/test/common/tls/handshaker_test.cc b/test/common/tls/handshaker_test.cc index 762bd336b68..6525439a19d 100644 --- a/test/common/tls/handshaker_test.cc +++ b/test/common/tls/handshaker_test.cc @@ -66,6 +66,17 @@ class HandshakerTest : public SslCertsTest { server_ssl_ = bssl::UniquePtr(SSL_new(server_ctx_.get())); SSL_set_accept_state(server_ssl_.get()); ASSERT_NE(key, nullptr); + + #ifdef ENVOY_SSL_OPENSSL + // In TLS1.3 OpenSSL server will send session ticket after an ssl handshake. + // While technically not part of the handshake, it's part of the server state-machine, + // and SSL_do_handshake will return errors (SSL_ERROR_WANT_WRITE) on the server-side if + // the session tickets (2 by default) have not been read by the client. + // To avoid this altogether, we disable session tickets by setting the number of tickets + // to generate for a new session to zero. + ossl_SSL_set_num_tickets(server_ssl_.get(), 0); // TODO: Could we hide this in SSL_CTX_new() ? + #endif + ASSERT_EQ(1, SSL_set_chain_and_key(server_ssl_.get(), chain.data(), chain.size(), key.get(), nullptr)); diff --git a/test/common/tls/integration/BUILD b/test/common/tls/integration/BUILD index 1fa8da34d26..5c8e450885b 100644 --- a/test/common/tls/integration/BUILD +++ b/test/common/tls/integration/BUILD @@ -52,6 +52,7 @@ envoy_cc_test( "//test/mocks/secret:secret_mocks", "//test/test_common:test_runtime_lib", "//test/test_common:utility_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", diff --git a/test/common/tls/integration/ssl_integration_test.cc b/test/common/tls/integration/ssl_integration_test.cc index 819b505ca00..ebe9dcc8368 100644 --- a/test/common/tls/integration/ssl_integration_test.cc +++ b/test/common/tls/integration/ssl_integration_test.cc @@ -27,6 +27,7 @@ #include "test/test_common/registry.h" #include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" +#include "source/common/ssl/ssl.h" #include "absl/strings/match.h" #include "absl/time/clock.h" @@ -55,7 +56,7 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, SslIntegrationTest, // Test that Envoy behaves correctly when receiving an SSLAlert for an unspecified code. The codes // are defined in the standard, and assigned codes have a string associated with them in BoringSSL, // which is included in logs. For an unknown code, verify that no crash occurs. -TEST_P(SslIntegrationTest, UnknownSslAlert) { +BORINGSSL_TEST_P(SslIntegrationTest, UnknownSslAlert) { initialize(); Network::ClientConnectionPtr connection = makeSslClientConnection({}); ConnectionStatusCallbacks callbacks; @@ -386,7 +387,8 @@ TEST_P(SslIntegrationTest, LogPeerIpSanUnsupportedIpVersion) { EXPECT_EQ(result, "1.2.3.4,0:1:2:3::4"); } -TEST_P(SslIntegrationTest, AsyncCertValidationSucceeds) { +// This test is disabled because it uses the timed_cert_validator which we don't support. +BORINGSSL_TEST_P(SslIntegrationTest, AsyncCertValidationSucceeds) { // Config client to use an async cert validator which defer the actual validation by 5ms. auto custom_validator_config = std::make_unique( envoy::config::core::v3::TypedExtensionConfig()); @@ -416,7 +418,8 @@ name: "envoy.tls.cert_validator.timed_cert_validator" connection->close(Network::ConnectionCloseType::NoFlush); } -TEST_P(SslIntegrationTest, AsyncCertValidationSucceedsWithLocalAddress) { +// This test is disabled because it uses the timed_cert_validator which we don't support. +BORINGSSL_TEST_P(SslIntegrationTest, AsyncCertValidationSucceedsWithLocalAddress) { auto custom_validator_config = std::make_unique( envoy::config::core::v3::TypedExtensionConfig()); TestUtility::loadFromYaml(TestEnvironment::substitute(R"EOF( @@ -469,7 +472,8 @@ name: "envoy.tls.cert_validator.timed_cert_validator" connection->close(Network::ConnectionCloseType::NoFlush); } -TEST_P(SslIntegrationTest, AsyncCertValidationAfterTearDown) { +// This test is disabled because it uses the timed_cert_validator which we don't support. +BORINGSSL_TEST_P(SslIntegrationTest, AsyncCertValidationAfterTearDown) { auto custom_validator_config = std::make_unique( envoy::config::core::v3::TypedExtensionConfig()); TestUtility::loadFromYaml(TestEnvironment::substitute(R"EOF( @@ -518,7 +522,8 @@ name: "envoy.tls.cert_validator.timed_cert_validator" } } -TEST_P(SslIntegrationTest, AsyncCertValidationAfterSslShutdown) { +// This test is disabled because it uses the timed_cert_validator which we don't support. +BORINGSSL_TEST_P(SslIntegrationTest, AsyncCertValidationAfterSslShutdown) { auto custom_validator_config = std::make_unique( envoy::config::core::v3::TypedExtensionConfig()); TestUtility::loadFromYaml(TestEnvironment::substitute(R"EOF( @@ -1317,7 +1322,7 @@ name: test-tls-context-provider EXPECT_EQ(test_server_->counter("aysnc_cert_selection.cert_selection_sync")->value(), 1); } -TEST_P(SslIntegrationTest, AsyncCertSelectorSucceeds) { +BORINGSSL_TEST_P(SslIntegrationTest, AsyncCertSelectorSucceeds) { tls_cert_selector_yaml_ = R"EOF( name: test-tls-context-provider typed_config: @@ -1335,7 +1340,7 @@ name: test-tls-context-provider 1); } -TEST_P(SslIntegrationTest, AsyncSleepCertSelectorSucceeds) { +BORINGSSL_TEST_P(SslIntegrationTest, AsyncSleepCertSelectorSucceeds) { tls_cert_selector_yaml_ = R"EOF( name: test-tls-context-provider typed_config: @@ -1353,7 +1358,7 @@ name: test-tls-context-provider 1); } -TEST_P(SslIntegrationTest, AsyncSleepCertSelectionAfterTearDown) { +BORINGSSL_TEST_P(SslIntegrationTest, AsyncSleepCertSelectionAfterTearDown) { tls_cert_selector_yaml_ = R"EOF( name: test-tls-context-provider typed_config: @@ -1384,7 +1389,7 @@ name: test-tls-context-provider TestUtility::DefaultTimeout, dispatcher_.get()); } -TEST_P(SslIntegrationTest, AsyncCertSelectionAfterSslShutdown) { +BORINGSSL_TEST_P(SslIntegrationTest, AsyncCertSelectionAfterSslShutdown) { tls_cert_selector_yaml_ = R"EOF( name: test-tls-context-provider typed_config: diff --git a/test/common/tls/io_handle_bio_test.cc b/test/common/tls/io_handle_bio_test.cc index f3734905191..c60e1721342 100644 --- a/test/common/tls/io_handle_bio_test.cc +++ b/test/common/tls/io_handle_bio_test.cc @@ -41,7 +41,11 @@ TEST_F(IoHandleBioTest, TestMiscApis) { int ret = BIO_reset(bio_); EXPECT_EQ(ret, 0); + #ifdef ENVOY_SSL_OPENSSL + ret = BIO_ctrl(bio_, BIO_CTRL_FLUSH, 0, nullptr); + #else ret = BIO_flush(bio_); + #endif EXPECT_EQ(ret, 1); } diff --git a/test/common/tls/ssl_socket_test.cc b/test/common/tls/ssl_socket_test.cc index f9a69cc9fdd..4d172e51e50 100644 --- a/test/common/tls/ssl_socket_test.cc +++ b/test/common/tls/ssl_socket_test.cc @@ -58,6 +58,7 @@ #include "test/test_common/registry.h" #include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" +#include "source/common/ssl/ssl.h" #include "absl/strings/str_replace.h" #include "absl/types/optional.h" @@ -66,6 +67,10 @@ #include "openssl/crypto.h" #include "openssl/ssl.h" +#ifdef ENVOY_SSL_OPENSSL +#include +#endif + using testing::_; using testing::ContainsRegex; using testing::DoAll; @@ -903,6 +908,11 @@ class TestUtilOptionsV2 : public TestUtilOptionsBase { TestUtilOptionsV2& setExpectedTransportFailureReasonContains( const std::string& expected_transport_failure_reason_contains) { expected_transport_failure_reason_contains_ = expected_transport_failure_reason_contains; +#ifdef ENVOY_SSL_OPENSSL + if (expected_transport_failure_reason_contains_ == "TLSV1.*_BAD_CERTIFICATE_HASH_VALUE") { + expected_transport_failure_reason_contains_ = "SSLV3_ALERT_HANDSHAKE_FAILURE"; + } +#endif return *this; } @@ -2135,7 +2145,7 @@ TEST_P(SslSocketTest, CertWithNotECCapable) { // TODO(luyao): We might need to modify ssl socket to set proper stats for failed handshake testUtil(test_options.setExpectedServerStats("") .setExpectedSni("server1.example.com") - .setExpectedTransportFailureReasonContains("HANDSHAKE_FAILURE_ON_CLIENT_HELLO")); + .setExpectedTransportFailureReasonContains(SSL_SELECT("HANDSHAKE_FAILURE_ON_CLIENT_HELLO", "SSLV3_ALERT_HANDSHAKE_FAILURE"))); } TEST_P(SslSocketTest, GetUriWithLocalUriSan) { @@ -2586,7 +2596,7 @@ TEST_P(SslSocketTest, FailedClientAuthCaVerification) { TestUtilOptions test_options(client_ctx_yaml, server_ctx_yaml, false, version_); testUtil(test_options.setExpectedServerStats("ssl.fail_verify_error") - .setExpectedVerifyErrorCode(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)); + .setExpectedVerifyErrorCode(SSL_SELECT(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT))); } TEST_P(SslSocketTest, FailedClientAuthSanVerificationNoClientCert) { @@ -3042,6 +3052,18 @@ TEST_P(SslSocketTest, CertificatesWithPassword) { } TEST_P(SslSocketTest, Pkcs12CertificatesWithPassword) { + #ifdef ENVOY_SSL_OPENSSL + // The password_protected_certkey.p12 used in this test, uses the "RC2-40-CBC" + // encryption algorithm, which OpenSSL considers legacy and insecure. + // Therefore, to get this test to pass, we need to temporarily load OpenSSL's + // legacy provider (as well as the default one) and also unload it when finished. + std::unique_ptr legacy_provider( + ossl_OSSL_PROVIDER_load(nullptr, "legacy"), + [](ossl_OSSL_PROVIDER *p){ ossl_OSSL_PROVIDER_unload(p); }); + std::unique_ptr default_provider( + ossl_OSSL_PROVIDER_load(nullptr, "default"), + [](ossl_OSSL_PROVIDER *p){ ossl_OSSL_PROVIDER_unload(p); }); + #endif envoy::config::listener::v3::Listener listener; envoy::config::listener::v3::FilterChain* filter_chain = listener.add_filter_chains(); envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext tls_context; @@ -5299,7 +5321,7 @@ TEST_P(SslSocketTest, SslError) { EXPECT_EQ(1UL, server_stats_store.counter("ssl.connection_error").value()); } -TEST_P(SslSocketTest, ProtocolVersions) { +BORINGSSL_TEST_P(SslSocketTest, ProtocolVersions) { envoy::config::listener::v3::Listener listener; envoy::config::listener::v3::FilterChain* filter_chain = listener.add_filter_chains(); envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext tls_context; @@ -6123,9 +6145,11 @@ TEST_P(SslSocketTest, RevokedIntermediateCertificate) { .setExpectedVerifyErrorCode(X509_V_ERR_CERT_REVOKED)); // Ensure that complete crl chains succeed with unrevoked certificates. + #ifndef ENVOY_SSL_OPENSSL TestUtilOptions complete_unrevoked_test_options(unrevoked_client_ctx_yaml, complete_server_ctx_yaml, true, version_); testUtil(complete_unrevoked_test_options.setExpectedSerialNumber(TEST_SAN_DNS4_CERT_SERIAL)); + #endif } TEST_P(SslSocketTest, RevokedIntermediateCertificateCRLInTrustedCA) { @@ -6209,9 +6233,11 @@ TEST_P(SslSocketTest, RevokedIntermediateCertificateCRLInTrustedCA) { .setExpectedVerifyErrorCode(X509_V_ERR_CERT_REVOKED)); // Ensure that complete crl chains succeed with unrevoked certificates. + #ifndef ENVOY_SSL_OPENSSL TestUtilOptions complete_unrevoked_test_options(unrevoked_client_ctx_yaml, complete_server_ctx_yaml, true, version_); testUtil(complete_unrevoked_test_options.setExpectedSerialNumber(TEST_SAN_DNS4_CERT_SERIAL)); + #endif } TEST_P(SslSocketTest, NotRevokedLeafCertificateOnlyLeafCRLValidation) { @@ -6842,7 +6868,7 @@ TEST_P(SslReadBufferLimitTest, SmallReadsIntoSameSlice) { } // Test asynchronous signing (ECDHE) using a private key provider. -TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignSuccess) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignSuccess) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -6876,7 +6902,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignSuccess) { } // Test asynchronous decryption (RSA). -TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncDecryptSuccess) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncDecryptSuccess) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_params: @@ -6913,7 +6939,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncDecryptSuccess) { } // Test synchronous signing (ECDHE). -TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncSignSuccess) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncSignSuccess) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -6947,7 +6973,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncSignSuccess) { } // Test synchronous decryption (RSA). -TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncDecryptSuccess) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncDecryptSuccess) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_params: @@ -6984,7 +7010,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncDecryptSuccess) { } // Test fallback for key provider. -TEST_P(SslSocketTest, RsaPrivateKeyProviderFallbackSuccess) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderFallbackSuccess) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_params: @@ -7025,7 +7051,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderFallbackSuccess) { } // Test asynchronous signing (ECDHE) failure (invalid signature). -TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignFailure) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignFailure) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -7060,7 +7086,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignFailure) { } // Test synchronous signing (ECDHE) failure (invalid signature). -TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncSignFailure) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncSignFailure) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -7095,7 +7121,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderSyncSignFailure) { } // Test the sign operation return with an error. -TEST_P(SslSocketTest, RsaPrivateKeyProviderSignFailure) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderSignFailure) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -7129,7 +7155,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderSignFailure) { } // Test the decrypt operation return with an error. -TEST_P(SslSocketTest, RsaPrivateKeyProviderDecryptFailure) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderDecryptFailure) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_params: @@ -7166,7 +7192,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderDecryptFailure) { } // Test the sign operation return with an error in complete. -TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignCompleteFailure) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignCompleteFailure) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -7201,7 +7227,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncSignCompleteFailure) { } // Test the decrypt operation return with an error in complete. -TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncDecryptCompleteFailure) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncDecryptCompleteFailure) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_params: @@ -7242,7 +7268,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderAsyncDecryptCompleteFailure) { // Test having one cert with private key method and another with just // private key. -TEST_P(SslSocketTest, RsaPrivateKeyProviderMultiCertSuccess) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderMultiCertSuccess) { const std::string client_ctx_yaml = absl::StrCat(R"EOF( common_tls_context: tls_params: @@ -7282,7 +7308,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderMultiCertSuccess) { // Test having two certs with private key methods. This will // synchronously fail because the second certificate is a ECDSA one and // the RSA method can't handle it. -TEST_P(SslSocketTest, RsaPrivateKeyProviderMultiCertFail) { +BORINGSSL_TEST_P(SslSocketTest, RsaPrivateKeyProviderMultiCertFail) { const std::string client_ctx_yaml = absl::StrCat(R"EOF( common_tls_context: tls_params: @@ -7328,7 +7354,7 @@ TEST_P(SslSocketTest, RsaPrivateKeyProviderMultiCertFail) { } // Test ECDSA private key method provider mode. -TEST_P(SslSocketTest, EcdsaPrivateKeyProviderSuccess) { +BORINGSSL_TEST_P(SslSocketTest, EcdsaPrivateKeyProviderSuccess) { const std::string client_ctx_yaml = absl::StrCat(R"EOF( common_tls_context: tls_params: @@ -7362,7 +7388,7 @@ TEST_P(SslSocketTest, EcdsaPrivateKeyProviderSuccess) { // Test having two certs with different private key method modes. It's expected that the ECDSA // provider mode is being used. RSA provider mode is set to fail with "async_method_error", but // that's not happening. -TEST_P(SslSocketTest, RsaAndEcdsaPrivateKeyProviderMultiCertSuccess) { +BORINGSSL_TEST_P(SslSocketTest, RsaAndEcdsaPrivateKeyProviderMultiCertSuccess) { const std::string client_ctx_yaml = absl::StrCat(R"EOF( common_tls_context: tls_params: @@ -7406,7 +7432,7 @@ TEST_P(SslSocketTest, RsaAndEcdsaPrivateKeyProviderMultiCertSuccess) { } // Test having two certs with different private key method modes. ECDSA provider is set to fail. -TEST_P(SslSocketTest, RsaAndEcdsaPrivateKeyProviderMultiCertFail) { +BORINGSSL_TEST_P(SslSocketTest, RsaAndEcdsaPrivateKeyProviderMultiCertFail) { const std::string client_ctx_yaml = absl::StrCat(R"EOF( common_tls_context: tls_params: @@ -7452,7 +7478,7 @@ TEST_P(SslSocketTest, RsaAndEcdsaPrivateKeyProviderMultiCertFail) { } // Test private key provider and cert validation can work together. -TEST_P(SslSocketTest, PrivateKeyProviderWithCertValidation) { +BORINGSSL_TEST_P(SslSocketTest, PrivateKeyProviderWithCertValidation) { const std::string client_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -7774,7 +7800,7 @@ TEST_P(SslSocketTest, Sni) { testUtil(test_options.setExpectedSni("foo.bar.com")); } -TEST_P(SslSocketTest, AsyncCustomCertValidatorSucceeds) { +BORINGSSL_TEST_P(SslSocketTest, AsyncCustomCertValidatorSucceeds) { const std::string client_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -7817,7 +7843,7 @@ TEST_P(SslSocketTest, AsyncCustomCertValidatorSucceeds) { .setExpectedSerialNumber(TEST_NO_SAN_CERT_SERIAL)); } -TEST_P(SslSocketTest, AsyncCustomCertValidatorFails) { +BORINGSSL_TEST_P(SslSocketTest, AsyncCustomCertValidatorFails) { const std::string server_ctx_yaml = R"EOF( common_tls_context: tls_certificates: @@ -7855,7 +7881,7 @@ TEST_P(SslSocketTest, AsyncCustomCertValidatorFails) { .setExpectedVerifyErrorCode(X509_V_ERR_CERT_REVOKED)); } -TEST_P(SslSocketTest, RsaKeyUsageVerificationEnforcementOff) { +BORINGSSL_TEST_P(SslSocketTest, RsaKeyUsageVerificationEnforcementOff) { envoy::config::listener::v3::Listener listener; envoy::config::listener::v3::FilterChain* filter_chain = listener.add_filter_chains(); envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext server_tls_context; @@ -7885,7 +7911,7 @@ TEST_P(SslSocketTest, RsaKeyUsageVerificationEnforcementOff) { testUtilV2(test_options); } -TEST_P(SslSocketTest, RsaKeyUsageVerificationEnforcementOn) { +BORINGSSL_TEST_P(SslSocketTest, RsaKeyUsageVerificationEnforcementOn) { envoy::config::listener::v3::Listener listener; envoy::config::listener::v3::FilterChain* filter_chain = listener.add_filter_chains(); envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext server_tls_context; diff --git a/test/common/tls/tls_certificate_selector_test.cc b/test/common/tls/tls_certificate_selector_test.cc index a3caf5b2b73..4c39f770d54 100644 --- a/test/common/tls/tls_certificate_selector_test.cc +++ b/test/common/tls/tls_certificate_selector_test.cc @@ -57,6 +57,7 @@ #include "test/test_common/registry.h" #include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" +#include "source/common/ssl/ssl.h" #include "absl/strings/str_replace.h" #include "absl/types/optional.h" @@ -354,7 +355,7 @@ TEST_P(TlsCertificateSelectorFactoryTest, Failed) { testUtil(Ssl::SelectionResult::SelectionStatus::Failed); } -TEST_P(TlsCertificateSelectorFactoryTest, Pending) { +BORINGSSL_TEST_P(TlsCertificateSelectorFactoryTest, Pending) { testUtil(Ssl::SelectionResult::SelectionStatus::Pending); } diff --git a/test/common/tls/utility_test.cc b/test/common/tls/utility_test.cc index 1738acb2671..61cf8eb4b2b 100644 --- a/test/common/tls/utility_test.cc +++ b/test/common/tls/utility_test.cc @@ -300,7 +300,9 @@ TEST(UtilityTest, SslErrorDescriptionTest) { {SSL_ERROR_SSL, "SSL"}, {SSL_ERROR_WANT_READ, "WANT_READ"}, {SSL_ERROR_WANT_WRITE, "WANT_WRITE"}, +#ifdef SSL_ERROR_WANT_PRIVATE_KEY_OPERATION {SSL_ERROR_WANT_PRIVATE_KEY_OPERATION, "WANT_PRIVATE_KEY_OPERATION"}, +#endif }; for (const auto& test_data : test_set) { diff --git a/test/extensions/access_loggers/grpc/BUILD b/test/extensions/access_loggers/grpc/BUILD index 84d573adc9d..6db5ebe6ebc 100644 --- a/test/extensions/access_loggers/grpc/BUILD +++ b/test/extensions/access_loggers/grpc/BUILD @@ -150,6 +150,7 @@ envoy_extension_cc_test( "//test/common/grpc:grpc_client_integration_lib", "//test/integration:http_integration_lib", "//test/test_common:utility_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/access_loggers/grpc/v3:pkg_cc_proto", diff --git a/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc b/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc index 0bcd6abbaef..29e6f59587d 100644 --- a/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc +++ b/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc @@ -20,6 +20,7 @@ #include "test/integration/http_integration.h" #include "test/integration/ssl_utility.h" #include "test/test_common/utility.h" +#include "source/common/ssl/ssl.h" #if defined(USE_CEL) #include "source/extensions/filters/network/rbac/config.h" @@ -606,7 +607,7 @@ TEST_P(TcpGrpcAccessLogIntegrationTest, SslTerminatedWithJA3) { tls_cipher_suite: value: 49199 tls_sni_hostname: sni - ja3_fingerprint: "ecaf91d232e224038f510cb81aa08b94" + ja3_fingerprint: "{}" local_certificate_properties: subject_alt_name: uri: "spiffe://lyft.com/backend-team" @@ -628,6 +629,7 @@ TEST_P(TcpGrpcAccessLogIntegrationTest, SslTerminatedWithJA3) { )EOF", Network::Test::getLoopbackAddressString(ipVersion()), Network::Test::getLoopbackAddressString(ipVersion()), + SSL_SELECT("ecaf91d232e224038f510cb81aa08b94", "f34cc73a821433e5f56e38868737a636"), Network::Test::getLoopbackAddressString(ipVersion())))); cleanup(); @@ -677,12 +679,14 @@ TEST_P(TcpGrpcAccessLogIntegrationTest, SslNotTerminated) { tls_properties: tls_sni_hostname: sni connection_properties: - received_bytes: 138 - sent_bytes: 138 + received_bytes: {} + sent_bytes: {} )EOF", Network::Test::getLoopbackAddressString(ipVersion()), Network::Test::getLoopbackAddressString(ipVersion()), - Network::Test::getLoopbackAddressString(ipVersion())))); + Network::Test::getLoopbackAddressString(ipVersion()), + SSL_SELECT(138, 163), + SSL_SELECT(138, 163)))); cleanup(); } @@ -730,14 +734,17 @@ TEST_P(TcpGrpcAccessLogIntegrationTest, SslNotTerminatedWithJA3) { address: {} tls_properties: tls_sni_hostname: sni - ja3_fingerprint: "ecaf91d232e224038f510cb81aa08b94" + ja3_fingerprint: "{}" connection_properties: - received_bytes: 138 - sent_bytes: 138 + received_bytes: {} + sent_bytes: {} )EOF", Network::Test::getLoopbackAddressString(ipVersion()), Network::Test::getLoopbackAddressString(ipVersion()), - Network::Test::getLoopbackAddressString(ipVersion())))); + Network::Test::getLoopbackAddressString(ipVersion()), + SSL_SELECT("ecaf91d232e224038f510cb81aa08b94", "f34cc73a821433e5f56e38868737a636"), + SSL_SELECT(138, 163), + SSL_SELECT(138, 163)))); cleanup(); } @@ -783,14 +790,17 @@ TEST_P(TcpGrpcAccessLogIntegrationTest, SslNotTerminatedWithJA3NoSNI) { socket_address: address: {} tls_properties: - ja3_fingerprint: "71d1f47d1125ac53c3c6a4863c087cfe" + ja3_fingerprint: "{}" connection_properties: - received_bytes: 126 - sent_bytes: 126 + received_bytes: {} + sent_bytes: {} )EOF", Network::Test::getLoopbackAddressString(ipVersion()), Network::Test::getLoopbackAddressString(ipVersion()), - Network::Test::getLoopbackAddressString(ipVersion())))); + Network::Test::getLoopbackAddressString(ipVersion()), + SSL_SELECT("71d1f47d1125ac53c3c6a4863c087cfe", "54619c7296adab310ed514d06812d95f"), + SSL_SELECT(126, 151), + SSL_SELECT(126, 151)))); cleanup(); } @@ -805,6 +815,13 @@ TEST_P(TcpGrpcAccessLogIntegrationTest, TlsHandshakeFailure_VerifyFailed) { setupTlsInspectorFilter(server_options); initialize(); + const auto peer_certificate_properties = SSL_SELECT(R"EOF( + subject_alt_name: + - uri: "spiffe://lyft.com/frontend-team" + subject: "emailAddress=frontend-team@lyft.com,CN=Test Frontend Team,OU=Lyft Engineering,O=Lyft,L=San Francisco,ST=California,C=US" + issuer: "CN=Test CA,OU=Lyft Engineering,O=Lyft,L=San Francisco,ST=California,C=US" +)EOF", + "{}"); Ssl::ClientSslTransportOptions ssl_options; ssl_options.setClientEcdsaCert(false); ssl_options.setCipherSuites({"ECDHE-RSA-AES128-GCM-SHA256"}); @@ -841,23 +858,21 @@ TEST_P(TcpGrpcAccessLogIntegrationTest, TlsHandshakeFailure_VerifyFailed) { tls_properties: tls_version: TLSv1_2 tls_cipher_suite: - value: 49199 + value: {1} local_certificate_properties: subject_alt_name: - uri: "spiffe://lyft.com/backend-team" subject: "emailAddress=backend-team@lyft.com,CN=Test Backend Team,OU=Lyft Engineering,O=Lyft,L=San Francisco,ST=California,C=US" - peer_certificate_properties: - subject_alt_name: - - uri: "spiffe://lyft.com/frontend-team" - subject: "emailAddress=frontend-team@lyft.com,CN=Test Frontend Team,OU=Lyft Engineering,O=Lyft,L=San Francisco,ST=California,C=US" - issuer: "CN=Test CA,OU=Lyft Engineering,O=Lyft,L=San Francisco,ST=California,C=US" + peer_certificate_properties: {2} upstream_remote_address: socket_address: {{}} upstream_local_address: socket_address: {{}} connection_properties: {{}} )EOF", - Network::Test::getLoopbackAddressString(ipVersion())))); + Network::Test::getLoopbackAddressString(ipVersion()), + SSL_SELECT(49199, 65535), + peer_certificate_properties))); cleanup(); } diff --git a/test/extensions/filters/listener/tls_inspector/BUILD b/test/extensions/filters/listener/tls_inspector/BUILD index b8e639653b8..e4a58aea429 100644 --- a/test/extensions/filters/listener/tls_inspector/BUILD +++ b/test/extensions/filters/listener/tls_inspector/BUILD @@ -43,6 +43,7 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/mocks/stats:stats_mocks", "//test/test_common:threadsafe_singleton_injector_lib", + "//source/common/ssl:ssl_lib", ], ) @@ -62,6 +63,7 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/mocks/stats:stats_mocks", "//test/test_common:threadsafe_singleton_injector_lib", + "//source/common/ssl:ssl_lib", ], ) @@ -147,6 +149,7 @@ envoy_cc_test( "//test/mocks/runtime:runtime_mocks", "//test/mocks/secret:secret_mocks", "//test/test_common:utility_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", diff --git a/test/extensions/filters/listener/tls_inspector/tls_inspector_integration_test.cc b/test/extensions/filters/listener/tls_inspector/tls_inspector_integration_test.cc index f846b5378ce..df07d024ec2 100644 --- a/test/extensions/filters/listener/tls_inspector/tls_inspector_integration_test.cc +++ b/test/extensions/filters/listener/tls_inspector/tls_inspector_integration_test.cc @@ -16,6 +16,7 @@ #include "test/integration/ssl_utility.h" #include "test/integration/utility.h" #include "test/mocks/secret/mocks.h" +#include "source/common/ssl/ssl.h" #include "gtest/gtest.h" @@ -24,7 +25,7 @@ namespace { class LargeBufferListenerFilter : public Network::ListenerFilter { public: - static constexpr int BUFFER_SIZE = 512; + static constexpr int BUFFER_SIZE = SSL_SELECT(512, 256); // Network::ListenerFilter Network::FilterStatus onAccept(Network::ListenerFilterCallbacks&) override { ENVOY_LOG_MISC(debug, "LargeBufferListenerFilter::onAccept"); @@ -294,9 +295,10 @@ TEST_P(TlsInspectorIntegrationTest, TlsInspectorMetadataPopulatedInAccessLog) { TEST_P(TlsInspectorIntegrationTest, JA3FingerprintIsSet) { // These TLS options will create a client hello message with // `JA3` fingerprint: - // `771,49199,23-65281-10-11-35-16-13,23,0` + // `771,49199-255,11-10-35-16-22-23-13,23,0-1-2` // MD5 hash: - // `71d1f47d1125ac53c3c6a4863c087cfe` + // `71d1f47d1125ac53c3c6a4863c087cfe` (BoringSSL) + // `54619c7296adab310ed514d06812d95f` (OpenSSL) Ssl::ClientSslTransportOptions ssl_options; ssl_options.setCipherSuites({"ECDHE-RSA-AES128-GCM-SHA256"}); ssl_options.setTlsVersion(envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_2); @@ -307,7 +309,7 @@ TEST_P(TlsInspectorIntegrationTest, JA3FingerprintIsSet) { client_->close(Network::ConnectionCloseType::NoFlush); EXPECT_THAT(waitForAccessLog(listener_access_log_name_), - testing::Eq("71d1f47d1125ac53c3c6a4863c087cfe")); + testing::Eq(SSL_SELECT("71d1f47d1125ac53c3c6a4863c087cfe", "54619c7296adab310ed514d06812d95f"))); test_server_->waitUntilHistogramHasSamples("tls_inspector.bytes_processed"); auto bytes_processed_histogram = test_server_->histogram("tls_inspector.bytes_processed"); @@ -316,14 +318,15 @@ TEST_P(TlsInspectorIntegrationTest, JA3FingerprintIsSet) { 1); EXPECT_EQ(static_cast(TestUtility::readSampleSum(test_server_->server().dispatcher(), *bytes_processed_histogram)), - 115); + SSL_SELECT(115, 145)); } // The `JA4` fingerprint is correct in the access log. TEST_P(TlsInspectorIntegrationTest, JA4FingerprintIsSet) { // These TLS options will create a client hello message with // `JA4` fingerprint: - // `t12i0107en_f06271c2b022_0f3b2bcde21d` + // `t12i0107en_f06271c2b022_0f3b2bcde21d` (BoringSSL) + // `t12i0207en_b06afd972a5c_e7e480e5a997` (OpenSSL) Ssl::ClientSslTransportOptions ssl_options; ssl_options.setCipherSuites({"ECDHE-RSA-AES128-GCM-SHA256"}); ssl_options.setTlsVersion(envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_2); @@ -334,7 +337,7 @@ TEST_P(TlsInspectorIntegrationTest, JA4FingerprintIsSet) { client_->close(Network::ConnectionCloseType::NoFlush); EXPECT_THAT(waitForAccessLog(listener_access_log_name_), - testing::Eq("t12i0107en_f06271c2b022_0f3b2bcde21d")); + testing::Eq(SSL_SELECT("t12i0107en_f06271c2b022_0f3b2bcde21d", "t12i0207en_b06afd972a5c_e7e480e5a997"))); test_server_->waitUntilHistogramHasSamples("tls_inspector.bytes_processed"); auto bytes_processed_histogram = test_server_->histogram("tls_inspector.bytes_processed"); @@ -343,7 +346,7 @@ TEST_P(TlsInspectorIntegrationTest, JA4FingerprintIsSet) { 1); EXPECT_EQ(static_cast(TestUtility::readSampleSum(test_server_->server().dispatcher(), *bytes_processed_histogram)), - 115); + SSL_SELECT(115, 145)); } TEST_P(TlsInspectorIntegrationTest, RequestedBufferSizeCanGrow) { @@ -389,7 +392,7 @@ TEST_P(TlsInspectorIntegrationTest, RequestedBufferSizeCanGrow) { 1); EXPECT_EQ(static_cast(TestUtility::readSampleSum(test_server_->server().dispatcher(), *bytes_processed_histogram)), - 515); + SSL_SELECT(515, 405)); } TEST_P(TlsInspectorIntegrationTest, RequestedBufferSizeCanStartBig) { @@ -427,7 +430,7 @@ TEST_P(TlsInspectorIntegrationTest, RequestedBufferSizeCanStartBig) { 1); auto bytes_processed = static_cast( TestUtility::readSampleSum(test_server_->server().dispatcher(), *bytes_processed_histogram)); - EXPECT_EQ(bytes_processed, 515); + EXPECT_EQ(bytes_processed, SSL_SELECT(515, 385)); // Double check that the test is effective by ensuring that the // LargeBufferListenerFilter::BUFFER_SIZE is smaller than the client hello. EXPECT_GT(bytes_processed, LargeBufferListenerFilter::BUFFER_SIZE); diff --git a/test/extensions/filters/listener/tls_inspector/tls_inspector_ja4_test.cc b/test/extensions/filters/listener/tls_inspector/tls_inspector_ja4_test.cc index 04964994438..efa837f1da1 100644 --- a/test/extensions/filters/listener/tls_inspector/tls_inspector_ja4_test.cc +++ b/test/extensions/filters/listener/tls_inspector/tls_inspector_ja4_test.cc @@ -8,6 +8,7 @@ #include "test/mocks/network/mocks.h" #include "test/mocks/stats/mocks.h" #include "test/test_common/threadsafe_singleton_injector.h" +#include "source/common/ssl/ssl.h" #include "gtest/gtest.h" @@ -50,7 +51,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // Browser Client Hello {"Browser-2", @@ -66,7 +67,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // Browser Client Hello {"Browser-3", @@ -82,7 +83,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // Chrome with `Cloudflare` QUIC {"Chrome-Cloudflare-QUIC", @@ -98,7 +99,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // HTTP2 with cookies {"HTTP2-with-cookies", @@ -114,7 +115,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // TLS SNI - Facebook {"TLS-SNI-Facebook", @@ -129,7 +130,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // Apple connection {"Apple-Connection", @@ -144,7 +145,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // Microsoft connection {"Microsoft-Connection", @@ -159,7 +160,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // Edge browser connection to Slack {"Edge-Slack-Connection", @@ -175,7 +176,7 @@ const std::vector> JA4_TEST_VE "eea50f122ddfd506694bb949d38dca486e39a0ef9331a6782bb8392a5bc7395189340732a15909e9c309fc4c7c0bd" "4102a78c99979e1eb8dcde030c469c38c3f79cee81c9da56db0ab4a3fe19d54da17bf67fc7efce7bb939a292e7c10" "82ac2880021201e639a41e760bacf644eeb7b751c0109159373ffdc666c640b661e2be906aa6c", - "t13d1516h2_8daaf6152771_9b887d9acb53"}, + SSL_SELECT("t13d1516h2_8daaf6152771_9b887d9acb53", "t13d1514h2_8daaf6152771_406260161a3b")}, // SSH {"SSH2-Example-1", @@ -228,7 +229,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000", - "t13d1516h2_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516h2_8daaf6152771_e5627efa2ab1", "t13d1514h2_8daaf6152771_827b515c4f52")}, // IPv6 {"IPv6", @@ -254,7 +255,7 @@ const std::vector> JA4_TEST_VE "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000", - "t13d1516baad_8daaf6152771_e5627efa2ab1"}, + SSL_SELECT("t13d1516baad_8daaf6152771_e5627efa2ab1", "t13d1514baad_8daaf6152771_827b515c4f52")}, }; class TlsInspectorJA4Test diff --git a/test/extensions/filters/listener/tls_inspector/tls_inspector_test.cc b/test/extensions/filters/listener/tls_inspector/tls_inspector_test.cc index 8c187d7e6b1..c7eccc76e41 100644 --- a/test/extensions/filters/listener/tls_inspector/tls_inspector_test.cc +++ b/test/extensions/filters/listener/tls_inspector/tls_inspector_test.cc @@ -10,6 +10,7 @@ #include "test/mocks/network/mocks.h" #include "test/mocks/stats/mocks.h" #include "test/test_common/threadsafe_singleton_injector.h" +#include "source/common/ssl/ssl.h" #include "absl/strings/str_format.h" #include "gtest/gtest.h" @@ -464,7 +465,7 @@ TEST_P(TlsInspectorTest, NotSsl) { ASSERT_EQ(1, bytes_processed.size()); EXPECT_EQ(5, bytes_processed[0]); EXPECT_EQ( - "TLS_error|error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER:TLS_error_end", + SSL_SELECT("TLS_error|error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER:TLS_error_end", "TLS_error|error:0A00010B:SSL routines::wrong version number:TLS_error_end"), cb_.streamInfo().downstreamTransportFailureReason()); } @@ -597,10 +598,10 @@ void TlsInspectorTest::testJA4(const std::string& expected_ja4, const std::strin } const absl::flat_hash_map basic_test_version_to_ja4_ = { - {TLS1_VERSION, "t10i040500_cefcabfea53d_950472255fe9"}, - {TLS1_1_VERSION, "t11i040500_cefcabfea53d_950472255fe9"}, - {TLS1_2_VERSION, "t12i100600_a8cf61a50a39_0f3b2bcde21d"}, - {TLS1_3_VERSION, "t13i030500_55b375c5d22e_678be4e4848e"}}; + {TLS1_VERSION, SSL_SELECT("t10i040500_cefcabfea53d_950472255fe9", "t10i130500_dcdf5333bb11_195413a0cc0f")}, + {TLS1_1_VERSION, SSL_SELECT("t11i040500_cefcabfea53d_950472255fe9", "t11i130500_dcdf5333bb11_195413a0cc0f")}, + {TLS1_2_VERSION, SSL_SELECT("t12i100600_a8cf61a50a39_0f3b2bcde21d", "t12i560600_e50dfccbdbbc_e7e480e5a997")}, + {TLS1_3_VERSION, SSL_SELECT("t13i030500_55b375c5d22e_678be4e4848e", "t13i040900_16476d049b0b_78f1d400d464")}}; TEST_P(TlsInspectorTest, JA4Basic) { const uint16_t min_version = std::get<0>(GetParam()); @@ -608,17 +609,17 @@ TEST_P(TlsInspectorTest, JA4Basic) { std::string expected_value = (min_version == Config::TLS_MIN_SUPPORTED_VERSION && max_version == Config::TLS_MAX_SUPPORTED_VERSION) - ? "t13i130900_f57a46bbacb6_78e6aca7449b" + ? SSL_SELECT("t13i130900_f57a46bbacb6_78e6aca7449b", "t13i590900_1fa906e7e9df_1f22a2ca17c4") : basic_test_version_to_ja4_.at(min_version); testJA4(expected_value); } const absl::flat_hash_map sni_test_version_to_ja4_ = { - {TLS1_VERSION, "t10d040600_cefcabfea53d_950472255fe9"}, - {TLS1_1_VERSION, "t11d040600_cefcabfea53d_950472255fe9"}, - {TLS1_2_VERSION, "t12d100700_a8cf61a50a39_0f3b2bcde21d"}, - {TLS1_3_VERSION, "t13d030600_55b375c5d22e_678be4e4848e"}}; + {TLS1_VERSION, SSL_SELECT("t10d040600_cefcabfea53d_950472255fe9", "t10d130600_dcdf5333bb11_195413a0cc0f")}, + {TLS1_1_VERSION, SSL_SELECT("t11d040600_cefcabfea53d_950472255fe9", "t11d130600_dcdf5333bb11_195413a0cc0f")}, + {TLS1_2_VERSION, SSL_SELECT("t12d100700_a8cf61a50a39_0f3b2bcde21d", "t12d560700_e50dfccbdbbc_e7e480e5a997")}, + {TLS1_3_VERSION, SSL_SELECT("t13d030600_55b375c5d22e_678be4e4848e", "t13d041000_16476d049b0b_78f1d400d464")}}; TEST_P(TlsInspectorTest, JA4WithSNI) { const uint16_t min_version = std::get<0>(GetParam()); @@ -626,17 +627,17 @@ TEST_P(TlsInspectorTest, JA4WithSNI) { std::string expected_value = (min_version == Config::TLS_MIN_SUPPORTED_VERSION && max_version == Config::TLS_MAX_SUPPORTED_VERSION) - ? "t13d131000_f57a46bbacb6_78e6aca7449b" + ? SSL_SELECT("t13d131000_f57a46bbacb6_78e6aca7449b", "t13d591000_1fa906e7e9df_1f22a2ca17c4") : sni_test_version_to_ja4_.at(min_version); testJA4(expected_value, "example.com"); } const absl::flat_hash_map alpn_test_version_to_ja4_ = { - {TLS1_VERSION, "t10i0406h2_cefcabfea53d_950472255fe9"}, - {TLS1_1_VERSION, "t11i0406h2_cefcabfea53d_950472255fe9"}, - {TLS1_2_VERSION, "t12i1007h2_a8cf61a50a39_0f3b2bcde21d"}, - {TLS1_3_VERSION, "t13i0306h2_55b375c5d22e_678be4e4848e"}}; + {TLS1_VERSION, SSL_SELECT("t10i0406h2_cefcabfea53d_950472255fe9", "t10i1306h2_dcdf5333bb11_195413a0cc0f")}, + {TLS1_1_VERSION, SSL_SELECT("t11i0406h2_cefcabfea53d_950472255fe9", "t11i1306h2_dcdf5333bb11_195413a0cc0f")}, + {TLS1_2_VERSION, SSL_SELECT("t12i1007h2_a8cf61a50a39_0f3b2bcde21d", "t12i5607h2_e50dfccbdbbc_e7e480e5a997")}, + {TLS1_3_VERSION, SSL_SELECT("t13i0306h2_55b375c5d22e_678be4e4848e", "t13i0410h2_16476d049b0b_78f1d400d464")}}; TEST_P(TlsInspectorTest, JA4WithALPN) { const uint16_t min_version = std::get<0>(GetParam()); @@ -644,17 +645,17 @@ TEST_P(TlsInspectorTest, JA4WithALPN) { std::string expected_value = (min_version == Config::TLS_MIN_SUPPORTED_VERSION && max_version == Config::TLS_MAX_SUPPORTED_VERSION) - ? "t13i1310h2_f57a46bbacb6_78e6aca7449b" + ? SSL_SELECT("t13i1310h2_f57a46bbacb6_78e6aca7449b", "t13i5910h2_1fa906e7e9df_1f22a2ca17c4") : alpn_test_version_to_ja4_.at(min_version); testJA4(expected_value, "", "\x02h2\x08http/1.1"); } const absl::flat_hash_map alpn_sni_test_version_to_ja4_ = { - {TLS1_VERSION, "t10d0407h2_cefcabfea53d_950472255fe9"}, - {TLS1_1_VERSION, "t11d0407h2_cefcabfea53d_950472255fe9"}, - {TLS1_2_VERSION, "t12d1008h2_a8cf61a50a39_0f3b2bcde21d"}, - {TLS1_3_VERSION, "t13d0307h2_55b375c5d22e_678be4e4848e"}}; + {TLS1_VERSION, SSL_SELECT("t10d0407h2_cefcabfea53d_950472255fe9", "t10d1307h2_dcdf5333bb11_195413a0cc0f")}, + {TLS1_1_VERSION, SSL_SELECT("t11d0407h2_cefcabfea53d_950472255fe9", "t11d1307h2_dcdf5333bb11_195413a0cc0f")}, + {TLS1_2_VERSION, SSL_SELECT("t12d1008h2_a8cf61a50a39_0f3b2bcde21d", "t12d5608h2_e50dfccbdbbc_e7e480e5a997")}, + {TLS1_3_VERSION, SSL_SELECT("t13d0307h2_55b375c5d22e_678be4e4848e", "t13d0411h2_16476d049b0b_78f1d400d464")}}; TEST_P(TlsInspectorTest, JA4WithSNIAndALPN) { const uint16_t min_version = std::get<0>(GetParam()); @@ -662,17 +663,17 @@ TEST_P(TlsInspectorTest, JA4WithSNIAndALPN) { std::string expected_value = (min_version == Config::TLS_MIN_SUPPORTED_VERSION && max_version == Config::TLS_MAX_SUPPORTED_VERSION) - ? "t13d1312h2_f57a46bbacb6_ef7df7f74e48" + ? SSL_SELECT("t13d1312h2_f57a46bbacb6_ef7df7f74e48", "t13d5911h2_1fa906e7e9df_1f22a2ca17c4") : alpn_sni_test_version_to_ja4_.at(min_version); testJA4(expected_value, "example.com", "\x02h2\x08http/1.1"); } const absl::flat_hash_map alpn_single_char_test_version_to_ja4_ = { - {TLS1_VERSION, "t10i0406hh_cefcabfea53d_950472255fe9"}, - {TLS1_1_VERSION, "t11i0406hh_cefcabfea53d_950472255fe9"}, - {TLS1_2_VERSION, "t12i1007hh_a8cf61a50a39_0f3b2bcde21d"}, - {TLS1_3_VERSION, "t13i0306hh_55b375c5d22e_678be4e4848e"}}; + {TLS1_VERSION, SSL_SELECT("t10i0406hh_cefcabfea53d_950472255fe9", "t10i1306hh_dcdf5333bb11_195413a0cc0f")}, + {TLS1_1_VERSION, SSL_SELECT("t11i0406hh_cefcabfea53d_950472255fe9", "t11i1306hh_dcdf5333bb11_195413a0cc0f")}, + {TLS1_2_VERSION, SSL_SELECT("t12i1007hh_a8cf61a50a39_0f3b2bcde21d", "t12i5607hh_e50dfccbdbbc_e7e480e5a997")}, + {TLS1_3_VERSION, SSL_SELECT("t13i0306hh_55b375c5d22e_678be4e4848e", "t13i0410hh_16476d049b0b_78f1d400d464")}}; TEST_P(TlsInspectorTest, JA4WithSingleCharacterALPN) { const uint16_t min_version = std::get<0>(GetParam()); @@ -685,17 +686,17 @@ TEST_P(TlsInspectorTest, JA4WithSingleCharacterALPN) { std::string expected_ja4 = (min_version == Config::TLS_MIN_SUPPORTED_VERSION && max_version == Config::TLS_MAX_SUPPORTED_VERSION) - ? "t13i1310hh_f57a46bbacb6_78e6aca7449b" // same char repeated + ? SSL_SELECT("t13i1310hh_f57a46bbacb6_78e6aca7449b", "t13i5910hh_1fa906e7e9df_1f22a2ca17c4") // same char repeated : alpn_single_char_test_version_to_ja4_.at(min_version); testJA4(expected_ja4, "", alpn); } const absl::flat_hash_map no_alpn_test_version_to_ja4_ = { - {TLS1_VERSION, "t10i040500_cefcabfea53d_950472255fe9"}, - {TLS1_1_VERSION, "t11i040500_cefcabfea53d_950472255fe9"}, - {TLS1_2_VERSION, "t12i100600_a8cf61a50a39_0f3b2bcde21d"}, - {TLS1_3_VERSION, "t13i030500_55b375c5d22e_678be4e4848e"}}; + {TLS1_VERSION, SSL_SELECT("t10i040500_cefcabfea53d_950472255fe9", "t10i130500_dcdf5333bb11_195413a0cc0f")}, + {TLS1_1_VERSION, SSL_SELECT("t11i040500_cefcabfea53d_950472255fe9", "t11i130500_dcdf5333bb11_195413a0cc0f")}, + {TLS1_2_VERSION, SSL_SELECT("t12i100600_a8cf61a50a39_0f3b2bcde21d", "t12i560600_e50dfccbdbbc_e7e480e5a997")}, + {TLS1_3_VERSION, SSL_SELECT("t13i030500_55b375c5d22e_678be4e4848e", "t13i040900_16476d049b0b_78f1d400d464")}}; TEST_P(TlsInspectorTest, JA4WithEmptyALPN) { const uint16_t min_version = std::get<0>(GetParam()); @@ -707,7 +708,7 @@ TEST_P(TlsInspectorTest, JA4WithEmptyALPN) { std::string expected_ja4 = (min_version == Config::TLS_MIN_SUPPORTED_VERSION && max_version == Config::TLS_MAX_SUPPORTED_VERSION) - ? "t13i130900_f57a46bbacb6_78e6aca7449b" // "00" for empty ALPN + ? SSL_SELECT("t13i130900_f57a46bbacb6_78e6aca7449b", "t13i590900_1fa906e7e9df_1f22a2ca17c4") // "00" for empty ALPN : no_alpn_test_version_to_ja4_.at(min_version); testJA4(expected_ja4, "", alpn); @@ -774,7 +775,7 @@ TEST_P(TlsInspectorTest, JA4VersionFallback) { mockSysCallForPeek(client_hello); // Should fall back to ClientHello version field - std::string expected_ja4 = "t12i100600_a8cf61a50a39_0f3b2bcde21d"; + std::string expected_ja4 = SSL_SELECT("t12i100600_a8cf61a50a39_0f3b2bcde21d", "t12i560600_e50dfccbdbbc_e7e480e5a997"); EXPECT_CALL(socket_, setJA4Hash(absl::string_view(expected_ja4))); EXPECT_CALL(socket_, setDetectedTransportProtocol(absl::string_view("tls"))); EXPECT_CALL(socket_, detectedTransportProtocol()).Times(::testing::AnyNumber()); @@ -822,10 +823,10 @@ TEST_P(TlsInspectorTest, JA4EmptyExtensionsList) { } const absl::flat_hash_map max_ciphers_test_version_to_ja4_ = { - {TLS1_VERSION, "t10i990500_f254cf4fa23b_950472255fe9"}, - {TLS1_1_VERSION, "t11i990500_f254cf4fa23b_950472255fe9"}, - {TLS1_2_VERSION, "t12i990600_f254cf4fa23b_0f3b2bcde21d"}, - {TLS1_3_VERSION, "t13i990500_b33cacf22aea_678be4e4848e"}}; + {TLS1_VERSION, SSL_SELECT("t10i990500_f254cf4fa23b_950472255fe9", "t10i990500_f254cf4fa23b_195413a0cc0f")}, + {TLS1_1_VERSION, SSL_SELECT("t11i990500_f254cf4fa23b_950472255fe9", "t11i990500_f254cf4fa23b_195413a0cc0f")}, + {TLS1_2_VERSION, SSL_SELECT("t12i990600_f254cf4fa23b_0f3b2bcde21d", "t12i990600_f254cf4fa23b_e7e480e5a997")}, + {TLS1_3_VERSION, SSL_SELECT("t13i990500_b33cacf22aea_678be4e4848e", "t13i990900_b33cacf22aea_78f1d400d464")}}; TEST_P(TlsInspectorTest, JA4MaxValuesCiphers) { const uint16_t min_version = std::get<0>(GetParam()); @@ -942,7 +943,7 @@ TEST_P(TlsInspectorTest, JA4MaxValuesCiphers) { // Set up proper expectations for socket calls std::string expected_ja4 = (min_version == Config::TLS_MIN_SUPPORTED_VERSION && max_version == Config::TLS_MAX_SUPPORTED_VERSION) - ? "t13i990900_b33cacf22aea_78e6aca7449b" + ? SSL_SELECT("t13i990900_b33cacf22aea_78e6aca7449b", "t13i990900_b33cacf22aea_1f22a2ca17c4") : max_ciphers_test_version_to_ja4_.at(min_version); EXPECT_CALL(socket_, setDetectedTransportProtocol(absl::string_view("tls"))); diff --git a/test/extensions/filters/listener/tls_inspector/tls_utility.cc b/test/extensions/filters/listener/tls_inspector/tls_utility.cc index dad5ea874e9..0c68a5114ee 100644 --- a/test/extensions/filters/listener/tls_inspector/tls_utility.cc +++ b/test/extensions/filters/listener/tls_inspector/tls_utility.cc @@ -220,14 +220,14 @@ std::vector generateClientHelloFromJA3Fingerprint(const std::string& ja // ALPN extension const uint16_t alpn_id = 0x10; std::vector alpn_extension = {(alpn_id & 0xff00) >> 8, alpn_id & 0xff, - // length - 0x00, 0x0b, - // list length - 0x00, 0x09, - // protocol length - 0x08, - // protocol name - 'H', 'T', 'T', 'P', '/', '1', '.', '1'}; + // length + 0x00, 0x0b, + // list length + 0x00, 0x09, + // protocol length + 0x08, + // protocol name + 'H', 'T', 'T', 'P', '/', '1', '.', '1'}; // extensions values = absl::StrSplit(fingerprint[2], '-', absl::SkipEmpty()); diff --git a/test/extensions/filters/network/ext_authz/BUILD b/test/extensions/filters/network/ext_authz/BUILD index 220e781edde..0e87cf57343 100644 --- a/test/extensions/filters/network/ext_authz/BUILD +++ b/test/extensions/filters/network/ext_authz/BUILD @@ -92,6 +92,7 @@ envoy_extension_cc_test( "//test/common/grpc:grpc_client_integration_lib", "//test/integration:integration_lib", "//test/test_common:utility_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/ext_authz/v3:pkg_cc_proto", "@envoy_api//envoy/service/auth/v3:pkg_cc_proto", diff --git a/test/extensions/filters/network/ext_authz/ext_authz_integration_test.cc b/test/extensions/filters/network/ext_authz/ext_authz_integration_test.cc index b1788d7c5f2..644e1f37cdd 100644 --- a/test/extensions/filters/network/ext_authz/ext_authz_integration_test.cc +++ b/test/extensions/filters/network/ext_authz/ext_authz_integration_test.cc @@ -11,6 +11,7 @@ #include "test/integration/ssl_utility.h" #include "test/test_common/environment.h" #include "test/test_common/utility.h" +#include "source/common/ssl/ssl.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -156,7 +157,7 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ExtAuthzNetworkIntegrationTest, GRPC_CLIENT // Test that when ext_authz denies with TLS and send_tls_alert_on_denial is true, // the connection is closed with a TLS alert. -TEST_P(ExtAuthzNetworkIntegrationTest, DenialWithTlsAlertEnabled) { +BORINGSSL_TEST_P(ExtAuthzNetworkIntegrationTest, DenialWithTlsAlertEnabled) { initializeTest(true /* send_tls_alert_on_denial */, true /* with_tls */); setupSslConnection(); diff --git a/test/integration/BUILD b/test/integration/BUILD index 6703d3aa1bb..4f2fdf7767d 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -1984,6 +1984,7 @@ envoy_cc_test( "//test/mocks/secret:secret_mocks", "//test/test_common:resources_lib", "//test/test_common:utility_lib", + "//source/common/ssl:ssl_lib", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", diff --git a/test/integration/sds_dynamic_integration_test.cc b/test/integration/sds_dynamic_integration_test.cc index 881e09be4d4..8b39682dc7e 100644 --- a/test/integration/sds_dynamic_integration_test.cc +++ b/test/integration/sds_dynamic_integration_test.cc @@ -37,6 +37,7 @@ #include "test/test_common/resources.h" #include "test/test_common/test_time_system.h" #include "test/test_common/utility.h" +#include "source/common/ssl/ssl.h" #include "absl/strings/match.h" #include "gmock/gmock.h" @@ -1481,7 +1482,7 @@ INSTANTIATE_TEST_SUITE_P(IpVersionsClientType, SdsDynamicDownstreamPrivateKeyInt testing::ValuesIn(getSdsTestsParams(true)), sdsTestParamsToString); // Validate that a basic SDS updates work with a private key provider. -TEST_P(SdsDynamicDownstreamPrivateKeyIntegrationTest, BasicPrivateKeyProvider) { +BORINGSSL_TEST_P(SdsDynamicDownstreamPrivateKeyIntegrationTest, BasicPrivateKeyProvider) { v3_resource_api_ = true; TestEnvironment::exec( @@ -1541,7 +1542,7 @@ INSTANTIATE_TEST_SUITE_P(IpVersionsClientType, SdsCdsPrivateKeyIntegrationTest, testing::ValuesIn(getSdsTestsParams(true)), sdsTestParamsToString); // Test private key providers in SDS+CDS setup. -TEST_P(SdsCdsPrivateKeyIntegrationTest, BasicSdsCdsPrivateKeyProvider) { +BORINGSSL_TEST_P(SdsCdsPrivateKeyIntegrationTest, BasicSdsCdsPrivateKeyProvider) { v3_resource_api_ = true; TestEnvironment::exec(