Coverage Report

Created: 2020-11-21 08:34

/src/botan/build/include/botan/asn1_obj.h
Line
Count
Source (jump to first uncovered line)
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,
28
   CONTEXT_SPECIFIC = 0x80,
29
30
   CONSTRUCTED      = 0x20,
31
32
   PRIVATE          = CONSTRUCTED | CONTEXT_SPECIFIC,
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,
46
   NUMERIC_STRING   = 0x12,
47
   PRINTABLE_STRING = 0x13,
48
   T61_STRING       = 0x14,
49
   IA5_STRING       = 0x16,
50
   VISIBLE_STRING   = 0x1A,
51
   UNIVERSAL_STRING = 0x1C,
52
   BMP_STRING       = 0x1E,
53
54
   UTC_TIME                = 0x17,
55
   GENERALIZED_TIME        = 0x18,
56
   UTC_OR_GENERALIZED_TIME = 0x19,
57
58
   NO_OBJECT        = 0xFF00,
59
   DIRECTORY_STRING = 0xFF01
60
};
61
62
std::string BOTAN_UNSTABLE_API asn1_tag_to_string(ASN1_Tag type);
63
std::string BOTAN_UNSTABLE_API asn1_class_to_string(ASN1_Tag type);
64
65
/**
66
* Basic ASN.1 Object Interface
67
*/
68
class BOTAN_PUBLIC_API(2,0) ASN1_Object
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
1.28M
      ASN1_Object() = default;
91
1.55M
      ASN1_Object(const ASN1_Object&) = default;
92
5.84k
      ASN1_Object & operator=(const ASN1_Object&) = default;
93
2.83M
      virtual ~ASN1_Object() = default;
94
   };
95
96
/**
97
* BER Encoded Object
98
*/
99
class BOTAN_PUBLIC_API(2,0) BER_Object final
100
   {
101
   public:
102
2.27M
      BER_Object() : m_type_tag(NO_OBJECT), m_class_tag(UNIVERSAL) {}
103
104
      BER_Object(const BER_Object& other) = default;
105
106
7.02k
      BER_Object& operator=(const BER_Object& other) = default;
107
108
611k
      BER_Object(BER_Object&& other) = default;
109
110
332k
      BER_Object& operator=(BER_Object&& other) = default;
111
112
3.41M
      bool is_set() const { return m_type_tag != NO_OBJECT; }
113
114
1.64M
      ASN1_Tag tagging() const { return ASN1_Tag(type() | get_class()); }
115
116
0
      ASN1_Tag type_tag() const { return m_type_tag; }
117
0
      ASN1_Tag class_tag() const { return m_class_tag; }
118
119
2.01M
      ASN1_Tag type() const { return m_type_tag; }
120
1.71M
      ASN1_Tag get_class() const { return m_class_tag; }
121
122
16.3M
      const uint8_t* bits() const { return m_value.data(); }
123
124
34.4M
      size_t length() const { return m_value.size(); }
125
126
      void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag,
127
                       const std::string& descr = "object") const;
128
129
      bool is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const;
130
131
      bool is_a(int type_tag, ASN1_Tag class_tag) const;
132
133
   private:
134
      ASN1_Tag m_type_tag, m_class_tag;
135
      secure_vector<uint8_t> m_value;
136
137
      friend class BER_Decoder;
138
139
      void set_tagging(ASN1_Tag type_tag, ASN1_Tag class_tag);
140
141
      uint8_t* mutable_bits(size_t length)
142
1.39M
         {
143
1.39M
         m_value.resize(length);
144
1.39M
         return m_value.data();
145
1.39M
         }
146
   };
147
148
/*
149
* ASN.1 Utility Functions
150
*/
151
class DataSource;
152
153
namespace ASN1 {
154
155
std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& val);
156
std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len);
157
std::string to_string(const BER_Object& obj);
158
159
/**
160
* Heuristics tests; is this object possibly BER?
161
* @param src a data source that will be peeked at but not modified
162
*/
163
bool maybe_BER(DataSource& src);
164
165
}
166
167
/**
168
* General BER Decoding Error Exception
169
*/
170
class BOTAN_PUBLIC_API(2,0) BER_Decoding_Error : public Decoding_Error
171
   {
172
   public:
173
      explicit BER_Decoding_Error(const std::string&);
174
   };
175
176
/**
177
* Exception For Incorrect BER Taggings
178
*/
179
class BOTAN_PUBLIC_API(2,0) BER_Bad_Tag final : public BER_Decoding_Error
180
   {
181
   public:
182
      BER_Bad_Tag(const std::string& msg, ASN1_Tag tag);
183
      BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2);
