Botan 3.12.0
Crypto and TLS for C&
x509_ext.cpp
Go to the documentation of this file.
1/*
2* X.509 Certificate Extensions
3* (C) 1999-2010,2012 Jack Lloyd
4* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity
5* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity
6* (C) 2024 Anton Einax, Dominik Schricker
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#include <botan/x509_ext.h>
12
13#include <botan/assert.h>
14#include <botan/ber_dec.h>
15#include <botan/der_enc.h>
16#include <botan/hash.h>
17#include <botan/x509cert.h>
18#include <botan/internal/bit_ops.h>
19#include <botan/internal/fmt.h>
20#include <botan/internal/int_utils.h>
21#include <botan/internal/loadstor.h>
22#include <botan/internal/x509_utils.h>
23#include <algorithm>
24#include <set>
25
26namespace Botan {
27
28namespace {
29
30constexpr size_t MaximumKeyIdentifierLength = 64;
31
32template <std::derived_from<Certificate_Extension> T>
33auto make_extension([[maybe_unused]] const OID& oid) {
34 BOTAN_DEBUG_ASSERT(oid == T::static_oid());
35 return std::make_unique<T>();
36}
37
38std::unique_ptr<Certificate_Extension> extension_from_oid(const OID& oid) {
39 if(auto iso_ext = is_sub_element_of(oid, {2, 5, 29})) {
40 // NOLINTNEXTLINE(*-switch-missing-default-case)
41 switch(*iso_ext) {
42 case 14:
43 return make_extension<Cert_Extension::Subject_Key_ID>(oid);
44 case 15:
45 return make_extension<Cert_Extension::Key_Usage>(oid);
46 case 17:
47 return make_extension<Cert_Extension::Subject_Alternative_Name>(oid);
48 case 18:
49 return make_extension<Cert_Extension::Issuer_Alternative_Name>(oid);
50 case 19:
51 return make_extension<Cert_Extension::Basic_Constraints>(oid);
52 case 20:
53 return make_extension<Cert_Extension::CRL_Number>(oid);
54 case 21:
55 return make_extension<Cert_Extension::CRL_ReasonCode>(oid);
56 case 28:
57 return make_extension<Cert_Extension::CRL_Issuing_Distribution_Point>(oid);
58 case 30:
59 return make_extension<Cert_Extension::Name_Constraints>(oid);
60 case 31:
61 return make_extension<Cert_Extension::CRL_Distribution_Points>(oid);
62 case 32:
63 return make_extension<Cert_Extension::Certificate_Policies>(oid);
64 case 35:
65 return make_extension<Cert_Extension::Authority_Key_ID>(oid);
66 case 37:
67 return make_extension<Cert_Extension::Extended_Key_Usage>(oid);
68 }
69 }
70
71 if(auto pkix_ext = is_sub_element_of(oid, {1, 3, 6, 1, 5, 5, 7, 1})) {
72 // NOLINTNEXTLINE(*-switch-missing-default-case)
73 switch(*pkix_ext) {
74 case 1:
75 return make_extension<Cert_Extension::Authority_Information_Access>(oid);
76 case 7:
77 return make_extension<Cert_Extension::IPAddressBlocks>(oid);
78 case 8:
79 return make_extension<Cert_Extension::ASBlocks>(oid);
80 case 26:
81 return make_extension<Cert_Extension::TNAuthList>(oid);
82 }
83 }
84
86 return make_extension<Cert_Extension::OCSP_NoCheck>(oid);
87 }
88
89 return nullptr; // unknown
90}
91
92bool is_valid_telephone_number(const ASN1_String& tn) {
93 //TelephoneNumber ::= IA5String (SIZE (1..15)) (FROM ("0123456789#*"))
94 const std::string valid_tn_chars("0123456789#*");
95
96 if(tn.empty() || (tn.size() > 15)) {
97 return false;
98 }
99
100 if(tn.value().find_first_not_of(valid_tn_chars) != std::string::npos) {
101 return false;
102 }
103
104 return true;
105}
106
107} // namespace
108
109std::vector<OID> Extensions::critical_extensions() const {
110 std::vector<OID> crit;
111
112 for(const auto& oid : m_extension_oids) {
113 auto ext_info = m_extension_info.find(oid);
114 BOTAN_ASSERT_NOMSG(ext_info != m_extension_info.end());
115 if(ext_info->second.is_critical()) {
116 crit.push_back(oid);
117 }
118 }
119
120 return crit;
121}
122
123/*
124* Create a Certificate_Extension object of some kind to handle
125*/
126std::unique_ptr<Certificate_Extension> Extensions::create_extn_obj(const OID& oid,
127 bool critical,
128 const std::vector<uint8_t>& body) {
129 auto extn = extension_from_oid(oid);
130
131 if(!extn) {
132 // some other unknown extension type
133 extn = std::make_unique<Cert_Extension::Unknown_Extension>(oid, critical);
134 } else {
135 try {
136 extn->decode_inner(body);
137 return extn;
138 } catch(const Exception&) {
139 // OID was recognized but contents failed to decode
140 extn = std::make_unique<Cert_Extension::Unknown_Extension>(oid, critical, /*failed_to_decode=*/true);
141 }
142 }
143
144 // This is always Unknown_Extension:
145 extn->decode_inner(body);
146 return extn;
147}
148
149const Certificate_Extension& Extensions::Extensions_Info::obj() const {
150 BOTAN_ASSERT_NONNULL(m_obj.get());
151 return *m_obj;
152}
153
154/*
155* Validate the extension (the default implementation is a NOP)
156*/
158 const std::optional<X509_Certificate>& /*unused*/,
159 const std::vector<X509_Certificate>& /*unused*/,
160 std::vector<std::set<Certificate_Status_Code>>& /*unused*/,
161 size_t /*unused*/) {}
162
163/*
164* Add a new cert
165*/
166void Extensions::add(std::unique_ptr<Certificate_Extension> extn, bool critical) {
167 // sanity check: we don't want to have the same extension more than once
168 if(m_extension_info.contains(extn->oid_of())) {
169 const std::string name = extn->oid_name();
170 throw Invalid_Argument("Extension " + name + " already present in Extensions::add");
171 }
172
173 const OID oid = extn->oid_of();
174 Extensions_Info info(critical, std::move(extn));
175 m_extension_oids.push_back(oid);
176 m_extension_info.emplace(oid, info);
177}
178
179bool Extensions::add_new(std::unique_ptr<Certificate_Extension> extn, bool critical) {
180 if(m_extension_info.contains(extn->oid_of())) {
181 return false; // already exists
182 }
183
184 const OID oid = extn->oid_of();
185 Extensions_Info info(critical, std::move(extn));
186 m_extension_oids.push_back(oid);
187 m_extension_info.emplace(oid, info);
188 return true;
189}
190
191bool Extensions::remove(const OID& oid) {
192 const bool erased = m_extension_info.erase(oid) > 0;
193
194 if(erased) {
195 m_extension_oids.erase(std::find(m_extension_oids.begin(), m_extension_oids.end(), oid));
196 }
197
198 return erased;
199}
200
201void Extensions::replace(std::unique_ptr<Certificate_Extension> extn, bool critical) {
202 // Remove it if it existed
203 remove(extn->oid_of());
204
205 const OID oid = extn->oid_of();
206 Extensions_Info info(critical, std::move(extn));
207 m_extension_oids.push_back(oid);
208 m_extension_info.emplace(oid, info);
209}
210
211bool Extensions::extension_set(const OID& oid) const {
212 return m_extension_info.contains(oid);
213}
214
216 auto i = m_extension_info.find(oid);
217 if(i != m_extension_info.end()) {
218 return i->second.is_critical();
219 }
220 return false;
221}
222
223std::vector<uint8_t> Extensions::get_extension_bits(const OID& oid) const {
224 auto i = m_extension_info.find(oid);
225 if(i == m_extension_info.end()) {
226 throw Invalid_Argument("Extensions::get_extension_bits no such extension set");
227 }
228
229 return i->second.bits();
230}
231
233 auto extn = m_extension_info.find(oid);
234 if(extn == m_extension_info.end()) {
235 return nullptr;
236 }
237
238 return &extn->second.obj();
239}
240
241std::unique_ptr<Certificate_Extension> Extensions::get(const OID& oid) const {
242 if(const Certificate_Extension* ext = this->get_extension_object(oid)) {
243 return ext->copy();
244 }
245 return nullptr;
246}
247
248std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> Extensions::extensions() const {
249 std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> exts;
250 exts.reserve(m_extension_info.size());
251 for(auto&& ext : m_extension_info) {
252 exts.push_back(std::make_pair(ext.second.obj().copy(), ext.second.is_critical()));
253 }
254 return exts;
255}
256
257std::map<OID, std::pair<std::vector<uint8_t>, bool>> Extensions::extensions_raw() const {
258 std::map<OID, std::pair<std::vector<uint8_t>, bool>> out;
259 for(auto&& ext : m_extension_info) {
260 out.emplace(ext.first, std::make_pair(ext.second.bits(), ext.second.is_critical()));
261 }
262 return out;
263}
264
265/*
266* Encode an Extensions list
267*/
268void Extensions::encode_into(DER_Encoder& to_object) const {
269 for(const auto& [oid, extn] : m_extension_info) {
270 const bool should_encode = extn.obj().should_encode();
271
272 if(should_encode) {
273 const auto is_critical = extn.is_critical() ? std::optional<bool>{true} : std::nullopt;
274 const std::vector<uint8_t>& ext_value = extn.bits();
275
276 to_object.start_sequence()
277 .encode(oid)
278 .encode_optional(is_critical)
279 .encode(ext_value, ASN1_Type::OctetString)
280 .end_cons();
281 }
282 }
283}
284
285/*
286* Decode a list of Extensions
287*/
289 m_extension_oids.clear();
290 m_extension_info.clear();
291
292 BER_Decoder sequence = from_source.start_sequence();
293
294 while(sequence.more_items()) {
295 OID oid;
296 bool critical = false;
297 std::vector<uint8_t> bits;
298
299 sequence.start_sequence()
300 .decode(oid)
303 .end_cons();
304
305 auto obj = create_extn_obj(oid, critical, bits);
306 Extensions_Info info(critical, bits, std::move(obj));
307
308 // RFC 5280 4.2: "A certificate MUST NOT include more than one
309 // instance of a particular extension."
310 if(!m_extension_info.emplace(oid, info).second) {
311 throw Decoding_Error("Duplicate certificate extension encountered");
312 }
313 m_extension_oids.push_back(oid);
314 }
315 sequence.verify_end();
316}
317
318namespace Cert_Extension {
319
322
324 m_is_ca(is_ca), m_path_length_constraint(path_length_constraint) {
325 if(!m_is_ca && m_path_length_constraint.has_value()) {
326 // RFC 5280 Sec 4.2.1.9 "CAs MUST NOT include the pathLenConstraint field unless the cA boolean is asserted"
327 throw Invalid_Argument(
328 "Basic_Constraints nonsensical to set a path length constraint for a non-CA basicConstraints");
329 }
330}
331
332/*
333* Checked accessor for the path_length_constraint member
334*/
336 if(m_is_ca) {
337 return m_path_length_constraint.value_or(NO_CERT_PATH_LIMIT);
338 } else {
339 throw Invalid_State("Basic_Constraints::get_path_limit: Not a CA");
340 }
341}
342
343/*
344* Encode the extension
345*/
346std::vector<uint8_t> Basic_Constraints::encode_inner() const {
347 std::vector<uint8_t> output;
348
349 if(m_is_ca) {
350 DER_Encoder(output).start_sequence().encode(m_is_ca).encode_optional(m_path_length_constraint).end_cons();
351 } else {
353 }
354
355 return output;
356}
357
358/*
359* Decode the extension
360*/
361void Basic_Constraints::decode_inner(const std::vector<uint8_t>& in) {
362 /*
363 * RFC 5280 Section 4.2.1.9
364 *
365 * BasicConstraints ::= SEQUENCE {
366 * cA BOOLEAN DEFAULT FALSE,
367 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
368 */
369 BER_Decoder(in, BER_Decoder::Limits::DER())
370 .start_sequence()
371 .decode_optional(m_is_ca, ASN1_Type::Boolean, ASN1_Class::Universal, false)
372 .decode_optional(m_path_length_constraint, ASN1_Type::Integer, ASN1_Class::Universal)
373 .end_cons()
374 .verify_end();
375
376 /* RFC 5280 Section 4.2.1.9:
377 * "CAs MUST NOT include the pathLenConstraint field unless the cA boolean
378 * is asserted and the key usage extension asserts the keyCertSign bit" */
379 if(!m_is_ca && m_path_length_constraint.has_value()) {
380 throw Decoding_Error("BasicConstraints pathLenConstraint must not be present when cA is FALSE");
381 }
382}
383
384/*
385* Encode the extension
386*/
387std::vector<uint8_t> Key_Usage::encode_inner() const {
388 if(m_constraints.empty()) {
389 throw Encoding_Error("Cannot encode empty PKIX key constraints");
390 }
391
392 const size_t constraint_bits = m_constraints.value();
393 const size_t unused_bits = ctz(static_cast<uint32_t>(constraint_bits));
394
395 std::vector<uint8_t> der;
396 der.push_back(static_cast<uint8_t>(ASN1_Type::BitString));
397 der.push_back(2 + ((unused_bits < 8) ? 1 : 0));
398 der.push_back(unused_bits % 8);
399 der.push_back(static_cast<uint8_t>((constraint_bits >> 8) & 0xFF));
400 if((constraint_bits & 0xFF) != 0) {
401 der.push_back(static_cast<uint8_t>(constraint_bits & 0xFF));
402 }
403
404 return der;
405}
406
407/*
408* Decode the extension
409*/
410void Key_Usage::decode_inner(const std::vector<uint8_t>& in) {
411 /* RFC 5280 Section 4.2.1.3 - KeyUsage ::= BIT STRING */
412 std::vector<uint8_t> bits;
413 BER_Decoder(in, BER_Decoder::Limits::DER())
415 .verify_end();
416
417 const uint16_t usage = [&bits]() -> uint16_t {
418 switch(bits.size()) {
419 case 0:
420 return 0;
421 case 1:
422 return make_uint16(bits[0], 0);
423 case 2:
424 return make_uint16(bits[0], bits[1]);
425 default:
426 throw Decoding_Error("Invalid KeyUsage bitstring encoding");
427 }
428 }();
429
430 /* RFC 5280 Section 4.2.1.3:
431 * "When the keyUsage extension appears in a certificate, at least one of
432 * the bits MUST be set to 1." */
433 if(usage == 0) {
434 throw Decoding_Error("KeyUsage extension must have at least one bit set");
435 }
436
437 m_constraints = Key_Constraints(usage);
438}
439
440/*
441* Encode the extension
442*/
443std::vector<uint8_t> Subject_Key_ID::encode_inner() const {
444 std::vector<uint8_t> output;
445 DER_Encoder(output).encode(m_key_id, ASN1_Type::OctetString);
446 return output;
447}
448
449/*
450* Decode the extension
451*/
452void Subject_Key_ID::decode_inner(const std::vector<uint8_t>& in) {
453 /* RFC 5280 Section 4.2.1.2 - SubjectKeyIdentifier ::= KeyIdentifier */
454 BER_Decoder(in, BER_Decoder::Limits::DER()).decode(m_key_id, ASN1_Type::OctetString).verify_end();
455
456 if(m_key_id.empty()) {
457 throw Decoding_Error("SubjectKeyIdentifier must not be empty");
458 }
459 if(m_key_id.size() > MaximumKeyIdentifierLength) {
460 throw Decoding_Error(
461 fmt("SubjectKeyIdentifier length {} exceeds limit of {} bytes", m_key_id.size(), MaximumKeyIdentifierLength));
462 }
463}
464
465/*
466* Subject_Key_ID Constructor
467*/
468Subject_Key_ID::Subject_Key_ID(const std::vector<uint8_t>& pub_key, std::string_view hash_name) {
469 auto hash = HashFunction::create_or_throw(hash_name);
470
471 m_key_id.resize(hash->output_length());
472
473 hash->update(pub_key);
474 hash->final(m_key_id.data());
475
476 // Truncate longer hashes, 192 bits here seems plenty
477 const size_t max_skid_len = (192 / 8);
478 if(m_key_id.size() > max_skid_len) {
479 m_key_id.resize(max_skid_len);
480 }
481}
482
483/*
484* Encode the extension
485*/
486std::vector<uint8_t> Authority_Key_ID::encode_inner() const {
487 std::vector<uint8_t> output;
488 DER_Encoder(output)
491 .end_cons();
492 return output;
493}
494
495/*
496* Decode the extension
497*/
498void Authority_Key_ID::decode_inner(const std::vector<uint8_t>& in) {
499 /*
500 * RFC 5280 Section 4.2.1.1
501 *
502 * AuthorityKeyIdentifier ::= SEQUENCE {
503 * keyIdentifier [0] KeyIdentifier OPTIONAL,
504 * authorityCertIssuer [1] GeneralNames OPTIONAL,
505 * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
506 */
508 BER_Decoder seq = ber.start_sequence();
509
510 const bool key_id_present = seq.peek_next_object().is_a(0, ASN1_Class::ContextSpecific);
511
513 ber.verify_end();
514
515 if(key_id_present) {
516 if(m_key_id.empty()) {
517 throw Decoding_Error("AuthorityKeyIdentifier keyIdentifier must not be empty");
518 }
519 if(m_key_id.size() > MaximumKeyIdentifierLength) {
520 throw Decoding_Error(fmt("AuthorityKeyIdentifier keyIdentifier length {} exceeds limit of {} bytes",
521 m_key_id.size(),
522 MaximumKeyIdentifierLength));
523 }
524 }
525}
526
527/*
528* Encode the extension
529*/
530std::vector<uint8_t> Subject_Alternative_Name::encode_inner() const {
531 std::vector<uint8_t> output;
532 DER_Encoder(output).encode(m_alt_name);
533 return output;
534}
535
536/*
537* Encode the extension
538*/
539std::vector<uint8_t> Issuer_Alternative_Name::encode_inner() const {
540 std::vector<uint8_t> output;
541 DER_Encoder(output).encode(m_alt_name);
542 return output;
543}
544
545/*
546* Decode the extension
547*/
548void Subject_Alternative_Name::decode_inner(const std::vector<uint8_t>& in) {
549 /* RFC 5280 Section 4.2.1.6 - SubjectAltName ::= GeneralNames
550 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName */
551 BER_Decoder(in, BER_Decoder::Limits::DER()).decode(m_alt_name).verify_end();
552 if(!m_alt_name.has_items()) {
553 throw Decoding_Error("SubjectAlternativeName extension must contain at least one GeneralName");
554 }
555}
556
557/*
558* Decode the extension
559*/
560void Issuer_Alternative_Name::decode_inner(const std::vector<uint8_t>& in) {
561 /* RFC 5280 Section 4.2.1.7 - IssuerAltName ::= GeneralNames
562 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName */
563 BER_Decoder(in, BER_Decoder::Limits::DER()).decode(m_alt_name).verify_end();
564 if(!m_alt_name.has_items()) {
565 throw Decoding_Error("IssuerAlternativeName extension must contain at least one GeneralName");
566 }
567}
568
569/*
570* Encode the extension
571*/
572std::vector<uint8_t> Extended_Key_Usage::encode_inner() const {
573 std::vector<uint8_t> output;
574 DER_Encoder(output).start_sequence().encode_list(m_oids).end_cons();
575 return output;
576}
577
578/*
579* Decode the extension
580*/
581void Extended_Key_Usage::decode_inner(const std::vector<uint8_t>& in) {
582 /* RFC 5280 Section 4.2.1.12 - ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId */
583 BER_Decoder(in, BER_Decoder::Limits::DER()).decode_list(m_oids).verify_end();
584 if(m_oids.empty()) {
585 throw Decoding_Error("ExtendedKeyUsage extension must contain at least one KeyPurposeId");
586 }
587}
588
589/*
590* Encode the extension
591*/
592std::vector<uint8_t> Name_Constraints::encode_inner() const {
593 throw Not_Implemented("Name_Constraints encoding");
594}
595
596/*
597* Decode the extension
598*/
599void Name_Constraints::decode_inner(const std::vector<uint8_t>& in) {
600 /*
601 * RFC 5280 Section 4.2.1.10
602 *
603 * NameConstraints ::= SEQUENCE {
604 * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
605 * excludedSubtrees [1] GeneralSubtrees OPTIONAL }
606 */
607 BER_Decoder ber(in, BER_Decoder::Limits::DER());
608 BER_Decoder inner = ber.start_sequence();
609
610 std::vector<GeneralSubtree> permitted;
611 if(inner.decode_optional_list(permitted, ASN1_Type(0), ASN1_Class::ExplicitContextSpecific)) {
612 if(permitted.empty()) {
613 throw Decoding_Error("Empty NameConstraint permitted list");
614 }
615 }
616
617 std::vector<GeneralSubtree> excluded;
618 if(inner.decode_optional_list(excluded, ASN1_Type(1), ASN1_Class::ExplicitContextSpecific)) {
619 if(excluded.empty()) {
620 throw Decoding_Error("Empty NameConstraint excluded list");
621 }
622 }
623
624 inner.end_cons();
625 ber.verify_end();
626
627 if(permitted.empty() && excluded.empty()) {
628 throw Decoding_Error("Empty NameConstraint extension");
629 }
630
631 m_name_constraints = NameConstraints(std::move(permitted), std::move(excluded));
632}
633
635 const std::optional<X509_Certificate>& /*issuer*/,
636 const std::vector<X509_Certificate>& cert_path,
637 std::vector<std::set<Certificate_Status_Code>>& cert_status,
638 size_t pos) {
639 if(!m_name_constraints.permitted().empty() || !m_name_constraints.excluded().empty()) {
640 if(!subject.is_CA_cert()) {
641 cert_status.at(pos).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR);
642 }
643
644 const bool issuer_name_constraint_critical = subject.is_critical("X509v3.NameConstraints");
645
646 // Check that all subordinate certs pass the name constraint
647 for(size_t j = 0; j < pos; ++j) {
648 const auto& cert = cert_path.at(j);
649
650 // RFC 5280 6.1.4(b): "Name constraints are not applied to self-issued
651 // certificates (unless the certificate is the final certificate in the path)"
652 // Position 0 is the end entity (final certificate); skip self-issued intermediates.
653 if(j > 0 && cert.issuer_dn() == cert.subject_dn()) {
654 continue;
655 }
656
657 if(!m_name_constraints.is_permitted(cert, issuer_name_constraint_critical)) {
658 cert_status.at(j).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR);
659 continue;
660 }
661
662 if(m_name_constraints.is_excluded(cert, issuer_name_constraint_critical)) {
663 cert_status.at(j).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR);
664 continue;
665 }
666 }
667 }
668}
669
670namespace {
671
672/*
673* A policy specifier
674*/
675class Policy_Information final : public ASN1_Object {
676 public:
677 Policy_Information() = default;
678
679 explicit Policy_Information(const OID& oid) : m_oid(oid) {}
680
681 const OID& oid() const { return m_oid; }
682
683 void encode_into(DER_Encoder& codec) const override { codec.start_sequence().encode(m_oid).end_cons(); }
684
685 void decode_from(BER_Decoder& codec) override {
686 codec.start_sequence().decode(m_oid).discard_remaining().end_cons();
687 }
688
689 private:
690 OID m_oid;
691};
692
693} // namespace
694
695/*
696* Encode the extension
697*/
698std::vector<uint8_t> Certificate_Policies::encode_inner() const {
699 std::vector<Policy_Information> policies;
700
701 policies.reserve(m_oids.size());
702 for(const auto& oid : m_oids) {
703 policies.push_back(Policy_Information(oid));
704 }
705
706 std::vector<uint8_t> output;
707 DER_Encoder(output).start_sequence().encode_list(policies).end_cons();
708 return output;
709}
710
711/*
712* Decode the extension
713*/
714void Certificate_Policies::decode_inner(const std::vector<uint8_t>& in) {
715 /* RFC 5280 Section 4.2.1.4 - CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation */
716 std::vector<Policy_Information> policies;
717
718 BER_Decoder(in, BER_Decoder::Limits::DER()).decode_list(policies).verify_end();
719 if(policies.empty()) {
720 throw Decoding_Error("CertificatePolicies extension must contain at least one PolicyInformation");
721 }
722 m_oids.clear();
723 for(const auto& policy : policies) {
724 m_oids.push_back(policy.oid());
725 }
726}
727
729 const std::optional<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) {
733 const std::set<OID> oid_set(m_oids.begin(), m_oids.end());
734 if(oid_set.size() != m_oids.size()) {
735 cert_status.at(pos).insert(Certificate_Status_Code::DUPLICATE_CERT_POLICY);
736 }
737}
738
739std::vector<uint8_t> Authority_Information_Access::encode_inner() const {
740 std::vector<uint8_t> output;
741 DER_Encoder der(output);
742
743 der.start_sequence();
744 // OCSP Responders
745 for(const auto& ocsp_responder : m_ocsp_responders) {
747 der.start_sequence()
748 .encode(OID::from_string("PKIX.OCSP"))
749 .add_object(ASN1_Type(6), ASN1_Class::ContextSpecific, url.value())
750 .end_cons();
751 }
752
753 // CA Issuers
754 for(const auto& ca_issuer : m_ca_issuers) {
755 const ASN1_String asn1_ca_issuer(ca_issuer, ASN1_Type::Ia5String);
756 der.start_sequence()
757 .encode(OID::from_string("PKIX.CertificateAuthorityIssuers"))
758 .add_object(ASN1_Type(6), ASN1_Class::ContextSpecific, asn1_ca_issuer.value())
759 .end_cons();
760 }
761
762 der.end_cons();
763 return output;
764}
765
766void Authority_Information_Access::decode_inner(const std::vector<uint8_t>& in) {
767 /*
768 * RFC 5280 Section 4.2.2.1
769 *
770 * AuthorityInfoAccessSyntax ::= SEQUENCE SIZE (1..MAX) OF AccessDescription
771 * AccessDescription ::= SEQUENCE {
772 * accessMethod OBJECT IDENTIFIER,
773 * accessLocation GeneralName }
774 */
775 BER_Decoder outer(in, BER_Decoder::Limits::DER());
776 BER_Decoder ber = outer.start_sequence();
777
778 const OID ocsp_responder = OID::from_string("PKIX.OCSP");
779 const OID ca_issuer = OID::from_string("PKIX.CertificateAuthorityIssuers");
780
781 size_t access_descriptions_seen = 0;
782 while(ber.more_items()) {
783 OID oid;
784
785 BER_Decoder info = ber.start_sequence();
786
787 info.decode(oid);
788 const BER_Object name = info.get_next_object();
789 info.end_cons();
790
791 access_descriptions_seen += 1;
792
793 if(oid == ocsp_responder && name.is_a(6, ASN1_Class::ContextSpecific)) {
794 m_ocsp_responders.push_back(ASN1::to_string(name));
795 } else if(oid == ca_issuer && name.is_a(6, ASN1_Class::ContextSpecific)) {
796 m_ca_issuers.push_back(ASN1::to_string(name));
797 }
798 }
799
800 ber.end_cons();
801 outer.verify_end();
802
803 if(access_descriptions_seen == 0) {
804 throw Decoding_Error("AuthorityInformationAccess extension must contain at least one AccessDescription");
805 }
806}
807
808/*
809* Checked accessor for the crl_number member
810*/
812 if(!m_has_value) {
813 throw Invalid_State("CRL_Number::get_crl_number: Not set");
814 }
815 return m_crl_number;
816}
817
818/*
819* Copy a CRL_Number extension
820*/
821std::unique_ptr<Certificate_Extension> CRL_Number::copy() const {
822 if(!m_has_value) {
823 throw Invalid_State("CRL_Number::copy: Not set");
824 }
825 return std::make_unique<CRL_Number>(m_crl_number);
826}
827
828/*
829* Encode the extension
830*/
831std::vector<uint8_t> CRL_Number::encode_inner() const {
832 std::vector<uint8_t> output;
833 DER_Encoder(output).encode(m_crl_number);
834 return output;
835}
836
837/*
838* Decode the extension
839*/
840void CRL_Number::decode_inner(const std::vector<uint8_t>& in) {
841 /* RFC 5280 Section 5.2.3 - CRLNumber ::= INTEGER (0..MAX) */
843 m_has_value = true;
844}
845
846/*
847* Encode the extension
848*/
849std::vector<uint8_t> CRL_ReasonCode::encode_inner() const {
850 std::vector<uint8_t> output;
851 DER_Encoder(output).encode(static_cast<size_t>(m_reason), ASN1_Type::Enumerated, ASN1_Class::Universal);
852 return output;
853}
854
855/*
856* Decode the extension
857*/
858void CRL_ReasonCode::decode_inner(const std::vector<uint8_t>& in) {
859 /*
860 * RFC 5280 Section 5.3.1
861 *
862 * CRLReason ::= ENUMERATED {
863 * unspecified (0),
864 * keyCompromise (1),
865 * cACompromise (2),
866 * affiliationChanged (3),
867 * superseded (4),
868 * cessationOfOperation (5),
869 * certificateHold (6),
870 * -- value 7 is not used
871 * removeFromCRL (8),
872 * privilegeWithdrawn (9),
873 * aACompromise (10) }
874 */
875 size_t reason_code = 0;
876 BER_Decoder(in, BER_Decoder::Limits::DER())
877 .decode(reason_code, ASN1_Type::Enumerated, ASN1_Class::Universal)
878 .verify_end();
879
880 if(reason_code == 7 || reason_code > 10) {
881 throw Decoding_Error(fmt("CRLReason has unknown enumeration value {}", reason_code));
882 }
883
884 m_reason = static_cast<CRL_Code>(reason_code);
885}
886
887std::vector<uint8_t> CRL_Distribution_Points::encode_inner() const {
888 std::vector<uint8_t> output;
889 DER_Encoder(output).start_sequence().encode_list(m_distribution_points).end_cons();
890 return output;
891}
892
893void CRL_Distribution_Points::decode_inner(const std::vector<uint8_t>& buf) {
894 /*
895 * RFC 5280 Section 4.2.1.13
896 *
897 * CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
898 */
899 BER_Decoder(buf, BER_Decoder::Limits::DER()).decode_list(m_distribution_points).verify_end();
900
901 if(m_distribution_points.empty()) {
902 throw Decoding_Error("CRLDistributionPoints extension must contain at least one DistributionPoint");
903 }
904
905 for(const auto& distribution_point : m_distribution_points) {
906 for(const auto& uri : distribution_point.point().uris()) {
907 m_crl_distribution_urls.push_back(uri);
908 }
909 }
910}
911
913 const auto uris = m_point.uris();
914
915 if(uris.empty()) {
916 throw Not_Implemented("Empty CRL_Distribution_Point encoding not implemented");
917 }
918
919 for(const auto& uri : uris) {
920 der.start_sequence()
924 .end_cons()
925 .end_cons()
926 .end_cons();
927 }
928}
929
941
942std::vector<uint8_t> CRL_Issuing_Distribution_Point::encode_inner() const {
943 throw Not_Implemented("CRL_Issuing_Distribution_Point encoding");
944}
945
946void CRL_Issuing_Distribution_Point::decode_inner(const std::vector<uint8_t>& buf) {
947 /* RFC 5280 Section 5.2.5 - IssuingDistributionPoint ::= SEQUENCE { ... } */
948 BER_Decoder(buf, BER_Decoder::Limits::DER()).decode(m_distribution_point).verify_end();
949}
950
952 throw Not_Implemented("TNAuthList extension entry serialization is not supported");
953}
954
956 const BER_Object obj = ber.get_next_object();
957
959 throw Decoding_Error(fmt("Unexpected TNEntry class tag {}", static_cast<uint32_t>(obj.get_class())));
960 }
961
962 const uint32_t type_tag = static_cast<uint32_t>(obj.type_tag());
963
964 if(type_tag == ServiceProviderCode) {
965 m_type = ServiceProviderCode;
966 ASN1_String spc_string;
967 BER_Decoder(obj, ber.limits()).decode(spc_string);
968 m_data = std::move(spc_string);
969 } else if(type_tag == TelephoneNumberRange) {
970 m_type = TelephoneNumberRange;
971 m_data = RangeContainer();
972 auto& range_items = std::get<RangeContainer>(m_data);
973 BER_Decoder outer(obj, ber.limits());
974 BER_Decoder list = outer.start_sequence();
975 while(list.more_items()) {
977
978 list.decode(entry.start);
979 if(!is_valid_telephone_number(entry.start)) {
980 throw Decoding_Error(fmt("Invalid TelephoneNumberRange start {}", entry.start.value()));
981 }
982
983 list.decode(entry.count);
984 if(entry.count < 2) {
985 throw Decoding_Error(fmt("Invalid TelephoneNumberRange count {}", entry.count));
986 }
987
988 range_items.emplace_back(std::move(entry));
989 }
990 list.end_cons();
991
992 if(range_items.empty()) {
993 throw Decoding_Error("TelephoneNumberRange is empty");
994 }
995 } else if(type_tag == TelephoneNumber) {
996 m_type = TelephoneNumber;
997 ASN1_String one_string;
998 BER_Decoder(obj, ber.limits()).decode(one_string);
999 if(!is_valid_telephone_number(one_string)) {
1000 throw Decoding_Error(fmt("Invalid TelephoneNumber {}", one_string.value()));
1001 }
1002 m_data = std::move(one_string);
1003 } else {
1004 throw Decoding_Error(fmt("Unexpected TNEntry type code {}", type_tag));
1005 };
1006}
1007
1008std::vector<uint8_t> TNAuthList::encode_inner() const {
1009 throw Not_Implemented("TNAuthList extension serialization is not supported");
1010}
1011
1012void TNAuthList::decode_inner(const std::vector<uint8_t>& in) {
1013 /* RFC 8226 Section 9 - TNAuthorizationList ::= SEQUENCE SIZE (1..MAX) OF TNEntry */
1015 if(m_tn_entries.empty()) {
1016 throw Decoding_Error("TNAuthorizationList is empty");
1017 }
1018}
1019
1022 return std::get<ASN1_String>(m_data).value();
1023}
1024
1027 return std::get<RangeContainer>(m_data);
1028}
1029
1030const std::string& TNAuthList::Entry::telephone_number() const {
1032 return std::get<ASN1_String>(m_data).value();
1033}
1034
1035std::vector<uint8_t> IPAddressBlocks::encode_inner() const {
1036 std::vector<uint8_t> output;
1037 DER_Encoder(output).start_sequence().encode_list(m_ip_addr_blocks).end_cons();
1038 return output;
1039}
1040
1041void IPAddressBlocks::decode_inner(const std::vector<uint8_t>& in) {
1042 /* RFC 3779 Section 2.2.3.1 - IPAddrBlocks ::= SEQUENCE OF IPAddressFamily */
1044 sort_and_merge();
1045}
1046
1048 into.start_sequence();
1049
1050 std::vector<uint8_t> afam = {get_byte<0>(m_afi), get_byte<1>(m_afi)};
1051
1052 if(m_safi.has_value()) {
1053 afam.push_back(m_safi.value());
1054 }
1055
1057
1058 if(std::holds_alternative<IPAddressChoice<Version::IPv4>>(m_ip_addr_choice)) {
1059 into.encode(std::get<IPAddressChoice<Version::IPv4>>(m_ip_addr_choice));
1060 } else {
1061 into.encode(std::get<IPAddressChoice<Version::IPv6>>(m_ip_addr_choice));
1062 }
1063 into.end_cons();
1064}
1065
1067 const ASN1_Type next_tag = from.peek_next_object().type_tag();
1068 if(next_tag != ASN1_Type::Sequence) {
1069 throw Decoding_Error(fmt("Unexpected type for IPAddressFamily {}", static_cast<uint32_t>(next_tag)));
1070 }
1071
1072 BER_Decoder seq_dec = from.start_sequence();
1073
1074 std::vector<uint8_t> addr_family;
1075 seq_dec.decode(addr_family, ASN1_Type::OctetString);
1076 const size_t addr_family_length = addr_family.size();
1077
1078 if(addr_family_length != 2 && addr_family_length != 3) {
1079 throw Decoding_Error("(S)AFI can only contain 2 or 3 bytes");
1080 }
1081
1082 m_afi = (addr_family[0] << 8) | addr_family[1];
1083
1084 if(addr_family_length == 3) {
1085 m_safi = addr_family[2];
1086 }
1087
1088 if(m_afi == 1) {
1090 seq_dec.decode(addr_choice);
1091 m_ip_addr_choice = addr_choice;
1092 } else if(m_afi == 2) {
1094 seq_dec.decode(addr_choice);
1095 m_ip_addr_choice = addr_choice;
1096 } else {
1097 throw Decoding_Error("Only AFI IPv4 and IPv6 are supported.");
1098 }
1099
1100 seq_dec.end_cons();
1101}
1102
1103void IPAddressBlocks::sort_and_merge() {
1104 // Sort IPAddressFamilies by afi/safi values
1105 //
1106 // see: https://www.rfc-editor.org/rfc/rfc3779.html#section-2.2.3.3
1107 //
1108 // v4 families are ordered before v6 families (i.e. they are sorted by afis, primarily),
1109 // families with no safis are ordered before families with safis
1110 //
1111 // families with the same afi/safi combination are then merged
1112
1113 // std::map is ordered, so using a pair (afi, optional(safi)) here works - std::nullopt is sorted before any actual values
1114 std::map<std::pair<uint16_t, std::optional<uint8_t>>, std::vector<IPAddressFamily>> afam_map;
1115 for(const IPAddressFamily& block : m_ip_addr_blocks) {
1116 auto key = std::make_pair(block.afi(), block.safi());
1117 std::vector<IPAddressFamily>& fams = afam_map[key];
1118 fams.push_back(block);
1119 }
1120
1121 std::vector<IPAddressFamily> merged_blocks;
1122 for(auto& it : afam_map) {
1123 // fams consists of families with the same afi/safi combination
1124 std::vector<IPAddressFamily>& fams = it.second;
1125 // since at least 1 block has to belong to a afi/safi combination for it to appear in the map,
1126 // fams cannot be empty
1127 BOTAN_ASSERT_NOMSG(!fams.empty());
1128
1129 // fams[0] has to have the same choice type as the fams in the same bucket
1130 if(std::holds_alternative<IPAddressChoice<Version::IPv4>>(fams[0].addr_choice())) {
1131 merged_blocks.push_back(merge<Version::IPv4>(fams));
1132 } else {
1133 merged_blocks.push_back(merge<Version::IPv6>(fams));
1134 }
1135 }
1136 m_ip_addr_blocks = merged_blocks;
1137}
1138
1139template <IPAddressBlocks::Version V>
1140IPAddressBlocks::IPAddressFamily IPAddressBlocks::merge(std::vector<IPAddressFamily>& blocks) {
1141 // Merge IPAddressFamilies that have the same afi/safi combination
1142 //
1143 // see: https://www.rfc-editor.org/rfc/rfc3779.html#section-2.2.3.3
1144
1145 BOTAN_ASSERT(!blocks.empty(), "Cannot merge an empty set of IP address blocks into a single family");
1146
1147 // nothing to merge
1148 if(blocks.size() == 1) {
1149 return blocks[0];
1150 }
1151
1152 bool all_inherit = true;
1153 bool none_inherit = true;
1154 for(const IPAddressFamily& block : blocks) {
1155 const IPAddressChoice<V> choice = std::get<IPAddressChoice<V>>(block.addr_choice());
1156 all_inherit = !choice.ranges().has_value() && all_inherit; // all the blocks have the 'inherit' value
1157 none_inherit = choice.ranges().has_value() && none_inherit;
1158 }
1159
1160 // they are all 'inherit', short-circuit using default constructor for nullopt
1161 if(all_inherit) {
1162 return IPAddressFamily(IPAddressChoice<V>(), blocks[0].safi());
1163 }
1164
1165 // some are inherit, and some have values - no sensible way to merge them
1166 if(!all_inherit && !none_inherit) {
1167 throw Decoding_Error("Invalid IPAddressBlocks: Only one of 'inherit' or 'do not inherit' is allowed per family");
1168 }
1169
1170 std::vector<IPAddressOrRange<V>> merged_ranges;
1171 for(const IPAddressFamily& block : blocks) {
1172 const IPAddressChoice<V> choice = std::get<IPAddressChoice<V>>(block.addr_choice());
1173 const std::vector<IPAddressOrRange<V>> ranges = choice.ranges().value();
1174 for(const IPAddressOrRange<V>& r : ranges) {
1175 merged_ranges.push_back(r);
1176 }
1177 }
1178
1179 // we have extracted all the ranges, and now rely on the constructor of IPAddressChoice to merge them
1180 IPAddressChoice<V> choice(merged_ranges);
1181 IPAddressFamily fam(choice, blocks[0].safi());
1182 return fam;
1183}
1184
1185namespace {
1186
1187constexpr auto IPv4 = IPAddressBlocks::Version::IPv4;
1188constexpr auto IPv6 = IPAddressBlocks::Version::IPv6;
1189
1190template <IPAddressBlocks::Version V>
1191using IPRangeVec = std::vector<IPAddressBlocks::IPAddressOrRange<V>>;
1192
1193// (S)AFI -> (needs_check, ptr to IPRangeVec)
1194// the pointer can be null, in which case the boolean will be false, as such the pointer's value will never be looked at
1195template <IPAddressBlocks::Version V>
1196using IPValidationMap = std::map<uint32_t, std::pair<bool, const IPRangeVec<V>*>>;
1197
1198template <typename T>
1199std::optional<std::vector<T>> sort_and_merge_ranges(std::optional<std::span<const T>> ranges) {
1200 // Sort and merge overlapping/adjacent IPAddressOrRange or ASIdOrRange objects.
1201 // cf. https://www.rfc-editor.org/rfc/rfc3779.html#section-2.2.3.6 and https://www.rfc-editor.org/rfc/rfc3779.html#section-3.2.3.4
1202 // This implementation uses only min-max ranges internally, so sorting by the prefix length is not necessary / impossible here.
1203
1204 if(!ranges.has_value()) {
1205 return std::nullopt;
1206 }
1207
1208 std::vector<T> sorted(ranges.value().begin(), ranges.value().end());
1209
1210 if(sorted.empty()) {
1211 return sorted;
1212 }
1213
1214 // sort by the min value
1215 std::sort(sorted.begin(), sorted.end(), [](T& a, T& b) { return a.min() < b.min(); });
1216
1217 // Single-pass merge: extend the last merged range or start a new one
1218 std::vector<T> merged;
1219 merged.reserve(sorted.size());
1220 merged.push_back(sorted[0]);
1221
1222 for(size_t i = 1; i < sorted.size(); ++i) {
1223 auto& back = merged.back();
1224 // they either overlap or are adjacent
1225 if(sorted[i].min() <= back.max() || sorted[i].min() == (back.max() + 1)) {
1226 back = T(back.min(), std::max(back.max(), sorted[i].max()));
1227 } else {
1228 merged.push_back(sorted[i]);
1229 }
1230 }
1231
1232 return merged;
1233}
1234
1235template <typename T>
1236bool validate_subject_in_issuer(std::span<const T> subject, std::span<const T> issuer) {
1237 // ensures that the subject ranges are enclosed by the issuer ranges
1238 // both vectors are already sorted, so we can do this in O(n+m)
1239
1240 // the issuer has 0 ranges to validate against, so this can only work if the subject also has none
1241 if(issuer.empty()) {
1242 return subject.empty();
1243 }
1244 for(auto subj = subject.begin(), issu = issuer.begin(); subj != subject.end();) {
1245 // the issuer range is smaller than the subject range, step to the next issuer range to check next round
1246 if(subj->min() > issu->max()) {
1247 issu++;
1248 // we have run out of issuer ranges, but still have subject ranges left to validate
1249 if(issu == issuer.end() && subj != subject.end()) {
1250 return false;
1251 }
1252 } else {
1253 // the subject is outside of the closest issuer range on the left (min) side
1254 if(subj->min() < issu->min()) {
1255 return false;
1256 }
1257 // the subject is outside of the closest issuer range on the right (max) side
1258 if(subj->max() > issu->max()) {
1259 return false;
1260 }
1261 // this range is contained within the issuer, advance to the next subject range
1262 subj++;
1263 }
1264 }
1265 return true;
1266}
1267
1268template <IPAddressBlocks::Version V>
1269void populate_validation_map(uint32_t afam,
1271 IPValidationMap<V>& map) {
1272 const std::optional<IPRangeVec<V>>& ranges = std::get<IPAddressBlocks::IPAddressChoice<V>>(choice).ranges();
1273 const bool has_value = ranges.has_value();
1274 const IPRangeVec<V>* value = has_value ? &ranges.value() : nullptr;
1275 map.emplace(afam, std::make_pair(has_value, std::move(value)));
1276}
1277
1278std::pair<IPValidationMap<IPv4>, IPValidationMap<IPv6>> create_validation_map(
1279 const std::vector<IPAddressBlocks::IPAddressFamily>& addr_blocks) {
1280 IPValidationMap<IPv4> v4_map;
1281 IPValidationMap<IPv6> v6_map;
1282
1283 for(const IPAddressBlocks::IPAddressFamily& block : addr_blocks) {
1284 uint32_t afam = block.afi();
1285 if(block.safi().has_value()) {
1286 afam = static_cast<uint32_t>(afam << 8) | block.safi().value();
1287 }
1288
1289 const IPAddressBlocks::IPAddressFamily::AddrChoice& a_choice = block.addr_choice();
1290 if(std::holds_alternative<IPAddressBlocks::IPAddressChoice<IPv4>>(a_choice)) {
1291 populate_validation_map(afam, a_choice, v4_map);
1292 } else {
1293 populate_validation_map(afam, a_choice, v6_map);
1294 }
1295 }
1296
1297 return std::make_pair(v4_map, v6_map);
1298}
1299
1300} // namespace
1301
1302template <IPAddressBlocks::Version V>
1304 std::optional<std::span<const IPAddressBlocks::IPAddressOrRange<V>>> ranges) {
1305 // NOLINTNEXTLINE(*-prefer-member-initializer)
1306 m_ip_addr_ranges = sort_and_merge_ranges<IPAddressOrRange<V>>(ranges);
1307}
1308
1309template <IPAddressBlocks::Version V>
1311 if(m_ip_addr_ranges.has_value()) {
1312 into.start_sequence().encode_list(m_ip_addr_ranges.value()).end_cons();
1313 } else {
1314 into.encode_null();
1315 }
1316}
1317
1318template <IPAddressBlocks::Version V>
1320 const ASN1_Type next_tag = from.peek_next_object().type_tag();
1321
1322 if(next_tag == ASN1_Type::Null) {
1323 from.decode_null();
1324 m_ip_addr_ranges = std::nullopt;
1325 } else if(next_tag == ASN1_Type::Sequence) {
1326 std::vector<IPAddressOrRange<V>> ip_ranges;
1327 from.decode_list(ip_ranges);
1328 m_ip_addr_ranges = sort_and_merge_ranges<IPAddressOrRange<V>>(ip_ranges);
1329 } else {
1330 throw Decoding_Error(fmt("Unexpected type for IPAddressChoice {}", static_cast<uint32_t>(next_tag)));
1331 }
1332}
1333
1334template <IPAddressBlocks::Version V>
1336 // Compress IPAddressOrRange as much as possible
1337 // cf. https://www.rfc-editor.org/rfc/rfc3779.html#section-2.2.3.7 - https://www.rfc-editor.org/rfc/rfc3779.html#section-2.2.3.9
1338 //
1339 // If possible encode as a prefix x.x.x.x/x, else encode as a range of min-max.
1340 // Single addresses are encoded as is (technically a /32 or /128 prefix).
1341 //
1342 // A range can be encoded as a prefix if the lowest n bits of the min address are 0
1343 // and the highest n bits of the max address are 1, or in other words, contiguous sequences of 0s and 1s are omitted.
1344 // To make reconstruction possible, an 'unused' octet is included at the start, since in the case of e.g. /25 only
1345 // the highest bit of the last octet is actually meaningful.
1346 //
1347 // If encoding requires a range, the individual elements can still be compressed using the above method,
1348 // but the number of used bits varies between them.
1349
1350 const size_t version_octets = static_cast<size_t>(V);
1351
1352 std::array<uint8_t, version_octets> min = m_min.value();
1353 std::array<uint8_t, version_octets> max = m_max.value();
1354
1355 uint8_t zeros = 0;
1356 uint8_t ones = 0;
1357
1358 bool zeros_done = false;
1359 bool ones_done = false;
1360
1361 // count contiguous 0s/1s from the right of the min/max addresses
1362 for(size_t i = version_octets; i > 0; i--) {
1363 if(!zeros_done) {
1364 const uint8_t local_zeros = static_cast<uint8_t>(std::countr_zero(min[i - 1]));
1365 zeros += local_zeros;
1366 zeros_done = (local_zeros != 8);
1367 }
1368
1369 if(!ones_done) {
1370 const uint8_t local_ones = static_cast<uint8_t>(std::countr_one(max[i - 1]));
1371 ones += local_ones;
1372 ones_done = (local_ones != 8);
1373 }
1374
1375 if(zeros_done && ones_done) {
1376 break;
1377 }
1378 }
1379
1380 // the part we want to compress
1381 const uint8_t host = std::min(zeros, ones);
1382
1383 // these we can outright drop
1384 const uint8_t discarded_octets = host / 8;
1385 // in a partially used octet
1386 const uint8_t unused_bits = host % 8;
1387
1388 bool octets_match = true;
1389 bool used_bits_match = true;
1390
1391 // we have octets to check
1392 if(discarded_octets < version_octets) {
1393 // check all but the last octet
1394 for(size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets - 1); i++) {
1395 if(min[i] != max[i]) {
1396 octets_match = false;
1397 break;
1398 }
1399 }
1400 // check the last significant octet if we have matched so far
1401 if(octets_match) {
1402 const uint8_t shifted_min = (min[version_octets - 1 - discarded_octets] >> unused_bits);
1403 const uint8_t shifted_max = (max[version_octets - 1 - discarded_octets] >> unused_bits);
1404 used_bits_match = (shifted_min == shifted_max);
1405 }
1406 }
1407
1408 // both the full octets and the partially used one match
1409 if(octets_match && used_bits_match) {
1410 // at this point the range can be encoded as a prefix
1411 std::vector<uint8_t> prefix;
1412
1413 prefix.push_back(unused_bits);
1414 for(size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets); i++) {
1415 prefix.push_back(min[i]);
1416 }
1417
1419 } else {
1420 const uint8_t discarded_octets_min = zeros / 8;
1421 const uint8_t unused_bits_min = zeros % 8;
1422
1423 const uint8_t discarded_octets_max = ones / 8;
1424 const uint8_t unused_bits_max = ones % 8;
1425
1426 // compress the max address by setting unused bits to 0, for the min address these are already 0
1427 if(unused_bits_max != 0) {
1428 BOTAN_ASSERT_NOMSG(discarded_octets_max < version_octets);
1429 max[version_octets - 1 - discarded_octets_max] >>= unused_bits_max;
1430 max[version_octets - 1 - discarded_octets_max] <<= unused_bits_max;
1431 }
1432
1433 std::vector<uint8_t> compressed_min;
1434 std::vector<uint8_t> compressed_max;
1435
1436 // construct the address as a byte sequence of the unused bits followed by the compressed address
1437 compressed_min.push_back(unused_bits_min);
1438 for(size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets_min); i++) {
1439 compressed_min.push_back(min[i]);
1440 }
1441
1442 compressed_max.push_back(unused_bits_max);
1443 for(size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets_max); i++) {
1444 compressed_max.push_back(max[i]);
1445 }
1446
1447 into.start_sequence()
1450 .end_cons();
1451 }
1452}
1453
1454template <IPAddressBlocks::Version V>
1456 const ASN1_Type next_tag = from.peek_next_object().type_tag();
1457
1458 // this can either be a prefix or a single address
1459 if(next_tag == ASN1_Type::BitString) {
1460 // construct a min and a max address from the prefix
1461
1462 std::vector<uint8_t> prefix_min;
1464
1465 // copy because we modify the address in `decode_single_address`, but we need it twice for min and max
1466 std::vector<uint8_t> prefix_max(prefix_min);
1467
1468 // min address gets filled with 0's
1469 m_min = decode_single_address(std::move(prefix_min), true);
1470 // max address with 1's
1471 m_max = decode_single_address(std::move(prefix_max), false);
1472 } else if(next_tag == ASN1_Type::Sequence) {
1473 // this is a range
1474
1475 std::vector<uint8_t> addr_min;
1476 std::vector<uint8_t> addr_max;
1477
1478 from.start_sequence()
1481 .end_cons();
1482
1483 m_min = decode_single_address(std::move(addr_min), true);
1484 m_max = decode_single_address(std::move(addr_max), false);
1485
1486 if(m_min > m_max) {
1487 throw Decoding_Error("IP address ranges must be sorted.");
1488 }
1489 } else {
1490 throw Decoding_Error(fmt("Unexpected type for IPAddressOrRange {}", static_cast<uint32_t>(next_tag)));
1491 }
1492}
1493
1494template <IPAddressBlocks::Version V>
1495IPAddressBlocks::IPAddress<V> IPAddressBlocks::IPAddressOrRange<V>::decode_single_address(std::vector<uint8_t> decoded,
1496 bool min) {
1497 const size_t version_octets = static_cast<size_t>(V);
1498
1499 // decode a single address according to https://datatracker.ietf.org/doc/html/rfc3779#section-2.1.1 and following
1500
1501 // we have to account for the octet at the beginning that specifies how many bits are unused in the last octet
1502 if(decoded.empty() || decoded.size() > version_octets + 1) {
1503 throw Decoding_Error(fmt("IP address range entries must have a length between 1 and {} bytes.", version_octets));
1504 }
1505
1506 const uint8_t unused = decoded.front();
1507 const uint8_t discarded_octets = version_octets - (static_cast<uint8_t>(decoded.size()) - 1);
1508
1509 decoded.erase(decoded.begin());
1510
1511 if(decoded.empty() && unused != 0) {
1512 throw Decoding_Error("IP address range entry specified unused bits, but did not provide any octets.");
1513 }
1514
1515 // if they were 8, the entire octet should have been discarded
1516 if(unused > 7) {
1517 throw Decoding_Error("IP address range entry specified invalid number of unused bits.");
1518 }
1519
1520 // pad to version length with 0's for min addresses, 255's (0xff) for max addresses
1521 const uint8_t fill_discarded = min ? 0 : 0xff;
1522 for(size_t i = 0; i < discarded_octets; i++) {
1523 decoded.push_back(fill_discarded);
1524 }
1525
1526 // for min addresses they should already be 0, but we set them to zero regardless
1527 // for max addresses this turns the unused bits to 1
1528 for(size_t i = 0; i < unused; i++) {
1529 if(min) {
1530 decoded[version_octets - 1 - discarded_octets] &= ~(1 << i);
1531 } else {
1532 decoded[version_octets - 1 - discarded_octets] |= (1 << i);
1533 }
1534 }
1535
1536 return IPAddressBlocks::IPAddress<V>(decoded);
1537}
1538
1539template <IPAddressBlocks::Version V>
1540IPAddressBlocks::IPAddress<V>::IPAddress(std::span<const uint8_t> v) {
1541 if(v.size() != Length) {
1542 throw Decoding_Error("number of bytes does not match IP version used");
1543 }
1544
1545 for(size_t i = 0; i < Length; i++) {
1546 m_value[i] = v[i];
1547 }
1548}
1549
1551 const std::optional<X509_Certificate>& /* unused */,
1552 const std::vector<X509_Certificate>& cert_path,
1553 std::vector<std::set<Certificate_Status_Code>>& cert_status,
1554 size_t pos) {
1555 // maps in the form of (s)afi -> (needs_checking, ranges)
1556 auto [v4_needs_check, v6_needs_check] = create_validation_map(m_ip_addr_blocks);
1557
1558 if(pos == cert_path.size() - 1) {
1559 // checks if any range / family has 'inherit' as a value somewhere, not allowed for the root cert
1560 auto validate_root_cert_ext = [&](const auto& map) {
1561 // check if any range has a value of 'false', indicating 'inherit'
1562 return std::any_of(map.begin(), map.end(), [&](const auto& it) {
1563 const auto& [_1, validation_info] = it;
1564 const auto& [needs_checking, _2] = validation_info;
1565 return !needs_checking;
1566 });
1567 };
1568 if(validate_root_cert_ext(v4_needs_check) || validate_root_cert_ext(v6_needs_check)) {
1569 cert_status.at(pos).insert(Certificate_Status_Code::IPADDR_BLOCKS_ERROR);
1570 }
1571 return;
1572 }
1573
1574 // traverse the chain until we find a cert with concrete values for the extension (so not 'inherit')
1575 for(auto cert_path_it = cert_path.begin() + pos + 1; cert_path_it != cert_path.end(); cert_path_it++) {
1576 const IPAddressBlocks* const parent_ip = cert_path_it->v3_extensions().get_extension_object_as<IPAddressBlocks>();
1577 // extension not present for parent
1578 if(parent_ip == nullptr) {
1579 cert_status.at(pos).insert(Certificate_Status_Code::IPADDR_BLOCKS_ERROR);
1580 return;
1581 }
1582 auto [issuer_v4, issuer_v6] = create_validation_map(parent_ip->addr_blocks());
1583
1584 auto validate_against_issuer = [&](auto& subject_map, const auto& issuer_map) {
1585 for(auto map_it = subject_map.begin(); map_it != subject_map.end(); map_it++) {
1586 auto& [afam, validation_info] = *map_it;
1587
1588 // the issuer does not have this combination of afi/safi
1589 if(issuer_map.count(afam) == 0) {
1590 cert_status.at(pos).insert(Certificate_Status_Code::IPADDR_BLOCKS_ERROR);
1591 return false;
1592 }
1593
1594 auto& [needs_check, subject_value] = validation_info;
1595 const auto& [issuer_has_value, issuer_value] = issuer_map.at(afam);
1596 BOTAN_ASSERT_NOMSG(!needs_check || subject_value != nullptr);
1597 BOTAN_ASSERT_NOMSG(!issuer_has_value || issuer_value != nullptr);
1598
1599 // we still need to check this range and the issuer has an actual value for it (so not 'inherit')
1600 if(needs_check && issuer_has_value) {
1601 if(!validate_subject_in_issuer(std::span(*subject_value), std::span(*issuer_value))) {
1602 cert_status.at(pos).insert(Certificate_Status_Code::IPADDR_BLOCKS_ERROR);
1603 return false;
1604 }
1605 needs_check = false;
1606 }
1607 }
1608 return true;
1609 };
1610
1611 if(!validate_against_issuer(v4_needs_check, issuer_v4) || !validate_against_issuer(v6_needs_check, issuer_v6)) {
1612 return;
1613 }
1614
1615 auto validate_no_checks_left = [&](const auto& map) {
1616 // check if all ranges have been checked, either by comparing their ranges if they have any,
1617 // or if they are inherit, their parent(s) will be validated later
1618 return std::all_of(map.begin(), map.end(), [&](const auto& it) {
1619 const auto& [_1, validation_info] = it;
1620 const auto& [needs_checking, _2] = validation_info;
1621 return !needs_checking;
1622 });
1623 };
1624
1625 if(validate_no_checks_left(v4_needs_check) && validate_no_checks_left(v6_needs_check)) {
1626 // we've validated what we need to and can stop traversing the cert chain
1627 return;
1628 }
1629 }
1630}
1631
1638
1639std::vector<uint8_t> ASBlocks::encode_inner() const {
1640 std::vector<uint8_t> output;
1641 DER_Encoder(output).encode(m_as_identifiers);
1642 return output;
1643}
1644
1645void ASBlocks::decode_inner(const std::vector<uint8_t>& in) {
1646 /* RFC 3779 Section 3.2.3.1 - ASIdentifiers ::= SEQUENCE { ... } */
1647 BER_Decoder(in, BER_Decoder::Limits::DER()).decode(m_as_identifiers).verify_end();
1648}
1649
1650ASBlocks::ASIdentifierChoice ASBlocks::add_new(const std::optional<ASIdentifierChoice>& old, asnum_t min, asnum_t max) {
1651 std::vector<ASIdOrRange> range;
1652 if(!old.has_value() || !old.value().ranges().has_value()) {
1653 range = {ASIdOrRange(min, max)};
1654 } else {
1655 range = old.value().ranges().value();
1656 range.push_back(ASIdOrRange(min, max));
1657 }
1658 return ASIdentifierChoice(range);
1659}
1660
1662 into.start_sequence();
1663
1664 if(!m_asnum.has_value() && !m_rdi.has_value()) {
1665 throw Encoding_Error("One of asnum, rdi must be present");
1666 }
1667
1668 if(m_asnum.has_value()) {
1669 into.start_explicit(0);
1670 into.encode(m_asnum.value());
1671 into.end_explicit();
1672 }
1673
1674 if(m_rdi.has_value()) {
1675 into.start_explicit(1);
1676 into.encode(m_rdi.value());
1677 into.end_explicit();
1678 }
1679
1680 into.end_cons();
1681}
1682
1684 const ASN1_Type next_tag = from.peek_next_object().type_tag();
1685 if(next_tag != ASN1_Type::Sequence) {
1686 throw Decoding_Error(fmt("Unexpected type for ASIdentifiers {}", static_cast<uint32_t>(next_tag)));
1687 }
1688
1689 BER_Decoder seq_dec = from.start_sequence();
1690
1691 const BER_Object elem_obj = seq_dec.get_next_object();
1692 const uint32_t elem_type_tag = static_cast<uint32_t>(elem_obj.type_tag());
1693
1694 // asnum, potentially followed by an rdi
1695 if(elem_type_tag == 0) {
1696 BER_Decoder as_obj_ber = BER_Decoder(elem_obj, seq_dec.limits());
1698 as_obj_ber.decode(asnum).verify_end();
1699 m_asnum = asnum;
1700
1701 const BER_Object rdi_obj = seq_dec.get_next_object();
1702 const ASN1_Type rdi_type_tag = rdi_obj.type_tag();
1703 if(static_cast<uint32_t>(rdi_type_tag) == 1) {
1704 BER_Decoder rdi_obj_ber = BER_Decoder(rdi_obj, seq_dec.limits());
1706 rdi_obj_ber.decode(rdi).verify_end();
1707 m_rdi = rdi;
1708 } else if(rdi_type_tag != ASN1_Type::NoObject) {
1709 throw Decoding_Error(fmt("Unexpected type for ASIdentifiers rdi: {}", static_cast<uint32_t>(rdi_type_tag)));
1710 }
1711 }
1712
1713 // just an rdi
1714 if(elem_type_tag == 1) {
1715 BER_Decoder rdi_obj_ber = BER_Decoder(elem_obj, seq_dec.limits());
1717 rdi_obj_ber.decode(rdi).verify_end();
1718 m_rdi = rdi;
1719 const BER_Object end = seq_dec.get_next_object();
1720 const ASN1_Type end_type_tag = end.type_tag();
1721 if(end_type_tag != ASN1_Type::NoObject) {
1722 throw Decoding_Error(
1723 fmt("Unexpected element with type {} in ASIdentifiers", static_cast<uint32_t>(end_type_tag)));
1724 }
1725 }
1726
1727 seq_dec.end_cons();
1728
1729 if(!m_asnum.has_value() && !m_rdi.has_value()) {
1730 throw Decoding_Error("Invalid encoding for ASIdentifiers");
1731 }
1732}
1733
1735 if(m_as_ranges.has_value()) {
1736 into.start_sequence().encode_list(m_as_ranges.value()).end_cons();
1737 } else {
1738 into.encode_null();
1739 }
1740}
1741
1742ASBlocks::ASIdentifierChoice::ASIdentifierChoice(const std::optional<std::vector<ASIdOrRange>>& ranges) {
1743 m_as_ranges = sort_and_merge_ranges<ASIdOrRange>(ranges);
1744}
1745
1747 const ASN1_Type next_tag = from.peek_next_object().type_tag();
1748
1749 if(next_tag == ASN1_Type::Null) {
1750 from.decode_null();
1751 m_as_ranges = std::nullopt;
1752 } else if(next_tag == ASN1_Type::Sequence) {
1753 std::vector<ASIdOrRange> as_ranges;
1754 from.decode_list(as_ranges);
1755
1756 m_as_ranges = sort_and_merge_ranges<ASIdOrRange>(as_ranges);
1757 } else {
1758 throw Decoding_Error(fmt("Unexpected type for ASIdentifierChoice {}", static_cast<uint32_t>(next_tag)));
1759 }
1760}
1761
1763 if(m_min == m_max) {
1764 into.encode(static_cast<size_t>(m_min));
1765 } else {
1766 if(m_min >= m_max) {
1767 throw Encoding_Error("AS range numbers must be sorted");
1768 }
1769 into.start_sequence().encode(static_cast<size_t>(m_min)).encode(static_cast<size_t>(m_max)).end_cons();
1770 }
1771}
1772
1774 const ASN1_Type next_tag = from.peek_next_object().type_tag();
1775
1776 size_t min = 0;
1777 size_t max = 0;
1778
1779 if(next_tag == ASN1_Type::Integer) {
1780 from.decode(min);
1782 m_max = m_min;
1783 } else if(next_tag == ASN1_Type::Sequence) {
1787 if(m_min >= m_max) {
1788 throw Decoding_Error("ASIdOrRange has min greater than max");
1789 }
1790 } else {
1791 throw Decoding_Error(fmt("Unexpected type for ASIdOrRange {}", static_cast<uint32_t>(next_tag)));
1792 }
1793}
1794
1795void ASBlocks::validate(const X509_Certificate& /* unused */,
1796 const std::optional<X509_Certificate>& /* unused */,
1797 const std::vector<X509_Certificate>& cert_path,
1798 std::vector<std::set<Certificate_Status_Code>>& cert_status,
1799 size_t pos) {
1800 // the extension may not contain asnums or rdis, but one of them is always present
1801 const bool asnum_present = m_as_identifiers.asnum().has_value();
1802 const bool rdi_present = m_as_identifiers.rdi().has_value();
1803
1804 if(!asnum_present && !rdi_present) {
1805 // Invalid, should have been caught during decoding
1806 cert_status.at(pos).insert(Certificate_Status_Code::AS_BLOCKS_ERROR);
1807 return;
1808 }
1809
1810 bool asnum_needs_check = asnum_present ? m_as_identifiers.asnum().value().ranges().has_value() : false;
1811 bool rdi_needs_check = rdi_present ? m_as_identifiers.rdi().value().ranges().has_value() : false;
1812
1813 // we are at the (trusted) root cert, there is no parent to verify against
1814 if(pos == cert_path.size() - 1) {
1815 // asnum / rdi is present, but has 'inherit' value, but there is nothing to inherit from
1816 if((asnum_present && !asnum_needs_check) || (rdi_present && !rdi_needs_check)) {
1817 cert_status.at(pos).insert(Certificate_Status_Code::AS_BLOCKS_ERROR);
1818 }
1819 return;
1820 }
1821
1822 // traverse the chain until we find a cert with concrete values for the extension (so not 'inherit')
1823 for(auto it = cert_path.begin() + pos + 1; it != cert_path.end(); it++) {
1824 const ASBlocks* const parent_as = it->v3_extensions().get_extension_object_as<ASBlocks>();
1825 // no extension at all or no asnums or no rdis (if needed)
1826 if(parent_as == nullptr || (asnum_present && !parent_as->as_identifiers().asnum().has_value()) ||
1827 (rdi_present && !parent_as->as_identifiers().rdi().has_value())) {
1828 cert_status.at(pos).insert(Certificate_Status_Code::AS_BLOCKS_ERROR);
1829 return;
1830 }
1831 const auto as_identifiers = parent_as->as_identifiers();
1832
1833 // only something to validate if the subject does not have 'inherit' as a value
1834 if(asnum_needs_check && as_identifiers.asnum().value().ranges().has_value()) {
1835 const std::vector<ASBlocks::ASIdOrRange>& subject_asnums = m_as_identifiers.asnum()->ranges().value();
1836 const std::vector<ASBlocks::ASIdOrRange>& issuer_asnums = as_identifiers.asnum()->ranges().value();
1837
1838 if(!validate_subject_in_issuer<ASBlocks::ASIdOrRange>(subject_asnums, issuer_asnums)) {
1839 cert_status.at(pos).insert(Certificate_Status_Code::AS_BLOCKS_ERROR);
1840 return;
1841 }
1842 // successfully validated the asnums, but we may need to step further for rdis
1843 asnum_needs_check = false;
1844 }
1845
1846 if(rdi_needs_check && as_identifiers.rdi().value().ranges().has_value()) {
1847 const std::vector<ASBlocks::ASIdOrRange>& subject_rdis = m_as_identifiers.rdi()->ranges().value();
1848 const std::vector<ASBlocks::ASIdOrRange>& issuer_rdis = as_identifiers.rdi()->ranges().value();
1849
1850 if(!validate_subject_in_issuer<ASBlocks::ASIdOrRange>(subject_rdis, issuer_rdis)) {
1851 cert_status.at(pos).insert(Certificate_Status_Code::AS_BLOCKS_ERROR);
1852 return;
1853 }
1854 // successfully validated the rdis, but we may need to step further for asnums
1855 rdi_needs_check = false;
1856 }
1857
1858 if(!asnum_needs_check && !rdi_needs_check) {
1859 // we've validated what we need to and can stop traversing the cert chain
1860 return;
1861 }
1862 }
1863}
1864
1865std::vector<uint8_t> OCSP_NoCheck::encode_inner() const {
1866 return {0x05, 0x00}; // NULL
1867}
1868
1869void OCSP_NoCheck::decode_inner(const std::vector<uint8_t>& buf) {
1870 /* RFC 6960 Section 4.2.2.2.1 - id-pkix-ocsp-nocheck (value SHALL be NULL) */
1871 BER_Decoder(buf, BER_Decoder::Limits::DER()).decode_null().verify_end();
1872}
1873
1874std::vector<uint8_t> Unknown_Extension::encode_inner() const {
1875 return m_bytes;
1876}
1877
1878void Unknown_Extension::decode_inner(const std::vector<uint8_t>& bytes) {
1879 // Just treat as an opaque blob at this level
1880 m_bytes = bytes;
1881}
1882
1883} // namespace Cert_Extension
1884
1885} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:129
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
const std::string & value() const
Definition asn1_obj.h:365
static Limits DER()
Definition ber_dec.h:35
const BER_Object & peek_next_object()
Definition ber_dec.cpp:415
BER_Object get_next_object()
Definition ber_dec.cpp:426
BER_Decoder & decode(bool &out)
Definition ber_dec.h:220
bool more_items() const
Definition ber_dec.cpp:371
Limits limits() const
Definition ber_dec.h:98
BER_Decoder & verify_end()
Definition ber_dec.cpp:381
BER_Decoder & end_cons()
Definition ber_dec.cpp:524
BER_Decoder & decode_list(std::vector< T > &out, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:430
BER_Decoder & discard_remaining()
Definition ber_dec.cpp:398
BER_Decoder start_sequence()
Definition ber_dec.h:160
BER_Decoder start_context_specific(uint32_t tag)
Definition ber_dec.h:164
BER_Decoder & decode_optional(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value=T())
Definition ber_dec.h:285
BER_Decoder & decode_null()
Definition ber_dec.cpp:568
BER_Decoder & decode_optional_string(std::vector< uint8_t, Alloc > &out, ASN1_Type real_type, uint32_t expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:329
BER_Decoder & decode_optional_implicit(T &out, ASN1_Type type_tag, ASN1_Class class_tag, ASN1_Type real_type, ASN1_Class real_class, const T &default_value=T())
Definition ber_dec.h:405
bool is_a(ASN1_Type type_tag, ASN1_Class class_tag) const
Definition asn1_obj.cpp:66
ASN1_Type type_tag() const
Definition asn1_obj.h:142
ASN1_Class get_class() const
Definition asn1_obj.h:148
void encode_into(DER_Encoder &to) const override
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:842
const std::optional< ASIdentifierChoice > & asnum() const
Definition x509_ext.h:861
const std::optional< ASIdentifierChoice > & rdi() const
Definition x509_ext.h:863
void encode_into(DER_Encoder &to) const override
void decode_from(BER_Decoder &from) override
const ASIdentifiers & as_identifiers() const
Definition x509_ext.h:923
void validate(const X509_Certificate &subject, const std::optional< X509_Certificate > &issuer, const std::vector< X509_Certificate > &cert_path, std::vector< std::set< Certificate_Status_Code > > &cert_status, size_t pos) override
BOTAN_FUTURE_EXPLICIT Basic_Constraints(bool is_ca=false, size_t path_length_constraint=0)
Definition x509_ext.cpp:320
std::optional< size_t > path_length_constraint() const
Definition x509_ext.h:53
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.cpp:821
void validate(const X509_Certificate &subject, const std::optional< X509_Certificate > &issuer, const std::vector< X509_Certificate > &cert_path, std::vector< std::set< Certificate_Status_Code > > &cert_status, size_t pos) override
Definition x509_ext.cpp:728
void encode_into(DER_Encoder &to) const override
void encode_into(DER_Encoder &to) const override
std::variant< IPAddressChoice< Version::IPv4 >, IPAddressChoice< Version::IPv6 > > AddrChoice
Definition x509_ext.h:704
void encode_into(DER_Encoder &to) const override
void validate(const X509_Certificate &subject, const std::optional< X509_Certificate > &issuer, const std::vector< X509_Certificate > &cert_path, std::vector< std::set< Certificate_Status_Code > > &cert_status, size_t pos) override
const std::vector< IPAddressFamily > & addr_blocks() const
Definition x509_ext.h:782
void validate(const X509_Certificate &subject, const std::optional< X509_Certificate > &issuer, const std::vector< X509_Certificate > &cert_path, std::vector< std::set< Certificate_Status_Code > > &cert_status, size_t pos) override
Definition x509_ext.cpp:634
const std::string & service_provider_code() const
const std::string & telephone_number() const
std::vector< TelephoneNumberRangeData > RangeContainer
Definition x509_ext.h:556
void decode_from(class BER_Decoder &from) override
Definition x509_ext.cpp:955
void encode_into(DER_Encoder &to) const override
Definition x509_ext.cpp:951
const RangeContainer & telephone_number_range() const
virtual std::vector< uint8_t > encode_inner() const =0
virtual void validate(const X509_Certificate &subject, const std::optional< X509_Certificate > &issuer, const std::vector< X509_Certificate > &cert_path, std::vector< std::set< Certificate_Status_Code > > &cert_status, size_t pos)
Definition x509_ext.cpp:157
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length)
Definition der_enc.cpp:217
DER_Encoder & end_explicit()
Definition der_enc.cpp:195
DER_Encoder & encode_optional(const T &value, const T &default_value)
Definition der_enc.h:124
DER_Encoder & encode_list(const std::vector< T > &values)
Definition der_enc.h:140
DER_Encoder & start_explicit(uint16_t type_tag)
Definition der_enc.cpp:188
DER_Encoder & start_sequence()
Definition der_enc.h:67
DER_Encoder & start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition der_enc.cpp:165
DER_Encoder & encode_null()
Definition der_enc.cpp:238
DER_Encoder & end_cons()
Definition der_enc.cpp:173
DER_Encoder & encode(bool b)
Definition der_enc.cpp:245
const Certificate_Extension * get_extension_object(const OID &oid) const
Definition x509_ext.cpp:232
std::map< OID, std::pair< std::vector< uint8_t >, bool > > extensions_raw() const
Definition x509_ext.cpp:257
std::vector< OID > critical_extensions() const
Definition x509_ext.cpp:109
std::unique_ptr< Certificate_Extension > get(const OID &oid) const
Definition x509_ext.cpp:241
void decode_from(BER_Decoder &from) override
Definition x509_ext.cpp:288
bool remove(const OID &oid)
Definition x509_ext.cpp:191
std::vector< uint8_t > get_extension_bits(const OID &oid) const
Definition x509_ext.cpp:223
bool critical_extension_set(const OID &oid) const
Definition x509_ext.cpp:215
std::vector< std::pair< std::unique_ptr< Certificate_Extension >, bool > > extensions() const
Definition x509_ext.cpp:248
void encode_into(DER_Encoder &to) const override
Definition x509_ext.cpp:268
void replace(std::unique_ptr< Certificate_Extension > extn, bool critical=false)
Definition x509_ext.cpp:201
bool add_new(std::unique_ptr< Certificate_Extension > extn, bool critical=false)
Definition x509_ext.cpp:179
bool extension_set(const OID &oid) const
Definition x509_ext.cpp:211
void add(std::unique_ptr< Certificate_Extension > extn, bool critical=false)
Definition x509_ext.cpp:166
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:308
static OID from_string(std::string_view str)
Definition asn1_oid.cpp:86
bool is_CA_cert() const
Definition x509cert.cpp:441
bool is_critical(std::string_view ex_name) const
Definition x509cert.cpp:571
std::string to_string(const BER_Object &obj)
Definition asn1_obj.cpp:190
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
ASN1_Type
Definition asn1_obj.h:43
constexpr RT checked_cast_to(AT i)
Definition int_utils.h:74
std::optional< uint32_t > is_sub_element_of(const OID &oid, std::initializer_list< uint32_t > prefix)
Definition x509_utils.h:16
BOTAN_FORCE_INLINE constexpr size_t ctz(T n)
Definition bit_ops.h:115
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition loadstor.h:92