Botan 2.19.1
Crypto and TLS for C&
pkix_types.h
Go to the documentation of this file.
1/*
2* (C) 1999-2010,2012,2018,2020 Jack Lloyd
3* (C) 2007 Yves Jerschow
4* (C) 2015 Kai Michaelis
5* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity
6* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#ifndef BOTAN_PKIX_TYPES_H_
12#define BOTAN_PKIX_TYPES_H_
13
14#include <botan/asn1_obj.h>
15#include <botan/pkix_enums.h>
16#include <vector>
17#include <string>
18#include <iosfwd>
19#include <map>
20#include <set>
21
22namespace Botan {
23
24class X509_Certificate;
25class Data_Store;
26class Public_Key;
27
28/**
29* Check that key constraints are permitted for a specific public key.
30* @param pub_key the public key on which the constraints shall be enforced on
31* @param constraints the constraints that shall be enforced on the key
32* @throw Invalid_Argument if the given constraints are not permitted for this key
33*/
34BOTAN_PUBLIC_API(2,0) void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key,
35 Key_Constraints constraints);
36
38
39/**
40* Distinguished Name
41*/
43 {
44 public:
45 X509_DN() = default;
46
47 explicit X509_DN(const std::multimap<OID, std::string>& args)
48 {
49 for(auto i : args)
50 add_attribute(i.first, i.second);
51 }
52
53 explicit X509_DN(const std::multimap<std::string, std::string>& args)
54 {
55 for(auto i : args)
56 add_attribute(i.first, i.second);
57 }
58
59 void encode_into(DER_Encoder&) const override;
60 void decode_from(BER_Decoder&) override;
61
62 bool has_field(const OID& oid) const;
63 ASN1_String get_first_attribute(const OID& oid) const;
64
65 /*
66 * Return the BER encoded data, if any
67 */
68 const std::vector<uint8_t>& get_bits() const { return m_dn_bits; }
69
70 bool empty() const { return m_rdn.empty(); }
71
72 std::string to_string() const;
73
74 const std::vector<std::pair<OID,ASN1_String>>& dn_info() const { return m_rdn; }
75
76 std::multimap<OID, std::string> get_attributes() const;
77 std::multimap<std::string, std::string> contents() const;
78
79 bool has_field(const std::string& attr) const;
80 std::vector<std::string> get_attribute(const std::string& attr) const;
81 std::string get_first_attribute(const std::string& attr) const;
82
83 void add_attribute(const std::string& key, const std::string& val);
84
85 void add_attribute(const OID& oid, const std::string& val)
86 {
87 add_attribute(oid, ASN1_String(val));
88 }
89
90 void add_attribute(const OID& oid, const ASN1_String& val);
91
92 static std::string deref_info_field(const std::string& key);
93
94 /**
95 * Lookup upper bounds in characters for the length of distinguished name fields
96 * as given in RFC 5280, Appendix A.
97 *
98 * @param oid the oid of the DN to lookup
99 * @return the upper bound, or zero if no ub is known to Botan
100 */
101 static size_t lookup_ub(const OID& oid);
102
103 private:
104 std::vector<std::pair<OID,ASN1_String>> m_rdn;
105 std::vector<uint8_t> m_dn_bits;
106 };
107
108bool BOTAN_PUBLIC_API(2,0) operator==(const X509_DN& dn1, const X509_DN& dn2);
109bool BOTAN_PUBLIC_API(2,0) operator!=(const X509_DN& dn1, const X509_DN& dn2);
110
111/*
112The ordering here is arbitrary and may change from release to release.
113It is intended for allowing DNs as keys in std::map and similiar containers
114*/
115bool BOTAN_PUBLIC_API(2,0) operator<(const X509_DN& dn1, const X509_DN& dn2);
116
117BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, const X509_DN& dn);
118BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, X509_DN& dn);
119
120/**
121* Alternative Name
122*/
124 {
125 public:
126 void encode_into(DER_Encoder&) const override;
127 void decode_from(BER_Decoder&) override;
128
129 std::multimap<std::string, std::string> contents() const;
130
131 bool has_field(const std::string& attr) const;
132 std::vector<std::string> get_attribute(const std::string& attr) const;
133
134 std::string get_first_attribute(const std::string& attr) const;
135
136 void add_attribute(const std::string& type, const std::string& value);
137 void add_othername(const OID& oid, const std::string& value, ASN1_Tag type);
138
139 const std::multimap<std::string, std::string>& get_attributes() const
140 {
141 return m_alt_info;
142 }
143
144 const std::multimap<OID, ASN1_String>& get_othernames() const
145 {
146 return m_othernames;
147 }
148
149 X509_DN dn() const;
150
151 bool has_items() const;
152
153 AlternativeName(const std::string& email_addr = "",
154 const std::string& uri = "",
155 const std::string& dns = "",
156 const std::string& ip_address = "");
157 private:
158 std::multimap<std::string, std::string> m_alt_info;
159 std::multimap<OID, ASN1_String> m_othernames;
160 };
161
162/**
163* Attribute
164*/
166 {
167 public:
168 void encode_into(DER_Encoder& to) const override;
169 void decode_from(BER_Decoder& from) override;
170
171 Attribute() = default;
172 Attribute(const OID&, const std::vector<uint8_t>&);
173 Attribute(const std::string&, const std::vector<uint8_t>&);
174
175 const OID& get_oid() const { return oid; }
176
177 const std::vector<uint8_t>& get_parameters() const { return parameters; }
178
179 BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:
180 /*
181 * These values are public for historical reasons, but in a future release
182 * they will be made private. Do not access them.
183 */
184 OID oid;
185 std::vector<uint8_t> parameters;
186 };
187
188/**
189* @brief X.509 GeneralName Type
190*
191* Handles parsing GeneralName types in their BER and canonical string
192* encoding. Allows matching GeneralNames against each other using
193* the rules laid out in the RFC 5280, sec. 4.2.1.10 (Name Contraints).
194*/
196 {
197 public:
198 enum MatchResult : int
199 {
205 };
206
207 /**
208 * Creates an empty GeneralName.
209 */
210 GeneralName() = default;
211
212 /**
213 * Creates a new GeneralName for its string format.
214 * @param str type and name, colon-separated, e.g., "DNS:google.com"
215 */
216 GeneralName(const std::string& str);
217
218 void encode_into(DER_Encoder&) const override;
219
220 void decode_from(BER_Decoder&) override;
221
222 /**
223 * @return Type of the name. Can be DN, DNS, IP, RFC822 or URI.
224 */
225 const std::string& type() const { return m_type; }
226
227 /**
228 * @return The name as string. Format depends on type.
229 */
230 const std::string& name() const { return m_name; }
231
232 /**
233 * Checks whether a given certificate (partially) matches this name.
234 * @param cert certificate to be matched
235 * @return the match result
236 */
237 MatchResult matches(const X509_Certificate& cert) const;
238
239 private:
240 std::string m_type;
241 std::string m_name;
242
243 bool matches_dns(const std::string&) const;
244 bool matches_dn(const std::string&) const;
245 bool matches_ip(const std::string&) const;
246 };
247
248std::ostream& operator<<(std::ostream& os, const GeneralName& gn);
249
250/**
251* @brief A single Name Constraint
252*
253* The Name Constraint extension adds a minimum and maximum path
254* length to a GeneralName to form a constraint. The length limits
255* are currently unused.
256*/
258 {
259 public:
260 /**
261 * Creates an empty name constraint.
262 */
263 GeneralSubtree() : m_base(), m_minimum(0), m_maximum(std::numeric_limits<std::size_t>::max())
264 {}
265
266 /***
267 * Creates a new name constraint.
268 * @param base name
269 * @param min minimum path length
270 * @param max maximum path length
271 */
272 GeneralSubtree(const GeneralName& base, size_t min, size_t max)
273 : m_base(base), m_minimum(min), m_maximum(max)
274 {}
275
276 /**
277 * Creates a new name constraint for its string format.
278 * @param str name constraint
279 */
280 GeneralSubtree(const std::string& str);
281
282 void encode_into(DER_Encoder&) const override;
283
284 void decode_from(BER_Decoder&) override;
285
286 /**
287 * @return name
288 */
289 const GeneralName& base() const { return m_base; }
290
291 /**
292 * @return minimum path length
293 */
294 size_t minimum() const { return m_minimum; }
295
296 /**
297 * @return maximum path length
298 */
299 size_t maximum() const { return m_maximum; }
300
301 private:
302 GeneralName m_base;
303 size_t m_minimum;
304 size_t m_maximum;
305 };
306
307std::ostream& operator<<(std::ostream& os, const GeneralSubtree& gs);
308
309/**
310* @brief Name Constraints
311*
312* Wraps the Name Constraints associated with a certificate.
313*/
315 {
316 public:
317 /**
318 * Creates an empty name NameConstraints.
319 */
320 NameConstraints() : m_permitted_subtrees(), m_excluded_subtrees() {}
321
322 /**
323 * Creates NameConstraints from a list of permitted and excluded subtrees.
324 * @param permitted_subtrees names for which the certificate is permitted
325 * @param excluded_subtrees names for which the certificate is not permitted
326 */
327 NameConstraints(std::vector<GeneralSubtree>&& permitted_subtrees,
328 std::vector<GeneralSubtree>&& excluded_subtrees)
329 : m_permitted_subtrees(permitted_subtrees), m_excluded_subtrees(excluded_subtrees)
330 {}
331
332 /**
333 * @return permitted names
334 */
335 const std::vector<GeneralSubtree>& permitted() const { return m_permitted_subtrees; }
336
337 /**
338 * @return excluded names
339 */
340 const std::vector<GeneralSubtree>& excluded() const { return m_excluded_subtrees; }
341
342 private:
343 std::vector<GeneralSubtree> m_permitted_subtrees;
344 std::vector<GeneralSubtree> m_excluded_subtrees;
345 };
346
347/**
348* X.509 Certificate Extension
349*/
351 {
352 public:
353 /**
354 * @return OID representing this extension
355 */
356 virtual OID oid_of() const = 0;
357
358 /*
359 * @return specific OID name
360 * If possible OIDS table should match oid_name to OIDS, ie
361 * OID::from_string(ext->oid_name()) == ext->oid_of()
362 * Should return empty string if OID is not known
363 */
364 virtual std::string oid_name() const = 0;
365
366 /**
367 * Make a copy of this extension
368 * @return copy of this
369 */
370 virtual Certificate_Extension* copy() const = 0;
371
372 /*
373 * Add the contents of this extension into the information
374 * for the subject and/or issuer, as necessary.
375 * @param subject the subject info
376 * @param issuer the issuer info
377 */
378 virtual void contents_to(Data_Store& subject,
379 Data_Store& issuer) const = 0;
380
381 /*
382 * Callback visited during path validation.
383 *
384 * An extension can implement this callback to inspect
385 * the path during path validation.
386 *
387 * If an error occurs during validation of this extension,
388 * an appropriate status code shall be added to cert_status.
389 *
390 * @param subject Subject certificate that contains this extension
391 * @param issuer Issuer certificate
392 * @param status Certificate validation status codes for subject certificate
393 * @param cert_path Certificate path which is currently validated
394 * @param pos Position of subject certificate in cert_path
395 */
396 virtual void validate(const X509_Certificate& subject, const X509_Certificate& issuer,
397 const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path,
398 std::vector<std::set<Certificate_Status_Code>>& cert_status,
399 size_t pos);
400
401 virtual ~Certificate_Extension() = default;
402 protected:
403 friend class Extensions;
404 virtual bool should_encode() const { return true; }
405 virtual std::vector<uint8_t> encode_inner() const = 0;
406 virtual void decode_inner(const std::vector<uint8_t>&) = 0;
407 };
408
409/**
410* X.509 Certificate Extension List
411*/
413 {
414 public:
415 /**
416 * Look up an object in the extensions, based on OID Returns
417 * nullptr if not set, if the extension was either absent or not
418 * handled. The pointer returned is owned by the Extensions
419 * object.
420 * This would be better with an optional<T> return value
421 */
422 const Certificate_Extension* get_extension_object(const OID& oid) const;
423
424 template<typename T>
425 const T* get_extension_object_as(const OID& oid = T::static_oid()) const
426 {
427 if(const Certificate_Extension* extn = get_extension_object(oid))
428 {
429 // Unknown_Extension oid_name is empty
430 if(extn->oid_name().empty())
431 {
432 return nullptr;
433 }
434 else if(const T* extn_as_T = dynamic_cast<const T*>(extn))
435 {
436 return extn_as_T;
437 }
438 else
439 {
440 throw Decoding_Error("Exception::get_extension_object_as dynamic_cast failed");
441 }
442 }
443
444 return nullptr;
445 }
446
447 /**
448 * Return the set of extensions in the order they appeared in the certificate
449 * (or as they were added, if constructed)
450 */
451 const std::vector<OID>& get_extension_oids() const
452 {
453 return m_extension_oids;
454 }
455
456 /**
457 * Return true if an extension was set
458 */
459 bool extension_set(const OID& oid) const;
460
461 /**
462 * Return true if an extesion was set and marked critical
463 */
464 bool critical_extension_set(const OID& oid) const;
465
466 /**
467 * Return the raw bytes of the extension
468 * Will throw if OID was not set as an extension.
469 */
470 std::vector<uint8_t> get_extension_bits(const OID& oid) const;
471
472 void encode_into(class DER_Encoder&) const override;
473 void decode_from(class BER_Decoder&) override;
474 void contents_to(Data_Store&, Data_Store&) const;
475
476 /**
477 * Adds a new extension to the list.
478 * @param extn pointer to the certificate extension (Extensions takes ownership)
479 * @param critical whether this extension should be marked as critical
480 * @throw Invalid_Argument if the extension is already present in the list
481 */
482 void add(Certificate_Extension* extn, bool critical = false);
483
484 /**
485 * Adds a new extension to the list unless it already exists. If the extension
486 * already exists within the Extensions object, the extn pointer will be deleted.
487 *
488 * @param extn pointer to the certificate extension (Extensions takes ownership)
489 * @param critical whether this extension should be marked as critical
490 * @return true if the object was added false if the extension was already used
491 */
492 bool add_new(Certificate_Extension* extn, bool critical = false);
493
494 /**
495 * Adds an extension to the list or replaces it.
496 * @param extn the certificate extension
497 * @param critical whether this extension should be marked as critical
498 */
499 void replace(Certificate_Extension* extn, bool critical = false);
500
501 /**
502 * Remove an extension from the list. Returns true if the
503 * extension had been set, false otherwise.
504 */
505 bool remove(const OID& oid);
506
507 /**
508 * Searches for an extension by OID and returns the result.
509 * Only the known extensions types declared in this header
510 * are searched for by this function.
511 * @return Copy of extension with oid, nullptr if not found.
512 * Can avoid creating a copy by using get_extension_object function
513 */
514 std::unique_ptr<Certificate_Extension> get(const OID& oid) const;
515
516 /**
517 * Searches for an extension by OID and returns the result decoding
518 * it to some arbitrary extension type chosen by the application.
519 *
520 * Only the unknown extensions, that is, extensions types that
521 * are not declared in this header, are searched for by this
522 * function.
523 *
524 * @return Pointer to new extension with oid, nullptr if not found.
525 */
526 template<typename T>
527 std::unique_ptr<T> get_raw(const OID& oid) const
528 {
529 auto extn_info = m_extension_info.find(oid);
530
531 if(extn_info != m_extension_info.end())
532 {
533 // Unknown_Extension oid_name is empty
534 if(extn_info->second.obj().oid_name() == "")
535 {
536 std::unique_ptr<T> ext(new T);
537 ext->decode_inner(extn_info->second.bits());
538 return ext;
539 }
540 }
541 return nullptr;
542 }
543
544 /**
545 * Returns a copy of the list of extensions together with the corresponding
546 * criticality flag. All extensions are encoded as some object, falling back
547 * to Unknown_Extension class which simply allows reading the bytes as well
548 * as the criticality flag.
549 */
550 std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> extensions() const;
551
552 /**
553 * Returns the list of extensions as raw, encoded bytes
554 * together with the corresponding criticality flag.
555 * Contains all extensions, including any extensions encoded as Unknown_Extension
556 */
557 std::map<OID, std::pair<std::vector<uint8_t>, bool>> extensions_raw() const;
558
560
561 Extensions(const Extensions&) = default;
562 Extensions& operator=(const Extensions&) = default;
563
564 Extensions(Extensions&&) = default;
566
567 private:
568 static std::unique_ptr<Certificate_Extension>
569 create_extn_obj(const OID& oid,
570 bool critical,
571 const std::vector<uint8_t>& body);
572
573 class Extensions_Info
574 {
575 public:
576 Extensions_Info(bool critical,
578 m_obj(ext),
579 m_bits(m_obj->encode_inner()),
580 m_critical(critical)
581 {
582 }
583
584 Extensions_Info(bool critical,
585 const std::vector<uint8_t>& encoding,
587 m_obj(ext),
588 m_bits(encoding),
589 m_critical(critical)
590 {
591 }
592
593 bool is_critical() const { return m_critical; }
594 const std::vector<uint8_t>& bits() const { return m_bits; }
595 const Certificate_Extension& obj() const
596 {
597 BOTAN_ASSERT_NONNULL(m_obj.get());
598 return *m_obj.get();
599 }
600
601 private:
602 std::shared_ptr<Certificate_Extension> m_obj;
603 std::vector<uint8_t> m_bits;
604 bool m_critical = false;
605 };
606
607 std::vector<OID> m_extension_oids;
608 std::map<OID, Extensions_Info> m_extension_info;
609 };
610
611}
612
613#endif
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:107
const std::multimap< std::string, std::string > & get_attributes() const
Definition: pkix_types.h:139
const std::multimap< OID, ASN1_String > & get_othernames() const
Definition: pkix_types.h:144
std::vector< uint8_t > parameters
Definition: pkix_types.h:185
const OID & get_oid() const
Definition: pkix_types.h:175
Attribute()=default
const std::vector< uint8_t > & get_parameters() const
Definition: pkix_types.h:177
virtual void contents_to(Data_Store &subject, Data_Store &issuer) const =0
virtual bool should_encode() const
Definition: pkix_types.h:404
virtual std::string oid_name() const =0
virtual OID oid_of() const =0
virtual Certificate_Extension * copy() const =0
virtual std::vector< uint8_t > encode_inner() const =0
virtual ~Certificate_Extension()=default
virtual void decode_inner(const std::vector< uint8_t > &)=0
std::unique_ptr< T > get_raw(const OID &oid) const
Definition: pkix_types.h:527
Extensions & operator=(const Extensions &)=default
Extensions(const Extensions &)=default
Extensions(Extensions &&)=default
const std::vector< OID > & get_extension_oids() const
Definition: pkix_types.h:451
const T * get_extension_object_as(const OID &oid=T::static_oid()) const
Definition: pkix_types.h:425
Extensions & operator=(Extensions &&)=default
X.509 GeneralName Type.
Definition: pkix_types.h:196
GeneralName()=default
const std::string & type() const
Definition: pkix_types.h:225
const std::string & name() const
Definition: pkix_types.h:230
A single Name Constraint.
Definition: pkix_types.h:258
size_t maximum() const
Definition: pkix_types.h:299
GeneralSubtree(const GeneralName &base, size_t min, size_t max)
Definition: pkix_types.h:272
size_t minimum() const
Definition: pkix_types.h:294
const GeneralName & base() const
Definition: pkix_types.h:289
Name Constraints.
Definition: pkix_types.h:315
NameConstraints(std::vector< GeneralSubtree > &&permitted_subtrees, std::vector< GeneralSubtree > &&excluded_subtrees)
Definition: pkix_types.h:327
const std::vector< GeneralSubtree > & permitted() const
Definition: pkix_types.h:335
const std::vector< GeneralSubtree > & excluded() const
Definition: pkix_types.h:340
X509_DN()=default
X509_DN(const std::multimap< OID, std::string > &args)
Definition: pkix_types.h:47
const std::vector< std::pair< OID, ASN1_String > > & dn_info() const
Definition: pkix_types.h:74
X509_DN(const std::multimap< std::string, std::string > &args)
Definition: pkix_types.h:53
bool empty() const
Definition: pkix_types.h:70
void add_attribute(const OID &oid, const std::string &val)
Definition: pkix_types.h:85
const std::vector< uint8_t > & get_bits() const
Definition: pkix_types.h:68
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
fe T
Definition: ge.cpp:37
bool matches(DataSource &source, const std::string &extra, size_t search_range)
Definition: pem.cpp:142
CK_ATTRIBUTE Attribute
Definition: p11.h:847
Definition: alg_id.cpp:13
int operator<<(int fd, Pipe &pipe)
Definition: fd_unix.cpp:17
ASN1_Tag
Definition: asn1_obj.h:25
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition: exceptn.cpp:11
void verify_cert_constraints_valid_for_key_type(const Public_Key &pub_key, Key_Constraints constraints)
Key_Constraints
Definition: pkix_enums.h:106
std::string key_constraints_to_string(Key_Constraints constraints)
Definition: bigint.h:1143
MechanismType type