1
#include "source/common/tls/server_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/common/tls/cert_validator/factory.h"
30
#include "source/common/tls/stats.h"
31
#include "source/common/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

            
44
namespace Extensions {
45
namespace TransportSockets {
46
namespace Tls {
47

            
48
1249
Ssl::CurveNIDVector getClientCurveNIDSupported(CBS& cbs) {
49
1249
  Ssl::CurveNIDVector cnsv{};
50
6194
  while (CBS_len(&cbs) > 0) {
51
4946
    uint16_t v;
52
4946
    if (!CBS_get_u16(&cbs, &v)) {
53
1
      break;
54
1
    }
55
    // Check for values that refer to the `sigalgs` used in TLSv1.3 negotiation (left)
56
    // or their equivalent curve expressed in TLSv1.2 `TLSEXT_TYPE_supported_groups`
57
    // present in ClientHello (right).
58
4945
    if (v == SSL_SIGN_ECDSA_SECP256R1_SHA256 || v == SSL_CURVE_SECP256R1) {
59
1237
      cnsv.push_back(NID_X9_62_prime256v1);
60
1237
    }
61
4945
    if (v == SSL_SIGN_ECDSA_SECP384R1_SHA384 || v == SSL_CURVE_SECP384R1) {
62
215
      cnsv.push_back(NID_secp384r1);
63
215
    }
64
4945
    if (v == SSL_SIGN_ECDSA_SECP521R1_SHA512 || v == SSL_CURVE_SECP521R1) {
65
6
      cnsv.push_back(NID_secp521r1);
66
6
    }
67
4945
  }
68
1249
  return cnsv;
69
1249
}
70

            
71
int ServerContextImpl::alpnSelectCallback(const unsigned char** out, unsigned char* outlen,
72
703
                                          const unsigned char* in, unsigned int inlen) {
73
  // Currently this uses the standard selection algorithm in priority order.
74
703
  const uint8_t* alpn_data = parsed_alpn_protocols_.data();
75
703
  size_t alpn_data_size = parsed_alpn_protocols_.size();
76

            
77
703
  if (SSL_select_next_proto(const_cast<unsigned char**>(out), outlen, alpn_data, alpn_data_size, in,
78
703
                            inlen) != OPENSSL_NPN_NEGOTIATED) {
79
47
    return SSL_TLSEXT_ERR_NOACK;
80
700
  } else {
81
656
    return SSL_TLSEXT_ERR_OK;
82
656
  }
83
703
}
84

            
85
absl::StatusOr<std::unique_ptr<ServerContextImpl>>
86
ServerContextImpl::create(Stats::Scope& scope, const Envoy::Ssl::ServerContextConfig& config,
87
                          Server::Configuration::CommonFactoryContext& factory_context,
88
3493
                          Ssl::ContextAdditionalInitFunc additional_init) {
89
3493
  absl::Status creation_status = absl::OkStatus();
90
3493
  auto ret = std::unique_ptr<ServerContextImpl>(
91
3493
      new ServerContextImpl(scope, config, config.tlsCertificates(), true, factory_context,
92
3493
                            additional_init, creation_status));
93
3493
  RETURN_IF_NOT_OK(creation_status);
94
3470
  return ret;
95
3493
}
96

            
97
ServerContextImpl::ServerContextImpl(
98
    Stats::Scope& scope, const Envoy::Ssl::ServerContextConfig& config,
99
    const std::vector<std::reference_wrapper<const Ssl::TlsCertificateConfig>>& tls_certificates,
100
    bool add_selector, Server::Configuration::CommonFactoryContext& factory_context,
101
    Ssl::ContextAdditionalInitFunc additional_init, absl::Status& creation_status)
102
3510
    : ContextImpl(scope, config, tls_certificates, factory_context, additional_init,
103
3510
                  creation_status),
104
3510
      session_ticket_keys_(config.sessionTicketKeys()),
105
3510
      ocsp_staple_policy_(config.ocspStaplePolicy()) {
106
3510
  if (!creation_status.ok()) {
107
17
    return;
108
17
  }
109
  // If creation failed, do not create the selector.
110
3493
  if (add_selector) {
111
3476
    tls_certificate_selector_ = config.tlsCertificateSelectorFactory().create(*this);
112
3476
  }
113

            
114
3493
  if (tls_certificates.empty() && !config.capabilities().provides_certificates &&
115
3493
      !(tls_certificate_selector_ && tls_certificate_selector_->providesCertificates())) {
116
1
    creation_status =
117
1
        absl::InvalidArgumentError("Server TlsCertificates must have a certificate specified");
118
1
    return;
119
1
  }
120

            
121
  // First, configure the base context for ClientHello interception.
122
  // TODO(htuch): replace with SSL_IDENTITY when we have this as a means to do multi-cert in
123
  // BoringSSL.
124
3492
  if (add_selector && !config.capabilities().provides_certificates) {
125
3474
    SSL_CTX_set_select_certificate_cb(
126
3474
        tls_contexts_[0].ssl_ctx_.get(),
127
3604
        [](const SSL_CLIENT_HELLO* client_hello) -> ssl_select_cert_result_t {
128
1309
          return static_cast<ServerContextImpl*>(
129
1309
                     SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)))
130
1309
              ->selectTlsContext(client_hello);
131
1309
        });
132
3474
  }
133

            
134
  // Compute the session context ID hash. We use all the certificate identities,
135
  // since we should have a common ID for session resumption no matter what cert
136
  // is used. We do this early because it can fail.
137
  // TODO(kuat): TLS selectors do not support resumption, so session ID is not populated.
138
3492
  absl::optional<SessionContextID> session_id;
139
3492
  if (!tls_certificates.empty()) {
140
3475
    absl::StatusOr<SessionContextID> id_or_error =
141
3475
        generateHashForSessionContextId(config.serverNames());
142
3475
    SET_AND_RETURN_IF_NOT_OK(id_or_error.status(), creation_status);
143
3474
    session_id = *id_or_error;
144
3474
  }
145

            
146
7052
  for (uint32_t i = 0; i < tls_contexts_.size(); ++i) {
147
3565
    auto& ctx = tls_contexts_[i];
148
3565
    if (!config.capabilities().verifies_peer_certificates) {
149
3565
      SET_AND_RETURN_IF_NOT_OK(cert_validator_->addClientValidationContext(
150
3565
                                   ctx.ssl_ctx_.get(), config.requireClientCertificate()),
151
3565
                               creation_status);
152
3565
    }
153

            
154
3565
    if (!parsed_alpn_protocols_.empty() && !config.capabilities().handles_alpn_selection) {
155
994
      SSL_CTX_set_alpn_select_cb(
156
994
          ctx.ssl_ctx_.get(),
157
994
          [](SSL*, const unsigned char** out, unsigned char* outlen, const unsigned char* in,
158
1083
             unsigned int inlen, void* arg) -> int {
159
703
            return static_cast<ServerContextImpl*>(arg)->alpnSelectCallback(out, outlen, in, inlen);
160
703
          },
161
994
          this);
162
994
    }
163

            
164
3565
    if (!config.preferClientCiphers()) {
165
      // Use server cipher preference based on config.
166
3563
      SSL_CTX_set_options(ctx.ssl_ctx_.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
167
3563
    }
168

            
169
    // If the handshaker handles session tickets natively, don't call
170
    // `SSL_CTX_set_tlsext_ticket_key_cb`.
171
3565
    if (config.disableStatelessSessionResumption()) {
172
35
      SSL_CTX_set_options(ctx.ssl_ctx_.get(), SSL_OP_NO_TICKET);
173
3553
    } else if (!session_ticket_keys_.empty() && !config.capabilities().handles_session_resumption) {
174
43
      SSL_CTX_set_tlsext_ticket_key_cb(
175
43
          ctx.ssl_ctx_.get(),
176
43
          [](SSL* ssl, uint8_t* key_name, uint8_t* iv, EVP_CIPHER_CTX* ctx, HMAC_CTX* hmac_ctx,
177
50
             int encrypt) -> int {
178
38
            ContextImpl* context_impl =
179
38
                static_cast<ContextImpl*>(SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
180
38
            ServerContextImpl* server_context_impl = dynamic_cast<ServerContextImpl*>(context_impl);
181
38
            RELEASE_ASSERT(server_context_impl != nullptr, ""); // for Coverity
182
38
            return server_context_impl->sessionTicketProcess(ssl, key_name, iv, ctx, hmac_ctx,
183
38
                                                             encrypt);
184
38
          });
185
43
    }
186

            
187
3565
    if (config.disableStatefulSessionResumption()) {
188
35
      SSL_CTX_set_session_cache_mode(ctx.ssl_ctx_.get(), SSL_SESS_CACHE_OFF);
189
35
    }
190

            
191
3565
    if (config.sessionTimeout() && !config.capabilities().handles_session_resumption) {
192
2
      auto timeout = config.sessionTimeout().value().count();
193
2
      SSL_CTX_set_timeout(ctx.ssl_ctx_.get(), uint32_t(timeout));
194
2
    }
195

            
196
3565
    if (session_id) {
197
3548
      int rc = SSL_CTX_set_session_id_context(ctx.ssl_ctx_.get(), session_id->data(),
198
3548
                                              session_id->size());
199
3548
      RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
200
3548
    }
201

            
202
    // tls_contexts_ is resized to be max(1, tls_certificates.size()) to it may be larger than
203
    // the number of certificates.
204
3565
    if (i < tls_certificates.size()) {
205
3548
      auto& ocsp_resp_bytes = tls_certificates[i].get().ocspStaple();
206
3548
      if (ocsp_resp_bytes.empty()) {
207
2363
        if (ctx.is_must_staple_) {
208
1
          creation_status =
209
1
              absl::InvalidArgumentError("OCSP response is required for must-staple certificate");
210
1
          return;
211
1
        }
212
2362
        if (ocsp_staple_policy_ == Ssl::ServerContextConfig::OcspStaplePolicy::MustStaple) {
213
1
          creation_status =
214
1
              absl::InvalidArgumentError("Required OCSP response is missing from TLS context");
215
1
          return;
216
1
        }
217
2708
      } else {
218
1185
        auto response_or_error =
219
1185
            Ocsp::OcspResponseWrapperImpl::create(ocsp_resp_bytes, factory_context_.timeSource());
220
1185
        SET_AND_RETURN_IF_NOT_OK(response_or_error.status(), creation_status);
221
1184
        if (!response_or_error.value()->matchesCertificate(*ctx.cert_chain_)) {
222
1
          creation_status =
223
1
              absl::InvalidArgumentError("OCSP response does not match its TLS certificate");
224
1
          return;
225
1
        }
226
1183
        ctx.ocsp_response_ = std::move(response_or_error.value());
227
1183
      }
228
3548
    }
229
3565
  }
230
3491
}
231

            
232
absl::StatusOr<ServerContextImpl::SessionContextID>
233
3475
ServerContextImpl::generateHashForSessionContextId(const std::vector<std::string>& server_names) {
234
3475
  uint8_t hash_buffer[EVP_MAX_MD_SIZE];
235
3475
  unsigned hash_length = 0;
236

            
237
3475
  bssl::ScopedEVP_MD_CTX md;
238

            
239
3475
  int rc = EVP_DigestInit(md.get(), EVP_sha256());
240
3475
  RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
241

            
242
  // Hash the CommonName/SANs of all the server certificates. This makes sure that sessions can only
243
  // be resumed to certificate(s) for the same name(s), but allows resuming to unique certs in the
244
  // case that different Envoy instances each have their own certs. All certificates in a
245
  // ServerContextImpl context are hashed together, since they all constitute a match on a filter
246
  // chain for resumption purposes.
247
3475
  if (!capabilities_.provides_certificates) {
248
3549
    for (const auto& ctx : tls_contexts_) {
249
3549
      X509* cert = SSL_CTX_get0_certificate(ctx.ssl_ctx_.get());
250
3549
      RELEASE_ASSERT(cert != nullptr, "TLS context should have an active certificate");
251
3549
      const X509_NAME* cert_subject = X509_get_subject_name(cert);
252
3549
      RELEASE_ASSERT(cert_subject != nullptr, "TLS certificate should have a subject");
253

            
254
3549
      const int cn_index = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, -1);
255
3549
      if (cn_index >= 0) {
256
3547
        const X509_NAME_ENTRY* cn_entry = X509_NAME_get_entry(cert_subject, cn_index);
257
3547
        RELEASE_ASSERT(cn_entry != nullptr, "certificate subject CN should be present");
258

            
259
3547
        const ASN1_STRING* cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry);
260
3547
        if (ASN1_STRING_length(cn_asn1) <= 0) {
261
          return absl::InvalidArgumentError("Invalid TLS context has an empty subject CN");
262
        }
263

            
264
3547
        rc =
265
3547
            EVP_DigestUpdate(md.get(), ASN1_STRING_get0_data(cn_asn1), ASN1_STRING_length(cn_asn1));
266
3547
        RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
267
3547
      }
268

            
269
3549
      unsigned san_count = 0;
270
3549
      bssl::UniquePtr<GENERAL_NAMES> san_names(static_cast<GENERAL_NAMES*>(
271
3549
          X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr)));
272

            
273
3549
      if (san_names != nullptr) {
274
11215
        for (const GENERAL_NAME* san : san_names.get()) {
275
11215
          switch (san->type) {
276
3484
          case GEN_IPADD:
277
3484
            rc = EVP_DigestUpdate(md.get(), san->d.iPAddress->data, san->d.iPAddress->length);
278
3484
            RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
279
3484
            ++san_count;
280
3484
            break;
281
4829
          case GEN_DNS:
282
4829
            rc = EVP_DigestUpdate(md.get(), ASN1_STRING_get0_data(san->d.dNSName),
283
4829
                                  ASN1_STRING_length(san->d.dNSName));
284
4829
            RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
285
4829
            ++san_count;
286
4829
            break;
287
2900
          case GEN_URI:
288
2900
            rc = EVP_DigestUpdate(md.get(), ASN1_STRING_get0_data(san->d.uniformResourceIdentifier),
289
2900
                                  ASN1_STRING_length(san->d.uniformResourceIdentifier));
290
2900
            RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
291
2900
            ++san_count;
292
2900
            break;
293
11215
          }
294
11215
        }
295
3407
      }
296

            
297
      // It's possible that the certificate doesn't have a subject, but
298
      // does have SANs. Make sure that we have one or the other.
299
3549
      if (cn_index < 0 && san_count == 0) {
300
1
        return absl::InvalidArgumentError(
301
1
            "Invalid TLS context has neither subject CN nor SAN names");
302
1
      }
303

            
304
3548
      rc = X509_NAME_digest(X509_get_issuer_name(cert), EVP_sha256(), hash_buffer, &hash_length);
305
3548
      RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
306
3548
      RELEASE_ASSERT(hash_length == SHA256_DIGEST_LENGTH,
307
3548
                     fmt::format("invalid SHA256 hash length {}", hash_length));
308

            
309
3548
      rc = EVP_DigestUpdate(md.get(), hash_buffer, hash_length);
310
3548
      RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
311
3548
    }
312
3475
  }
313

            
314
3474
  cert_validator_->updateDigestForSessionId(md, hash_buffer, hash_length);
315

            
316
  // Hash configured SNIs for this context, so that sessions cannot be resumed across different
317
  // filter chains, even when using the same server certificate.
318
3474
  for (const auto& name : server_names) {
319
28
    rc = EVP_DigestUpdate(md.get(), name.data(), name.size());
320
28
    RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
321
28
  }
322

            
323
3474
  SessionContextID session_id;
324

            
325
  // Ensure that the output size of the hash we are using is no greater than
326
  // TLS session ID length that we want to generate.
327
3474
  static_assert(session_id.size() == SHA256_DIGEST_LENGTH, "hash size mismatch");
328
3474
  static_assert(session_id.size() == SSL_MAX_SSL_SESSION_ID_LENGTH, "TLS session ID size mismatch");
329

            
330
3474
  rc = EVP_DigestFinal(md.get(), session_id.data(), &hash_length);
331
3474
  RELEASE_ASSERT(rc == 1, Utility::getLastCryptoError().value_or(""));
332
3474
  RELEASE_ASSERT(hash_length == session_id.size(),
333
3474
                 "SHA256 hash length must match TLS Session ID size");
334

            
335
3474
  return session_id;
336
3474
}
337

            
338
int ServerContextImpl::sessionTicketProcess(SSL*, uint8_t* key_name, uint8_t* iv,
339
38
                                            EVP_CIPHER_CTX* ctx, HMAC_CTX* hmac_ctx, int encrypt) {
340
38
  const EVP_MD* hmac = EVP_sha256();
341
38
  const EVP_CIPHER* cipher = EVP_aes_256_cbc();
342

            
343
38
  if (encrypt == 1) {
344
    // Encrypt
345
22
    RELEASE_ASSERT(!session_ticket_keys_.empty(), "");
346
    // TODO(ggreenway): validate in SDS that session_ticket_keys_ cannot be empty,
347
    // or if we allow it to be emptied, reconfigure the context so this callback
348
    // isn't set.
349

            
350
22
    const Envoy::Ssl::ServerContextConfig::SessionTicketKey& key = session_ticket_keys_.front();
351

            
352
22
    static_assert(std::tuple_size<decltype(key.name_)>::value == SSL_TICKET_KEY_NAME_LEN,
353
22
                  "Expected key.name length");
354
22
    std::copy_n(key.name_.begin(), SSL_TICKET_KEY_NAME_LEN, key_name);
355

            
356
22
    const int rc = RAND_bytes(iv, EVP_CIPHER_iv_length(cipher));
357
22
    ASSERT(rc);
358

            
359
    // This RELEASE_ASSERT is logically a static_assert, but we can't actually get
360
    // EVP_CIPHER_key_length(cipher) at compile-time
361
22
    RELEASE_ASSERT(key.aes_key_.size() == EVP_CIPHER_key_length(cipher), "");
362
22
    if (!EVP_EncryptInit_ex(ctx, cipher, nullptr, key.aes_key_.data(), iv)) {
363
      return -1;
364
    }
365

            
366
22
    if (!HMAC_Init_ex(hmac_ctx, key.hmac_key_.data(), key.hmac_key_.size(), hmac, nullptr)) {
367
      return -1;
368
    }
369

            
370
22
    return 1; // success
371
22
  } else {
372
    // Decrypt
373
16
    bool is_enc_key = true; // first element is the encryption key
374
16
    for (const Envoy::Ssl::ServerContextConfig::SessionTicketKey& key : session_ticket_keys_) {
375
16
      static_assert(std::tuple_size<decltype(key.name_)>::value == SSL_TICKET_KEY_NAME_LEN,
376
16
                    "Expected key.name length");
377
16
      if (std::equal(key.name_.begin(), key.name_.end(), key_name)) {
378
14
        if (!HMAC_Init_ex(hmac_ctx, key.hmac_key_.data(), key.hmac_key_.size(), hmac, nullptr)) {
379
          return -1;
380
        }
381

            
382
14
        RELEASE_ASSERT(key.aes_key_.size() == EVP_CIPHER_key_length(cipher), "");
383
14
        if (!EVP_DecryptInit_ex(ctx, cipher, nullptr, key.aes_key_.data(), iv)) {
384
          return -1;
385
        }
386

            
387
        // If our current encryption was not the decryption key, renew
388
14
        return is_enc_key ? 1  // success; do not renew
389
14
                          : 2; // success: renew key
390
14
      }
391
2
      is_enc_key = false;
392
2
    }
393

            
394
2
    return 0; // decryption failed
395
16
  }
396
38
}
397

            
398
// Returns a list of client capabilities for ECDSA curves as NIDs. An empty vector indicates
399
// a client that is unable to handle ECDSA.
400
Ssl::CurveNIDVector
401
1248
ServerContextImpl::getClientEcdsaCapabilities(const SSL_CLIENT_HELLO& ssl_client_hello) const {
402
1248
  CBS client_hello;
403
1248
  CBS_init(&client_hello, ssl_client_hello.client_hello, ssl_client_hello.client_hello_len);
404

            
405
  // This is the TLSv1.3 case (TLSv1.2 on the wire and the supported_versions extensions present).
406
  // We just need to look at signature algorithms.
407
1248
  const uint16_t client_version = ssl_client_hello.version;
408
1248
  if (client_version == TLS1_2_VERSION && tls_max_version_ == TLS1_3_VERSION) {
409
    // If the supported_versions extension is found then we assume that the client is competent
410
    // enough that just checking the signature_algorithms is sufficient.
411
1116
    const uint8_t* supported_versions_data;
412
1116
    size_t supported_versions_len;
413
1116
    if (SSL_early_callback_ctx_extension_get(&ssl_client_hello, TLSEXT_TYPE_supported_versions,
414
1116
                                             &supported_versions_data, &supported_versions_len)) {
415
225
      const uint8_t* signature_algorithms_data;
416
225
      size_t signature_algorithms_len;
417
225
      if (SSL_early_callback_ctx_extension_get(&ssl_client_hello, TLSEXT_TYPE_signature_algorithms,
418
225
                                               &signature_algorithms_data,
419
225
                                               &signature_algorithms_len)) {
420
225
        CBS signature_algorithms_ext, signature_algorithms;
421
225
        CBS_init(&signature_algorithms_ext, signature_algorithms_data, signature_algorithms_len);
422
225
        if (!CBS_get_u16_length_prefixed(&signature_algorithms_ext, &signature_algorithms) ||
423
225
            CBS_len(&signature_algorithms_ext) != 0) {
424
          return Ssl::CurveNIDVector{};
425
        }
426
225
        return getClientCurveNIDSupported(signature_algorithms);
427
225
      }
428

            
429
      return Ssl::CurveNIDVector{};
430
225
    }
431
1116
  }
432

            
433
  // Otherwise we are < TLSv1.3 and need to look at both the curves in the supported_groups for
434
  // ECDSA and also for a compatible cipher suite. https://tools.ietf.org/html/rfc4492#section-5.1.1
435
1023
  const uint8_t* curvelist_data;
436
1023
  size_t curvelist_len;
437
1023
  if (!SSL_early_callback_ctx_extension_get(&ssl_client_hello, TLSEXT_TYPE_supported_groups,
438
1023
                                            &curvelist_data, &curvelist_len)) {
439
    return Ssl::CurveNIDVector{};
440
  }
441

            
442
1023
  CBS curvelist;
443
1023
  CBS_init(&curvelist, curvelist_data, curvelist_len);
444

            
445
1023
  Ssl::CurveNIDVector client_capabilities = getClientCurveNIDSupported(curvelist);
446
  // if we haven't got any curves in common with the client, return empty CurveNIDVector.
447
1023
  if (client_capabilities.empty()) {
448
3
    return Ssl::CurveNIDVector{};
449
3
  }
450

            
451
  // The client must have offered an ECDSA ciphersuite that we like.
452
1020
  CBS cipher_suites;
453
1020
  CBS_init(&cipher_suites, ssl_client_hello.cipher_suites, ssl_client_hello.cipher_suites_len);
454

            
455
1113
  while (CBS_len(&cipher_suites) > 0) {
456
1047
    uint16_t cipher_id;
457
1047
    if (!CBS_get_u16(&cipher_suites, &cipher_id)) {
458
      return Ssl::CurveNIDVector{};
459
    }
460
    // All tls_context_ share the same set of enabled ciphers, so we can just look at the base
461
    // context.
462
1047
    if (tls_contexts_[0].isCipherEnabled(cipher_id, client_version)) {
463
954
      return client_capabilities;
464
954
    }
465
1047
  }
466

            
467
66
  return Ssl::CurveNIDVector{};
468
1020
}
469

            
470
1268
bool isClientOcspCapable(const SSL_CLIENT_HELLO& ssl_client_hello) {
471
1268
  const uint8_t* status_request_data;
472
1268
  size_t status_request_len;
473
1268
  if (SSL_early_callback_ctx_extension_get(&ssl_client_hello, TLSEXT_TYPE_status_request,
474
1268
                                           &status_request_data, &status_request_len)) {
475
10
    return true;
476
10
  }
477

            
478
1258
  return false;
479
1268
}
480

            
481
std::pair<const Ssl::TlsContext&, Ssl::OcspStapleAction>
482
ServerContextImpl::findTlsContext(absl::string_view sni,
483
                                  const Ssl::CurveNIDVector& client_ecdsa_capabilities,
484
4727
                                  bool client_ocsp_capable, bool* cert_matched_sni) {
485
4727
  ASSERT(tls_certificate_selector_ != nullptr);
486
4727
  return tls_certificate_selector_->findTlsContext(sni, client_ecdsa_capabilities,
487
4727
                                                   client_ocsp_capable, cert_matched_sni);
488
4727
}
489

            
490
enum ssl_select_cert_result_t
491
1309
ServerContextImpl::selectTlsContext(const SSL_CLIENT_HELLO* ssl_client_hello) {
492
1309
  ASSERT(tls_certificate_selector_ != nullptr);
493

            
494
1309
  auto* extended_socket_info = reinterpret_cast<Envoy::Ssl::SslExtendedSocketInfo*>(
495
1309
      SSL_get_ex_data(ssl_client_hello->ssl, ContextImpl::sslExtendedSocketInfoIndex()));
496

            
497
1309
  auto selection_result = extended_socket_info->certificateSelectionResult();
498
1309
  switch (selection_result) {
499
1276
  case Ssl::CertificateSelectionStatus::NotStarted:
500
    // continue
501
1276
    break;
502

            
503
27
  case Ssl::CertificateSelectionStatus::Pending:
504
27
    ENVOY_LOG(trace, "already waiting certificate");
505
27
    return ssl_select_cert_retry;
506

            
507
5
  case Ssl::CertificateSelectionStatus::Successful:
508
5
    ENVOY_LOG(trace, "wait certificate success");
509
5
    return ssl_select_cert_success;
510

            
511
1
  default:
512
1
    ENVOY_LOG(trace, "wait certificate failed");
513
1
    return ssl_select_cert_error;
514
1309
  }
515

            
516
1276
  ENVOY_LOG(trace, "TLS context selection result: {}, before selectTlsContext",
517
1276
            static_cast<int>(selection_result));
518

            
519
1276
  const auto result = tls_certificate_selector_->selectTlsContext(
520
1276
      *ssl_client_hello, extended_socket_info->createCertificateSelectionCallback());
521

            
522
1276
  ENVOY_LOG(trace,
523
1276
            "TLS context selection result: {}, after selectTlsContext, selection result status: {}",
524
1276
            static_cast<int>(extended_socket_info->certificateSelectionResult()),
525
1276
            static_cast<int>(result.status));
526
1276
  ASSERT(extended_socket_info->certificateSelectionResult() ==
527
1276
             Ssl::CertificateSelectionStatus::Pending,
528
1276
         "invalid selection result");
529

            
530
1276
  extended_socket_info->setCertSelectionHandle(std::move(result.handle));
531
1276
  switch (result.status) {
532
1251
  case Ssl::SelectionResult::SelectionStatus::Success:
533
1251
    extended_socket_info->onCertificateSelectionCompleted(*result.selected_ctx, result.staple,
534
1251
                                                          false);
535
1251
    return ssl_select_cert_success;
536
20
  case Ssl::SelectionResult::SelectionStatus::Pending:
537
20
    return ssl_select_cert_retry;
538
5
  case Ssl::SelectionResult::SelectionStatus::Failed:
539
5
    extended_socket_info->onCertificateSelectionCompleted(OptRef<const Ssl::TlsContext>(), false,
540
5
                                                          false);
541
5
    return ssl_select_cert_error;
542
1276
  }
543
  PANIC_DUE_TO_CORRUPT_ENUM;
544
}
545

            
546
absl::StatusOr<Ssl::ServerContextSharedPtr> ServerContextFactoryImpl::createServerContext(
547
    Stats::Scope& scope, const Envoy::Ssl::ServerContextConfig& config,
548
    Server::Configuration::CommonFactoryContext& factory_context,
549
3493
    Ssl::ContextAdditionalInitFunc additional_init) {
550
3493
  return ServerContextImpl::create(scope, config, factory_context, std::move(additional_init));
551
3493
}
552

            
553
REGISTER_FACTORY(ServerContextFactoryImpl, ServerContextFactory);
554

            
555
} // namespace Tls
556
} // namespace TransportSockets
557
} // namespace Extensions
558
} // namespace Envoy