Skip to content

Commit 60c6cb1

Browse files
jwendellclaude
andcommitted
Adapt Envoy source code for OpenSSL compatibility
This commit modifies Envoy's C++ source code to work with OpenSSL through the bssl-compat layer, handling differences in SSL/TLS implementations. TLS/SSL changes: - Handle OpenSSL opaque structures (use EVP functions instead of direct access) - Add RTLD_DEEPBIND flag when loading OpenSSL shared libraries - Fix alert code and error code mappings between BoringSSL and OpenSSL - Adjust default TLS versions, ciphers, and curves for FIPS compatibility - Add EAGAIN handling in SslSocket::doRead/doWrite methods - Fix BIO initialization and error handling Context and configuration: - Set TLSv1.3 as max version for FIPS mode - Implement SSL_CTX_set_compliance_policy for certificate validation - Remove calls to unimplemented BoringSSL-specific functions - Adjust certificate verification callbacks for OpenSSL Test adaptations: - Update expected fingerprints and byte counts to match OpenSSL - Fix test values for TLS inspector, JA4 fingerprinting - Adjust SSL version tests for OpenSSL defaults - Disable async certificate validation tests (not supported with OpenSSL) - Disable some QUIC tests (QUIC not supported in OpenSSL build) - Fix hot restart tests for OpenSSL version string Version reporting: - Report "OpenSSL" instead of "BoringSSL" in version string Build fixes: - Comment out QUIC code compilation where needed - Add -latomic linker flag for clang - Fix maxmind and luajit2 builds for s390x/ppc64le 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jonh Wendell <jwendell@redhat.com>
1 parent b86721d commit 60c6cb1

41 files changed

Lines changed: 406 additions & 221 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

source/common/quic/BUILD

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,13 @@ envoy_cc_library(
9292
name = "quic_stat_names_lib",
9393
srcs = ["quic_stat_names.cc"],
9494
hdrs = ["quic_stat_names.h"],
95-
deps = select({
96-
"//bazel:disable_http3": [
97-
"//envoy/stats:stats_interface",
98-
"//source/common/stats:symbol_table_lib",
99-
],
100-
"//conditions:default": [
101-
"//envoy/stats:stats_interface",
102-
"//source/common/stats:symbol_table_lib",
103-
"@com_github_google_quiche//:quic_core_error_codes_lib",
104-
"@com_github_google_quiche//:quic_core_types_lib",
105-
],
106-
}),
95+
tags = ["nofips"],
96+
deps = [
97+
"//envoy/stats:stats_interface",
98+
"//source/common/stats:symbol_table_lib",
99+
"@com_github_google_quiche//:quic_core_error_codes_lib",
100+
"@com_github_google_quiche//:quic_core_types_lib",
101+
],
107102
)
108103

