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 <chrono>
9 #include <bitset>
10 #include "PointerVector.h"
11 
13 
16 namespace pcpp
17 {
19  enum class Asn1TagClass : uint8_t
20  {
22  Universal = 0,
24  Application = 1,
26  ContextSpecific = 2,
28  Private = 3,
29  };
30 
32  enum class Asn1UniversalTagType : uint8_t
33  {
35  EndOfContent = 0,
37  Boolean = 1,
39  Integer = 2,
41  BitString = 3,
43  OctetString = 4,
45  Null = 5,
47  ObjectIdentifier = 6,
49  ObjectDescriptor = 7,
51  External = 8,
53  Real = 9,
55  Enumerated = 10,
57  EmbeddedPDV = 11,
59  UTF8String = 12,
63  Time = 14,
65  Reserved = 15,
67  Sequence = 16,
69  Set = 17,
71  NumericString = 18,
73  PrintableString = 19,
75  T61String = 20,
77  VideotexString = 21,
79  IA5String = 22,
81  UTCTime = 23,
83  GeneralizedTime = 24,
85  GraphicString = 25,
87  VisibleString = 26,
89  GeneralString = 27,
91  UniversalString = 28,
93  CharacterString = 29,
95  BMPString = 30,
97  Date = 31,
99  TimeOfDay = 32,
101  DateTime = 33,
103  Duration = 34,
105  ObjectIdentifierIRI = 35,
109  NotApplicable = 255
110  };
111 
117  {
118  public:
126  static std::unique_ptr<Asn1Record> decode(const uint8_t* data, size_t dataLen, bool lazy = true);
127 
130  std::vector<uint8_t> encode();
131 
134  {
135  return m_TagClass;
136  }
137 
139  bool isConstructed() const
140  {
141  return m_IsConstructed;
142  }
143 
147 
149  uint8_t getTagType() const
150  {
151  return m_TagType;
152  }
153 
155  size_t getValueLength() const
156  {
157  return m_ValueLength;
158  }
159 
161  size_t getTotalLength() const
162  {
163  return m_TotalLength;
164  }
165 
167  std::string toString();
168 
173  template <class Asn1RecordType> Asn1RecordType* castAs()
174  {
175  auto result = dynamic_cast<Asn1RecordType*>(this);
176  if (result == nullptr)
177  {
178  throw std::bad_cast();
179  }
180  return result;
181  }
182 
183  virtual ~Asn1Record() = default;
184 
185  protected:
187  bool m_IsConstructed = false;
188  uint8_t m_TagType = 0;
189 
190  size_t m_ValueLength = 0;
191  size_t m_TotalLength = 0;
192 
193  uint8_t const* m_EncodedValue = nullptr;
194 
195  Asn1Record() = default;
196 
197  static std::unique_ptr<Asn1Record> decodeInternal(const uint8_t* data, size_t dataLen, bool lazy);
198 
199  virtual void decodeValue(uint8_t const* data, bool lazy) = 0;
200  virtual std::vector<uint8_t> encodeValue() const = 0;
201 
202  static std::unique_ptr<Asn1Record> decodeTagAndCreateRecord(const uint8_t* data, size_t dataLen,
203  uint8_t& tagLen);
204  uint8_t decodeLength(const uint8_t* data, size_t dataLen);
205  void decodeValueIfNeeded();
206 
207  uint8_t encodeTag();
208  std::vector<uint8_t> encodeLength() const;
209 
210  virtual std::vector<std::string> toStringList();
211 
212  friend class Asn1ConstructedRecord;
213  };
214 
219  {
220  friend class Asn1Record;
221 
222  public:
229  Asn1GenericRecord(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const uint8_t* value,
230  size_t valueLen);
231 
237  Asn1GenericRecord(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const std::string& value);
238 
239  ~Asn1GenericRecord() override = default;
240 
242  const uint8_t* getValue()
243  {
244  decodeValueIfNeeded();
245  return m_Value.get();
246  }
247 
248  protected:
249  Asn1GenericRecord() = default;
250 
251  void decodeValue(uint8_t const* data, bool lazy) override;
252  std::vector<uint8_t> encodeValue() const override;
253 
254  private:
255  std::unique_ptr<uint8_t[]> m_Value = nullptr;
256 
257  void init(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const uint8_t* value, size_t valueLen);
258  };
259 
263  {
264  friend class Asn1Record;
265 
266  public:
271  explicit Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType,
272  const std::vector<Asn1Record*>& subRecords);
273 
278  explicit Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType,
279  const PointerVector<Asn1Record>& subRecords);
280 
284  {
285  decodeValueIfNeeded();
286  return m_SubRecords;
287  };
288 
289  protected:
290  Asn1ConstructedRecord() = default;
291 
292  void decodeValue(uint8_t const* data, bool lazy) override;
293  std::vector<uint8_t> encodeValue() const override;
294 
295  std::vector<std::string> toStringList() override;
296 
297  template <typename Iterator> void init(Asn1TagClass tagClass, uint8_t tagType, Iterator begin, Iterator end)
298  {
299  m_TagType = tagType;
300  m_TagClass = tagClass;
301  m_IsConstructed = true;
302 
303  size_t recordValueLength = 0;
304  for (Iterator recordIter = begin; recordIter != end; ++recordIter)
305  {
306  auto encodedRecord = (*recordIter)->encode();
307  auto copyRecord = Asn1Record::decode(encodedRecord.data(), encodedRecord.size(), false);
308  m_SubRecords.pushBack(std::move(copyRecord));
309  recordValueLength += encodedRecord.size();
310  }
311 
312  m_ValueLength = recordValueLength;
313  m_TotalLength = recordValueLength + 1 + (m_ValueLength < 128 ? 1 : 2);
314  }
315 
316  private:
317  PointerVector<Asn1Record> m_SubRecords;
318  };
319 
323  {
324  friend class Asn1Record;
325 
326  public:
329  explicit Asn1SequenceRecord(const std::vector<Asn1Record*>& subRecords);
330 
333  explicit Asn1SequenceRecord(const PointerVector<Asn1Record>& subRecords);
334 
335  private:
336  Asn1SequenceRecord() = default;
337  };
338 
342  {
343  friend class Asn1Record;
344 
345  public:
348  explicit Asn1SetRecord(const std::vector<Asn1Record*>& subRecords);
349 
352  explicit Asn1SetRecord(const PointerVector<Asn1Record>& subRecords);
353 
354  private:
355  Asn1SetRecord() = default;
356  };
357 
362  {
363  friend class Asn1Record;
364 
365  protected:
366  Asn1PrimitiveRecord() = default;
367  explicit Asn1PrimitiveRecord(Asn1UniversalTagType tagType);
368  };
369 
373  {
374  friend class Asn1Record;
375 
376  public:
377  template <typename T>
378  using EnableIfUnsignedIntegral =
379  std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value, int>;
380 
383  explicit Asn1IntegerRecord(uint64_t value);
384 
388  explicit Asn1IntegerRecord(const std::string& value);
389 
392  template <typename T, EnableIfUnsignedIntegral<T> = 0> T getIntValue()
393  {
394  decodeValueIfNeeded();
395  return m_Value.getInt<T>();
396  }
397 
399  PCPP_DEPRECATED("Use getIntValue instead")
400  uint32_t getValue()
401  {
402  return getIntValue<uint32_t>();
403  }
404 
406  std::string getValueAsString()
407  {
408  decodeValueIfNeeded();
409  return m_Value.toString();
410  }
411 
412  protected:
413  Asn1IntegerRecord() = default;
414 
415  void decodeValue(uint8_t const* data, bool lazy) override;
416  std::vector<uint8_t> encodeValue() const override;
417 
418  std::vector<std::string> toStringList() override;
419 
420  private:
421  class BigInt
422  {
423  public:
424  BigInt() = default;
425 
426  template <typename T, EnableIfUnsignedIntegral<T> = 0> explicit BigInt(T value)
427  {
428  m_Value = initFromInt(value);
429  }
430 
431  explicit BigInt(const std::string& value);
432  BigInt(const BigInt& other);
433 
434  template <typename T, EnableIfUnsignedIntegral<T> = 0> BigInt& operator=(T value)
435  {
436  m_Value = initFromInt(value);
437  return *this;
438  }
439  BigInt& operator=(const std::string& value);
440  size_t size() const;
441 
442  template <typename T, EnableIfUnsignedIntegral<T> = 0> T getInt() const
443  {
444  if (!canFit<T>())
445  {
446  throw std::overflow_error("Value cannot fit into requested int type");
447  }
448 
449  std::stringstream sstream;
450  sstream << std::hex << m_Value;
451 
452  uint64_t result;
453  sstream >> result;
454  return static_cast<T>(result);
455  }
456 
457  template <typename T, EnableIfUnsignedIntegral<T> = 0> bool canFit() const
458  {
459  return sizeof(T) >= (m_Value.size() + 1) / 2;
460  }
461 
462  std::string toString() const;
463  std::vector<uint8_t> toBytes() const;
464 
465  private:
466  std::string m_Value;
467 
468  static std::string initFromString(const std::string& value);
469 
470  template <typename T, EnableIfUnsignedIntegral<T> = 0> static std::string initFromInt(T value)
471  {
472  std::stringstream ss;
473  ss << std::hex << static_cast<uint64_t>(value);
474  return ss.str();
475  }
476  };
477 
478  BigInt m_Value;
479  };
480 
484  {
485  friend class Asn1Record;
486 
487  public:
490  explicit Asn1EnumeratedRecord(uint32_t value);
491 
492  private:
493  Asn1EnumeratedRecord() = default;
494  };
495 
499  template <Asn1UniversalTagType TagType> class Asn1StringRecord : public Asn1PrimitiveRecord
500  {
501  public:
503  std::string getValue()
504  {
505  decodeValueIfNeeded();
506  return m_Value;
507  };
508 
509  protected:
511  {}
512 
513  explicit Asn1StringRecord(const std::string& value) : Asn1PrimitiveRecord(TagType), m_Value(value)
514  {
515  m_ValueLength = value.size();
516  m_TotalLength = m_ValueLength + 2;
517  }
518 
519  void decodeValue(uint8_t const* data, bool lazy) override
520  {
521  m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
522  }
523  std::vector<uint8_t> encodeValue() const override
524  {
525  return { m_Value.begin(), m_Value.end() };
526  }
527 
528  std::vector<std::string> toStringList() override
529  {
530  return { Asn1Record::toStringList().front() + ", Value: " + getValue() };
531  }
532 
533  std::string m_Value;
534  };
535 
538  class Asn1OctetStringRecord : public Asn1StringRecord<Asn1UniversalTagType::OctetString>
539  {
540  friend class Asn1Record;
541 
542  public:
543  using Asn1StringRecord::Asn1StringRecord;
544 
548  explicit Asn1OctetStringRecord(const uint8_t* value, size_t valueLength);
549 
552  explicit Asn1OctetStringRecord(const std::string& value) : Asn1StringRecord(value)
553  {}
554 
555  protected:
556  void decodeValue(uint8_t const* data, bool lazy) override;
557  std::vector<uint8_t> encodeValue() const override;
558 
559  private:
560  Asn1OctetStringRecord() = default;
561 
562  bool m_IsPrintable = true;
563  };
564 
567  class Asn1UTF8StringRecord : public Asn1StringRecord<Asn1UniversalTagType::UTF8String>
568  {
569  friend class Asn1Record;
570 
571  public:
574  explicit Asn1UTF8StringRecord(const std::string& value) : Asn1StringRecord(value)
575  {}
576 
577  private:
578  Asn1UTF8StringRecord() = default;
579  };
580 
583  class Asn1PrintableStringRecord : public Asn1StringRecord<Asn1UniversalTagType::PrintableString>
584  {
585  friend class Asn1Record;
586 
587  public:
590  explicit Asn1PrintableStringRecord(const std::string& value) : Asn1StringRecord(value)
591  {}
592 
593  private:
594  Asn1PrintableStringRecord() = default;
595  };
596 
599  class Asn1IA5StringRecord : public Asn1StringRecord<Asn1UniversalTagType::IA5String>
600  {
601  friend class Asn1Record;
602 
603  public:
606  explicit Asn1IA5StringRecord(const std::string& value) : Asn1StringRecord(value)
607  {}
608 
609  private:
610  Asn1IA5StringRecord() = default;
611  };
612 
616  {
617  friend class Asn1Record;
618 
619  public:
622  explicit Asn1BooleanRecord(bool value);
623 
625  bool getValue()
626  {
627  decodeValueIfNeeded();
628  return m_Value;
629  };
630 
631  protected:
632  void decodeValue(uint8_t const* data, bool lazy) override;
633  std::vector<uint8_t> encodeValue() const override;
634 
635  std::vector<std::string> toStringList() override;
636 
637  private:
638  Asn1BooleanRecord() = default;
639 
640  bool m_Value = false;
641  };
642 
646  {
647  friend class Asn1Record;
648 
649  public:
652 
653  protected:
654  void decodeValue(uint8_t const* data, bool lazy) override
655  {}
656  std::vector<uint8_t> encodeValue() const override
657  {
658  return {};
659  }
660  };
661 
665  {
666  friend class Asn1ObjectIdentifierRecord;
667 
668  public:
672  explicit Asn1ObjectIdentifier(const uint8_t* data, size_t dataLen);
673 
677  explicit Asn1ObjectIdentifier(const std::string& oidString);
678 
680  const std::vector<uint32_t>& getComponents() const
681  {
682  return m_Components;
683  }
684 
687  bool operator==(const Asn1ObjectIdentifier& other) const
688  {
689  return m_Components == other.m_Components;
690  }
691 
694  bool operator!=(const Asn1ObjectIdentifier& other) const
695  {
696  return m_Components != other.m_Components;
697  }
698 
701  std::string toString() const;
702 
705  std::vector<uint8_t> toBytes() const;
706 
707  friend std::ostream& operator<<(std::ostream& os, const Asn1ObjectIdentifier& oid)
708  {
709  return os << oid.toString();
710  }
711 
712  protected:
713  Asn1ObjectIdentifier() = default;
714 
715  private:
716  std::vector<uint32_t> m_Components;
717  };
718 
722  {
723  friend class Asn1Record;
724 
725  public:
729 
732  {
733  decodeValueIfNeeded();
734  return m_Value;
735  }
736 
737  protected:
738  void decodeValue(uint8_t const* data, bool lazy) override;
739  std::vector<uint8_t> encodeValue() const override;
740 
741  std::vector<std::string> toStringList() override;
742 
743  private:
744  Asn1ObjectIdentifier m_Value;
745 
746  Asn1ObjectIdentifierRecord() = default;
747  };
748 
753  {
754  public:
759  std::chrono::system_clock::time_point getValue(const std::string& timezone = "Z")
760  {
761  decodeValueIfNeeded();
762  return adjustTimezones(m_Value, "Z", timezone);
763  };
764 
771  std::string getValueAsString(const std::string& format = "%Y-%m-%d %H:%M:%S", const std::string& timezone = "Z",
772  bool includeMilliseconds = false);
773 
774  protected:
775  Asn1TimeRecord() = default;
776  explicit Asn1TimeRecord(Asn1UniversalTagType tagType, const std::chrono::system_clock::time_point& value,
777  const std::string& timezone);
778 
779  std::chrono::system_clock::time_point m_Value;
780 
781  std::vector<std::string> toStringList() override;
782 
783  static void validateTimezone(const std::string& timezone);
784  static std::chrono::system_clock::time_point adjustTimezones(const std::chrono::system_clock::time_point& value,
785  const std::string& fromTimezone,
786  const std::string& toTimezone);
787  };
788 
792  {
793  friend class Asn1Record;
794 
795  public:
799  explicit Asn1UtcTimeRecord(const std::chrono::system_clock::time_point& value, bool withSeconds = true);
800 
801  protected:
802  void decodeValue(uint8_t const* data, bool lazy) override;
803  std::vector<uint8_t> encodeValue() const override;
804 
805  private:
806  Asn1UtcTimeRecord() = default;
807  bool m_WithSeconds = true;
808  };
809 
813  {
814  friend class Asn1Record;
815 
816  public:
822  explicit Asn1GeneralizedTimeRecord(const std::chrono::system_clock::time_point& value,
823  const std::string& timezone = "Z");
824 
825  protected:
826  void decodeValue(uint8_t const* data, bool lazy) override;
827  std::vector<uint8_t> encodeValue() const override;
828 
829  private:
830  Asn1GeneralizedTimeRecord() = default;
831  std::string m_Timezone;
832  };
833 
837  {
838  friend class Asn1Record;
839 
840  public:
844  explicit Asn1BitStringRecord(const std::string& value);
845 
847  std::string getValue()
848  {
849  decodeValueIfNeeded();
850  return m_Value.toString();
851  };
852 
854  std::vector<uint8_t> getVecValue()
855  {
856  decodeValueIfNeeded();
857  return m_Value.toBytes();
858  }
859 
860  protected:
861  void decodeValue(uint8_t const* data, bool lazy) override;
862  std::vector<uint8_t> encodeValue() const override;
863 
864  std::vector<std::string> toStringList() override;
865 
866  private:
867  class BitSet
868  {
869  public:
870  BitSet() = default;
871  explicit BitSet(const std::string& value);
872  BitSet(const uint8_t* data, size_t numBits);
873 
874  BitSet& operator=(const std::string& value);
875 
876  size_t sizeInBytes() const;
877  std::string toString() const;
878  std::vector<uint8_t> toBytes() const;
879  size_t getNumBits() const
880  {
881  return m_NumBits;
882  }
883 
884  private:
885  void initFromString(const std::string& value);
886 
887  std::vector<std::bitset<8>> m_Data;
888  size_t m_NumBits = 0;
889  };
890 
891  Asn1BitStringRecord() = default;
892 
893  BitSet m_Value;
894  };
895 } // namespace pcpp
Definition: Asn1Codec.h:837
std::string getValue()
Definition: Asn1Codec.h:847
std::vector< uint8_t > getVecValue()
Definition: Asn1Codec.h:854
Asn1BitStringRecord(const std::string &value)
Definition: Asn1Codec.h:616
Asn1BooleanRecord(bool value)
bool getValue()
Definition: Asn1Codec.h:625
Definition: Asn1Codec.h:263
PointerVector< Asn1Record > & getSubRecords()
Definition: Asn1Codec.h:283
Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType, const PointerVector< Asn1Record > &subRecords)
Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType, const std::vector< Asn1Record * > &subRecords)
Definition: Asn1Codec.h:484
Asn1EnumeratedRecord(uint32_t value)
Definition: Asn1Codec.h:813
Asn1GeneralizedTimeRecord(const std::chrono::system_clock::time_point &value, const std::string &timezone="Z")
Definition: Asn1Codec.h:219
const uint8_t * getValue()
Definition: Asn1Codec.h:242
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:600
Asn1IA5StringRecord(const std::string &value)
Definition: Asn1Codec.h:606
Definition: Asn1Codec.h:373
Asn1IntegerRecord(uint64_t value)
T getIntValue()
Definition: Asn1Codec.h:392
uint32_t getValue()
Definition: Asn1Codec.h:400
std::string getValueAsString()
Definition: Asn1Codec.h:406
Asn1IntegerRecord(const std::string &value)
Definition: Asn1Codec.h:646
Asn1NullRecord()
A constructor to create a record of type Null.
Definition: Asn1Codec.h:665
std::vector< uint8_t > toBytes() const
bool operator==(const Asn1ObjectIdentifier &other) const
Definition: Asn1Codec.h:687
std::string toString() const
Asn1ObjectIdentifier(const uint8_t *data, size_t dataLen)
bool operator!=(const Asn1ObjectIdentifier &other) const
Definition: Asn1Codec.h:694
Asn1ObjectIdentifier(const std::string &oidString)
const std::vector< uint32_t > & getComponents() const
Definition: Asn1Codec.h:680
Definition: Asn1Codec.h:722
const Asn1ObjectIdentifier & getValue()
Definition: Asn1Codec.h:731
Asn1ObjectIdentifierRecord(const Asn1ObjectIdentifier &value)
Definition: Asn1Codec.h:539
Asn1OctetStringRecord(const std::string &value)
Definition: Asn1Codec.h:552
Asn1OctetStringRecord(const uint8_t *value, size_t valueLength)
Definition: Asn1Codec.h:362
Definition: Asn1Codec.h:584
Asn1PrintableStringRecord(const std::string &value)
Definition: Asn1Codec.h:590
Definition: Asn1Codec.h:117
uint8_t getTagType() const
Definition: Asn1Codec.h:149
std::vector< uint8_t > encode()
bool isConstructed() const
Definition: Asn1Codec.h:139
Asn1UniversalTagType getUniversalTagType() const
Asn1TagClass getTagClass() const
Definition: Asn1Codec.h:133
std::string toString()
size_t getTotalLength() const
Definition: Asn1Codec.h:161
Asn1RecordType * castAs()
Definition: Asn1Codec.h:173
size_t getValueLength() const
Definition: Asn1Codec.h:155
static std::unique_ptr< Asn1Record > decode(const uint8_t *data, size_t dataLen, bool lazy=true)
Definition: Asn1Codec.h:323
Asn1SequenceRecord(const PointerVector< Asn1Record > &subRecords)
Asn1SequenceRecord(const std::vector< Asn1Record * > &subRecords)
Definition: Asn1Codec.h:342
Asn1SetRecord(const PointerVector< Asn1Record > &subRecords)
Asn1SetRecord(const std::vector< Asn1Record * > &subRecords)
Definition: Asn1Codec.h:500
std::string getValue()
Definition: Asn1Codec.h:503
Definition: Asn1Codec.h:753
std::string getValueAsString(const std::string &format="%Y-%m-%d %H:%M:%S", const std::string &timezone="Z", bool includeMilliseconds=false)
std::chrono::system_clock::time_point getValue(const std::string &timezone="Z")
Definition: Asn1Codec.h:759
Definition: Asn1Codec.h:568
Asn1UTF8StringRecord(const std::string &value)
Definition: Asn1Codec.h:574
Definition: Asn1Codec.h:792
Asn1UtcTimeRecord(const std::chrono::system_clock::time_point &value, bool withSeconds=true)
Definition: PointerVector.h:50
The main namespace for the PcapPlusPlus lib.
Asn1TagClass
An enum for representing ASN.1 tag class.
Definition: Asn1Codec.h:20
@ 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:33
@ 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.