• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5793483731

08 Aug 2023 06:21AM UTC coverage: 91.629% (-0.06%) from 91.688%
5793483731

Pull #3609

github

web-flow
Merge 0676a3d0a into 702b9f6af
Pull Request #3609: [TLS 1.3] Hybrid PQ/T key establishment

78942 of 86154 relevant lines covered (91.63%)

12319036.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.7
/src/lib/tls/tls_messages.h
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 <chrono>
13
#include <memory>
14
#include <optional>
15
#include <set>
16
#include <string>
17
#include <variant>
18
#include <vector>
19

20
#include <botan/pk_keys.h>
21
#include <botan/strong_type.h>
22
#include <botan/tls_ciphersuite.h>
23
#include <botan/tls_extensions.h>
24
#include <botan/tls_handshake_msg.h>
25
#include <botan/tls_policy.h>
26
#include <botan/tls_session.h>
27
#include <botan/x509cert.h>
28

29
namespace Botan {
30

31
class Public_Key;
32
class Credentials_Manager;
33

34
namespace OCSP {
35
class Response;
36
}
37

38
namespace TLS {
39

40
class Session_Manager;
41
class Handshake_IO;
42
class Handshake_State;
43
class Hello_Retry_Request;
44
class Callbacks;
45
class Cipher_State;
46
class Policy;
47

48
std::vector<uint8_t> make_hello_random(RandomNumberGenerator& rng, Callbacks& cb, const Policy& policy);
49

50
/**
51
* DTLS Hello Verify Request
52
*/
53
class BOTAN_UNSTABLE_API Hello_Verify_Request final : public Handshake_Message {
2,333✔
54
   public:
55
      std::vector<uint8_t> serialize() const override;
56

57
      Handshake_Type type() const override { return Handshake_Type::HelloVerifyRequest; }
731✔
58

59
      const std::vector<uint8_t>& cookie() const { return m_cookie; }
1,166✔
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
                           std::string_view 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
   public:
78
      Client_Hello(const Client_Hello&) = delete;
79
      Client_Hello& operator=(const Client_Hello&) = delete;
80
      Client_Hello(Client_Hello&&) noexcept;
81
      Client_Hello& operator=(Client_Hello&&) noexcept;
82

83
      ~Client_Hello() override;
84

85
      Handshake_Type type() const override;
86

87
      /**
88
       * Return the version indicated in the ClientHello.
89
       * This may differ from the version indicated in the supported_versions extension.
90
       *
91
       * See RFC 8446 4.1.2:
92
       *   TLS 1.3, the client indicates its version preferences in the
93
       *   "supported_versions" extension (Section 4.2.1) and the
94
       *   legacy_version field MUST be set to 0x0303, which is the version
95
       *   number for TLS 1.2.
96
       */
97
      Protocol_Version legacy_version() const;
98

99
      const std::vector<uint8_t>& random() const;
100

101
      const Session_ID& session_id() const;
102

103
      const std::vector<uint16_t>& ciphersuites() const;
104

105
      bool offered_suite(uint16_t ciphersuite) const;
106

107
      std::vector<Signature_Scheme> signature_schemes() const;
108
      std::vector<Signature_Scheme> certificate_signature_schemes() const;
109

110
      std::vector<Group_Params> supported_ecc_curves() const;
111

112
      std::vector<Group_Params> supported_dh_groups() const;
113

114
      std::vector<Protocol_Version> supported_versions() const;
115

116
      std::string sni_hostname() const;
117

118
      bool supports_alpn() const;
119

120
      bool sent_signature_algorithms() const;
121

122
      std::vector<std::string> next_protocols() const;
123

124
      std::vector<uint16_t> srtp_profiles() const;
125

126
      std::vector<uint8_t> serialize() const override;
127

128
      const std::vector<uint8_t>& cookie() const;
129

130
      std::vector<uint8_t> cookie_input_data() const;
131

132
      std::set<Extension_Code> extension_types() const;
133

134
      const Extensions& extensions() const;
135

136
   protected:
137
      Client_Hello();
138
      explicit Client_Hello(std::unique_ptr<Client_Hello_Internal> data);
139

140
      const std::vector<uint8_t>& compression_methods() const;
141

142
   protected:
143
      std::unique_ptr<Client_Hello_Internal> m_data;
144
};
145

146
class BOTAN_UNSTABLE_API Client_Hello_12 final : public Client_Hello {
10,608✔
147
   public:
148
      class Settings final {
2,535✔
149
         public:
150
            Settings(const Protocol_Version version, std::string_view hostname = "") :
2,426✔
151
                  m_new_session_version(version), m_hostname(hostname) {}
2,426✔
152

153
            Protocol_Version protocol_version() const { return m_new_session_version; }
4,852✔
154

155
            const std::string& hostname() const { return m_hostname; }
2,426✔
156

157
         private:
158
            const Protocol_Version m_new_session_version;
159
            const std::string m_hostname;
160
      };
161

162
   public:
163
      explicit Client_Hello_12(const std::vector<uint8_t>& buf);
164

165
      Client_Hello_12(Handshake_IO& io,
166
                      Handshake_Hash& hash,
167
                      const Policy& policy,
168
                      Callbacks& cb,
169
                      RandomNumberGenerator& rng,
170
                      const std::vector<uint8_t>& reneg_info,
171
                      const Settings& client_settings,
172
                      const std::vector<std::string>& next_protocols);
173

174
      Client_Hello_12(Handshake_IO& io,
175
                      Handshake_Hash& hash,
176
                      const Policy& policy,
177
                      Callbacks& cb,
178
                      RandomNumberGenerator& rng,
179
                      const std::vector<uint8_t>& reneg_info,
180
                      const Session_with_Handle& session_and_handle,
181
                      const std::vector<std::string>& next_protocols);
182

183
   protected:
184
      friend class Client_Hello_13;  // to allow construction by Client_Hello_13::parse()
185
      Client_Hello_12(std::unique_ptr<Client_Hello_Internal> data);
186

187
   public:
188
      using Client_Hello::compression_methods;
189
      using Client_Hello::random;
190

191
      bool prefers_compressed_ec_points() const;
192

193
      bool secure_renegotiation() const;
194

195
      std::vector<uint8_t> renegotiation_info() const;
196

197
      bool supports_session_ticket() const;
198

199
      Session_Ticket session_ticket() const;
200

201
      std::optional<Session_Handle> session_handle() const;
202

203
      bool supports_extended_master_secret() const;
204

205
      bool supports_cert_status_message() const;
206

207
      bool supports_encrypt_then_mac() const;
208

209
      void update_hello_cookie(const Hello_Verify_Request& hello_verify);
210

211
   private:
212
      std::unique_ptr<Supported_Groups> make_tls12_supported_groups(const Policy& policy) const;
213
};
214

215
#if defined(BOTAN_HAS_TLS_13)
216

217
class BOTAN_UNSTABLE_API Client_Hello_13 final : public Client_Hello {
8,406✔
218
   public:
219
      /**
220
       * Creates a client hello which might optionally use the passed-in
221
       * @p session for resumption. In that case, this will "extract" the
222
       * master secret from the passed-in @p session.
223
       */
224
      Client_Hello_13(const Policy& policy,
225
                      Callbacks& cb,
226
                      RandomNumberGenerator& rng,
227
                      std::string_view hostname,
228
                      const std::vector<std::string>& next_protocols,
229
                      std::optional<Session_with_Handle>& session,
230
                      std::vector<ExternalPSK> psks);
231

232
      static std::variant<Client_Hello_13, Client_Hello_12> parse(const std::vector<uint8_t>& buf);
233

234
      void retry(const Hello_Retry_Request& hrr,
235
                 const Transcript_Hash_State& transcript_hash_state,
236
                 Callbacks& cb,
237
                 RandomNumberGenerator& rng);
238

239
      /**
240
       * Select the highest protocol version from the list of versions
241
       * supported by the client. If no such version can be determind this
242
       * returns std::nullopt.
243
       */
244
      std::optional<Protocol_Version> highest_supported_version(const Policy& policy) const;
245

246
      /**
247
       * This validates that a Client Hello received after sending a Hello
248
       * Retry Request was updated in accordance with RFC 8446 4.1.2. If issues
249
       * are found, this method throws accordingly.
250
       */
251
      void validate_updates(const Client_Hello_13& new_ch);
252

253
   private:
254
      Client_Hello_13(std::unique_ptr<Client_Hello_Internal> data);
255

256
      /**
257
       * If the Client Hello contains a PSK extensions with identities this will
258
       * generate the PSK binders as described in RFC 8446 4.2.11.2.
259
       * Note that the passed in \p transcript_hash_state might be virgin for
260
       * the initial Client Hello and should be primed with ClientHello1 and
261
       * HelloRetryRequest for an updated Client Hello.
262
       */
263
      void calculate_psk_binders(Transcript_Hash_State transcript_hash_state);
264
};
265

266
#endif  // BOTAN_HAS_TLS_13
267

268
class Server_Hello_Internal;
269

270
/**
271
* Server Hello Message
272
*/
273
class BOTAN_UNSTABLE_API Server_Hello : public Handshake_Message {
274
   public:
275
      Server_Hello(const Server_Hello&) = delete;
276
      Server_Hello& operator=(const Server_Hello&) = delete;
277
      Server_Hello(Server_Hello&&) noexcept;
278
      Server_Hello& operator=(Server_Hello&&) noexcept;
279

280
      ~Server_Hello() override;
281

282
      std::vector<uint8_t> serialize() const override;
283

284
      Handshake_Type type() const override;
285

286
      // methods available in both subclasses' interface
287
      uint16_t ciphersuite() const;
288
      const Extensions& extensions() const;
289
      const Session_ID& session_id() const;
290

291
      virtual Protocol_Version selected_version() const = 0;
292

293
   protected:
294
      explicit Server_Hello(std::unique_ptr<Server_Hello_Internal> data);
295

296
      // methods used internally and potentially exposed by one of the subclasses
297
      std::set<Extension_Code> extension_types() const;
298
      const std::vector<uint8_t>& random() const;
299
      uint8_t compression_method() const;
300
      Protocol_Version legacy_version() const;
301

302
   protected:
303
      std::unique_ptr<Server_Hello_Internal> m_data;
304
};
305

306
class BOTAN_UNSTABLE_API Server_Hello_12 final : public Server_Hello {
9,259✔
307
   public:
308
      class Settings final {
1,348✔
309
         public:
310
            Settings(Session_ID new_session_id,
674✔
311
                     Protocol_Version new_session_version,
312
                     uint16_t ciphersuite,
313
                     bool offer_session_ticket) :
674✔
314
                  m_new_session_id(std::move(new_session_id)),
674✔
315
                  m_new_session_version(new_session_version),
674✔
316
                  m_ciphersuite(ciphersuite),
674✔
317
                  m_offer_session_ticket(offer_session_ticket) {}
674✔
318

319
            const Session_ID& session_id() const { return m_new_session_id; }
674✔
320

321
            Protocol_Version protocol_version() const { return m_new_session_version; }
674✔
322

323
            uint16_t ciphersuite() const { return m_ciphersuite; }
674✔
324

325
            bool offer_session_ticket() const { return m_offer_session_ticket; }
631✔
326

327
         private:
328
            const Session_ID m_new_session_id;
329
            Protocol_Version m_new_session_version;
330
            uint16_t m_ciphersuite;
331
            bool m_offer_session_ticket;
332
      };
333

334
      Server_Hello_12(Handshake_IO& io,
335
                      Handshake_Hash& hash,
336
                      const Policy& policy,
337
                      Callbacks& cb,
338
                      RandomNumberGenerator& rng,
339
                      const std::vector<uint8_t>& secure_reneg_info,
340
                      const Client_Hello_12& client_hello,
341
                      const Settings& settings,
342
                      std::string_view next_protocol);
343

344
      Server_Hello_12(Handshake_IO& io,
345
                      Handshake_Hash& hash,
346
                      const Policy& policy,
347
                      Callbacks& cb,
348
                      RandomNumberGenerator& rng,
349
                      const std::vector<uint8_t>& secure_reneg_info,
350
                      const Client_Hello_12& client_hello,
351
                      const Session& resumed_session,
352
                      bool offer_session_ticket,
353
                      std::string_view next_protocol);
354

355
      explicit Server_Hello_12(const std::vector<uint8_t>& buf);
356

357
   protected:
358
      friend class Server_Hello_13;  // to allow construction by Server_Hello_13::parse()
359
      explicit Server_Hello_12(std::unique_ptr<Server_Hello_Internal> data);
360

361
   public:
362
      using Server_Hello::compression_method;
363
      using Server_Hello::extension_types;
364
      using Server_Hello::legacy_version;
365
      using Server_Hello::random;
366

367
      /**
368
       * @returns the selected version as indicated in the legacy_version field
369
       */
370
      Protocol_Version selected_version() const override;
371

372
      bool secure_renegotiation() const;
373

374
      std::vector<uint8_t> renegotiation_info() const;
375

376
      std::string next_protocol() const;
377

378
      bool supports_extended_master_secret() const;
379

380
      bool supports_encrypt_then_mac() const;
381

382
      bool supports_certificate_status_message() const;
383

384
      bool supports_session_ticket() const;
385

386
      uint16_t srtp_profile() const;
387
      bool prefers_compressed_ec_points() const;
388

389
      /**
390
       * Return desired downgrade version indicated by hello random, if any.
391
       */
392
      std::optional<Protocol_Version> random_signals_downgrade() const;
393
};
394

395
#if defined(BOTAN_HAS_TLS_13)
396

397
class Hello_Retry_Request;
398

399
class BOTAN_UNSTABLE_API Server_Hello_13 : public Server_Hello {
6,265✔
400
   protected:
401
      static const struct Server_Hello_Tag {
402
      } as_server_hello;
403

404
      static const struct Hello_Retry_Request_Tag {
405
      } as_hello_retry_request;
406

407
      static const struct Hello_Retry_Request_Creation_Tag {
408
      } as_new_hello_retry_request;
409

410
      // These constructors are meant for instantiating Server Hellos
411
      // after parsing a peer's message. They perform basic validation
412
      // and are therefore not suitable for constructing a message to
413
      // be sent to a client.
414
      explicit Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Server_Hello_Tag tag = as_server_hello);
415
      explicit Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Hello_Retry_Request_Tag tag);
416
      void basic_validation() const;
417

418
      // Instantiate a Server Hello as response to a client's Client Hello
419
      // (called from Server_Hello_13::create())
420
      Server_Hello_13(const Client_Hello_13& ch,
421
                      std::optional<Named_Group> key_exchange_group,
422
                      Session_Manager& session_mgr,
423
                      Credentials_Manager& credentials_mgr,
424
                      RandomNumberGenerator& rng,
425
                      Callbacks& cb,
426
                      const Policy& policy);
427

428
      explicit Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Hello_Retry_Request_Creation_Tag tag);