109104
envoy_cc_library(
@@ -603,12 +598,13 @@ envoy_cc_library(
603598

604599
envoy_cc_library(
605600
name = "send_buffer_monitor_lib",
606-
srcs = envoy_select_enable_http3(["send_buffer_monitor.cc"]),
607-
hdrs = envoy_select_enable_http3(["send_buffer_monitor.h"]),
608-
deps = envoy_select_enable_http3([
601+
srcs = ["send_buffer_monitor.cc"],
602+
hdrs = ["send_buffer_monitor.h"],
603+
tags = ["nofips"],
604+
deps = [
609605
"//source/common/common:assert_lib",
610606
"@com_github_google_quiche//:quic_core_session_lib",
611-
]),
607+
],
612608
)
613609

614610
envoy_cc_library(
@@ -704,13 +700,13 @@ envoy_cc_library(
704700

705701
envoy_cc_library(
706702
name = "cert_compression_lib",
707-
srcs = envoy_select_enable_http3(["cert_compression.cc"]),
708-
hdrs = envoy_select_enable_http3(["cert_compression.h"]),
703+
srcs = ["cert_compression.cc"],
704+
hdrs = ["cert_compression.h"],
709705
external_deps = ["ssl"],
710-
deps = envoy_select_enable_http3([
706+
deps = [
711707
"//bazel/foreign_cc:zlib",
712708
"//source/common/common:assert_lib",
713709
"//source/common/common:logger_lib",
714710
"//source/common/runtime:runtime_lib",
715-
]),
711+
],
716712
)

source/common/runtime/runtime_features.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ RUNTIME_GUARD(envoy_restart_features_move_locality_schedulers_to_lb);
9393
RUNTIME_GUARD(envoy_restart_features_raise_file_limits);
9494
RUNTIME_GUARD(envoy_restart_features_skip_backing_cluster_check_for_sds);
9595
RUNTIME_GUARD(envoy_restart_features_use_eds_cache_for_ads);
96-
RUNTIME_GUARD(envoy_restart_features_validate_http3_pseudo_headers);
96+
RUNTIME_GUARD(envoy_restart_features_use_fast_protobuf_hash);
97+
RUNTIME_GUARD(envoy_reloadable_features_enable_intermediate_ca);
9798

9899
// Begin false flags. Most of them should come with a TODO to flip true.
99100

source/common/tls/cert_validator/default_validator.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ absl::StatusOr<int> DefaultCertValidator::initializeSslContexts(std::vector<SSL_
8888

8989
for (auto& ctx : contexts) {
9090
X509_STORE* store = SSL_CTX_get_cert_store(ctx);
91-
X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN);
91+
// RH - Restore reloadable feature check to avoid failure of RevokedIntermediateCertificate test
92+
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.enable_intermediate_ca")) {
93+
X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN);
94+
}
9295
bool has_crl = false;
9396
for (const X509_INFO* item : list.get()) {
9497
if (item->x509) {
@@ -143,7 +146,10 @@ absl::StatusOr<int> DefaultCertValidator::initializeSslContexts(std::vector<SSL_
143146

144147
for (auto& ctx : contexts) {
145148
X509_STORE* store = SSL_CTX_get_cert_store(ctx);
146-
X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN);
149+
// RH - Restore reloadable feature check to avoid failure of RevokedIntermediateCertificate test
150+
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.enable_intermediate_ca")) {
151+
X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN);
152+
}
147153
for (const X509_INFO* item : list.get()) {
148154
if (item->crl) {
149155
X509_STORE_add_crl(store, item->crl);

source/common/tls/client_context_impl.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ ClientContextImpl::newSsl(const Network::TransportSocketOptionsConstSharedPtr& o
156156
SSL_set_renegotiate_mode(ssl_con.get(), ssl_renegotiate_freely);
157157
}
158158

159+
#if 0 // Disabled as not implemented in the bSSL layer
159160
SSL_set_enforce_rsa_key_usage(ssl_con.get(), enforce_rsa_key_usage_);
161+
#endif
160162

161163
if (max_session_keys_ > 0) {
162164
if (session_keys_single_use_) {

source/common/tls/context_config_impl.cc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace Tls {
2626

2727
namespace {
2828

29+
static const bool isFipsEnabled = ContextConfigImpl::getFipsEnabled();
30+
2931
std::string generateCertificateHash(const std::string& cert_data) {
3032
Buffer::OwnedImpl buffer(cert_data);
3133

@@ -378,8 +380,8 @@ const unsigned ClientContextConfigImpl::DEFAULT_MIN_VERSION = TLS1_2_VERSION;
378380
const unsigned ClientContextConfigImpl::DEFAULT_MAX_VERSION = TLS1_2_VERSION;
379381

380382
const std::string ClientContextConfigImpl::DEFAULT_CIPHER_SUITES =
381-
"[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:"
382-
"[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:"
383+
"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:"
384+
"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:"
383385
"ECDHE-ECDSA-AES256-GCM-SHA384:"
384386
"ECDHE-RSA-AES256-GCM-SHA384:";
385387

@@ -389,10 +391,11 @@ const std::string ClientContextConfigImpl::DEFAULT_CIPHER_SUITES_FIPS =
389391
"ECDHE-ECDSA-AES256-GCM-SHA384:"
390392
"ECDHE-RSA-AES256-GCM-SHA384:";
391393

392-
const std::string ClientContextConfigImpl::DEFAULT_CURVES = "X25519:"
393-
"P-256";
394+
const std::string ClientContextConfigImpl::DEFAULT_CURVES =
395+
"X25519:P-256";
394396

395-
const std::string ClientContextConfigImpl::DEFAULT_CURVES_FIPS = "P-256";
397+
const std::string ClientContextConfigImpl::DEFAULT_CURVES_FIPS =
398+
"P-256";
396399

397400
absl::StatusOr<std::unique_ptr<ClientContextConfigImpl>> ClientContextConfigImpl::create(
398401
const envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext& config,

source/common/tls/context_config_impl.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,19 @@ class ContextConfigImpl : public virtual Ssl::ContextConfig {
8383
const envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext&
8484
dynamic_cvc,
8585
const std::string& name);
86+
static bool getFipsEnabled() {
87+
std::ifstream file("/proc/sys/crypto/fips_enabled");
88+
if (file.fail()) {
89+
return false;
90+
}
91+
92+
std::stringstream file_string;
93+
file_string << file.rdbuf();
94+
95+
std::string fipsEnabledText = file_string.str();
96+
fipsEnabledText.erase(fipsEnabledText.find_last_not_of("\n") + 1);
97+
return fipsEnabledText.compare("1") == 0;
98+
}
8699

87100
protected:
88101
ContextConfigImpl(const envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& config,

source/common/tls/context_impl.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,9 @@ ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& c
182182
// even request client certs. So, instead, we should configure a callback to skip
183183
// validation and always supply the callback to boring SSL.
184184
SSL_CTX_set_custom_verify(ctx, verify_mode, customVerifyCallback);
185+
#if 0 // Disabled as not implememnted in the bSSL layer
185186
SSL_CTX_set_reverify_on_resume(ctx, /*reverify_on_resume_enabled)=*/1);
187+
#endif
186188
}
187189
}
188190
}
@@ -324,6 +326,7 @@ ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& c
324326
parsed_alpn_protocols_ = parseAlpnProtocols(config.alpnProtocols(), creation_status);
325327
SET_AND_RETURN_IF_NOT_OK(creation_status, creation_status);
326328

329+
327330
// Register stat names based on lists reported by BoringSSL.
328331
std::vector<const char*> list(SSL_get_all_cipher_names(nullptr, 0));
329332
SSL_get_all_cipher_names(list.data(), list.size());
@@ -333,6 +336,7 @@ ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& c
333336
SSL_get_all_curve_names(list.data(), list.size());
334337
stat_name_set_->rememberBuiltins(list);
335338

339+
336340
list.resize(SSL_get_all_signature_algorithm_names(nullptr, 0));
337341
SSL_get_all_signature_algorithm_names(list.data(), list.size());
338342
stat_name_set_->rememberBuiltins(list);
@@ -362,6 +366,7 @@ ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& c
362366
}
363367
}
364368

369+
365370
// Compliance policy must be applied last to have a defined behavior.
366371
if (const auto policy = config.compliancePolicy(); policy.has_value()) {
367372
switch (policy.value()) {
@@ -561,9 +566,11 @@ void ContextImpl::logHandshake(SSL* ssl) const {
561566
// Increment the `was_key_usage_invalid_` stats to indicate the given cert would have triggered an
562567
// error but is allowed because the enforcement that rsa key usage and tls usage need to be
563568
// matched has been disabled.
569+
#if 0 // Disabled as SSL_was_key_usage_invalid() is not implememnted in the bSSL layer
564570
if (SSL_was_key_usage_invalid(ssl)) {
565571
stats_.was_key_usage_invalid_.inc();
566572
}
573+
#endif
567574
}
568575

569576
std::vector<Ssl::PrivateKeyMethodProviderSharedPtr> ContextImpl::getPrivateKeyMethodProviders() {

source/common/tls/io_handle_bio.cc

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,30 @@ inline Envoy::Network::IoHandle* bio_io_handle(BIO* bio) {
1818
return reinterpret_cast<Envoy::Network::IoHandle*>(BIO_get_data(bio));
1919
}
2020

21+
// NOLINTNEXTLINE(readability-identifier-naming)
22+
int io_handle_new(BIO* bio) {
23+
BIO_set_init(bio, 0);
24+
BIO_set_data(bio, nullptr);
25+
BIO_clear_flags(bio, ~0);
26+
return 1;
27+
}
28+
29+
// NOLINTNEXTLINE(readability-identifier-naming)
30+
int io_handle_free(BIO* bio) {
31+
if (bio == nullptr) {
32+
return 0;
33+
}
34+
35+
if (BIO_get_shutdown(bio)) {
36+
if (BIO_get_init(bio)) {
37+
bio_io_handle(bio)->close();
38+
}
39+
BIO_set_init(bio, 0);
40+
BIO_clear_flags(bio, ~0);
41+
}
42+
return 1;
43+
}
44+
2145
// NOLINTNEXTLINE(readability-identifier-naming)
2246
int io_handle_read(BIO* b, char* out, int outl) {
2347
if (out == nullptr) {
@@ -61,10 +85,22 @@ int io_handle_write(BIO* b, const char* in, int inl) {
6185
}
6286

6387
// NOLINTNEXTLINE(readability-identifier-naming)
64-
long io_handle_ctrl(BIO*, int cmd, long, void*) {
88+
long io_handle_ctrl(BIO* b, int cmd, long num, void*) {
6589
long ret = 1;
6690

6791
switch (cmd) {
92+
case BIO_C_SET_FD:
93+
RELEASE_ASSERT(false, "should not be called");
94+
break;
95+
case BIO_C_GET_FD:
96+
RELEASE_ASSERT(false, "should not be called");
97+
break;
98+
case BIO_CTRL_GET_CLOSE:
99+
ret = BIO_get_shutdown(b);
100+
break;
101+
case BIO_CTRL_SET_CLOSE:
102+
BIO_set_shutdown(b, int(num));
103+
break;
68104
case BIO_CTRL_FLUSH:
69105
ret = 1;
70106
break;
@@ -75,6 +111,7 @@ long io_handle_ctrl(BIO*, int cmd, long, void*) {
75111
return ret;
76112
}
77113

114+
78115
// NOLINTNEXTLINE(readability-identifier-naming)
79116
const BIO_METHOD* BIO_s_io_handle(void) {
80117
static const BIO_METHOD* method = [&] {
@@ -83,6 +120,8 @@ const BIO_METHOD* BIO_s_io_handle(void) {
83120
RELEASE_ASSERT(BIO_meth_set_read(ret, io_handle_read), "");
84121
RELEASE_ASSERT(BIO_meth_set_write(ret, io_handle_write), "");
85122
RELEASE_ASSERT(BIO_meth_set_ctrl(ret, io_handle_ctrl), "");
123+
RELEASE_ASSERT(BIO_meth_set_create(ret, io_handle_new), "");
124+
RELEASE_ASSERT(BIO_meth_set_destroy(ret, io_handle_free), "");
86125
return ret;
87126
}();
88127
return method;
@@ -99,6 +138,7 @@ BIO* BIO_new_io_handle(Envoy::Network::IoHandle* io_handle) {
99138

100139
// Initialize the BIO
101140
BIO_set_data(b, io_handle);
141+
BIO_set_shutdown(b, 0);
102142
BIO_set_init(b, 1);
103143

104144
return b;

source/common/tls/ocsp/asn1_utility.cc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,10 @@ absl::StatusOr<std::string> Asn1Utility::parseInteger(CBS& cbs) {
8888
CSmartPtr<ASN1_INTEGER, freeAsn1Integer> asn1_integer(
8989
c2i_ASN1_INTEGER(nullptr, &head, CBS_len(&num)));
9090
if (asn1_integer != nullptr) {
91-
BIGNUM num_bn;
92-
BN_init(&num_bn);
93-
ASN1_INTEGER_to_BN(asn1_integer.get(), &num_bn);
91+
bssl::UniquePtr<BIGNUM> num_bn {BN_new()};
92+
ASN1_INTEGER_to_BN(asn1_integer.get(), num_bn.get());
9493

95-
CSmartPtr<char, freeOpensslString> char_hex_number(BN_bn2hex(&num_bn));
96-
BN_free(&num_bn);
94+
CSmartPtr<char, freeOpensslString> char_hex_number(BN_bn2hex(num_bn.get()));
9795
if (char_hex_number != nullptr) {
9896
std::string hex_number(char_hex_number.get());
9997
return hex_number;

source/common/tls/server_context_config_impl.cc

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,15 @@ bool getStatelessSessionResumptionDisabled(
8686

8787
} // namespace
8888

89-
const unsigned ServerContextConfigImpl::DEFAULT_MIN_VERSION = TLS1_2_VERSION;
89+
static const bool isFipsEnabled = ContextConfigImpl::getFipsEnabled();
90+
91+
const unsigned ServerContextConfigImpl::DEFAULT_MIN_VERSION = TLS1_VERSION;
92+
9093
const unsigned ServerContextConfigImpl::DEFAULT_MAX_VERSION = TLS1_3_VERSION;
9194

9295
const std::string ServerContextConfigImpl::DEFAULT_CIPHER_SUITES =
93-
"[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:"
94-
"[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:"
96+
"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:"
97+
"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:"
9598
"ECDHE-ECDSA-AES256-GCM-SHA384:"
9699
"ECDHE-RSA-AES256-GCM-SHA384:";
97100

@@ -101,10 +104,11 @@ const std::string ServerContextConfigImpl::DEFAULT_CIPHER_SUITES_FIPS =
101104
"ECDHE-ECDSA-AES256-GCM-SHA384:"
102105
"ECDHE-RSA-AES256-GCM-SHA384:";
103106

104-
const std::string ServerContextConfigImpl::DEFAULT_CURVES = "X25519:"
105-
"P-256";
107+
const std::string ServerContextConfigImpl::DEFAULT_CURVES =
108+
"X25519:P-256";
106109

107-
const std::string ServerContextConfigImpl::DEFAULT_CURVES_FIPS = "P-256";
110+
const std::string ServerContextConfigImpl::DEFAULT_CURVES_FIPS =
111+
"P-256" ;
108112

109113
absl::StatusOr<std::unique_ptr<ServerContextConfigImpl>> ServerContextConfigImpl::create(
110114
const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config,

0 commit comments

Comments
 (0)