/src/botan/build/include/botan/tls_messages.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * TLS Messages |
3 | | * (C) 2004-2011,2015 Jack Lloyd |
4 | | * 2016 Matthias Gierlings |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #ifndef BOTAN_TLS_MESSAGES_H_ |
10 | | #define BOTAN_TLS_MESSAGES_H_ |
11 | | |
12 | | #include <vector> |
13 | | #include <string> |
14 | | #include <set> |
15 | | #include <memory> |
16 | | #include <optional> |
17 | | #include <variant> |
18 | | #include <chrono> |
19 | | |
20 | | #include <botan/tls_extensions.h> |
21 | | #include <botan/tls_handshake_msg.h> |
22 | | #include <botan/tls_session.h> |
23 | | #include <botan/tls_policy.h> |
24 | | #include <botan/tls_ciphersuite.h> |
25 | | #include <botan/pk_keys.h> |
26 | | #include <botan/x509cert.h> |
27 | | |
28 | | namespace Botan { |
29 | | |
30 | | class Public_Key; |
31 | | class Credentials_Manager; |
32 | | |
33 | | namespace OCSP { |
34 | | class Response; |
35 | | } |
36 | | |
37 | | namespace TLS { |
38 | | |
39 | | class Session; |
40 | | class Handshake_IO; |
41 | | class Handshake_State; |
42 | | class Hello_Retry_Request; |
43 | | class Callbacks; |
44 | | class Cipher_State; |
45 | | |
46 | | std::vector<uint8_t> make_hello_random(RandomNumberGenerator& rng, |
47 | | Callbacks& cb, |
48 | | const Policy& policy); |
49 | | |
50 | | /** |
51 | | * DTLS Hello Verify Request |
52 | | */ |
53 | | class BOTAN_UNSTABLE_API Hello_Verify_Request final : public Handshake_Message |
54 | | { |
55 | | public: |
56 | | std::vector<uint8_t> serialize() const override; |
57 | 4.28k | Handshake_Type type() const override { return Handshake_Type::HelloVerifyRequest; } |
58 | | |
59 | 2.14k | const std::vector<uint8_t>& cookie() const { return m_cookie; } |
60 | | |
61 | | explicit Hello_Verify_Request(const std::vector<uint8_t>& buf); |
62 | | |
63 | | Hello_Verify_Request(const std::vector<uint8_t>& client_hello_bits, |
64 | | const std::string& client_identity, |
65 | | const SymmetricKey& secret_key); |
66 | | |
67 | | private: |
68 | | std::vector<uint8_t> m_cookie; |
69 | | }; |
70 | | |
71 | | class Client_Hello_Internal; |
72 | | |
73 | | /** |
74 | | * Client Hello Message |
75 | | */ |
76 | | class BOTAN_UNSTABLE_API Client_Hello : public Handshake_Message |
77 | | { |
78 | | public: |
79 | | Client_Hello(const Client_Hello&) = delete; |
80 | | Client_Hello& operator=(const Client_Hello&) = delete; |
81 | | Client_Hello(Client_Hello&&); |
82 | | Client_Hello& operator=(Client_Hello&&); |
83 | | |
84 | | ~Client_Hello(); |
85 | | |
86 | | Handshake_Type type() const override; |
87 | | |
88 | | /** |
89 | | * Return the version indicated in the ClientHello. |
90 | | * This may differ from the version indicated in the supported_versions extension. |
91 | | * |
92 | | * See RFC 8446 4.1.2: |
93 | | * TLS 1.3, the client indicates its version preferences in the |
94 | | * "supported_versions" extension (Section 4.2.1) and the |
95 | | * legacy_version field MUST be set to 0x0303, which is the version |
96 | | * number for TLS 1.2. |
97 | | */ |
98 | | Protocol_Version legacy_version() const; |
99 | | |
100 | | const std::vector<uint8_t>& random() const; |
101 | | |
102 | | const std::vector<uint8_t>& session_id() const; |
103 | | |
104 | | const std::vector<uint16_t>& ciphersuites() const; |
105 | | |
106 | | bool offered_suite(uint16_t ciphersuite) const; |
107 | | |
108 | | std::vector<Signature_Scheme> signature_schemes() const; |
109 | | std::vector<Signature_Scheme> certificate_signature_schemes() const; |
110 | | |
111 | | std::vector<Group_Params> supported_ecc_curves() const; |
112 | | |
113 | | std::vector<Group_Params> supported_dh_groups() const; |
114 | | |
115 | | std::vector<Protocol_Version> supported_versions() const; |
116 | | |
117 | | std::string sni_hostname() const; |
118 | | |
119 | | bool supports_alpn() const; |
120 | | |
121 | | bool sent_signature_algorithms() const; |
122 | | |
123 | | std::vector<std::string> next_protocols() const; |
124 | | |
125 | | std::vector<uint16_t> srtp_profiles() const; |
126 | | |
127 | | std::vector<uint8_t> serialize() const override; |
128 | | |
129 | | |
130 | | const std::vector<uint8_t>& cookie() const; |
131 | | |
132 | | std::vector<uint8_t> cookie_input_data() const; |
133 | | |
134 | | std::set<Extension_Code> extension_types() const; |
135 | | |
136 | | const Extensions& extensions() const; |
137 | | |
138 | | protected: |
139 | | Client_Hello(); |
140 | | explicit Client_Hello(std::unique_ptr<Client_Hello_Internal> data); |
141 | | |
142 | | const std::vector<uint8_t>& compression_methods() const; |
143 | | |
144 | | protected: |
145 | | std::unique_ptr<Client_Hello_Internal> m_data; |
146 | | }; |
147 | | |
148 | | class BOTAN_UNSTABLE_API Client_Hello_12 final : public Client_Hello |
149 | | { |
150 | | public: |
151 | | class Settings final |
152 | | { |
153 | | public: |
154 | | Settings(const Protocol_Version version, |
155 | | const std::string& hostname = ""): |
156 | | m_new_session_version(version), |
157 | 2.42k | m_hostname(hostname) {} |
158 | | |
159 | 4.85k | const Protocol_Version protocol_version() const { return m_new_session_version; } |
160 | 4.85k | const std::string& hostname() const { return m_hostname; } |
161 | | |
162 | | private: |
163 | | const Protocol_Version m_new_session_version; |
164 | | const std::string m_hostname; |
165 | | }; |
166 | | |
167 | | public: |
168 | | explicit Client_Hello_12(const std::vector<uint8_t>& buf); |
169 | | |
170 | | Client_Hello_12(Handshake_IO& io, |
171 | | Handshake_Hash& hash, |
172 | | const Policy& policy, |
173 | | Callbacks& cb, |
174 | | RandomNumberGenerator& rng, |
175 | | const std::vector<uint8_t>& reneg_info, |
176 | | const Settings& client_settings, |
177 | | const std::vector<std::string>& next_protocols); |
178 | | |
179 | | Client_Hello_12(Handshake_IO& io, |
180 | | Handshake_Hash& hash, |
181 | | const Policy& policy, |
182 | | Callbacks& cb, |
183 | | RandomNumberGenerator& rng, |
184 | | const std::vector<uint8_t>& reneg_info, |
185 | | const Session& session, |
186 | | const std::vector<std::string>& next_protocols); |
187 | | |
188 | | protected: |
189 | | friend class Client_Hello_13; // to allow construction by Client_Hello_13::parse() |
190 | | Client_Hello_12(std::unique_ptr<Client_Hello_Internal> data); |
191 | | |
192 | | public: |
193 | | using Client_Hello::random; |
194 | | using Client_Hello::compression_methods; |
195 | | |
196 | | bool prefers_compressed_ec_points() const; |
197 | | |
198 | | bool secure_renegotiation() const; |
199 | | |
200 | | std::vector<uint8_t> renegotiation_info() const; |
201 | | |
202 | | bool supports_session_ticket() const; |
203 | | |
204 | | std::vector<uint8_t> session_ticket() const; |
205 | | |
206 | | bool supports_extended_master_secret() const; |
207 | | |
208 | | bool supports_cert_status_message() const; |
209 | | |
210 | | bool supports_encrypt_then_mac() const; |
211 | | |
212 | | void update_hello_cookie(const Hello_Verify_Request& hello_verify); |
213 | | }; |
214 | | |
215 | | #if defined(BOTAN_HAS_TLS_13) |
216 | | |
217 | | class BOTAN_UNSTABLE_API Client_Hello_13 final : public Client_Hello |
218 | | { |
219 | | public: |
220 | | Client_Hello_13(const Policy& policy, |
221 | | Callbacks& cb, |
222 | | RandomNumberGenerator& rng, |
223 | | const std::string& hostname, |
224 | | const std::vector<std::string>& next_protocols, |
225 | | const std::optional<Session>& session = std::nullopt); |
226 | | |
227 | | static std::variant<Client_Hello_13, Client_Hello_12> |
228 | | parse(const std::vector<uint8_t>& buf); |
229 | | |
230 | | void retry(const Hello_Retry_Request& hrr, |
231 | | const Transcript_Hash_State& transcript_hash_state, |
232 | | Callbacks& cb, |
233 | | RandomNumberGenerator& rng); |
234 | | |
235 | | /** |
236 | | * Select the highest protocol version from the list of versions |
237 | | * supported by the client. If no such version can be determind this |
238 | | * returns std::nullopt. |
239 | | */ |
240 | | std::optional<Protocol_Version> highest_supported_version(const Policy& policy) const; |
241 | | |
242 | | /** |
243 | | * This validates that a Client Hello received after sending a Hello |
244 | | * Retry Request was updated in accordance with RFC 8446 4.1.2. If issues |
245 | | * are found, this method throws accordingly. |
246 | | */ |
247 | | void validate_updates(const Client_Hello_13& new_ch); |
248 | | |
249 | | private: |
250 | | Client_Hello_13(std::unique_ptr<Client_Hello_Internal> data); |
251 | | |
252 | | /** |
253 | | * If the Client Hello contains a PSK extensions with identities this will |
254 | | * generate the PSK binders as described in RFC 8446 4.2.11.2. |
255 | | * Note that the passed in \p transcript_hash_state might be virgin for |
256 | | * the initial Client Hello and should be primed with ClientHello1 and |
257 | | * HelloRetryRequest for an updated Client Hello. |
258 | | */ |
259 | | void calculate_psk_binders(Transcript_Hash_State transcript_hash_state); |
260 | | }; |
261 | | |
262 | | #endif // BOTAN_HAS_TLS_13 |
263 | | |
264 | | class Server_Hello_Internal; |
265 | | |
266 | | /** |
267 | | * Server Hello Message |
268 | | */ |
269 | | class BOTAN_UNSTABLE_API Server_Hello : public Handshake_Message |
270 | | { |
271 | | public: |
272 | | Server_Hello(const Server_Hello&) = delete; |
273 | | Server_Hello& operator=(const Server_Hello&) = delete; |
274 | | Server_Hello(Server_Hello&&); |
275 | | Server_Hello& operator=(Server_Hello&&); |
276 | | |
277 | | ~Server_Hello(); |
278 | | |
279 | | std::vector<uint8_t> serialize() const override; |
280 | | |
281 | | Handshake_Type type() const override; |
282 | | |
283 | | // methods available in both subclasses' interface |
284 | | uint16_t ciphersuite() const; |
285 | | const Extensions& extensions() const; |
286 | | const std::vector<uint8_t>& session_id() const; |
287 | | |
288 | | virtual Protocol_Version selected_version() const = 0; |
289 | | |
290 | | protected: |
291 | | explicit Server_Hello(std::unique_ptr<Server_Hello_Internal> data); |
292 | | |
293 | | // methods used internally and potentially exposed by one of the subclasses |
294 | | std::set<Extension_Code> extension_types() const; |
295 | | const std::vector<uint8_t>& random() const; |
296 | | uint8_t compression_method() const; |
297 | | Protocol_Version legacy_version() const; |
298 | | |
299 | | protected: |
300 | | std::unique_ptr<Server_Hello_Internal> m_data; |
301 | | }; |
302 | | |
303 | | class BOTAN_UNSTABLE_API Server_Hello_12 final : public Server_Hello |
304 | | { |
305 | | public: |
306 | | class Settings final |
307 | | { |
308 | | public: |
309 | | Settings(const std::vector<uint8_t> new_session_id, |
310 | | Protocol_Version new_session_version, |
311 | | uint16_t ciphersuite, |
312 | | bool offer_session_ticket) : |
313 | | m_new_session_id(new_session_id), |
314 | | m_new_session_version(new_session_version), |
315 | | m_ciphersuite(ciphersuite), |
316 | 20.1k | m_offer_session_ticket(offer_session_ticket) {} |
317 | | |
318 | 20.1k | const std::vector<uint8_t>& session_id() const { return m_new_session_id; } |
319 | 40.3k | Protocol_Version protocol_version() const { return m_new_session_version; } |
320 | 20.1k | uint16_t ciphersuite() const { return m_ciphersuite; } |
321 | 4.83k | bool offer_session_ticket() const { return m_offer_session_ticket; } |
322 | | |
323 | | private: |
324 | | const std::vector<uint8_t> m_new_session_id; |
325 | | Protocol_Version m_new_session_version; |
326 | | uint16_t m_ciphersuite; |
327 | | bool m_offer_session_ticket; |
328 | | }; |
329 | | |
330 | | Server_Hello_12(Handshake_IO& io, |
331 | | Handshake_Hash& hash, |
332 | | const Policy& policy, |
333 | | Callbacks& cb, |
334 | | RandomNumberGenerator& rng, |
335 | | const std::vector<uint8_t>& secure_reneg_info, |
336 | | const Client_Hello_12& client_hello, |
337 | | const Settings& settings, |
338 | | const std::string& next_protocol); |
339 | | |
340 | | Server_Hello_12(Handshake_IO& io, |
341 | | Handshake_Hash& hash, |
342 | | const Policy& policy, |
343 | | Callbacks& cb, |
344 | | RandomNumberGenerator& rng, |
345 | | const std::vector<uint8_t>& secure_reneg_info, |
346 | | const Client_Hello_12& client_hello, |
347 | | Session& resumed_session, |
348 | | bool offer_session_ticket, |
349 | | const std::string& next_protocol); |
350 | | |
351 | | explicit Server_Hello_12(const std::vector<uint8_t> &buf); |
352 | | |
353 | | protected: |
354 | | friend class Server_Hello_13; // to allow construction by Server_Hello_13::parse() |
355 | | explicit Server_Hello_12(std::unique_ptr<Server_Hello_Internal> data); |
356 | | |
357 | | public: |
358 | | using Server_Hello::random; |
359 | | using Server_Hello::compression_method; |
360 | | using Server_Hello::extension_types; |
361 | | using Server_Hello::legacy_version; |
362 | | |
363 | | /** |
364 | | * @returns the selected version as indicated in the legacy_version field |
365 | | */ |
366 | | Protocol_Version selected_version() const override; |
367 | | |
368 | | bool secure_renegotiation() const; |
369 | | |
370 | | std::vector<uint8_t> renegotiation_info() const; |
371 | | |
372 | | std::string next_protocol() const; |
373 | | |
374 | | bool supports_extended_master_secret() const; |
375 | | |
376 | | bool supports_encrypt_then_mac() const; |
377 | | |
378 | | bool supports_certificate_status_message() const; |
379 | | |
380 | | bool supports_session_ticket() const; |
381 | | |
382 | | uint16_t srtp_profile() const; |
383 | | bool prefers_compressed_ec_points() const; |
384 | | |
385 | | /** |
386 | | * Return desired downgrade version indicated by hello random, if any. |
387 | | */ |
388 | | std::optional<Protocol_Version> random_signals_downgrade() const; |
389 | | }; |
390 | | |
391 | | #if defined(BOTAN_HAS_TLS_13) |
392 | | |
393 | | class Hello_Retry_Request; |
394 | | |
395 | | class BOTAN_UNSTABLE_API Server_Hello_13 : public Server_Hello |
396 | | { |
397 | | protected: |
398 | | static struct Server_Hello_Tag {} as_server_hello; |
399 | | static struct Hello_Retry_Request_Tag {} as_hello_retry_request; |
400 | | static struct Hello_Retry_Request_Creation_Tag {} as_new_hello_retry_request; |
401 | | |
402 | | // These constructors are meant for instantiating Server Hellos |
403 | | // after parsing a peer's message. They perform basic validation |
404 | | // and are therefore not suitable for constructing a message to |
405 | | // be sent to a client. |
406 | | explicit Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Server_Hello_Tag tag = as_server_hello); |
407 | | explicit Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Hello_Retry_Request_Tag tag); |
408 | | void basic_validation() const; |
409 | | |
410 | | // Instantiate a Server Hello as response to a client's Client Hello |
411 | | // (called from Server_Hello_13::create()) |
412 | | Server_Hello_13(const Client_Hello_13& ch, std::optional<Named_Group> key_exchange_group, RandomNumberGenerator& rng, Callbacks& cb, const Policy& policy); |
413 | | |
414 | | explicit Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Hello_Retry_Request_Creation_Tag tag); |
415 | | |
416 | | public: |
417 | | static std::variant<Hello_Retry_Request, Server_Hello_13> |
418 | | create(const Client_Hello_13& ch, bool hello_retry_request_allowed, RandomNumberGenerator& rng, const Policy& policy, Callbacks& cb); |
419 | | |
420 | | static std::variant<Hello_Retry_Request, Server_Hello_13, Server_Hello_12> |
421 | | parse(const std::vector<uint8_t>& buf); |
422 | | |
423 | | /** |
424 | | * Return desired downgrade version indicated by hello random, if any. |
425 | | */ |
426 | | std::optional<Protocol_Version> random_signals_downgrade() const; |
427 | | |
428 | | /** |
429 | | * @returns the selected version as indicated by the supported_versions extension |
430 | | */ |
431 | | Protocol_Version selected_version() const override; |
432 | | }; |
433 | | |
434 | | class BOTAN_UNSTABLE_API Hello_Retry_Request final : public Server_Hello_13 |
435 | | { |
436 | | protected: |
437 | | friend class Server_Hello_13; // to allow construction by Server_Hello_13::parse() and ::create() |
438 | | explicit Hello_Retry_Request(std::unique_ptr<Server_Hello_Internal> data); |
439 | | Hello_Retry_Request(const Client_Hello_13& ch, Named_Group selected_group, const Policy& policy, Callbacks& cb); |
440 | | |
441 | | public: |
442 | 0 | Handshake_Type type() const override { return Handshake_Type::HelloRetryRequest; } |
443 | 0 | Handshake_Type wire_type() const override { return Handshake_Type::ServerHello; } |
444 | | }; |
445 | | |
446 | | #endif // BOTAN_HAS_TLS_13 |
447 | | |
448 | | class BOTAN_UNSTABLE_API Encrypted_Extensions final : public Handshake_Message |
449 | | { |
450 | | public: |
451 | | explicit Encrypted_Extensions(const std::vector<uint8_t>& buf); |
452 | | Encrypted_Extensions(const Client_Hello_13& client_hello, const Policy& policy, Callbacks& cb); |
453 | | |
454 | 8.65k | Handshake_Type type() const override { return Handshake_Type::EncryptedExtensions; } |
455 | | |
456 | 0 | const Extensions& extensions() const { return m_extensions; } |
457 | | |
458 | | std::vector<uint8_t> serialize() const override; |
459 | | |
460 | | private: |
461 | | Extensions m_extensions; |
462 | | }; |
463 | | |
464 | | /** |
465 | | * Client Key Exchange Message |
466 | | */ |
467 | | class BOTAN_UNSTABLE_API Client_Key_Exchange final : public Handshake_Message |
468 | | { |
469 | | public: |
470 | 0 | Handshake_Type type() const override { return Handshake_Type::ClientKeyExchange; } |
471 | | |
472 | | const secure_vector<uint8_t>& pre_master_secret() const |
473 | 13.5k | { return m_pre_master; } |
474 | | |
475 | | Client_Key_Exchange(Handshake_IO& io, |
476 | | Handshake_State& state, |
477 | | const Policy& policy, |
478 | | Credentials_Manager& creds, |
479 | | const Public_Key* server_public_key, |
480 | | const std::string& hostname, |
481 | | RandomNumberGenerator& rng); |
482 | | |
483 | | Client_Key_Exchange(const std::vector<uint8_t>& buf, |
484 | | const Handshake_State& state, |
485 | | const Private_Key* server_rsa_kex_key, |
486 | | Credentials_Manager& creds, |
487 | | const Policy& policy, |
488 | | RandomNumberGenerator& rng); |
489 | | |
490 | | private: |
491 | | std::vector<uint8_t> serialize() const override |
492 | 0 | { return m_key_material; } |
493 | | |
494 | | std::vector<uint8_t> m_key_material; |
495 | | secure_vector<uint8_t> m_pre_master; |
496 | | }; |
497 | | |
498 | | /** |
499 | | * Certificate Message of TLS 1.2 |
500 | | */ |
501 | | class BOTAN_UNSTABLE_API Certificate_12 final : public Handshake_Message |
502 | | { |
503 | | public: |
504 | 438 | Handshake_Type type() const override { return Handshake_Type::Certificate; } |
505 | 220 | const std::vector<X509_Certificate>& cert_chain() const { return m_certs; } |
506 | | |
507 | 0 | size_t count() const { return m_certs.size(); } |
508 | 0 | bool empty() const { return m_certs.empty(); } |
509 | | |
510 | | Certificate_12(Handshake_IO& io, |
511 | | Handshake_Hash& hash, |
512 | | const std::vector<X509_Certificate>& certs); |
513 | | |
514 | | Certificate_12(const std::vector<uint8_t>& buf, const Policy& policy); |
515 | | |
516 | | std::vector<uint8_t> serialize() const override; |
517 | | |
518 | | private: |
519 | | std::vector<X509_Certificate> m_certs; |
520 | | }; |
521 | | |
522 | | class Certificate_Request_13; |
523 | | |
524 | | /** |
525 | | * Certificate Message of TLS 1.3 |
526 | | */ |
527 | | class BOTAN_UNSTABLE_API Certificate_13 final : public Handshake_Message |
528 | | { |
529 | | public: |
530 | | struct Certificate_Entry |
531 | | { |
532 | | // TODO: RFC 8446 4.4.2 specifies the possibility to negotiate the usage |
533 | | // of a single raw public key in lieu of the X.509 certificate |
534 | | // chain. This is left for future work. |
535 | | X509_Certificate certificate; |
536 | | Extensions extensions; |
537 | | }; |
538 | | |
539 | | public: |
540 | 0 | Handshake_Type type() const override { return Handshake_Type::Certificate; } |
541 | | std::vector<X509_Certificate> cert_chain() const; |
542 | | |
543 | 0 | size_t count() const { return m_entries.size(); } |
544 | 0 | bool empty() const { return m_entries.empty(); } |
545 | | const X509_Certificate& leaf() const; |
546 | 0 | const std::vector<uint8_t>& request_context() const { return m_request_context; } |
547 | | |
548 | | /** |
549 | | * Create a Client Certificate message |
550 | | * ... in response to a Certificate Request message. |
551 | | */ |
552 | | Certificate_13(const Certificate_Request_13& cert_request, |
553 | | const std::string& hostname, |
554 | | Credentials_Manager& credentials_manager, |
555 | | Callbacks& callbacks); |
556 | | |
557 | | /** |
558 | | * Create a Server Certificate message |
559 | | * ... in response to a Client Hello indicating the need to authenticate |
560 | | * with a server certificate. |
561 | | */ |
562 | | Certificate_13(const Client_Hello_13& client_hello, |
563 | | Credentials_Manager& credentials_manager, |
564 | | Callbacks& callbacks); |
565 | | |
566 | | /** |
567 | | * Deserialize a Certificate message |
568 | | * @param buf the serialized message |
569 | | * @param policy the TLS policy |
570 | | * @param side is this a Connection_Side::Server or Connection_Side::Client certificate message |
571 | | */ |
572 | | Certificate_13(const std::vector<uint8_t>& buf, |
573 | | const Policy& policy, |
574 | | const Connection_Side side); |
575 | | |
576 | | /** |
577 | | * Validate a Certificate message regarding what extensions are expected based on |
578 | | * previous handshake messages. Also call the tls_examine_extenions() callback |
579 | | * for each entry. |
580 | | * |
581 | | * @param requested_extensions Extensions of Client_Hello or Certificate_Request messages |
582 | | */ |
583 | | void validate_extensions(const std::set<Extension_Code>& requested_extensions, Callbacks& cb) const; |
584 | | |
585 | | /** |
586 | | * Verify the certificate chain |
587 | | * |
588 | | * @throws if verification fails. |
589 | | */ |
590 | | void verify(Callbacks& callbacks, |
591 | | const Policy& policy, |
592 | | Credentials_Manager& creds, |
593 | | const std::string& hostname, |
594 | | bool use_ocsp) const; |
595 | | |
596 | | std::vector<uint8_t> serialize() const override; |
597 | | |
598 | | private: |
599 | | void setup_entries(std::vector<X509_Certificate> cert_chain, |
600 | | const Certificate_Status_Request* csr, |
601 | | Callbacks& callbacks); |
602 | | |
603 | | private: |
604 | | std::vector<uint8_t> m_request_context; |
605 | | std::vector<Certificate_Entry> m_entries; |
606 | | Connection_Side m_side; |
607 | | }; |
608 | | |
609 | | /** |
610 | | * Certificate Status (RFC 6066) |
611 | | */ |
612 | | class BOTAN_UNSTABLE_API Certificate_Status final : public Handshake_Message |
613 | | { |
614 | | public: |
615 | 0 | Handshake_Type type() const override { return Handshake_Type::CertificateStatus; } |
616 | | |
617 | | //std::shared_ptr<const OCSP::Response> response() const { return m_response; } |
618 | | |
619 | 0 | const std::vector<uint8_t>& response() const { return m_response; } |
620 | | |
621 | | explicit Certificate_Status(const std::vector<uint8_t>& buf, const Connection_Side from); |
622 | | |
623 | | Certificate_Status(Handshake_IO& io, |
624 | | Handshake_Hash& hash, |
625 | | const OCSP::Response& response); |
626 | | |
627 | | /* |
628 | | * Create a Certificate_Status message using an already DER encoded OCSP response. |
629 | | */ |
630 | | Certificate_Status(Handshake_IO& io, |
631 | | Handshake_Hash& hash, |
632 | | std::vector<uint8_t> raw_response_bytes); |
633 | | |
634 | | Certificate_Status(std::vector<uint8_t> raw_response_bytes); |
635 | | |
636 | | std::vector<uint8_t> serialize() const override; |
637 | | |
638 | | private: |
639 | | std::vector<uint8_t> m_response; |
640 | | }; |
641 | | |
642 | | /** |
643 | | * Certificate Request Message (TLS 1.2) |
644 | | */ |
645 | | class BOTAN_UNSTABLE_API Certificate_Request_12 final : public Handshake_Message |
646 | | { |
647 | | public: |
648 | | Handshake_Type type() const override; |
649 | | |
650 | | const std::vector<std::string>& acceptable_cert_types() const; |
651 | | |
652 | | const std::vector<X509_DN>& acceptable_CAs() const; |
653 | | |
654 | | const std::vector<Signature_Scheme>& signature_schemes() const; |
655 | | |
656 | | Certificate_Request_12(Handshake_IO& io, |
657 | | Handshake_Hash& hash, |
658 | | const Policy& policy, |
659 | | const std::vector<X509_DN>& allowed_cas); |
660 | | |
661 | | explicit Certificate_Request_12(const std::vector<uint8_t>& buf); |
662 | | |
663 | | std::vector<uint8_t> serialize() const override; |
664 | | |
665 | | private: |
666 | | std::vector<X509_DN> m_names; |
667 | | std::vector<std::string> m_cert_key_types; |
668 | | std::vector<Signature_Scheme> m_schemes; |
669 | | }; |
670 | | |
671 | | #if defined(BOTAN_HAS_TLS_13) |
672 | | |
673 | | class BOTAN_UNSTABLE_API Certificate_Request_13 final : public Handshake_Message |
674 | | { |
675 | | public: |
676 | | Handshake_Type type() const override; |
677 | | |
678 | | Certificate_Request_13(const std::vector<uint8_t>& buf, const Connection_Side side); |
679 | | |
680 | | //! Creates a Certificate_Request message if it is required by the configuration |
681 | | //! @return std::nullopt if configuration does not require client authentication |
682 | | static std::optional<Certificate_Request_13> maybe_create(const Client_Hello_13& sni_hostname, |
683 | | Credentials_Manager& cred_mgr, |
684 | | Callbacks& callbacks, |
685 | | const Policy& policy); |
686 | | |
687 | | std::vector<X509_DN> acceptable_CAs() const; |
688 | | const std::vector<Signature_Scheme>& signature_schemes() const; |
689 | | const std::vector<Signature_Scheme>& certificate_signature_schemes() const; |
690 | | |
691 | 0 | const Extensions& extensions() const { return m_extensions; } |
692 | | |
693 | | std::vector<uint8_t> serialize() const override; |
694 | | |
695 | 0 | const std::vector<uint8_t> context() const { return m_context; } |
696 | | |
697 | | private: |
698 | | Certificate_Request_13(std::vector<X509_DN> acceptable_CAs, |
699 | | const Policy& policy, |
700 | | Callbacks& callbacks); |
701 | | |
702 | | private: |
703 | | std::vector<uint8_t> m_context; |
704 | | Extensions m_extensions; |
705 | | }; |
706 | | |
707 | | #endif |
708 | | |
709 | | class BOTAN_UNSTABLE_API Certificate_Verify : public Handshake_Message |
710 | | { |
711 | | public: |
712 | 0 | Handshake_Type type() const override { return Handshake_Type::CertificateVerify; } |
713 | | |
714 | 0 | Signature_Scheme signature_scheme() const { return m_scheme; } |
715 | | |
716 | | Certificate_Verify(const std::vector<uint8_t>& buf); |
717 | 0 | Certificate_Verify() = default; |
718 | | |
719 | | std::vector<uint8_t> serialize() const override; |
720 | | |
721 | | protected: |
722 | | std::vector<uint8_t> m_signature; |
723 | | Signature_Scheme m_scheme; |
724 | | }; |
725 | | |
726 | | /** |
727 | | * Certificate Verify Message |
728 | | */ |
729 | | class BOTAN_UNSTABLE_API Certificate_Verify_12 final : public Certificate_Verify |
730 | | { |
731 | | public: |
732 | | using Certificate_Verify::Certificate_Verify; |
733 | | |
734 | | Certificate_Verify_12(Handshake_IO& io, |
735 | | Handshake_State& state, |
736 | | const Policy& policy, |
737 | | RandomNumberGenerator& rng, |
738 | | const Private_Key* key); |
739 | | |
740 | | /** |
741 | | * Check the signature on a certificate verify message |
742 | | * @param cert the purported certificate |
743 | | * @param state the handshake state |
744 | | * @param policy the TLS policy |
745 | | */ |
746 | | bool verify(const X509_Certificate& cert, |
747 | | const Handshake_State& state, |
748 | | const Policy& policy) const; |
749 | | }; |
750 | | |
751 | | #if defined(BOTAN_HAS_TLS_13) |
752 | | |
753 | | /** |
754 | | * Certificate Verify Message |
755 | | */ |
756 | | class BOTAN_UNSTABLE_API Certificate_Verify_13 final : public Certificate_Verify |
757 | | { |
758 | | public: |
759 | | /** |
760 | | * Deserialize a Certificate message |
761 | | * @param buf the serialized message |
762 | | * @param side is this a Connection_Side::Server or Connection_Side::Client certificate message |
763 | | */ |
764 | | Certificate_Verify_13(const std::vector<uint8_t>& buf, |
765 | | const Connection_Side side); |
766 | | |
767 | | Certificate_Verify_13( |
768 | | const Certificate_13& certificate_message, |
769 | | const std::vector<Signature_Scheme>& peer_allowed_schemes, |
770 | | const std::string& hostname, |
771 | | const Transcript_Hash& hash, |
772 | | Connection_Side whoami, |
773 | | Credentials_Manager& creds_mgr, |
774 | | const Policy& policy, |
775 | | Callbacks& callbacks, |
776 | | RandomNumberGenerator& rng); |
777 | | |
778 | | bool verify(const X509_Certificate& cert, |
779 | | Callbacks& callbacks, |
780 | | const Transcript_Hash& transcript_hash) const; |
781 | | |
782 | | private: |
783 | | Connection_Side m_side; |
784 | | }; |
785 | | |
786 | | #endif |
787 | | |
788 | | /** |
789 | | * Finished Message |
790 | | */ |
791 | | class BOTAN_UNSTABLE_API Finished : public Handshake_Message |
792 | | { |
793 | | public: |
794 | | explicit Finished(const std::vector<uint8_t>& buf); |
795 | | |
796 | 644 | Handshake_Type type() const override { return Handshake_Type::Finished; } |
797 | | |
798 | | std::vector<uint8_t> verify_data() const; |
799 | | |
800 | | std::vector<uint8_t> serialize() const override; |
801 | | |
802 | | protected: |
803 | | using Handshake_Message::Handshake_Message; |
804 | | std::vector<uint8_t> m_verification_data; |
805 | | }; |
806 | | |
807 | | class BOTAN_UNSTABLE_API Finished_12 final : public Finished |
808 | | { |
809 | | public: |
810 | | using Finished::Finished; |
811 | | Finished_12(Handshake_IO& io, |
812 | | Handshake_State& state, |
813 | | Connection_Side side); |
814 | | |
815 | | bool verify(const Handshake_State& state, Connection_Side side) const; |
816 | | }; |
817 | | |
818 | | #if defined(BOTAN_HAS_TLS_13) |
819 | | class BOTAN_UNSTABLE_API Finished_13 final : public Finished |
820 | | { |
821 | | public: |
822 | | using Finished::Finished; |
823 | | Finished_13(Cipher_State* cipher_state, |
824 | | const Transcript_Hash& transcript_hash); |
825 | | |
826 | | bool verify(Cipher_State* cipher_state, |
827 | | const Transcript_Hash& transcript_hash) const; |
828 | | }; |
829 | | #endif |
830 | | |
831 | | /** |
832 | | * Hello Request Message |
833 | | */ |
834 | | class BOTAN_UNSTABLE_API Hello_Request final : public Handshake_Message |
835 | | { |
836 | | public: |
837 | 0 | Handshake_Type type() const override { return Handshake_Type::HelloRequest; } |
838 | | |
839 | | explicit Hello_Request(Handshake_IO& io); |
840 | | explicit Hello_Request(const std::vector<uint8_t>& buf); |
841 | | |
842 | | private: |
843 | | std::vector<uint8_t> serialize() const override; |
844 | | }; |
845 | | |
846 | | /** |
847 | | * Server Key Exchange Message |
848 | | */ |
849 | | class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message |
850 | | { |
851 | | public: |
852 | 39.8k | Handshake_Type type() const override { return Handshake_Type::ServerKeyExchange; } |
853 | | |
854 | 19.9k | const std::vector<uint8_t>& params() const { return m_params; } |
855 | | |
856 | | bool verify(const Public_Key& server_key, |
857 | | const Handshake_State& state, |
858 | | const Policy& policy) const; |
859 | | |
860 | | // Only valid for certain kex types |
861 | | const Private_Key& server_kex_key() const; |
862 | | |
863 | | Server_Key_Exchange(Handshake_IO& io, |
864 | | Handshake_State& state, |
865 | | const Policy& policy, |
866 | | Credentials_Manager& creds, |
867 | | RandomNumberGenerator& rng, |
868 | | const Private_Key* signing_key = nullptr); |
869 | | |
870 | | Server_Key_Exchange(const std::vector<uint8_t>& buf, |
871 | | Kex_Algo kex_alg, |
872 | | Auth_Method sig_alg, |
873 | | Protocol_Version version); |
874 | | |
875 | | private: |
876 | | std::vector<uint8_t> serialize() const override; |
877 | | |
878 | | std::unique_ptr<Private_Key> m_kex_key; |
879 | | |
880 | | std::vector<uint8_t> m_params; |
881 | | |
882 | | std::vector<uint8_t> m_signature; |
883 | | Signature_Scheme m_scheme; |
884 | | }; |
885 | | |
886 | | /** |
887 | | * Server Hello Done Message |
888 | | */ |
889 | | class BOTAN_UNSTABLE_API Server_Hello_Done final : public Handshake_Message |
890 | | { |
891 | | public: |
892 | 39.8k | Handshake_Type type() const override { return Handshake_Type::ServerHelloDone; } |
893 | | |
894 | | explicit Server_Hello_Done(Handshake_IO& io, Handshake_Hash& hash); |
895 | | explicit Server_Hello_Done(const std::vector<uint8_t>& buf); |
896 | | |
897 | | private: |
898 | | std::vector<uint8_t> serialize() const override; |
899 | | }; |
900 | | |
901 | | /** |
902 | | * New Session Ticket Message |
903 | | */ |
904 | | class BOTAN_UNSTABLE_API New_Session_Ticket_12 final : public Handshake_Message |
905 | | { |
906 | | public: |
907 | 346 | Handshake_Type type() const override { return Handshake_Type::NewSessionTicket; } |
908 | | |
909 | 0 | std::chrono::seconds ticket_lifetime_hint() const { return m_ticket_lifetime_hint; } |
910 | 0 | const std::vector<uint8_t>& ticket() const { return m_ticket; } |
911 | | |
912 | | New_Session_Ticket_12(Handshake_IO& io, |
913 | | Handshake_Hash& hash, |
914 | | const std::vector<uint8_t>& ticket, |
915 | | std::chrono::seconds lifetime); |
916 | | |
917 | | New_Session_Ticket_12(Handshake_IO& io, |
918 | | Handshake_Hash& hash); |
919 | | |
920 | | explicit New_Session_Ticket_12(const std::vector<uint8_t>& buf); |
921 | | |
922 | | std::vector<uint8_t> serialize() const override; |
923 | | |
924 | | private: |
925 | | std::chrono::seconds m_ticket_lifetime_hint; |
926 | | std::vector<uint8_t> m_ticket; |
927 | | }; |
928 | | |
929 | | #if defined(BOTAN_HAS_TLS_13) |
930 | | |
931 | | class BOTAN_UNSTABLE_API New_Session_Ticket_13 final : public Handshake_Message |
932 | | { |
933 | | public: |
934 | 0 | Handshake_Type type() const override { return Handshake_Type::NewSessionTicket; } |
935 | | |
936 | | New_Session_Ticket_13(const std::vector<uint8_t>& buf, |
937 | | Connection_Side from); |
938 | | |
939 | | std::vector<uint8_t> serialize() const override; |
940 | | |
941 | 0 | const Extensions& extensions() const { return m_extensions; } |
942 | | |
943 | 0 | const std::vector<uint8_t>& ticket() const { return m_ticket; } |
944 | 0 | const std::vector<uint8_t>& nonce() const { return m_ticket_nonce; } |
945 | 0 | uint32_t ticket_age_add() const { return m_ticket_age_add; } |
946 | 0 | std::chrono::seconds lifetime_hint() const { return m_ticket_lifetime_hint; } |
947 | | |
948 | | /** |
949 | | * @return the number of bytes allowed for early data or std::nullopt |
950 | | * when early data is not allowed at all |
951 | | */ |
952 | | std::optional<uint32_t> early_data_byte_limit() const; |
953 | | |
954 | | private: |
955 | | // RFC 8446 4.6.1 |
956 | | // Clients MUST NOT cache tickets for longer than 7 days, regardless of |
957 | | // the ticket_lifetime, and MAY delete tickets earlier based on local |
958 | | // policy. A server MAY treat a ticket as valid for a shorter period |
959 | | // of time than what is stated in the ticket_lifetime. |
960 | | // |
961 | | // ... hence we call it 'lifetime hint'. |
962 | | std::chrono::seconds m_ticket_lifetime_hint; |
963 | | uint32_t m_ticket_age_add; |
964 | | std::vector<uint8_t> m_ticket_nonce; |
965 | | std::vector<uint8_t> m_ticket; |
966 | | Extensions m_extensions; |
967 | | }; |
968 | | |
969 | | #endif |
970 | | |
971 | | /** |
972 | | * Change Cipher Spec |
973 | | */ |
974 | | class BOTAN_UNSTABLE_API Change_Cipher_Spec final : public Handshake_Message |
975 | | { |
976 | | public: |
977 | 322 | Handshake_Type type() const override { return Handshake_Type::HandshakeCCS; } |
978 | | |
979 | | std::vector<uint8_t> serialize() const override |
980 | 322 | { return std::vector<uint8_t>(1, 1); } |
981 | | }; |
982 | | |
983 | | class BOTAN_UNSTABLE_API Key_Update final : public Handshake_Message |
984 | | { |
985 | | public: |
986 | 0 | Handshake_Type type() const override { return Handshake_Type::KeyUpdate; } |
987 | | |
988 | | explicit Key_Update(const bool request_peer_update); |
989 | | explicit Key_Update(const std::vector<uint8_t>& buf); |
990 | | |
991 | | std::vector<uint8_t> serialize() const override; |
992 | | |
993 | 0 | bool expects_reciprocation() const { return m_update_requested; } |
994 | | |
995 | | private: |
996 | | bool m_update_requested; |
997 | | }; |
998 | | |
999 | | #if defined(BOTAN_HAS_TLS_13) |
1000 | | |
1001 | | namespace { |
1002 | | template <typename T> |
1003 | | struct as_wrapped_references |
1004 | | { |
1005 | | }; |
1006 | | |
1007 | | template <typename... AlternativeTs> |
1008 | | struct as_wrapped_references<std::variant<AlternativeTs...>> |
1009 | | { |
1010 | | using type = std::variant<std::reference_wrapper<AlternativeTs>...>; |
1011 | | }; |
1012 | | |
1013 | | template <typename T> |
1014 | | using as_wrapped_references_t = typename as_wrapped_references<T>::type; |
1015 | | } |
1016 | | |
1017 | | // Handshake message types from RFC 8446 4. |
1018 | | using Handshake_Message_13 = std::variant< |
1019 | | Client_Hello_13, |
1020 | | Client_Hello_12, |
1021 | | Server_Hello_13, |
1022 | | Server_Hello_12, |
1023 | | Hello_Retry_Request, |
1024 | | // End_Of_Early_Data, |
1025 | | Encrypted_Extensions, |
1026 | | Certificate_13, |
1027 | | Certificate_Request_13, |
1028 | | Certificate_Verify_13, |
1029 | | Finished_13>; |
1030 | | using Handshake_Message_13_Ref = as_wrapped_references_t<Handshake_Message_13>; |
1031 | | |
1032 | | using Post_Handshake_Message_13 = std::variant< |
1033 | | New_Session_Ticket_13, |
1034 | | Key_Update>; |
1035 | | |
1036 | | // Key_Update is handled generically by the Channel. The messages assigned |
1037 | | // to those variants are the ones that need to be handled by the specific |
1038 | | // client and/or server implementations. |
1039 | | using Server_Post_Handshake_13_Message = std::variant<New_Session_Ticket_13, Key_Update>; |
1040 | | using Client_Post_Handshake_13_Message = std::variant<Key_Update>; |
1041 | | |
1042 | | using Server_Handshake_13_Message = std::variant< |
1043 | | Server_Hello_13, |
1044 | | Server_Hello_12, // indicates a TLS version downgrade |
1045 | | Hello_Retry_Request, |
1046 | | Encrypted_Extensions, |
1047 | | Certificate_13, |
1048 | | Certificate_Request_13, |
1049 | | Certificate_Verify_13, |
1050 | | Finished_13>; |
1051 | | using Server_Handshake_13_Message_Ref = as_wrapped_references_t<Server_Handshake_13_Message>; |
1052 | | |
1053 | | using Client_Handshake_13_Message = std::variant< |
1054 | | Client_Hello_13, |
1055 | | Client_Hello_12, // indicates a TLS peer that does not offer TLS 1.3 |
1056 | | Certificate_13, |
1057 | | Certificate_Verify_13, |
1058 | | Finished_13>; |
1059 | | using Client_Handshake_13_Message_Ref = as_wrapped_references_t<Client_Handshake_13_Message>; |
1060 | | |
1061 | | #endif // BOTAN_HAS_TLS_13 |
1062 | | |
1063 | | } |
1064 | | |
1065 | | } |
1066 | | |
1067 | | #endif |