429

430
   public:
431
      static std::variant<Hello_Retry_Request, Server_Hello_13> create(const Client_Hello_13& ch,
432
                                                                       bool hello_retry_request_allowed,
433
                                                                       Session_Manager& session_mgr,
434
                                                                       Credentials_Manager& credentials_mgr,
435
                                                                       RandomNumberGenerator& rng,
436
                                                                       const Policy& policy,
437
                                                                       Callbacks& cb);
438

439
      static std::variant<Hello_Retry_Request, Server_Hello_13, Server_Hello_12> parse(const std::vector<uint8_t>& buf);
440

441
      /**
442
       * Return desired downgrade version indicated by hello random, if any.
443
       */
444
      std::optional<Protocol_Version> random_signals_downgrade() const;
445

446
      /**
447
       * @returns the selected version as indicated by the supported_versions extension
448
       */
449
      Protocol_Version selected_version() const final;
450
};
451

452
class BOTAN_UNSTABLE_API Hello_Retry_Request final : public Server_Hello_13 {
756✔
453
   protected:
454
      friend class Server_Hello_13;  // to allow construction by Server_Hello_13::parse() and ::create()
455
      explicit Hello_Retry_Request(std::unique_ptr<Server_Hello_Internal> data);
456
      Hello_Retry_Request(const Client_Hello_13& ch, Named_Group selected_group, const Policy& policy, Callbacks& cb);
457

458
   public:
459
      Handshake_Type type() const override { return Handshake_Type::HelloRetryRequest; }
39✔
460

461
      Handshake_Type wire_type() const override { return Handshake_Type::ServerHello; }
×
462
};
463

