PcapPlusPlus  Next
Asn1Codec.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <string>
4 #include <memory>
5 #include <typeinfo>
6 #include <stdexcept>
7 #include <sstream>
8 #include "PointerVector.h"
9 
11 
14 namespace pcpp
15 {
17  enum class Asn1TagClass : uint8_t
18  {
20  Universal = 0,
22  Application = 1,
24  ContextSpecific = 2,
26  Private = 3,
27  };
28 
30  enum class Asn1UniversalTagType : uint8_t
31  {
33  EndOfContent = 0,
35  Boolean = 1,
37  Integer = 2,
39  BitString = 3,
41  OctetString = 4,
43  Null = 5,
45  ObjectIdentifier = 6,
47  ObjectDescriptor = 7,
49  External = 8,
51  Real = 9,
53  Enumerated = 10,
55  EmbeddedPDV = 11,
57  UTF8String = 12,
61  Time = 14,
63  Reserved = 15,
65  Sequence = 16,
67  Set = 17,
69  NumericString = 18,
71  PrintableString = 19,
73  T61String = 20,
75  VideotexString = 21,
77  IA5String = 22,
79  UTCTime = 23,
81  GeneralizedTime = 24,
83  GraphicString = 25,
85  VisibleString = 26,
87  GeneralString = 27,
89  UniversalString = 28,
91  CharacterString = 29,
93  BMPString = 30,
95  Date = 31,
97  TimeOfDay = 32,
99  DateTime = 33,
101  Duration = 34,
103  ObjectIdentifierIRI = 35,
107  NotApplicable = 255
108  };
109 
115  {
116  public:
124  static std::unique_ptr<Asn1Record> decode(const uint8_t* data, size_t dataLen, bool lazy = true);
125 
128  std::vector<uint8_t> encode();
129 
132  {
133  return m_TagClass;
134  }
135 
137  bool isConstructed() const
138  {
139  return m_IsConstructed;
140  }
141 
145 
147  uint8_t getTagType() const
148  {
149  return m_TagType;
150  }
151 
153  size_t getValueLength() const
154  {
155  return m_ValueLength;
156  }
157 
159  size_t getTotalLength() const
160  {
161  return m_TotalLength;
162  }
163 
165  std::string toString();
166 
171  template <class Asn1RecordType> Asn1RecordType* castAs()
172  {
173  auto result = dynamic_cast<Asn1RecordType*>(this);
174  if (result == nullptr)
175  {
176  throw std::bad_cast();
177  }
178  return result;
179  }
180 
181  virtual ~Asn1Record() = default;
182 
183  protected:
185  bool m_IsConstructed = false;
186  uint8_t m_TagType = 0;
187 
188  size_t m_ValueLength = 0;
189  size_t m_TotalLength = 0;
190 
191  uint8_t* m_EncodedValue = nullptr;
192 
193  Asn1Record() = default;
194 
195  static Asn1Record* decodeInternal(const uint8_t* data, size_t dataLen, bool lazy);
196 
197  virtual void decodeValue(uint8_t* data, bool lazy) = 0;
198  virtual std::vector<uint8_t> encodeValue() const = 0;
199 
200  static Asn1Record* decodeTagAndCreateRecord(const uint8_t* data, size_t dataLen, uint8_t& tagLen);
201  uint8_t decodeLength(const uint8_t* data, size_t dataLen);
202  void decodeValueIfNeeded();
203 
204  uint8_t encodeTag();
205  std::vector<uint8_t> encodeLength() const;
206 
207  virtual std::vector<std::string> toStringList();
208 
209  friend class Asn1ConstructedRecord;
210  };
211 
216  {
217  friend class Asn1Record;
218 
219  public:
226  Asn1GenericRecord(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const uint8_t* value,
227  size_t valueLen);
228 
234  Asn1GenericRecord(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const std::string& value);
235 
236  ~Asn1GenericRecord() override;
237 
239  const uint8_t* getValue()
240  {
241  decodeValueIfNeeded();
242  return m_Value;
243  }
244 
245  protected:
246  Asn1GenericRecord() = default;
247 
248  void decodeValue(uint8_t* data, bool lazy) override;
249  std::vector<uint8_t> encodeValue() const override;
250 
251  private:
252  uint8_t* m_Value = nullptr;
253 
254  void init(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const uint8_t* value, size_t valueLen);
255  };
256 
260  {
261  friend class Asn1Record;
262 
263  public:
268  explicit Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType,
269  const std::vector<Asn1Record*>& subRecords);
270 
275  explicit Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType,
276  const PointerVector<Asn1Record>& subRecords);
277 
281  {
282  decodeValueIfNeeded();
283  return m_SubRecords;
284  };
285 
286  protected:
287  Asn1ConstructedRecord() = default;
288 
289  void decodeValue(uint8_t* data, bool lazy) override;
290  std::vector<uint8_t> encodeValue() const override;
291 
292  std::vector<std::string> toStringList() override;
293 
294  template <typename Iterator> void init(Asn1TagClass tagClass, uint8_t tagType, Iterator begin, Iterator end)
295  {
296  m_TagType = tagType;
297  m_TagClass = tagClass;
298  m_IsConstructed = true;
299 
300  size_t recordValueLength = 0;
301  for (Iterator recordIter = begin; recordIter != end; ++recordIter)
302  {
303  auto encodedRecord = (*recordIter)->encode();
304  auto copyRecord = Asn1Record::decode(encodedRecord.data(), encodedRecord.size(), false);
305  m_SubRecords.pushBack(std::move(copyRecord));
306  recordValueLength += encodedRecord.size();
307  }
308 
309  m_ValueLength = recordValueLength;
310  m_TotalLength = recordValueLength + 1 + (m_ValueLength < 128 ? 1 : 2);
311  }
312 
313  private:
314  PointerVector<Asn1Record> m_SubRecords;
315  };
316 
320  {
321  friend class Asn1Record;
322 
323  public:
326  explicit Asn1SequenceRecord(const std::vector<Asn1Record*>& subRecords);
327 
330  explicit Asn1SequenceRecord(const PointerVector<Asn1Record>& subRecords);
331 
332  private:
333  Asn1SequenceRecord() = default;
334  };
335 
339  {
340  friend class Asn1Record;
341 
342  public:
345  explicit Asn1SetRecord(const std::vector<Asn1Record*>& subRecords);
346 
349  explicit Asn1SetRecord(const PointerVector<Asn1Record>& subRecords);
350 
351  private:
352  Asn1SetRecord() = default;
353  };
354 
359  {
360  friend class Asn1Record;
361 
362  protected:
363  Asn1PrimitiveRecord() = default;
364  explicit Asn1PrimitiveRecord(Asn1UniversalTagType tagType);
365  };
366 
370  {
371  friend class Asn1Record;
372 
373  public:
374  template <typename T>
375  using EnableIfUnsignedIntegral =
376  std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value, int>;
377 
380  explicit Asn1IntegerRecord(uint64_t value);
381 
385  explicit Asn1IntegerRecord(const std::string& value);
386 
389  template <typename T, EnableIfUnsignedIntegral<T> = 0> T getIntValue()
390  {
391  decodeValueIfNeeded();
392  return m_Value.getInt<T>();
393  }
394 
396  PCPP_DEPRECATED("Use getIntValue instead")
397  uint32_t getValue()
398  {
399  return getIntValue<uint32_t>();
400  }
401 
403  std::string getValueAsString()
404  {
405  decodeValueIfNeeded();
406  return m_Value.toString();
407  }
408 
409  protected:
410  Asn1IntegerRecord() = default;
411 
412  void decodeValue(uint8_t* data, bool lazy) override;
413  std::vector<uint8_t> encodeValue() const override;
414 
415  std::vector<std::string> toStringList() override;
416 
417  private:
418  class BigInt
419  {
420  public:
421  BigInt() = default;
422 
423  template <typename T, EnableIfUnsignedIntegral<T> = 0> explicit BigInt(T value)
424  {
425  m_Value = initFromInt(value);
426  }
427 
428  explicit BigInt(const std::string& value);
429  BigInt(const BigInt& other);
430 
431  template <typename T, EnableIfUnsignedIntegral<T> = 0> BigInt& operator=(T value)
432  {
433  m_Value = initFromInt(value);
434  return *this;
435  }
436  BigInt& operator=(const std::string& value);
437  size_t size() const;
438 
439  template <typename T, EnableIfUnsignedIntegral<T> = 0> T getInt() const
440  {
441  if (!canFit<T>())
442  {
443  throw std::overflow_error("Value cannot fit into requested int type");
444  }
445 
446  std::stringstream sstream;
447  sstream << std::hex << m_Value;
448 
449  uint64_t result;
450  sstream >> result;
451  return static_cast<T>(result);
452  }
453 
454  template <typename T, EnableIfUnsignedIntegral<T> = 0> bool canFit() const
455  {
456  return sizeof(T) >= (m_Value.size() + 1) / 2;
457  }
458 
459  std::string toString() const;
460  std::vector<uint8_t> toBytes() const;
461 
462  private:
463  std::string m_Value;
464 
465  static std::string initFromString(const std::string& value);
466 
467  template <typename T, EnableIfUnsignedIntegral<T> = 0> static std::string initFromInt(T value)
468  {
469  std::stringstream ss;
470  ss << std::hex << static_cast<uint64_t>(value);
471  return ss.str();
472  }
473  };
474 
475  BigInt m_Value;
476  };
477 
481  {
482  friend class Asn1Record;
483 
484  public:
487  explicit Asn1EnumeratedRecord(uint32_t value);
488 
489  private:
490  Asn1EnumeratedRecord() = default;
491  };
492 
496  {
497  friend class Asn1Record;
498 
499  public:
502  explicit Asn1OctetStringRecord(const std::string& value);
503 
507  explicit Asn1OctetStringRecord(const uint8_t* value, size_t valueLength);
508 
510  std::string getValue()
511  {
512  decodeValueIfNeeded();
513  return m_Value;
514  };
515 
516  protected:
517  void decodeValue(uint8_t* data, bool lazy) override;
518  std::vector<uint8_t> encodeValue() const override;
519 
520  std::vector<std::string> toStringList() override;
521 
522  private:
523  std::string m_Value;
524  bool m_IsPrintable = true;
525 
526  Asn1OctetStringRecord() = default;
527  };
528 
532  {
533  friend class Asn1Record;
534 
535  public:
538  explicit Asn1BooleanRecord(bool value);
539 
541  bool getValue()
542  {
543  decodeValueIfNeeded();
544  return m_Value;
545  };
546 
547  protected:
548  void decodeValue(uint8_t* data, bool lazy) override;
549  std::vector<uint8_t> encodeValue() const override;
550 
551  std::vector<std::string> toStringList() override;
552 
553  private:
554  Asn1BooleanRecord() = default;
555 
556  bool m_Value = false;
557  };
558 
562  {
563  friend class Asn1Record;
564 
565  public:
568 
569  protected:
570  void decodeValue(uint8_t* data, bool lazy) override
571  {}
572  std::vector<uint8_t> encodeValue() const override
573  {
574  return {};
575  }
576  };
577 } // namespace pcpp
Definition: Asn1Codec.h:532
Asn1BooleanRecord(bool value)
bool getValue()
Definition: Asn1Codec.h:541
Definition: Asn1Codec.h:260
PointerVector< Asn1Record > & getSubRecords()
Definition: Asn1Codec.h:280
Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType, const PointerVector< Asn1Record > &subRecords)
Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType, const std::vector< Asn1Record * > &subRecords)
Definition: Asn1Codec.h:481
Asn1EnumeratedRecord(uint32_t value)
Definition: Asn1Codec.h:216
const uint8_t * getValue()
Definition: Asn1Codec.h:239
Asn1GenericRecord(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const uint8_t *value, size_t valueLen)
Asn1GenericRecord(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const std::string &value)
Definition: Asn1Codec.h:370
Asn1IntegerRecord(uint64_t value)
T getIntValue()
Definition: Asn1Codec.h:389
uint32_t getValue()
Definition: Asn1Codec.h:397
std::string getValueAsString()
Definition: Asn1Codec.h:403
Asn1IntegerRecord(const std::string &value)
Definition: Asn1Codec.h:562
Asn1NullRecord()
A constructor to create a record of type Null.
Definition: Asn1Codec.h:496
Asn1OctetStringRecord(const std::string &value)
std::string getValue()
Definition: Asn1Codec.h:510
Asn1OctetStringRecord(const uint8_t *value, size_t valueLength)
Definition: Asn1Codec.h:359
Definition: Asn1Codec.h:115
uint8_t getTagType() const
Definition: Asn1Codec.h:147
std::vector< uint8_t > encode()
bool isConstructed() const
Definition: Asn1Codec.h:137
Asn1UniversalTagType getUniversalTagType() const
Asn1TagClass getTagClass() const
Definition: Asn1Codec.h:131
std::string toString()
size_t getTotalLength() const
Definition: Asn1Codec.h:159
Asn1RecordType * castAs()
Definition: Asn1Codec.h:171
size_t getValueLength() const
Definition: Asn1Codec.h:153
static std::unique_ptr< Asn1Record > decode(const uint8_t *data, size_t dataLen, bool lazy=true)
Definition: Asn1Codec.h:320
Asn1SequenceRecord(const PointerVector< Asn1Record > &subRecords)
Asn1SequenceRecord(const std::vector< Asn1Record * > &subRecords)
Definition: Asn1Codec.h:339
Asn1SetRecord(const PointerVector< Asn1Record > &subRecords)
Asn1SetRecord(const std::vector< Asn1Record * > &subRecords)
Definition: PointerVector.h:50
The main namespace for the PcapPlusPlus lib.
Asn1TagClass
An enum for representing ASN.1 tag class.
Definition: Asn1Codec.h:18
@ ContextSpecific
The Context-Specific tag class.
@ Private
The Private tag class.
@ Universal
The Universal tag class.
@ Application
The Application tag class.
Asn1UniversalTagType
An enum for representing ASN.1 Universal tag types.
Definition: Asn1Codec.h:31
@ BitString
The universal tag type for Bit String.
@ Enumerated
The universal tag type for Enumerated.
@ ObjectIdentifierIRI
The universal tag type for Object Identifier Internationalized Resource Identifier (IRI)
@ ObjectDescriptor
The universal tag type for Object Descriptor.
@ TimeOfDay
The universal tag type for Time of Day.
@ GraphicString
The universal tag type for GraphicString.
@ UTCTime
The universal tag type for UTC time.
@ Boolean
The universal tag type for Boolean.
@ EmbeddedPDV
The universal tag type for Embedded-PDV.
@ OctetString
The universal tag type for Octet String.
@ UniversalString
The universal tag type for UniversalString.
@ Sequence
The universal tag type Sequence.
@ Date
The universal tag type for Date.
@ RelativeObjectIdentifierIRI
The universal tag type for Relative Object Identifier Internationalized Resource Identifier (IRI)
@ PrintableString
The universal tag type for Printable String.
@ CharacterString
The universal tag type for CharacterString.
@ RelativeObjectIdentifier
The universal tag type for Relative Object Identifier.
@ Set
The universal tag type for Set.
@ ObjectIdentifier
The universal tag type for Object Identifier.
@ IA5String
The universal tag type for IA5String.
@ VideotexString
The universal tag type for Videotex String.
@ NotApplicable
A non-applicable value.
@ Real
The universal tag type for Real.
@ DateTime
The universal tag type for Date-Time.
@ EndOfContent
The reserved identifier for the End-of-Contents marker in an indefinite length encoding.
@ Reserved
A reserved value.
@ Integer
The universal tag type for Integer.
@ Time
The universal tag type for Time.
@ External
The universal tag type for External.
@ BMPString
The universal tag type for BMPString.
@ UTF8String
The universal tag type for UTF8 String.
@ Null
The universal tag type for Null.
@ GeneralizedTime
The universal tag type for Generalized time.
@ T61String
The universal tag type for T61String.
@ Duration
The universal tag type for Duration.
@ VisibleString
The universal tag type for VisibleString.
@ GeneralString
The universal tag type for GeneralString.
@ NumericString
The universal tag type for Numeric String.