diff --git a/api/envoy/service/tls_session_cache/v3/tls_session_cache.proto b/api/envoy/service/tls_session_cache/v3/tls_session_cache.proto index 248d7dd01be5..a893075b9da5 100644 --- a/api/envoy/service/tls_session_cache/v3/tls_session_cache.proto +++ b/api/envoy/service/tls_session_cache/v3/tls_session_cache.proto @@ -13,7 +13,10 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: TLS session cache service] service TlsSessionCacheService { - rpc TlsSession(TlsSessionRequest) returns (TlsSessionResponse) { + rpc TlsSessionStore(TlsSessionRequest) returns (TlsSessionResponse) { + } + + rpc TlsSessionFetch(TlsSessionRequest) returns (TlsSessionResponse) { } } diff --git a/source/common/tls/context_config_impl.cc b/source/common/tls/context_config_impl.cc index 691888f9443e..1a6675eb0662 100644 --- a/source/common/tls/context_config_impl.cc +++ b/source/common/tls/context_config_impl.cc @@ -356,164 +356,6 @@ ClientContextConfigImpl::ClientContextConfigImpl( } } -const unsigned ServerContextConfigImpl::DEFAULT_MIN_VERSION = TLS1_2_VERSION; -const unsigned ServerContextConfigImpl::DEFAULT_MAX_VERSION = TLS1_3_VERSION; - -const std::string ServerContextConfigImpl::DEFAULT_CIPHER_SUITES = -#ifndef BORINGSSL_FIPS - "[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:" - "[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:" -#else // BoringSSL FIPS - "ECDHE-ECDSA-AES128-GCM-SHA256:" - "ECDHE-RSA-AES128-GCM-SHA256:" -#endif - "ECDHE-ECDSA-AES256-GCM-SHA384:" - "ECDHE-RSA-AES256-GCM-SHA384:"; - -const std::string ServerContextConfigImpl::DEFAULT_CURVES = -#ifndef BORINGSSL_FIPS - "X25519:" -#endif - "P-256"; - -absl::StatusOr> ServerContextConfigImpl::create( - const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config, - Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { - absl::Status creation_status = absl::OkStatus(); - std::unique_ptr ret = absl::WrapUnique( - new ServerContextConfigImpl(config, secret_provider_context, creation_status)); - RETURN_IF_NOT_OK(creation_status); - return ret; -} - -ServerContextConfigImpl::ServerContextConfigImpl( - const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config, - Server::Configuration::TransportSocketFactoryContext& factory_context, - absl::Status& creation_status) - : ContextConfigImpl(config.common_tls_context(), DEFAULT_MIN_VERSION, DEFAULT_MAX_VERSION, - DEFAULT_CIPHER_SUITES, DEFAULT_CURVES, factory_context, creation_status), - require_client_certificate_( - PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, require_client_certificate, false)), - ocsp_staple_policy_(ocspStaplePolicyFromProto(config.ocsp_staple_policy())), - session_ticket_keys_provider_( - getTlsSessionTicketKeysConfigProvider(factory_context, config, creation_status)), - disable_stateless_session_resumption_(getStatelessSessionResumptionDisabled(config)), - disable_stateful_session_resumption_(config.disable_stateful_session_resumption()), - full_scan_certs_on_sni_mismatch_( - PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, full_scan_certs_on_sni_mismatch, false)) { - SET_AND_RETURN_IF_NOT_OK(creation_status, creation_status); - if (session_ticket_keys_provider_ != nullptr) { - // Validate tls session ticket keys early to reject bad sds updates. - stk_validation_callback_handle_ = session_ticket_keys_provider_->addValidationCallback( - [this](const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& keys) { - return getSessionTicketKeys(keys).status(); - }); - // Load inlined, static or dynamic secret that's already available. - if (session_ticket_keys_provider_->secret() != nullptr) { - auto keys_or_error = getSessionTicketKeys(*session_ticket_keys_provider_->secret()); - SET_AND_RETURN_IF_NOT_OK(keys_or_error.status(), creation_status); - session_ticket_keys_ = *keys_or_error; - } - } - - if (!capabilities().provides_certificates) { - if ((config.common_tls_context().tls_certificates().size() + - config.common_tls_context().tls_certificate_sds_secret_configs().size()) == 0) { - creation_status = absl::InvalidArgumentError("No TLS certificates found for server context"); - } else if (!config.common_tls_context().tls_certificates().empty() && - !config.common_tls_context().tls_certificate_sds_secret_configs().empty()) { - creation_status = absl::InvalidArgumentError( - "SDS and non-SDS TLS certificates may not be mixed in server contexts"); - return; - } - } - - if (config.has_session_timeout()) { - session_timeout_ = - std::chrono::seconds(DurationUtil::durationToSeconds(config.session_timeout())); - } - if (config.has_session_cache_service()) { - tls_session_cache_grpc_timeout_ = std::chrono::milliseconds( - DurationUtil::durationToMilliseconds(config.session_cache_service().timeout())); - tls_session_cache_grpc_service_ = config.session_cache_service().grpc_service(); - enable_tls_session_cache_ = true; - } else { - enable_tls_session_cache_ = false; - } -} - -void ServerContextConfigImpl::setSecretUpdateCallback(std::function callback) { - ContextConfigImpl::setSecretUpdateCallback(callback); - if (session_ticket_keys_provider_) { - // Once session_ticket_keys_ receives new secret, this callback updates - // ContextConfigImpl::session_ticket_keys_ with new session ticket keys. - stk_update_callback_handle_ = - session_ticket_keys_provider_->addUpdateCallback([this, callback]() { - auto keys_or_error = getSessionTicketKeys(*session_ticket_keys_provider_->secret()); - RETURN_IF_NOT_OK(keys_or_error.status()); - session_ticket_keys_ = *keys_or_error; - return callback(); - }); - } -} - -absl::StatusOr> -ServerContextConfigImpl::getSessionTicketKeys( - const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& keys) { - std::vector result; - for (const auto& datasource : keys.keys()) { - auto datasource_or_error = Config::DataSource::read(datasource, false, api_); - RETURN_IF_NOT_OK(datasource_or_error.status()); - auto key_or_error = getSessionTicketKey(std::move(*datasource_or_error)); - RETURN_IF_NOT_OK(key_or_error.status()); - result.emplace_back(std::move(*key_or_error)); - } - return result; -} - -// Extracts a SessionTicketKey from raw binary data. -// Throws if key_data is invalid. -absl::StatusOr -ServerContextConfigImpl::getSessionTicketKey(const std::string& key_data) { - // If this changes, need to figure out how to deal with key files - // that previously worked. For now, just assert so we'll notice that - // it changed if it does. - static_assert(sizeof(SessionTicketKey) == 80, "Input is expected to be this size"); - - if (key_data.size() != sizeof(SessionTicketKey)) { - return absl::InvalidArgumentError(fmt::format("Incorrect TLS session ticket key length. " - "Length {}, expected length {}.", - key_data.size(), sizeof(SessionTicketKey))); - } - - SessionTicketKey dst_key; - - std::copy_n(key_data.begin(), dst_key.name_.size(), dst_key.name_.begin()); - size_t pos = dst_key.name_.size(); - std::copy_n(key_data.begin() + pos, dst_key.hmac_key_.size(), dst_key.hmac_key_.begin()); - pos += dst_key.hmac_key_.size(); - std::copy_n(key_data.begin() + pos, dst_key.aes_key_.size(), dst_key.aes_key_.begin()); - pos += dst_key.aes_key_.size(); - ASSERT(key_data.begin() + pos == key_data.end()); - - return dst_key; -} - -Ssl::ServerContextConfig::OcspStaplePolicy ServerContextConfigImpl::ocspStaplePolicyFromProto( - const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::OcspStaplePolicy& - policy) { - switch (policy) { - PANIC_ON_PROTO_ENUM_SENTINEL_VALUES; - case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::LENIENT_STAPLING: - return Ssl::ServerContextConfig::OcspStaplePolicy::LenientStapling; - case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::STRICT_STAPLING: - return Ssl::ServerContextConfig::OcspStaplePolicy::StrictStapling; - case envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::MUST_STAPLE: - return Ssl::ServerContextConfig::OcspStaplePolicy::MustStaple; - } - PANIC_DUE_TO_CORRUPT_ENUM; -} - } // namespace Tls } // namespace TransportSockets } // namespace Extensions diff --git a/source/common/tls/context_config_impl.h b/source/common/tls/context_config_impl.h index afaac3a196b0..28ecdbbb37e9 100644 --- a/source/common/tls/context_config_impl.h +++ b/source/common/tls/context_config_impl.h @@ -12,7 +12,6 @@ #include "source/common/common/empty_string.h" #include "source/common/json/json_loader.h" #include "source/common/ssl/tls_certificate_config_impl.h" -#include "source/common/tls/session_cache/session_cache.h" namespace Envoy { namespace Extensions { @@ -148,82 +147,6 @@ class ClientContextConfigImpl : public ContextConfigImpl, public Envoy::Ssl::Cli const size_t max_session_keys_; }; -class ServerContextConfigImpl : public ContextConfigImpl, public Envoy::Ssl::ServerContextConfig { -public: - static absl::StatusOr> - create(const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config, - Server::Configuration::TransportSocketFactoryContext& secret_provider_context); - - // Ssl::ServerContextConfig - bool requireClientCertificate() const override { return require_client_certificate_; } - OcspStaplePolicy ocspStaplePolicy() const override { return ocsp_staple_policy_; } - const std::vector& sessionTicketKeys() const override { - return session_ticket_keys_; - } - absl::optional sessionTimeout() const override { return session_timeout_; } - - bool isReady() const override { - const bool parent_is_ready = ContextConfigImpl::isReady(); - const bool session_ticket_keys_are_ready = - (session_ticket_keys_provider_ == nullptr || !session_ticket_keys_.empty()); - return parent_is_ready && session_ticket_keys_are_ready; - } - - void setSecretUpdateCallback(std::function callback) override; - bool disableStatelessSessionResumption() const override { - return disable_stateless_session_resumption_; - } - bool disableStatefulSessionResumption() const override { - return disable_stateful_session_resumption_; - } - - bool fullScanCertsOnSNIMismatch() const override { return full_scan_certs_on_sni_mismatch_; } - - bool enableTlsSessionCache() const override { return enable_tls_session_cache_; } - - const envoy::config::core::v3::GrpcService& tlsSessionCacheGrpcService() const override { - return tls_session_cache_grpc_service_; - } - - std::chrono::milliseconds tlsSessionCacheGrpcTimeout() const override { - return tls_session_cache_grpc_timeout_; - } - -private: - ServerContextConfigImpl( - const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config, - Server::Configuration::TransportSocketFactoryContext& secret_provider_context, - absl::Status& creation_status); - - static const unsigned DEFAULT_MIN_VERSION; - static const unsigned DEFAULT_MAX_VERSION; - static const std::string DEFAULT_CIPHER_SUITES; - static const std::string DEFAULT_CURVES; - - const bool require_client_certificate_; - const OcspStaplePolicy ocsp_staple_policy_; - std::vector session_ticket_keys_; - const Secret::TlsSessionTicketKeysConfigProviderSharedPtr session_ticket_keys_provider_; - Envoy::Common::CallbackHandlePtr stk_update_callback_handle_; - Envoy::Common::CallbackHandlePtr stk_validation_callback_handle_; - - absl::StatusOr> getSessionTicketKeys( - const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& keys); - absl::StatusOr - getSessionTicketKey(const std::string& key_data); - static OcspStaplePolicy ocspStaplePolicyFromProto( - const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::OcspStaplePolicy& - policy); - - absl::optional session_timeout_; - const bool disable_stateless_session_resumption_; - const bool disable_stateful_session_resumption_; - bool full_scan_certs_on_sni_mismatch_; - bool enable_tls_session_cache_; - envoy::config::core::v3::GrpcService tls_session_cache_grpc_service_; - std::chrono::milliseconds tls_session_cache_grpc_timeout_; -}; - } // namespace Tls } // namespace TransportSockets } // namespace Extensions diff --git a/source/common/tls/server_context_config_impl.cc b/source/common/tls/server_context_config_impl.cc index bfd611dbdb60..2d2253818c72 100644 --- a/source/common/tls/server_context_config_impl.cc +++ b/source/common/tls/server_context_config_impl.cc @@ -155,6 +155,15 @@ ServerContextConfigImpl::ServerContextConfigImpl( session_timeout_ = std::chrono::seconds(DurationUtil::durationToSeconds(config.session_timeout())); } + + if (config.has_session_cache_service()) { + tls_session_cache_grpc_timeout_ = std::chrono::milliseconds( + DurationUtil::durationToMilliseconds(config.session_cache_service().timeout())); + tls_session_cache_grpc_service_ = config.session_cache_service().grpc_service(); + enable_tls_session_cache_ = true; + } else { + enable_tls_session_cache_ = false; + } } void ServerContextConfigImpl::setSecretUpdateCallback(std::function callback) { diff --git a/source/common/tls/server_context_config_impl.h b/source/common/tls/server_context_config_impl.h index 5cacbbb0d438..95dd2f0054a6 100644 --- a/source/common/tls/server_context_config_impl.h +++ b/source/common/tls/server_context_config_impl.h @@ -41,6 +41,16 @@ class ServerContextConfigImpl : public ContextConfigImpl, public Envoy::Ssl::Ser bool fullScanCertsOnSNIMismatch() const override { return full_scan_certs_on_sni_mismatch_; } + bool enableTlsSessionCache() const override { return enable_tls_session_cache_; } + + const envoy::config::core::v3::GrpcService& tlsSessionCacheGrpcService() const override { + return tls_session_cache_grpc_service_; + } + + std::chrono::milliseconds tlsSessionCacheGrpcTimeout() const override { + return tls_session_cache_grpc_timeout_; + } + private: ServerContextConfigImpl( const envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext& config, @@ -71,6 +81,9 @@ class ServerContextConfigImpl : public ContextConfigImpl, public Envoy::Ssl::Ser const bool disable_stateless_session_resumption_; const bool disable_stateful_session_resumption_; bool full_scan_certs_on_sni_mismatch_; + bool enable_tls_session_cache_; + envoy::config::core::v3::GrpcService tls_session_cache_grpc_service_; + std::chrono::milliseconds tls_session_cache_grpc_timeout_; }; } // namespace Tls diff --git a/source/common/tls/session_cache/session_cache_impl.cc b/source/common/tls/session_cache/session_cache_impl.cc index 011c6adf99c7..d6d6597a2bb5 100644 --- a/source/common/tls/session_cache/session_cache_impl.cc +++ b/source/common/tls/session_cache/session_cache_impl.cc @@ -20,11 +20,13 @@ namespace TransportSockets { namespace Tls { namespace SessionCache { -GrpcClientImpl::GrpcClientImpl(Grpc::RawAsyncClientSharedPtr& async_client, +GrpcClientImpl::GrpcClientImpl(const Grpc::RawAsyncClientSharedPtr& async_client, const absl::optional& timeout) : async_client_(async_client), timeout_(timeout), - service_method_(*Protobuf::DescriptorPool::generated_pool()->FindMethodByName( - "envoy.service.tls_session_cache.v3.TlsSessionCacheService.TlsSession")) {} + service_method_store_(*Protobuf::DescriptorPool::generated_pool()->FindMethodByName( + "envoy.service.tls_session_cache.v3.TlsSessionCacheService.TlsSessionStore")), + service_method_fetch_(*Protobuf::DescriptorPool::generated_pool()->FindMethodByName( + "envoy.service.tls_session_cache.v3.TlsSessionCacheService.TlsSessionFetch")) {} GrpcClientImpl::~GrpcClientImpl() {} @@ -42,7 +44,7 @@ void GrpcClientImpl::storeTlsSessionCache(Network::TransportSocketCallbacks* cal request.set_type(::envoy::service::tls_session_cache::v3::STORE); ENVOY_LOG(debug, "Sending request to store session_id: {} and session_key: {}", session_id, *session_data); - async_client_->send(service_method_, request, *this, Envoy::Tracing::NullSpan::instance(), + async_client_->send(service_method_store_, request, *this, Envoy::Tracing::NullSpan::instance(), Http::AsyncClient::RequestOptions().setTimeout(timeout_)); } @@ -57,7 +59,7 @@ void GrpcClientImpl::fetchTlsSessionCache(Network::TransportSocketCallbacks* cal request.set_session_id(session_id); request.set_type(::envoy::service::tls_session_cache::v3::FETCH); ENVOY_LOG(debug, "Sending request to fetch session_id: {}", session_id); - async_client_->send(service_method_, request, *this, Envoy::Tracing::NullSpan::instance(), + async_client_->send(service_method_fetch_, request, *this, Envoy::Tracing::NullSpan::instance(), Http::AsyncClient::RequestOptions().setTimeout(timeout_)); } diff --git a/source/common/tls/session_cache/session_cache_impl.h b/source/common/tls/session_cache/session_cache_impl.h index d212c6aadd9b..670e219904a1 100644 --- a/source/common/tls/session_cache/session_cache_impl.h +++ b/source/common/tls/session_cache/session_cache_impl.h @@ -33,7 +33,7 @@ class GrpcClientImpl : public Client, public TlsSessionAsyncCallbacks, public Logger::Loggable { public: - GrpcClientImpl(Grpc::RawAsyncClientSharedPtr& async_client, + GrpcClientImpl(const Grpc::RawAsyncClientSharedPtr& async_client, const absl::optional& timeout); ~GrpcClientImpl() override; @@ -63,7 +63,8 @@ class GrpcClientImpl : public Client, Network::TransportSocketCallbacks* callbacks_; SSL* ssl_; int index_; - const Protobuf::MethodDescriptor& service_method_; + const Protobuf::MethodDescriptor& service_method_store_; + const Protobuf::MethodDescriptor& service_method_fetch_; }; /**