464
class BOTAN_UNSTABLE_API Encrypted_Extensions final : public Handshake_Message {
3,935✔
465
   public:
466
      explicit Encrypted_Extensions(const std::vector<uint8_t>& buf);
467
      Encrypted_Extensions(const Client_Hello_13& client_hello, const Policy& policy, Callbacks& cb);
468

469
      Handshake_Type type() const override { return Handshake_Type::EncryptedExtensions; }
1,135✔
470

471
      const Extensions& extensions() const { return m_extensions; }
957✔
472

473
      std::vector<uint8_t> serialize() const override;
474

475
   private:
476
      Extensions m_extensions;
477
};
478

479
#endif  // BOTAN_HAS_TLS_13
480

481
/**
482
* Client Key Exchange Message
483
*/
484
class BOTAN_UNSTABLE_API Client_Key_Exchange final : public Handshake_Message {
1,386✔
485
   public:
486
      Handshake_Type type() const override { return Handshake_Type::ClientKeyExchange; }
2,325✔
487

488
      const secure_vector<uint8_t>& pre_master_secret() const { return m_pre_master; }
1,392✔
489

490
      /**
491
       * @returns the agreed upon PSK identity or std::nullopt if not applicable
492
       */
493
      const std::optional<std::string>& psk_identity() const { return m_psk_identity; }
1,292✔
494

495
      Client_Key_Exchange(Handshake_IO& io,
496
                          Handshake_State& state,
497
                          const Policy& policy,
498
                          Credentials_Manager& creds,
499
                          const Public_Key* server_public_key,
500
                          std::string_view hostname,
501
                          RandomNumberGenerator& rng);
502

503
      Client_Key_Exchange(const std::vector<uint8_t>& buf,
504
                          const Handshake_State& state,
505
                          const Private_Key* server_rsa_kex_key,
506
                          Credentials_Manager& creds,
507
                          const Policy& policy,
508
                          RandomNumberGenerator& rng);
509

510
   private:
511
      std::vector<uint8_t> serialize() const override { return m_key_material; }
752✔
512

513
      std::vector<uint8_t> m_key_material;
514
      secure_vector<uint8_t> m_pre_master;
515
      std::optional<std::string> m_psk_identity;
516
};
517

