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