Botan  2.18.1
Crypto and TLS for C++11
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 
22 namespace Botan {
23 
24 class X509_Certificate;
25 class Data_Store;
26 class 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 */
34 BOTAN_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 
108 bool BOTAN_PUBLIC_API(2,0) operator==(const X509_DN& dn1, const X509_DN& dn2);
109 bool BOTAN_PUBLIC_API(2,0) operator!=(const X509_DN& dn1, const X509_DN& dn2);
110 
111 /*
112 The ordering here is arbitrary and may change from release to release.
113 It is intended for allowing DNs as keys in std::map and similiar containers
114 */
115 bool BOTAN_PUBLIC_API(2,0) operator<(const X509_DN& dn1, const X509_DN& dn2);
116 
117 BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, const X509_DN& dn);
118 BOTAN_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 
248 std::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 
307 std::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;
565  Extensions& operator=(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,
577  Certificate_Extension* ext) :
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,
586  Certificate_Extension* ext) :
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
size_t maximum() const
Definition: pkix_types.h:299
int operator<<(int fd, Pipe &pipe)
Definition: fd_unix.cpp:17
const std::vector< uint8_t > & get_bits() const
Definition: pkix_types.h:68
bool empty() const
Definition: pkix_types.h:70
const std::vector< std::pair< OID, ASN1_String > > & dn_info() const
Definition: pkix_types.h:74
const std::string & type() const
Definition: pkix_types.h:225
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Definition: bigint.h:1143
const std::vector< GeneralSubtree > & excluded() const
Definition: pkix_types.h:340
ASN1_Tag
Definition: asn1_obj.h:25
MechanismType type
const std::multimap< std::string, std::string > & get_attributes() const
Definition: pkix_types.h:139
const T * get_extension_object_as(const OID &oid=T::static_oid()) const
Definition: pkix_types.h:425
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition: exceptn.cpp:11
const std::multimap< OID, ASN1_String > & get_othernames() const
Definition: pkix_types.h:144
X509_DN(const std::multimap< std::string, std::string > &args)
Definition: pkix_types.h:53
const std::vector< OID > & get_extension_oids() const
Definition: pkix_types.h:451
NameConstraints(std::vector< GeneralSubtree > &&permitted_subtrees, std::vector< GeneralSubtree > &&excluded_subtrees)
Definition: pkix_types.h:327
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:107
bool matches(DataSource &source, const std::string &extra, size_t search_range)
Definition: pem.cpp:142
const std::vector< GeneralSubtree > & permitted() const
Definition: pkix_types.h:335
std::unique_ptr< T > get_raw(const OID &oid) const
Definition: pkix_types.h:527
const std::string & name() const
Definition: pkix_types.h:230
const GeneralName & base() const
Definition: pkix_types.h:289
const OID & get_oid() const
Definition: pkix_types.h:175
std::vector< uint8_t > parameters
Definition: pkix_types.h:185
Definition: alg_id.cpp:13
X.509 GeneralName Type.
Definition: pkix_types.h:195
A single Name Constraint.
Definition: pkix_types.h:257
void verify_cert_constraints_valid_for_key_type(const Public_Key &pub_key, Key_Constraints constraints)
std::string key_constraints_to_string(Key_Constraints constraints)
size_t minimum() const
Definition: pkix_types.h:294
X509_DN(const std::multimap< OID, std::string > &args)
Definition: pkix_types.h:47
GeneralSubtree(const GeneralName &base, size_t min, size_t max)
Definition: pkix_types.h:272
const std::vector< uint8_t > & get_parameters() const
Definition: pkix_types.h:177
CK_ATTRIBUTE Attribute
Definition: p11.h:847
fe T
Definition: ge.cpp:37
void add_attribute(const OID &oid, const std::string &val)
Definition: pkix_types.h:85
Key_Constraints
Definition: pkix_enums.h:106
virtual bool should_encode() const
Definition: pkix_types.h:404
Name Constraints.
Definition: pkix_types.h:314