1
#include "source/common/tls/client_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
namespace Extensions {
44
namespace TransportSockets {
45
namespace Tls {
46

            
47
absl::StatusOr<std::unique_ptr<ClientContextImpl>>
48
ClientContextImpl::create(Stats::Scope& scope, const Envoy::Ssl::ClientContextConfig& config,
49
3504
                          Server::Configuration::CommonFactoryContext& factory_context) {
50
3504
  absl::Status creation_status = absl::OkStatus();
51
3504
  auto ret = std::unique_ptr<ClientContextImpl>(new ClientContextImpl(
52
3504
      scope, config, config.tlsCertificates(), true, factory_context, creation_status));
53
3504
  RETURN_IF_NOT_OK(creation_status);
54
3483
  return ret;
55
3504
}
56

            
57
ClientContextImpl::ClientContextImpl(
58
    Stats::Scope& scope, const Envoy::Ssl::ClientContextConfig& config,
59
    const std::vector<std::reference_wrapper<const Ssl::TlsCertificateConfig>>& tls_certificates,
60
    bool add_selector, Server::Configuration::CommonFactoryContext& factory_context,
61
    absl::Status& creation_status)
62
3517
    : ContextImpl(scope, config, tls_certificates, factory_context, nullptr /* additional_init */,
63
3517
                  creation_status),
64
3517
      server_name_indication_(config.serverNameIndication()),
65
3517
      auto_host_sni_(config.autoHostServerNameIndication()),
66
3517
      allow_renegotiation_(config.allowRenegotiation()),
67
3517
      enforce_rsa_key_usage_(config.enforceRsaKeyUsage()),
68
3517
      max_session_keys_(config.maxSessionKeys()) {
69
3517
  if (!creation_status.ok()) {
70
20
    return;
71
20
  }
72

            
73
  // Disallow insecure configuration.
74
3497
  if (config.autoSniSanMatch() && config.certificateValidationContext() == nullptr) {
75
1
    creation_status = absl::InvalidArgumentError(
76
1
        "'auto_sni_san_validation' was configured without a validation context");
77
1
    return;
78
1
  }
79

            
80
  // This should be guaranteed during configuration ingestion for client contexts.
81
3496
  if (tls_contexts_.size() != 1) {
82
    creation_status =
83
        absl::InvalidArgumentError("Client TLS context supports only a single certificate");
84
    return;
85
  }
86

            
87
3496
  if (!parsed_alpn_protocols_.empty()) {
88
1111
    for (auto& ctx : tls_contexts_) {
89
1111
      const int rc = SSL_CTX_set_alpn_protos(ctx.ssl_ctx_.get(), parsed_alpn_protocols_.data(),
90
1111
                                             parsed_alpn_protocols_.size());
91
1111
      RELEASE_ASSERT(rc == 0, Utility::getLastCryptoError().value_or(""));
92
1111
    }
93
1111
  }
94

            
95
3496
  if (max_session_keys_ > 0) {
96
3480
    SSL_CTX_set_session_cache_mode(tls_contexts_[0].ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT);
97
3480
    SSL_CTX_sess_set_new_cb(
98
3521
        tls_contexts_[0].ssl_ctx_.get(), [](SSL* ssl, SSL_SESSION* session) -> int {
99
863
          ContextImpl* context_impl =
100
863
              static_cast<ContextImpl*>(SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
101
863
          ClientContextImpl* client_context_impl = dynamic_cast<ClientContextImpl*>(context_impl);
102
863
          RELEASE_ASSERT(client_context_impl != nullptr, ""); // for Coverity
103
863
          return client_context_impl->newSessionKey(session);
104
863
        });
105
3480
  }
106

            
107
3496
  if (add_selector) {
108
3483
    if (auto factory = config.tlsCertificateSelectorFactory(); factory) {
109
14
      tls_certificate_selector_ = factory->createUpstreamTlsCertificateSelector(*this);
110
14
      SSL_CTX_set_cert_cb(
111
14
          tls_contexts_[0].ssl_ctx_.get(),
112
32
          [](SSL* ssl, void*) -> int {
113
32
            return static_cast<ClientContextImpl*>(SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)))
114
32
                ->selectTlsContext(ssl);
115
32
          },
116
14
          nullptr);
117
14
    }
118
3483
  }
119
3496
}
120

            
121
absl::StatusOr<bssl::UniquePtr<SSL>>
122
ClientContextImpl::newSsl(const Network::TransportSocketOptionsConstSharedPtr& options,
123
1198
                          Upstream::HostDescriptionConstSharedPtr host) {
124
1198
  absl::StatusOr<bssl::UniquePtr<SSL>> ssl_con_or_status(ContextImpl::newSsl(options, host));
125
1198
  if (!ssl_con_or_status.ok()) {
126
    return ssl_con_or_status;
127
  }
128

            
129
1198
  bssl::UniquePtr<SSL> ssl_con = std::move(ssl_con_or_status.value());
130

            
131
1198
  std::string server_name_indication;
132
1198
  if (options && options->serverNameOverride().has_value()) {
133
189
    server_name_indication = options->serverNameOverride().value();
134
1188
  } else if (auto_host_sni_ && host != nullptr && !host->hostname().empty()) {
135
5
    server_name_indication = host->hostname();
136
1007
  } else {
137
1004
    server_name_indication = server_name_indication_;
138
1004
  }
139

            
140
1198
  if (!server_name_indication.empty()) {
141
264
    const int rc = SSL_set_tlsext_host_name(ssl_con.get(), server_name_indication.c_str());
142
264
    if (rc != 1) {
143
2
      return absl::InvalidArgumentError(
144
2
          absl::StrCat("Failed to create upstream TLS due to failure setting SNI: ",
145
2
                       Utility::getLastCryptoError().value_or("unknown")));
146
2
    }
147
264
  }
148

            
149
1196
  if (options && !options->verifySubjectAltNameListOverride().empty()) {
150
62
    SSL_set_verify(ssl_con.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
151
62
  }
152

            
153
  // We determine what ALPN using the following precedence:
154
  // 1. Option-provided ALPN override.
155
  // 2. ALPN statically configured in the upstream TLS context.
156
  // 3. Option-provided ALPN fallback.
157

            
158
  // At this point in the code the ALPN has already been set (if present) to the value specified in
159
  // the TLS context. We've stored this value in parsed_alpn_protocols_ so we can check that to see
160
  // if it's already been set.
161
1196
  bool has_alpn_defined = !parsed_alpn_protocols_.empty();
162
1196
  absl::Status parse_status = absl::OkStatus();
163
1196
  if (options) {
164
    // ALPN override takes precedence over TLS context specified, so blindly overwrite it.
165
711
    has_alpn_defined |=
166
711
        parseAndSetAlpn(options->applicationProtocolListOverride(), *ssl_con, parse_status);
167
711
  }
168

            
169
1196
  if (options && !has_alpn_defined && !options->applicationProtocolFallback().empty()) {
170
    // If ALPN hasn't already been set (either through TLS context or override), use the fallback.
171
602
    parseAndSetAlpn(options->applicationProtocolFallback(), *ssl_con, parse_status);
172
602
  }
173
1196
  RETURN_IF_NOT_OK(parse_status);
174

            
175
1196
  if (allow_renegotiation_) {
176
25
    SSL_set_renegotiate_mode(ssl_con.get(), ssl_renegotiate_freely);
177
25
  }
178

            
179
1196
  SSL_set_enforce_rsa_key_usage(ssl_con.get(), enforce_rsa_key_usage_);
180

            
181
1196
  if (max_session_keys_ > 0) {
182
1192
    if (session_keys_single_use_) {
183
      // Stored single-use session keys, use write/write locks.
184
1
      absl::WriterMutexLock l(session_keys_mu_);
185
1
      if (!session_keys_.empty()) {
186
        // Use the most recently stored session key, since it has the highest
187
        // probability of still being recognized/accepted by the server.
188
1
        SSL_SESSION* session = session_keys_.front().get();
189
1
        SSL_set_session(ssl_con.get(), session);
190
        // Remove single-use session key (TLS 1.3) after first use.
191
1
        if (SSL_SESSION_should_be_single_use(session)) {
192
1
          session_keys_.pop_front();
193
1
        }
194
1
      }
195
1191
    } else {
196
      // Never stored single-use session keys, use read/write locks.
197
1191
      absl::ReaderMutexLock l(session_keys_mu_);
198
1191
      if (!session_keys_.empty()) {
199
        // Use the most recently stored session key, since it has the highest
200
        // probability of still being recognized/accepted by the server.
201
209
        SSL_SESSION* session = session_keys_.front().get();
202
209
        SSL_set_session(ssl_con.get(), session);
203
209
      }
204
1191
    }
205
1192
  }
206

            
207
1196
  return ssl_con;
208
1196
}
209

            
210
863
int ClientContextImpl::newSessionKey(SSL_SESSION* session) {
211
  // In case we ever store single-use session key (TLS 1.3),
212
  // we need to switch to using write/write locks.
213
863
  if (SSL_SESSION_should_be_single_use(session)) {
214
52
    session_keys_single_use_ = true;
215
52
  }
216
863
  absl::WriterMutexLock l(session_keys_mu_);
217
  // Evict oldest entries.
218
939
  while (session_keys_.size() >= max_session_keys_) {
219
76
    session_keys_.pop_back();
220
76
  }
221
  // Add new session key at the front of the queue, so that it's used first.
222
863
  session_keys_.push_front(bssl::UniquePtr<SSL_SESSION>(session));
223
863
  return 1; // Tell BoringSSL that we took ownership of the session.
224
863
}
225

            
226
// This callback should return 1 on success, 0 on internal error, and negative number
227
// on failure or pause a handshake.
228
32
int ClientContextImpl::selectTlsContext(SSL* ssl) {
229
32
  ASSERT(tls_certificate_selector_ != nullptr);
230

            
231
32
  auto* extended_socket_info = reinterpret_cast<Envoy::Ssl::SslExtendedSocketInfo*>(
232
32
      SSL_get_ex_data(ssl, ContextImpl::sslExtendedSocketInfoIndex()));
233

            
234
32
  auto selection_result = extended_socket_info->certificateSelectionResult();
235
32
  switch (selection_result) {
236
18
  case Ssl::CertificateSelectionStatus::NotStarted:
237
    // continue
238
18
    break;
239

            
240
12
  case Ssl::CertificateSelectionStatus::Pending:
241
12
    ENVOY_LOG(trace, "already waiting certificate");
242
12
    return -1;
243

            
244
1
  case Ssl::CertificateSelectionStatus::Successful:
245
1
    ENVOY_LOG(trace, "wait certificate success");
246
1
    return 1;
247

            
248
1
  default:
249
1
    ENVOY_LOG(trace, "wait certificate failed");
250
1
    return 0;
251
32
  }
252

            
253
18
  ENVOY_LOG(trace, "upstream TLS context selection result: {}, before selectTlsContext",
254
18
            static_cast<int>(selection_result));
255
18
  auto transport_socket_options_shared_ptr_ptr =
256
18
      static_cast<const Network::TransportSocketOptionsConstSharedPtr*>(SSL_get_app_data(ssl));
257
18
  ASSERT(transport_socket_options_shared_ptr_ptr);
258

            
259
18
  const auto result = tls_certificate_selector_->selectTlsContext(
260
18
      *ssl, *transport_socket_options_shared_ptr_ptr,
261
18
      extended_socket_info->createCertificateSelectionCallback());
262

            
263
18
  ENVOY_LOG(trace,
264
18
            "upstream TLS context selection result: {}, after selectTlsContext, selection result "
265
18
            "status: {}",
266
18
            static_cast<int>(extended_socket_info->certificateSelectionResult()),
267
18
            static_cast<int>(result.status));
268
18
  ASSERT(extended_socket_info->certificateSelectionResult() ==
269
18
             Ssl::CertificateSelectionStatus::Pending,
270
18
         "invalid selection result");
271

            
272
18
  extended_socket_info->setCertSelectionHandle(std::move(result.handle));
273
18
  switch (result.status) {
274
5
  case Ssl::SelectionResult::SelectionStatus::Success:
275
5
    extended_socket_info->onCertificateSelectionCompleted(*result.selected_ctx, result.staple,
276
5
                                                          false);
277
5
    return 1;
278
12
  case Ssl::SelectionResult::SelectionStatus::Pending:
279
12
    return -1;
280
1
  case Ssl::SelectionResult::SelectionStatus::Failed:
281
1
    extended_socket_info->onCertificateSelectionCompleted(OptRef<const Ssl::TlsContext>(), false,
282
1
                                                          false);
283
1
    return 0;
284
18
  }
285
  PANIC_DUE_TO_CORRUPT_ENUM;
286
}
287

            
288
} // namespace Tls
289
} // namespace TransportSockets
290
} // namespace Extensions
291
} // namespace Envoy