184
   };
185
186
/**
187
* This class represents ASN.1 object identifiers.
188
*/
189
class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object
190
   {
191
   public:
192
193
      /**
194
      * Create an uninitialied OID object
195
      */
196
264k
      explicit OID() {}
197
198
      /**
199
      * Construct an OID from a string.
200
      * @param str a string in the form "a.b.c" etc., where a,b,c are numbers
201
      */
202
      explicit OID(const std::string& str);
203
204
      /**
205
      * Initialize an OID from a sequence of integer values
206
      */
207
24.9k
      explicit OID(std::initializer_list<uint32_t> init) : m_id(init) {}
208
209
      /**
210
      * Initialize an OID from a vector of integer values
211
      */
212
0
      explicit OID(std::vector<uint32_t>&& init) : m_id(init) {}
213
214
      /**
215
      * Construct an OID from a string.
216
      * @param str a string in the form "a.b.c" etc., where a,b,c are numbers
217
      *        or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier")
218
      */
219
      static OID from_string(const std::string& str);
220
221
      void encode_into(class DER_Encoder&) const override;
222
      void decode_from(class BER_Decoder&) override;
223
224
      /**
225
      * Find out whether this OID is empty
226
      * @return true is no OID value is set
227
      */
228
21.8k
      bool empty() const { return m_id.empty(); }
229
230
      /**
231
      * Find out whether this OID has a value
232
      * @return true is this OID has a value
233
      */
234
38.0k
      bool has_value() const { return (m_id.empty() == false); }
235
236
      /**
237
      * Get this OID as list (vector) of its components.
238
      * @return vector representing this OID
239
      */
240
1.39M
      const std::vector<uint32_t>& get_components() const { return m_id; }
241
242
0
      const std::vector<uint32_t>& get_id() const { return get_components(); }
243
244
      /**
245
      * Get this OID as a dotted-decimal string
246
      * @return string representing this OID
247
      */
248
      std::string to_string() const;
249
250
      /**
251
      * If there is a known name associated with this OID, return that.
252
      * Otherwise return the result of to_string
253
      */
254
      std::string to_formatted_string() const;
255
256
      /**
257
      * Compare two OIDs.
258
      * @return true if they are equal, false otherwise
259
      */
260
      bool operator==(const OID& other) const
261
631k
         {
262
631k
         return m_id == other.m_id;
263
631k
         }
264
265
   private:
266
      std::vector<uint32_t> m_id;
267
   };
268
269
/**
270
* Append another component onto the OID.
271
* @param oid the OID to add the new component to
272
* @param new_comp the new component to add
273
*/
274
OID BOTAN_PUBLIC_API(2,0) operator+(const OID& oid, uint32_t new_comp);
275
276
/**
277
* Compare two OIDs.
278
* @param a the first OID
279
* @param b the second OID
280
* @return true if a is not equal to b
281
*/
282
inline bool operator!=(const OID& a, const OID& b)
283
87.5k
   {
284
87.5k
   return !(a == b);
285
87.5k
   }
286
287
/**
288
* Compare two OIDs.
289
* @param a the first OID
290
* @param b the second OID
291
* @return true if a is lexicographically smaller than b
292
*/
293
bool BOTAN_PUBLIC_API(2,0) operator<(const OID& a, const OID& b);
294
295
/**
296
* Time (GeneralizedTime/UniversalTime)
297
*/
298
class BOTAN_PUBLIC_API(2,0) ASN1_Time final : public ASN1_Object
299
   {
300
   public:
301
      /// DER encode a ASN1_Time
302
      void encode_into(DER_Encoder&) const override;
303
304
      // Decode a BER encoded ASN1_Time
305
      void decode_from(BER_Decoder&) override;
306
307
      /// Return an internal string representation of the time
308
      std::string to_string() const;
309
310
      /// Returns a human friendly string replesentation of no particular formatting
311
      std::string readable_string() const;
312
313
      /// Return if the time has been set somehow
314
      bool time_is_set() const;
315
316
      ///  Compare this time against another
317
      int32_t cmp(const ASN1_Time& other) const;
318
319
      /// Create an invalid ASN1_Time
320
60.1k
      ASN1_Time() = default;
321
322
      /// Create a ASN1_Time from a time point
323
      explicit ASN1_Time(const std::chrono::system_clock::time_point& time);
324
325
      /// Create an ASN1_Time from string
326
      ASN1_Time(const std::string& t_spec, ASN1_Tag tag);
327
328
      /// Returns a STL timepoint object
329
      std::chrono::system_clock::time_point to_std_timepoint() const;
330
331
      /// Return time since epoch
332
      uint64_t time_since_epoch() const;
333
334
   private:
335
      void set_to(const std::string& t_spec, ASN1_Tag);
336
      bool passes_sanity_check() const;
337
338
      uint32_t m_year = 0;
339
      uint32_t m_month = 0;
340
      uint32_t m_day = 0;
341
      uint32_t m_hour = 0;
342
      uint32_t m_minute = 0;
343
      uint32_t m_second = 0;
344
      ASN1_Tag m_tag = NO_OBJECT;
345
   };
