LCOV - code coverage report
Current view: top level - source/extensions/transport_sockets/tls - context_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 1017 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 47 0.0 %

          Line data    Source code
       1             : #include "source/extensions/transport_sockets/tls/context_impl.h"
       2             : 
       3             : #include <openssl/ssl.h>
       4             : 
       5             : #include <algorithm>
       6             : #include <cstddef>
       7             : #include <cstdint>
       8             : #include <memory>
       9             : #include <string>
      10             : #include <utility>
      11             : #include <vector>
      12             : 
      13             : #include "envoy/admin/v3/certs.pb.h"
      14             : #include "envoy/common/exception.h"
      15             : #include "envoy/common/platform.h"
      16             : #include "envoy/ssl/ssl_socket_extended_info.h"
      17             : #include "envoy/stats/scope.h"
      18             : #include "envoy/type/matcher/v3/string.pb.h"
      19             : 
      20             : #include "source/common/common/assert.h"
      21             : #include "source/common/common/base64.h"
      22             : #include "source/common/common/fmt.h"
      23             : #include "source/common/common/hex.h"
      24             : #include "source/common/common/utility.h"
      25             : #include "source/common/network/address_impl.h"
      26             : #include "source/common/protobuf/utility.h"
      27             : #include "source/common/runtime/runtime_features.h"
      28             : #include "source/common/stats/utility.h"
      29             : #include "source/extensions/transport_sockets/tls/cert_validator/factory.h"
      30             : #include "source/extensions/transport_sockets/tls/stats.h"
      31             : #include "source/extensions/transport_sockets/tls/utility.h"
      32             : 
      33             : #include "absl/container/node_hash_set.h"
      34             : #include "absl/strings/match.h"
      35             : #include "absl/strings/str_join.h"
      36             : #include "cert_validator/cert_validator.h"
      37             : #include "openssl/evp.h"
      38             : #include "openssl/hmac.h"
      39             : #include "openssl/pkcs12.h"
      40             : #include "openssl/rand.h"
      41             : 
      42             : namespace Envoy {
      43             : namespace Extensions {
      44             : namespace TransportSockets {
      45             : namespace Tls {
      46             : 
      47             : namespace {
      48             : 
      49           0 : bool cbsContainsU16(CBS& cbs, uint16_t n) {
      50           0 :   while (CBS_len(&cbs) > 0) {
      51           0 :     uint16_t v;
      52           0 :     if (!CBS_get_u16(&cbs, &v)) {
      53           0 :       return false;
      54           0 :     }
      55           0 :     if (v == n) {
      56           0 :       return true;
      57           0 :     }
      58           0 :   }
      59             : 
      60           0 :   return false;
      61           0 : }
      62             : 
      63           0 : void logSslErrorChain() {
      64           0 :   while (uint64_t err = ERR_get_error()) {
      65           0 :     ENVOY_LOG_MISC(debug, "SSL error: {}:{}:{}:{}", err,
      66           0 :                    absl::NullSafeStringView(ERR_lib_error_string(err)),
      67           0 :                    absl::NullSafeStringView(ERR_func_error_string(err)), ERR_GET_REASON(err),
      68           0 :                    absl::NullSafeStringView(ERR_reason_error_string(err)));
      69           0 :   }
      70           0 : }
      71             : 
      72             : } // namespace
      73             : 
      74           0 : int ContextImpl::sslExtendedSocketInfoIndex() {
      75           0 :   CONSTRUCT_ON_FIRST_USE(int, []() -> int {
      76           0 :     int ssl_context_index = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
      77           0 :     RELEASE_ASSERT(ssl_context_index >= 0, "");
      78           0 :     return ssl_context_index;
      79           0 :   }());
      80           0 : }
      81             : 
      82             : ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& config,
      83             :                          TimeSource& time_source)
      84             :     : scope_(scope), stats_(generateSslStats(scope)), time_source_(time_source),
      85             :       tls_max_version_(config.maxProtocolVersion()),
      86             :       stat_name_set_(scope.symbolTable().makeSet("TransportSockets::Tls")),
      87             :       unknown_ssl_cipher_(stat_name_set_->add("unknown_ssl_cipher")),
      88             :       unknown_ssl_curve_(stat_name_set_->add("unknown_ssl_curve")),
      89             :       unknown_ssl_algorithm_(stat_name_set_->add("unknown_ssl_algorithm")),
      90             :       unknown_ssl_version_(stat_name_set_->add("unknown_ssl_version")),
      91             :       ssl_ciphers_(stat_name_set_->add("ssl.ciphers")),
      92             :       ssl_versions_(stat_name_set_->add("ssl.versions")),
      93             :       ssl_curves_(stat_name_set_->add("ssl.curves")),
      94             :       ssl_sigalgs_(stat_name_set_->add("ssl.sigalgs")), capabilities_(config.capabilities()),
      95           0 :       tls_keylog_local_(config.tlsKeyLogLocal()), tls_keylog_remote_(config.tlsKeyLogRemote()) {
      96             : 
      97           0 :   auto cert_validator_name = getCertValidatorName(config.certificateValidationContext());
      98           0 :   auto cert_validator_factory =
      99           0 :       Registry::FactoryRegistry<CertValidatorFactory>::getFactory(cert_validator_name);
     100             : 
     101           0 :   if (!cert_validator_factory) {
     102           0 :     throwEnvoyExceptionOrPanic(
     103           0 :         absl::StrCat("Failed to get certificate validator factory for ", cert_validator_name));
     104           0 :   }
     105             : 
     106           0 :   cert_validator_ = cert_validator_factory->createCertValidator(
     107           0 :       config.certificateValidationContext(), stats_, time_source_);
     108             : 
     109           0 :   const auto tls_certificates = config.tlsCertificates();
     110           0 :   tls_contexts_.resize(std::max(static_cast<size_t>(1), tls_certificates.size()));
     111             : 
     112           0 :   std::vector<SSL_CTX*> ssl_contexts(tls_contexts_.size());
     113           0 :   for (size_t i = 0; i < tls_contexts_.size(); i++) {
     114           0 :     auto& ctx = tls_contexts_[i];
     115           0 :     ctx.ssl_ctx_.reset(SSL_CTX_new(TLS_method()));
     116           0 :     ssl_contexts[i] = ctx.ssl_ctx_.get();
     117             : 
     118           0 :     int rc = SSL_CTX_set_app_data(ctx.ssl_ctx_.get(), this);
     119           0 :     RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
     120             : 
     121           0 :     rc = SSL_CTX_set_min_proto_version(ctx.ssl_ctx_.get(), config.minProtocolVersion());
     122           0 :     RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
     123             : 
     124           0 :     rc = SSL_CTX_set_max_proto_version(ctx.ssl_ctx_.get(), config.maxProtocolVersion());
     125           0 :     RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
     126             : 
     127           0 :     if (!capabilities_.provides_ciphers_and_curves &&
     128           0 :         !SSL_CTX_set_strict_cipher_list(ctx.ssl_ctx_.get(), config.cipherSuites().c_str())) {
     129             :       // Break up a set of ciphers into each individual cipher and try them each individually in
     130             :       // order to attempt to log which specific one failed. Example of config.cipherSuites():
     131             :       // "-ALL:[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:ECDHE-ECDSA-AES128-SHA".
     132             :       //
     133             :       // "-" is both an operator when in the leading position of a token (-ALL: don't allow this
     134             :       // cipher), and the common separator in names (ECDHE-ECDSA-AES128-GCM-SHA256). Don't split on
     135             :       // it because it will separate pieces of the same cipher. When it is a leading character, it
     136             :       // is removed below.
     137           0 :       std::vector<absl::string_view> ciphers =
     138           0 :           StringUtil::splitToken(config.cipherSuites(), ":+![|]", false);
     139           0 :       std::vector<std::string> bad_ciphers;
     140           0 :       for (const auto& cipher : ciphers) {
     141           0 :         std::string cipher_str(cipher);
     142             : 
     143           0 :         if (absl::StartsWith(cipher_str, "-")) {
     144           0 :           cipher_str.erase(cipher_str.begin());
     145           0 :         }
     146             : 
     147           0 :         if (!SSL_CTX_set_strict_cipher_list(ctx.ssl_ctx_.get(), cipher_str.c_str())) {
     148           0 :           bad_ciphers.push_back(cipher_str);
     149           0 :         }
     150           0 :       }
     151           0 :       throwEnvoyExceptionOrPanic(fmt::format("Failed to initialize cipher suites {}. The following "
     152           0 :                                              "ciphers were rejected when tried individually: {}",
     153           0 :                                              config.cipherSuites(),
     154           0 :                                              absl::StrJoin(bad_ciphers, ", ")));
     155           0 :     }
     156             : 
     157           0 :     if (!capabilities_.provides_ciphers_and_curves &&
     158           0 :         !SSL_CTX_set1_curves_list(ctx.ssl_ctx_.get(), config.ecdhCurves().c_str())) {
     159           0 :       throwEnvoyExceptionOrPanic(
     160           0 :           absl::StrCat("Failed to initialize ECDH curves ", config.ecdhCurves()));
     161           0 :     }
     162             : 
     163             :     // Set signature algorithms if given, otherwise fall back to BoringSSL defaults.
     164           0 :     if (!capabilities_.provides_sigalgs && !config.signatureAlgorithms().empty()) {
     165           0 :       if (!SSL_CTX_set1_sigalgs_list(ctx.ssl_ctx_.get(), config.signatureAlgorithms().c_str())) {
     166           0 :         throwEnvoyExceptionOrPanic(absl::StrCat("Failed to initialize TLS signature algorithms ",
     167           0 :                                                 config.signatureAlgorithms()));
     168           0 :       }
     169           0 :     }
     170           0 :   }
     171             : 
     172           0 :   auto verify_mode = cert_validator_->initializeSslContexts(
     173           0 :       ssl_contexts, config.capabilities().provides_certificates);
     174           0 :   if (!capabilities_.verifies_peer_certificates) {
     175           0 :     for (auto ctx : ssl_contexts) {
     176           0 :       if (verify_mode != SSL_VERIFY_NONE) {
     177             :         // TODO(danzh) Envoy's use of SSL_VERIFY_NONE does not quite match the actual semantics as
     178             :         // a client. As a client, SSL_VERIFY_NONE means to verify the certificate (which will fail
     179             :         // without trust anchors), save the result in the session ticket, but otherwise continue
     180             :         // with the handshake. But Envoy actually wants it to accept all certificates. The
     181             :         // disadvantage of using SSL_VERIFY_NONE is that it records the verify_result, which Envoy
     182             :         // never queries but gets saved in session tickets, and tries to find an anchor that isn't
     183             :         // there. And also it differs from server side behavior of SSL_VERIFY_NONE which won't
     184             :         // even request client certs. So, instead, we should configure a callback to skip
     185             :         // validation and always supply the callback to boring SSL.
     186           0 :         SSL_CTX_set_custom_verify(ctx, verify_mode, customVerifyCallback);
     187           0 :         SSL_CTX_set_reverify_on_resume(ctx, /*reverify_on_resume_enabled)=*/1);
     188           0 :       }
     189           0 :     }
     190           0 :   }
     191             : 
     192             : #ifdef BORINGSSL_FIPS
     193             :   if (!capabilities_.is_fips_compliant) {
     194             :     throwEnvoyExceptionOrPanic(
     195             :         "Can't load a FIPS noncompliant custom handshaker while running in FIPS compliant mode.");
     196             :   }
     197             : #endif
     198             : 
     199           0 :   if (!capabilities_.provides_certificates) {
     200           0 :     for (uint32_t i = 0; i < tls_certificates.size(); ++i) {
     201           0 :       auto& ctx = tls_contexts_[i];
     202             :       // Load certificate chain.
     203           0 :       const auto& tls_certificate = tls_certificates[i].get();
     204           0 :       if (!tls_certificate.pkcs12().empty()) {
     205           0 :         ctx.loadPkcs12(tls_certificate.pkcs12(), tls_certificate.pkcs12Path(),
     206           0 :                        tls_certificate.password());
     207           0 :       } else {
     208           0 :         ctx.loadCertificateChain(tls_certificate.certificateChain(),
     209           0 :                                  tls_certificate.certificateChainPath());
     210           0 :       }
     211             : 
     212             :       // The must staple extension means the certificate promises to carry
     213             :       // with it an OCSP staple. https://tools.ietf.org/html/rfc7633#section-6
     214           0 :       constexpr absl::string_view tls_feature_ext = "1.3.6.1.5.5.7.1.24";
     215           0 :       constexpr absl::string_view must_staple_ext_value = "\x30\x3\x02\x01\x05";
     216           0 :       auto must_staple = Utility::getCertificateExtensionValue(*ctx.cert_chain_, tls_feature_ext);
     217           0 :       if (must_staple == must_staple_ext_value) {
     218           0 :         ctx.is_must_staple_ = true;
     219           0 :       }
     220             : 
     221           0 :       bssl::UniquePtr<EVP_PKEY> public_key(X509_get_pubkey(ctx.cert_chain_.get()));
     222           0 :       const int pkey_id = EVP_PKEY_id(public_key.get());
     223           0 :       ctx.is_ecdsa_ = pkey_id == EVP_PKEY_EC;
     224           0 :       switch (pkey_id) {
     225           0 :       case EVP_PKEY_EC: {
     226             :         // We only support P-256 ECDSA today.
     227           0 :         const EC_KEY* ecdsa_public_key = EVP_PKEY_get0_EC_KEY(public_key.get());
     228             :         // Since we checked the key type above, this should be valid.
     229           0 :         ASSERT(ecdsa_public_key != nullptr);
     230           0 :         const EC_GROUP* ecdsa_group = EC_KEY_get0_group(ecdsa_public_key);
     231           0 :         if (ecdsa_group == nullptr ||
     232           0 :             EC_GROUP_get_curve_name(ecdsa_group) != NID_X9_62_prime256v1) {
     233           0 :           throwEnvoyExceptionOrPanic(
     234           0 :               fmt::format("Failed to load certificate chain from {}, only P-256 "
     235           0 :                           "ECDSA certificates are supported",
     236           0 :                           ctx.cert_chain_file_path_));
     237           0 :         }
     238           0 :         ctx.is_ecdsa_ = true;
     239           0 :       } break;
     240           0 :       case EVP_PKEY_RSA: {
     241             :         // We require RSA certificates with 2048-bit or larger keys.
     242           0 :         const RSA* rsa_public_key = EVP_PKEY_get0_RSA(public_key.get());
     243             :         // Since we checked the key type above, this should be valid.
     244           0 :         ASSERT(rsa_public_key != nullptr);
     245           0 :         const unsigned rsa_key_length = RSA_bits(rsa_public_key);
     246             : #ifdef BORINGSSL_FIPS
     247             :         if (rsa_key_length != 2048 && rsa_key_length != 3072 && rsa_key_length != 4096) {
     248             :           throwEnvoyExceptionOrPanic(
     249             :               fmt::format("Failed to load certificate chain from {}, only RSA certificates with "
     250             :                           "2048-bit, 3072-bit or 4096-bit keys are supported in FIPS mode",
     251             :                           ctx.cert_chain_file_path_));
     252             :         }
     253             : #else
     254           0 :         if (rsa_key_length < 2048) {
     255           0 :           throwEnvoyExceptionOrPanic(
     256           0 :               fmt::format("Failed to load certificate chain from {}, only RSA "
     257           0 :                           "certificates with 2048-bit or larger keys are supported",
     258           0 :                           ctx.cert_chain_file_path_));
     259           0 :         }
     260           0 : #endif
     261           0 :       } break;
     262             : #ifdef BORINGSSL_FIPS
     263             :       default:
     264             :         throwEnvoyExceptionOrPanic(
     265             :             fmt::format("Failed to load certificate chain from {}, only RSA and "
     266             :                         "ECDSA certificates are supported in FIPS mode",
     267             :                         ctx.cert_chain_file_path_));
     268             : #endif
     269           0 :       }
     270             : 
     271           0 :       Envoy::Ssl::PrivateKeyMethodProviderSharedPtr private_key_method_provider =
     272           0 :           tls_certificate.privateKeyMethod();
     273             :       // We either have a private key or a BoringSSL private key method provider.
     274           0 :       if (private_key_method_provider) {
     275           0 :         ctx.private_key_method_provider_ = private_key_method_provider;
     276             :         // The provider has a reference to the private key method for the context lifetime.
     277           0 :         Ssl::BoringSslPrivateKeyMethodSharedPtr private_key_method =
     278           0 :             private_key_method_provider->getBoringSslPrivateKeyMethod();
     279           0 :         if (private_key_method == nullptr) {
     280           0 :           throwEnvoyExceptionOrPanic(
     281           0 :               fmt::format("Failed to get BoringSSL private key method from provider"));
     282           0 :         }
     283             : #ifdef BORINGSSL_FIPS
     284             :         if (!ctx.private_key_method_provider_->checkFips()) {
     285             :           throwEnvoyExceptionOrPanic(
     286             :               fmt::format("Private key method doesn't support FIPS mode with current parameters"));
     287             :         }
     288             : #endif
     289           0 :         SSL_CTX_set_private_key_method(ctx.ssl_ctx_.get(), private_key_method.get());
     290           0 :       } else if (!tls_certificate.privateKey().empty()) {
     291             :         // Load private key.
     292           0 :         ctx.loadPrivateKey(tls_certificate.privateKey(), tls_certificate.privateKeyPath(),
     293           0 :                            tls_certificate.password());
     294           0 :       }
     295           0 :     }
     296           0 :   }
     297             : 
     298             :   // use the server's cipher list preferences
     299           0 :   for (auto& ctx : tls_contexts_) {
     300           0 :     SSL_CTX_set_options(ctx.ssl_ctx_.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
     301           0 :   }
     302             : 
     303           0 :   parsed_alpn_protocols_ = parseAlpnProtocols(config.alpnProtocols());
     304             : 
     305           0 : #if BORINGSSL_API_VERSION >= 21
     306             :   // Register stat names based on lists reported by BoringSSL.
     307           0 :   std::vector<const char*> list(SSL_get_all_cipher_names(nullptr, 0));
     308           0 :   SSL_get_all_cipher_names(list.data(), list.size());
     309           0 :   stat_name_set_->rememberBuiltins(list);
     310             : 
     311           0 :   list.resize(SSL_get_all_curve_names(nullptr, 0));
     312           0 :   SSL_get_all_curve_names(list.data(), list.size());
     313           0 :   stat_name_set_->rememberBuiltins(list);
     314             : 
     315           0 :   list.resize(SSL_get_all_signature_algorithm_names(nullptr, 0));
     316           0 :   SSL_get_all_signature_algorithm_names(list.data(), list.size());
     317           0 :   stat_name_set_->rememberBuiltins(list);
     318             : 
     319           0 :   list.resize(SSL_get_all_version_names(nullptr, 0));
     320           0 :   SSL_get_all_version_names(list.data(), list.size());
     321           0 :   stat_name_set_->rememberBuiltins(list);
     322             : #else
     323             :   // Use the SSL library to iterate over the configured ciphers.
     324             :   //
     325             :   // Note that if a negotiated cipher suite is outside of this set, we'll issue an ENVOY_BUG.
     326             :   for (TlsContext& tls_context : tls_contexts_) {
     327             :     for (const SSL_CIPHER* cipher : SSL_CTX_get_ciphers(tls_context.ssl_ctx_.get())) {
     328             :       stat_name_set_->rememberBuiltin(SSL_CIPHER_get_name(cipher));
     329             :     }
     330             :   }
     331             : 
     332             :   // Add supported cipher suites from the TLS 1.3 spec:
     333             :   // https://tools.ietf.org/html/rfc8446#appendix-B.4
     334             :   // AES-CCM cipher suites are removed (no BoringSSL support).
     335             :   //
     336             :   // Note that if a negotiated cipher suite is outside of this set, we'll issue an ENVOY_BUG.
     337             :   stat_name_set_->rememberBuiltins(
     338             :       {"TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"});
     339             : 
     340             :   // All supported curves. Source:
     341             :   // https://github.com/google/boringssl/blob/3743aafdacff2f7b083615a043a37101f740fa53/ssl/ssl_key_share.cc#L302-L309
     342             :   //
     343             :   // Note that if a negotiated curve is outside of this set, we'll issue an ENVOY_BUG.
     344             :   stat_name_set_->rememberBuiltins({"P-224", "P-256", "P-384", "P-521", "X25519", "CECPQ2"});
     345             : 
     346             :   // All supported signature algorithms. Source:
     347             :   // https://github.com/google/boringssl/blob/3743aafdacff2f7b083615a043a37101f740fa53/ssl/ssl_privkey.cc#L436-L453
     348             :   //
     349             :   // Note that if a negotiated algorithm is outside of this set, we'll issue an ENVOY_BUG.
     350             :   stat_name_set_->rememberBuiltins({
     351             :       "rsa_pkcs1_md5_sha1",
     352             :       "rsa_pkcs1_sha1",
     353             :       "rsa_pkcs1_sha256",
     354             :       "rsa_pkcs1_sha384",
     355             :       "rsa_pkcs1_sha512",
     356             :       "ecdsa_sha1",
     357             :       "ecdsa_secp256r1_sha256",
     358             :       "ecdsa_secp384r1_sha384",
     359             :       "ecdsa_secp521r1_sha512",
     360             :       "rsa_pss_rsae_sha256",
     361             :       "rsa_pss_rsae_sha384",
     362             :       "rsa_pss_rsae_sha512",
     363             :       "ed25519",
     364             :   });
     365             : 
     366             :   // All supported protocol versions.
     367             :   //
     368             :   // Note that if a negotiated version is outside of this set, we'll issue an ENVOY_BUG.
     369             :   stat_name_set_->rememberBuiltins({"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"});
     370             : #endif
     371             : 
     372             :   // As late as possible, run the custom SSL_CTX configuration callback on each
     373             :   // SSL_CTX, if set.
     374           0 :   if (auto sslctx_cb = config.sslctxCb(); sslctx_cb) {
     375           0 :     for (TlsContext& ctx : tls_contexts_) {
     376           0 :       sslctx_cb(ctx.ssl_ctx_.get());
     377           0 :     }
     378           0 :   }
     379             : 
     380           0 :   if (!config.tlsKeyLogPath().empty()) {
     381           0 :     ENVOY_LOG(debug, "Enable tls key log");
     382           0 :     tls_keylog_file_ = config.accessLogManager().createAccessLog(
     383           0 :         Filesystem::FilePathAndType{Filesystem::DestinationType::File, config.tlsKeyLogPath()});
     384           0 :     for (auto& context : tls_contexts_) {
     385           0 :       SSL_CTX* ctx = context.ssl_ctx_.get();
     386           0 :       ASSERT(ctx != nullptr);
     387           0 :       SSL_CTX_set_keylog_callback(ctx, keylogCallback);
     388           0 :     }
     389           0 :   }
     390           0 : }
     391             : 
     392           0 : void ContextImpl::keylogCallback(const SSL* ssl, const char* line) {
     393           0 :   ASSERT(ssl != nullptr);
     394           0 :   auto callbacks =
     395           0 :       static_cast<Network::TransportSocketCallbacks*>(SSL_get_ex_data(ssl, sslSocketIndex()));
     396           0 :   auto ctx = static_cast<ContextImpl*>(SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
     397           0 :   ASSERT(callbacks != nullptr);
     398           0 :   ASSERT(ctx != nullptr);
     399             : 
     400           0 :   if ((ctx->tls_keylog_local_.getIpListSize() == 0 ||
     401           0 :        ctx->tls_keylog_local_.contains(
     402           0 :            *(callbacks->connection().connectionInfoProvider().localAddress()))) &&
     403           0 :       (ctx->tls_keylog_remote_.getIpListSize() == 0 ||
     404           0 :        ctx->tls_keylog_remote_.contains(
     405           0 :            *(callbacks->connection().connectionInfoProvider().remoteAddress())))) {
     406           0 :     ctx->tls_keylog_file_->write(absl::StrCat(line, "\n"));
     407           0 :   }
     408           0 : }
     409             : 
     410           0 : int ContextImpl::sslSocketIndex() {
     411           0 :   CONSTRUCT_ON_FIRST_USE(int, []() -> int {
     412           0 :     int ssl_socket_index = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
     413           0 :     RELEASE_ASSERT(ssl_socket_index >= 0, "");
     414           0 :     return ssl_socket_index;
     415           0 :   }());
     416           0 : }
     417             : 
     418             : int ServerContextImpl::alpnSelectCallback(const unsigned char** out, unsigned char* outlen,
     419           0 :                                           const unsigned char* in, unsigned int inlen) {
     420             :   // Currently this uses the standard selection algorithm in priority order.
     421           0 :   const uint8_t* alpn_data = parsed_alpn_protocols_.data();
     422           0 :   size_t alpn_data_size = parsed_alpn_protocols_.size();
     423             : 
     424           0 :   if (SSL_select_next_proto(const_cast<unsigned char**>(out), outlen, alpn_data, alpn_data_size, in,
     425           0 :                             inlen) != OPENSSL_NPN_NEGOTIATED) {
     426           0 :     return SSL_TLSEXT_ERR_NOACK;
     427           0 :   } else {
     428           0 :     return SSL_TLSEXT_ERR_OK;
     429           0 :   }
     430           0 : }
     431             : 
     432           0 : std::vector<uint8_t> ContextImpl::parseAlpnProtocols(const std::string& alpn_protocols) {
     433           0 :   if (alpn_protocols.empty()) {
     434           0 :     return {};
     435           0 :   }
     436             : 
     437           0 :   if (alpn_protocols.size() >= 65535) {
     438           0 :     throwEnvoyExceptionOrPanic("Invalid ALPN protocol string");
     439           0 :   }
     440             : 
     441           0 :   std::vector<uint8_t> out(alpn_protocols.size() + 1);
     442           0 :   size_t start = 0;
     443           0 :   for (size_t i = 0; i <= alpn_protocols.size(); i++) {
     444           0 :     if (i == alpn_protocols.size() || alpn_protocols[i] == ',') {
     445           0 :       if (i - start > 255) {
     446           0 :         throwEnvoyExceptionOrPanic("Invalid ALPN protocol string");
     447           0 :       }
     448             : 
     449           0 :       out[start] = i - start;
     450           0 :       start = i + 1;
     451           0 :     } else {
     452           0 :       out[i + 1] = alpn_protocols[i];
     453           0 :     }
     454           0 :   }
     455             : 
     456           0 :   return out;
     457           0 : }
     458             : 
     459             : bssl::UniquePtr<SSL>
     460           0 : ContextImpl::newSsl(const Network::TransportSocketOptionsConstSharedPtr& options) {
     461             :   // We use the first certificate for a new SSL object, later in the
     462             :   // SSL_CTX_set_select_certificate_cb() callback following ClientHello, we replace with the
     463             :   // selected certificate via SSL_set_SSL_CTX().
     464           0 :   auto ssl_con = bssl::UniquePtr<SSL>(SSL_new(tls_contexts_[0].ssl_ctx_.get()));
     465           0 :   SSL_set_app_data(ssl_con.get(), &options);
     466           0 :   return ssl_con;
     467           0 : }
     468             : 
     469           0 : enum ssl_verify_result_t ContextImpl::customVerifyCallback(SSL* ssl, uint8_t* out_alert) {
     470           0 :   auto* extended_socket_info = reinterpret_cast<Envoy::Ssl::SslExtendedSocketInfo*>(
     471           0 :       SSL_get_ex_data(ssl, ContextImpl::sslExtendedSocketInfoIndex()));
     472           0 :   if (extended_socket_info->certificateValidationResult() != Ssl::ValidateStatus::NotStarted) {
     473           0 :     if (extended_socket_info->certificateValidationResult() == Ssl::ValidateStatus::Pending) {
     474           0 :       return ssl_verify_retry;
     475           0 :     }
     476           0 :     ENVOY_LOG(trace, "Already has a result: {}",
     477           0 :               static_cast<int>(extended_socket_info->certificateValidationStatus()));
     478             :     // Already has a binary result, return immediately.
     479           0 :     *out_alert = extended_socket_info->certificateValidationAlert();
     480           0 :     return extended_socket_info->certificateValidationResult() == Ssl::ValidateStatus::Successful
     481           0 :                ? ssl_verify_ok
     482           0 :                : ssl_verify_invalid;
     483           0 :   }
     484             :   // Hasn't kicked off any validation for this connection yet.
     485           0 :   SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
     486           0 :   ContextImpl* context_impl = static_cast<ContextImpl*>(SSL_CTX_get_app_data(ssl_ctx));
     487           0 :   auto transport_socket_options_shared_ptr_ptr =
     488           0 :       static_cast<const Network::TransportSocketOptionsConstSharedPtr*>(SSL_get_app_data(ssl));
     489           0 :   ASSERT(transport_socket_options_shared_ptr_ptr);
     490           0 :   ValidationResults result = context_impl->customVerifyCertChain(
     491           0 :       extended_socket_info, *transport_socket_options_shared_ptr_ptr, ssl);
     492           0 :   switch (result.status) {
     493           0 :   case ValidationResults::ValidationStatus::Successful:
     494           0 :     return ssl_verify_ok;
     495           0 :   case ValidationResults::ValidationStatus::Pending:
     496           0 :     return ssl_verify_retry;
     497           0 :   case ValidationResults::ValidationStatus::Failed: {
     498           0 :     if (result.tls_alert.has_value() && out_alert) {
     499           0 :       *out_alert = result.tls_alert.value();
     500           0 :     }
     501           0 :     return ssl_verify_invalid;
     502           0 :   }
     503           0 :   }
     504           0 :   PANIC("not reached");
     505           0 : }
     506             : 
     507             : ValidationResults ContextImpl::customVerifyCertChain(
     508             :     Envoy::Ssl::SslExtendedSocketInfo* extended_socket_info,
     509           0 :     const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options, SSL* ssl) {
     510           0 :   ASSERT(extended_socket_info);
     511           0 :   STACK_OF(X509)* cert_chain = SSL_get_peer_full_cert_chain(ssl);
     512           0 :   if (cert_chain == nullptr) {
     513           0 :     extended_socket_info->setCertificateValidationStatus(Ssl::ClientValidationStatus::NotValidated);
     514           0 :     stats_.fail_verify_error_.inc();
     515           0 :     ENVOY_LOG(debug, "verify cert failed: no cert chain");
     516           0 :     return {ValidationResults::ValidationStatus::Failed, Ssl::ClientValidationStatus::NotValidated,
     517           0 :             SSL_AD_INTERNAL_ERROR, absl::nullopt};
     518           0 :   }
     519           0 :   ASSERT(cert_validator_);
     520           0 :   const char* host_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
     521             : 
     522           0 :   CertValidator::ExtraValidationContext validation_ctx;
     523           0 :   validation_ctx.callbacks =
     524           0 :       static_cast<Network::TransportSocketCallbacks*>(SSL_get_ex_data(ssl, sslSocketIndex()));
     525             : 
     526           0 :   ValidationResults result = cert_validator_->doVerifyCertChain(
     527           0 :       *cert_chain, extended_socket_info->createValidateResultCallback(), transport_socket_options,
     528           0 :       *SSL_get_SSL_CTX(ssl), validation_ctx, SSL_is_server(ssl),
     529           0 :       absl::NullSafeStringView(host_name));
     530           0 :   if (result.status != ValidationResults::ValidationStatus::Pending) {
     531           0 :     extended_socket_info->setCertificateValidationStatus(result.detailed_status);
     532           0 :     extended_socket_info->onCertificateValidationCompleted(
     533           0 :         result.status == ValidationResults::ValidationStatus::Successful, false);
     534           0 :   }
     535           0 :   return result;
     536           0 : }
     537             : 
     538             : void ContextImpl::incCounter(const Stats::StatName name, absl::string_view value,
     539           0 :                              const Stats::StatName fallback) const {
     540           0 :   const Stats::StatName value_stat_name = stat_name_set_->getBuiltin(value, fallback);
     541           0 :   ENVOY_BUG(value_stat_name != fallback,
     542           0 :             absl::StrCat("Unexpected ", scope_.symbolTable().toString(name), " value: ", value));
     543           0 :   Stats::Utility::counterFromElements(scope_, {name, value_stat_name}).inc();
     544           0 : }
     545             : 
     546           0 : void ContextImpl::logHandshake(SSL* ssl) const {
     547           0 :   stats_.handshake_.inc();
     548             : 
     549           0 :   if (SSL_session_reused(ssl)) {
     550           0 :     stats_.session_reused_.inc();
     551           0 :   }
     552             : 
     553           0 :   incCounter(ssl_ciphers_, SSL_get_cipher_name(ssl), unknown_ssl_cipher_);
     554           0 :   incCounter(ssl_versions_, SSL_get_version(ssl), unknown_ssl_version_);
     555             : 
     556           0 :   const uint16_t curve_id = SSL_get_curve_id(ssl);
     557           0 :   if (curve_id) {
     558           0 :     incCounter(ssl_curves_, SSL_get_curve_name(curve_id), unknown_ssl_curve_);
     559           0 :   }
     560             : 
     561           0 :   const uint16_t sigalg_id = SSL_get_peer_signature_algorithm(ssl);
     562           0 :   if (sigalg_id) {
     563           0 :     const char* sigalg = SSL_get_signature_algorithm_name(sigalg_id, 1 /* include curve */);
     564           0 :     incCounter(ssl_sigalgs_, sigalg, unknown_ssl_algorithm_);
     565           0 :   }
     566             : 
     567           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl));
     568           0 :   if (!cert.get()) {
     569           0 :     stats_.no_certificate_.inc();
     570           0 :   }
     571             : 
     572             : #if defined(BORINGSSL_FIPS) && BORINGSSL_API_VERSION >= 18
     573             : #error "Delete preprocessor check below; no longer needed"
     574             : #endif
     575             : 
     576           0 : #if BORINGSSL_API_VERSION >= 18
     577             :   // Increment the `was_key_usage_invalid_` stats to indicate the given cert would have triggered an
     578             :   // error but is allowed because the enforcement that rsa key usage and tls usage need to be
     579             :   // matched has been disabled.
     580           0 :   if (SSL_was_key_usage_invalid(ssl)) {
     581           0 :     stats_.was_key_usage_invalid_.inc();
     582           0 :   }
     583           0 : #endif // BORINGSSL_API_VERSION
     584           0 : }
     585             : 
     586           0 : std::vector<Ssl::PrivateKeyMethodProviderSharedPtr> ContextImpl::getPrivateKeyMethodProviders() {
     587           0 :   std::vector<Envoy::Ssl::PrivateKeyMethodProviderSharedPtr> providers;
     588             : 
     589           0 :   for (auto& tls_context : tls_contexts_) {
     590           0 :     Envoy::Ssl::PrivateKeyMethodProviderSharedPtr provider =
     591           0 :         tls_context.getPrivateKeyMethodProvider();
     592           0 :     if (provider) {
     593           0 :       providers.push_back(provider);
     594           0 :     }
     595           0 :   }
     596           0 :   return providers;
     597           0 : }
     598             : 
     599           0 : absl::optional<uint32_t> ContextImpl::daysUntilFirstCertExpires() const {
     600           0 :   absl::optional<uint32_t> daysUntilExpiration = cert_validator_->daysUntilFirstCertExpires();
     601           0 :   if (!daysUntilExpiration.has_value()) {
     602           0 :     return absl::nullopt;
     603           0 :   }
     604           0 :   for (auto& ctx : tls_contexts_) {
     605           0 :     const absl::optional<uint32_t> tmp =
     606           0 :         Utility::getDaysUntilExpiration(ctx.cert_chain_.get(), time_source_);
     607           0 :     if (!tmp.has_value()) {
     608           0 :       return absl::nullopt;
     609           0 :     }
     610           0 :     daysUntilExpiration = std::min<uint32_t>(tmp.value(), daysUntilExpiration.value());
     611           0 :   }
     612           0 :   return daysUntilExpiration;
     613           0 : }
     614             : 
     615           0 : absl::optional<uint64_t> ContextImpl::secondsUntilFirstOcspResponseExpires() const {
     616           0 :   absl::optional<uint64_t> secs_until_expiration;
     617           0 :   for (auto& ctx : tls_contexts_) {
     618           0 :     if (ctx.ocsp_response_) {
     619           0 :       uint64_t next_expiration = ctx.ocsp_response_->secondsUntilExpiration();
     620           0 :       secs_until_expiration = std::min<uint64_t>(
     621           0 :           next_expiration, secs_until_expiration.value_or(std::numeric_limits<uint64_t>::max()));
     622           0 :     }
     623           0 :   }
     624             : 
     625           0 :   return secs_until_expiration;
     626           0 : }
     627             : 
     628           0 : Envoy::Ssl::CertificateDetailsPtr ContextImpl::getCaCertInformation() const {
     629           0 :   return cert_validator_->getCaCertInformation();
     630           0 : }
     631             : 
     632           0 : std::vector<Envoy::Ssl::CertificateDetailsPtr> ContextImpl::getCertChainInformation() const {
     633           0 :   std::vector<Envoy::Ssl::CertificateDetailsPtr> cert_details;
     634           0 :   for (const auto& ctx : tls_contexts_) {
     635           0 :     if (ctx.cert_chain_ == nullptr) {
     636           0 :       continue;
     637           0 :     }
     638             : 
     639           0 :     auto detail = Utility::certificateDetails(ctx.cert_chain_.get(), ctx.getCertChainFileName(),
     640           0 :                                               time_source_);
     641           0 :     auto ocsp_resp = ctx.ocsp_response_.get();
     642           0 :     if (ocsp_resp) {
     643           0 :       auto* ocsp_details = detail->mutable_ocsp_details();
     644           0 :       ProtobufWkt::Timestamp* valid_from = ocsp_details->mutable_valid_from();
     645           0 :       TimestampUtil::systemClockToTimestamp(ocsp_resp->getThisUpdate(), *valid_from);
     646           0 :       ProtobufWkt::Timestamp* expiration = ocsp_details->mutable_expiration();
     647           0 :       TimestampUtil::systemClockToTimestamp(ocsp_resp->getNextUpdate(), *expiration);
     648           0 :     }
     649           0 :     cert_details.push_back(std::move(detail));
     650           0 :   }
     651           0 :   return cert_details;
     652           0 : }
     653             : 
     654             : ClientContextImpl::ClientContextImpl(Stats::Scope& scope,
     655             :                                      const Envoy::Ssl::ClientContextConfig& config,
     656             :                                      TimeSource& time_source)
     657             :     : ContextImpl(scope, config, time_source),
     658             :       server_name_indication_(config.serverNameIndication()),
     659             :       allow_renegotiation_(config.allowRenegotiation()),
     660             :       enforce_rsa_key_usage_(config.enforceRsaKeyUsage()),
     661           0 :       max_session_keys_(config.maxSessionKeys()) {
     662             :   // This should be guaranteed during configuration ingestion for client contexts.
     663           0 :   ASSERT(tls_contexts_.size() == 1);
     664           0 :   if (!parsed_alpn_protocols_.empty()) {
     665           0 :     for (auto& ctx : tls_contexts_) {
     666           0 :       const int rc = SSL_CTX_set_alpn_protos(ctx.ssl_ctx_.get(), parsed_alpn_protocols_.data(),
     667           0 :                                              parsed_alpn_protocols_.size());
     668           0 :       RELEASE_ASSERT(rc == 0, Utility::getLastCryptoError().value_or(""));
     669           0 :     }
     670           0 :   }
     671             : 
     672           0 :   if (max_session_keys_ > 0) {
     673           0 :     SSL_CTX_set_session_cache_mode(tls_contexts_[0].ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT);
     674           0 :     SSL_CTX_sess_set_new_cb(
     675           0 :         tls_contexts_[0].ssl_ctx_.get(), [](SSL* ssl, SSL_SESSION* session) -> int {
     676           0 :           ContextImpl* context_impl =
     677           0 :               static_cast<ContextImpl*>(SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
     678           0 :           ClientContextImpl* client_context_impl = dynamic_cast<ClientContextImpl*>(context_impl);
     679           0 :           RELEASE_ASSERT(client_context_impl != nullptr, ""); // for Coverity
     680           0 :           return client_context_impl->newSessionKey(session);
     681           0 :         });
     682           0 :   }
     683           0 : }
     684             : 
     685           0 : bool ContextImpl::parseAndSetAlpn(const std::vector<std::string>& alpn, SSL& ssl) {
     686           0 :   std::vector<uint8_t> parsed_alpn = parseAlpnProtocols(absl::StrJoin(alpn, ","));
     687           0 :   if (!parsed_alpn.empty()) {
     688           0 :     const int rc = SSL_set_alpn_protos(&ssl, parsed_alpn.data(), parsed_alpn.size());
     689             :     // This should only if memory allocation fails, e.g. OOM.
     690           0 :     RELEASE_ASSERT(rc == 0, Utility::getLastCryptoError().value_or(""));
     691           0 :     return true;
     692           0 :   }
     693             : 
     694           0 :   return false;
     695           0 : }
     696             : 
     697             : bssl::UniquePtr<SSL>
     698           0 : ClientContextImpl::newSsl(const Network::TransportSocketOptionsConstSharedPtr& options) {
     699           0 :   bssl::UniquePtr<SSL> ssl_con(ContextImpl::newSsl(options));
     700             : 
     701           0 :   const std::string server_name_indication = options && options->serverNameOverride().has_value()
     702           0 :                                                  ? options->serverNameOverride().value()
     703           0 :                                                  : server_name_indication_;
     704           0 :   if (!server_name_indication.empty()) {
     705           0 :     const int rc = SSL_set_tlsext_host_name(ssl_con.get(), server_name_indication.c_str());
     706           0 :     RELEASE_ASSERT(rc, Utility::getLastCryptoError().value_or(""));
     707           0 :   }
     708             : 
     709           0 :   if (options && !options->verifySubjectAltNameListOverride().empty()) {
     710           0 :     SSL_set_verify(ssl_con.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
     711           0 :   }
     712             : 
     713             :   // We determine what ALPN using the following precedence:
     714             :   // 1. Option-provided ALPN override.
     715             :   // 2. ALPN statically configured in the upstream TLS context.
     716             :   // 3. Option-provided ALPN fallback.
     717             : 
     718             :   // At this point in the code the ALPN has already been set (if present) to the value specified in
     719             :   // the TLS context. We've stored this value in parsed_alpn_protocols_ so we can check that to see
     720             :   // if it's already been set.
     721           0 :   bool has_alpn_defined = !parsed_alpn_protocols_.empty();
     722           0 :   if (options) {
     723             :     // ALPN override takes precedence over TLS context specified, so blindly overwrite it.
     724           0 :     has_alpn_defined |= parseAndSetAlpn(options->applicationProtocolListOverride(), *ssl_con);
     725           0 :   }
     726             : 
     727           0 :   if (options && !has_alpn_defined && !options->applicationProtocolFallback().empty()) {
     728             :     // If ALPN hasn't already been set (either through TLS context or override), use the fallback.
     729           0 :     parseAndSetAlpn(options->applicationProtocolFallback(), *ssl_con);
     730           0 :   }
     731             : 
     732           0 :   if (allow_renegotiation_) {
     733           0 :     SSL_set_renegotiate_mode(ssl_con.get(), ssl_renegotiate_freely);
     734           0 :   }
     735             : 
     736           0 :   SSL_set_enforce_rsa_key_usage(ssl_con.get(), enforce_rsa_key_usage_);
     737             : 
     738           0 :   if (max_session_keys_ > 0) {
     739           0 :     if (session_keys_single_use_) {
     740             :       // Stored single-use session keys, use write/write locks.
     741           0 :       absl::WriterMutexLock l(&session_keys_mu_);
     742           0 :       if (!session_keys_.empty()) {
     743             :         // Use the most recently stored session key, since it has the highest
     744             :         // probability of still being recognized/accepted by the server.
     745           0 :         SSL_SESSION* session = session_keys_.front().get();
     746           0 :         SSL_set_session(ssl_con.get(), session);
     747             :         // Remove single-use session key (TLS 1.3) after first use.
     748           0 :         if (SSL_SESSION_should_be_single_use(session)) {
     749           0 :           session_keys_.pop_front();
     750           0 :         }
     751           0 :       }
     752           0 :     } else {
     753             :       // Never stored single-use session keys, use read/write locks.
     754           0 :       absl::ReaderMutexLock l(&session_keys_mu_);
     755           0 :       if (!session_keys_.empty()) {
     756             :         // Use the most recently stored session key, since it has the highest
     757             :         // probability of still being recognized/accepted by the server.
     758           0 :         SSL_SESSION* session = session_keys_.front().get();
     759           0 :         SSL_set_session(ssl_con.get(), session);
     760           0 :       }
     761           0 :     }
     762           0 :   }
     763             : 
     764           0 :   return ssl_con;
     765           0 : }
     766             : 
     767           0 : int ClientContextImpl::newSessionKey(SSL_SESSION* session) {
     768             :   // In case we ever store single-use session key (TLS 1.3),
     769             :   // we need to switch to using write/write locks.
     770           0 :   if (SSL_SESSION_should_be_single_use(session)) {
     771           0 :     session_keys_single_use_ = true;
     772           0 :   }
     773           0 :   absl::WriterMutexLock l(&session_keys_mu_);
     774             :   // Evict oldest entries.
     775           0 :   while (session_keys_.size() >= max_session_keys_) {
     776           0 :     session_keys_.pop_back();
     777           0 :   }
     778             :   // Add new session key at the front of the queue, so that it's used first.
     779           0 :   session_keys_.push_front(bssl::UniquePtr<SSL_SESSION>(session));
     780           0 :   return 1; // Tell BoringSSL that we took ownership of the session.
     781           0 : }
     782             : 
     783             : ServerContextImpl::ServerContextImpl(Stats::Scope& scope,
     784             :                                      const Envoy::Ssl::ServerContextConfig& config,
     785             :                                      const std::vector<std::string>& server_names,
     786             :                                      TimeSource& time_source)
     787             :     : ContextImpl(scope, config, time_source), session_ticket_keys_(config.sessionTicketKeys()),
     788             :       ocsp_staple_policy_(config.ocspStaplePolicy()),
     789           0 :       full_scan_certs_on_sni_mismatch_(config.fullScanCertsOnSNIMismatch()) {
     790           0 :   if (config.tlsCertificates().empty() && !config.capabilities().provides_certificates) {
     791           0 :     throwEnvoyExceptionOrPanic("Server TlsCertificates must have a certificate specified");
     792           0 :   }
     793             : 
     794           0 :   for (auto& ctx : tls_contexts_) {
     795           0 :     if (ctx.cert_chain_ == nullptr) {
     796           0 :       continue;
     797           0 :     }
     798           0 :     bssl::UniquePtr<EVP_PKEY> public_key(X509_get_pubkey(ctx.cert_chain_.get()));
     799           0 :     const int pkey_id = EVP_PKEY_id(public_key.get());
     800             :     // Load DNS SAN entries and Subject Common Name as server name patterns after certificate
     801             :     // chain loaded, and populate ServerNamesMap which will be used to match SNI.
     802           0 :     has_rsa_ |= (pkey_id == EVP_PKEY_RSA);
     803           0 :     populateServerNamesMap(ctx, pkey_id);
     804           0 :   }
     805             : 
     806             :   // Compute the session context ID hash. We use all the certificate identities,
     807             :   // since we should have a common ID for session resumption no matter what cert
     808             :   // is used. We do this early because it can throw an EnvoyException.
     809           0 :   const SessionContextID session_id = generateHashForSessionContextId(server_names);
     810             : 
     811             :   // First, configure the base context for ClientHello interception.
     812             :   // TODO(htuch): replace with SSL_IDENTITY when we have this as a means to do multi-cert in
     813             :   // BoringSSL.
     814           0 :   if (!config.capabilities().provides_certificates) {
     815           0 :     SSL_CTX_set_select_certificate_cb(
     816           0 :         tls_contexts_[0].ssl_ctx_.get(),
     817           0 :         [](const SSL_CLIENT_HELLO* client_hello) -> ssl_select_cert_result_t {
     818           0 :           return static_cast<ServerContextImpl*>(
     819           0 :                      SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)))
     820           0 :               ->selectTlsContext(client_hello);
     821           0 :         });
     822           0 :   }
     823             : 
     824           0 :   const auto tls_certificates = config.tlsCertificates();
     825             : 
     826           0 :   for (uint32_t i = 0; i < tls_certificates.size(); ++i) {
     827           0 :     auto& ctx = tls_contexts_[i];
     828           0 :     if (!config.capabilities().verifies_peer_certificates) {
     829           0 :       cert_validator_->addClientValidationContext(ctx.ssl_ctx_.get(),
     830           0 :                                                   config.requireClientCertificate());
     831           0 :     }
     832             : 
     833           0 :     if (!parsed_alpn_protocols_.empty() && !config.capabilities().handles_alpn_selection) {
     834           0 :       SSL_CTX_set_alpn_select_cb(
     835           0 :           ctx.ssl_ctx_.get(),
     836           0 :           [](SSL*, const unsigned char** out, unsigned char* outlen, const unsigned char* in,
     837           0 :              unsigned int inlen, void* arg) -> int {
     838           0 :             return static_cast<ServerContextImpl*>(arg)->alpnSelectCallback(out, outlen, in, inlen);
     839           0 :           },
     840           0 :           this);
     841           0 :     }
     842             : 
     843             :     // If the handshaker handles session tickets natively, don't call
     844             :     // `SSL_CTX_set_tlsext_ticket_key_cb`.
     845           0 :     if (config.disableStatelessSessionResumption()) {
     846           0 :       SSL_CTX_set_options(ctx.ssl_ctx_.get(), SSL_OP_NO_TICKET);
     847           0 :     } else if (!session_ticket_keys_.empty() && !config.capabilities().handles_session_resumption) {
     848           0 :       SSL_CTX_set_tlsext_ticket_key_cb(
     849           0 :           ctx.ssl_ctx_.get(),
     850           0 :           [](SSL* ssl, uint8_t* key_name, uint8_t* iv, EVP_CIPHER_CTX* ctx, HMAC_CTX* hmac_ctx,
     851           0 :              int encrypt) -> int {
     852           0 :             ContextImpl* context_impl =
     853           0 :                 static_cast<ContextImpl*>(SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
     854           0 :             ServerContextImpl* server_context_impl = dynamic_cast<ServerContextImpl*>(context_impl);
     855           0 :             RELEASE_ASSERT(server_context_impl != nullptr, ""); // for Coverity
     856           0 :             return server_context_impl->sessionTicketProcess(ssl, key_name, iv, ctx, hmac_ctx,
     857           0 :                                                              encrypt);
     858           0 :           });
     859           0 :     }
     860             : 
     861           0 :     if (config.disableStatefulSessionResumption()) {
     862           0 :       SSL_CTX_set_session_cache_mode(ctx.ssl_ctx_.get(), SSL_SESS_CACHE_OFF);
     863           0 :     }
     864             : 
     865           0 :     if (config.sessionTimeout() && !config.capabilities().handles_session_resumption) {
     866           0 :       auto timeout = config.sessionTimeout().value().count();
     867           0 :       SSL_CTX_set_timeout(ctx.ssl_ctx_.get(), uint32_t(timeout));
     868           0 :     }
     869             : 
     870           0 :     int rc =
     871           0 :         SSL_CTX_set_session_id_context(ctx.ssl_ctx_.get(), session_id.data(), session_id.size());
     872           0 :     RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
     873             : 
     874           0 :     auto& ocsp_resp_bytes = tls_certificates[i].get().ocspStaple();
     875           0 :     if (ocsp_resp_bytes.empty()) {
     876           0 :       if (ctx.is_must_staple_) {
     877           0 :         throwEnvoyExceptionOrPanic("OCSP response is required for must-staple certificate");
     878           0 :       }
     879           0 :       if (ocsp_staple_policy_ == Ssl::ServerContextConfig::OcspStaplePolicy::MustStaple) {
     880           0 :         throwEnvoyExceptionOrPanic("Required OCSP response is missing from TLS context");
     881           0 :       }
     882           0 :     } else {
     883           0 :       auto response = std::make_unique<Ocsp::OcspResponseWrapper>(ocsp_resp_bytes, time_source_);
     884           0 :       if (!response->matchesCertificate(*ctx.cert_chain_)) {
     885           0 :         throwEnvoyExceptionOrPanic("OCSP response does not match its TLS certificate");
     886           0 :       }
     887           0 :       ctx.ocsp_response_ = std::move(response);
     888           0 :     }
     889           0 :   }
     890           0 : }
     891             : 
     892           0 : void ServerContextImpl::populateServerNamesMap(TlsContext& ctx, int pkey_id) {
     893           0 :   if (ctx.cert_chain_ == nullptr) {
     894           0 :     return;
     895           0 :   }
     896             : 
     897           0 :   auto populate = [&](const std::string& sn) {
     898           0 :     std::string sn_pattern = sn;
     899           0 :     if (absl::StartsWith(sn, "*.")) {
     900           0 :       sn_pattern = sn.substr(1);
     901           0 :     }
     902           0 :     PkeyTypesMap pkey_types_map;
     903             :     // Multiple certs with different key type are allowed for one server name pattern.
     904           0 :     auto sn_match = server_names_map_.try_emplace(sn_pattern, pkey_types_map).first;
     905           0 :     auto pt_match = sn_match->second.find(pkey_id);
     906           0 :     if (pt_match != sn_match->second.end()) {
     907             :       // When there are duplicate names, prefer the earlier one.
     908             :       //
     909             :       // If all of the SANs in a certificate are unused due to duplicates, it could be useful
     910             :       // to issue a warning, but that would require additional tracking that hasn't been
     911             :       // implemented.
     912           0 :       return;
     913           0 :     }
     914           0 :     sn_match->second.emplace(std::pair<int, std::reference_wrapper<TlsContext>>(pkey_id, ctx));
     915           0 :   };
     916             : 
     917           0 :   bssl::UniquePtr<GENERAL_NAMES> san_names(static_cast<GENERAL_NAMES*>(
     918           0 :       X509_get_ext_d2i(ctx.cert_chain_.get(), NID_subject_alt_name, nullptr, nullptr)));
     919           0 :   if (san_names != nullptr) {
     920           0 :     auto dns_sans = Utility::getSubjectAltNames(*ctx.cert_chain_, GEN_DNS);
     921             :     // https://www.rfc-editor.org/rfc/rfc6066#section-3
     922             :     // Currently, the only server names supported are DNS hostnames, so we
     923             :     // only save dns san entries to match SNI.
     924           0 :     for (const auto& san : dns_sans) {
     925           0 :       populate(san);
     926           0 :     }
     927           0 :   } else {
     928             :     // https://www.rfc-editor.org/rfc/rfc6125#section-6.4.4
     929             :     // As noted, a client MUST NOT seek a match for a reference identifier
     930             :     // of CN-ID if the presented identifiers include a DNS-ID, SRV-ID,
     931             :     // URI-ID, or any application-specific identifier types supported by the
     932             :     // client.
     933           0 :     X509_NAME* cert_subject = X509_get_subject_name(ctx.cert_chain_.get());
     934           0 :     const int cn_index = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, -1);
     935           0 :     if (cn_index >= 0) {
     936           0 :       X509_NAME_ENTRY* cn_entry = X509_NAME_get_entry(cert_subject, cn_index);
     937           0 :       if (cn_entry) {
     938           0 :         ASN1_STRING* cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry);
     939           0 :         if (ASN1_STRING_length(cn_asn1) > 0) {
     940           0 :           std::string subject_cn(reinterpret_cast<const char*>(ASN1_STRING_data(cn_asn1)),
     941           0 :                                  ASN1_STRING_length(cn_asn1));
     942           0 :           populate(subject_cn);
     943           0 :         }
     944           0 :       }
     945           0 :     }
     946           0 :   }
     947           0 : }
     948             : 
     949             : ServerContextImpl::SessionContextID
     950           0 : ServerContextImpl::generateHashForSessionContextId(const std::vector<std::string>& server_names) {
     951           0 :   uint8_t hash_buffer[EVP_MAX_MD_SIZE];
     952           0 :   unsigned hash_length = 0;
     953             : 
     954           0 :   bssl::ScopedEVP_MD_CTX md;
     955             : 
     956           0 :   int rc = EVP_DigestInit(md.get(), EVP_sha256());
     957           0 :   RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
     958             : 
     959             :   // Hash the CommonName/SANs of all the server certificates. This makes sure that sessions can only
     960             :   // be resumed to certificate(s) for the same name(s), but allows resuming to unique certs in the
     961             :   // case that different Envoy instances each have their own certs. All certificates in a
     962             :   // ServerContextImpl context are hashed together, since they all constitute a match on a filter
     963             :   // chain for resumption purposes.
     964           0 :   if (!capabilities_.provides_certificates) {
     965           0 :     for (const auto& ctx : tls_contexts_) {
     966           0 :       X509* cert = SSL_CTX_get0_certificate(ctx.ssl_ctx_.get());
     967           0 :       RELEASE_ASSERT(cert != nullptr, "TLS context should have an active certificate");
     968           0 :       X509_NAME* cert_subject = X509_get_subject_name(cert);
     969           0 :       RELEASE_ASSERT(cert_subject != nullptr, "TLS certificate should have a subject");
     970             : 
     971           0 :       const int cn_index = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, -1);
     972           0 :       if (cn_index >= 0) {
     973           0 :         X509_NAME_ENTRY* cn_entry = X509_NAME_get_entry(cert_subject, cn_index);
     974           0 :         RELEASE_ASSERT(cn_entry != nullptr, "certificate subject CN should be present");
     975             : 
     976           0 :         ASN1_STRING* cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry);
     977           0 :         if (ASN1_STRING_length(cn_asn1) <= 0) {
     978           0 :           throwEnvoyExceptionOrPanic("Invalid TLS context has an empty subject CN");
     979           0 :         }
     980             : 
     981           0 :         rc = EVP_DigestUpdate(md.get(), ASN1_STRING_data(cn_asn1), ASN1_STRING_length(cn_asn1));
     982           0 :         RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
     983           0 :       }
     984             : 
     985           0 :       unsigned san_count = 0;
     986           0 :       bssl::UniquePtr<GENERAL_NAMES> san_names(static_cast<GENERAL_NAMES*>(
     987           0 :           X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr)));
     988             : 
     989           0 :       if (san_names != nullptr) {
     990           0 :         for (const GENERAL_NAME* san : san_names.get()) {
     991           0 :           switch (san->type) {
     992           0 :           case GEN_IPADD:
     993           0 :             rc = EVP_DigestUpdate(md.get(), san->d.iPAddress->data, san->d.iPAddress->length);
     994           0 :             RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
     995           0 :             ++san_count;
     996           0 :             break;
     997           0 :           case GEN_DNS:
     998           0 :             rc = EVP_DigestUpdate(md.get(), ASN1_STRING_data(san->d.dNSName),
     999           0 :                                   ASN1_STRING_length(san->d.dNSName));
    1000           0 :             RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
    1001           0 :             ++san_count;
    1002           0 :             break;
    1003           0 :           case GEN_URI:
    1004           0 :             rc = EVP_DigestUpdate(md.get(), ASN1_STRING_data(san->d.uniformResourceIdentifier),
    1005           0 :                                   ASN1_STRING_length(san->d.uniformResourceIdentifier));
    1006           0 :             RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
    1007           0 :             ++san_count;
    1008           0 :             break;
    1009           0 :           }
    1010           0 :         }
    1011           0 :       }
    1012             : 
    1013             :       // It's possible that the certificate doesn't have a subject, but
    1014             :       // does have SANs. Make sure that we have one or the other.
    1015           0 :       if (cn_index < 0 && san_count == 0) {
    1016           0 :         throwEnvoyExceptionOrPanic("Invalid TLS context has neither subject CN nor SAN names");
    1017           0 :       }
    1018             : 
    1019           0 :       rc = X509_NAME_digest(X509_get_issuer_name(cert), EVP_sha256(), hash_buffer, &hash_length);
    1020           0 :       RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
    1021           0 :       RELEASE_ASSERT(hash_length == SHA256_DIGEST_LENGTH,
    1022           0 :                      fmt::format("invalid SHA256 hash length {}", hash_length));
    1023             : 
    1024           0 :       rc = EVP_DigestUpdate(md.get(), hash_buffer, hash_length);
    1025           0 :       RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
    1026           0 :     }
    1027           0 :   }
    1028             : 
    1029           0 :   cert_validator_->updateDigestForSessionId(md, hash_buffer, hash_length);
    1030             : 
    1031             :   // Hash configured SNIs for this context, so that sessions cannot be resumed across different
    1032             :   // filter chains, even when using the same server certificate.
    1033           0 :   for (const auto& name : server_names) {
    1034           0 :     rc = EVP_DigestUpdate(md.get(), name.data(), name.size());
    1035           0 :     RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
    1036           0 :   }
    1037             : 
    1038           0 :   SessionContextID session_id;
    1039             : 
    1040             :   // Ensure that the output size of the hash we are using is no greater than
    1041             :   // TLS session ID length that we want to generate.
    1042           0 :   static_assert(session_id.size() == SHA256_DIGEST_LENGTH, "hash size mismatch");
    1043           0 :   static_assert(session_id.size() == SSL_MAX_SSL_SESSION_ID_LENGTH, "TLS session ID size mismatch");
    1044             : 
    1045           0 :   rc = EVP_DigestFinal(md.get(), session_id.data(), &hash_length);
    1046           0 :   RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
    1047           0 :   RELEASE_ASSERT(hash_length == session_id.size(),
    1048           0 :                  "SHA256 hash length must match TLS Session ID size");
    1049             : 
    1050           0 :   return session_id;
    1051           0 : }
    1052             : 
    1053             : int ServerContextImpl::sessionTicketProcess(SSL*, uint8_t* key_name, uint8_t* iv,
    1054           0 :                                             EVP_CIPHER_CTX* ctx, HMAC_CTX* hmac_ctx, int encrypt) {
    1055           0 :   const EVP_MD* hmac = EVP_sha256();
    1056           0 :   const EVP_CIPHER* cipher = EVP_aes_256_cbc();
    1057             : 
    1058           0 :   if (encrypt == 1) {
    1059             :     // Encrypt
    1060           0 :     RELEASE_ASSERT(!session_ticket_keys_.empty(), "");
    1061             :     // TODO(ggreenway): validate in SDS that session_ticket_keys_ cannot be empty,
    1062             :     // or if we allow it to be emptied, reconfigure the context so this callback
    1063             :     // isn't set.
    1064             : 
    1065           0 :     const Envoy::Ssl::ServerContextConfig::SessionTicketKey& key = session_ticket_keys_.front();
    1066             : 
    1067           0 :     static_assert(std::tuple_size<decltype(key.name_)>::value == SSL_TICKET_KEY_NAME_LEN,
    1068           0 :                   "Expected key.name length");
    1069           0 :     std::copy_n(key.name_.begin(), SSL_TICKET_KEY_NAME_LEN, key_name);
    1070             : 
    1071           0 :     const int rc = RAND_bytes(iv, EVP_CIPHER_iv_length(cipher));
    1072           0 :     ASSERT(rc);
    1073             : 
    1074             :     // This RELEASE_ASSERT is logically a static_assert, but we can't actually get
    1075             :     // EVP_CIPHER_key_length(cipher) at compile-time
    1076           0 :     RELEASE_ASSERT(key.aes_key_.size() == EVP_CIPHER_key_length(cipher), "");
    1077           0 :     if (!EVP_EncryptInit_ex(ctx, cipher, nullptr, key.aes_key_.data(), iv)) {
    1078           0 :       return -1;
    1079           0 :     }
    1080             : 
    1081           0 :     if (!HMAC_Init_ex(hmac_ctx, key.hmac_key_.data(), key.hmac_key_.size(), hmac, nullptr)) {
    1082           0 :       return -1;
    1083           0 :     }
    1084             : 
    1085           0 :     return 1; // success
    1086           0 :   } else {
    1087             :     // Decrypt
    1088           0 :     bool is_enc_key = true; // first element is the encryption key
    1089           0 :     for (const Envoy::Ssl::ServerContextConfig::SessionTicketKey& key : session_ticket_keys_) {
    1090           0 :       static_assert(std::tuple_size<decltype(key.name_)>::value == SSL_TICKET_KEY_NAME_LEN,
    1091           0 :                     "Expected key.name length");
    1092           0 :       if (std::equal(key.name_.begin(), key.name_.end(), key_name)) {
    1093           0 :         if (!HMAC_Init_ex(hmac_ctx, key.hmac_key_.data(), key.hmac_key_.size(), hmac, nullptr)) {
    1094           0 :           return -1;
    1095           0 :         }
    1096             : 
    1097           0 :         RELEASE_ASSERT(key.aes_key_.size() == EVP_CIPHER_key_length(cipher), "");
    1098           0 :         if (!EVP_DecryptInit_ex(ctx, cipher, nullptr, key.aes_key_.data(), iv)) {
    1099           0 :           return -1;
    1100           0 :         }
    1101             : 
    1102             :         // If our current encryption was not the decryption key, renew
    1103           0 :         return is_enc_key ? 1  // success; do not renew
    1104           0 :                           : 2; // success: renew key
    1105           0 :       }
    1106           0 :       is_enc_key = false;
    1107           0 :     }
    1108             : 
    1109           0 :     return 0; // decryption failed
    1110           0 :   }
    1111           0 : }
    1112             : 
    1113           0 : bool ServerContextImpl::isClientEcdsaCapable(const SSL_CLIENT_HELLO* ssl_client_hello) {
    1114           0 :   CBS client_hello;
    1115           0 :   CBS_init(&client_hello, ssl_client_hello->client_hello, ssl_client_hello->client_hello_len);
    1116             : 
    1117             :   // This is the TLSv1.3 case (TLSv1.2 on the wire and the supported_versions extensions present).
    1118             :   // We just need to look at signature algorithms.
    1119           0 :   const uint16_t client_version = ssl_client_hello->version;
    1120           0 :   if (client_version == TLS1_2_VERSION && tls_max_version_ == TLS1_3_VERSION) {
    1121             :     // If the supported_versions extension is found then we assume that the client is competent
    1122             :     // enough that just checking the signature_algorithms is sufficient.
    1123           0 :     const uint8_t* supported_versions_data;
    1124           0 :     size_t supported_versions_len;
    1125           0 :     if (SSL_early_callback_ctx_extension_get(ssl_client_hello, TLSEXT_TYPE_supported_versions,
    1126           0 :                                              &supported_versions_data, &supported_versions_len)) {
    1127           0 :       const uint8_t* signature_algorithms_data;
    1128           0 :       size_t signature_algorithms_len;
    1129           0 :       if (SSL_early_callback_ctx_extension_get(ssl_client_hello, TLSEXT_TYPE_signature_algorithms,
    1130           0 :                                                &signature_algorithms_data,
    1131           0 :                                                &signature_algorithms_len)) {
    1132           0 :         CBS signature_algorithms_ext, signature_algorithms;
    1133           0 :         CBS_init(&signature_algorithms_ext, signature_algorithms_data, signature_algorithms_len);
    1134           0 :         if (!CBS_get_u16_length_prefixed(&signature_algorithms_ext, &signature_algorithms) ||
    1135           0 :             CBS_len(&signature_algorithms_ext) != 0) {
    1136           0 :           return false;
    1137           0 :         }
    1138           0 :         if (cbsContainsU16(signature_algorithms, SSL_SIGN_ECDSA_SECP256R1_SHA256)) {
    1139           0 :           return true;
    1140           0 :         }
    1141           0 :       }
    1142             : 
    1143           0 :       return false;
    1144           0 :     }
    1145           0 :   }
    1146             : 
    1147             :   // Otherwise we are < TLSv1.3 and need to look at both the curves in the supported_groups for
    1148             :   // ECDSA and also for a compatible cipher suite. https://tools.ietf.org/html/rfc4492#section-5.1.1
    1149           0 :   const uint8_t* curvelist_data;
    1150           0 :   size_t curvelist_len;
    1151           0 :   if (!SSL_early_callback_ctx_extension_get(ssl_client_hello, TLSEXT_TYPE_supported_groups,
    1152           0 :                                             &curvelist_data, &curvelist_len)) {
    1153           0 :     return false;
    1154           0 :   }
    1155             : 
    1156           0 :   CBS curvelist;
    1157           0 :   CBS_init(&curvelist, curvelist_data, curvelist_len);
    1158             : 
    1159             :   // We only support P256 ECDSA curves today.
    1160           0 :   if (!cbsContainsU16(curvelist, SSL_CURVE_SECP256R1)) {
    1161           0 :     return false;
    1162           0 :   }
    1163             : 
    1164             :   // The client must have offered an ECDSA ciphersuite that we like.
    1165           0 :   CBS cipher_suites;
    1166           0 :   CBS_init(&cipher_suites, ssl_client_hello->cipher_suites, ssl_client_hello->cipher_suites_len);
    1167             : 
    1168           0 :   while (CBS_len(&cipher_suites) > 0) {
    1169           0 :     uint16_t cipher_id;
    1170           0 :     if (!CBS_get_u16(&cipher_suites, &cipher_id)) {
    1171           0 :       return false;
    1172           0 :     }
    1173             :     // All tls_context_ share the same set of enabled ciphers, so we can just look at the base
    1174             :     // context.
    1175           0 :     if (tls_contexts_[0].isCipherEnabled(cipher_id, client_version)) {
    1176           0 :       return true;
    1177           0 :     }
    1178           0 :   }
    1179             : 
    1180           0 :   return false;
    1181           0 : }
    1182             : 
    1183           0 : bool ServerContextImpl::isClientOcspCapable(const SSL_CLIENT_HELLO* ssl_client_hello) {
    1184           0 :   const uint8_t* status_request_data;
    1185           0 :   size_t status_request_len;
    1186           0 :   if (SSL_early_callback_ctx_extension_get(ssl_client_hello, TLSEXT_TYPE_status_request,
    1187           0 :                                            &status_request_data, &status_request_len)) {
    1188           0 :     return true;
    1189           0 :   }
    1190             : 
    1191           0 :   return false;
    1192           0 : }
    1193             : 
    1194             : OcspStapleAction ServerContextImpl::ocspStapleAction(const TlsContext& ctx,
    1195           0 :                                                      bool client_ocsp_capable) {
    1196           0 :   if (!client_ocsp_capable) {
    1197           0 :     return OcspStapleAction::ClientNotCapable;
    1198           0 :   }
    1199             : 
    1200           0 :   auto& response = ctx.ocsp_response_;
    1201             : 
    1202           0 :   auto policy = ocsp_staple_policy_;
    1203           0 :   if (ctx.is_must_staple_) {
    1204             :     // The certificate has the must-staple extension, so upgrade the policy to match.
    1205           0 :     policy = Ssl::ServerContextConfig::OcspStaplePolicy::MustStaple;
    1206           0 :   }
    1207             : 
    1208           0 :   const bool valid_response = response && !response->isExpired();
    1209             : 
    1210           0 :   switch (policy) {
    1211           0 :   case Ssl::ServerContextConfig::OcspStaplePolicy::LenientStapling:
    1212           0 :     if (!valid_response) {
    1213           0 :       return OcspStapleAction::NoStaple;
    1214           0 :     }
    1215           0 :     return OcspStapleAction::Staple;
    1216             : 
    1217           0 :   case Ssl::ServerContextConfig::OcspStaplePolicy::StrictStapling:
    1218           0 :     if (valid_response) {
    1219           0 :       return OcspStapleAction::Staple;
    1220           0 :     }
    1221           0 :     if (response) {
    1222             :       // Expired response.
    1223           0 :       return OcspStapleAction::Fail;
    1224           0 :     }
    1225           0 :     return OcspStapleAction::NoStaple;
    1226             : 
    1227           0 :   case Ssl::ServerContextConfig::OcspStaplePolicy::MustStaple:
    1228           0 :     if (!valid_response) {
    1229           0 :       return OcspStapleAction::Fail;
    1230           0 :     }
    1231           0 :     return OcspStapleAction::Staple;
    1232           0 :   }
    1233           0 :   PANIC_DUE_TO_CORRUPT_ENUM;
    1234           0 : }
    1235             : 
    1236             : enum ssl_select_cert_result_t
    1237           0 : ServerContextImpl::selectTlsContext(const SSL_CLIENT_HELLO* ssl_client_hello) {
    1238           0 :   const bool client_ecdsa_capable = isClientEcdsaCapable(ssl_client_hello);
    1239           0 :   const bool client_ocsp_capable = isClientOcspCapable(ssl_client_hello);
    1240           0 :   absl::string_view sni = absl::NullSafeStringView(
    1241           0 :       SSL_get_servername(ssl_client_hello->ssl, TLSEXT_NAMETYPE_host_name));
    1242             : 
    1243             :   // selected_ctx represents the final selected certificate, it should meet all requirements or pick
    1244             :   // a candidate
    1245           0 :   const TlsContext* selected_ctx = nullptr;
    1246           0 :   const TlsContext* candidate_ctx = nullptr;
    1247           0 :   OcspStapleAction ocsp_staple_action;
    1248             : 
    1249           0 :   auto selected = [&](const TlsContext& ctx) -> bool {
    1250           0 :     auto action = ocspStapleAction(ctx, client_ocsp_capable);
    1251           0 :     if (action == OcspStapleAction::Fail) {
    1252             :       // The selected ctx must adhere to OCSP policy
    1253           0 :       return false;
    1254           0 :     }
    1255             : 
    1256           0 :     if (client_ecdsa_capable == ctx.is_ecdsa_) {
    1257           0 :       selected_ctx = &ctx;
    1258           0 :       ocsp_staple_action = action;
    1259           0 :       return true;
    1260           0 :     }
    1261             : 
    1262           0 :     if (client_ecdsa_capable && !ctx.is_ecdsa_ && candidate_ctx == nullptr) {
    1263             :       // ECDSA cert is preferred if client is ECDSA capable, so RSA cert is marked as a candidate,
    1264             :       // searching will continue until exhausting all certs or find a exact match.
    1265           0 :       candidate_ctx = &ctx;
    1266           0 :       ocsp_staple_action = action;
    1267           0 :       return false;
    1268           0 :     }
    1269             : 
    1270           0 :     return false;
    1271           0 :   };
    1272             : 
    1273           0 :   auto select_from_map = [this, &selected](absl::string_view server_name) -> void {
    1274           0 :     auto it = server_names_map_.find(server_name);
    1275           0 :     if (it == server_names_map_.end()) {
    1276           0 :       return;
    1277           0 :     }
    1278           0 :     const auto& pkey_types_map = it->second;
    1279           0 :     for (const auto& entry : pkey_types_map) {
    1280           0 :       if (selected(entry.second.get())) {
    1281           0 :         break;
    1282           0 :       }
    1283           0 :     }
    1284           0 :   };
    1285             : 
    1286           0 :   auto tail_select = [&](bool go_to_next_phase) {
    1287           0 :     if (selected_ctx == nullptr) {
    1288           0 :       selected_ctx = candidate_ctx;
    1289           0 :     }
    1290             : 
    1291           0 :     if (selected_ctx == nullptr && !go_to_next_phase) {
    1292           0 :       selected_ctx = &tls_contexts_[0];
    1293           0 :       ocsp_staple_action = ocspStapleAction(*selected_ctx, client_ocsp_capable);
    1294           0 :     }
    1295           0 :   };
    1296             : 
    1297             :   // Select cert based on SNI if SNI is provided by client.
    1298           0 :   if (!sni.empty()) {
    1299             :     // Match on exact server name, i.e. "www.example.com" for "www.example.com".
    1300           0 :     select_from_map(sni);
    1301           0 :     tail_select(true);
    1302             : 
    1303           0 :     if (selected_ctx == nullptr) {
    1304             :       // Match on wildcard domain, i.e. ".example.com" for "www.example.com".
    1305             :       // https://datatracker.ietf.org/doc/html/rfc6125#section-6.4
    1306           0 :       size_t pos = sni.find('.', 1);
    1307           0 :       if (pos < sni.size() - 1 && pos != std::string::npos) {
    1308           0 :         absl::string_view wildcard = sni.substr(pos);
    1309           0 :         select_from_map(wildcard);
    1310           0 :       }
    1311           0 :     }
    1312           0 :     tail_select(full_scan_certs_on_sni_mismatch_);
    1313           0 :   }
    1314             :   // Full scan certs if SNI is not provided by client;
    1315             :   // Full scan certs if client provides SNI but no cert matches to it,
    1316             :   // it requires full_scan_certs_on_sni_mismatch is enabled.
    1317           0 :   if (selected_ctx == nullptr) {
    1318           0 :     candidate_ctx = nullptr;
    1319             :     // Skip loop when there is no cert compatible to key type
    1320           0 :     if (client_ecdsa_capable || (!client_ecdsa_capable && has_rsa_)) {
    1321           0 :       for (const auto& ctx : tls_contexts_) {
    1322           0 :         if (selected(ctx)) {
    1323           0 :           break;
    1324           0 :         }
    1325           0 :       }
    1326           0 :     }
    1327           0 :     tail_select(false);
    1328           0 :   }
    1329             : 
    1330             :   // Apply the selected context. This must be done before OCSP stapling below
    1331             :   // since applying the context can remove the previously-set OCSP response.
    1332             :   // This will only return NULL if memory allocation fails.
    1333           0 :   RELEASE_ASSERT(SSL_set_SSL_CTX(ssl_client_hello->ssl, selected_ctx->ssl_ctx_.get()) != nullptr,
    1334           0 :                  "");
    1335             : 
    1336           0 :   if (client_ocsp_capable) {
    1337           0 :     stats_.ocsp_staple_requests_.inc();
    1338           0 :   }
    1339             : 
    1340           0 :   switch (ocsp_staple_action) {
    1341           0 :   case OcspStapleAction::Staple: {
    1342             :     // We avoid setting the OCSP response if the client didn't request it, but doing so is safe.
    1343           0 :     RELEASE_ASSERT(selected_ctx->ocsp_response_,
    1344           0 :                    "OCSP response must be present under OcspStapleAction::Staple");
    1345           0 :     auto& resp_bytes = selected_ctx->ocsp_response_->rawBytes();
    1346           0 :     int rc = SSL_set_ocsp_response(ssl_client_hello->ssl, resp_bytes.data(), resp_bytes.size());
    1347           0 :     RELEASE_ASSERT(rc != 0, "");
    1348           0 :     stats_.ocsp_staple_responses_.inc();
    1349           0 :   } break;
    1350           0 :   case OcspStapleAction::NoStaple:
    1351           0 :     stats_.ocsp_staple_omitted_.inc();
    1352           0 :     break;
    1353           0 :   case OcspStapleAction::Fail:
    1354           0 :     stats_.ocsp_staple_failed_.inc();
    1355           0 :     return ssl_select_cert_error;
    1356           0 :   case OcspStapleAction::ClientNotCapable:
    1357           0 :     break;
    1358           0 :   }
    1359             : 
    1360           0 :   return ssl_select_cert_success;
    1361           0 : }
    1362             : 
    1363           0 : bool TlsContext::isCipherEnabled(uint16_t cipher_id, uint16_t client_version) {
    1364           0 :   const SSL_CIPHER* c = SSL_get_cipher_by_value(cipher_id);
    1365           0 :   if (c == nullptr) {
    1366           0 :     return false;
    1367           0 :   }
    1368             :   // Skip TLS 1.2 only ciphersuites unless the client supports it.
    1369           0 :   if (SSL_CIPHER_get_min_version(c) > client_version) {
    1370           0 :     return false;
    1371           0 :   }
    1372           0 :   if (SSL_CIPHER_get_auth_nid(c) != NID_auth_ecdsa) {
    1373           0 :     return false;
    1374           0 :   }
    1375           0 :   for (const SSL_CIPHER* our_c : SSL_CTX_get_ciphers(ssl_ctx_.get())) {
    1376           0 :     if (SSL_CIPHER_get_id(our_c) == SSL_CIPHER_get_id(c)) {
    1377           0 :       return true;
    1378           0 :     }
    1379           0 :   }
    1380           0 :   return false;
    1381           0 : }
    1382             : 
    1383             : ValidationResults ContextImpl::customVerifyCertChainForQuic(
    1384             :     STACK_OF(X509)& cert_chain, Ssl::ValidateResultCallbackPtr callback, bool is_server,
    1385             :     const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options,
    1386           0 :     const CertValidator::ExtraValidationContext& validation_context, const std::string& host_name) {
    1387           0 :   ASSERT(!tls_contexts_.empty());
    1388             :   // It doesn't matter which SSL context is used, because they share the same cert validation
    1389             :   // config.
    1390           0 :   SSL_CTX* ssl_ctx = tls_contexts_[0].ssl_ctx_.get();
    1391           0 :   if (SSL_CTX_get_verify_mode(ssl_ctx) == SSL_VERIFY_NONE) {
    1392             :     // Skip validation if the TLS is configured SSL_VERIFY_NONE.
    1393           0 :     return {ValidationResults::ValidationStatus::Successful,
    1394           0 :             Envoy::Ssl::ClientValidationStatus::NotValidated, absl::nullopt, absl::nullopt};
    1395           0 :   }
    1396           0 :   ValidationResults result =
    1397           0 :       cert_validator_->doVerifyCertChain(cert_chain, std::move(callback), transport_socket_options,
    1398           0 :                                          *ssl_ctx, validation_context, is_server, host_name);
    1399           0 :   return result;
    1400           0 : }
    1401             : 
    1402           0 : void TlsContext::loadCertificateChain(const std::string& data, const std::string& data_path) {
    1403           0 :   cert_chain_file_path_ = data_path;
    1404           0 :   bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(const_cast<char*>(data.data()), data.size()));
    1405           0 :   RELEASE_ASSERT(bio != nullptr, "");
    1406           0 :   cert_chain_.reset(PEM_read_bio_X509_AUX(bio.get(), nullptr, nullptr, nullptr));
    1407           0 :   if (cert_chain_ == nullptr || !SSL_CTX_use_certificate(ssl_ctx_.get(), cert_chain_.get())) {
    1408           0 :     logSslErrorChain();
    1409           0 :     throwEnvoyExceptionOrPanic(
    1410           0 :         absl::StrCat("Failed to load certificate chain from ", cert_chain_file_path_));
    1411           0 :   }
    1412             :   // Read rest of the certificate chain.
    1413           0 :   while (true) {
    1414           0 :     bssl::UniquePtr<X509> cert(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
    1415           0 :     if (cert == nullptr) {
    1416           0 :       break;
    1417           0 :     }
    1418           0 :     if (!SSL_CTX_add_extra_chain_cert(ssl_ctx_.get(), cert.get())) {
    1419           0 :       throwEnvoyExceptionOrPanic(
    1420           0 :           absl::StrCat("Failed to load certificate chain from ", cert_chain_file_path_));
    1421           0 :     }
    1422             :     // SSL_CTX_add_extra_chain_cert() takes ownership.
    1423           0 :     cert.release();
    1424           0 :   }
    1425             :   // Check for EOF.
    1426           0 :   const uint32_t err = ERR_peek_last_error();
    1427           0 :   if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
    1428           0 :     ERR_clear_error();
    1429           0 :   } else {
    1430           0 :     throwEnvoyExceptionOrPanic(
    1431           0 :         absl::StrCat("Failed to load certificate chain from ", cert_chain_file_path_));
    1432           0 :   }
    1433           0 : }
    1434             : 
    1435             : void TlsContext::loadPrivateKey(const std::string& data, const std::string& data_path,
    1436           0 :                                 const std::string& password) {
    1437           0 :   bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(const_cast<char*>(data.data()), data.size()));
    1438           0 :   RELEASE_ASSERT(bio != nullptr, "");
    1439           0 :   bssl::UniquePtr<EVP_PKEY> pkey(
    1440           0 :       PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr,
    1441           0 :                               !password.empty() ? const_cast<char*>(password.c_str()) : nullptr));
    1442             : 
    1443           0 :   if (pkey == nullptr || !SSL_CTX_use_PrivateKey(ssl_ctx_.get(), pkey.get())) {
    1444           0 :     throwEnvoyExceptionOrPanic(fmt::format("Failed to load private key from {}, Cause: {}",
    1445           0 :                                            data_path,
    1446           0 :                                            Utility::getLastCryptoError().value_or("unknown")));
    1447           0 :   }
    1448             : 
    1449           0 :   checkPrivateKey(pkey, data_path);
    1450           0 : }
    1451             : 
    1452             : void TlsContext::loadPkcs12(const std::string& data, const std::string& data_path,
    1453           0 :                             const std::string& password) {
    1454           0 :   cert_chain_file_path_ = data_path;
    1455           0 :   bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(const_cast<char*>(data.data()), data.size()));
    1456           0 :   RELEASE_ASSERT(bio != nullptr, "");
    1457           0 :   bssl::UniquePtr<PKCS12> pkcs12(d2i_PKCS12_bio(bio.get(), nullptr));
    1458             : 
    1459           0 :   EVP_PKEY* temp_private_key = nullptr;
    1460           0 :   X509* temp_cert = nullptr;
    1461           0 :   STACK_OF(X509)* temp_ca_certs = nullptr;
    1462           0 :   if (pkcs12 == nullptr ||
    1463           0 :       !PKCS12_parse(pkcs12.get(), !password.empty() ? const_cast<char*>(password.c_str()) : nullptr,
    1464           0 :                     &temp_private_key, &temp_cert, &temp_ca_certs)) {
    1465           0 :     logSslErrorChain();
    1466           0 :     throwEnvoyExceptionOrPanic(absl::StrCat("Failed to load pkcs12 from ", data_path));
    1467           0 :   }
    1468           0 :   cert_chain_.reset(temp_cert);
    1469           0 :   bssl::UniquePtr<EVP_PKEY> pkey(temp_private_key);
    1470           0 :   bssl::UniquePtr<STACK_OF(X509)> ca_certificates(temp_ca_certs);
    1471           0 :   if (ca_certificates != nullptr) {
    1472           0 :     X509* ca_cert = nullptr;
    1473           0 :     while ((ca_cert = sk_X509_pop(ca_certificates.get())) != nullptr) {
    1474             :       // This transfers ownership to ssl_ctx therefore ca_cert does not need to be freed.
    1475           0 :       SSL_CTX_add_extra_chain_cert(ssl_ctx_.get(), ca_cert);
    1476           0 :     }
    1477           0 :   }
    1478           0 :   if (!SSL_CTX_use_certificate(ssl_ctx_.get(), cert_chain_.get())) {
    1479           0 :     logSslErrorChain();
    1480           0 :     throwEnvoyExceptionOrPanic(absl::StrCat("Failed to load certificate from ", data_path));
    1481           0 :   }
    1482           0 :   if (temp_private_key == nullptr || !SSL_CTX_use_PrivateKey(ssl_ctx_.get(), pkey.get())) {
    1483           0 :     throwEnvoyExceptionOrPanic(fmt::format("Failed to load private key from {}, Cause: {}",
    1484           0 :                                            data_path,
    1485           0 :                                            Utility::getLastCryptoError().value_or("unknown")));
    1486           0 :   }
    1487             : 
    1488           0 :   checkPrivateKey(pkey, data_path);
    1489           0 : }
    1490             : 
    1491             : void TlsContext::checkPrivateKey(const bssl::UniquePtr<EVP_PKEY>& pkey,
    1492           0 :                                  const std::string& key_path) {
    1493             : #ifdef BORINGSSL_FIPS
    1494             :   // Verify that private keys are passing FIPS pairwise consistency tests.
    1495             :   switch (EVP_PKEY_id(pkey.get())) {
    1496             :   case EVP_PKEY_EC: {
    1497             :     const EC_KEY* ecdsa_private_key = EVP_PKEY_get0_EC_KEY(pkey.get());
    1498             :     if (!EC_KEY_check_fips(ecdsa_private_key)) {
    1499             :       throwEnvoyExceptionOrPanic(fmt::format("Failed to load private key from {}, ECDSA key failed "
    1500             :                                              "pairwise consistency test required in FIPS mode",
    1501             :                                              key_path));
    1502             :     }
    1503             :   } break;
    1504             :   case EVP_PKEY_RSA: {
    1505             :     RSA* rsa_private_key = EVP_PKEY_get0_RSA(pkey.get());
    1506             :     if (!RSA_check_fips(rsa_private_key)) {
    1507             :       throwEnvoyExceptionOrPanic(fmt::format("Failed to load private key from {}, RSA key failed "
    1508             :                                              "pairwise consistency test required in FIPS mode",
    1509             :                                              key_path));
    1510             :     }
    1511             :   } break;
    1512             :   }
    1513             : #else
    1514           0 :   UNREFERENCED_PARAMETER(pkey);
    1515           0 :   UNREFERENCED_PARAMETER(key_path);
    1516           0 : #endif
    1517           0 : }
    1518             : 
    1519             : } // namespace Tls
    1520             : } // namespace TransportSockets
    1521             : } // namespace Extensions
    1522             : } // namespace Envoy

Generated by: LCOV version 1.15