Botan  2.18.1
Crypto and TLS for C++11
asn1_obj.h
Go to the documentation of this file.
1 /*
2 * (C) 1999-2007,2018,2020 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6 
7 #ifndef BOTAN_ASN1_OBJECT_TYPES_H_
8 #define BOTAN_ASN1_OBJECT_TYPES_H_
9 
10 #include <botan/secmem.h>
11 #include <botan/exceptn.h>
12 #include <vector>
13 #include <string>
14 #include <chrono>
15 
16 namespace Botan {
17 
18 class BER_Decoder;
19 class DER_Encoder;
20 
21 /**
22 * ASN.1 Type and Class Tags
23 * This will become an enum class in a future major release
24 */
25 enum ASN1_Tag : uint32_t {
26  UNIVERSAL = 0x00,
27  APPLICATION = 0x40,
29 
30  CONSTRUCTED = 0x20,
31 
33 
34  EOC = 0x00,
35  BOOLEAN = 0x01,
36  INTEGER = 0x02,
37  BIT_STRING = 0x03,
38  OCTET_STRING = 0x04,
39  NULL_TAG = 0x05,
40  OBJECT_ID = 0x06,
41  ENUMERATED = 0x0A,
42  SEQUENCE = 0x10,
43  SET = 0x11,
44 
45  UTF8_STRING = 0x0C,
48  T61_STRING = 0x14,
49  IA5_STRING = 0x16,
52  BMP_STRING = 0x1E,
53 
54  UTC_TIME = 0x17,
57 
58  NO_OBJECT = 0xFF00,
60 };
61 
64 
65 /**
66 * Basic ASN.1 Object Interface
67 */
69  {
70  public:
71  /**
72  * Encode whatever this object is into to
73  * @param to the DER_Encoder that will be written to
74  */
75  virtual void encode_into(DER_Encoder& to) const = 0;
76 
77  /**
78  * Decode whatever this object is from from
79  * @param from the BER_Decoder that will be read from
80  */
81  virtual void decode_from(BER_Decoder& from) = 0;
82 
83  /**
84  * Return the encoding of this object. This is a convenience
85  * method when just one object needs to be serialized. Use
86  * DER_Encoder for complicated encodings.
87  */
88  std::vector<uint8_t> BER_encode() const;
89 
90  ASN1_Object() = default;
91  ASN1_Object(const ASN1_Object&) = default;
92  ASN1_Object & operator=(const ASN1_Object&) = default;
93  virtual ~ASN1_Object() = default;
94  };
95 
96 /**
97 * BER Encoded Object
98 */
100  {
101  public:
102  BER_Object() : type_tag(NO_OBJECT), class_tag(UNIVERSAL) {}
103 
104  BER_Object(const BER_Object& other) = default;
105 
106  BER_Object& operator=(const BER_Object& other) = default;
107 
108  BER_Object(BER_Object&& other) = default;
109 
110  BER_Object& operator=(BER_Object&& other) = default;
111 
112  bool is_set() const { return type_tag != NO_OBJECT; }
113 
114  ASN1_Tag tagging() const { return ASN1_Tag(type() | get_class()); }
115 
116  ASN1_Tag type() const { return type_tag; }
117  ASN1_Tag get_class() const { return class_tag; }
118 
119  const uint8_t* bits() const { return value.data(); }
120 
121  size_t length() const { return value.size(); }
122 
123  void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag,
124  const std::string& descr = "object") const;
125 
126  bool is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const;
127 
128  bool is_a(int type_tag, ASN1_Tag class_tag) const;
129 
130  BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:
131  /*
132  * The following member variables are public for historical reasons, but
133  * will be made private in a future major release. Use the accessor
134  * functions above.
135  */
136  ASN1_Tag type_tag, class_tag;
138 
139  private:
140 
141  friend class BER_Decoder;
142 
143  void set_tagging(ASN1_Tag type_tag, ASN1_Tag class_tag);
144 
145  uint8_t* mutable_bits(size_t length)
146  {
147  value.resize(length);
148  return value.data();
149  }
150  };
151 
152 /*
153 * ASN.1 Utility Functions
154 */
155 class DataSource;
156 
157 namespace ASN1 {
158 
159 std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& val);
160 std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len);
161 std::string to_string(const BER_Object& obj);
162 
163 /**
164 * Heuristics tests; is this object possibly BER?
165 * @param src a data source that will be peeked at but not modified
166 */
167 bool maybe_BER(DataSource& src);
168 
169 }
170 
171 /**
172 * General BER Decoding Error Exception
173 */
175  {
176  public:
177  explicit BER_Decoding_Error(const std::string&);
178  };
179 
180 /**
181 * Exception For Incorrect BER Taggings
182 */
184  {
185  public:
186  BER_Bad_Tag(const std::string& msg, ASN1_Tag tag);
187  BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2);
188  };
189 
190 /**
191 * This class represents ASN.1 object identifiers.
192 */
194  {
195  public:
196 
197  /**
198  * Create an uninitialied OID object
199  */
200  explicit OID() {}
201 
202  /**
203  * Construct an OID from a string.
204  * @param str a string in the form "a.b.c" etc., where a,b,c are numbers
205  */
206  explicit OID(const std::string& str);
207 
208  /**
209  * Initialize an OID from a sequence of integer values
210  */
211  explicit OID(std::initializer_list<uint32_t> init) : m_id(init) {}
212 
213  /**
214  * Initialize an OID from a vector of integer values
215  */
216  explicit OID(std::vector<uint32_t>&& init) : m_id(init) {}
217 
218  /**
219  * Construct an OID from a string.
220  * @param str a string in the form "a.b.c" etc., where a,b,c are numbers
221  * or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier")
222  */
223  static OID from_string(const std::string& str);
224 
225  void encode_into(class DER_Encoder&) const override;
226  void decode_from(class BER_Decoder&) override;
227 
228  /**
229  * Find out whether this OID is empty
230  * @return true is no OID value is set
231  */
232  bool empty() const { return m_id.empty(); }
233 
234  /**
235  * Find out whether this OID has a value
236  * @return true is this OID has a value
237  */
238  bool has_value() const { return (m_id.empty() == false); }
239 
240  /**
241  * Get this OID as list (vector) of its components.
242  * @return vector representing this OID
243  */
244  const std::vector<uint32_t>& get_components() const { return m_id; }
245 
246  const std::vector<uint32_t>& get_id() const { return get_components(); }
247 
248  /**
249  * Get this OID as a string
250  * @return string representing this OID
251  */
252  std::string BOTAN_DEPRECATED("Use OID::to_string") as_string() const
253  {
254  return this->to_string();
255  }
256 
257  /**
258  * Get this OID as a dotted-decimal string
259  * @return string representing this OID
260  */
261  std::string to_string() const;
262 
263  /**
264  * If there is a known name associated with this OID, return that.
265  * Otherwise return the result of to_string
266  */
267  std::string to_formatted_string() const;
268 
269  /**
270  * Compare two OIDs.
271  * @return true if they are equal, false otherwise
272  */
273  bool operator==(const OID& other) const
274  {
275  return m_id == other.m_id;
276  }
277 
278  /**
279  * Reset this instance to an empty OID.
280  */
281  void BOTAN_DEPRECATED("Avoid mutation of OIDs") clear() { m_id.clear(); }
282 
283  /**
284  * Add a component to this OID.
285  * @param new_comp the new component to add to the end of this OID
286  * @return reference to *this
287  */
288  BOTAN_DEPRECATED("Avoid mutation of OIDs") OID& operator+=(uint32_t new_comp)
289  {
290  m_id.push_back(new_comp);
291  return (*this);
292  }
293 
294  private:
295  std::vector<uint32_t> m_id;
296  };
297 
298 /**
299 * Append another component onto the OID.
300 * @param oid the OID to add the new component to
301 * @param new_comp the new component to add
302 */
303 OID BOTAN_PUBLIC_API(2,0) operator+(const OID& oid, uint32_t new_comp);
304 
305 /**
306 * Compare two OIDs.
307 * @param a the first OID
308 * @param b the second OID
309 * @return true if a is not equal to b
310 */
311 inline bool operator!=(const OID& a, const OID& b)
312  {
313  return !(a == b);
314  }
315 
316 /**
317 * Compare two OIDs.
318 * @param a the first OID
319 * @param b the second OID
320 * @return true if a is lexicographically smaller than b
321 */
322 bool BOTAN_PUBLIC_API(2,0) operator<(const OID& a, const OID& b);
323 
324 /**
325 * Time (GeneralizedTime/UniversalTime)
326 */
328  {
329  public:
330  /// DER encode a ASN1_Time
331  void encode_into(DER_Encoder&) const override;
332 
333  // Decode a BER encoded ASN1_Time
334  void decode_from(BER_Decoder&) override;
335 
336  /// Return an internal string representation of the time
337  std::string to_string() const;
338 
339  /// Returns a human friendly string replesentation of no particular formatting
340  std::string readable_string() const;
341 
342  /// Return if the time has been set somehow
343  bool time_is_set() const;
344 
345  /// Compare this time against another
346  int32_t cmp(const ASN1_Time& other) const;
347 
348  /// Create an invalid ASN1_Time
349  ASN1_Time() = default;
350 
351  /// Create a ASN1_Time from a time point
352  explicit ASN1_Time(const std::chrono::system_clock::time_point& time);
353 
354  /// Create an ASN1_Time from string
355  ASN1_Time(const std::string& t_spec, ASN1_Tag tag);
356 
357  /// Returns a STL timepoint object
358  std::chrono::system_clock::time_point to_std_timepoint() const;
359 
360  /// Return time since epoch
361  uint64_t time_since_epoch() const;
362 
363  private:
364  void set_to(const std::string& t_spec, ASN1_Tag);
365  bool passes_sanity_check() const;
366 
367  uint32_t m_year = 0;
368  uint32_t m_month = 0;
369  uint32_t m_day = 0;
370  uint32_t m_hour = 0;
371  uint32_t m_minute = 0;
372  uint32_t m_second = 0;
373  ASN1_Tag m_tag = NO_OBJECT;
374  };
375 
376 /*
377 * Comparison Operations
378 */
379 bool BOTAN_PUBLIC_API(2,0) operator==(const ASN1_Time&, const ASN1_Time&);
380 bool BOTAN_PUBLIC_API(2,0) operator!=(const ASN1_Time&, const ASN1_Time&);
381 bool BOTAN_PUBLIC_API(2,0) operator<=(const ASN1_Time&, const ASN1_Time&);
382 bool BOTAN_PUBLIC_API(2,0) operator>=(const ASN1_Time&, const ASN1_Time&);
383 bool BOTAN_PUBLIC_API(2,0) operator<(const ASN1_Time&, const ASN1_Time&);
384 bool BOTAN_PUBLIC_API(2,0) operator>(const ASN1_Time&, const ASN1_Time&);
385 
387 
388 /**
389 * ASN.1 string type
390 * This class normalizes all inputs to a UTF-8 std::string
391 */
393  {
394  public:
395  void encode_into(class DER_Encoder&) const override;
396  void decode_from(class BER_Decoder&) override;
397 
398  ASN1_Tag tagging() const { return m_tag; }
399 
400  const std::string& value() const { return m_utf8_str; }
401 
402  size_t size() const { return value().size(); }
403 
404  bool empty() const { return m_utf8_str.empty(); }
405 
406  std::string BOTAN_DEPRECATED("Use value() to get UTF-8 string instead")
407  iso_8859() const;
408 
409  /**
410  * Return true iff this is a tag for a known string type we can handle.
411  * This ignores string types that are not supported, eg teletexString
412  */
413  static bool is_string_type(ASN1_Tag tag);
414 
415  bool operator==(const ASN1_String& other) const
416  { return value() == other.value(); }
417 
418  explicit ASN1_String(const std::string& utf8 = "");
419  ASN1_String(const std::string& utf8, ASN1_Tag tag);
420  private:
421  std::vector<uint8_t> m_data;
422  std::string m_utf8_str;
423  ASN1_Tag m_tag;
424  };
425 
426 /**
427 * Algorithm Identifier
428 */
430  {
431  public:
432  enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM };
433 
434  void encode_into(class DER_Encoder&) const override;
435  void decode_from(class BER_Decoder&) override;
436 
437  AlgorithmIdentifier() = default;
438 
439  AlgorithmIdentifier(const OID& oid, Encoding_Option enc);
440  AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc);
441 
442  AlgorithmIdentifier(const OID& oid, const std::vector<uint8_t>& params);
443  AlgorithmIdentifier(const std::string& oid_name, const std::vector<uint8_t>& params);
444 
445  const OID& get_oid() const { return oid; }
446  const std::vector<uint8_t>& get_parameters() const { return parameters; }
447 
448  bool parameters_are_null() const;
449  bool parameters_are_empty() const { return parameters.empty(); }
450 
452  {
453  return parameters_are_empty() || parameters_are_null();
454  }
455 
456  BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:
457  /*
458  * These values are public for historical reasons, but in a future release
459  * they will be made private. Do not access them.
460  */
461  OID oid;
462  std::vector<uint8_t> parameters;
463  };
464 
465 /*
466 * Comparison Operations
467 */
468 bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&,
469  const AlgorithmIdentifier&);
470 bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&,
471  const AlgorithmIdentifier&);
472 
473 }
474 
475 #endif
std::string asn1_tag_to_string(ASN1_Tag type)
Definition: asn1_obj.cpp:108
ASN1_Tag tagging() const
Definition: asn1_obj.h:114
#define BOTAN_UNSTABLE_API
Definition: compiler.h:44
std::string asn1_class_to_string(ASN1_Tag type)
Definition: asn1_obj.cpp:87
const std::vector< uint32_t > & get_components() const
Definition: asn1_obj.h:244
OID(std::initializer_list< uint32_t > init)
Definition: asn1_obj.h:211
bool parameters_are_empty() const
Definition: asn1_obj.h:449
std::vector< uint8_t > parameters
Definition: asn1_obj.h:462
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
bool operator==(const OID &other) const
Definition: asn1_obj.h:273
bool maybe_BER(DataSource &source)
Definition: asn1_obj.cpp:222
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
ASN1_Tag
Definition: asn1_obj.h:25
MechanismType type
ASN1_Tag type() const
Definition: asn1_obj.h:116
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition: exceptn.cpp:11
ASN1_Tag get_class() const
Definition: asn1_obj.h:117
secure_vector< uint8_t > value
Definition: asn1_obj.h:137
BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES class_tag
Definition: asn1_obj.h:136
bool empty() const
Definition: asn1_obj.h:232
size_t length() const
Definition: asn1_obj.h:121
size_t size() const
Definition: asn1_obj.h:402
Definition: alg_id.cpp:13
secure_vector< uint8_t > BER_encode(const Private_Key &key)
Definition: pkcs8.cpp:139
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:195
const std::vector< uint8_t > & get_parameters() const
Definition: asn1_obj.h:446
const uint8_t * bits() const
Definition: asn1_obj.h:119
const std::string & value() const
Definition: asn1_obj.h:400
int(* init)(CTX *)
const OID & get_oid() const
Definition: asn1_obj.h:445
bool has_value() const
Definition: asn1_obj.h:238
ASN1_Tag tagging() const
Definition: asn1_obj.h:398
const std::vector< uint32_t > & get_id() const
Definition: asn1_obj.h:246
bool parameters_are_null_or_empty() const
Definition: asn1_obj.h:451
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
OID(std::vector< uint32_t > &&init)
Definition: asn1_obj.h:216
bool empty() const
Definition: asn1_obj.h:404
bool is_set() const
Definition: asn1_obj.h:112