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
|