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