PcapPlusPlus  Next
X509Decoder.h
1 #pragma once
2 #include <chrono>
3 #include "Asn1Codec.h"
4 #include "X509ExtensionDataDecoder.h"
5 
8 namespace pcpp
9 {
12  enum class X509Version : uint8_t
13  {
15  V1 = 0,
17  V2 = 1,
19  V3 = 2,
20  };
21 
27  {
28  public:
30  enum Value : uint8_t
31  {
41  MD5,
42 
44  RSA,
55 
66 
68  DSA,
73 
80 
83  };
84 
85  X509Algorithm() = default;
86 
87  // cppcheck-suppress noExplicitConstructor
90  constexpr X509Algorithm(Value value) : m_Value(value)
91  {}
92 
94  std::string toString() const;
95 
97  std::string getOidValue() const;
98 
104 
105  // Allow switch and comparisons.
106  constexpr operator Value() const
107  {
108  return m_Value;
109  }
110 
111  // Prevent usage: if(LdapOperationType)
112  explicit operator bool() const = delete;
113 
114  private:
115  Value m_Value = Unknown;
116  };
117 
121  {
122  public:
124  enum Value : uint8_t
125  {
165  Unknown
166  };
167 
168  X520DistinguishedName() = default;
169 
170  constexpr X520DistinguishedName(Value value) : m_Value(value)
171  {}
172 
174  std::string toString() const;
175 
178  std::string getShortName() const;
179 
181  std::string getOidValue() const;
182 
187 
188  // Allow switch and comparisons.
189  constexpr operator Value() const
190  {
191  return m_Value;
192  }
193  explicit operator bool() const = delete;
194 
195  private:
196  Value m_Value = Unknown;
197  };
198 
202  {
203  public:
206  enum Value : uint8_t
207  {
253  Unknown
254  };
255 
256  X509ExtensionType() = default;
257 
258  // cppcheck-suppress noExplicitConstructor
261  constexpr X509ExtensionType(Value value) : m_Value(value)
262  {}
263 
265  std::string toString() const;
266 
268  std::string getOidValue() const;
269 
274 
275  // Allow switch and comparisons.
276  constexpr operator Value() const
277  {
278  return m_Value;
279  }
280  explicit operator bool() const = delete;
281 
282  private:
283  Value m_Value = Unknown;
284  };
285 
289  {
290  public:
293  explicit X509SerialNumber(const std::string& serialNumber) : m_SerialNumber(serialNumber)
294  {}
295 
299  std::string toString(const std::string& delimiter = ":") const;
300 
301  private:
302  std::string m_SerialNumber;
303  };
304 
308  {
309  public:
313  explicit X509Timestamp(Asn1TimeRecord* timeRecord) : m_Record(timeRecord)
314  {}
315 
322  std::string toString(const std::string& format = "%Y-%m-%d %H:%M:%S", const std::string& timezone = "Z",
323  bool includeMilliseconds = false) const;
324 
329  std::chrono::system_clock::time_point getTimestamp(const std::string& timezone = "Z") const;
330 
331  private:
332  Asn1TimeRecord* m_Record;
333  };
334 
337  class X509Key
338  {
339  public:
342  explicit X509Key(const std::vector<uint8_t>& key) : m_Key(key)
343  {}
344 
348  std::string toString(const std::string& delimiter = ":") const;
349 
352  const std::vector<uint8_t>& getBytes() const;
353 
354  private:
355  std::vector<uint8_t> m_Key;
356  };
357 
360  namespace X509Internal
361  {
362  // Forward declarations
363  class X509Certificate;
364  class X509TBSCertificate;
365  class X509Name;
366  class X509SubjectPublicKeyInfo;
367  class X509Extension;
368  class X509Extensions;
369 
373  template <typename Asn1RecordType> class X509Base
374  {
375  protected:
376  explicit X509Base(Asn1RecordType* root) : m_Root(root)
377  {}
378 
379  Asn1RecordType* m_Root;
380  };
381 
384  class X509VersionRecord : public X509Base<Asn1ConstructedRecord>
385  {
386  using X509Base::X509Base;
387  friend class X509TBSCertificate;
388 
389  public:
393 
397  static bool isValidVersionRecord(const Asn1Record* record);
398 
399  private:
400  static constexpr int versionOffset = 0;
401  };
402 
405  class X509RelativeDistinguishedName : public X509Base<Asn1SetRecord>
406  {
407  using X509Base::X509Base;
408  friend class X509Name;
409 
410  public:
414 
417  std::string getValue() const;
418 
419  private:
420  static constexpr int typeOffset = 0;
421  static constexpr int valueOffset = 1;
422 
423  Asn1Record* getRecord(int index) const;
424  };
425 
428  class X509Name : public X509Base<Asn1SequenceRecord>
429  {
430  using X509Base::X509Base;
431  friend class X509TBSCertificate;
432 
433  public:
436  std::vector<X509RelativeDistinguishedName> getRDNs() const;
437  };
438 
441  class X509AlgorithmIdentifier : public X509Base<Asn1SequenceRecord>
442  {
443  using X509Base::X509Base;
444  friend class X509SubjectPublicKeyInfo;
445  friend class X509TBSCertificate;
446  friend class X509Certificate;
447 
448  public:
452 
453  private:
454  static constexpr int algorithmOffset = 0;
455  };
456 
459  class X509Validity : public X509Base<Asn1SequenceRecord>
460  {
461  using X509Base::X509Base;
462  friend class X509TBSCertificate;
463 
464  public:
468 
472 
473  private:
474  static constexpr int notBeforeOffset = 0;
475  static constexpr int notAfterOffset = 1;
476  };
477 
480  class X509SubjectPublicKeyInfo : public X509Base<Asn1SequenceRecord>
481  {
482  using X509Base::X509Base;
483  friend class X509TBSCertificate;
484 
485  public:
489 
493 
494  private:
495  static constexpr int algorithmOffset = 0;
496  static constexpr int subjectPublicKeyOffset = 1;
497  };
498 
501  class X509Extension : public X509Base<Asn1SequenceRecord>
502  {
503  friend class X509Extensions;
504  using X509Base::X509Base;
505 
506  public:
510 
513  bool isCritical() const;
514 
517  std::string getValue() const;
518 
519  private:
520  static constexpr int extensionIdOffset = 0;
521 
522  int m_CriticalOffset = -1;
523  int m_ExtensionValueOffset = 1;
524 
526  };
527 
530  class X509Extensions : public X509Base<Asn1ConstructedRecord>
531  {
532  using X509Base::X509Base;
533  friend class X509TBSCertificate;
534 
535  public:
538  std::vector<X509Extension> getExtensions() const;
539 
543  static bool isValidExtensionsRecord(const Asn1Record* record);
544  };
545 
548  class X509TBSCertificate : public X509Base<Asn1SequenceRecord>
549  {
550  using X509Base::X509Base;
551  friend class X509Certificate;
552 
553  public:
557 
561 
565 
569 
573 
577 
581 
584  std::unique_ptr<X509Extensions> getExtensions() const;
585 
586  private:
587  int m_VersionOffset = -1;
588  int m_SerialNumberOffset = 0;
589  int m_SignatureOffset = 1;
590  int m_IssuerOffset = 2;
591  int m_ValidityOffset = 3;
592  int m_SubjectOffset = 4;
593  int m_SubjectPublicKeyInfoOffset = 5;
594  int m_IssuerUniqueID = -1;
595  int m_SubjectUniqueID = -1;
596  int m_ExtensionsOffset = -1;
597 
599  int getIndex(int offset) const
600  {
601  return m_VersionOffset + offset;
602  }
603  };
604 
608  {
609  public:
613 
617 
621 
625 
630  static std::unique_ptr<X509Certificate> decode(const uint8_t* data, size_t dataLen);
631 
634  std::vector<uint8_t> encode();
635 
636  private:
637  static constexpr int tbsCertificateOffset = 0;
638  static constexpr int signatureAlgorithmOffset = 1;
639  static constexpr int signatureOffset = 2;
640 
641  explicit X509Certificate(std::unique_ptr<Asn1Record> root) : m_Root(std::move(root))
642  {}
643 
644  std::unique_ptr<Asn1Record> m_Root;
645  };
646  } // namespace X509Internal
647 
648  // Forward declarations
649  class X509Certificate;
650 
653  class X509Name
654  {
655  friend class X509Certificate;
656 
657  public:
660  struct RDN
661  {
663  std::string value;
664 
666  bool operator==(const RDN& other) const
667  {
668  return type == other.type && value == other.value;
669  }
670 
672  bool operator!=(const RDN& other) const
673  {
674  return !(*this == other);
675  }
676 
678  friend std::ostream& operator<<(std::ostream& os, const RDN& rdn)
679  {
680  os << "RDN{type=" << rdn.type.getShortName() << ", value=" << rdn.value << "}";
681  return os;
682  }
683  };
684 
688  std::string toString(const std::string& delimiter = ", ") const;
689 
692  const std::vector<RDN>& getRDNs() const
693  {
694  return m_RDNs;
695  }
696 
697  private:
698  explicit X509Name(const X509Internal::X509Name& internalName);
699  std::vector<RDN> m_RDNs;
700  };
701 
705  {
706  friend class X509Certificate;
707 
708  public:
712  {
713  return m_Type;
714  }
715 
718  bool isCritical() const
719  {
720  return m_IsCritical;
721  }
722 
726  std::unique_ptr<X509ExtensionData> getData() const;
727 
730  std::string getRawDataAsHexString() const
731  {
732  return m_Data;
733  }
734 
735  private:
736  X509Extension(const X509Internal::X509Extension& internalExtension);
737 
738  bool m_IsCritical;
739  X509ExtensionType m_Type;
740  std::string m_Data;
741  };
742 
746  {
747  public:
755  static std::unique_ptr<X509Certificate> fromDER(uint8_t* derData, size_t derDataLen, bool ownDerData = false);
756 
761  static std::unique_ptr<X509Certificate> fromDER(const std::string& derData);
762 
767  static std::unique_ptr<X509Certificate> fromDERFile(const std::string& derFileName);
768 
772 
776 
780 
784 
788 
792 
796 
800 
804 
808 
811  const std::vector<X509Extension>& getExtensions() const;
812 
816  bool hasExtension(const X509ExtensionType& extensionType) const;
817 
821  const X509Extension* getExtension(X509ExtensionType extensionType) const;
822 
825  std::vector<uint8_t> toDER() const;
826 
830  std::string toJson(int indent = -1) const;
831 
835 
836  // Prevent copying
837  X509Certificate(const X509Certificate&) = delete;
838  X509Certificate& operator=(const X509Certificate&) = delete;
839 
840  private:
841  // Constructor/Destructor
842  X509Certificate(uint8_t* derData, size_t derDataLen, bool ownDerData);
843  X509Certificate(std::unique_ptr<uint8_t[]> derData, size_t derDataLen);
844 
845  std::unique_ptr<X509Internal::X509Certificate> m_X509Internal;
846  X509Internal::X509TBSCertificate m_TBSCertificate;
847  mutable std::vector<X509Extension> m_Extensions;
848  mutable bool m_ExtensionsParsed = false;
849  std::unique_ptr<uint8_t[]> m_DerData;
850  };
851 } // namespace pcpp
Definition: Asn1Codec.h:665
Definition: Asn1Codec.h:117
Definition: Asn1Codec.h:323
Definition: Asn1Codec.h:753
Definition: X509Decoder.h:27
Value
Define enum types and the corresponding int values.
Definition: X509Decoder.h:31
@ DSAWithSHA256
DSA with SHA-256 signature algorithm.
Definition: X509Decoder.h:72
@ SHA512
SHA-512 hashing algorithm.
Definition: X509Decoder.h:39
@ ECDSAWithSHA1
ECDSA with SHA-1 signature algorithm.
Definition: X509Decoder.h:59
@ ECDSAWithSHA384
ECDSA with SHA-384 signature algorithm.
Definition: X509Decoder.h:63
@ RSAWithSHA1
RSA with SHA-1 signature algorithm.
Definition: X509Decoder.h:46
@ ECDSAWithSHA256
ECDSA with SHA-256 signature algorithm.
Definition: X509Decoder.h:61
@ SHA256
SHA-256 hashing algorithm.
Definition: X509Decoder.h:35
@ DiffieHellman
Diffie-Hellman key exchange algorithm.
Definition: X509Decoder.h:79
@ RSAWithSHA256
RSA with SHA-256 signature algorithm.
Definition: X509Decoder.h:48
@ ECDSAWithSHA512
ECDSA with SHA-512 signature algorithm.
Definition: X509Decoder.h:65
@ RSAWithSHA384
RSA with SHA-384 signature algorithm.
Definition: X509Decoder.h:50
@ DSA
Digital Signature Algorithm.
Definition: X509Decoder.h:68
@ Unknown
Unknown or unsupported algorithm.
Definition: X509Decoder.h:82
@ RSAPSS
RSA Probabilistic Signature Scheme (PSS)
Definition: X509Decoder.h:54
@ ECDSA
Elliptic Curve Digital Signature Algorithm.
Definition: X509Decoder.h:57
@ RSAWithSHA512
RSA with SHA-512 signature algorithm.
Definition: X509Decoder.h:52
@ DSAWithSHA1
DSA with SHA-1 signature algorithm.
Definition: X509Decoder.h:70
@ RSA
RSA encryption/signature algorithm.
Definition: X509Decoder.h:44
@ SHA1
SHA-1 hashing algorithm.
Definition: X509Decoder.h:33
@ ED448
EdDSA using Curve448 (Ed448)
Definition: X509Decoder.h:77
@ MD5
MD5 hashing algorithm (considered cryptographically broken)
Definition: X509Decoder.h:41
@ SHA384
SHA-384 hashing algorithm.
Definition: X509Decoder.h:37
@ ED25519
EdDSA using Curve25519 (Ed25519)
Definition: X509Decoder.h:75
constexpr X509Algorithm(Value value)
Definition: X509Decoder.h:90
std::string getOidValue() const
std::string toString() const
static X509Algorithm fromOidValue(const Asn1ObjectIdentifier &value)
Definition: X509Decoder.h:746
X509Key getPublicKey() const
const X509Extension * getExtension(X509ExtensionType extensionType) const
X509Name getSubject() const
const X509Internal::X509Certificate * getRawCertificate() const
std::vector< uint8_t > toDER() const
X509SerialNumber getSerialNumber() const
X509Name getIssuer() const
X509Key getSignature() const
static std::unique_ptr< X509Certificate > fromDERFile(const std::string &derFileName)
X509Timestamp getNotBefore() const
const std::vector< X509Extension > & getExtensions() const
X509Timestamp getNotAfter() const
static std::unique_ptr< X509Certificate > fromDER(const std::string &derData)
X509Algorithm getPublicKeyAlgorithm() const
bool hasExtension(const X509ExtensionType &extensionType) const
static std::unique_ptr< X509Certificate > fromDER(uint8_t *derData, size_t derDataLen, bool ownDerData=false)
X509Version getVersion() const
X509Algorithm getSignatureAlgorithm() const
std::string toJson(int indent=-1) const
Definition: X509Decoder.h:705
X509ExtensionType getType() const
Definition: X509Decoder.h:711
std::unique_ptr< X509ExtensionData > getData() const
bool isCritical() const
Definition: X509Decoder.h:718
std::string getRawDataAsHexString() const
Definition: X509Decoder.h:730
Definition: X509Decoder.h:202
std::string toString() const
constexpr X509ExtensionType(Value value)
Definition: X509Decoder.h:261
Value
Definition: X509Decoder.h:207
@ Unknown
Unknown or unsupported extension type.
Definition: X509Decoder.h:253
@ AuthorityKeyIdentifier
Authority Key Identifier - Identifies the public key used to verify the signature on this certificate...
Definition: X509Decoder.h:218
@ SubjectAltName
Subject Alternative Name - Allows identities to be bound to the subject of the certificate.
Definition: X509Decoder.h:220
@ CertificatePolicies
Certificate Policies - Contains a sequence of one or more policy terms.
Definition: X509Decoder.h:228
@ PolicyMappings
Definition: X509Decoder.h:231
@ InhibitAnyPolicy
Definition: X509Decoder.h:239
@ CTPrecertificateSCTs
Signed Certificate Timestamp - Contains a list of SCTs from Certificate Transparency logs.
Definition: X509Decoder.h:241
@ NameConstraints
Definition: X509Decoder.h:236
@ KeyUsage
Key Usage - Defines the purpose of the key contained in the certificate.
Definition: X509Decoder.h:211
@ AuthorityInfoAccess
Authority Information Access - Describes how to access CA information and services.
Definition: X509Decoder.h:226
@ ExtendedKeyUsage
Extended Key Usage - Indicates one or more purposes for which the certified public key may be used.
Definition: X509Decoder.h:213
@ BasicConstraints
Basic Constraints - Indicates if the subject is a CA and the maximum path length.
Definition: X509Decoder.h:209
@ SubjectKeyIdentifier
Definition: X509Decoder.h:216
@ IssuerAltName
Issuer Alternative Name - Allows additional identities to be associated with the issuer.
Definition: X509Decoder.h:222
@ CrlDistributionPoints
CRL Distribution Points - Identifies how CRL information is obtained.
Definition: X509Decoder.h:224
@ PolicyConstraints
Policy Constraints - Specifies constraints on path validation.
Definition: X509Decoder.h:233
@ TLSFeature
TLS Feature - Indicates which TLS features are required for the certificate to be used.
Definition: X509Decoder.h:247
@ SubjectInfoAccess
Subject Information Access - Describes how to access additional information about the subject.
Definition: X509Decoder.h:243
@ SubjectDirectoryAttributes
Subject Directory Attributes - Conveys identification attributes of the subject.
Definition: X509Decoder.h:251
@ FreshestCRL
Freshest CRL - Identifies how delta CRL information is obtained.
Definition: X509Decoder.h:245
@ OcspNoCheck
OCSP No Check - Indicates that an OCSP client should trust the certificate for OCSP signing.
Definition: X509Decoder.h:249
std::string getOidValue() const
static X509ExtensionType fromOidValue(const Asn1ObjectIdentifier &value)
Definition: X509Decoder.h:442
Definition: X509Decoder.h:374
Definition: X509Decoder.h:608
static std::unique_ptr< X509Certificate > decode(const uint8_t *data, size_t dataLen)
Asn1SequenceRecord * getAsn1Root() const
std::vector< uint8_t > encode()
X509TBSCertificate getTbsCertificate() const
X509AlgorithmIdentifier getSignatureAlgorithm() const
Definition: X509Decoder.h:502
X509ExtensionType getType() const
Definition: X509Decoder.h:531
static bool isValidExtensionsRecord(const Asn1Record *record)
std::vector< X509Extension > getExtensions() const
Definition: X509Decoder.h:429
std::vector< X509RelativeDistinguishedName > getRDNs() const
X509AlgorithmIdentifier getAlgorithm() const
Definition: X509Decoder.h:549
X509SubjectPublicKeyInfo getSubjectPublicKeyInfo() const
X509AlgorithmIdentifier getSignature() const
X509SerialNumber getSerialNumber() const
std::unique_ptr< X509Extensions > getExtensions() const
Definition: X509Decoder.h:460
X509Timestamp getNotBefore() const
X509Timestamp getNotAfter() const
Definition: X509Decoder.h:385
static bool isValidVersionRecord(const Asn1Record *record)
Definition: X509Decoder.h:338
std::string toString(const std::string &delimiter=":") const
const std::vector< uint8_t > & getBytes() const
X509Key(const std::vector< uint8_t > &key)
Definition: X509Decoder.h:342
Definition: X509Decoder.h:654
const std::vector< RDN > & getRDNs() const
Definition: X509Decoder.h:692
std::string toString(const std::string &delimiter=", ") const
Definition: X509Decoder.h:289
X509SerialNumber(const std::string &serialNumber)
Definition: X509Decoder.h:293
std::string toString(const std::string &delimiter=":") const
Definition: X509Decoder.h:308
std::chrono::system_clock::time_point getTimestamp(const std::string &timezone="Z") const
std::string toString(const std::string &format="%Y-%m-%d %H:%M:%S", const std::string &timezone="Z", bool includeMilliseconds=false) const
X509Timestamp(Asn1TimeRecord *timeRecord)
Definition: X509Decoder.h:313
Definition: X509Decoder.h:121
static X520DistinguishedName fromOidValue(const Asn1ObjectIdentifier &value)
std::string getOidValue() const
Value
Define enum types and the corresponding int values.
Definition: X509Decoder.h:125
@ BusinessCategory
Business Category - Type of business or organization.
Definition: X509Decoder.h:163
@ EmailAddress
Email Address - Email address in the format user@domain.
Definition: X509Decoder.h:157
@ Country
Country Name (C) - Two-letter ISO 3166-1 alpha-2 country code.
Definition: X509Decoder.h:133
@ SerialNumber
Serial Number - Serial number of the certificate.
Definition: X509Decoder.h:131
@ CommonName
Common Name (CN) - Typically the fully qualified domain name (FQDN)
Definition: X509Decoder.h:127
@ Unknown
Unknown or unsupported distinguished name type.
Definition: X509Decoder.h:165
@ DnQualifier
Distinguished Name Qualifier - Disambiguates similar distinguished names.
Definition: X509Decoder.h:153
@ GivenName
Given Name (GN) - First name of a person.
Definition: X509Decoder.h:145
@ Organization
Organization Name (O) - Name of the organization.
Definition: X509Decoder.h:139
@ Locality
Locality (L) - City or locality name.
Definition: X509Decoder.h:135
@ Initials
Initials - Initials of a person's name.
Definition: X509Decoder.h:147
@ StateOrProvince
State or Province Name (ST) - State or province name.
Definition: X509Decoder.h:137
@ Pseudonym
Pseudonym - A person's nickname or alias.
Definition: X509Decoder.h:149
@ Surname
Surname (SN) - Family name of a person.
Definition: X509Decoder.h:129
@ Title
Title - Job title or position.
Definition: X509Decoder.h:143
@ StreetAddress
Street Address - Physical street address.
Definition: X509Decoder.h:161
@ DomainComponent
Domain Component (DC) - Domain component in domain names (e.g., "example" in "example....
Definition: X509Decoder.h:155
@ OrganizationalUnit
Organizational Unit (OU) - Department or division within an organization.
Definition: X509Decoder.h:141
@ PostalCode
Postal Code - Postal or ZIP code.
Definition: X509Decoder.h:159
@ GenerationQualifier
Generation Qualifier - A qualifier indicating a person's generation (e.g., Jr., Sr....
Definition: X509Decoder.h:151
std::string getShortName() const
std::string toString() const
The main namespace for the PcapPlusPlus lib.
X509Version
Definition: X509Decoder.h:13
@ V1
X.509 Version 1.
@ V3
X.509 Version 3.
@ V2
X.509 Version 2.
Definition: X509Decoder.h:661
bool operator==(const RDN &other) const
Equality comparison operator.
Definition: X509Decoder.h:666
X520DistinguishedName type
The type of the distinguished name.
Definition: X509Decoder.h:662
bool operator!=(const RDN &other) const
Inequality comparison operator.
Definition: X509Decoder.h:672
friend std::ostream & operator<<(std::ostream &os, const RDN &rdn)
Stream output operator for RDN.
Definition: X509Decoder.h:678
std::string value
The value of the distinguished name.
Definition: X509Decoder.h:663