518
/**
519
* Certificate Message of TLS 1.2
520
*/
521
class BOTAN_UNSTABLE_API Certificate_12 final : public Handshake_Message {
1,822✔
522
   public:
523
      Handshake_Type type() const override { return Handshake_Type::Certificate; }
2,722✔
524

525
      const std::vector<X509_Certificate>& cert_chain() const { return m_certs; }
2,767✔
526

527
      size_t count() const { return m_certs.size(); }
528

529
      bool empty() const { return m_certs.empty(); }
614✔
530

531
      Certificate_12(Handshake_IO& io, Handshake_Hash& hash, const std::vector<X509_Certificate>& certs);
532

533
      Certificate_12(const std::vector<uint8_t>& buf, const Policy& policy);
534

535
      std::vector<uint8_t> serialize() const override;
536

537
   private:
538
      std::vector<X509_Certificate> m_certs;
539
};
540

541
#if defined(BOTAN_HAS_TLS_13)
542

543
class Certificate_Request_13;
544

545
/**
546
* Certificate Message of TLS 1.3
547
*/
548
class BOTAN_UNSTABLE_API Certificate_13 final : public Handshake_Message {
3,071✔
549
   public:
550
      struct Certificate_Entry {
2,585✔
551
            // TODO: RFC 8446 4.4.2 specifies the possibility to negotiate the usage
552
            //       of a single raw public key in lieu of the X.509 certificate
553
            //       chain. This is left for future work.
554
            X509_Certificate certificate;
555
            Extensions extensions;
556
      };
557

558
   public:
559
      Handshake_Type type() const override { return Handshake_Type::Certificate; }
763✔
560

561
      std::vector<X509_Certificate> cert_chain() const;
562

563
      size_t count() const { return m_entries.size(); }
564

565
      bool empty() const { return m_entries.empty(); }
1,083✔
566

567
      const X509_Certificate& leaf() const;
568

569
      const std::vector<uint8_t>& request_context() const { return m_request_context; }
413✔
570

571
      /**
572
       * Create a Client Certificate message
573
       * ... in response to a Certificate Request message.
574
       */
575
      Certificate_13(const Certificate_Request_13& cert_request,
576
                     std::string_view hostname,
577
                     Credentials_Manager& credentials_manager,
578
                     Callbacks& callbacks);
579

580
      /**
581
       * Create a Server Certificate message
582
       * ... in response to a Client Hello indicating the need to authenticate
583
       *     with a server certificate.
584
       */
585
      Certificate_13(const Client_Hello_13& client_hello,
586
                     Credentials_Manager& credentials_manager,
587
                     Callbacks& callbacks);
588

589
      /**
590
      * Deserialize a Certificate message
591
      * @param buf the serialized message
592
      * @param policy the TLS policy
593
      * @param side is this a Connection_Side::Server or Connection_Side::Client certificate message
594
      */
595
      Certificate_13(const std::vector<uint8_t>& buf, const Policy& policy, Connection_Side side);
596

597
      /**
598
      * Validate a Certificate message regarding what extensions are expected based on
599
      * previous handshake messages. Also call the tls_examine_extenions() callback
600
      * for each entry.
601
      *
602
      * @param requested_extensions Extensions of Client_Hello or Certificate_Request messages
603
      */
604
      void validate_extensions(const std::set<Extension_Code>& requested_extensions, Callbacks& cb) const;
605

606
      /**
607
       * Verify the certificate chain
608
       *
609
       * @throws if verification fails.
610
       */
611
      void verify(Callbacks& callbacks,
612
                  const Policy& policy,
613
                  Credentials_Manager& creds,
614
                  std::string_view hostname,
615
                  bool use_ocsp) const;
616

617
      std::vector<uint8_t> serialize() const override;
618

619
   private:
620
      void setup_entries(std::vector<X509_Certificate> cert_chain,
621
                         const Certificate_Status_Request* csr,
622
                         Callbacks& callbacks);
623

624
   private:
625
      std::vector<uint8_t> m_request_context;
626
      std::vector<Certificate_Entry> m_entries;
627
      Connection_Side m_side;
628
};
629

