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

          Line data    Source code
       1             : #include "source/extensions/transport_sockets/tls/context_config_impl.h"
       2             : 
       3             : #include <memory>
       4             : #include <string>
       5             : 
       6             : #include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h"
       7             : 
       8             : #include "source/common/common/assert.h"
       9             : #include "source/common/common/empty_string.h"
      10             : #include "source/common/config/datasource.h"
      11             : #include "source/common/network/cidr_range.h"
      12             : #include "source/common/protobuf/utility.h"
      13             : #include "source/common/secret/sds_api.h"
      14             : #include "source/common/ssl/certificate_validation_context_config_impl.h"
      15             : #include "source/extensions/transport_sockets/tls/ssl_handshaker.h"
      16             : 
      17             : #include "openssl/ssl.h"
      18             : 
      19             : namespace Envoy {
      20             : namespace Extensions {
      21             : namespace TransportSockets {
      22             : namespace Tls {
      23             : 
      24             : namespace {
      25             : 
      26             : std::vector<Secret::TlsCertificateConfigProviderSharedPtr> getTlsCertificateConfigProviders(
      27             :     const envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& config,
      28           0 :     Server::Configuration::TransportSocketFactoryContext& factory_context) {
      29           0 :   std::vector<Secret::TlsCertificateConfigProviderSharedPtr> providers;
      30           0 :   if (!config.tls_certificates().empty()) {
      31           0 :     for (const auto& tls_certificate : config.tls_certificates()) {
      32           0 :       if (!tls_certificate.has_private_key_provider() && !tls_certificate.has_certificate_chain() &&
      33           0 :           !tls_certificate.has_private_key() && !tls_certificate.has_pkcs12()) {
      34           0 :         continue;
      35           0 :       }
      36           0 :       providers.push_back(
      37           0 :           factory_context.secretManager().createInlineTlsCertificateProvider(tls_certificate));
      38           0 :     }
      39           0 :     return providers;
      40           0 :   }
      41           0 :   if (!config.tls_certificate_sds_secret_configs().empty()) {
      42           0 :     for (const auto& sds_secret_config : config.tls_certificate_sds_secret_configs()) {
      43           0 :       if (sds_secret_config.has_sds_config()) {
      44             :         // Fetch dynamic secret.
      45           0 :         providers.push_back(factory_context.secretManager().findOrCreateTlsCertificateProvider(
      46           0 :             sds_secret_config.sds_config(), sds_secret_config.name(), factory_context,
      47           0 :             factory_context.initManager()));
      48           0 :       } else {
      49             :         // Load static secret.
      50           0 :         auto secret_provider = factory_context.secretManager().findStaticTlsCertificateProvider(
      51           0 :             sds_secret_config.name());
      52           0 :         if (!secret_provider) {
      53           0 :           throwEnvoyExceptionOrPanic(
      54           0 :               fmt::format("Unknown static secret: {}", sds_secret_config.name()));
      55           0 :         }
      56           0 :         providers.push_back(secret_provider);
      57           0 :       }
      58           0 :     }
      59           0 :     return providers;
      60           0 :   }
      61           0 :   return {};
      62           0 : }
      63             : 
      64             : Secret::CertificateValidationContextConfigProviderSharedPtr getProviderFromSds(
      65             :     Server::Configuration::TransportSocketFactoryContext& factory_context,
      66           0 :     const envoy::extensions::transport_sockets::tls::v3::SdsSecretConfig& sds_secret_config) {
      67           0 :   if (sds_secret_config.has_sds_config()) {
      68             :     // Fetch dynamic secret.
      69           0 :     return factory_context.secretManager().findOrCreateCertificateValidationContextProvider(
      70           0 :         sds_secret_config.sds_config(), sds_secret_config.name(), factory_context,
      71           0 :         factory_context.initManager());
      72           0 :   } else {
      73             :     // Load static secret.
      74           0 :     auto secret_provider =
      75           0 :         factory_context.secretManager().findStaticCertificateValidationContextProvider(
      76           0 :             sds_secret_config.name());
      77           0 :     if (!secret_provider) {
      78           0 :       throwEnvoyExceptionOrPanic(fmt::format("Unknown static certificate validation context: {}",
      79           0 :                                              sds_secret_config.name()));
      80           0 :     }
      81           0 :     return secret_provider;
      82           0 :   }
      83           0 :   return nullptr;
      84           0 : }
      85             : 
      86             : Secret::CertificateValidationContextConfigProviderSharedPtr
      87             : getCertificateValidationContextConfigProvider(
      88             :     const envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& config,
      89             :     Server::Configuration::TransportSocketFactoryContext& factory_context,
      90             :     std::unique_ptr<envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext>*
      91           0 :         default_cvc) {
      92           0 :   switch (config.validation_context_type_case()) {
      93           0 :   case envoy::extensions::transport_sockets::tls::v3::CommonTlsContext::ValidationContextTypeCase::
      94           0 :       kValidationContext:
      95           0 :     return factory_context.secretManager().createInlineCertificateValidationContextProvider(
      96           0 :         config.validation_context());
      97           0 :   case envoy::extensions::transport_sockets::tls::v3::CommonTlsContext::ValidationContextTypeCase::
      98           0 :       kValidationContextSdsSecretConfig:
      99           0 :     return getProviderFromSds(factory_context, config.validation_context_sds_secret_config());
     100           0 :   case envoy::extensions::transport_sockets::tls::v3::CommonTlsContext::ValidationContextTypeCase::
     101           0 :       kCombinedValidationContext: {
     102           0 :     *default_cvc = std::make_unique<
     103           0 :         envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext>(
     104           0 :         config.combined_validation_context().default_validation_context());
     105           0 :     const auto& sds_secret_config =
     106           0 :         config.combined_validation_context().validation_context_sds_secret_config();
     107           0 :     return getProviderFromSds(factory_context, sds_secret_config);
     108           0 :   }
     109           0 :   default:
     110           0 :     return nullptr;
     111           0 :   }
     112           0 : }
     113             : 
     114             : Secret::TlsSessionTicketKeysConfigProviderSharedPtr getTlsSessionTicketKeysConfigProvider(
     115             :     Server::Configuration::TransportSocketFactoryContext& factory_context,
     116           0 :     const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config) {
     117             : 
     118           0 :   switch (config.session_ticket_keys_type_case()) {
     119           0 :   case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::
     120           0 :       SessionTicketKeysTypeCase::kSessionTicketKeys:
     121           0 :     return factory_context.secretManager().createInlineTlsSessionTicketKeysProvider(
     122           0 :         config.session_ticket_keys());
     123           0 :   case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::
     124           0 :       SessionTicketKeysTypeCase::kSessionTicketKeysSdsSecretConfig: {
     125           0 :     const auto& sds_secret_config = config.session_ticket_keys_sds_secret_config();
     126           0 :     if (sds_secret_config.has_sds_config()) {
     127             :       // Fetch dynamic secret.
     128           0 :       return factory_context.secretManager().findOrCreateTlsSessionTicketKeysContextProvider(
     129           0 :           sds_secret_config.sds_config(), sds_secret_config.name(), factory_context,
     130           0 :           factory_context.initManager());
     131           0 :     } else {
     132             :       // Load static secret.
     133           0 :       auto secret_provider =
     134           0 :           factory_context.secretManager().findStaticTlsSessionTicketKeysContextProvider(
     135           0 :               sds_secret_config.name());
     136           0 :       if (!secret_provider) {
     137           0 :         throwEnvoyExceptionOrPanic(
     138           0 :             fmt::format("Unknown tls session ticket keys: {}", sds_secret_config.name()));
     139           0 :       }
     140           0 :       return secret_provider;
     141           0 :     }
     142           0 :   }
     143           0 :   case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::
     144           0 :       SessionTicketKeysTypeCase::kDisableStatelessSessionResumption:
     145           0 :   case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::
     146           0 :       SessionTicketKeysTypeCase::SESSION_TICKET_KEYS_TYPE_NOT_SET:
     147           0 :     return nullptr;
     148           0 :   default:
     149           0 :     throwEnvoyExceptionOrPanic(fmt::format("Unexpected case for oneof session_ticket_keys: {}",
     150           0 :                                            config.session_ticket_keys_type_case()));
     151           0 :   }
     152           0 : }
     153             : 
     154             : bool getStatelessSessionResumptionDisabled(
     155           0 :     const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config) {
     156           0 :   if (config.session_ticket_keys_type_case() ==
     157           0 :       envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::
     158           0 :           SessionTicketKeysTypeCase::kDisableStatelessSessionResumption) {
     159           0 :     return config.disable_stateless_session_resumption();
     160           0 :   } else {
     161           0 :     return false;
     162           0 :   }
     163           0 : }
     164             : 
     165             : } // namespace
     166             : 
     167             : ContextConfigImpl::ContextConfigImpl(
     168             :     const envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& config,
     169             :     const unsigned default_min_protocol_version, const unsigned default_max_protocol_version,
     170             :     const std::string& default_cipher_suites, const std::string& default_curves,
     171             :     Server::Configuration::TransportSocketFactoryContext& factory_context)
     172             :     : api_(factory_context.serverFactoryContext().api()),
     173             :       options_(factory_context.serverFactoryContext().options()),
     174             :       singleton_manager_(factory_context.serverFactoryContext().singletonManager()),
     175             :       alpn_protocols_(RepeatedPtrUtil::join(config.alpn_protocols(), ",")),
     176             :       cipher_suites_(StringUtil::nonEmptyStringOrDefault(
     177             :           RepeatedPtrUtil::join(config.tls_params().cipher_suites(), ":"), default_cipher_suites)),
     178             :       ecdh_curves_(StringUtil::nonEmptyStringOrDefault(
     179             :           RepeatedPtrUtil::join(config.tls_params().ecdh_curves(), ":"), default_curves)),
     180             :       signature_algorithms_(RepeatedPtrUtil::join(config.tls_params().signature_algorithms(), ":")),
     181             :       tls_certificate_providers_(getTlsCertificateConfigProviders(config, factory_context)),
     182             :       certificate_validation_context_provider_(
     183             :           getCertificateValidationContextConfigProvider(config, factory_context, &default_cvc_)),
     184             :       min_protocol_version_(tlsVersionFromProto(config.tls_params().tls_minimum_protocol_version(),
     185             :                                                 default_min_protocol_version)),
     186             :       max_protocol_version_(tlsVersionFromProto(config.tls_params().tls_maximum_protocol_version(),
     187             :                                                 default_max_protocol_version)),
     188           0 :       factory_context_(factory_context), tls_keylog_path_(config.key_log().path()) {
     189           0 :   auto list_or_error = Network::Address::IpList::create(config.key_log().local_address_range());
     190           0 :   THROW_IF_STATUS_NOT_OK(list_or_error, throw);
     191           0 :   tls_keylog_local_ = std::move(list_or_error.value());
     192           0 :   list_or_error = Network::Address::IpList::create(config.key_log().remote_address_range());
     193           0 :   THROW_IF_STATUS_NOT_OK(list_or_error, throw);
     194           0 :   tls_keylog_remote_ = std::move(list_or_error.value());
     195             : 
     196           0 :   if (certificate_validation_context_provider_ != nullptr) {
     197           0 :     if (default_cvc_) {
     198             :       // We need to validate combined certificate validation context.
     199             :       // The default certificate validation context and dynamic certificate validation
     200             :       // context could only contain partial fields, which is okay to fail the validation.
     201             :       // But the combined certificate validation context should pass validation. If
     202             :       // validation of combined certificate validation context fails,
     203             :       // getCombinedValidationContextConfig() throws exception, validation_context_config_ will not
     204             :       // get updated.
     205           0 :       cvc_validation_callback_handle_ =
     206           0 :           certificate_validation_context_provider_->addValidationCallback(
     207           0 :               [this](
     208           0 :                   const envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext&
     209           0 :                       dynamic_cvc) { getCombinedValidationContextConfig(dynamic_cvc); });
     210           0 :     }
     211             :     // Load inlined, static or dynamic secret that's already available.
     212           0 :     if (certificate_validation_context_provider_->secret() != nullptr) {
     213           0 :       if (default_cvc_) {
     214           0 :         validation_context_config_ =
     215           0 :             getCombinedValidationContextConfig(*certificate_validation_context_provider_->secret());
     216           0 :       } else {
     217           0 :         auto config_or_status = Envoy::Ssl::CertificateValidationContextConfigImpl::create(
     218           0 :             *certificate_validation_context_provider_->secret(), api_);
     219           0 :         if (!config_or_status.status().ok()) {
     220           0 :           throwEnvoyExceptionOrPanic(std::string(config_or_status.status().message()));
     221           0 :         }
     222           0 :         validation_context_config_ = std::move(config_or_status.value());
     223           0 :       }
     224           0 :     }
     225           0 :   }
     226             :   // Load inlined, static or dynamic secrets that are already available.
     227           0 :   if (!tls_certificate_providers_.empty()) {
     228           0 :     for (auto& provider : tls_certificate_providers_) {
     229           0 :       if (provider->secret() != nullptr) {
     230           0 :         tls_certificate_configs_.emplace_back(*provider->secret(), factory_context, api_);
     231           0 :       }
     232           0 :     }
     233           0 :   }
     234             : 
     235           0 :   HandshakerFactoryContextImpl handshaker_factory_context(api_, options_, alpn_protocols_,
     236           0 :                                                           singleton_manager_);
     237           0 :   Ssl::HandshakerFactory* handshaker_factory;
     238           0 :   if (config.has_custom_handshaker()) {
     239             :     // If a custom handshaker is configured, derive the factory from the config.
     240           0 :     const auto& handshaker_config = config.custom_handshaker();
     241           0 :     handshaker_factory =
     242           0 :         &Config::Utility::getAndCheckFactory<Ssl::HandshakerFactory>(handshaker_config);
     243           0 :     handshaker_factory_cb_ = handshaker_factory->createHandshakerCb(
     244           0 :         handshaker_config.typed_config(), handshaker_factory_context,
     245           0 :         factory_context.messageValidationVisitor());
     246           0 :   } else {
     247             :     // Otherwise, derive the config from the default factory.
     248           0 :     handshaker_factory = HandshakerFactoryImpl::getDefaultHandshakerFactory();
     249           0 :     handshaker_factory_cb_ = handshaker_factory->createHandshakerCb(
     250           0 :         *handshaker_factory->createEmptyConfigProto(), handshaker_factory_context,
     251           0 :         factory_context.messageValidationVisitor());
     252           0 :   }
     253           0 :   capabilities_ = handshaker_factory->capabilities();
     254           0 :   sslctx_cb_ = handshaker_factory->sslctxCb(handshaker_factory_context);
     255           0 : }
     256             : 
     257             : Ssl::CertificateValidationContextConfigPtr ContextConfigImpl::getCombinedValidationContextConfig(
     258             :     const envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext&
     259           0 :         dynamic_cvc) {
     260           0 :   envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext combined_cvc =
     261           0 :       *default_cvc_;
     262           0 :   combined_cvc.MergeFrom(dynamic_cvc);
     263           0 :   auto config_or_status =
     264           0 :       Envoy::Ssl::CertificateValidationContextConfigImpl::create(combined_cvc, api_);
     265           0 :   if (!config_or_status.status().ok()) {
     266           0 :     throwEnvoyExceptionOrPanic(std::string(config_or_status.status().message()));
     267           0 :   }
     268           0 :   return std::move(config_or_status.value());
     269           0 : }
     270             : 
     271           0 : void ContextConfigImpl::setSecretUpdateCallback(std::function<void()> callback) {
     272             :   // When any of tls_certificate_providers_ receives a new secret, this callback updates
     273             :   // ContextConfigImpl::tls_certificate_configs_ with new secret.
     274           0 :   for (const auto& tls_certificate_provider : tls_certificate_providers_) {
     275           0 :     tc_update_callback_handles_.push_back(
     276           0 :         tls_certificate_provider->addUpdateCallback([this, callback]() {
     277           0 :           tls_certificate_configs_.clear();
     278           0 :           for (const auto& tls_certificate_provider : tls_certificate_providers_) {
     279           0 :             auto* secret = tls_certificate_provider->secret();
     280           0 :             if (secret != nullptr) {
     281           0 :               tls_certificate_configs_.emplace_back(*secret, factory_context_, api_);
     282           0 :             }
     283           0 :           }
     284           0 :           callback();
     285           0 :         }));
     286           0 :   }
     287           0 :   if (certificate_validation_context_provider_) {
     288           0 :     if (default_cvc_) {
     289             :       // Once certificate_validation_context_provider_ receives new secret, this callback updates
     290             :       // ContextConfigImpl::validation_context_config_ with a combined certificate validation
     291             :       // context. The combined certificate validation context is created by merging new secret
     292             :       // into default_cvc_.
     293           0 :       cvc_update_callback_handle_ =
     294           0 :           certificate_validation_context_provider_->addUpdateCallback([this, callback]() {
     295           0 :             validation_context_config_ = getCombinedValidationContextConfig(
     296           0 :                 *certificate_validation_context_provider_->secret());
     297           0 :             callback();
     298           0 :           });
     299           0 :     } else {
     300             :       // Once certificate_validation_context_provider_ receives new secret, this callback updates
     301             :       // ContextConfigImpl::validation_context_config_ with new secret.
     302           0 :       cvc_update_callback_handle_ =
     303           0 :           certificate_validation_context_provider_->addUpdateCallback([this, callback]() {
     304           0 :             auto config_or_status = Envoy::Ssl::CertificateValidationContextConfigImpl::create(
     305           0 :                 *certificate_validation_context_provider_->secret(), api_);
     306           0 :             if (!config_or_status.status().ok()) {
     307           0 :               throwEnvoyExceptionOrPanic(std::string(config_or_status.status().message()));
     308           0 :             }
     309           0 :             validation_context_config_ = std::move(config_or_status.value());
     310           0 :             callback();
     311           0 :           });
     312           0 :     }
     313           0 :   }
     314           0 : }
     315             : 
     316           0 : Ssl::HandshakerFactoryCb ContextConfigImpl::createHandshaker() const {
     317           0 :   return handshaker_factory_cb_;
     318           0 : }
     319             : 
     320             : unsigned ContextConfigImpl::tlsVersionFromProto(
     321             :     const envoy::extensions::transport_sockets::tls::v3::TlsParameters::TlsProtocol& version,
     322           0 :     unsigned default_version) {
     323           0 :   switch (version) {
     324           0 :     PANIC_ON_PROTO_ENUM_SENTINEL_VALUES;
     325           0 :   case envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLS_AUTO:
     326           0 :     return default_version;
     327           0 :   case envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_0:
     328           0 :     return TLS1_VERSION;
     329           0 :   case envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_1:
     330           0 :     return TLS1_1_VERSION;
     331           0 :   case envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_2:
     332           0 :     return TLS1_2_VERSION;
     333           0 :   case envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3:
     334           0 :     return TLS1_3_VERSION;
     335           0 :   }
     336           0 :   IS_ENVOY_BUG("unexpected tls version provided");
     337           0 :   return default_version;
     338           0 : }
     339             : 
     340             : const unsigned ClientContextConfigImpl::DEFAULT_MIN_VERSION = TLS1_2_VERSION;
     341             : const unsigned ClientContextConfigImpl::DEFAULT_MAX_VERSION = TLS1_2_VERSION;
     342             : 
     343             : const std::string ClientContextConfigImpl::DEFAULT_CIPHER_SUITES =
     344             : #ifndef BORINGSSL_FIPS
     345             :     "[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:"
     346             :     "[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:"
     347             : #else // BoringSSL FIPS
     348             :     "ECDHE-ECDSA-AES128-GCM-SHA256:"
     349             :     "ECDHE-RSA-AES128-GCM-SHA256:"
     350             : #endif
     351             :     "ECDHE-ECDSA-AES256-GCM-SHA384:"
     352             :     "ECDHE-RSA-AES256-GCM-SHA384:";
     353             : 
     354             : const std::string ClientContextConfigImpl::DEFAULT_CURVES =
     355             : #ifndef BORINGSSL_FIPS
     356             :     "X25519:"
     357             : #endif
     358             :     "P-256";
     359             : 
     360             : ClientContextConfigImpl::ClientContextConfigImpl(
     361             :     const envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext& config,
     362             :     Server::Configuration::TransportSocketFactoryContext& factory_context)
     363             :     : ContextConfigImpl(config.common_tls_context(), DEFAULT_MIN_VERSION, DEFAULT_MAX_VERSION,
     364             :                         DEFAULT_CIPHER_SUITES, DEFAULT_CURVES, factory_context),
     365             :       server_name_indication_(config.sni()), allow_renegotiation_(config.allow_renegotiation()),
     366             :       enforce_rsa_key_usage_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, enforce_rsa_key_usage, false)),
     367           0 :       max_session_keys_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, max_session_keys, 1)) {
     368             :   // BoringSSL treats this as a C string, so embedded NULL characters will not
     369             :   // be handled correctly.
     370           0 :   if (server_name_indication_.find('\0') != std::string::npos) {
     371           0 :     throwEnvoyExceptionOrPanic("SNI names containing NULL-byte are not allowed");
     372           0 :   }
     373             :   // TODO(PiotrSikora): Support multiple TLS certificates.
     374           0 :   if ((config.common_tls_context().tls_certificates().size() +
     375           0 :        config.common_tls_context().tls_certificate_sds_secret_configs().size()) > 1) {
     376           0 :     throwEnvoyExceptionOrPanic("Multiple TLS certificates are not supported for client contexts");
     377           0 :   }
     378           0 : }
     379             : 
     380             : const unsigned ServerContextConfigImpl::DEFAULT_MIN_VERSION = TLS1_2_VERSION;
     381             : const unsigned ServerContextConfigImpl::DEFAULT_MAX_VERSION = TLS1_3_VERSION;
     382             : 
     383             : const std::string ServerContextConfigImpl::DEFAULT_CIPHER_SUITES =
     384             : #ifndef BORINGSSL_FIPS
     385             :     "[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:"
     386             :     "[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:"
     387             : #else // BoringSSL FIPS
     388             :     "ECDHE-ECDSA-AES128-GCM-SHA256:"
     389             :     "ECDHE-RSA-AES128-GCM-SHA256:"
     390             : #endif
     391             :     "ECDHE-ECDSA-AES256-GCM-SHA384:"
     392             :     "ECDHE-RSA-AES256-GCM-SHA384:";
     393             : 
     394             : const std::string ServerContextConfigImpl::DEFAULT_CURVES =
     395             : #ifndef BORINGSSL_FIPS
     396             :     "X25519:"
     397             : #endif
     398             :     "P-256";
     399             : 
     400             : ServerContextConfigImpl::ServerContextConfigImpl(
     401             :     const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config,
     402             :     Server::Configuration::TransportSocketFactoryContext& factory_context)
     403             :     : ContextConfigImpl(config.common_tls_context(), DEFAULT_MIN_VERSION, DEFAULT_MAX_VERSION,
     404             :                         DEFAULT_CIPHER_SUITES, DEFAULT_CURVES, factory_context),
     405             :       require_client_certificate_(
     406             :           PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, require_client_certificate, false)),
     407             :       ocsp_staple_policy_(ocspStaplePolicyFromProto(config.ocsp_staple_policy())),
     408             :       session_ticket_keys_provider_(getTlsSessionTicketKeysConfigProvider(factory_context, config)),
     409             :       disable_stateless_session_resumption_(getStatelessSessionResumptionDisabled(config)),
     410             :       disable_stateful_session_resumption_(config.disable_stateful_session_resumption()),
     411             :       full_scan_certs_on_sni_mismatch_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(
     412             :           config, full_scan_certs_on_sni_mismatch,
     413             :           !Runtime::runtimeFeatureEnabled(
     414           0 :               "envoy.reloadable_features.no_full_scan_certs_on_sni_mismatch"))) {
     415             : 
     416           0 :   if (session_ticket_keys_provider_ != nullptr) {
     417             :     // Validate tls session ticket keys early to reject bad sds updates.
     418           0 :     stk_validation_callback_handle_ = session_ticket_keys_provider_->addValidationCallback(
     419           0 :         [this](const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& keys) {
     420           0 :           getSessionTicketKeys(keys);
     421           0 :         });
     422             :     // Load inlined, static or dynamic secret that's already available.
     423           0 :     if (session_ticket_keys_provider_->secret() != nullptr) {
     424           0 :       session_ticket_keys_ = getSessionTicketKeys(*session_ticket_keys_provider_->secret());
     425           0 :     }
     426           0 :   }
     427             : 
     428           0 :   if (!capabilities().provides_certificates) {
     429           0 :     if ((config.common_tls_context().tls_certificates().size() +
     430           0 :          config.common_tls_context().tls_certificate_sds_secret_configs().size()) == 0) {
     431           0 :       throwEnvoyExceptionOrPanic("No TLS certificates found for server context");
     432           0 :     } else if (!config.common_tls_context().tls_certificates().empty() &&
     433           0 :                !config.common_tls_context().tls_certificate_sds_secret_configs().empty()) {
     434           0 :       throwEnvoyExceptionOrPanic(
     435           0 :           "SDS and non-SDS TLS certificates may not be mixed in server contexts");
     436           0 :     }
     437           0 :   }
     438             : 
     439           0 :   if (config.has_session_timeout()) {
     440           0 :     session_timeout_ =
     441           0 :         std::chrono::seconds(DurationUtil::durationToSeconds(config.session_timeout()));
     442           0 :   }
     443           0 : }
     444             : 
     445           0 : void ServerContextConfigImpl::setSecretUpdateCallback(std::function<void()> callback) {
     446           0 :   ContextConfigImpl::setSecretUpdateCallback(callback);
     447           0 :   if (session_ticket_keys_provider_) {
     448             :     // Once session_ticket_keys_ receives new secret, this callback updates
     449             :     // ContextConfigImpl::session_ticket_keys_ with new session ticket keys.
     450           0 :     stk_update_callback_handle_ =
     451           0 :         session_ticket_keys_provider_->addUpdateCallback([this, callback]() {
     452           0 :           session_ticket_keys_ = getSessionTicketKeys(*session_ticket_keys_provider_->secret());
     453           0 :           callback();
     454           0 :         });
     455           0 :   }
     456           0 : }
     457             : 
     458             : std::vector<Ssl::ServerContextConfig::SessionTicketKey>
     459             : ServerContextConfigImpl::getSessionTicketKeys(
     460           0 :     const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& keys) {
     461           0 :   std::vector<Ssl::ServerContextConfig::SessionTicketKey> result;
     462           0 :   for (const auto& datasource : keys.keys()) {
     463           0 :     result.emplace_back(getSessionTicketKey(Config::DataSource::read(datasource, false, api_)));
     464           0 :   }
     465           0 :   return result;
     466           0 : }
     467             : 
     468             : // Extracts a SessionTicketKey from raw binary data.
     469             : // Throws if key_data is invalid.
     470             : Ssl::ServerContextConfig::SessionTicketKey
     471           0 : ServerContextConfigImpl::getSessionTicketKey(const std::string& key_data) {
     472             :   // If this changes, need to figure out how to deal with key files
     473             :   // that previously worked. For now, just assert so we'll notice that
     474             :   // it changed if it does.
     475           0 :   static_assert(sizeof(SessionTicketKey) == 80, "Input is expected to be this size");
     476             : 
     477           0 :   if (key_data.size() != sizeof(SessionTicketKey)) {
     478           0 :     throwEnvoyExceptionOrPanic(fmt::format("Incorrect TLS session ticket key length. "
     479           0 :                                            "Length {}, expected length {}.",
     480           0 :                                            key_data.size(), sizeof(SessionTicketKey)));
     481           0 :   }
     482             : 
     483           0 :   SessionTicketKey dst_key;
     484             : 
     485           0 :   std::copy_n(key_data.begin(), dst_key.name_.size(), dst_key.name_.begin());
     486           0 :   size_t pos = dst_key.name_.size();
     487           0 :   std::copy_n(key_data.begin() + pos, dst_key.hmac_key_.size(), dst_key.hmac_key_.begin());
     488           0 :   pos += dst_key.hmac_key_.size();
     489           0 :   std::copy_n(key_data.begin() + pos, dst_key.aes_key_.size(), dst_key.aes_key_.begin());
     490           0 :   pos += dst_key.aes_key_.size();
     491           0 :   ASSERT(key_data.begin() + pos == key_data.end());
     492             : 
     493           0 :   return dst_key;
     494           0 : }
     495             : 
     496             : Ssl::ServerContextConfig::OcspStaplePolicy ServerContextConfigImpl::ocspStaplePolicyFromProto(
     497             :     const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::OcspStaplePolicy&
     498           0 :         policy) {
     499           0 :   switch (policy) {
     500           0 :     PANIC_ON_PROTO_ENUM_SENTINEL_VALUES;
     501           0 :   case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::LENIENT_STAPLING:
     502           0 :     return Ssl::ServerContextConfig::OcspStaplePolicy::LenientStapling;
     503           0 :   case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::STRICT_STAPLING:
     504           0 :     return Ssl::ServerContextConfig::OcspStaplePolicy::StrictStapling;
     505           0 :   case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::MUST_STAPLE:
     506           0 :     return Ssl::ServerContextConfig::OcspStaplePolicy::MustStaple;
     507           0 :   }
     508           0 :   PANIC_DUE_TO_CORRUPT_ENUM;
     509           0 : }
     510             : 
     511             : } // namespace Tls
     512             : } // namespace TransportSockets
     513             : } // namespace Extensions
     514             : } // namespace Envoy

Generated by: LCOV version 1.15