Botan 2.19.1
Crypto and TLS for C&
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
16namespace Botan {
17
18class BER_Decoder;
19class DER_Encoder;
20
21/**
22* ASN.1 Type and Class Tags
23* This will become an enum class in a future major release
24*/
25enum ASN1_Tag : uint32_t {
26 UNIVERSAL = 0x00,
29
31
33
34 EOC = 0x00,
35 BOOLEAN = 0x01,
36 INTEGER = 0x02,
37 BIT_STRING = 0x03,
39 NULL_TAG = 0x05,
40 OBJECT_ID = 0x06,
41 ENUMERATED = 0x0A,
42 SEQUENCE = 0x10,
43 SET = 0x11,
44
48 T61_STRING = 0x14,
49 IA5_STRING = 0x16,
52 BMP_STRING = 0x1E,
53
54 UTC_TIME = 0x17,
57
58 NO_OBJECT = 0xFF00,
59 DIRECTORY_STRING = 0xFF01
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 */
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*/
155class DataSource;
156
157namespace ASN1 {
158
159std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& val);
160std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len);
161std::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*/
167bool 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*/
303OID 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*/
311inline 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*/
322bool 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*/
379bool BOTAN_PUBLIC_API(2,0) operator==(const ASN1_Time&, const ASN1_Time&);
380bool BOTAN_PUBLIC_API(2,0) operator!=(const ASN1_Time&, const ASN1_Time&);
381bool BOTAN_PUBLIC_API(2,0) operator<=(const ASN1_Time&, const ASN1_Time&);
382bool BOTAN_PUBLIC_API(2,0) operator>=(const ASN1_Time&, const ASN1_Time&);
383bool BOTAN_PUBLIC_API(2,0) operator<(const ASN1_Time&, const ASN1_Time&);
384bool 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
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*/
468bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&,
469 const AlgorithmIdentifier&);
470bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&,
471 const AlgorithmIdentifier&);
472
473}
474
475#endif
ASN1_Object & operator=(const ASN1_Object &)=default
ASN1_Object(const ASN1_Object &)=default
virtual ~ASN1_Object()=default
virtual void decode_from(BER_Decoder &from)=0
ASN1_Object()=default
virtual void encode_into(DER_Encoder &to) const =0
const std::string & value() const
Definition: asn1_obj.h:400
bool empty() const
Definition: asn1_obj.h:404
size_t size() const
Definition: asn1_obj.h:402
ASN1_Tag tagging() const
Definition: asn1_obj.h:398
ASN1_Time()=default
Create an invalid ASN1_Time.
bool parameters_are_empty() const
Definition: asn1_obj.h:449
bool parameters_are_null_or_empty() const
Definition: asn1_obj.h:451
const std::vector< uint8_t > & get_parameters() const
Definition: asn1_obj.h:446
const OID & get_oid() const
Definition: asn1_obj.h:445
std::vector< uint8_t > parameters
Definition: asn1_obj.h:462
size_t length() const
Definition: asn1_obj.h:121
ASN1_Tag type() const
Definition: asn1_obj.h:116
BER_Object(BER_Object &&other)=default
ASN1_Tag tagging() const
Definition: asn1_obj.h:114
const uint8_t * bits() const
Definition: asn1_obj.h:119
BER_Object & operator=(const BER_Object &other)=default
secure_vector< uint8_t > value
Definition: asn1_obj.h:137
BER_Object(const BER_Object &other)=default
bool is_set() const
Definition: asn1_obj.h:112
BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES class_tag
Definition: asn1_obj.h:136
BER_Object & operator=(BER_Object &&other)=default
ASN1_Tag get_class() const
Definition: asn1_obj.h:117
const std::vector< uint32_t > & get_id() const
Definition: asn1_obj.h:246
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 operator==(const OID &other) const
Definition: asn1_obj.h:273
OID(std::vector< uint32_t > &&init)
Definition: asn1_obj.h:216
bool has_value() const
Definition: asn1_obj.h:238
bool empty() const
Definition: asn1_obj.h:232
int(* init)(CTX *)
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
#define BOTAN_UNSTABLE_API
Definition: compiler.h:44
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:195
bool maybe_BER(DataSource &source)
Definition: asn1_obj.cpp:222
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
secure_vector< uint8_t > BER_encode(const Private_Key &key)
Definition: pkcs8.cpp:139
Definition: alg_id.cpp:13
ASN1_Tag
Definition: asn1_obj.h:25
@ UTC_TIME
Definition: asn1_obj.h:54
@ DIRECTORY_STRING
Definition: asn1_obj.h:59
@ CONSTRUCTED
Definition: asn1_obj.h:30
@ GENERALIZED_TIME
Definition: asn1_obj.h:55
@ IA5_STRING
Definition: asn1_obj.h:49
@ UNIVERSAL_STRING
Definition: asn1_obj.h:51
@ BIT_STRING
Definition: asn1_obj.h:37
@ PRINTABLE_STRING
Definition: asn1_obj.h:47
@ T61_STRING
Definition: asn1_obj.h:48
@ UTF8_STRING
Definition: asn1_obj.h:45
@ SEQUENCE
Definition: asn1_obj.h:42
@ APPLICATION
Definition: asn1_obj.h:27
@ NUMERIC_STRING
Definition: asn1_obj.h:46
@ BOOLEAN
Definition: asn1_obj.h:35
@ CONTEXT_SPECIFIC
Definition: asn1_obj.h:28
@ BMP_STRING
Definition: asn1_obj.h:52
@ ENUMERATED
Definition: asn1_obj.h:41
@ NO_OBJECT
Definition: asn1_obj.h:58
@ UTC_OR_GENERALIZED_TIME
Definition: asn1_obj.h:56
@ OCTET_STRING
Definition: asn1_obj.h:38
@ NULL_TAG
Definition: asn1_obj.h:39
@ UNIVERSAL
Definition: asn1_obj.h:26
@ VISIBLE_STRING
Definition: asn1_obj.h:50
@ EOC
Definition: asn1_obj.h:34
@ OBJECT_ID
Definition: asn1_obj.h:40
@ SET
Definition: asn1_obj.h:43
@ INTEGER
Definition: asn1_obj.h:36
@ PRIVATE
Definition: asn1_obj.h:32
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition: exceptn.cpp:11
std::string asn1_class_to_string(ASN1_Tag type)
Definition: asn1_obj.cpp:87
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
std::string asn1_tag_to_string(ASN1_Tag type)
Definition: asn1_obj.cpp:108
MechanismType type