Botan 3.7.1
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*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_X509_EXTENSIONS_H_
9#define BOTAN_X509_EXTENSIONS_H_
10
11#include <botan/pkix_types.h>
12
13#include <botan/assert.h>
14#include <set>
15
16namespace Botan {
17
18class X509_Certificate;
19
20namespace Cert_Extension {
21
22static const size_t NO_CERT_PATH_LIMIT = 0xFFFFFFF0;
23
24/**
25* Basic Constraints Extension
26*/
28 public:
29 std::unique_ptr<Certificate_Extension> copy() const override {
30 return std::make_unique<Basic_Constraints>(m_is_ca, m_path_limit);
31 }
32
33 Basic_Constraints(bool ca = false, size_t limit = 0) : m_is_ca(ca), m_path_limit(limit) {}
34
35 bool get_is_ca() const { return m_is_ca; }
36
37 size_t get_path_limit() const;
38
39 static OID static_oid() { return OID("2.5.29.19"); }
40
41 OID oid_of() const override { return static_oid(); }
42
43 private:
44 std::string oid_name() const override { return "X509v3.BasicConstraints"; }
45
46 std::vector<uint8_t> encode_inner() const override;
47 void decode_inner(const std::vector<uint8_t>&) override;
48
49 bool m_is_ca;
50 size_t m_path_limit;
51};
52
53/**
54* Key Usage Constraints Extension
55*/
57 public:
58 std::unique_ptr<Certificate_Extension> copy() const override {
59 return std::make_unique<Key_Usage>(m_constraints);
60 }
61
62 explicit Key_Usage(Key_Constraints c) : m_constraints(c) {}
63
64 explicit Key_Usage() : m_constraints(Key_Constraints::None) {}
65
66 Key_Constraints get_constraints() const { return m_constraints; }
67
68 static OID static_oid() { return OID("2.5.29.15"); }
69
70 OID oid_of() const override { return static_oid(); }
71
72 private:
73 std::string oid_name() const override { return "X509v3.KeyUsage"; }
74
75 bool should_encode() const override { return !m_constraints.empty(); }
76
77 std::vector<uint8_t> encode_inner() const override;
78 void decode_inner(const std::vector<uint8_t>&) override;
79
80 Key_Constraints m_constraints;
81};
82
83/**
84* Subject Key Identifier Extension
85*/
87 public:
88 Subject_Key_ID() = default;
89
90 explicit Subject_Key_ID(const std::vector<uint8_t>& k) : m_key_id(k) {}
91
92 Subject_Key_ID(const std::vector<uint8_t>& public_key, std::string_view hash_fn);
93
94 std::unique_ptr<Certificate_Extension> copy() const override {
95 return std::make_unique<Subject_Key_ID>(m_key_id);
96 }
97
98 const std::vector<uint8_t>& get_key_id() const { return m_key_id; }
99
100 static OID static_oid() { return OID("2.5.29.14"); }
101
102 OID oid_of() const override { return static_oid(); }
103
104 private:
105 std::string oid_name() const override { return "X509v3.SubjectKeyIdentifier"; }
106
107 bool should_encode() const override { return (!m_key_id.empty()); }
108
109 std::vector<uint8_t> encode_inner() const override;
110 void decode_inner(const std::vector<uint8_t>&) override;
111
112 std::vector<uint8_t> m_key_id;
113};
114
115/**
116* Authority Key Identifier Extension
117*/
119 public:
120 std::unique_ptr<Certificate_Extension> copy() const override {
121 return std::make_unique<Authority_Key_ID>(m_key_id);
122 }
123
124 Authority_Key_ID() = default;
125
126 explicit Authority_Key_ID(const std::vector<uint8_t>& k) : m_key_id(k) {}
127
128 const std::vector<uint8_t>& get_key_id() const { return m_key_id; }
129
130 static OID static_oid() { return OID("2.5.29.35"); }
131
132 OID oid_of() const override { return static_oid(); }
133
134 private:
135 std::string oid_name() const override { return "X509v3.AuthorityKeyIdentifier"; }
136
137 bool should_encode() const override { return (!m_key_id.empty()); }
138
139 std::vector<uint8_t> encode_inner() const override;
140 void decode_inner(const std::vector<uint8_t>&) override;
141
142 std::vector<uint8_t> m_key_id;
143};
144
145/**
146* Subject Alternative Name Extension
147*/
149 public:
150 const AlternativeName& get_alt_name() const { return m_alt_name; }
151
152 static OID static_oid() { return OID("2.5.29.17"); }
153
154 OID oid_of() const override { return static_oid(); }
155
156 std::unique_ptr<Certificate_Extension> copy() const override {
157 return std::make_unique<Subject_Alternative_Name>(get_alt_name());
158 }
159
161
162 private:
163 std::string oid_name() const override { return "X509v3.SubjectAlternativeName"; }
164
165 bool should_encode() const override { return m_alt_name.has_items(); }
166
167 std::vector<uint8_t> encode_inner() const override;
168 void decode_inner(const std::vector<uint8_t>&) override;
169
170 AlternativeName m_alt_name;
171};
172
173/**
174* Issuer Alternative Name Extension
175*/
177 public:
178 const AlternativeName& get_alt_name() const { return m_alt_name; }
179
180 static OID static_oid() { return OID("2.5.29.18"); }
181
182 OID oid_of() const override { return static_oid(); }
183
184 std::unique_ptr<Certificate_Extension> copy() const override {
185 return std::make_unique<Issuer_Alternative_Name>(get_alt_name());
186 }
187
189
190 private:
191 std::string oid_name() const override { return "X509v3.IssuerAlternativeName"; }
192
193 bool should_encode() const override { return m_alt_name.has_items(); }
194
195 std::vector<uint8_t> encode_inner() const override;
196 void decode_inner(const std::vector<uint8_t>&) override;
197
198 AlternativeName m_alt_name;
199};
200
201/**
202* Extended Key Usage Extension
203*/
205 public:
206 std::unique_ptr<Certificate_Extension> copy() const override {
207 return std::make_unique<Extended_Key_Usage>(m_oids);
208 }
209
211
212 explicit Extended_Key_Usage(const std::vector<OID>& o) : m_oids(o) {}
213
214 const std::vector<OID>& object_identifiers() const { return m_oids; }
215
216 static OID static_oid() { return OID("2.5.29.37"); }
217
218 OID oid_of() const override { return static_oid(); }
219
220 private:
221 std::string oid_name() const override { return "X509v3.ExtendedKeyUsage"; }
222
223 bool should_encode() const override { return (!m_oids.empty()); }
224
225 std::vector<uint8_t> encode_inner() const override;
226 void decode_inner(const std::vector<uint8_t>&) override;
227
228 std::vector<OID> m_oids;
229};
230
231/**
232* Name Constraints
233*/
235 public:
236 std::unique_ptr<Certificate_Extension> copy() const override {
237 return std::make_unique<Name_Constraints>(m_name_constraints);
238 }
239
240 Name_Constraints() = default;
241
242 Name_Constraints(const NameConstraints& nc) : m_name_constraints(nc) {}
243
244 void validate(const X509_Certificate& subject,
245 const X509_Certificate& issuer,
246 const std::vector<X509_Certificate>& cert_path,
247 std::vector<std::set<Certificate_Status_Code>>& cert_status,
248 size_t pos) override;
249
250 const NameConstraints& get_name_constraints() const { return m_name_constraints; }
251
252 static OID static_oid() { return OID("2.5.29.30"); }
253
254 OID oid_of() const override { return static_oid(); }
255
256 private:
257 std::string oid_name() const override { return "X509v3.NameConstraints"; }
258
259 bool should_encode() const override { return true; }
260
261 std::vector<uint8_t> encode_inner() const override;
262 void decode_inner(const std::vector<uint8_t>&) override;
263
264 NameConstraints m_name_constraints;
265};
266
267/**
268* Certificate Policies Extension
269*/
271 public:
272 std::unique_ptr<Certificate_Extension> copy() const override {
273 return std::make_unique<Certificate_Policies>(m_oids);
274 }
275
277
278 explicit Certificate_Policies(const std::vector<OID>& o) : m_oids(o) {}
279
280 const std::vector<OID>& get_policy_oids() const { return m_oids; }
281
282 static OID static_oid() { return OID("2.5.29.32"); }
283
284 OID oid_of() const override { return static_oid(); }
285
286 void validate(const X509_Certificate& subject,
287 const X509_Certificate& issuer,
288 const std::vector<X509_Certificate>& cert_path,
289 std::vector<std::set<Certificate_Status_Code>>& cert_status,
290 size_t pos) override;
291
292 private:
293 std::string oid_name() const override { return "X509v3.CertificatePolicies"; }
294
295 bool should_encode() const override { return (!m_oids.empty()); }
296
297 std::vector<uint8_t> encode_inner() const override;
298 void decode_inner(const std::vector<uint8_t>&) override;
299
300 std::vector<OID> m_oids;
301};
302
303/**
304* Authority Information Access Extension
305*/
307 public:
308 std::unique_ptr<Certificate_Extension> copy() const override {
309 return std::make_unique<Authority_Information_Access>(m_ocsp_responder, m_ca_issuers);
310 }
311
313
314 explicit Authority_Information_Access(std::string_view ocsp,
315 const std::vector<std::string>& ca_issuers = std::vector<std::string>()) :
316 m_ocsp_responder(ocsp), m_ca_issuers(ca_issuers) {}
317
318 std::string ocsp_responder() const { return m_ocsp_responder; }
319
320 static OID static_oid() { return OID("1.3.6.1.5.5.7.1.1"); }
321
322 OID oid_of() const override { return static_oid(); }
323
324 const std::vector<std::string>& ca_issuers() const { return m_ca_issuers; }
325
326 private:
327 std::string oid_name() const override { return "PKIX.AuthorityInformationAccess"; }
328
329 bool should_encode() const override { return (!m_ocsp_responder.empty() || !m_ca_issuers.empty()); }
330
331 std::vector<uint8_t> encode_inner() const override;
332 void decode_inner(const std::vector<uint8_t>&) override;
333
334 std::string m_ocsp_responder;
335 std::vector<std::string> m_ca_issuers;
336};
337
338/**
339* CRL Number Extension
340*/
342 public:
343 std::unique_ptr<Certificate_Extension> copy() const override;
344
345 CRL_Number() : m_has_value(false), m_crl_number(0) {}
346
347 CRL_Number(size_t n) : m_has_value(true), m_crl_number(n) {}
348
349 size_t get_crl_number() const;
350
351 static OID static_oid() { return OID("2.5.29.20"); }
352
353 OID oid_of() const override { return static_oid(); }
354
355 private:
356 std::string oid_name() const override { return "X509v3.CRLNumber"; }
357
358 bool should_encode() const override { return m_has_value; }
359
360 std::vector<uint8_t> encode_inner() const override;
361 void decode_inner(const std::vector<uint8_t>&) override;
362
363 bool m_has_value;
364 size_t m_crl_number;
365};
366
367/**
368* CRL Entry Reason Code Extension
369*/
371 public:
372 std::unique_ptr<Certificate_Extension> copy() const override {
373 return std::make_unique<CRL_ReasonCode>(m_reason);
374 }
375
376 explicit CRL_ReasonCode(CRL_Code r = CRL_Code::Unspecified) : m_reason(r) {}
377
378 CRL_Code get_reason() const { return m_reason; }
379
380 static OID static_oid() { return OID("2.5.29.21"); }
381
382 OID oid_of() const override { return static_oid(); }
383
384 private:
385 std::string oid_name() const override { return "X509v3.ReasonCode"; }
386
387 bool should_encode() const override { return (m_reason != CRL_Code::Unspecified); }
388
389 std::vector<uint8_t> encode_inner() const override;
390 void decode_inner(const std::vector<uint8_t>&) override;
391
392 CRL_Code m_reason;
393};
394
395/**
396* CRL Distribution Points Extension
397* todo enforce restrictions from RFC 5280 4.2.1.13
398*/
400 public:
402 public:
403 void encode_into(DER_Encoder&) const override;
404 void decode_from(BER_Decoder&) override;
405
406 explicit Distribution_Point(const AlternativeName& name = AlternativeName()) : m_point(name) {}
407
408 const AlternativeName& point() const { return m_point; }
409
410 private:
411 AlternativeName m_point;
412 };
413
414 std::unique_ptr<Certificate_Extension> copy() const override {
415 return std::make_unique<CRL_Distribution_Points>(m_distribution_points);
416 }
417
419
420 explicit CRL_Distribution_Points(const std::vector<Distribution_Point>& points) : m_distribution_points(points) {}
421
422 const std::vector<Distribution_Point>& distribution_points() const { return m_distribution_points; }
423
424 const std::vector<std::string>& crl_distribution_urls() const { return m_crl_distribution_urls; }
425
426 static OID static_oid() { return OID("2.5.29.31"); }
427
428 OID oid_of() const override { return static_oid(); }
429
430 private:
431 std::string oid_name() const override { return "X509v3.CRLDistributionPoints"; }
432
433 bool should_encode() const override { return !m_distribution_points.empty(); }
434
435 std::vector<uint8_t> encode_inner() const override;
436 void decode_inner(const std::vector<uint8_t>&) override;
437
438 std::vector<Distribution_Point> m_distribution_points;
439 std::vector<std::string> m_crl_distribution_urls;
440};
441
442/**
443* CRL Issuing Distribution Point Extension
444* todo enforce restrictions from RFC 5280 5.2.5
445*/
447 public:
449
451 m_distribution_point(distribution_point) {}
452
453 std::unique_ptr<Certificate_Extension> copy() const override {
454 return std::make_unique<CRL_Issuing_Distribution_Point>(m_distribution_point);
455 }
456
457 const AlternativeName& get_point() const { return m_distribution_point.point(); }
458
459 static OID static_oid() { return OID("2.5.29.28"); }
460
461 OID oid_of() const override { return static_oid(); }
462
463 private:
464 std::string oid_name() const override { return "X509v3.CRLIssuingDistributionPoint"; }
465
466 bool should_encode() const override { return true; }
467
468 std::vector<uint8_t> encode_inner() const override;
469 void decode_inner(const std::vector<uint8_t>&) override;
470
471 CRL_Distribution_Points::Distribution_Point m_distribution_point;
472};
473
474/**
475* OCSP NoCheck Extension
476*
477* RFC6960 4.2.2.2.1
478* A CA may specify that an OCSP client can trust a responder for the
479* lifetime of the responder's certificate. The CA does so by
480* including the extension id-pkix-ocsp-nocheck.
481*
482* In other words: OCSP responder certificates with this extension do not need
483* to be validated against some revocation info.
484*/
486 public:
487 OCSP_NoCheck() = default;
488
489 std::unique_ptr<Certificate_Extension> copy() const override { return std::make_unique<OCSP_NoCheck>(); }
490
491 static OID static_oid() { return OID("1.3.6.1.5.5.7.48.1.5"); }
492
493 OID oid_of() const override { return static_oid(); }
494
495 private:
496 std::string oid_name() const override { return "PKIX.OCSP.NoCheck"; }
497
498 bool should_encode() const override { return true; }
499
500 std::vector<uint8_t> encode_inner() const override { return {}; }
501
502 void decode_inner(const std::vector<uint8_t>&) override;
503};
504
505/**
506* TNAuthList extension
507*
508* RFC8226 Secure Telephone Identity Credentials
509* https://www.rfc-editor.org/rfc/rfc8226#section-9
510*/
512 public:
513 class Entry final : public ASN1_Object {
514 public:
515 /* TNEntry choice values
516 * see: https://datatracker.ietf.org/doc/html/rfc8226#section-9 */
517 enum Type { ServiceProviderCode = 0, TelephoneNumberRange = 1, TelephoneNumber = 2 };
518
520 ASN1_String start; //TelephoneNumber (IA5String)
521 size_t count; //2..MAX
522 };
523
524 using RangeContainer = std::vector<TelephoneNumberRangeData>;
525 using DataContainer = std::variant<ASN1_String, RangeContainer>;
526
527 void encode_into(DER_Encoder&) const override;
528 void decode_from(class BER_Decoder& from) override;
529
530 Type type() const { return m_type; }
531
532 const std::string& service_provider_code() const {
533 BOTAN_STATE_CHECK(type() == Type::ServiceProviderCode);
534 return std::get<ASN1_String>(m_data).value();
535 }
536
538 BOTAN_STATE_CHECK(type() == Type::TelephoneNumberRange);
539 return std::get<RangeContainer>(m_data);
540 }
541
542 const std::string& telephone_number() const {
543 BOTAN_STATE_CHECK(type() == Type::TelephoneNumber);
544 return std::get<ASN1_String>(m_data).value();
545 }
546
547 private:
548 Type m_type;
549 DataContainer m_data;
550 };
551
552 TNAuthList() = default;
553
554 std::unique_ptr<Certificate_Extension> copy() const override { return std::make_unique<TNAuthList>(*this); }
555
556 static OID static_oid() { return OID("1.3.6.1.5.5.7.1.26"); }
557
558 OID oid_of() const override { return static_oid(); }
559
560 const std::vector<Entry>& entries() const { return m_tn_entries; }
561
562 private:
563 std::string oid_name() const override { return "PKIX.TNAuthList"; }
564
565 bool should_encode() const override { return true; }
566
567 std::vector<uint8_t> encode_inner() const override;
568 void decode_inner(const std::vector<uint8_t>&) override;
569
570 std::vector<Entry> m_tn_entries;
571};
572
573/**
574* An unknown X.509 extension
575* Will add a failure to the path validation result, if critical
576*/
578 public:
579 Unknown_Extension(const OID& oid, bool critical) : m_oid(oid), m_critical(critical) {}
580
581 std::unique_ptr<Certificate_Extension> copy() const override {
582 return std::make_unique<Unknown_Extension>(m_oid, m_critical);
583 }
584
585 /**
586 * Return the OID of this unknown extension
587 */
588 OID oid_of() const override { return m_oid; }
589
590 //static_oid not defined for Unknown_Extension
591
592 /**
593 * Return the extension contents
594 */
595 const std::vector<uint8_t>& extension_contents() const { return m_bytes; }
596
597 /**
598 * Return if this extension was marked critical
599 */
600 bool is_critical_extension() const { return m_critical; }
601
603 const X509_Certificate&,
604 const std::vector<X509_Certificate>&,
605 std::vector<std::set<Certificate_Status_Code>>& cert_status,
606 size_t pos) override {
607 if(m_critical) {
608 cert_status.at(pos).insert(Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION);
609 }
610 }
611
612 private:
613 std::string oid_name() const override { return ""; }
614
615 bool should_encode() const override { return true; }
616
617 std::vector<uint8_t> encode_inner() const override;
618 void decode_inner(const std::vector<uint8_t>&) override;
619
620 OID m_oid;
621 bool m_critical;
622 std::vector<uint8_t> m_bytes;
623};
624
625} // namespace Cert_Extension
626
627} // namespace Botan
628
629#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:19
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:41
Authority_Information_Access(std::string_view ocsp, const std::vector< std::string > &ca_issuers=std::vector< std::string >())
Definition x509_ext.h:314
const std::vector< std::string > & ca_issuers() const
Definition x509_ext.h:324
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:308
Authority_Key_ID(const std::vector< uint8_t > &k)
Definition x509_ext.h:126
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:120
const std::vector< uint8_t > & get_key_id() const
Definition x509_ext.h:128
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:29
Basic_Constraints(bool ca=false, size_t limit=0)
Definition x509_ext.h:33
Distribution_Point(const AlternativeName &name=AlternativeName())
Definition x509_ext.h:406
CRL_Distribution_Points(const std::vector< Distribution_Point > &points)
Definition x509_ext.h:420
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:414
const std::vector< std::string > & crl_distribution_urls() const
Definition x509_ext.h:424
const std::vector< Distribution_Point > & distribution_points() const
Definition x509_ext.h:422
const AlternativeName & get_point() const
Definition x509_ext.h:457
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:453
CRL_Issuing_Distribution_Point(const CRL_Distribution_Points::Distribution_Point &distribution_point)
Definition x509_ext.h:450
OID oid_of() const override
Definition x509_ext.h:353
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:372
CRL_ReasonCode(CRL_Code r=CRL_Code::Unspecified)
Definition x509_ext.h:376
const std::vector< OID > & get_policy_oids() const
Definition x509_ext.h:280
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:272
Certificate_Policies(const std::vector< OID > &o)
Definition x509_ext.h:278
const std::vector< OID > & object_identifiers() const
Definition x509_ext.h:214
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:206
Extended_Key_Usage(const std::vector< OID > &o)
Definition x509_ext.h:212
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:184
const AlternativeName & get_alt_name() const
Definition x509_ext.h:178
Issuer_Alternative_Name(const AlternativeName &name=AlternativeName())
Definition x509_ext.h:188
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:58
OID oid_of() const override
Definition x509_ext.h:70
Key_Usage(Key_Constraints c)
Definition x509_ext.h:62
Key_Constraints get_constraints() const
Definition x509_ext.h:66
Name_Constraints(const NameConstraints &nc)
Definition x509_ext.h:242
const NameConstraints & get_name_constraints() const
Definition x509_ext.h:250
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:236
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:489
OID oid_of() const override
Definition x509_ext.h:493
const AlternativeName & get_alt_name() const
Definition x509_ext.h:150
Subject_Alternative_Name(const AlternativeName &name=AlternativeName())
Definition x509_ext.h:160
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:156
Subject_Key_ID(const std::vector< uint8_t > &k)
Definition x509_ext.h:90
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:94
const std::vector< uint8_t > & get_key_id() const
Definition x509_ext.h:98
const std::string & service_provider_code() const
Definition x509_ext.h:532
const std::string & telephone_number() const
Definition x509_ext.h:542
const RangeContainer & telephone_number_range() const
Definition x509_ext.h:537
std::vector< TelephoneNumberRangeData > RangeContainer
Definition x509_ext.h:524
std::variant< ASN1_String, RangeContainer > DataContainer
Definition x509_ext.h:525
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:554
OID oid_of() const override
Definition x509_ext.h:558
const std::vector< Entry > & entries() const
Definition x509_ext.h:560
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:602
std::unique_ptr< Certificate_Extension > copy() const override
Definition x509_ext.h:581
Unknown_Extension(const OID &oid, bool critical)
Definition x509_ext.h:579
const std::vector< uint8_t > & extension_contents() const
Definition x509_ext.h:595
Name Constraints.
Definition pkix_types.h:360
std::string name
int(* final)(unsigned char *, CTX *)