Repository: envoyproxy/envoy
File: source/common/tls/context_config_impl.cc (C++)

Code before:
    absl::Status& creation_status)
    : ContextConfigImpl(
          config.common_tls_context(), config.auto_sni_san_validation(), DEFAULT_MIN_VERSION,
          DEFAULT_MAX_VERSION, FIPS_mode() ? DEFAULT_CIPHER_SUITES_FIPS : DEFAULT_CIPHER_SUITES,
          FIPS_mode() ? DEFAULT_CURVES_FIPS : DEFAULT_CURVES, factory_context, creation_status),
      server_name_indication_(config.sni()), auto_host_sni_(config.auto_host_sni()),
      allow_renegotiation_(config.allow_renegotiation()),
      enforce_rsa_key_usage_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, enforce_rsa_key_usage, true)),
      max_session_keys_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, max_session_keys, 1)) {

  if (!config.has_enforce_rsa_key_usage()) {
    ENVOY_LOG(
        warn,
        "The 'enforce_rsa_key_usage' option is not configured, its default value is changed to "
        "true, and the config option will be deprecated in the next version. The handshake will "
        "fail "
        "if the keyUsage extension is present and incompatible with the "
        "TLS usage. Please update the certificates to be compliant.");
  } else if (!enforce_rsa_key_usage_) {
    ENVOY_LOG(
        warn,
        "The 'enforce_rsa_key_usage' option is set to false, which disables the enforcement of RSA "
        "key usage. This option will be deprecated in the next version. The handshake will fail "
        "if the keyUsage extension is present and incompatible with the "
        "TLS usage. Please update the certificates to be compliant.");
    factory_context.serverFactoryContext().runtime().countDeprecatedFeatureUse();
  }

  // BoringSSL treats this as a C string, so embedded NULL characters will not
  // be handled correctly.
  if (server_name_indication_.find('\0') != std::string::npos) {
    creation_status = absl::InvalidArgumentError("SNI names containing NULL-byte are not allowed");
    return;
  }

  // TODO(PiotrSikora): Support multiple TLS certificates.
  if ((config.common_tls_context().tls_certificates().size() +
       config.common_tls_context().tls_certificate_sds_secret_configs().size()) > 1 &&
      !config.common_tls_context().has_custom_tls_certificate_selector()) {
    creation_status = absl::InvalidArgumentError(
        "Multiple TLS certificates are not supported for client contexts");
    return;
  }

  if (config.common_tls_context().has_custom_tls_certificate_selector()) {
    const auto& provider_config = config.common_tls_context().custom_tls_certificate_selector();
    Ssl::UpstreamTlsCertificateSelectorConfigFactory& provider_factory =
        Config::Utility::getAndCheckFactory<Ssl::UpstreamTlsCertificateSelectorConfigFactory>(
            provider_config);
    ProtobufTypes::MessagePtr message = Config::Utility::translateAnyToFactoryConfig(
        provider_config.typed_config(), factory_context.messageValidationVisitor(),

Review comment (suggestion):
On second thought, I think that `google.protobuf.BoolValue enforce_rsa_key_usage = 5;` should be marked as deprecated right now. And that will automatically increment this counter if it's used.

Also, the docs there say

```
  // .. note::
  //   The default value is ``false`` (i.e., enforcement off). It is expected to change to ``true`` in a future release.
```
and that needs to be updated

Code after:
    absl::Status& creation_status)
    : ContextConfigImpl(
          config.common_tls_context(), config.auto_sni_san_validation(), DEFAULT_MIN_VERSION,
          DEFAULT_MAX_VERSION, FIPS_mode() ? DEFAULT_CIPHER_SUITES_FIPS : DEFAULT_CIPHER_SUITES,
          FIPS_mode() ? DEFAULT_CURVES_FIPS : DEFAULT_CURVES, factory_context, creation_status),
      server_name_indication_(config.sni()), auto_host_sni_(config.auto_host_sni()),
      allow_renegotiation_(config.allow_renegotiation()),
      enforce_rsa_key_usage_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, enforce_rsa_key_usage, true)),
      max_session_keys_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, max_session_keys, 1)) {

  if (!enforce_rsa_key_usage_) {
    ENVOY_LOG(
        warn,
        "The 'enforce_rsa_key_usage' option is set to false, which disables the enforcement of RSA "
        "key usage. This option will be removed in the next version. The handshake will fail "
        "if the keyUsage extension is present and incompatible with the "
        "TLS usage. Please update the certificates to be compliant.");
  }

  // BoringSSL treats this as a C string, so embedded NULL characters will not
  // be handled correctly.
  if (server_name_indication_.find('\0') != std::string::npos) {
    creation_status = absl::InvalidArgumentError("SNI names containing NULL-byte are not allowed");
    return;
  }

  // TODO(PiotrSikora): Support multiple TLS certificates.
  if ((config.common_tls_context().tls_certificates().size() +
       config.common_tls_context().tls_certificate_sds_secret_configs().size()) > 1 &&
      !config.common_tls_context().has_custom_tls_certificate_selector()) {
    creation_status = absl::InvalidArgumentError(
        "Multiple TLS certificates are not supported for client contexts");
    return;
  }

  if (config.common_tls_context().has_custom_tls_certificate_selector()) {
    const auto& provider_config = config.common_tls_context().custom_tls_certificate_selector();
    Ssl::UpstreamTlsCertificateSelectorConfigFactory& provider_factory =
        Config::Utility::getAndCheckFactory<Ssl::UpstreamTlsCertificateSelectorConfigFactory>(
            provider_config);
    ProtobufTypes::MessagePtr message = Config::Utility::translateAnyToFactoryConfig(
        provider_config.typed_config(), factory_context.messageValidationVisitor(),
        provider_factory);
    auto selector_factory = provider_factory.createUpstreamTlsCertificateSelectorFactory(
        *message, factory_context, *this);
    SET_AND_RETURN_IF_NOT_OK(selector_factory.status(), creation_status);
    tls_certificate_selector_factory_ = *std::move(selector_factory);
  }
}

void ClientContextConfigImpl::setSecretUpdateCallback(std::function<absl::Status()> callback) {