346
347
/*
348
* Comparison Operations
349
*/
350
bool BOTAN_PUBLIC_API(2,0) operator==(const ASN1_Time&, const ASN1_Time&);
351
bool BOTAN_PUBLIC_API(2,0) operator!=(const ASN1_Time&, const ASN1_Time&);
352
bool BOTAN_PUBLIC_API(2,0) operator<=(const ASN1_Time&, const ASN1_Time&);
353
bool BOTAN_PUBLIC_API(2,0) operator>=(const ASN1_Time&, const ASN1_Time&);
354
bool BOTAN_PUBLIC_API(2,0) operator<(const ASN1_Time&, const ASN1_Time&);
355
bool BOTAN_PUBLIC_API(2,0) operator>(const ASN1_Time&, const ASN1_Time&);
356
357
typedef ASN1_Time X509_Time;
358
359
/**
360
* ASN.1 string type
361
* This class normalizes all inputs to a UTF-8 std::string
362
*/
363
class BOTAN_PUBLIC_API(2,0) ASN1_String final : public ASN1_Object
364
   {
365
   public:
366
      void encode_into(class DER_Encoder&) const override;
367
      void decode_from(class BER_Decoder&) override;
368
369
954
      ASN1_Tag tagging() const { return m_tag; }
370
371
189k
      const std::string& value() const { return m_utf8_str; }
372
373
0
      size_t size() const { return value().size(); }
374
375
110k
      bool empty() const { return m_utf8_str.empty(); }
376
377
      /**
378
      * Return true iff this is a tag for a known string type we can handle.
379
      * This ignores string types that are not supported, eg teletexString
380
      */
381
      static bool is_string_type(ASN1_Tag tag);
382
383
      bool operator==(const ASN1_String& other) const
384
0
         { return value() == other.value(); }
385
386
      explicit ASN1_String(const std::string& utf8 = "");
387
      ASN1_String(const std::string& utf8, ASN1_Tag tag);
388
   private:
389
      std::vector<uint8_t> m_data;
390
      std::string m_utf8_str;
391
      ASN1_Tag m_tag;
392
   };
393
394
/**
395
* Algorithm Identifier
396
*/
397
class BOTAN_PUBLIC_API(2,0) AlgorithmIdentifier final : public ASN1_Object
398
   {
399
   public:
400
      enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM };
401
402
      void encode_into(class DER_Encoder&) const override;
403
      void decode_from(class BER_Decoder&) override;
404
405
84.5k
      AlgorithmIdentifier() = default;
406
407
      AlgorithmIdentifier(const OID& oid, Encoding_Option enc);
408
      AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc);
409
410
      AlgorithmIdentifier(const OID& oid, const std::vector<uint8_t>& params);
411
      AlgorithmIdentifier(const std::string& oid_name, const std::vector<uint8_t>& params);
412
413
11.6k
      const OID& oid() const { return m_oid; }
414
12.1k
      const std::vector<uint8_t>& parameters() const { return m_parameters; }
415
416
84.3k
      const OID& get_oid() const { return m_oid; }
417
5.11k
      const std::vector<uint8_t>& get_parameters() const { return m_parameters; }
418
419
      bool parameters_are_null() const;
420
49.9k
      bool parameters_are_empty() const { return m_parameters.empty(); }
421
422
      bool parameters_are_null_or_empty() const
423
49.8k
         {
424
49.8k
         return parameters_are_empty() || parameters_are_null();
425
49.8k
         }
426
427
   private:
428
      OID m_oid;
429
      std::vector<uint8_t> m_parameters;
430
   };
431
432
/*
433
* Comparison Operations
434
*/
435
bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&,
436
                                      const AlgorithmIdentifier&);
437
bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&,
438
                                      const AlgorithmIdentifier&);
439
440
}
441
442
#endif