Botan 3.1.1
Crypto and TLS for C&
tls_extensions.h
Go to the documentation of this file.
1/*
2* TLS Extensions
3* (C) 2011,2012,2016,2018,2019 Jack Lloyd
4* (C) 2016 Juraj Somorovsky
5* (C) 2016 Matthias Gierlings
6* (C) 2021 Elektrobit Automotive GmbH
7* (C) 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
8*
9* Botan is released under the Simplified BSD License (see license.txt)
10*/
11
12#ifndef BOTAN_TLS_EXTENSIONS_H_
13#define BOTAN_TLS_EXTENSIONS_H_
14
15#include <botan/pkix_types.h>
16#include <botan/secmem.h>
17#include <botan/tls_algos.h>
18#include <botan/tls_magic.h>
19#include <botan/tls_session.h>
20#include <botan/tls_signature_scheme.h>
21#include <botan/tls_version.h>
22
23#include <algorithm>
24#include <memory>
25#include <optional>
26#include <set>
27#include <string>
28#include <variant>
29#include <vector>
30
31namespace Botan {
32
33class RandomNumberGenerator;
34
35namespace TLS {
36
37#if defined(BOTAN_HAS_TLS_13)
38class Callbacks;
39class Session_Manager;
40class Cipher_State;
41class Ciphersuite;
42class Transcript_Hash_State;
43
44enum class PSK_Key_Exchange_Mode : uint8_t { PSK_KE = 0, PSK_DHE_KE = 1 };
45
46#endif
47class Policy;
48class TLS_Data_Reader;
49
50enum class Extension_Code : uint16_t {
53
54 SupportedGroups = 10,
55 EcPointFormats = 11,
58 UseSrtp = 14,
60
61 // SignedCertificateTimestamp = 18, // NYI
62
63 EncryptThenMac = 22,
65
66 RecordSizeLimit = 28,
67
68 SessionTicket = 35,
69
71#if defined(BOTAN_HAS_TLS_13)
72 PresharedKey = 41,
73 EarlyData = 42,
74 Cookie = 44,
75
76 PskKeyExchangeModes = 45,
77 CertificateAuthorities = 47,
78 // OidFilters = 48, // NYI
79
80 KeyShare = 51,
81#endif
82
83 SafeRenegotiation = 65281,
84};
85
86/**
87* Base class representing a TLS extension of some kind
88*/
90 public:
91 /**
92 * @return code number of the extension
93 */
94 virtual Extension_Code type() const = 0;
95
96 /**
97 * @return serialized binary for the extension
98 */
99 virtual std::vector<uint8_t> serialize(Connection_Side whoami) const = 0;
100
101 /**
102 * @return if we should encode this extension or not
103 */
104 virtual bool empty() const = 0;
105
106 /**
107 * @return true if this extension is known and implemented by Botan
108 */
109 virtual bool is_implemented() const { return true; }
110
111 virtual ~Extension() = default;
112};
113
114/**
115* Server Name Indicator extension (RFC 3546)
116*/
118 public:
119 static Extension_Code static_type() { return Extension_Code::ServerNameIndication; }
120
121 Extension_Code type() const override { return static_type(); }
122
123 explicit Server_Name_Indicator(std::string_view host_name) : m_sni_host_name(host_name) {}
124
125 Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size);
126
127 std::string host_name() const { return m_sni_host_name; }
128
129 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
130
131 bool empty() const override { return false; }
132
133 private:
134 std::string m_sni_host_name;
135};
136
137/**
138* Renegotiation Indication Extension (RFC 5746)
139*/
141 public:
142 static Extension_Code static_type() { return Extension_Code::SafeRenegotiation; }
143
144 Extension_Code type() const override { return static_type(); }
145
147
148 explicit Renegotiation_Extension(const std::vector<uint8_t>& bits) : m_reneg_data(bits) {}
149
150 Renegotiation_Extension(TLS_Data_Reader& reader, uint16_t extension_size);
151
152 const std::vector<uint8_t>& renegotiation_info() const { return m_reneg_data; }
153
154 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
155
156 bool empty() const override { return false; } // always send this
157
158 private:
159 std::vector<uint8_t> m_reneg_data;
160};
161
162/**
163* ALPN (RFC 7301)
164*/
166 public:
167 static Extension_Code static_type() { return Extension_Code::ApplicationLayerProtocolNegotiation; }
168
169 Extension_Code type() const override { return static_type(); }
170
171 const std::vector<std::string>& protocols() const { return m_protocols; }
172
173 std::string single_protocol() const;
174
175 /**
176 * Single protocol, used by server
177 */
178 explicit Application_Layer_Protocol_Notification(std::string_view protocol) :
179 m_protocols(1, std::string(protocol)) {}
180
181 /**
182 * List of protocols, used by client
183 */
184 explicit Application_Layer_Protocol_Notification(const std::vector<std::string>& protocols) :
185 m_protocols(protocols) {}
186
187 Application_Layer_Protocol_Notification(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from);
188
189 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
190
191 bool empty() const override { return m_protocols.empty(); }
192
193 private:
194 std::vector<std::string> m_protocols;
195};
196
197/**
198* Session Ticket Extension (RFC 5077)
199*/
201 public:
202 static Extension_Code static_type() { return Extension_Code::SessionTicket; }
203
204 Extension_Code type() const override { return static_type(); }
205
206 /**
207 * @return contents of the session ticket
208 */
209 const Session_Ticket& contents() const { return m_ticket; }
210
211 /**
212 * Create empty extension, used by both client and server
213 */
215
216 /**
217 * Extension with ticket, used by client
218 */
219 explicit Session_Ticket_Extension(Session_Ticket session_ticket) : m_ticket(std::move(session_ticket)) {}
220
221 /**
222 * Deserialize a session ticket
223 */
224 Session_Ticket_Extension(TLS_Data_Reader& reader, uint16_t extension_size);
225
226 std::vector<uint8_t> serialize(Connection_Side) const override { return m_ticket.get(); }
227
228 bool empty() const override { return false; }
229
230 private:
231 Session_Ticket m_ticket;
232};
233
234/**
235* Supported Groups Extension (RFC 7919)
236*/
238 public:
239 static Extension_Code static_type() { return Extension_Code::SupportedGroups; }
240
241 Extension_Code type() const override { return static_type(); }
242
243 const std::vector<Group_Params>& groups() const;
244 std::vector<Group_Params> ec_groups() const;
245 std::vector<Group_Params> dh_groups() const;
246
247 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
248
249 explicit Supported_Groups(const std::vector<Group_Params>& groups);
250
251 Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size);
252
253 bool empty() const override { return m_groups.empty(); }
254
255 private:
256 std::vector<Group_Params> m_groups;
257};
258
259// previously Supported Elliptic Curves Extension (RFC 4492)
260//using Supported_Elliptic_Curves = Supported_Groups;
261
262/**
263* Supported Point Formats Extension (RFC 4492)
264*/
266 public:
267 enum ECPointFormat : uint8_t {
269 ANSIX962_COMPRESSED_PRIME = 1,
270 ANSIX962_COMPRESSED_CHAR2 = 2, // don't support these curves
271 };
272
273 static Extension_Code static_type() { return Extension_Code::EcPointFormats; }
274
275 Extension_Code type() const override { return static_type(); }
276
277 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
278
279 explicit Supported_Point_Formats(bool prefer_compressed) : m_prefers_compressed(prefer_compressed) {}
280
281 Supported_Point_Formats(TLS_Data_Reader& reader, uint16_t extension_size);
282
283 bool empty() const override { return false; }
284
285 bool prefers_compressed() { return m_prefers_compressed; }
286
287 private:
288 bool m_prefers_compressed = false;
289};
290
291/**
292* Signature Algorithms Extension for TLS 1.2 (RFC 5246)
293*/
295 public:
296 static Extension_Code static_type() { return Extension_Code::SignatureAlgorithms; }
297
298 Extension_Code type() const override { return static_type(); }
299
300 const std::vector<Signature_Scheme>& supported_schemes() const { return m_schemes; }
301
302 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
303
304 bool empty() const override { return m_schemes.empty(); }
305
306 explicit Signature_Algorithms(std::vector<Signature_Scheme> schemes) : m_schemes(std::move(schemes)) {}
307
308 Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size);
309
310 private:
311 std::vector<Signature_Scheme> m_schemes;
312};
313
314/**
315* Signature_Algorithms_Cert for TLS 1.3 (RFC 8446)
316*
317* RFC 8446 4.2.3
318* TLS 1.3 provides two extensions for indicating which signature algorithms
319* may be used in digital signatures. The "signature_algorithms_cert"
320* extension applies to signatures in certificates, and the
321* "signature_algorithms" extension, which originally appeared in TLS 1.2,
322* applies to signatures in CertificateVerify messages.
323*
324* RFC 8446 4.2.3
325* TLS 1.2 implementations SHOULD also process this extension.
326*/
328 public:
329 static Extension_Code static_type() { return Extension_Code::CertSignatureAlgorithms; }
330
331 Extension_Code type() const override { return static_type(); }
332
333 const std::vector<Signature_Scheme>& supported_schemes() const { return m_schemes; }
334
335 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
336
337 bool empty() const override { return m_schemes.empty(); }
338
339 explicit Signature_Algorithms_Cert(std::vector<Signature_Scheme> schemes) : m_schemes(std::move(schemes)) {}
340
341 Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size);
342
343 private:
344 std::vector<Signature_Scheme> m_schemes;
345};
346
347/**
348* Used to indicate SRTP algorithms for DTLS (RFC 5764)
349*/
351 public:
352 static Extension_Code static_type() { return Extension_Code::UseSrtp; }
353
354 Extension_Code type() const override { return static_type(); }
355
356 const std::vector<uint16_t>& profiles() const { return m_pp; }
357
358 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
359
360 bool empty() const override { return m_pp.empty(); }
361
362 explicit SRTP_Protection_Profiles(const std::vector<uint16_t>& pp) : m_pp(pp) {}
363
364 explicit SRTP_Protection_Profiles(uint16_t pp) : m_pp(1, pp) {}
365
366 SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size);
367
368 private:
369 std::vector<uint16_t> m_pp;
370};
371
372/**
373* Extended Master Secret Extension (RFC 7627)
374*/
376 public:
377 static Extension_Code static_type() { return Extension_Code::ExtendedMasterSecret; }
378
379 Extension_Code type() const override { return static_type(); }
380
381 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
382
383 bool empty() const override { return false; }
384
386
387 Extended_Master_Secret(TLS_Data_Reader& reader, uint16_t extension_size);
388};
389
390/**
391* Encrypt-then-MAC Extension (RFC 7366)
392*/
394 public:
395 static Extension_Code static_type() { return Extension_Code::EncryptThenMac; }
396
397 Extension_Code type() const override { return static_type(); }
398
399 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
400
401 bool empty() const override { return false; }
402
403 Encrypt_then_MAC() = default;
404
405 Encrypt_then_MAC(TLS_Data_Reader& reader, uint16_t extension_size);
406};
407
408class Certificate_Status_Request_Internal;
409
410/**
411* Certificate Status Request (RFC 6066)
412*/
414 public:
415 static Extension_Code static_type() { return Extension_Code::CertificateStatusRequest; }
416
417 Extension_Code type() const override { return static_type(); }
418
419 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
420
421 bool empty() const override { return false; }
422
423 const std::vector<uint8_t>& get_responder_id_list() const;
424 const std::vector<uint8_t>& get_request_extensions() const;
425 const std::vector<uint8_t>& get_ocsp_response() const;
426
427 // TLS 1.2 Server generated version: empty
429
430 // TLS 1.2 Client version, both lists can be empty
431 Certificate_Status_Request(std::vector<uint8_t> ocsp_responder_ids,
432 std::vector<std::vector<uint8_t>> ocsp_key_ids);
433
434 // TLS 1.3 version
435 Certificate_Status_Request(std::vector<uint8_t> response);
436
438 uint16_t extension_size,
439 Handshake_Type message_type,
440 Connection_Side from);
441
443
444 private:
445 std::unique_ptr<Certificate_Status_Request_Internal> m_impl;
446};
447
448/**
449* Supported Versions from RFC 8446
450*/
452 public:
453 static Extension_Code static_type() { return Extension_Code::SupportedVersions; }
454
455 Extension_Code type() const override { return static_type(); }
456
457 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
458
459 bool empty() const override { return m_versions.empty(); }
460
461 Supported_Versions(Protocol_Version version, const Policy& policy);
462
463 Supported_Versions(Protocol_Version version) { m_versions.push_back(version); }
464
465 Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from);
466
467 bool supports(Protocol_Version version) const;
468
469 const std::vector<Protocol_Version>& versions() const { return m_versions; }
470
471 private:
472 std::vector<Protocol_Version> m_versions;
473};
474
476
477/**
478* Record Size Limit (RFC 8449)
479*
480* TODO: the record size limit is currently not honored by the TLS 1.2 stack
481*/
483 public:
484 static Extension_Code static_type() { return Extension_Code::RecordSizeLimit; }
485
486 Extension_Code type() const override { return static_type(); }
487
488 explicit Record_Size_Limit(const uint16_t limit);
489
490 Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from);
491
492 uint16_t limit() const { return m_limit; }
493
494 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
495
496 bool empty() const override { return m_limit == 0; }
497
498 private:
499 uint16_t m_limit;
500};
501
503
504#if defined(BOTAN_HAS_TLS_13)
505/**
506* Cookie from RFC 8446 4.2.2
507*/
508class BOTAN_UNSTABLE_API Cookie final : public Extension {
509 public:
510 static Extension_Code static_type() { return Extension_Code::Cookie; }
511
512 Extension_Code type() const override { return static_type(); }
513
514 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
515
516 bool empty() const override { return m_cookie.empty(); }
517
518 const std::vector<uint8_t>& get_cookie() const { return m_cookie; }
519
520 explicit Cookie(const std::vector<uint8_t>& cookie);
521
522 explicit Cookie(TLS_Data_Reader& reader, uint16_t extension_size);
523
524 private:
525 std::vector<uint8_t> m_cookie;
526};
527
528/**
529* Pre-Shared Key Exchange Modes from RFC 8446 4.2.9
530*/
531class BOTAN_UNSTABLE_API PSK_Key_Exchange_Modes final : public Extension {
532 public:
533 static Extension_Code static_type() { return Extension_Code::PskKeyExchangeModes; }
534
535 Extension_Code type() const override { return static_type(); }
536
537 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
538
539 bool empty() const override { return m_modes.empty(); }
540
541 const std::vector<PSK_Key_Exchange_Mode>& modes() const { return m_modes; }
542
543 explicit PSK_Key_Exchange_Modes(std::vector<PSK_Key_Exchange_Mode> modes) : m_modes(std::move(modes)) {}
544
545 explicit PSK_Key_Exchange_Modes(TLS_Data_Reader& reader, uint16_t extension_size);
546
547 private:
548 std::vector<PSK_Key_Exchange_Mode> m_modes;
549};
550
551/**
552 * Certificate Authorities Extension from RFC 8446 4.2.4
553 */
554class BOTAN_UNSTABLE_API Certificate_Authorities final : public Extension {
555 public:
556 static Extension_Code static_type() { return Extension_Code::CertificateAuthorities; }
557
558 Extension_Code type() const override { return static_type(); }
559
560 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
561
562 bool empty() const override { return m_distinguished_names.empty(); }
563
564 const std::vector<X509_DN>& distinguished_names() const { return m_distinguished_names; }
565
566 Certificate_Authorities(TLS_Data_Reader& reader, uint16_t extension_size);
567 explicit Certificate_Authorities(std::vector<X509_DN> acceptable_DNs);
568
569 private:
570 std::vector<X509_DN> m_distinguished_names;
571};
572
573/**
574 * Pre-Shared Key extension from RFC 8446 4.2.11
575 */
576class BOTAN_UNSTABLE_API PSK final : public Extension {
577 public:
578 static Extension_Code static_type() { return Extension_Code::PresharedKey; }
579
580 Extension_Code type() const override { return static_type(); }
581
582 std::vector<uint8_t> serialize(Connection_Side side) const override;
583
584 /**
585 * Returns the cipher state representing the PSK selected by the server.
586 * Note that this destructs the list of offered PSKs and its cipher states
587 * and must therefore not be called more than once.
588 */
589 std::unique_ptr<Cipher_State> select_cipher_state(const PSK& server_psk, const Ciphersuite& cipher);
590
591 /**
592 * Selects one of the offered PSKs that is compatible with \p cipher.
593 * @retval PSK extension object that can be added to the Server Hello response
594 * @retval std::nullptr if no PSK offered by the client is convenient
595 */
596 std::unique_ptr<PSK> select_offered_psk(const Ciphersuite& cipher,
597 Session_Manager& session_mgr,
598 Callbacks& callbacks,
599 const Policy& policy);
600
601 /**
602 * Remove PSK identities from the list in \p m_psk that are not compatible
603 * with the passed in \p cipher suite.
604 * This is useful to react to Hello Retry Requests. See RFC 8446 4.1.4.
605 */
606 void filter(const Ciphersuite& cipher);
607
608 /**
609 * Pulls the Session to resume from a PSK extension in Server Hello.
610 */
611 Session take_session_to_resume();
612
613 bool empty() const override;
614
615 PSK(TLS_Data_Reader& reader, uint16_t extension_size, Handshake_Type message_type);
616
617 /**
618 * Creates a PSK extension with a TLS 1.3 session object containing a
619 * master_secret. Note that it will extract that secret from the session,
620 * and won't create a copy of it.
621 *
622 * @param session_to_resume the session to be resumed; note that the
623 * master secret will be taken away from the
624 * session object.
625 * @param callbacks the application's callbacks
626 */
627 PSK(Session_with_Handle& session_to_resume, Callbacks& callbacks);
628
629 ~PSK();
630
631 void calculate_binders(const Transcript_Hash_State& truncated_transcript_hash);
632 bool validate_binder(const PSK& server_psk, const std::vector<uint8_t>& binder) const;
633
634 // TODO: Implement pure PSK negotiation that is not used for session
635 // resumption.
636
637 private:
638 /**
639 * Creates a PSK extension that specifies the server's selection of an
640 * offered client PSK. The @p session_to_resume is kept internally
641 * and used later for the initialization of the Cipher_State object.
642 *
643 * Note: This constructor is called internally in PSK::select_offered_psk().
644 */
645 PSK(Session session_to_resume, const uint16_t psk_index);
646
647 private:
648 class PSK_Internal;
649 std::unique_ptr<PSK_Internal> m_impl;
650};
651
652/**
653* Key_Share from RFC 8446 4.2.8
654*/
655class BOTAN_UNSTABLE_API Key_Share final : public Extension {
656 public:
657 static Extension_Code static_type() { return Extension_Code::KeyShare; }
658
659 Extension_Code type() const override { return static_type(); }
660
661 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
662
663 bool empty() const override;
664
665 /**
666 * Creates a Key_Share extension meant for the Server Hello that
667 * performs a key encapsulation with the selected public key from
668 * the client.
669 *
670 * @note This will retain the shared secret in the Key_Share extension
671 * until it is retrieved via take_shared_secret().
672 */
673 static std::unique_ptr<Key_Share> create_as_encapsulation(Group_Params selected_group,
674 const Key_Share& client_keyshare,
675 const Policy& policy,
676 Callbacks& cb,
677 RandomNumberGenerator& rng);
678
679 /**
680 * Decapsulate the shared secret with the peer's key share. This method
681 * can be called on a ClientHello's Key_Share with a ServerHello's
682 * Key_Share.
683 *
684 * @note After the decapsulation the client's private key is destroyed.
685 * Multiple calls will result in an exception.
686 */
687 secure_vector<uint8_t> decapsulate(const Key_Share& server_keyshare,
688 const Policy& policy,
689 Callbacks& cb,
690 RandomNumberGenerator& rng);
691
692 /**
693 * Update a ClientHello's Key_Share to comply with a HelloRetryRequest.
694 *
695 * This will create new Key_Share_Entries and should only be called on a ClientHello Key_Share with a HelloRetryRequest Key_Share.
696 */
697 void retry_offer(const Key_Share& retry_request_keyshare,
698 const std::vector<Named_Group>& supported_groups,
699 Callbacks& cb,
700 RandomNumberGenerator& rng);
701
702 /**
703 * @return key exchange groups the peer offered key share entries for
704 */
705 std::vector<Named_Group> offered_groups() const;
706
707 /**
708 * @return key exchange group that was selected by a Hello Retry Request
709 */
710 Named_Group selected_group() const;
711
712 /**
713 * @returns the shared secret that was obtained by constructing this
714 * Key_Share object with the peer's.
715 *
716 * @note the shared secret value is std:move'd out. Multiple calls will
717 * result in an exception.
718 */
719 secure_vector<uint8_t> take_shared_secret();
720
721 Key_Share(TLS_Data_Reader& reader, uint16_t extension_size, Handshake_Type message_type);
722
723 // constructor used for ClientHello msg
724 Key_Share(const Policy& policy, Callbacks& cb, RandomNumberGenerator& rng);
725
726 // constructor used for HelloRetryRequest msg
727 explicit Key_Share(Named_Group selected_group);
728
729 // destructor implemented in .cpp to hide Key_Share_Impl
730 ~Key_Share();
731
732 private:
733 // constructor used for ServerHello
734 // (called via create_as_encapsulation())
735 Key_Share(Group_Params selected_group,
736 const Key_Share& client_keyshare,
737 const Policy& policy,
738 Callbacks& cb,
739 RandomNumberGenerator& rng);
740
741 private:
742 class Key_Share_Impl;
743 std::unique_ptr<Key_Share_Impl> m_impl;
744};
745
746/**
747 * Indicates usage or support of early data as described in RFC 8446 4.2.10.
748 */
749class BOTAN_UNSTABLE_API EarlyDataIndication final : public Extension {
750 public:
751 static Extension_Code static_type() { return Extension_Code::EarlyData; }
752
753 Extension_Code type() const override { return static_type(); }
754
755 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
756
757 bool empty() const override;
758
759 std::optional<uint32_t> max_early_data_size() const { return m_max_early_data_size; }
760
761 EarlyDataIndication(TLS_Data_Reader& reader, uint16_t extension_size, Handshake_Type message_type);
762
763 /**
764 * The max_early_data_size is exclusively provided by servers when using
765 * this extension in the NewSessionTicket message! Otherwise it stays
766 * std::nullopt and results in an empty extension. (RFC 8446 4.2.10).
767 */
768 EarlyDataIndication(std::optional<uint32_t> max_early_data_size = std::nullopt) :
769 m_max_early_data_size(std::move(max_early_data_size)) {}
770
771 private:
772 std::optional<uint32_t> m_max_early_data_size;
773};
774
775#endif
776
777/**
778* Unknown extensions are deserialized as this type
779*/
781 public:
782 Unknown_Extension(Extension_Code type, TLS_Data_Reader& reader, uint16_t extension_size);
783
784 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
785
786 const std::vector<uint8_t>& value() { return m_value; }
787
788 bool empty() const override { return false; }
789
790 Extension_Code type() const override { return m_type; }
791
792 bool is_implemented() const override { return false; }
793
794 private:
795 Extension_Code m_type;
796 std::vector<uint8_t> m_value;
797};
798
799/**
800* Represents a block of extensions in a hello message
801*/
803 public:
804 std::set<Extension_Code> extension_types() const;
805
806 const std::vector<std::unique_ptr<Extension>>& all() const { return m_extensions; }
807
808 template <typename T>
809 T* get() const {
810 return dynamic_cast<T*>(get(T::static_type()));
811 }
812
813 template <typename T>
814 bool has() const {
815 return get<T>() != nullptr;
816 }
817
818 bool has(Extension_Code type) const { return get(type) != nullptr; }
819
820 size_t size() const { return m_extensions.size(); }
821
822 void add(std::unique_ptr<Extension> extn);
823
824 void add(Extension* extn) { add(std::unique_ptr<Extension>(extn)); }
825
827 const auto i = std::find_if(
828 m_extensions.cbegin(), m_extensions.cend(), [type](const auto& ext) { return ext->type() == type; });
829
830 return (i != m_extensions.end()) ? i->get() : nullptr;
831 }
832
833 std::vector<uint8_t> serialize(Connection_Side whoami) const;
834
835 void deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type);
836
837 /**
838 * @param allowed_extensions extension types that are allowed
839 * @param allow_unknown_extensions if true, ignores unrecognized extensions
840 * @returns true if this contains any extensions that are not contained in @p allowed_extensions.
841 */
842 bool contains_other_than(const std::set<Extension_Code>& allowed_extensions,
843 const bool allow_unknown_extensions = false) const;
844
845 /**
846 * @param allowed_extensions extension types that are allowed
847 * @returns true if this contains any extensions implemented by Botan that
848 * are not contained in @p allowed_extensions.
849 */
850 bool contains_implemented_extensions_other_than(const std::set<Extension_Code>& allowed_extensions) const {
851 return contains_other_than(allowed_extensions, true);
852 }
853
854 /**
855 * Take the extension with the given type out of the extensions list.
856 * Returns a nullptr if the extension didn't exist.
857 */
858 template <typename T>
859 decltype(auto) take() {
860 std::unique_ptr<T> out_ptr;
861
862 auto ext = take(T::static_type());
863 if(ext != nullptr) {
864 out_ptr.reset(dynamic_cast<T*>(ext.get()));
865 BOTAN_ASSERT_NOMSG(out_ptr != nullptr);
866 ext.release();
867 }
868
869 return out_ptr;
870 }
871
872 /**
873 * Take the extension with the given type out of the extensions list.
874 * Returns a nullptr if the extension didn't exist.
875 */
876 std::unique_ptr<Extension> take(Extension_Code type);
877
878 /**
879 * Remove an extension from this extensions object, if it exists.
880 * Returns true if the extension existed (and thus is now removed),
881 * otherwise false (the extension wasn't set in the first place).
882 *
883 * Note: not used internally, might be used in Callbacks::tls_modify_extensions()
884 */
885 bool remove_extension(Extension_Code type) { return take(type) != nullptr; }
886
887 Extensions() = default;
888 Extensions(Extensions&&) = default;
890
892 deserialize(reader, side, message_type);
893 }
894
895 private:
896 Extensions(const Extensions&) = delete;
897 Extensions& operator=(const Extensions&) = delete;
898
899 std::vector<std::unique_ptr<Extension>> m_extensions;
900};
901
902} // namespace TLS
903
904} // namespace Botan
905
906#endif
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:59
Application_Layer_Protocol_Notification(std::string_view protocol)
const std::vector< std::string > & protocols() const
Application_Layer_Protocol_Notification(const std::vector< std::string > &protocols)
const std::vector< uint8_t > & get_request_extensions() const
const std::vector< uint8_t > & get_responder_id_list() const
Extension_Code type() const override
Extension_Code type() const override
static Extension_Code static_type()
bool empty() const override
static Extension_Code static_type()
Extension_Code type() const override
virtual std::vector< uint8_t > serialize(Connection_Side whoami) const =0
virtual bool is_implemented() const
virtual Extension_Code type() const =0
virtual bool empty() const =0
virtual ~Extension()=default
Extensions(Extensions &&)=default
void add(Extension *extn)
Extension * get(Extension_Code type) const
bool contains_implemented_extensions_other_than(const std::set< Extension_Code > &allowed_extensions) const
Extensions(TLS_Data_Reader &reader, Connection_Side side, Handshake_Type message_type)
decltype(auto) take()
Extensions & operator=(Extensions &&)=default
bool remove_extension(Extension_Code type)
bool has(Extension_Code type) const
const std::vector< std::unique_ptr< Extension > > & all() const
Extension_Code type() const override
static Extension_Code static_type()
bool empty() const override
static Extension_Code static_type()
Renegotiation_Extension(const std::vector< uint8_t > &bits)
Extension_Code type() const override
const std::vector< uint8_t > & renegotiation_info() const
Extension_Code type() const override
SRTP_Protection_Profiles(const std::vector< uint16_t > &pp)
const std::vector< uint16_t > & profiles() const
static Extension_Code static_type()
static Extension_Code static_type()
Extension_Code type() const override
Server_Name_Indicator(std::string_view host_name)
static Extension_Code static_type()
Extension_Code type() const override
Session_Ticket_Extension(Session_Ticket session_ticket)
std::vector< uint8_t > serialize(Connection_Side) const override
const Session_Ticket & contents() const
static Extension_Code static_type()
Signature_Algorithms_Cert(std::vector< Signature_Scheme > schemes)
const std::vector< Signature_Scheme > & supported_schemes() const
Extension_Code type() const override
Signature_Algorithms(std::vector< Signature_Scheme > schemes)
const std::vector< Signature_Scheme > & supported_schemes() const
static Extension_Code static_type()
Extension_Code type() const override
bool empty() const override
Extension_Code type() const override
static Extension_Code static_type()
Supported_Point_Formats(bool prefer_compressed)
Extension_Code type() const override
static Extension_Code static_type()
static Extension_Code static_type()
const std::vector< Protocol_Version > & versions() const
bool empty() const override
Supported_Versions(Protocol_Version version)
Extension_Code type() const override
bool empty() const override
const std::vector< uint8_t > & value()
bool is_implemented() const override
Extension_Code type() const override
int(* final)(unsigned char *, CTX *)
#define BOTAN_UNSTABLE_API
Definition: compiler.h:33
FE_25519 T
Definition: ge.cpp:34
Group_Params Named_Group
Definition: alg_id.cpp:13
Definition: bigint.h:1030