/proc/self/cwd/envoy/ssl/handshaker.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include "envoy/api/api.h" |
4 | | #include "envoy/config/typed_config.h" |
5 | | #include "envoy/network/connection.h" |
6 | | #include "envoy/network/post_io_action.h" |
7 | | #include "envoy/protobuf/message_validator.h" |
8 | | #include "envoy/server/lifecycle_notifier.h" |
9 | | #include "envoy/server/options.h" |
10 | | #include "envoy/singleton/manager.h" |
11 | | |
12 | | #include "openssl/ssl.h" |
13 | | |
14 | | namespace Envoy { |
15 | | |
16 | | namespace Server { |
17 | | namespace Configuration { |
18 | | class CommonFactoryContext; |
19 | | } // namespace Configuration |
20 | | } // namespace Server |
21 | | |
22 | | namespace Ssl { |
23 | | |
24 | | // Opaque type defined and used by the ``ServerContext``. |
25 | | struct TlsContext; |
26 | | |
27 | | class ServerContextConfig; |
28 | | |
29 | | class HandshakeCallbacks { |
30 | | public: |
31 | 0 | virtual ~HandshakeCallbacks() = default; |
32 | | |
33 | | /** |
34 | | * @return the connection. |
35 | | */ |
36 | | virtual Network::Connection& connection() const PURE; |
37 | | |
38 | | /** |
39 | | * A callback which will be executed at most once upon successful completion |
40 | | * of a handshake. |
41 | | */ |
42 | | virtual void onSuccess(SSL* ssl) PURE; |
43 | | |
44 | | /** |
45 | | * A callback which will be executed at most once upon handshake failure. |
46 | | */ |
47 | | virtual void onFailure() PURE; |
48 | | |
49 | | /** |
50 | | * Returns a pointer to the transportSocketCallbacks struct, or nullptr if |
51 | | * unset. |
52 | | */ |
53 | | virtual Network::TransportSocketCallbacks* transportSocketCallbacks() PURE; |
54 | | |
55 | | /** |
56 | | * A callback to be called upon certificate validation completion if the validation is |
57 | | * asynchronous. |
58 | | */ |
59 | | virtual void onAsynchronousCertValidationComplete() PURE; |
60 | | |
61 | | /** |
62 | | * A callback to be called upon certificate selection completion if the selection is |
63 | | * asynchronous. |
64 | | */ |
65 | | virtual void onAsynchronousCertificateSelectionComplete() PURE; |
66 | | }; |
67 | | |
68 | | /** |
69 | | * Base interface for performing TLS handshakes. |
70 | | */ |
71 | | class Handshaker { |
72 | | public: |
73 | 0 | virtual ~Handshaker() = default; |
74 | | |
75 | | /** |
76 | | * Performs a TLS handshake and returns an action indicating |
77 | | * whether the callsite should close the connection or keep it open. |
78 | | */ |
79 | | virtual Network::PostIoAction doHandshake() PURE; |
80 | | }; |
81 | | |
82 | | using HandshakerSharedPtr = std::shared_ptr<Handshaker>; |
83 | | using HandshakerFactoryCb = |
84 | | std::function<HandshakerSharedPtr(bssl::UniquePtr<SSL>, int, HandshakeCallbacks*)>; |
85 | | |
86 | | // Callback for modifying an SSL_CTX. |
87 | | using SslCtxCb = std::function<void(SSL_CTX*)>; |
88 | | |
89 | | class HandshakerFactoryContext { |
90 | | public: |
91 | 0 | virtual ~HandshakerFactoryContext() = default; |
92 | | |
93 | | /** |
94 | | * Returns the singleton manager. |
95 | | */ |
96 | | virtual Singleton::Manager& singletonManager() PURE; |
97 | | |
98 | | /** |
99 | | * @return reference to the server options |
100 | | */ |
101 | | virtual const Server::Options& options() const PURE; |
102 | | |
103 | | /** |
104 | | * @return reference to the Api object |
105 | | */ |
106 | | virtual Api::Api& api() PURE; |
107 | | |
108 | | /** |
109 | | * The list of supported protocols exposed via ALPN, from ContextConfig. |
110 | | */ |
111 | | virtual absl::string_view alpnProtocols() const PURE; |
112 | | |
113 | | /** |
114 | | * @return reference to the server lifecycle notifier |
115 | | */ |
116 | | virtual Server::ServerLifecycleNotifier& lifecycleNotifier() PURE; |
117 | | }; |
118 | | |
119 | | struct HandshakerCapabilities { |
120 | | // Whether or not a handshaker implementation provides certificates itself. |
121 | | bool provides_certificates = false; |
122 | | |
123 | | // Whether or not a handshaker implementation verifies certificates itself. |
124 | | bool verifies_peer_certificates = false; |
125 | | |
126 | | // Whether or not a handshaker implementation handles session resumption |
127 | | // itself. |
128 | | bool handles_session_resumption = false; |
129 | | |
130 | | // Whether or not a handshaker implementation provides its own list of ciphers |
131 | | // and curves. |
132 | | bool provides_ciphers_and_curves = false; |
133 | | |
134 | | // Whether or not a handshaker implementation handles ALPN selection. |
135 | | bool handles_alpn_selection = false; |
136 | | |
137 | | // Should return true if this handshaker is FIPS-compliant. |
138 | | // Envoy will fail to compile if this returns true and `--define=boringssl=fips`. |
139 | | bool is_fips_compliant = true; |
140 | | |
141 | | // Whether or not a handshaker implementation provides its own list of |
142 | | // supported signature algorithms. |
143 | | bool provides_sigalgs = false; |
144 | | }; |
145 | | |
146 | | class HandshakerFactory : public Config::TypedFactory { |
147 | | public: |
148 | | /** |
149 | | * @returns a callback to create a Handshaker. Accepts the |config| and |
150 | | * |validation_visitor| for early validation. This virtual base doesn't |
151 | | * perform MessageUtil::downcastAndValidate, but an implementation should. |
152 | | */ |
153 | | virtual HandshakerFactoryCb |
154 | | createHandshakerCb(const Protobuf::Message& message, |
155 | | HandshakerFactoryContext& handshaker_factory_context, |
156 | | ProtobufMessage::ValidationVisitor& validation_visitor) PURE; |
157 | | |
158 | 0 | std::string category() const override { return "envoy.tls_handshakers"; } |
159 | | |
160 | | /** |
161 | | * Implementations should return a struct with their capabilities. See |
162 | | * HandshakerCapabilities above. For any capability a Handshaker |
163 | | * implementation explicitly declares, Envoy will not also configure that SSL |
164 | | * capability. |
165 | | */ |
166 | | virtual HandshakerCapabilities capabilities() const PURE; |
167 | | |
168 | | /** |
169 | | * Implementations should return a callback for configuring an SSL_CTX context |
170 | | * before it is used to create any SSL objects. Providing |
171 | | * |handshaker_factory_context| as an argument allows callsites to access the |
172 | | * API and other factory context methods. |
173 | | */ |
174 | | virtual SslCtxCb sslctxCb(HandshakerFactoryContext& handshaker_factory_context) const PURE; |
175 | | }; |
176 | | |
177 | | struct SelectionResult { |
178 | | enum class SelectionStatus { |
179 | | // A certificate was successfully selected. |
180 | | Success, |
181 | | // Certificate selection will complete asynchronously later. |
182 | | Pending, |
183 | | // Certificate selection failed. |
184 | | Failed, |
185 | | }; |
186 | | SelectionStatus status; // Status of the certificate selection. |
187 | | // Selected TLS context which it only be non-null when status is Success. |
188 | | const Ssl::TlsContext* selected_ctx; |
189 | | // True if OCSP stapling should be enabled. |
190 | | bool staple; |
191 | | }; |
192 | | |
193 | | /** |
194 | | * Used to return the result from an asynchronous cert selection. |
195 | | */ |
196 | | class CertificateSelectionCallback { |
197 | | public: |
198 | 0 | virtual ~CertificateSelectionCallback() = default; |
199 | | |
200 | | virtual Event::Dispatcher& dispatcher() PURE; |
201 | | |
202 | | /** |
203 | | * Called when the asynchronous cert selection completes. |
204 | | * @param selected_ctx selected Ssl::TlsContext, it's empty when selection failed. |
205 | | * @param staple true when need to set OCSP response. |
206 | | */ |
207 | | virtual void onCertificateSelectionResult(OptRef<const Ssl::TlsContext> selected_ctx, |
208 | | bool staple) PURE; |
209 | | }; |
210 | | |
211 | | using CertificateSelectionCallbackPtr = std::unique_ptr<CertificateSelectionCallback>; |
212 | | |
213 | | enum class OcspStapleAction { Staple, NoStaple, Fail, ClientNotCapable }; |
214 | | |
215 | | class TlsCertificateSelector { |
216 | | public: |
217 | 0 | virtual ~TlsCertificateSelector() = default; |
218 | | |
219 | | /** |
220 | | * Select TLS context based on the client hello in non-QUIC TLS handshake. |
221 | | * |
222 | | * @return selected_ctx should only not be null when status is SelectionStatus::Success, and it |
223 | | * will have the same lifetime as ``ServerContextImpl``. |
224 | | */ |
225 | | virtual SelectionResult selectTlsContext(const SSL_CLIENT_HELLO& ssl_client_hello, |
226 | | CertificateSelectionCallbackPtr cb) PURE; |
227 | | |
228 | | /** |
229 | | * Finds the best matching context in QUIC TLS handshake, which doesn't support async mode yet. |
230 | | * |
231 | | * @return context will have the same lifetime as ``ServerContextImpl``. |
232 | | */ |
233 | | virtual std::pair<const Ssl::TlsContext&, OcspStapleAction> |
234 | | findTlsContext(absl::string_view sni, bool client_ecdsa_capable, bool client_ocsp_capable, |
235 | | bool* cert_matched_sni) PURE; |
236 | | }; |
237 | | |
238 | | using TlsCertificateSelectorPtr = std::unique_ptr<TlsCertificateSelector>; |
239 | | |
240 | | class TlsCertificateSelectorContext { |
241 | | public: |
242 | 0 | virtual ~TlsCertificateSelectorContext() = default; |
243 | | |
244 | | /** |
245 | | * @return reference to the initialized Tls Contexts. |
246 | | */ |
247 | | virtual const std::vector<TlsContext>& getTlsContexts() const PURE; |
248 | | }; |
249 | | |
250 | | using TlsCertificateSelectorFactory = std::function<TlsCertificateSelectorPtr( |
251 | | const ServerContextConfig&, TlsCertificateSelectorContext&)>; |
252 | | |
253 | | class TlsCertificateSelectorConfigFactory : public Config::TypedFactory { |
254 | | public: |
255 | | /** |
256 | | * @param for_quic true when in quic context, which does not support selecting certificate |
257 | | * asynchronously. |
258 | | * @returns a factory to create a TlsCertificateSelector. Accepts the |config| and |
259 | | * |validation_visitor| for early validation. This virtual base doesn't |
260 | | * perform MessageUtil::downcastAndValidate, but an implementation should. |
261 | | */ |
262 | | virtual TlsCertificateSelectorFactory |
263 | | createTlsCertificateSelectorFactory(const Protobuf::Message& config, |
264 | | Server::Configuration::CommonFactoryContext& factory_context, |
265 | | ProtobufMessage::ValidationVisitor& validation_visitor, |
266 | | absl::Status& creation_status, bool for_quic) PURE; |
267 | | |
268 | 0 | std::string category() const override { return "envoy.tls.certificate_selectors"; } |
269 | | }; |
270 | | |
271 | | } // namespace Ssl |
272 | | } // namespace Envoy |