1
#pragma once
2

            
3
#include <sys/types.h>
4

            
5
#include <cstdint>
6

            
7
#include "envoy/network/connection.h"
8
#include "envoy/network/transport_socket.h"
9
#include "envoy/secret/secret_callbacks.h"
10
#include "envoy/server/options.h"
11
#include "envoy/ssl/handshaker.h"
12
#include "envoy/ssl/private_key/private_key_callbacks.h"
13
#include "envoy/ssl/ssl_socket_extended_info.h"
14
#include "envoy/ssl/ssl_socket_state.h"
15
#include "envoy/stats/scope.h"
16
#include "envoy/stats/stats_macros.h"
17

            
18
#include "source/common/common/logger.h"
19
#include "source/common/tls/connection_info_impl_base.h"
20
#include "source/common/tls/utility.h"
21

            
22
#include "absl/container/node_hash_map.h"
23
#include "absl/synchronization/mutex.h"
24
#include "absl/types/optional.h"
25
#include "openssl/ssl.h"
26

            
27
namespace Envoy {
28
namespace Extensions {
29
namespace TransportSockets {
30
namespace Tls {
31

            
32
class SslHandshakerImpl;
33
class SslExtendedSocketInfoImpl;
34

            
35
class ValidateResultCallbackImpl : public Ssl::ValidateResultCallback {
36
public:
37
  ValidateResultCallbackImpl(Event::Dispatcher& dispatcher,
38
                             SslExtendedSocketInfoImpl& extended_socket_info)
39
1194
      : dispatcher_(dispatcher), extended_socket_info_(extended_socket_info) {}
40

            
41
7
  Event::Dispatcher& dispatcher() override { return dispatcher_; }
42

            
43
  void onCertValidationResult(bool succeeded, Ssl::ClientValidationStatus detailed_status,
44
                              const std::string& error_details, uint8_t tls_alert) override;
45

            
46
  void onSslHandshakeCancelled();
47

            
48
private:
49
  Event::Dispatcher& dispatcher_;
50
  OptRef<SslExtendedSocketInfoImpl> extended_socket_info_;
51
};
52

            
53
class CertificateSelectionCallbackImpl : public Ssl::CertificateSelectionCallback,
54
                                         protected Logger::Loggable<Logger::Id::connection> {
55
public:
56
  CertificateSelectionCallbackImpl(Event::Dispatcher& dispatcher,
57
                                   SslExtendedSocketInfoImpl& extended_socket_info)
58
1294
      : dispatcher_(dispatcher), extended_socket_info_(extended_socket_info) {}
59

            
60
31
  Event::Dispatcher& dispatcher() override { return dispatcher_; }
61

            
62
  void onCertificateSelectionResult(OptRef<const Ssl::TlsContext> selected_ctx,
63
                                    bool staple) override;
64

            
65
  void onSslHandshakeCancelled();
66

            
67
private:
68
  Event::Dispatcher& dispatcher_;
69
  OptRef<SslExtendedSocketInfoImpl> extended_socket_info_;
70
};
71

            
72
class SslExtendedSocketInfoImpl : public Envoy::Ssl::SslExtendedSocketInfo {
73
public:
74
2591
  explicit SslExtendedSocketInfoImpl(SslHandshakerImpl& handshaker) : ssl_handshaker_(handshaker) {}
75
  // Overridden to notify cert_validate_result_callback_ that the handshake has been cancelled.
76
  ~SslExtendedSocketInfoImpl() override;
77

            
78
  void setCertificateValidationStatus(Envoy::Ssl::ClientValidationStatus validated) override;
79
  Envoy::Ssl::ClientValidationStatus certificateValidationStatus() const override;
80
  Ssl::ValidateResultCallbackPtr createValidateResultCallback() override;
81
  void onCertificateValidationCompleted(bool succeeded, bool async) override;
82
1230
  Ssl::ValidateStatus certificateValidationResult() const override {
83
1230
    return cert_validation_result_;
84
1230
  }
85
6
  uint8_t certificateValidationAlert() const override { return cert_validation_alert_; }
86

            
87
7
  void setCertificateValidationAlert(uint8_t alert) { cert_validation_alert_ = alert; }
88

            
89
  Ssl::CertificateSelectionCallbackPtr createCertificateSelectionCallback() override;
90
1294
  void setCertSelectionHandle(Ssl::SelectionHandleConstSharedPtr cert_selection_handle) override {
91
1294
    ASSERT(cert_selection_handle_ == nullptr);
92
1294
    cert_selection_handle_ = std::move(cert_selection_handle);
93
1294
  }
94
  void onCertificateSelectionCompleted(OptRef<const Ssl::TlsContext> selected_ctx, bool staple,
95
                                       bool async) override;
96
1353
  Ssl::CertificateSelectionStatus certificateSelectionResult() const override {
97
1353
    return cert_selection_result_;
98
1353
  }
99

            
100
59
  void setCertificateValidationError(absl::string_view error_details) override {
101
59
    cert_validation_error_ = std::string(error_details);
102
59
  }
103
60
  absl::string_view certificateValidationError() const override { return cert_validation_error_; }
104

            
105
private:
106
  Envoy::Ssl::ClientValidationStatus certificate_validation_status_{
107
      Envoy::Ssl::ClientValidationStatus::NotValidated};
108
  SslHandshakerImpl& ssl_handshaker_;
109
  // Latch the in-flight async cert validation callback.
110
  // nullopt if there is none.
111
  OptRef<ValidateResultCallbackImpl> cert_validate_result_callback_;
112
  // Stores the TLS alert.
113
  uint8_t cert_validation_alert_{SSL_AD_CERTIFICATE_UNKNOWN};
114
  // Stores the validation result if there is any.
115
  // nullopt if no validation has ever been kicked off.
116
  Ssl::ValidateStatus cert_validation_result_{Ssl::ValidateStatus::NotStarted};
117
  // Latch the in-flight cert selection callback.
118
  // nullopt if there is none.
119
  OptRef<CertificateSelectionCallbackImpl> cert_selection_callback_{absl::nullopt};
120
  // Stores the cert selection result if there is any.
121
  // NotStarted if no cert selection has ever been kicked off.
122
  Ssl::CertificateSelectionStatus cert_selection_result_{
123
      Ssl::CertificateSelectionStatus::NotStarted};
124
  // Stores the detailed certificate validation error message.
125
  std::string cert_validation_error_;
126
  // Stores additional per-connection data needed by the certificate selector.
127
  Ssl::SelectionHandleConstSharedPtr cert_selection_handle_;
128
};
129

            
130
class SslHandshakerImpl : public ConnectionInfoImplBase,
131
                          public Ssl::Handshaker,
132
                          protected Logger::Loggable<Logger::Id::connection> {
133
public:
134
  SslHandshakerImpl(bssl::UniquePtr<SSL> ssl, int ssl_extended_socket_info_index,
135
                    Ssl::HandshakeCallbacks* handshake_callbacks);
136

            
137
  // Ssl::ConnectionInfo
138
  bool peerCertificateValidated() const override;
139

            
140
  // ConnectionInfoImplBase
141
91561
  SSL* ssl() const override { return ssl_.get(); }
142

            
143
  // Ssl::Handshaker
144
  Network::PostIoAction doHandshake() override;
145

            
146
55399
  Ssl::SocketState state() const { return state_; }
147
2503
  void setState(Ssl::SocketState state) { state_ = state; }
148
2527
  Ssl::HandshakeCallbacks* handshakeCallbacks() { return handshake_callbacks_; }
149

            
150
  bssl::UniquePtr<SSL> ssl_;
151

            
152
private:
153
  Ssl::HandshakeCallbacks* handshake_callbacks_;
154

            
155
  Ssl::SocketState state_{Ssl::SocketState::PreHandshake};
156
  mutable SslExtendedSocketInfoImpl extended_socket_info_;
157
};
158

            
159
using SslHandshakerImplSharedPtr = std::shared_ptr<SslHandshakerImpl>;
160

            
161
class HandshakerFactoryContextImpl : public Ssl::HandshakerFactoryContext {
162
public:
163
  HandshakerFactoryContextImpl(Api::Api& api, const Server::Options& options,
164
                               absl::string_view alpn_protocols,
165
                               Singleton::Manager& singleton_manager,
166
                               Server::ServerLifecycleNotifier& lifecycle_notifier)
167
7070
      : api_(api), options_(options), alpn_protocols_(alpn_protocols),
168
7070
        singleton_manager_(singleton_manager), lifecycle_notifier_(lifecycle_notifier) {}
169

            
170
  // HandshakerFactoryContext
171
5
  Api::Api& api() override { return api_; }
172
1
  const Server::Options& options() const override { return options_; }
173
  absl::string_view alpnProtocols() const override { return alpn_protocols_; }
174
  Singleton::Manager& singletonManager() override { return singleton_manager_; }
175
1
  Server::ServerLifecycleNotifier& lifecycleNotifier() override { return lifecycle_notifier_; }
176

            
177
private:
178
  Api::Api& api_;
179
  const Server::Options& options_;
180
  const std::string alpn_protocols_;
181
  Singleton::Manager& singleton_manager_;
182
  Server::ServerLifecycleNotifier& lifecycle_notifier_;
183
};
184

            
185
class HandshakerFactoryImpl : public Ssl::HandshakerFactory {
186
public:
187
  std::string name() const override { return "envoy.default_tls_handshaker"; }
188

            
189
7066
  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
190
7066
    return ProtobufTypes::MessagePtr{new Envoy::Protobuf::Struct()};
191
7066
  }
192

            
193
  Ssl::HandshakerFactoryCb createHandshakerCb(const Protobuf::Message&,
194
                                              Ssl::HandshakerFactoryContext&,
195
7066
                                              ProtobufMessage::ValidationVisitor&) override {
196
    // The default HandshakerImpl doesn't take a config or use the HandshakerFactoryContext.
197
7066
    return [](bssl::UniquePtr<SSL> ssl, int ssl_extended_socket_info_index,
198
7291
              Ssl::HandshakeCallbacks* handshake_callbacks) {
199
2582
      return std::make_shared<SslHandshakerImpl>(std::move(ssl), ssl_extended_socket_info_index,
200
2582
                                                 handshake_callbacks);
201
2582
    };
202
7066
  }
203

            
204
7069
  Ssl::HandshakerCapabilities capabilities() const override {
205
    // The default handshaker impl requires Envoy to handle all enumerated behaviors.
206
7069
    return Ssl::HandshakerCapabilities{};
207
7069
  }
208

            
209
7066
  Ssl::SslCtxCb sslctxCb(Ssl::HandshakerFactoryContext&) const override {
210
    // The default handshaker impl doesn't additionally modify SSL_CTX.
211
7066
    return nullptr;
212
7066
  }
213

            
214
7066
  static HandshakerFactory* getDefaultHandshakerFactory() {
215
7066
    static HandshakerFactoryImpl default_handshaker_factory;
216
7066
    return &default_handshaker_factory;
217
7066
  }
218
};
219

            
220
} // namespace Tls
221
} // namespace TransportSockets
222
} // namespace Extensions
223
} // namespace Envoy