/src/botan/build/include/botan/x509_ext.h
Line | Count | Source (jump to first uncovered line) |
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 | | #include <set> |
13 | | |
14 | | namespace Botan { |
15 | | |
16 | | class X509_Certificate; |
17 | | |
18 | | namespace Cert_Extension { |
19 | | |
20 | | static const size_t NO_CERT_PATH_LIMIT = 0xFFFFFFF0; |
21 | | |
22 | | /** |
23 | | * Basic Constraints Extension |
24 | | */ |
25 | | class BOTAN_PUBLIC_API(2,0) Basic_Constraints final : public Certificate_Extension |
26 | | { |
27 | | public: |
28 | | Basic_Constraints* copy() const override |
29 | 0 | { return new Basic_Constraints(m_is_ca, m_path_limit); } |
30 | | |
31 | | Basic_Constraints(bool ca = false, size_t limit = 0) : |
32 | 1.73k | m_is_ca(ca), m_path_limit(limit) {} |
33 | | |
34 | 149 | bool get_is_ca() const { return m_is_ca; } |
35 | | size_t get_path_limit() const; |
36 | | |
37 | 45.9k | static OID static_oid() { return OID("2.5.29.19"); } |
38 | 0 | OID oid_of() const override { return static_oid(); } |
39 | | |
40 | | private: |
41 | | std::string oid_name() const override |
42 | 149 | { return "X509v3.BasicConstraints"; } |
43 | | |
44 | | std::vector<uint8_t> encode_inner() const override; |
45 | | void decode_inner(const std::vector<uint8_t>&) override; |
46 | | |
47 | | bool m_is_ca; |
48 | | size_t m_path_limit; |
49 | | }; |
50 | | |
51 | | /** |
52 | | * Key Usage Constraints Extension |
53 | | */ |
54 | | class BOTAN_PUBLIC_API(2,0) Key_Usage final : public Certificate_Extension |
55 | | { |
56 | | public: |
57 | 0 | Key_Usage* copy() const override { return new Key_Usage(m_constraints); } |
58 | | |
59 | 1.55k | explicit Key_Usage(Key_Constraints c = NO_CONSTRAINTS) : m_constraints(c) {} |
60 | | |
61 | 118 | Key_Constraints get_constraints() const { return m_constraints; } |
62 | | |
63 | 51.6k | static OID static_oid() { return OID("2.5.29.15"); } |
64 | 0 | OID oid_of() const override { return static_oid(); } |
65 | | |
66 | | private: |
67 | 118 | std::string oid_name() const override { return "X509v3.KeyUsage"; } |
68 | | |
69 | | bool should_encode() const override |
70 | 0 | { return (m_constraints != NO_CONSTRAINTS); } |
71 | | std::vector<uint8_t> encode_inner() const override; |
72 | | void decode_inner(const std::vector<uint8_t>&) override; |
73 | | |
74 | | Key_Constraints m_constraints; |
75 | | }; |
76 | | |
77 | | /** |
78 | | * Subject Key Identifier Extension |
79 | | */ |
80 | | class BOTAN_PUBLIC_API(2,0) Subject_Key_ID final : public Certificate_Extension |
81 | | { |
82 | | public: |
83 | 1.65k | Subject_Key_ID() = default; |
84 | | |
85 | 0 | explicit Subject_Key_ID(const std::vector<uint8_t>& k) : m_key_id(k) {} |
86 | | |
87 | | Subject_Key_ID(const std::vector<uint8_t>& public_key, |
88 | | const std::string& hash_fn); |
89 | | |
90 | | Subject_Key_ID* copy() const override |
91 | 0 | { return new Subject_Key_ID(m_key_id); } |
92 | | |
93 | 393 | const std::vector<uint8_t>& get_key_id() const { return m_key_id; } |
94 | | |
95 | 53.3k | static OID static_oid() { return OID("2.5.29.14"); } |
96 | 0 | OID oid_of() const override { return static_oid(); } |
97 | | |
98 | | private: |
99 | | |
100 | | std::string oid_name() const override |
101 | 393 | { return "X509v3.SubjectKeyIdentifier"; } |
102 | | |
103 | 0 | bool should_encode() const override { return (m_key_id.size() > 0); } |
104 | | std::vector<uint8_t> encode_inner() const override; |
105 | | void decode_inner(const std::vector<uint8_t>&) override; |
106 | | |
107 | | std::vector<uint8_t> m_key_id; |
108 | | }; |
109 | | |
110 | | /** |
111 | | * Authority Key Identifier Extension |
112 | | */ |
113 | | class BOTAN_PUBLIC_API(2,0) Authority_Key_ID final : public Certificate_Extension |
114 | | { |
115 | | public: |
116 | | Authority_Key_ID* copy() const override |
117 | 0 | { return new Authority_Key_ID(m_key_id); } |
118 | | |
119 | 1.64k | Authority_Key_ID() = default; |
120 | 0 | explicit Authority_Key_ID(const std::vector<uint8_t>& k) : m_key_id(k) {} |
121 | | |
122 | 538 | const std::vector<uint8_t>& get_key_id() const { return m_key_id; } |
123 | | |
124 | 40.9k | static OID static_oid() { return OID("2.5.29.35"); } |
125 | 0 | OID oid_of() const override { return static_oid(); } |
126 | | |
127 | | private: |
128 | | std::string oid_name() const override |
129 | 538 | { return "X509v3.AuthorityKeyIdentifier"; } |
130 | | |
131 | 0 | bool should_encode() const override { return (m_key_id.size() > 0); } |
132 | | std::vector<uint8_t> encode_inner() const override; |
133 | | void decode_inner(const std::vector<uint8_t>&) override; |
134 | | |
135 | | std::vector<uint8_t> m_key_id; |
136 | | }; |
137 | | |
138 | | /** |
139 | | * Subject Alternative Name Extension |
140 | | */ |
141 | | class BOTAN_PUBLIC_API(2,4) Subject_Alternative_Name final : public Certificate_Extension |
142 | | { |
143 | | public: |
144 | 303 | const AlternativeName& get_alt_name() const { return m_alt_name; } |
145 | | |
146 | 50.1k | static OID static_oid() { return OID("2.5.29.17"); } |
147 | 0 | OID oid_of() const override { return static_oid(); } |
148 | | |
149 | | Subject_Alternative_Name* copy() const override |
150 | 0 | { return new Subject_Alternative_Name(get_alt_name()); } |
151 | | |
152 | | explicit Subject_Alternative_Name(const AlternativeName& name = AlternativeName()) : |
153 | 2.64k | m_alt_name(name) {} |
154 | | |
155 | | private: |
156 | 303 | std::string oid_name() const override { return "X509v3.SubjectAlternativeName"; } |
157 | | |
158 | 0 | bool should_encode() const override { return m_alt_name.has_items(); } |
159 | | std::vector<uint8_t> encode_inner() const override; |
160 | | void decode_inner(const std::vector<uint8_t>&) override; |
161 | | |
162 | | AlternativeName m_alt_name; |
163 | | }; |
164 | | |
165 | | /** |
166 | | * Issuer Alternative Name Extension |
167 | | */ |
168 | | class BOTAN_PUBLIC_API(2,0) Issuer_Alternative_Name final : public Certificate_Extension |
169 | | { |
170 | | public: |
171 | 130 | const AlternativeName& get_alt_name() const { return m_alt_name; } |
172 | | |
173 | 47.4k | static OID static_oid() { return OID("2.5.29.18"); } |
174 | 0 | OID oid_of() const override { return static_oid(); } |
175 | | |
176 | | Issuer_Alternative_Name* copy() const override |
177 | 0 | { return new Issuer_Alternative_Name(get_alt_name()); } |
178 | | |
179 | | explicit Issuer_Alternative_Name(const AlternativeName& name = AlternativeName()) : |
180 | 1.52k | m_alt_name(name) {} |
181 | | |
182 | | private: |
183 | 130 | std::string oid_name() const override { return "X509v3.IssuerAlternativeName"; } |
184 | | |
185 | 0 | bool should_encode() const override { return m_alt_name.has_items(); } |
186 | | std::vector<uint8_t> encode_inner() const override; |
187 | | void decode_inner(const std::vector<uint8_t>&) override; |
188 | | |
189 | | AlternativeName m_alt_name; |
190 | | }; |
191 | | |
192 | | /** |
193 | | * Extended Key Usage Extension |
194 | | */ |
195 | | class BOTAN_PUBLIC_API(2,0) Extended_Key_Usage final : public Certificate_Extension |
196 | | { |
197 | | public: |
198 | | Extended_Key_Usage* copy() const override |
199 | 0 | { return new Extended_Key_Usage(m_oids); } |
200 | | |
201 | 1.15k | Extended_Key_Usage() = default; |
202 | 0 | explicit Extended_Key_Usage(const std::vector<OID>& o) : m_oids(o) {} |
203 | | |
204 | 105 | const std::vector<OID>& get_oids() const { return m_oids; } |
205 | | |
206 | 30.9k | static OID static_oid() { return OID("2.5.29.37"); } |
207 | 0 | OID oid_of() const override { return static_oid(); } |
208 | | |
209 | | private: |
210 | 105 | std::string oid_name() const override { return "X509v3.ExtendedKeyUsage"; } |
211 | | |
212 | 0 | bool should_encode() const override { return (m_oids.size() > 0); } |
213 | | std::vector<uint8_t> encode_inner() const override; |
214 | | void decode_inner(const std::vector<uint8_t>&) override; |
215 | | |
216 | | std::vector<OID> m_oids; |
217 | | }; |
218 | | |
219 | | /** |
220 | | * Name Constraints |
221 | | */ |
222 | | class BOTAN_PUBLIC_API(2,0) Name_Constraints final : public Certificate_Extension |
223 | | { |
224 | | public: |
225 | | Name_Constraints* copy() const override |
226 | 0 | { return new Name_Constraints(m_name_constraints); } |
227 | | |
228 | 4.13k | Name_Constraints() = default; |
229 | 0 | Name_Constraints(const NameConstraints &nc) : m_name_constraints(nc) {} |
230 | | |
231 | | void validate(const X509_Certificate& subject, const X509_Certificate& issuer, |
232 | | const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, |
233 | | std::vector<std::set<Certificate_Status_Code>>& cert_status, |
234 | | size_t pos) override; |
235 | | |
236 | 49 | const NameConstraints& get_name_constraints() const { return m_name_constraints; } |
237 | | |
238 | 38.8k | static OID static_oid() { return OID("2.5.29.30"); } |
239 | 0 | OID oid_of() const override { return static_oid(); } |
240 | | |
241 | | private: |
242 | | std::string oid_name() const override |
243 | 49 | { return "X509v3.NameConstraints"; } |
244 | | |
245 | 0 | bool should_encode() const override { return true; } |
246 | | std::vector<uint8_t> encode_inner() const override; |
247 | | void decode_inner(const std::vector<uint8_t>&) override; |
248 | | |
249 | | NameConstraints m_name_constraints; |
250 | | }; |
251 | | |
252 | | /** |
253 | | * Certificate Policies Extension |
254 | | */ |
255 | | class BOTAN_PUBLIC_API(2,0) Certificate_Policies final : public Certificate_Extension |
256 | | { |
257 | | public: |
258 | | Certificate_Policies* copy() const override |
259 | 0 | { return new Certificate_Policies(m_oids); } |
260 | | |
261 | 1.03k | Certificate_Policies() = default; |
262 | 0 | explicit Certificate_Policies(const std::vector<OID>& o) : m_oids(o) {} |
263 | | |
264 | 66 | const std::vector<OID>& get_policy_oids() const { return m_oids; } |
265 | | |
266 | 31.9k | static OID static_oid() { return OID("2.5.29.32"); } |
267 | 0 | OID oid_of() const override { return static_oid(); } |
268 | | |
269 | | void validate(const X509_Certificate& subject, const X509_Certificate& issuer, |
270 | | const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, |
271 | | std::vector<std::set<Certificate_Status_Code>>& cert_status, |
272 | | size_t pos) override; |
273 | | private: |
274 | | std::string oid_name() const override |
275 | 66 | { return "X509v3.CertificatePolicies"; } |
276 | | |
277 | 0 | bool should_encode() const override { return (m_oids.size() > 0); } |
278 | | std::vector<uint8_t> encode_inner() const override; |
279 | | void decode_inner(const std::vector<uint8_t>&) override; |
280 | | |
281 | | std::vector<OID> m_oids; |
282 | | }; |
283 | | |
284 | | /** |
285 | | * Authority Information Access Extension |
286 | | */ |
287 | | class BOTAN_PUBLIC_API(2,0) Authority_Information_Access final : public Certificate_Extension |
288 | | { |
289 | | public: |
290 | | Authority_Information_Access* copy() const override |
291 | 0 | { return new Authority_Information_Access(m_ocsp_responder, m_ca_issuers); } |
292 | | |
293 | 629 | Authority_Information_Access() = default; |
294 | | |
295 | | explicit Authority_Information_Access(const std::string& ocsp, const std::vector<std::string>& ca_issuers = std::vector<std::string>()) : |
296 | 0 | m_ocsp_responder(ocsp), m_ca_issuers(ca_issuers) {} |
297 | | |
298 | 64 | std::string ocsp_responder() const { return m_ocsp_responder; } |
299 | | |
300 | 29.7k | static OID static_oid() { return OID("1.3.6.1.5.5.7.1.1"); } |
301 | 0 | OID oid_of() const override { return static_oid(); } |
302 | 64 | const std::vector<std::string> ca_issuers() const { return m_ca_issuers; } |
303 | | |
304 | | private: |
305 | | std::string oid_name() const override |
306 | 64 | { return "PKIX.AuthorityInformationAccess"; } |
307 | | |
308 | 0 | bool should_encode() const override { return (!m_ocsp_responder.empty()); } |
309 | | |
310 | | std::vector<uint8_t> encode_inner() const override; |
311 | | void decode_inner(const std::vector<uint8_t>&) override; |
312 | | |
313 | | |
314 | | std::string m_ocsp_responder; |
315 | | std::vector<std::string> m_ca_issuers; |
316 | | }; |
317 | | |
318 | | /** |
319 | | * CRL Number Extension |
320 | | */ |
321 | | class BOTAN_PUBLIC_API(2,0) CRL_Number final : public Certificate_Extension |
322 | | { |
323 | | public: |
324 | | CRL_Number* copy() const override; |
325 | | |
326 | 818 | CRL_Number() : m_has_value(false), m_crl_number(0) {} |
327 | 0 | CRL_Number(size_t n) : m_has_value(true), m_crl_number(n) {} |
328 | | |
329 | | size_t get_crl_number() const; |
330 | | |
331 | 33.2k | static OID static_oid() { return OID("2.5.29.20"); } |
332 | 0 | OID oid_of() const override { return static_oid(); } |
333 | | |
334 | | private: |
335 | 2 | std::string oid_name() const override { return "X509v3.CRLNumber"; } |
336 | | |
337 | 0 | bool should_encode() const override { return m_has_value; } |
338 | | std::vector<uint8_t> encode_inner() const override; |
339 | | void decode_inner(const std::vector<uint8_t>&) override; |
340 | | |
341 | | bool m_has_value; |
342 | | size_t m_crl_number; |
343 | | }; |
344 | | |
345 | | /** |
346 | | * CRL Entry Reason Code Extension |
347 | | */ |
348 | | class BOTAN_PUBLIC_API(2,0) CRL_ReasonCode final : public Certificate_Extension |
349 | | { |
350 | | public: |
351 | | CRL_ReasonCode* copy() const override |
352 | 0 | { return new CRL_ReasonCode(m_reason); } |
353 | | |
354 | 2.93k | explicit CRL_ReasonCode(CRL_Code r = UNSPECIFIED) : m_reason(r) {} |
355 | | |
356 | 973 | CRL_Code get_reason() const { return m_reason; } |
357 | | |
358 | 36.4k | static OID static_oid() { return OID("2.5.29.21"); } |
359 | 0 | OID oid_of() const override { return static_oid(); } |
360 | | |
361 | | private: |
362 | 973 | std::string oid_name() const override { return "X509v3.ReasonCode"; } |
363 | | |
364 | 0 | bool should_encode() const override { return (m_reason != UNSPECIFIED); } |
365 | | std::vector<uint8_t> encode_inner() const override; |
366 | | void decode_inner(const std::vector<uint8_t>&) override; |
367 | | |
368 | | CRL_Code m_reason; |
369 | | }; |
370 | | |
371 | | /** |
372 | | * CRL Distribution Points Extension |
373 | | * todo enforce restrictions from RFC 5280 4.2.1.13 |
374 | | */ |
375 | | class BOTAN_PUBLIC_API(2,0) CRL_Distribution_Points final : public Certificate_Extension |
376 | | { |
377 | | public: |
378 | | class BOTAN_PUBLIC_API(2,0) Distribution_Point final : public ASN1_Object |
379 | | { |
380 | | public: |
381 | | void encode_into(class DER_Encoder&) const override; |
382 | | void decode_from(class BER_Decoder&) override; |
383 | | |
384 | 540 | const AlternativeName& point() const { return m_point; } |
385 | | private: |
386 | | AlternativeName m_point; |
387 | | }; |
388 | | |
389 | | CRL_Distribution_Points* copy() const override |
390 | 0 | { return new CRL_Distribution_Points(m_distribution_points); } |
391 | | |
392 | 2.27k | CRL_Distribution_Points() = default; |
393 | | |
394 | | explicit CRL_Distribution_Points(const std::vector<Distribution_Point>& points) : |
395 | 0 | m_distribution_points(points) {} |
396 | | |
397 | | const std::vector<Distribution_Point>& distribution_points() const |
398 | 0 | { return m_distribution_points; } |
399 | | |
400 | | const std::vector<std::string>& crl_distribution_urls() const |
401 | 58 | { return m_crl_distribution_urls; } |
402 | | |
403 | 34.6k | static OID static_oid() { return OID("2.5.29.31"); } |
404 | 0 | OID oid_of() const override { return static_oid(); } |
405 | | |
406 | | private: |
407 | | std::string oid_name() const override |
408 | 58 | { return "X509v3.CRLDistributionPoints"; } |
409 | | |
410 | | bool should_encode() const override |
411 | 0 | { return !m_distribution_points.empty(); } |
412 | | |
413 | | std::vector<uint8_t> encode_inner() const override; |
414 | | void decode_inner(const std::vector<uint8_t>&) override; |
415 | | |
416 | | std::vector<Distribution_Point> m_distribution_points; |
417 | | std::vector<std::string> m_crl_distribution_urls; |
418 | | }; |
419 | | |
420 | | /** |
421 | | * CRL Issuing Distribution Point Extension |
422 | | * todo enforce restrictions from RFC 5280 5.2.5 |
423 | | */ |
424 | | class CRL_Issuing_Distribution_Point final : public Certificate_Extension |
425 | | { |
426 | | public: |
427 | 427 | CRL_Issuing_Distribution_Point() = default; |
428 | | |
429 | | explicit CRL_Issuing_Distribution_Point(const CRL_Distribution_Points::Distribution_Point& distribution_point) : |
430 | 0 | m_distribution_point(distribution_point) {} |
431 | | |
432 | | CRL_Issuing_Distribution_Point* copy() const override |
433 | 0 | { return new CRL_Issuing_Distribution_Point(m_distribution_point); } |
434 | | |
435 | | const AlternativeName& get_point() const |
436 | 7 | { return m_distribution_point.point(); } |
437 | | |
438 | 21.4k | static OID static_oid() { return OID("2.5.29.28"); } |
439 | 0 | OID oid_of() const override { return static_oid(); } |
440 | | |
441 | | private: |
442 | | std::string oid_name() const override |
443 | 7 | { return "X509v3.CRLIssuingDistributionPoint"; } |
444 | | |
445 | 0 | bool should_encode() const override { return true; } |
446 | | std::vector<uint8_t> encode_inner() const override; |
447 | | void decode_inner(const std::vector<uint8_t>&) override; |
448 | | |
449 | | CRL_Distribution_Points::Distribution_Point m_distribution_point; |
450 | | }; |
451 | | |
452 | | /** |
453 | | * An unknown X.509 extension |
454 | | * Will add a failure to the path validation result, if critical |
455 | | */ |
456 | | class BOTAN_PUBLIC_API(2,4) Unknown_Extension final : public Certificate_Extension |
457 | | { |
458 | | public: |
459 | | Unknown_Extension(const OID& oid, bool critical) : |
460 | 34.3k | m_oid(oid), m_critical(critical) {} |
461 | | |
462 | | Unknown_Extension* copy() const override |
463 | 0 | { return new Unknown_Extension(m_oid, m_critical); } |
464 | | |
465 | | /** |
466 | | * Return the OID of this unknown extension |
467 | | */ |
468 | | OID oid_of() const override |
469 | 0 | { return m_oid; } |
470 | | |
471 | | //static_oid not defined for Unknown_Extension |
472 | | |
473 | | /** |
474 | | * Return the extension contents |
475 | | */ |
476 | 0 | const std::vector<uint8_t>& extension_contents() const { return m_bytes; } |
477 | | |
478 | | /** |
479 | | * Return if this extension was marked critical |
480 | | */ |
481 | 0 | bool is_critical_extension() const { return m_critical; } |
482 | | |
483 | | void validate(const X509_Certificate&, const X509_Certificate&, |
484 | | const std::vector<std::shared_ptr<const X509_Certificate>>&, |
485 | | std::vector<std::set<Certificate_Status_Code>>& cert_status, |
486 | | size_t pos) override |
487 | 0 | { |
488 | 0 | if(m_critical) |
489 | 0 | { |
490 | 0 | cert_status.at(pos).insert(Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION); |
491 | 0 | } |
492 | 0 | } |
493 | | |
494 | | private: |
495 | 3.13k | std::string oid_name() const override { return ""; } |
496 | | |
497 | 0 | bool should_encode() const override { return true; } |
498 | | std::vector<uint8_t> encode_inner() const override; |
499 | | void decode_inner(const std::vector<uint8_t>&) override; |
500 | | |
501 | | OID m_oid; |
502 | | bool m_critical; |
503 | | std::vector<uint8_t> m_bytes; |
504 | | }; |
505 | | |
506 | | } |
507 | | |
508 | | } |
509 | | |
510 | | #endif |