Botan 3.0.0-alpha0
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 Class Tags
23*/
24enum class ASN1_Class : uint32_t {
25 Universal = 0b0000'0000,
26 Application = 0b0100'0000,
27 ContextSpecific = 0b1000'0000,
28 Private = 0b1100'0000,
29
30 Constructed = 0b0010'0000,
32
33 NoObject = 0xFF00
34};
35
36/**
37* ASN.1 Type Tags
38*/
39enum class ASN1_Type : uint32_t {
40 Eoc = 0x00,
41 Boolean = 0x01,
42 Integer = 0x02,
43 BitString = 0x03,
44 OctetString = 0x04,
45 Null = 0x05,
46 ObjectId = 0x06,
47 Enumerated = 0x0A,
48 Sequence = 0x10,
49 Set = 0x11,
50
51 Utf8String = 0x0C,
52 NumericString = 0x12,
53 PrintableString = 0x13,
54 TeletexString = 0x14,
55 Ia5String = 0x16,
56 VisibleString = 0x1A,
57 UniversalString = 0x1C,
58 BmpString = 0x1E,
59
60 UtcTime = 0x17,
61 GeneralizedTime = 0x18,
62
63 NoObject = 0xFF00,
64};
65
67 {
68 return static_cast<uint32_t>(x) & static_cast<uint32_t>(y);
69 }
70
72 {
73 return static_cast<ASN1_Type>(static_cast<uint32_t>(x) | static_cast<uint32_t>(y));
74 }
75
77 {
78 return static_cast<ASN1_Class>(static_cast<uint32_t>(x) | static_cast<uint32_t>(y));
79 }
80
81inline uint32_t operator|(ASN1_Type x, ASN1_Class y)
82 {
83 return static_cast<uint32_t>(x) | static_cast<uint32_t>(y);
84 }
85
86inline uint32_t operator|(ASN1_Class x, ASN1_Type y)
87 {
88 return static_cast<uint32_t>(x) | static_cast<uint32_t>(y);
89 }
90
93
94/**
95* Basic ASN.1 Object Interface
96*/
98 {
99 public:
100 /**
101 * Encode whatever this object is into to
102 * @param to the DER_Encoder that will be written to
103 */
104 virtual void encode_into(DER_Encoder& to) const = 0;
105
106 /**
107 * Decode whatever this object is from from
108 * @param from the BER_Decoder that will be read from
109 */
110 virtual void decode_from(BER_Decoder& from) = 0;
111
112 /**
113 * Return the encoding of this object. This is a convenience
114 * method when just one object needs to be serialized. Use
115 * DER_Encoder for complicated encodings.
116 */
117 std::vector<uint8_t> BER_encode() const;
118
119 ASN1_Object() = default;
120 ASN1_Object(const ASN1_Object&) = default;
121 ASN1_Object & operator=(const ASN1_Object&) = default;
122 virtual ~ASN1_Object() = default;
123 };
124
125/**
126* BER Encoded Object
127*/
129 {
130 public:
131 BER_Object() : m_type_tag(ASN1_Type::NoObject), m_class_tag(ASN1_Class::Universal) {}
132
133 BER_Object(const BER_Object& other) = default;
134
135 BER_Object& operator=(const BER_Object& other) = default;
136
137 BER_Object(BER_Object&& other) = default;
138
139 BER_Object& operator=(BER_Object&& other) = default;
140
141 bool is_set() const { return m_type_tag != ASN1_Type::NoObject; }
142
143 uint32_t tagging() const { return type_tag() | class_tag(); }
144
145 ASN1_Type type_tag() const { return m_type_tag; }
146 ASN1_Class class_tag() const { return m_class_tag; }
147
148 ASN1_Type type() const { return m_type_tag; }
149 ASN1_Class get_class() const { return m_class_tag; }
150
151 const uint8_t* bits() const { return m_value.data(); }
152
153 size_t length() const { return m_value.size(); }
154
155 void assert_is_a(ASN1_Type type_tag, ASN1_Class class_tag,
156 const std::string& descr = "object") const;
157
158 bool is_a(ASN1_Type type_tag, ASN1_Class class_tag) const;
159
160 bool is_a(int type_tag, ASN1_Class class_tag) const;
161
162 private:
163 ASN1_Type m_type_tag;
164 ASN1_Class m_class_tag;
166
167 friend class BER_Decoder;
168
169 void set_tagging(ASN1_Type type_tag, ASN1_Class class_tag);
170
171 uint8_t* mutable_bits(size_t length)
172 {
173 m_value.resize(length);
174 return m_value.data();
175 }
176 };
177
178/*
179* ASN.1 Utility Functions
180*/
181class DataSource;
182
183namespace ASN1 {
184
185std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& val);
186std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len);
187std::string to_string(const BER_Object& obj);
188
189/**
190* Heuristics tests; is this object possibly BER?
191* @param src a data source that will be peeked at but not modified
192*/
193bool maybe_BER(DataSource& src);
194
195}
196
197/**
198* General BER Decoding Error Exception
199*/
201 {
202 public:
203 explicit BER_Decoding_Error(const std::string&);
204 };
205
206/**
207* Exception For Incorrect BER Taggings
208*/
210 {
211 public:
212 BER_Bad_Tag(const std::string& msg, uint32_t tagging);
213 };
214
215/**
216* This class represents ASN.1 object identifiers.
217*/
219 {
220 public:
221
222 /**
223 * Create an uninitialied OID object
224 */
225 explicit OID() {}
226
227 /**
228 * Construct an OID from a string.
229 * @param str a string in the form "a.b.c" etc., where a,b,c are numbers
230 */
231 explicit OID(const std::string& str);
232
233 /**
234 * Initialize an OID from a sequence of integer values
235 */
236 explicit OID(std::initializer_list<uint32_t> init) : m_id(init) {}
237
238 /**
239 * Initialize an OID from a vector of integer values
240 */
241 explicit OID(std::vector<uint32_t>&& init) : m_id(init) {}
242
243 /**
244 * Construct an OID from a string.
245 * @param str a string in the form "a.b.c" etc., where a,b,c are numbers
246 * or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier")
247 */
248 static OID from_string(const std::string& str);
249
250 void encode_into(DER_Encoder&) const override;
251 void decode_from(BER_Decoder&) override;
252
253 /**
254 * Find out whether this OID is empty
255 * @return true is no OID value is set
256 */
257 bool empty() const { return m_id.empty(); }
258
259 /**
260 * Find out whether this OID has a value
261 * @return true is this OID has a value
262 */
263 bool has_value() const { return (m_id.empty() == false); }
264
265 /**
266 * Get this OID as list (vector) of its components.
267 * @return vector representing this OID
268 */
269 const std::vector<uint32_t>& get_components() const { return m_id; }
270
271 const std::vector<uint32_t>& get_id() const { return get_components(); }
272
273 /**
274 * Get this OID as a dotted-decimal string
275 * @return string representing this OID
276 */
277 std::string to_string() const;
278
279 /**
280 * If there is a known name associated with this OID, return that.
281 * Otherwise return the result of to_string
282 */
283 std::string to_formatted_string() const;
284
285 /**
286 * Compare two OIDs.
287 * @return true if they are equal, false otherwise
288 */
289 bool operator==(const OID& other) const
290 {
291 return m_id == other.m_id;
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);
356
357 /// Create an ASN1_Time from string and a specified tagging (Utc or Generalized)
358 ASN1_Time(const std::string& t_spec, ASN1_Type tag);
359
360 /// Returns a STL timepoint object
361 std::chrono::system_clock::time_point to_std_timepoint() const;
362
363 /// Return time since epoch
364 uint64_t time_since_epoch() const;
365
366 private:
367 void set_to(const std::string& t_spec, ASN1_Type type);
368 bool passes_sanity_check() const;
369
370 uint32_t m_year = 0;
371 uint32_t m_month = 0;
372 uint32_t m_day = 0;
373 uint32_t m_hour = 0;
374 uint32_t m_minute = 0;
375 uint32_t m_second = 0;
377 };
378
379/*
380* Comparison Operations
381*/
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&);
385bool BOTAN_PUBLIC_API(2,0) operator>=(const ASN1_Time&, const ASN1_Time&);
386bool BOTAN_PUBLIC_API(2,0) operator<(const ASN1_Time&, const ASN1_Time&);
387bool BOTAN_PUBLIC_API(2,0) operator>(const ASN1_Time&, const ASN1_Time&);
388
390
391/**
392* ASN.1 string type
393* This class normalizes all inputs to a UTF-8 std::string
394*/
396 {
397 public:
398 void encode_into(DER_Encoder&) const override;
399 void decode_from(BER_Decoder&) override;
400
401 ASN1_Type tagging() const { return m_tag; }
402
403 const std::string& value() const { return m_utf8_str; }
404
405 size_t size() const { return value().size(); }
406
407 bool empty() const { return m_utf8_str.empty(); }
408
409 /**
410 * Return true iff this is a tag for a known string type we can handle.
411 */
412 static bool is_string_type(ASN1_Type tag);
413
414 bool operator==(const ASN1_String& other) const
415 { return value() == other.value(); }
416
417 explicit ASN1_String(const std::string& utf8 = "");
418 ASN1_String(const std::string& utf8, ASN1_Type tag);
419 private:
420 std::vector<uint8_t> m_data;
421 std::string m_utf8_str;
422 ASN1_Type m_tag;
423 };
424
425/**
426* Algorithm Identifier
427*/
429 {
430 public:
431 enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM };
432
433 void encode_into(DER_Encoder&) const override;
434 void decode_from(BER_Decoder&) override;
435
437
438 AlgorithmIdentifier(const OID& oid, Encoding_Option enc);
439 AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc);
440
441 AlgorithmIdentifier(const OID& oid, const std::vector<uint8_t>& params);
442 AlgorithmIdentifier(const std::string& oid_name, const std::vector<uint8_t>& params);
443
444 const OID& oid() const { return m_oid; }
445 const std::vector<uint8_t>& parameters() const { return m_parameters; }
446
447 const OID& get_oid() const { return m_oid; }
448 const std::vector<uint8_t>& get_parameters() const { return m_parameters; }
449
450 bool parameters_are_null() const;
451 bool parameters_are_empty() const { return m_parameters.empty(); }
452
454 {
455 return parameters_are_empty() || parameters_are_null();
456 }
457
458 private:
459 OID m_oid;
460 std::vector<uint8_t> m_parameters;
461 };
462
463/*
464* Comparison Operations
465*/
466bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&,
467 const AlgorithmIdentifier&);
468bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&,
469 const AlgorithmIdentifier&);
470
471}
472
473#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:403
bool empty() const
Definition: asn1_obj.h:407
size_t size() const
Definition: asn1_obj.h:405
bool operator==(const ASN1_String &other) const
Definition: asn1_obj.h:414
ASN1_Type tagging() const
Definition: asn1_obj.h:401
ASN1_Time()=default
Create an invalid ASN1_Time.
bool parameters_are_empty() const
Definition: asn1_obj.h:451
bool parameters_are_null_or_empty() const
Definition: asn1_obj.h:453
const std::vector< uint8_t > & parameters() const
Definition: asn1_obj.h:445
const OID & oid() const
Definition: asn1_obj.h:444
const std::vector< uint8_t > & get_parameters() const
Definition: asn1_obj.h:448
const OID & get_oid() const
Definition: asn1_obj.h:447
size_t length() const
Definition: asn1_obj.h:153
BER_Object(BER_Object &&other)=default
const uint8_t * bits() const
Definition: asn1_obj.h:151
BER_Object & operator=(const BER_Object &other)=default
ASN1_Type type_tag() const
Definition: asn1_obj.h:145
uint32_t tagging() const
Definition: asn1_obj.h:143
BER_Object(const BER_Object &other)=default
bool is_set() const
Definition: asn1_obj.h:141
BER_Object & operator=(BER_Object &&other)=default
ASN1_Type type() const
Definition: asn1_obj.h:148
ASN1_Class get_class() const
Definition: asn1_obj.h:149
ASN1_Class class_tag() const
Definition: asn1_obj.h:146
const std::vector< uint32_t > & get_id() const
Definition: asn1_obj.h:271
const std::vector< uint32_t > & get_components() const
Definition: asn1_obj.h:269
OID(std::initializer_list< uint32_t > init)
Definition: asn1_obj.h:236
bool operator==(const OID &other) const
Definition: asn1_obj.h:289
OID(std::vector< uint32_t > &&init)
Definition: asn1_obj.h:241
bool has_value() const
Definition: asn1_obj.h:263
bool empty() const
Definition: asn1_obj.h:257
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
PolynomialVector b
Definition: kyber.cpp:821
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:191
bool maybe_BER(DataSource &source)
Definition: asn1_obj.cpp:218
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:209
std::vector< uint8_t > BER_encode(const Private_Key &key, RandomNumberGenerator &rng, const std::string &pass, std::chrono::milliseconds msec, const std::string &pbe_algo)
Definition: pkcs8.cpp:189
Definition: alg_id.cpp:13
ASN1_Type operator|(ASN1_Type x, ASN1_Type y)
Definition: asn1_obj.h:71
std::string asn1_tag_to_string(ASN1_Type type)
Definition: asn1_obj.cpp:108
ASN1_Class
Definition: asn1_obj.h:24
ASN1_Type
Definition: asn1_obj.h:39
std::string asn1_class_to_string(ASN1_Class type)
Definition: asn1_obj.cpp:87
bool intersects(ASN1_Class x, ASN1_Class y)
Definition: asn1_obj.h:66
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition: exceptn.cpp:11
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
MechanismType type