630
#endif  // BOTAN_HAS_TLS_13
631

632
/**
633
* Certificate Status (RFC 6066)
634
*/
635
class BOTAN_UNSTABLE_API Certificate_Status final : public Handshake_Message {
174✔
636
   public:
637
      Handshake_Type type() const override { return Handshake_Type::CertificateStatus; }
129✔
638

639
      //std::shared_ptr<const OCSP::Response> response() const { return m_response; }
640

641
      const std::vector<uint8_t>& response() const { return m_response; }
73✔
642

643
      explicit Certificate_Status(const std::vector<uint8_t>& buf, Connection_Side from);
644

645
      Certificate_Status(Handshake_IO& io, Handshake_Hash& hash, const OCSP::Response& response);
646

647
      /*
648
       * Create a Certificate_Status message using an already DER encoded OCSP response.
649
       */
650
      Certificate_Status(Handshake_IO& io, Handshake_Hash& hash, std::vector<uint8_t> raw_response_bytes);
651

652
      Certificate_Status(std::vector<uint8_t> raw_response_bytes);
653

654
      std::vector<uint8_t> serialize() const override;
655

656
   private:
657
      std::vector<uint8_t> m_response;
658
};
659

660
/**
661
* Certificate Request Message (TLS 1.2)
662
*/
663
class BOTAN_UNSTABLE_API Certificate_Request_12 final : public Handshake_Message {
398✔
664
   public:
665
      Handshake_Type type() const override;
666

667
      const std::vector<std::string>& acceptable_cert_types() const;
668

669
      const std::vector<X509_DN>& acceptable_CAs() const;
670

671
      const std::vector<Signature_Scheme>& signature_schemes() const;
672

673
      Certificate_Request_12(Handshake_IO& io,
674
                             Handshake_Hash& hash,
675
                             const Policy& policy,
676
                             const std::vector<X509_DN>& allowed_cas);
677

678
      explicit Certificate_Request_12(const std::vector<uint8_t>& buf);
679

680
      std::vector<uint8_t> serialize() const override;
681

682
   private:
683
      std::vector<X509_DN> m_names;
684
      std::vector<std::string> m_cert_key_types;
685
      std::vector<Signature_Scheme> m_schemes;
686
};
687

