Skip to content

Commit 3dcb02f

Browse files
committed
Ability to build both SSL variants
Signed-off-by: Jonh Wendell <[email protected]>
1 parent 0203513 commit 3dcb02f

File tree

19 files changed

+305
-70
lines changed

19 files changed

+305
-70
lines changed

.bazelrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,4 +599,6 @@ try-import %workspace%/clang.bazelrc
599599
try-import %workspace%/user.bazelrc
600600
try-import %workspace%/local_tsan.bazelrc
601601

602-
import %workspace%/openssl/bazelrc
602+
# OpenSSL-specific configuration (use with --config=openssl)
603+
# To use the default BoringSSL backend, simply don't specify this config
604+
try-import %workspace%/openssl/openssl.bazelrc

.github/workflows/envoy-openssl.yml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,33 @@ jobs:
2222
${{ github.repository == 'envoyproxy/envoy-openssl' }}
2323
steps:
2424
- name: Free disk space
25-
uses: envoyproxy/toolshed/gh-actions/[email protected].23
25+
uses: envoyproxy/toolshed/gh-actions/[email protected].28
2626
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
2727
- run: |
2828
./ci/run_envoy_docker.sh './ci/do_ci.sh gcc //test/...'
29+
env:
30+
BAZEL_BUILD_EXTRA_OPTIONS: >-
31+
--config=remote-envoy-engflow
32+
--config=bes-envoy-engflow
33+
--config=remote-ci
34+
--config=openssl
35+
ENVOY_RBE: 1
36+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37+
38+
boringssl:
39+
runs-on: ubuntu-24.04
40+
timeout-minutes: 180
41+
permissions:
42+
contents: read
43+
packages: read
44+
if: >-
45+
${{ github.repository == 'envoyproxy/envoy-openssl' }}
46+
steps:
47+
- name: Free disk space
48+
uses: envoyproxy/toolshed/gh-actions/[email protected]
49+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
50+
- run: |
51+
./ci/run_envoy_docker.sh './ci/do_ci.sh dev //test/...'
2952
env:
3053
BAZEL_BUILD_EXTRA_OPTIONS: >-
3154
--config=remote-envoy-engflow

