Botan 3.9.0
Crypto and TLS for C&
x509_ext.h
Go to the documentation of this file.
1/*
2* X.509 Certificate Extensions
3* (C) 1999-2007,2012 Jack Lloyd
4* (C) 2024 Anton Einax, Dominik Schricker
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#ifndef BOTAN_X509_EXTENSIONS_H_
10#define BOTAN_X509_EXTENSIONS_H_
11
12#include <botan/pkix_types.h>
13
14#include <array>
15#include <memory>
16#include <optional>
17#include <set>
18#include <string>
19#include <string_view>
20#include <vector>
21
22namespace Botan {
23
25
26namespace Cert_Extension {
27
28static const size_t NO_CERT_PATH_LIMIT = 0xFFFFFFF0;
29
30/**
31* Basic Constraints Extension
32*/
34 public:
35 std::unique_ptr<Certificate_Extension> copy() const override {
36 return std::make_unique<Basic_Constraints>(m_is_ca, m_path_length_constraint);
37 }
38
39 BOTAN_FUTURE_EXPLICIT Basic_Constraints(bool is_ca = false, size_t path_length_constraint = 0);
40
41 Basic_Constraints(bool is_ca, std::optional<size_t> path_length_constraint);
42
43 BOTAN_DEPRECATED("Use is_ca") bool get_is_ca() const { return m_is_ca; }
44
45 /**
46 * Note that this function returns NO_CERT_PATH_LIMIT if the value was not set
47 * in the extension.
48 */
49 BOTAN_DEPRECATED("Use path_length_constraint") size_t get_path_limit() const;
50
51 bool is_ca() const { return m_is_ca; }
52
53 std::optional<size_t> path_length_constraint() const { return m_path_length_constraint; }
54
55 static OID static_oid() { return OID({2, 5, 29, 19}); }
56
57 OID oid_of() const override { return static_oid(); }
58
59 private:
60 std::string oid_name() const override { return "X509v3.BasicConstraints"; }
61
62 std::vector<uint8_t> encode_inner() const override;
63 void decode_inner(const std::vector<uint8_t>& in) override;
64
65 bool m_is_ca;
66 std::optional<size_t> m_path_length_constraint;
67};
68
69/**
70* Key Usage Constraints Extension
71*/
73 public:
74 std::unique_ptr<Certificate_Extension> copy() const override {
75 return std::make_unique<Key_Usage>(m_constraints);
76 }
77
78 explicit Key_Usage(Key_Constraints c) : m_constraints(c) {}
79
80 explicit Key_Usage() : m_constraints(Key_Constraints::None) {}
81
82 Key_Constraints get_constraints() const { return m_constraints; }
83
84 static OID static_oid() { return OID({2, 5, 29, 15}); }
85
86 OID oid_of() const override { return static_oid(); }
87
88 private:
89 std::string oid_name() const override { return "X509v3.KeyUsage"; }
90
91 bool should_encode() const override { return !m_constraints.empty(); }
92
93 std::vector<uint8_t> encode_inner() const override;
94 void decode_inner(const std::vector<uint8_t>& in) override;
95
96 Key_Constraints m_constraints;
97};
98
99/**
100* Subject Key Identifier Extension
101*/
103 public:
104 Subject_Key_ID() = default;
105
106 explicit Subject_Key_ID(const std::vector<uint8_t>& k) : m_key_id(k) {}
107
108 Subject_Key_ID(const std::vector<uint8_t>& public_key, std::string_view hash_fn);
109
110 std::unique_ptr<Certificate_Extension> copy() const override {
111 return std::make_unique<Subject_Key_ID>(m_key_id);
112 }
113
114 const std::vector<uint8_t>& get_key_id() const { return m_key_id; }
115
116 static OID static_oid() { return OID({2, 5, 29, 14}); }
117
118 OID oid_of() const override { return static_oid(); }
119
120 private:
121 std::string oid_name() const override { return "X509v3.SubjectKeyIdentifier"; }
122
123 bool should_encode() const override { return (!m_key_id.empty()); }
124
125 std::vector<uint8_t> encode_inner() const override;
126 void decode_inner(const std::vector<uint8_t>& in) override;
127
128 std::vector<uint8_t> m_key_id;
129};
130
131/**
132* Authority Key Identifier Extension
133*/
135 public:
136 std::unique_ptr<Certificate_Extension> copy() const override {
137 return std::make_unique<Authority_Key_ID>(m_key_id);
138 }
139
140 Authority_Key_ID() = default;
141
142 explicit Authority_Key_ID(const std::vector<uint8_t>& k) : m_key_id(k) {}
143
144 const std::vector<uint8_t>& get_key_id() const { return m_key_id; }
145
146 static OID static_oid() { return OID({2, 5, 29, 35}); }
147
148 OID oid_of() const override { return static_oid(); }
149
150 private:
151 std::string oid_name() const override { return "X509v3.AuthorityKeyIdentifier"; }
152
153 bool should_encode() const override { return (!m_key_id.empty()); }
154
155 std::vector<uint8_t> encode_inner() const override;
156 void decode_inner(const std::vector<uint8_t>& in) override;
157
158 std::vector<uint8_t> m_key_id;
159};
160
161/**
162* Subject Alternative Name Extension
163*/
165 public:
166 const AlternativeName& get_alt_name() const { return m_alt_name; }
167
168 static OID static_oid() { return OID({2, 5, 29, 17}); }
169
170 OID oid_of() const override { return static_oid(); }
171
172 std::unique_ptr<Certificate_Extension> copy() const override {
173 return std::make_unique<Subject_Alternative_Name>(get_alt_name());
174 }
175
176 explicit Subject_Alternative_Name(const AlternativeName& name = AlternativeName()) : m_alt_name(name) {}
177
178 private:
179 std::string oid_name() const override { return "X509v3.SubjectAlternativeName"; }
180
181 bool should_encode() const override { return m_alt_name.has_items(); }
182
183 std::vector<uint8_t> encode_inner() const override;
184 void decode_inner(const std::vector<uint8_t>& in) override;
185
186 AlternativeName m_alt_name;
187};
188
189/**
190* Issuer Alternative Name Extension
191*/
193 public:
194 const AlternativeName& get_alt_name() const { return m_alt_name; }
195
196 static OID static_oid() { return OID({2, 5, 29, 18}); }
197
198 OID oid_of() const override { return static_oid(); }
199
200 std::unique_ptr<Certificate_Extension> copy() const override {
201 return std::make_unique<Issuer_Alternative_Name>(get_alt_name());
202 }
203
204 explicit Issuer_Alternative_Name(const AlternativeName& name = AlternativeName()) : m_alt_name(name) {}
205
206 private:
207 std::string oid_name() const override { return "X509v3.IssuerAlternativeName"; }
208
209 bool should_encode() const override { return m_alt_name.has_items(); }
210
211 std::vector<uint8_t> encode_inner() const override;
212 void decode_inner(const std::vector<uint8_t>& in) override;
213
214 AlternativeName m_alt_name;
215};
216
217/**
218* Extended Key Usage Extension
219*/
221 public:
222 std::unique_ptr<Certificate_Extension> copy() const override {
223 return std::make_unique<Extended_Key_Usage>(m_oids);
224 }
225
227
228 explicit Extended_Key_Usage(const std::vector<OID>& o) : m_oids(o) {}
229
230 const std::vector<OID>& object_identifiers() const { return m_oids; }
231
232 static OID static_oid() { return OID({2, 5, 29, 37}); }
233
234 OID oid_of() const override { return static_oid(); }
235
236 private:
237 std::string oid_name() const override { return "X509v3.ExtendedKeyUsage"; }
238
239 bool should_encode() const override { return (!m_oids.empty()); }
240
241 std::vector<uint8_t> encode_inner() const override;
242 void decode_inner(const std::vector<uint8_t>& in) override;
243
244 std::vector<OID> m_oids;
245};
246
247/**
248* Name Constraints
249*/
251 public:
252 std::unique_ptr<Certificate_Extension> copy() const override {
253 return std::make_unique<Name_Constraints>(m_name_constraints);
254 }
255
256 Name_Constraints() = default;
257
258 BOTAN_FUTURE_EXPLICIT Name_Constraints(const NameConstraints& nc) : m_name_constraints(nc) {}
259
260 void validate(const X509_Certificate& subject,
261 const X509_Certificate& issuer,
262 const std::vector<X509_Certificate>& cert_path,
263 std::vector<std::set<Certificate_Status_Code>>& cert_status,
264 size_t pos) override;
265
266 const NameConstraints& get_name_constraints() const { return m_name_constraints; }
267
268 static OID static_oid() { return OID({2, 5, 29, 30}); }
269
270 OID oid_of() const override { return static_oid(); }
271
272 private:
273 std::string oid_name() const override { return "X509v3.NameConstraints"; }
274
275 bool should_encode() const override { return true; }
276
277 std::vector<uint8_t> encode_inner() const override;
278 void decode_inner(const std::vector<uint8_t>& in) override;
279
280 NameConstraints m_name_constraints;
281};
282
283/**
284* Certificate Policies Extension
285*/
287 public:
288 std::unique_ptr<Certificate_Extension> copy() const override {
289 return std::make_unique<Certificate_Policies>(m_oids);
290 }
291
293
294 explicit Certificate_Policies(const std::vector<OID>& o) : m_oids(o) {}
295
296 const std::vector<OID>& get_policy_oids() const { return m_oids; }
297
298 static OID static_oid() { return OID({2, 5, 29, 32}); }
299
300 OID oid_of() const override { return static_oid(); }
301
302 void validate(const X509_Certificate& subject,
303 const X509_Certificate& issuer,
304 const std::vector<X509_Certificate>& cert_path,
305 std::vector<std::set<Certificate_Status_Code>>& cert_status,
306 size_t pos) override;
307
308 private:
309 std::string oid_name() const override { return "X509v3.CertificatePolicies"; }
310
311 bool should_encode() const override { return (!m_oids.empty()); }
312
313 std::vector<uint8_t> encode_inner() const override;
314 void decode_inner(const std::vector<uint8_t>& in) override;
315
316 std::vector<OID> m_oids;
317};
318
319/**
320* Authority Information Access Extension
321*/
323 public:
324 std::unique_ptr<Certificate_Extension> copy() const override {
325 return std::make_unique<Authority_Information_Access>(m_ocsp_responder, m_ca_issuers);
326 }
327
329
330 explicit Authority_Information_Access(std::string_view ocsp,
331 const std::vector<std::string>& ca_issuers = std::vector<std::string>()) :
332 m_ocsp_responder(ocsp), m_ca_issuers(ca_issuers) {}
333
334 std::string ocsp_responder() const { return m_ocsp_responder; }
335
336 static OID static_oid() { return OID({1, 3, 6, 1, 5, 5, 7, 1, 1}); }
337
338 OID oid_of() const override { return static_oid(); }
339
340 const std::vector<std::string>& ca_issuers() const { return m_ca_issuers; }
341
342 private:
343 std::string oid_name() const override { return "PKIX.AuthorityInformationAccess"; }
344
345 bool should_encode() const override { return (!m_ocsp_responder.empty() || !m_ca_issuers.empty()); }
346
347 std::vector<uint8_t> encode_inner() const override;
348 void decode_inner(const std::vector<uint8_t>& in) override;
349
350 std::string m_ocsp_responder;
351 std::vector<std::string> m_ca_issuers;
352};
353
354/**
355* CRL Number Extension
356*/
358 public:
359 std::unique_ptr<Certificate_Extension> copy() const override;
360
361 CRL_Number() : m_has_value(false), m_crl_number(0) {}
362
363 BOTAN_FUTURE_EXPLICIT CRL_Number(size_t n) : m_has_value(true), m_crl_number(n) {}
364
365 size_t get_crl_number() const;
366
367 static OID static_oid() { return OID({2, 5, 29, 20}); }
368
369 OID oid_of() const override { return static_oid(); }
370
371 private:
372 std::string oid_name() const override { return "X509v3.CRLNumber"; }
373
374 bool should_encode() const override { return m_has_value; }
375
376 std::vector<uint8_t> encode_inner() const override;
377 void decode_inner(const std::vector<uint8_t>& in) override;
378
379 bool m_has_value;
380 size_t m_crl_number;
381};
382
383/**
384* CRL Entry Reason Code Extension
385*/
387 public:
388 std::unique_ptr<Certificate_Extension> copy() const override {
389 return std::make_unique<CRL_ReasonCode>(m_reason);
390 }
391
392 explicit CRL_ReasonCode(CRL_Code r = CRL_Code::Unspecified) : m_reason(r) {}
393
394 CRL_Code get_reason() const { return m_reason; }
395
396 static OID static_oid() { return OID({2, 5, 29, 21}); }
397
398 OID oid_of() const override { return static_oid(); }
399
400 private:
401 std::string oid_name() const override { return "X509v3.ReasonCode"; }
402
403 bool should_encode() const override { return (m_reason != CRL_Code::Unspecified); }
404
405 std::vector<uint8_t> encode_inner() const override;
406 void decode_inner(const std::vector<uint8_t>& in) override;
407
408 CRL_Code m_reason;
409};
410
411/**
412* CRL Distribution Points Extension
413* todo enforce restrictions from RFC 5280 4.2.1.13
414*/
416 public:
418 public:
419 void encode_into(DER_Encoder& to) const override;
420 void decode_from(BER_Decoder& from) override;
421
422 explicit Distribution_Point(const AlternativeName& name = AlternativeName()) : m_point(name) {}
423
424 const AlternativeName& point() const { return m_point; }
425
426 private:
427 AlternativeName m_point;
428 };
429
430 std::unique_ptr<Certificate_Extension> copy() const override {
431 return std::make_unique<CRL_Distribution_Points>(m_distribution_points);
432 }
433
435
436 explicit CRL_Distribution_Points(const std::vector<Distribution_Point>& points) : m_distribution_points(points) {}
437
438 const std::vector<Distribution_Point>& distribution_points() const { return m_distribution_points; }
439
440 const std::vector<std::string>& crl_distribution_urls() const { return m_crl_distribution_urls; }
441
442 static OID static_oid() { return OID({2, 5, 29, 31}); }
443
444 OID oid_of() const override { return static_oid(); }
445
446 private:
447 std::string oid_name() const override { return "X509v3.CRLDistributionPoints"; }
448
449 bool should_encode() const override { return !m_distribution_points.empty(); }
450
451 std::vector<uint8_t> encode_inner() const override;
452 void decode_inner(const std::vector<uint8_t>& in) override;
453
454 std::vector<Distribution_Point> m_distribution_points;
455 std::vector<std::string> m_crl_distribution_urls;
456};
457
458/**
459* CRL Issuing Distribution Point Extension
460* todo enforce restrictions from RFC 5280 5.2.5
461*/
463 public:
465
467 m_distribution_point(distribution_point) {}
468
469 std::unique_ptr<Certificate_Extension> copy() const override {
470 return std::make_unique<CRL_Issuing_Distribution_Point>(m_distribution_point);
471 }
472
473 const AlternativeName& get_point() const { return m_distribution_point.point(); }
474
475 static OID static_oid() { return OID({2, 5, 29, 28}); }
476
477 OID oid_of() const override { return static_oid(); }
478
479 private:
480 std::string oid_name() const override { return "X509v3.CRLIssuingDistributionPoint"; }
481
482 bool should_encode() const override { return true; }
483
484 std::vector<uint8_t> encode_inner() const override;
485 void decode_inner(const std::vector<uint8_t>& in) override;
486
487 CRL_Distribution_Points::Distribution_Point m_distribution_point;
488};
489
490/**
491* OCSP NoCheck Extension
492*
493* RFC6960 4.2.2.2.1
494* A CA may specify that an OCSP client can trust a responder for the
495* lifetime of the responder's certificate. The CA does so by
496* including the extension id-pkix-ocsp-nocheck.
497*
498* In other words: OCSP responder certificates with this extension do not need
499* to be validated against some revocation info.
500*/
502 public:
503 OCSP_NoCheck() = default;
504
505 std::unique_ptr<Certificate_Extension> copy() const override { return std::make_unique<OCSP_NoCheck>(); }
506
507 static OID static_oid() { return OID({1, 3, 6, 1, 5, 5, 7, 48, 1, 5}); }
508
509 OID oid_of() const override { return static_oid(); }
510
511 private:
512 std::string oid_name() const override { return "PKIX.OCSP.NoCheck"; }
513
514 bool should_encode() const override { return true; }
515
516 std::vector<uint8_t> encode_inner() const override { return {}; }
517
518 void decode_inner(const std::vector<uint8_t>& in) override;
519};
520
521/**
522* TNAuthList extension
523*
524* RFC8226 Secure Telephone Identity Credentials
525* https://www.rfc-editor.org/rfc/rfc8226#section-9
526*/
528 public:
529 class BOTAN_PUBLIC_API(3, 5) Entry final : public ASN1_Object {
530 public:
531 /* TNEntry choice values
532 * see: https://datatracker.ietf.org/doc/html/rfc8226#section-9 */
534
536 ASN1_String start; //TelephoneNumber (IA5String)
537 size_t count{}; //2..MAX
538 };
539
540 using RangeContainer = std::vector<TelephoneNumberRangeData>;
541 using DataContainer = std::variant<ASN1_String, RangeContainer>;
542
543 void encode_into(DER_Encoder& to) const override;
544 void decode_from(class BER_Decoder& from) override;
545
546 Type type() const { return m_type; }
547
548 const std::string& service_provider_code() const;
549
550 const RangeContainer& telephone_number_range() const;
551
552 const std::string& telephone_number() const;
553
554 private:
555 Type m_type{};
556 DataContainer m_data;
557 };
558
559 TNAuthList() = default;
560
561 std::unique_ptr<Certificate_Extension> copy() const override { return std::make_unique<TNAuthList>(*this); }
562
563 static OID static_oid() { return OID({1, 3, 6, 1, 5, 5, 7, 1, 26}); }
564
565 OID oid_of() const override { return static_oid(); }
566
567 const std::vector<Entry>& entries() const { return m_tn_entries; }
568
569 private:
570 std::string oid_name() const override { return "PKIX.TNAuthList"; }
571
572 bool should_encode() const override { return true; }
573
574 std::vector<uint8_t> encode_inner() const override;
575 void decode_inner(const std::vector<uint8_t>& in) override;
576
577 std::vector<Entry> m_tn_entries;
578};
579
580/**
581 * IP Address Blocks Extension
582 *
583 * RFC 3779 X.509 Extensions for IP Addr
584 *
585*/
587 public:
588 enum class BOTAN_PUBLIC_API(3, 9) Version : uint8_t {
589 IPv4 = 4,
590 IPv6 = 16,
591 };
592
593 template <Version V>
594 class BOTAN_PUBLIC_API(3, 9) IPAddress final {
595 static constexpr size_t Length = static_cast<size_t>(V);
596
597 public:
598 explicit IPAddress(std::span<const uint8_t> v);
599
600 std::array<uint8_t, Length> value() const { return m_value; }
601
602 private:
603 friend class IPAddressBlocks;
604 IPAddress() = default;
605
606 void next() {
607 for(auto it = m_value.rbegin(); it != m_value.rend(); it++) {
608 // we increment the current octet
609 (*it)++;
610 // if it did not wrap around we are done, else look at the next octet
611 if(*it != 0) {
612 break;
613 }
614 }
615 }
616
617 friend IPAddress<V> operator+(IPAddress<V> lhs, size_t rhs) {
618 // we only really need to be able to compute +1, so this is fine
619 for(size_t i = 0; i < rhs; i++) {
620 lhs.next();
621 }
622 return IPAddress<V>(lhs);
623 }
624
625 friend std::strong_ordering operator<=>(const IPAddress<V> lhs, const IPAddress<V>& rhs) {
626 for(size_t i = 0; i < Length; i++) {
627 if(lhs.value()[i] < rhs.value()[i]) {
628 return std::strong_ordering::less;
629 } else if(lhs.value()[i] > rhs.value()[i]) {
630 return std::strong_ordering::greater;
631 }
632 }
633 return std::strong_ordering::equal;
634 }
635
636 friend bool operator==(const IPAddress<V>& lhs, const IPAddress<V>& rhs) {
637 return lhs.value() == rhs.value();
638 }
639
640 std::array<uint8_t, Length> m_value;
641 };
642
643 template <Version V>
644 class BOTAN_PUBLIC_API(3, 9) IPAddressOrRange final : public ASN1_Object {
645 public:
646 void encode_into(DER_Encoder& to) const override;
647 void decode_from(BER_Decoder& from) override;
648
649 IPAddressOrRange() = default;
650
651 explicit IPAddressOrRange(const IPAddress<V>& addr) : m_min(addr), m_max(addr) {}
652
653 IPAddressOrRange(const IPAddress<V>& min, const IPAddress<V>& max) : m_min(min), m_max(max) {
654 if(max < min) {
655 throw Decoding_Error("IP address ranges must be sorted");
656 }
657 }
658
659 IPAddress<V> min() const { return m_min; }
660
661 IPAddress<V> max() const { return m_max; }
662
663 private:
664 IPAddress<V> m_min{};
665 IPAddress<V> m_max{};
666
667 IPAddress<V> decode_single_address(std::vector<uint8_t> decoded, bool min);
668 };
669
670 template <Version V>
671 class BOTAN_PUBLIC_API(3, 9) IPAddressChoice final : public ASN1_Object {
672 public:
673 void encode_into(DER_Encoder& to) const override;
674 void decode_from(BER_Decoder& from) override;
675
676 const std::optional<std::vector<IPAddressOrRange<V>>>& ranges() const { return m_ip_addr_ranges; }
677
678 IPAddressChoice() = default;
679
680 explicit IPAddressChoice(std::optional<std::span<const IPAddressOrRange<V>>> ranges);
681
682 private:
683 std::optional<std::vector<IPAddressOrRange<V>>> m_ip_addr_ranges;
684 };
685
686 class BOTAN_PUBLIC_API(3, 9) IPAddressFamily final : public ASN1_Object {
687 public:
688 typedef std::variant<IPAddressChoice<Version::IPv4>, IPAddressChoice<Version::IPv6>> AddrChoice;
689
690 void encode_into(DER_Encoder& to) const override;
691 void decode_from(BER_Decoder& from) override;
692
693 IPAddressFamily() = default;
694
695 explicit IPAddressFamily(const AddrChoice& choice, std::optional<uint8_t> safi = std::nullopt) :
696 m_safi(safi), m_ip_addr_choice(choice) {
697 if(std::holds_alternative<IPAddressChoice<Version::IPv4>>(choice)) {
698 m_afi = 1;
699 } else {
700 m_afi = 2;
701 }
702 }
703
704 uint16_t afi() const { return m_afi; }
705
706 std::optional<uint8_t> safi() const { return m_safi; }
707
708 const AddrChoice& addr_choice() const { return m_ip_addr_choice; }
709
710 private:
711 uint16_t m_afi = 1;
712 std::optional<uint8_t> m_safi;
713 AddrChoice m_ip_addr_choice;
714 };
715
716 IPAddressBlocks() = default;
717
718 explicit IPAddressBlocks(const std::vector<IPAddressFamily>& blocks) : m_ip_addr_blocks(blocks) {
719 this->sort_and_merge();
720 }
721
722 std::unique_ptr<Certificate_Extension> copy() const override { return std::make_unique<IPAddressBlocks>(*this); }
723
724 static OID static_oid() { return OID({1, 3, 6, 1, 5, 5, 7, 1, 7}); }
725
726 OID oid_of() const override { return static_oid(); }
727
728 void validate(const X509_Certificate& subject,
729 const X509_Certificate& issuer,
730 const std::vector<X509_Certificate>& cert_path,
731 std::vector<std::set<Certificate_Status_Code>>& cert_status,
732 size_t pos) override;
733
734 /// Add a single IP address to this extension (for the specified SAFI, if any)
735 template <Version V>
736 void add_address(const std::array<uint8_t, static_cast<size_t>(V)>& address,
737 std::optional<uint8_t> safi = std::nullopt) {
738 add_address<V>(address, address, safi);
739 }
740
741 /// Add an IP address range to this extension (for the specified SAFI, if any)
742 template <Version V>
743 void add_address(const std::array<uint8_t, static_cast<std::size_t>(V)>& min,
744 const std::array<uint8_t, static_cast<std::size_t>(V)>& max,
745 std::optional<uint8_t> safi = std::nullopt) {
746 std::vector<IPAddressOrRange<V>> addresses = {IPAddressOrRange<V>(IPAddress<V>(min), IPAddress<V>(max))};
747 m_ip_addr_blocks.push_back(IPAddressFamily(IPAddressChoice<V>(addresses), safi));
748 sort_and_merge();
749 }
750
751 /// Make the extension contain no allowed IP addresses for the specified IP version (and SAFI, if any)
752 template <Version V>
753 void restrict(std::optional<uint8_t> safi = std::nullopt) {
754 std::vector<IPAddressOrRange<V>> addresses = {};
755 m_ip_addr_blocks.push_back(IPAddressFamily(IPAddressChoice<V>(addresses), safi));
756 sort_and_merge();
757 }
758
759 /// Mark the specified IP version as 'inherit' (for the specified SAFI, if any)
760 template <Version V>
761 void inherit(std::optional<uint8_t> safi = std::nullopt) {
762 m_ip_addr_blocks.push_back(IPAddressFamily(IPAddressChoice<V>(), safi));
763 sort_and_merge();
764 }
765
766 const std::vector<IPAddressFamily>& addr_blocks() const { return m_ip_addr_blocks; }
767
768 private:
769 std::string oid_name() const override { return "PKIX.IpAddrBlocks"; }
770
771 bool should_encode() const override { return true; }
772
773 std::vector<uint8_t> encode_inner() const override;
774 void decode_inner(const std::vector<uint8_t>& in) override;
775
776 std::vector<IPAddressFamily> m_ip_addr_blocks;
777
778 void sort_and_merge();
779 template <Version V>
780 IPAddressFamily merge(std::vector<IPAddressFamily>& blocks);
781};
782
783/**
784 * AS Blocks Extension
785 *
786 * RFC 3779 X.509 Extensions for AS ID
787 *
788*/
790 public:
791 typedef uint32_t asnum_t;
792
793 class BOTAN_PUBLIC_API(3, 9) ASIdOrRange final : public ASN1_Object {
794 public:
795 void encode_into(DER_Encoder& to) const override;
796 void decode_from(BER_Decoder& from) override;
797
798 asnum_t min() const { return m_min; }
799
800 asnum_t max() const { return m_max; }
801
802 ASIdOrRange() = default;
803
804 explicit ASIdOrRange(asnum_t id) : m_min(id), m_max(id) {}
805
806 ASIdOrRange(asnum_t min, asnum_t max) : m_min(min), m_max(max) {
807 if(max < min) {
808 throw Decoding_Error("AS range numbers must be sorted");
809 }
810 }
811
812 private:
813 asnum_t m_min = 0;
814 asnum_t m_max = 0;
815 };
816
818 public:
819 void encode_into(DER_Encoder& to) const override;
820 void decode_from(BER_Decoder& from) override;
821
823
824 explicit ASIdentifierChoice(const std::optional<std::vector<ASIdOrRange>>& ranges);
825
826 const std::optional<std::vector<ASIdOrRange>>& ranges() const { return m_as_ranges; }
827
828 private:
829 std::optional<std::vector<ASIdOrRange>> m_as_ranges;
830 };
831
832 class BOTAN_PUBLIC_API(3, 9) ASIdentifiers final : public ASN1_Object {
833 public:
834 void encode_into(DER_Encoder& to) const override;
835 void decode_from(BER_Decoder& from) override;
836
837 explicit ASIdentifiers(const std::optional<ASIdentifierChoice>& asnum,
838 const std::optional<ASIdentifierChoice>& rdi) :
839 m_asnum(asnum), m_rdi(rdi) {
840 if(!m_asnum.has_value() && !m_rdi.has_value()) {
841 throw Decoding_Error("One of asnum, rdi must be present");
842 }
843 }
844
845 const std::optional<ASIdentifierChoice>& asnum() const { return m_asnum; }
846
847 const std::optional<ASIdentifierChoice>& rdi() const { return m_rdi; }
848
849 private:
850 friend class ASBlocks;
851 ASIdentifiers() = default;
852
853 std::optional<ASIdentifierChoice> m_asnum;
854 std::optional<ASIdentifierChoice> m_rdi;
855 };
856
857 ASBlocks() = default;
858
859 explicit ASBlocks(const ASIdentifiers& as_idents) : m_as_identifiers(as_idents) {}
860
861 std::unique_ptr<Certificate_Extension> copy() const override { return std::make_unique<ASBlocks>(*this); }
862
863 static OID static_oid() { return OID({1, 3, 6, 1, 5, 5, 7, 1, 8}); }
864
865 OID oid_of() const override { return static_oid(); }
866
867 void validate(const X509_Certificate& subject,
868 const X509_Certificate& issuer,
869 const std::vector<X509_Certificate>& cert_path,
870 std::vector<std::set<Certificate_Status_Code>>& cert_status,
871 size_t pos) override;
872
873 /// Add a single asnum to this extension
874 void add_asnum(asnum_t asnum) { add_asnum(asnum, asnum); }
875
876 /// Add an asnum range to this extension
877 void add_asnum(asnum_t min, asnum_t max) {
878 m_as_identifiers = ASIdentifiers(add_new(m_as_identifiers.asnum(), min, max), m_as_identifiers.rdi());
879 }
880
881 /// Make the extension contain no allowed asnum's
883 std::vector<ASIdOrRange> empty;
884 m_as_identifiers = ASIdentifiers(ASIdentifierChoice(empty), m_as_identifiers.rdi());
885 }
886
887 /// Mark the asnum entry as 'inherit'
888 void inherit_asnum() { m_as_identifiers = ASIdentifiers(ASIdentifierChoice(), m_as_identifiers.rdi()); }
889
890 /// Add a single rdi to this extension
891 void add_rdi(asnum_t rdi) { add_rdi(rdi, rdi); }
892
893 /// Add an rdi range to this extension
894 void add_rdi(asnum_t min, asnum_t max) {
895 m_as_identifiers = ASIdentifiers(m_as_identifiers.asnum(), add_new(m_as_identifiers.rdi(), min, max));
896 }
897
898 /// Make the extension contain no allowed rdi's
900 std::vector<ASIdOrRange> empty;
901 m_as_identifiers = ASIdentifiers(m_as_identifiers.asnum(), ASIdentifierChoice(empty));
902 }
903
904 /// Mark the rdi entry as 'inherit'
905 void inherit_rdi() { m_as_identifiers = ASIdentifiers(m_as_identifiers.asnum(), ASIdentifierChoice()); }
906
907 const ASIdentifiers& as_identifiers() const { return m_as_identifiers; }
908
909 private:
910 ASIdentifiers m_as_identifiers;
911
912 std::string oid_name() const override { return "PKIX.AutonomousSysIds"; }
913
914 bool should_encode() const override { return true; }
915
916 static ASIdentifierChoice add_new(const std::optional<ASIdentifierChoice>& old, asnum_t min, asnum_t max);
917
918 std::vector<uint8_t> encode_inner() const override;
919 void decode_inner(const std::vector<uint8_t>& in) override;
920};
921
922/**
923* An unknown X.509 extension
924* Will add a failure to the path validation result, if critical
925*/
927 public:
928 Unknown_Extension(const OID& oid, bool critical) : m_oid(oid), m_critical(critical) {}
929
930 std::unique_ptr<Certificate_Extension> copy() const override {
931 return std::make_unique<Unknown_Extension>(m_oid, m_critical);
932 }
933
934 /**
935 * Return the OID of this unknown extension
936 */
937 OID oid_of() const override { return m_oid; }
938
939 //static_oid not defined for Unknown_Extension
940
941 /**
942 * Return the extension contents
943 */
944 const std::vector<uint8_t>& extension_contents() const { return m_bytes; }
945
946 /**
947 * Return if this extension was marked critical
948 */
949 bool is_critical_extension() const { return m_critical; }
950
951 void validate(const X509_Certificate& /*subject*/,
952 const X509_Certificate& /*issuer*/,
953 const std::vector<X509_Certificate>& /*cert_path*/,
954 std::vector<std::set<Certificate_Status_Code>>& cert_status,
955 size_t pos) override {
956 if(m_critical) {
957 cert_status.at(pos).insert(Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION);
958 }
959 }
960
961 private:
962 std::string oid_name() const override { return ""; }
963
964 bool should_encode() const override { return true; }
965
966 std::vector<uint8_t> encode_inner() const override;
967 void decode_inner(const std::vector<uint8_t>& in) override;
968
969 OID m_oid;
970 bool m_critical;
971 std::vector<uint8_t> m_bytes;
972};
973
974} // namespace Cert_Extension
975
976} // namespace Botan
977
978#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
ASN1_Object()=default
void encode_into(DER_Encoder &to) const override
ASIdOrRange(asnum_t min, asnum_t max)
Definition x509_ext.h:806
void decode_from(BER_Decoder &from) override
void encode_into(DER_Encoder &to) const override
void decode_from(BER_Decoder &from) override
const std::optional< std::vector< ASIdOrRange > > & ranges() const
Definition x509_ext.h:826
const std::optional< ASIdentifierChoice > & asnum() const
Definition x509_ext.h:845
ASIdentifiers(const std::optional< ASIdentifierChoice > &asnum, const std::optional< ASIdentifierChoice > &rdi)
Definition x509_ext.h:837
const std::optional< ASIdentifierChoice > & rdi() const
Definition x509_ext.h:847
void encode_into(DER_Encoder &to) const override
void decode_from(BER_Decoder &from) override
void inherit_asnum()
Mark the asnum entry as 'inherit'.
Definition x509_ext.h:888
void restrict_rdi()
Make the extension contain no allowed rdi's.
Definition x509_ext.h:899
void inherit_rdi()
Mark the rdi entry as 'inherit'.
Definition x509_ext.h:905
void add_rdi(asnum_t min, asnum_t max)
Add an rdi range to this extension.
Definition x509_ext.h:894
const ASIdentifiers & as_identifiers() const
Definition x509_ext.h:907
ASBlocks(const ASIdentifiers &as_idents)
Definition x509_ext.h:859
OID oid_of() const override
Definition x509_ext.h:865
void restrict_asnum()
Make the extension contain no allowed asnum's.
Definition x509_ext.h:882
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:861
void add_asnum(asnum_t asnum)
Add a single asnum to this extension.
Definition x509_ext.h:874
void add_rdi(asnum_t rdi)
Add a single rdi to this extension.
Definition x509_ext.h:891
void add_asnum(asnum_t min, asnum_t max)
Add an asnum range to this extension.
Definition x509_ext.h:877
Authority_Information_Access(std::string_view ocsp, const std::vector< std::string > &ca_issuers=std::vector< std::string >())
Definition x509_ext.h:330
const std::vector< std::string > & ca_issuers() const
Definition x509_ext.h:340
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:324
Authority_Key_ID(const std::vector< uint8_t > &k)
Definition x509_ext.h:142
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:136
const std::vector< uint8_t > & get_key_id() const
Definition x509_ext.h:144
BOTAN_FUTURE_EXPLICIT Basic_Constraints(bool is_ca=false, size_t path_length_constraint=0)
Definition x509_ext.cpp:293
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:35
std::optional< size_t > path_length_constraint() const
Definition x509_ext.h:53
Distribution_Point(const AlternativeName &name=AlternativeName())
Definition x509_ext.h:422
CRL_Distribution_Points(const std::vector< Distribution_Point > &points)
Definition x509_ext.h:436
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:430
const std::vector< std::string > & crl_distribution_urls() const
Definition x509_ext.h:440
const std::vector< Distribution_Point > & distribution_points() const
Definition x509_ext.h:438
const AlternativeName & get_point() const
Definition x509_ext.h:473
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:469
CRL_Issuing_Distribution_Point(const CRL_Distribution_Points::Distribution_Point &distribution_point)
Definition x509_ext.h:466
OID oid_of() const override
Definition x509_ext.h:369
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.cpp:697
BOTAN_FUTURE_EXPLICIT CRL_Number(size_t n)
Definition x509_ext.h:363
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:388
CRL_ReasonCode(CRL_Code r=CRL_Code::Unspecified)
Definition x509_ext.h:392
const std::vector< OID > & get_policy_oids() const
Definition x509_ext.h:296
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:288
Certificate_Policies(const std::vector< OID > &o)
Definition x509_ext.h:294
const std::vector< OID > & object_identifiers() const
Definition x509_ext.h:230
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:222
Extended_Key_Usage(const std::vector< OID > &o)
Definition x509_ext.h:228
const std::optional< std::vector< IPAddressOrRange< V > > > & ranges() const
Definition x509_ext.h:676
void encode_into(DER_Encoder &to) const override
IPAddressChoice(std::optional< std::span< const IPAddressOrRange< V > > > ranges)
void encode_into(DER_Encoder &to) const override
Definition x509_ext.cpp:888
std::variant< IPAddressChoice< Version::IPv4 >, IPAddressChoice< Version::IPv6 > > AddrChoice
Definition x509_ext.h:688
IPAddressFamily(const AddrChoice &choice, std::optional< uint8_t > safi=std::nullopt)
Definition x509_ext.h:695
void encode_into(DER_Encoder &to) const override
IPAddressOrRange(const IPAddress< V > &min, const IPAddress< V > &max)
Definition x509_ext.h:653
friend bool operator==(const IPAddress< V > &lhs, const IPAddress< V > &rhs)
Definition x509_ext.h:636
friend IPAddress< V > operator+(IPAddress< V > lhs, size_t rhs)
Definition x509_ext.h:617
friend std::strong_ordering operator<=>(const IPAddress< V > lhs, const IPAddress< V > &rhs)
Definition x509_ext.h:625
std::array< uint8_t, Length > value() const
Definition x509_ext.h:600
void inherit(std::optional< uint8_t > safi=std::nullopt)
Mark the specified IP version as 'inherit' (for the specified SAFI, if any)
Definition x509_ext.h:761
void add_address(const std::array< uint8_t, static_cast< size_t >(V)> &address, std::optional< uint8_t > safi=std::nullopt)
Add a single IP address to this extension (for the specified SAFI, if any)
Definition x509_ext.h:736
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:722
void restrict(std::optional< uint8_t > safi=std::nullopt)
Make the extension contain no allowed IP addresses for the specified IP version (and SAFI,...
Definition x509_ext.h:753
void add_address(const std::array< uint8_t, static_cast< std::size_t >(V)> &min, const std::array< uint8_t, static_cast< std::size_t >(V)> &max, std::optional< uint8_t > safi=std::nullopt)
Add an IP address range to this extension (for the specified SAFI, if any)
Definition x509_ext.h:743
const std::vector< IPAddressFamily > & addr_blocks() const
Definition x509_ext.h:766
IPAddressBlocks(const std::vector< IPAddressFamily > &blocks)
Definition x509_ext.h:718
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:200
const AlternativeName & get_alt_name() const
Definition x509_ext.h:194
Issuer_Alternative_Name(const AlternativeName &name=AlternativeName())
Definition x509_ext.h:204
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:74
OID oid_of() const override
Definition x509_ext.h:86
Key_Usage(Key_Constraints c)
Definition x509_ext.h:78
Key_Constraints get_constraints() const
Definition x509_ext.h:82
BOTAN_FUTURE_EXPLICIT Name_Constraints(const NameConstraints &nc)
Definition x509_ext.h:258
const NameConstraints & get_name_constraints() const
Definition x509_ext.h:266
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:252
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:505
OID oid_of() const override
Definition x509_ext.h:509
const AlternativeName & get_alt_name() const
Definition x509_ext.h:166
Subject_Alternative_Name(const AlternativeName &name=AlternativeName())
Definition x509_ext.h:176
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:172
Subject_Key_ID(const std::vector< uint8_t > &k)
Definition x509_ext.h:106
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:110
const std::vector< uint8_t > & get_key_id() const
Definition x509_ext.h:114
std::vector< TelephoneNumberRangeData > RangeContainer
Definition x509_ext.h:540
void decode_from(class BER_Decoder &from) override
Definition x509_ext.cpp:803
void encode_into(DER_Encoder &to) const override
Definition x509_ext.cpp:799
std::variant< ASN1_String, RangeContainer > DataContainer
Definition x509_ext.h:541
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:561
OID oid_of() const override
Definition x509_ext.h:565
const std::vector< Entry > & entries() const
Definition x509_ext.h:567
void validate(const X509_Certificate &, const X509_Certificate &, const std::vector< X509_Certificate > &, std::vector< std::set< Certificate_Status_Code > > &cert_status, size_t pos) override
Definition x509_ext.h:951
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:930
Unknown_Extension(const OID &oid, bool critical)
Definition x509_ext.h:928
const std::vector< uint8_t > & extension_contents() const
Definition x509_ext.h:944
virtual bool should_encode() const
Definition pkix_types.h:465
virtual std::string oid_name() const =0
virtual std::vector< uint8_t > encode_inner() const =0
Name Constraints.
Definition pkix_types.h:367