688
#if defined(BOTAN_HAS_TLS_13)
689

690
class BOTAN_UNSTABLE_API Certificate_Request_13 final : public Handshake_Message {
726✔
691
   public:
692
      Handshake_Type type() const override;
693

694
      Certificate_Request_13(const std::vector<uint8_t>& buf, Connection_Side side);
695

696
      //! Creates a Certificate_Request message if it is required by the configuration
697
      //! @return std::nullopt if configuration does not require client authentication
698
      static std::optional<Certificate_Request_13> maybe_create(const Client_Hello_13& sni_hostname,
699
                                                                Credentials_Manager& cred_mgr,
700
                                                                Callbacks& callbacks,
701
                                                                const Policy& policy);
702

703
      std::vector<X509_DN> acceptable_CAs() const;
704
      const std::vector<Signature_Scheme>& signature_schemes() const;
705
      const std::vector<Signature_Scheme>& certificate_signature_schemes() const;
706

707
      const Extensions& extensions() const { return m_extensions; }
201✔
708

709
      std::vector<uint8_t> serialize() const override;
710

711
      const std::vector<uint8_t>& context() const { return m_context; }
107✔
712

713
   private:
714
      Certificate_Request_13(std::vector<X509_DN> acceptable_CAs, const Policy& policy, Callbacks& callbacks);
715

716
   private:
717
      std::vector<uint8_t> m_context;
718
      Extensions m_extensions;
719
};
720

721
#endif
722

723
class BOTAN_UNSTABLE_API Certificate_Verify : public Handshake_Message {
5,318✔
724
   public:
725
      Handshake_Type type() const override { return Handshake_Type::CertificateVerify; }
1,190✔
726

727
      Signature_Scheme signature_scheme() const { return m_scheme; }
320✔
728

729
      Certificate_Verify(const std::vector<uint8_t>& buf);
730
      Certificate_Verify() = default;
366✔
731

732
      std::vector<uint8_t> serialize() const override;
733

734
   protected:
735
      std::vector<uint8_t> m_signature;
736
      Signature_Scheme m_scheme;
737
};
738

739
/**
740
* Certificate Verify Message
741
*/
742
class BOTAN_UNSTABLE_API Certificate_Verify_12 final : public Certificate_Verify {
743
   public:
744
      using Certificate_Verify::Certificate_Verify;
131✔
745

746
      Certificate_Verify_12(Handshake_IO& io,
747
                            Handshake_State& state,
748
                            const Policy& policy,
749
                            RandomNumberGenerator& rng,
750
                            const Private_Key* key);
751

752
      /**
753
      * Check the signature on a certificate verify message
754
      * @param cert the purported certificate
755
      * @param state the handshake state
756
      * @param policy the TLS policy
757
      */
758
      bool verify(const X509_Certificate& cert, const Handshake_State& state, const Policy& policy) const;
759
};
760

761
#if defined(BOTAN_HAS_TLS_13)
762

763
/**
764
* Certificate Verify Message
765
*/
766
class BOTAN_UNSTABLE_API Certificate_Verify_13 final : public Certificate_Verify {
4,281✔
767
   public:
768
      /**
769
      * Deserialize a Certificate message
770
      * @param buf the serialized message
771
      * @param side is this a Connection_Side::Server or Connection_Side::Client certificate message
772
      */
773
      Certificate_Verify_13(const std::vector<uint8_t>& buf, Connection_Side side);
774

775
      Certificate_Verify_13(const Certificate_13& certificate_message,
776
                            const std::vector<Signature_Scheme>& peer_allowed_schemes,
777
                            std::string_view hostname,
778
                            const Transcript_Hash& hash,
779
                            Connection_Side whoami,
780
                            Credentials_Manager& creds_mgr,
781
                            const Policy& policy,
782
                            Callbacks& callbacks,
783
                            RandomNumberGenerator& rng);
784

785
      bool verify(const X509_Certificate& cert, Callbacks& callbacks, const Transcript_Hash& transcript_hash) const;
786

787
   private:
788
      Connection_Side m_side;
789
};
790

791
#endif
792