SSL_BACKEND_SELECTION.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# SSL Backend Selection Support
2+
3+
This document describes how to build Envoy with either BoringSSL (upstream default) or OpenSSL (via bssl-compat).
4+
5+
## Overview
6+
7+
The build system now supports selecting between two SSL backends:
8+
- **BoringSSL** (default) - The upstream SSL library used by Envoy
9+
- **OpenSSL** (via bssl-compat) - OpenSSL 3.0.x with a BoringSSL compatibility layer
10+
11+
## Usage
12+
13+
### Building with BoringSSL (Default)
14+
15+
Simply build as normal without any special flags:
16+
17+
```bash
18+
bazel build //source/exe:envoy-static
19+
```
20+
21+
### Building with OpenSSL
22+
23+
Use the `--config=openssl` flag (recommended):
24+
25+
```bash
26+
bazel build --config=openssl //source/exe:envoy-static
27+
```
28+
29+
This automatically:
30+
- Sets `--define=ssl=openssl` to select the OpenSSL backend
31+
- Adds `-DENVOY_SSL_OPENSSL` compiler flag
32+
- Disables QUIC/HTTP3 support
33+
- Restricts tests to IPv4 only
34+
35+
Alternatively, you can use just the define flag (not recommended as it doesn't apply other OpenSSL-specific settings):
36+
37+
```bash
38+
bazel build --define=ssl=openssl //source/exe:envoy-static
39+
```
40+
41+
## Implementation Details
42+
43+
### Build System Changes
44+
45+
1. **Config Settings** (`bazel/BUILD`):
46+
- Added `ssl_openssl` config_setting for `--define=ssl=openssl`
47+
- Added `ssl_boringssl` config_setting for `--define=ssl=boringssl`
48+
49+
2. **Aliases** (`bazel/BUILD`):
50+
- `//bazel:boringssl` now conditionally points to either `@boringssl//:ssl` or `@bssl-compat//:ssl`
51+
- `//bazel:boringcrypto` now conditionally points to either `@boringssl//:crypto` or `@bssl-compat//:crypto`
52+
53+
3. **Dependencies** (`bazel/repositories.bzl`):
54+
- Both BoringSSL and OpenSSL (via bssl-compat) are loaded
55+
- Selection happens at build time via the aliases
56+
57+
4. **Helper Function** (`bazel/envoy_select.bzl`):
58+
- Added `envoy_select_ssl()` for conditional compilation based on SSL backend
59+
- Example: `envoy_select_ssl(if_openssl = [...], if_boringssl = [...])`
60+
61+
5. **Preprocessor Defines**:
62+
- When `ssl=openssl` is set, `-DENVOY_SSL_OPENSSL` is added to compilation flags
63+
- This allows source code to conditionally compile OpenSSL-specific code
64+
65+
### Source Code Changes
66+
67+
OpenSSL-specific code is wrapped with `#ifdef ENVOY_SSL_OPENSSL`:
68+
69+
1. **SSL Socket** (`source/common/tls/ssl_socket.cc`):
70+
- EAGAIN handling in `SSL_ERROR_SSL` cases
71+
72+
2. **Context Implementation** (`source/common/tls/context_impl.cc`):
73+
- Disabled `SSL_CTX_set_reverify_on_resume()` (not in bssl-compat)
74+
- Disabled `SSL_was_key_usage_invalid()` (not in bssl-compat)
75+
76+
3. **BIO Handling** (`source/common/tls/io_handle_bio.cc`):
77+
- Added `io_handle_new()` and `io_handle_free()` for OpenSSL
78+
- Added BIO control commands for OpenSSL
79+
80+
4. **Version Reporting** (`source/common/version/BUILD`):
81+
- Reports "OpenSSL" or "BoringSSL" based on build configuration
82+
83+
### Configuration Files
84+
85+
The `openssl/bazelrc` file automatically:
86+
- Sets `--define=ssl=openssl`
87+
- Adds `-DENVOY_SSL_OPENSSL` compiler flag
88+
- Disables QUIC/HTTP3 support
89+
- Restricts tests to IPv4 only
90+
91+
## Test Considerations
92+
93+
Some tests have different expectations for OpenSSL vs BoringSSL:
94+
- TLS fingerprints may differ
95+
- Cipher suite ordering may differ
96+
- Alert codes may differ
97+
98+
Tests should use `#ifdef ENVOY_SSL_OPENSSL` to adjust expectations accordingly.
99+
100+
## Migration Guide
101+
102+
### For Users
103+
104+
- To use BoringSSL: No changes needed (default behavior)
105+
- To use OpenSSL: Add `--define=ssl=openssl` to your build commands
106+
107+
### For Developers
108+
109+
When adding SSL-related code:
110+
111+
1. **If the code works with both backends**: No special handling needed
112+
113+
2. **If the code is OpenSSL-specific**: Wrap it with:
114+
```cpp
115+
#ifdef ENVOY_SSL_OPENSSL
116+
// OpenSSL-specific code here
117+
#endif
118+
```
119+
120+
3. **If the code is BoringSSL-specific**: Wrap it with:
121+
```cpp
122+
#ifndef ENVOY_SSL_OPENSSL
123+
// BoringSSL-specific code here
124+
#endif
125+
```
126+
127+
4. **For conditional build dependencies**: Use `envoy_select_ssl()` in BUILD files:
128+
```python
129+
deps = [...] + envoy_select_ssl(
130+
if_openssl = ["//openssl/specific:dep"],
131+
if_boringssl = ["//boringssl/specific:dep"],
132+
)
133+
```
134+
135+
## Limitations
136+
137+
When building with OpenSSL:
138+
- QUIC/HTTP3 support is disabled (OpenSSL doesn't provide QUIC implementation)
139+
- Some BoringSSL-specific APIs are not available
140+
- Test coverage may differ from BoringSSL builds

bazel/BUILD

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,16 @@ config_setting(
497497
values = {"define": "boringssl=disabled"},
498498
)
499499

500+
config_setting(
501+
name = "ssl_openssl",
502+
values = {"define": "ssl=openssl"},
503+
)
504+
505+
config_setting(
506+
name = "ssl_boringssl",
507+
values = {"define": "ssl=boringssl"},
508+
)
509+
500510
selects.config_setting_group(
501511
name = "boringssl_fips_x86",
502512
match_all = [
@@ -559,15 +569,21 @@ config_setting(
559569
values = {"define": "uhv=enabled"},
560570
)
561571

562-
# Alias pointing to the selected version of BoringSSL:
572+
# Alias pointing to the selected SSL implementation (BoringSSL or OpenSSL via bssl-compat):
563573
alias(
564574
name = "boringssl",
565-
actual = "@envoy//bssl-compat:ssl"
575+
actual = select({
576+
":ssl_openssl": "@bssl-compat//:ssl",
577+
"//conditions:default": "@boringssl//:ssl",
578+
}),
566579
)
567580

568581
alias(
569582
name = "boringcrypto",
570-
actual = "@envoy//bssl-compat:crypto"
583+
actual = select({
584+
":ssl_openssl": "@bssl-compat//:crypto",
585+
"//conditions:default": "@boringssl//:crypto",
586+
}),
571587
)
572588

573589
config_setting(

bazel/envoy_build_system.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ load(
4545
_envoy_select_hot_restart = "envoy_select_hot_restart",
4646
_envoy_select_nghttp2 = "envoy_select_nghttp2",
4747
_envoy_select_signal_trace = "envoy_select_signal_trace",
48+
_envoy_select_ssl = "envoy_select_ssl",
4849
_envoy_select_static_extension_registration = "envoy_select_static_extension_registration",
4950
_envoy_select_wasm_cpp_tests = "envoy_select_wasm_cpp_tests",
5051
_envoy_select_wasm_rust_tests = "envoy_select_wasm_rust_tests",
@@ -256,6 +257,7 @@ envoy_select_hot_restart = _envoy_select_hot_restart
256257
envoy_select_nghttp2 = _envoy_select_nghttp2
257258
envoy_select_enable_http_datagrams = _envoy_select_enable_http_datagrams
258259
envoy_select_signal_trace = _envoy_select_signal_trace
260+
envoy_select_ssl = _envoy_select_ssl
259261
envoy_select_wasm_cpp_tests = _envoy_select_wasm_cpp_tests
260262
envoy_select_wasm_rust_tests = _envoy_select_wasm_rust_tests
261263
envoy_select_wasm_v8 = _envoy_select_wasm_v8

bazel/envoy_select.bzl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ def envoy_select_boringssl(if_fips, default = None, if_disabled = None):
2020
"//conditions:default": default or [],
2121
})
2222

23+
# Selects the given values based on the SSL backend (BoringSSL or OpenSSL).
24+
def envoy_select_ssl(if_openssl, if_boringssl = None, repository = ""):
25+
return select({
26+
repository + "//bazel:ssl_openssl": if_openssl,
27+
"//conditions:default": if_boringssl or [],
28+
})
29+
2330
# Selects the given values if Google gRPC is enabled in the current build.
2431
def envoy_select_google_grpc(xs, repository = ""):
2532
return select({

bazel/repositories.bzl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,20 @@ def envoy_dependencies(skip_targets = []):
136136
# Setup external Bazel rules
137137
_foreign_cc_dependencies()
138138

139+
# Load both SSL backends - the actual one used is selected via --define=ssl=<boringssl|openssl>
140+
_boringssl()
141+
_boringssl_fips()
139142
_openssl()
140143

141-
# Binding to an alias pointing to the bssl-compat layer
144+
# Binding to an alias that selects between BoringSSL and OpenSSL via bssl-compat
145+
# The selection is made in //bazel:boringssl and //bazel:boringcrypto aliases
142146
native.bind(
143147
name = "ssl",
144-
actual = "@envoy//bssl-compat:ssl",
148+
actual = "@envoy//bazel:boringssl",
145149
)
146150
native.bind(
147151
name = "crypto",
148-
actual = "@envoy//bssl-compat:crypto",
152+
actual = "@envoy//bazel:boringcrypto",
149153
)
150154

151155
# The long repo names (`com_github_fmtlib_fmt` instead of `fmtlib`) are

bssl-compat/WORKSPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
workspace(name = "bssl_compat")

openssl/bazelrc

Lines changed: 0 additions & 25 deletions
This file was deleted.

openssl/openssl.bazelrc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# This file is sourced from %workspace%/.bazelrc, and includes additional
2+
# configuration specific to building envoy on openssl/bssl-compat
3+
# Use with: bazel build --config=openssl ...
4+
5+
#build:openssl:clang --linkopt=-latomic
6+
7+
# Select OpenSSL as the SSL backend instead of BoringSSL
8+
common:openssl --define=ssl=openssl
9+
10+
# Define ENVOY_SSL_OPENSSL for preprocessor conditionals in source code
11+
build:openssl --copt=-DENVOY_SSL_OPENSSL
12+
build:openssl --host_copt=-DENVOY_SSL_OPENSSL
13+
14+
test:openssl --test_env=ENVOY_IP_TEST_VERSIONS=v4only
15+
16+
# As of today we do not support QUIC/HTTP3, hence we exclude it from the build, always.
17+
# Unfortunately, just setting //bazel:http3=False, is not enough to achieve this.
18+
# Instead, we also have to use boringssl=fips define and filter on the nofips tag.
19+
# This is based on the fact that the FIPS version of BoringSSL doesn't provide enough
20+
# of the functions required to build the QUIC implementation provided by Quiche i.e. if
21+
# we say that we are using the FIPS version of BoringSSL, then all the QUIC support is
22+
# excluded from the build.
23+
common:openssl --//bazel:http3=False
24+
common:openssl --define=boringssl=fips
25+
build:openssl --build_tag_filters=-nofips
26+
test:openssl --test_tag_filters=-nofips
27+
28+
# Arch-specific build flags for OpenSSL builds, triggered with --config=$ARCH in bazel build command
29+
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++
30+
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++
31+
32+
# LLVM paths for bssl-compat prefixer tool (only needed for OpenSSL builds)
33+
common:openssl --action_env=Clang_DIR=/opt/llvm
34+
common:openssl --action_env=LLVM_DIR=/opt/llvm

0 commit comments

Comments
 (0)