793
/**
794
* Finished Message
795
*/
796
class BOTAN_UNSTABLE_API Finished : public Handshake_Message {
10,263✔
797
   public:
798
      explicit Finished(const std::vector<uint8_t>& buf);
799

800
      Handshake_Type type() const override { return Handshake_Type::Finished; }
7,533✔
801

802
      std::vector<uint8_t> verify_data() const;
803

804
      std::vector<uint8_t> serialize() const override;
805

806
   protected:
807
      using Handshake_Message::Handshake_Message;
2,398✔
808
      std::vector<uint8_t> m_verification_data;
809
};
810

811
class BOTAN_UNSTABLE_API Finished_12 final : public Finished {
812
   public:
813
      using Finished::Finished;
1,736✔
814
      Finished_12(Handshake_IO& io, Handshake_State& state, Connection_Side side);
815

816
      bool verify(const Handshake_State& state, Connection_Side side) const;
817
};
818

819
#if defined(BOTAN_HAS_TLS_13)
820
class BOTAN_UNSTABLE_API Finished_13 final : public Finished {
8,644✔
821
   public:
822
      using Finished::Finished;
620✔
823
      Finished_13(Cipher_State* cipher_state, const Transcript_Hash& transcript_hash);
824

825
      bool verify(Cipher_State* cipher_state, const Transcript_Hash& transcript_hash) const;
826
};
827
#endif
828

829
/**
830
* Hello Request Message
831
*/
832
class BOTAN_UNSTABLE_API Hello_Request final : public Handshake_Message {
35✔
833
   public:
834
      Handshake_Type type() const override { return Handshake_Type::HelloRequest; }
×
835

836
      explicit Hello_Request(Handshake_IO& io);
837
      explicit Hello_Request(const std::vector<uint8_t>& buf);
838

839
   private:
840
      std::vector<uint8_t> serialize() const override;
841
};
842

843
/**
844
* Server Key Exchange Message
845
*/
846
class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message {
1,336✔
847
   public:
848
      Handshake_Type type() const override { return Handshake_Type::ServerKeyExchange; }
2,070✔
849

850
      const std::vector<uint8_t>& params() const { return m_params; }
3,075✔
851

852
      bool verify(const Public_Key& server_key, const Handshake_State& state, const Policy& policy) const;
853

854
      // Only valid for certain kex types
855
      const PK_Key_Agreement_Key& server_kex_key() const;
856

857
      /**
858
       * @returns the agreed upon KEX group or std::nullopt if the KEX type does
859
       *          not depend on a group
860
       */
861
      const std::optional<Group_Params>& shared_group() const { return m_shared_group; }
551✔
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<PK_Key_Agreement_Key> m_kex_key;
879
      std::optional<Group_Params> m_shared_group;
880

881
      std::vector<uint8_t> m_params;
882

883
      std::vector<uint8_t> m_signature;
884
      Signature_Scheme m_scheme;
885
};
886

887
/**
888
* Server Hello Done Message
889
*/
890
class BOTAN_UNSTABLE_API Server_Hello_Done final : public Handshake_Message {
1,425✔
891
   public:
892
      Handshake_Type type() const override { return Handshake_Type::ServerHelloDone; }
2,214✔
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 {
5✔
905
   public:
906
      Handshake_Type type() const override { return Handshake_Type::NewSessionTicket; }
1,618✔
907

908
      std::chrono::seconds ticket_lifetime_hint() const { return m_ticket_lifetime_hint; }
582✔
909

910
      const Session_Ticket& ticket() const { return m_ticket; }
1,163✔
911

912
      New_Session_Ticket_12(Handshake_IO& io,
913
                            Handshake_Hash& hash,
914
                            Session_Ticket ticket,
915
                            std::chrono::seconds lifetime);
916

917
      New_Session_Ticket_12(Handshake_IO& io, Handshake_Hash& hash);
918

919
      explicit New_Session_Ticket_12(const std::vector<uint8_t>& buf);
920

921
      std::vector<uint8_t> serialize() const override;
922

923
   private:
924
      std::chrono::seconds m_ticket_lifetime_hint;
925
      Session_Ticket m_ticket;
926
};
927

928
#if defined(BOTAN_HAS_TLS_13)
929

930
/// @brief Used to derive the ticket's PSK from the resumption_master_secret
931
using Ticket_Nonce = Strong<std::vector<uint8_t>, struct Ticket_Nonce_>;
932

933
class BOTAN_UNSTABLE_API New_Session_Ticket_13 final : public Handshake_Message {
3,029✔
934
   public:
935
      Handshake_Type type() const override { return Handshake_Type::NewSessionTicket; }
1,090✔
936

937
      New_Session_Ticket_13(Ticket_Nonce nonce,
938
                            const Session& session,
939
                            const Session_Handle& handle,
940
                            Callbacks& callbacks);
941

942
      New_Session_Ticket_13(const std::vector<uint8_t>& buf, Connection_Side from);
943

944
      std::vector<uint8_t> serialize() const override;
945

946
      const Extensions& extensions() const { return m_extensions; }
552✔
947

948
      const Opaque_Session_Handle& handle() const { return m_handle; }
552✔
949

950
      const Ticket_Nonce& nonce() const { return m_ticket_nonce; }
552✔
951

952
      uint32_t ticket_age_add() const { return m_ticket_age_add; }
552✔
953

954
      std::chrono::seconds lifetime_hint() const { return m_ticket_lifetime_hint; }
552✔
955

956
      /**
957
       * @return  the number of bytes allowed for early data or std::nullopt
958
       *          when early data is not allowed at all
959
       */
960
      std::optional<uint32_t> early_data_byte_limit() const;
961

962
   private:
963
      // RFC 8446 4.6.1
964
      //    Clients MUST NOT cache tickets for longer than 7 days, regardless of
965
      //    the ticket_lifetime, and MAY delete tickets earlier based on local
966
      //    policy.  A server MAY treat a ticket as valid for a shorter period
967
      //    of time than what is stated in the ticket_lifetime.
968
      //
969
      // ... hence we call it 'lifetime hint'.
970
      std::chrono::seconds m_ticket_lifetime_hint;
971
      uint32_t m_ticket_age_add;
972
      Ticket_Nonce m_ticket_nonce;
973
      Opaque_Session_Handle m_handle;
974
      Extensions m_extensions;
975
};
976

977
#endif
978

979
/**
980
* Change Cipher Spec
981
*/
982
class BOTAN_UNSTABLE_API Change_Cipher_Spec final : public Handshake_Message {
3,520✔
983
   public:
984
      Handshake_Type type() const override { return Handshake_Type::HandshakeCCS; }
1,757✔
985

986
      std::vector<uint8_t> serialize() const override { return std::vector<uint8_t>(1, 1); }
1,757✔
987
};
988

989
#if defined(BOTAN_HAS_TLS_13)
990

991
class BOTAN_UNSTABLE_API Key_Update final : public Handshake_Message {
68✔
992
   public:
993
      Handshake_Type type() const override { return Handshake_Type::KeyUpdate; }
14✔
994

995
      explicit Key_Update(bool request_peer_update);
996
      explicit Key_Update(const std::vector<uint8_t>& buf);
997

998
      std::vector<uint8_t> serialize() const override;
999

1000
      bool expects_reciprocation() const { return m_update_requested; }
27✔
1001

1002
   private:
1003
      bool m_update_requested;
1004
};
1005

1006
namespace {
1007
template <typename T>
1008
struct as_wrapped_references {};
1009

1010
template <typename... AlternativeTs>
1011
struct as_wrapped_references<std::variant<AlternativeTs...>> {
1012
      using type = std::variant<std::reference_wrapper<AlternativeTs>...>;
1013
};
1014

1015
template <typename T>
1016
using as_wrapped_references_t = typename as_wrapped_references<T>::type;
1017
}  // namespace
1018

1019
// Handshake message types from RFC 8446 4.
1020
using Handshake_Message_13 = std::variant<Client_Hello_13,
1021
                                          Client_Hello_12,
1022
                                          Server_Hello_13,
1023
                                          Server_Hello_12,
1024
                                          Hello_Retry_Request,
1025
                                          // End_Of_Early_Data,
1026
                                          Encrypted_Extensions,
1027
                                          Certificate_13,
1028
                                          Certificate_Request_13,
1029
                                          Certificate_Verify_13,
1030
                                          Finished_13>;
1031
using Handshake_Message_13_Ref = as_wrapped_references_t<Handshake_Message_13>;
1032

1033
using Post_Handshake_Message_13 = std::variant<New_Session_Ticket_13, Key_Update>;
1034

1035
// Key_Update is handled generically by the Channel. The messages assigned
1036
// to those variants are the ones that need to be handled by the specific
1037
// client and/or server implementations.
1038
using Server_Post_Handshake_13_Message = std::variant<New_Session_Ticket_13, Key_Update>;
1039
using Client_Post_Handshake_13_Message = std::variant<Key_Update>;
1040

1041
using Server_Handshake_13_Message = std::variant<Server_Hello_13,
1042
                                                 Server_Hello_12,  // indicates a TLS version downgrade
1043
                                                 Hello_Retry_Request,
1044
                                                 Encrypted_Extensions,
1045
                                                 Certificate_13,
1046
                                                 Certificate_Request_13,
1047
                                                 Certificate_Verify_13,
1048
                                                 Finished_13>;
1049
using Server_Handshake_13_Message_Ref = as_wrapped_references_t<Server_Handshake_13_Message>;
1050

1051
using Client_Handshake_13_Message = std::variant<Client_Hello_13,
1052
                                                 Client_Hello_12,  // indicates a TLS peer that does not offer TLS 1.3
1053
                                                 Certificate_13,
1054
                                                 Certificate_Verify_13,
1055
                                                 Finished_13>;
1056
using Client_Handshake_13_Message_Ref = as_wrapped_references_t<Client_Handshake_13_Message>;
1057

1058
#endif  // BOTAN_HAS_TLS_13
1059

1060
}  // namespace TLS
1061

1062
}  // namespace Botan
1063

1064
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc