PcapPlusPlus  Next
X509Decoder.h
1 #pragma once
2 #include <chrono>
3 #include "Asn1Codec.h"
4 #include "CryptoDataReader.h"
5 #include "X509ExtensionDataDecoder.h"
6 
9 namespace pcpp
10 {
13  enum class X509Version : uint8_t
14  {
16  V1 = 0,
18  V2 = 1,
20  V3 = 2,
21  };
22 
28  {
29  public:
31  enum Value : uint8_t
32  {
42  MD5,
43 
45  RSA,
56 
67 
69  DSA,
74 
81 
84  };
85 
86  X509Algorithm() = default;
87 
88  // cppcheck-suppress noExplicitConstructor
91  constexpr X509Algorithm(Value value) : m_Value(value)
92  {}
93 
95  std::string toString() const;
96 
98  std::string getOidValue() const;
99 
105 
106  // Allow switch and comparisons.
107  constexpr operator Value() const
108  {
109  return m_Value;
110  }
111 
112  // Prevent usage: if(LdapOperationType)
113  explicit operator bool() const = delete;
114 
115  private:
116  Value m_Value = Unknown;
117  };
118 
122  {
123  public:
125  enum Value : uint8_t
126  {
166  Unknown
167  };
168 
169  X520DistinguishedName() = default;
170 
171  constexpr X520DistinguishedName(Value value) : m_Value(value)
172  {}
173 
175  std::string toString() const;
176 
179  std::string getShortName() const;
180 
182  std::string getOidValue() const;
183 
188 
189  // Allow switch and comparisons.
190  constexpr operator Value() const
191  {
192  return m_Value;
193  }
194  explicit operator bool() const = delete;
195 
196  private:
197  Value m_Value = Unknown;
198  };
199 
203  {
204  public:
207  enum Value : uint8_t
208  {
254  Unknown
255  };
256 
257  X509ExtensionType() = default;
258 
259  // cppcheck-suppress noExplicitConstructor
262  constexpr X509ExtensionType(Value value) : m_Value(value)
263  {}
264 
266  std::string toString() const;
267 
269  std::string getOidValue() const;
270 
275 
276  // Allow switch and comparisons.
277  constexpr operator Value() const
278  {
279  return m_Value;
280  }
281  explicit operator bool() const = delete;
282 
283  private:
284  Value m_Value = Unknown;
285  };
286 
290  {
291  public:
294  explicit X509SerialNumber(const std::string& serialNumber) : m_SerialNumber(serialNumber)
295  {}
296 
300  std::string toString(const std::string& delimiter = ":") const;
301 
302  private:
303  std::string m_SerialNumber;
304  };
305 
309  {
310  public:
314  explicit X509Timestamp(Asn1TimeRecord* timeRecord) : m_Record(timeRecord)
315  {}
316 
323  std::string toString(const std::string& format = "%Y-%m-%d %H:%M:%S", const std::string& timezone = "Z",
324  bool includeMilliseconds = false) const;
325 
330  std::chrono::system_clock::time_point getTimestamp(const std::string& timezone = "Z") const;
331 
332  private:
333  Asn1TimeRecord* m_Record;
334  };
335 
338  class X509Key
339  {
340  public:
343  explicit X509Key(const std::vector<uint8_t>& key) : m_Key(key)
344  {}
345 
349  std::string toString(const std::string& delimiter = ":") const;
350 
353  const std::vector<uint8_t>& getBytes() const;
354 
355  private:
356  std::vector<uint8_t> m_Key;
357  };
358 
361  namespace X509Internal
362  {
363  // Forward declarations
364  class X509Certificate;
365  class X509TBSCertificate;
366  class X509Name;
367  class X509SubjectPublicKeyInfo;
368  class X509Extension;
369  class X509Extensions;
370 
374  template <typename Asn1RecordType> class X509Base
375  {
376  protected:
377  explicit X509Base(Asn1RecordType* root) : m_Root(root)
378  {}
379 
380  Asn1RecordType* m_Root;
381  };
382 
385  class X509VersionRecord : public X509Base<Asn1ConstructedRecord>
386  {
387  using X509Base::X509Base;
388  friend class X509TBSCertificate;
389 
390  public:
394 
398  static bool isValidVersionRecord(const Asn1Record* record);
399 
400  private:
401  static constexpr int versionOffset = 0;
402  };
403 
406  class X509RelativeDistinguishedName : public X509Base<Asn1SetRecord>
407  {
408  using X509Base::X509Base;
409  friend class X509Name;
410 
411  public:
415 
418  std::string getValue() const;
419 
420  private:
421  static constexpr int typeOffset = 0;
422  static constexpr int valueOffset = 1;
423 
424  Asn1Record* getRecord(int index) const;
425  };
426 
429  class X509Name : public X509Base<Asn1SequenceRecord>
430  {
431  using X509Base::X509Base;
432  friend class X509TBSCertificate;
433 
434  public:
437  std::vector<X509RelativeDistinguishedName> getRDNs() const;
438  };
439 
442  class X509AlgorithmIdentifier : public X509Base<Asn1SequenceRecord>
443  {
444  using X509Base::X509Base;
445  friend class X509SubjectPublicKeyInfo;
446  friend class X509TBSCertificate;
447  friend class X509Certificate;
448 
449  public:
453 
454  private:
455  static constexpr int algorithmOffset = 0;
456  };
457 
460  class X509Validity : public X509Base<Asn1SequenceRecord>
461  {
462  using X509Base::X509Base;
463  friend class X509TBSCertificate;
464 
465  public:
469 
473 
474  private:
475  static constexpr int notBeforeOffset = 0;
476  static constexpr int notAfterOffset = 1;
477  };
478 
481  class X509SubjectPublicKeyInfo : public X509Base<Asn1SequenceRecord>
482  {
483  using X509Base::X509Base;
484  friend class X509TBSCertificate;
485 
486  public:
490 
494 
495  private:
496  static constexpr int algorithmOffset = 0;
497  static constexpr int subjectPublicKeyOffset = 1;
498  };
499 
502  class X509Extension : public X509Base<Asn1SequenceRecord>
503  {
504  friend class X509Extensions;
505  using X509Base::X509Base;
506 
507  public:
511 
514  bool isCritical() const;
515 
518  std::string getValue() const;
519 
520  private:
521  static constexpr int extensionIdOffset = 0;
522 
523  int m_CriticalOffset = -1;
524  int m_ExtensionValueOffset = 1;
525 
527  };
528 
531  class X509Extensions : public X509Base<Asn1ConstructedRecord>
532  {
533  using X509Base::X509Base;
534  friend class X509TBSCertificate;
535 
536  public:
539  std::vector<X509Extension> getExtensions() const;
540 
544  static bool isValidExtensionsRecord(const Asn1Record* record);
545  };
546 
549  class X509TBSCertificate : public X509Base<Asn1SequenceRecord>
550  {
551  using X509Base::X509Base;
552  friend class X509Certificate;
553 
554  public:
558 
562 
566 
570 
574 
578 
582 
585  std::unique_ptr<X509Extensions> getExtensions() const;
586 
587  private:
588  int m_VersionOffset = -1;
589  int m_SerialNumberOffset = 0;
590  int m_SignatureOffset = 1;
591  int m_IssuerOffset = 2;
592  int m_ValidityOffset = 3;
593  int m_SubjectOffset = 4;
594  int m_SubjectPublicKeyInfoOffset = 5;
595  int m_IssuerUniqueID = -1;
596  int m_SubjectUniqueID = -1;
597  int m_ExtensionsOffset = -1;
598 
600  };
601 
605  {
606  public:
610 
614 
618 
622 
627  static std::unique_ptr<X509Certificate> decode(const uint8_t* data, size_t dataLen);
628 
631  std::vector<uint8_t> encode();
632 
633  private:
634  static constexpr int tbsCertificateOffset = 0;
635  static constexpr int signatureAlgorithmOffset = 1;
636  static constexpr int signatureOffset = 2;
637 
638  explicit X509Certificate(std::unique_ptr<Asn1Record> root) : m_Root(std::move(root))
639  {}
640 
641  std::unique_ptr<Asn1Record> m_Root;
642  };
643  } // namespace X509Internal
644 
645  // Forward declarations
646  class X509Certificate;
647 
650  class X509Name
651  {
652  friend class X509Certificate;
653 
654  public:
657  struct RDN
658  {
660  std::string value;
661 
663  bool operator==(const RDN& other) const
664  {
665  return type == other.type && value == other.value;
666  }
667 
669  bool operator!=(const RDN& other) const
670  {
671  return !(*this == other);
672  }
673 
675  friend std::ostream& operator<<(std::ostream& os, const RDN& rdn)
676  {
677  os << "RDN{type=" << rdn.type.getShortName() << ", value=" << rdn.value << "}";
678  return os;
679  }
680  };
681 
685  std::string toString(const std::string& delimiter = ", ") const;
686 
689  const std::vector<RDN>& getRDNs() const
690  {
691  return m_RDNs;
692  }
693 
694  private:
695  explicit X509Name(const X509Internal::X509Name& internalName);
696  std::vector<RDN> m_RDNs;
697  };
698 
702  {
703  friend class X509Certificate;
704 
705  public:
709  {
710  return m_Type;
711  }
712 
715  bool isCritical() const
716  {
717  return m_IsCritical;
718  }
719 
723  std::unique_ptr<X509ExtensionData> getData() const;
724 
727  std::string getRawDataAsHexString() const
728  {
729  return m_Data;
730  }
731 
732  private:
733  X509Extension(const X509Internal::X509Extension& internalExtension);
734 
735  bool m_IsCritical;
736  X509ExtensionType m_Type;
737  std::string m_Data;
738  };
739 
742  class X509Certificate : public internal::CryptoDataReader<X509Certificate>
743  {
744  public:
748 
752 
756 
760 
764 
768 
772 
776 
780 
784 
787  const std::vector<X509Extension>& getExtensions() const;
788 
792  bool hasExtension(const X509ExtensionType& extensionType) const;
793 
797  const X509Extension* getExtension(X509ExtensionType extensionType) const;
798 
801  std::vector<uint8_t> toDER() const;
802 
805  std::string toPEM() const;
806 
810  std::string toJson(int indent = -1) const;
811 
815 
816  // Prevent copying
817  X509Certificate(const X509Certificate&) = delete;
818  X509Certificate& operator=(const X509Certificate&) = delete;
819 
820  private:
821  // Constructor/Destructor
822  X509Certificate(uint8_t* derData, size_t derDataLen, bool ownDerData);
823  X509Certificate(std::unique_ptr<uint8_t[]> derData, size_t derDataLen);
824 
826 
827  std::unique_ptr<X509Internal::X509Certificate> m_X509Internal;
828  X509Internal::X509TBSCertificate m_TBSCertificate;
829  mutable std::vector<X509Extension> m_Extensions;
830  mutable bool m_ExtensionsParsed = false;
831  std::unique_ptr<uint8_t[]> m_DerData;
832 
833  static constexpr const char* pemLabel = "CERTIFICATE";
834  };
835 } // namespace pcpp
Definition: Asn1Codec.h:699
Definition: Asn1Codec.h:131
Definition: Asn1Codec.h:355
Definition: Asn1Codec.h:787
Definition: X509Decoder.h:28
Value
Define enum types and the corresponding int values.
Definition: X509Decoder.h:32
@ DSAWithSHA256
DSA with SHA-256 signature algorithm.
Definition: X509Decoder.h:73
@ SHA512
SHA-512 hashing algorithm.
Definition: X509Decoder.h:40
@ ECDSAWithSHA1
ECDSA with SHA-1 signature algorithm.
Definition: X509Decoder.h:60
@ ECDSAWithSHA384
ECDSA with SHA-384 signature algorithm.
Definition: X509Decoder.h:64
@ RSAWithSHA1
RSA with SHA-1 signature algorithm.
Definition: X509Decoder.h:47
@ ECDSAWithSHA256
ECDSA with SHA-256 signature algorithm.
Definition: X509Decoder.h:62
@ SHA256
SHA-256 hashing algorithm.
Definition: X509Decoder.h:36
@ DiffieHellman
Diffie-Hellman key exchange algorithm.
Definition: X509Decoder.h:80
@ RSAWithSHA256
RSA with SHA-256 signature algorithm.
Definition: X509Decoder.h:49
@ ECDSAWithSHA512
ECDSA with SHA-512 signature algorithm.
Definition: X509Decoder.h:66
@ RSAWithSHA384
RSA with SHA-384 signature algorithm.
Definition: X509Decoder.h:51
@ DSA
Digital Signature Algorithm.
Definition: X509Decoder.h:69
@ Unknown
Unknown or unsupported algorithm.
Definition: X509Decoder.h:83
@ RSAPSS
RSA Probabilistic Signature Scheme (PSS)
Definition: X509Decoder.h:55
@ ECDSA
Elliptic Curve Digital Signature Algorithm.
Definition: X509Decoder.h:58
@ RSAWithSHA512
RSA with SHA-512 signature algorithm.
Definition: X509Decoder.h:53
@ DSAWithSHA1
DSA with SHA-1 signature algorithm.
Definition: X509Decoder.h:71
@ RSA
RSA encryption/signature algorithm.
Definition: X509Decoder.h:45
@ SHA1
SHA-1 hashing algorithm.
Definition: X509Decoder.h:34
@ ED448
EdDSA using Curve448 (Ed448)
Definition: X509Decoder.h:78
@ MD5
MD5 hashing algorithm (considered cryptographically broken)
Definition: X509Decoder.h:42
@ SHA384
SHA-384 hashing algorithm.
Definition: X509Decoder.h:38
@ ED25519
EdDSA using Curve25519 (Ed25519)
Definition: X509Decoder.h:76
constexpr X509Algorithm(Value value)
Definition: X509Decoder.h:91
std::string getOidValue() const
std::string toString() const
static X509Algorithm fromOidValue(const Asn1ObjectIdentifier &value)
Definition: X509Decoder.h:743
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
X509Timestamp getNotBefore() const
const std::vector< X509Extension > & getExtensions() const
std::string toPEM() const
X509Timestamp getNotAfter() const
X509Algorithm getPublicKeyAlgorithm() const
bool hasExtension(const X509ExtensionType &extensionType) const
X509Version getVersion() const
X509Algorithm getSignatureAlgorithm() const
std::string toJson(int indent=-1) const
Definition: X509Decoder.h:702
X509ExtensionType getType() const
Definition: X509Decoder.h:708
std::unique_ptr< X509ExtensionData > getData() const
bool isCritical() const
Definition: X509Decoder.h:715
std::string getRawDataAsHexString() const
Definition: X509Decoder.h:727
Definition: X509Decoder.h:203
std::string toString() const
constexpr X509ExtensionType(Value value)
Definition: X509Decoder.h:262
Value
Definition: X509Decoder.h:208
@ Unknown
Unknown or unsupported extension type.
Definition: X509Decoder.h:254
@ AuthorityKeyIdentifier
Authority Key Identifier - Identifies the public key used to verify the signature on this certificate...
Definition: X509Decoder.h:219
@ SubjectAltName
Subject Alternative Name - Allows identities to be bound to the subject of the certificate.
Definition: X509Decoder.h:221
@ CertificatePolicies
Certificate Policies - Contains a sequence of one or more policy terms.
Definition: X509Decoder.h:229
@ PolicyMappings
Definition: X509Decoder.h:232
@ InhibitAnyPolicy
Definition: X509Decoder.h:240
@ CTPrecertificateSCTs
Signed Certificate Timestamp - Contains a list of SCTs from Certificate Transparency logs.
Definition: X509Decoder.h:242
@ NameConstraints
Definition: X509Decoder.h:237
@ KeyUsage
Key Usage - Defines the purpose of the key contained in the certificate.
Definition: X509Decoder.h:212
@ AuthorityInfoAccess
Authority Information Access - Describes how to access CA information and services.
Definition: X509Decoder.h:227
@ ExtendedKeyUsage
Extended Key Usage - Indicates one or more purposes for which the certified public key may be used.
Definition: X509Decoder.h:214
@ BasicConstraints
Basic Constraints - Indicates if the subject is a CA and the maximum path length.
Definition: X509Decoder.h:210
@ SubjectKeyIdentifier
Definition: X509Decoder.h:217
@ IssuerAltName
Issuer Alternative Name - Allows additional identities to be associated with the issuer.
Definition: X509Decoder.h:223
@ CrlDistributionPoints
CRL Distribution Points - Identifies how CRL information is obtained.
Definition: X509Decoder.h:225
@ PolicyConstraints
Policy Constraints - Specifies constraints on path validation.
Definition: X509Decoder.h:234
@ TLSFeature
TLS Feature - Indicates which TLS features are required for the certificate to be used.
Definition: X509Decoder.h:248
@ SubjectInfoAccess
Subject Information Access - Describes how to access additional information about the subject.
Definition: X509Decoder.h:244
@ SubjectDirectoryAttributes
Subject Directory Attributes - Conveys identification attributes of the subject.
Definition: X509Decoder.h:252
@ FreshestCRL
Freshest CRL - Identifies how delta CRL information is obtained.
Definition: X509Decoder.h:246
@ OcspNoCheck
OCSP No Check - Indicates that an OCSP client should trust the certificate for OCSP signing.
Definition: X509Decoder.h:250
std::string getOidValue() const
static X509ExtensionType fromOidValue(const Asn1ObjectIdentifier &value)
Definition: X509Decoder.h:443
Definition: X509Decoder.h:375
Definition: X509Decoder.h:605
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:503
X509ExtensionType getType() const
Definition: X509Decoder.h:532
static bool isValidExtensionsRecord(const Asn1Record *record)
std::vector< X509Extension > getExtensions() const
Definition: X509Decoder.h:430
std::vector< X509RelativeDistinguishedName > getRDNs() const
X509AlgorithmIdentifier getAlgorithm() const
Definition: X509Decoder.h:550
X509SubjectPublicKeyInfo getSubjectPublicKeyInfo() const
X509AlgorithmIdentifier getSignature() const
X509SerialNumber getSerialNumber() const
std::unique_ptr< X509Extensions > getExtensions() const
Definition: X509Decoder.h:461
X509Timestamp getNotBefore() const
X509Timestamp getNotAfter() const
Definition: X509Decoder.h:386
static bool isValidVersionRecord(const Asn1Record *record)
Definition: X509Decoder.h:339
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:343
Definition: X509Decoder.h:651
const std::vector< RDN > & getRDNs() const
Definition: X509Decoder.h:689
std::string toString(const std::string &delimiter=", ") const
Definition: X509Decoder.h:290
X509SerialNumber(const std::string &serialNumber)
Definition: X509Decoder.h:294
std::string toString(const std::string &delimiter=":") const
Definition: X509Decoder.h:309
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:314
Definition: X509Decoder.h:122
static X520DistinguishedName fromOidValue(const Asn1ObjectIdentifier &value)
std::string getOidValue() const
Value
Define enum types and the corresponding int values.
Definition: X509Decoder.h:126
@ BusinessCategory
Business Category - Type of business or organization.
Definition: X509Decoder.h:164
@ EmailAddress
Email Address - Email address in the format user@domain.
Definition: X509Decoder.h:158
@ Country
Country Name (C) - Two-letter ISO 3166-1 alpha-2 country code.
Definition: X509Decoder.h:134
@ SerialNumber
Serial Number - Serial number of the certificate.
Definition: X509Decoder.h:132
@ CommonName
Common Name (CN) - Typically the fully qualified domain name (FQDN)
Definition: X509Decoder.h:128
@ Unknown
Unknown or unsupported distinguished name type.
Definition: X509Decoder.h:166
@ DnQualifier
Distinguished Name Qualifier - Disambiguates similar distinguished names.
Definition: X509Decoder.h:154
@ GivenName
Given Name (GN) - First name of a person.
Definition: X509Decoder.h:146
@ Organization
Organization Name (O) - Name of the organization.
Definition: X509Decoder.h:140
@ Locality
Locality (L) - City or locality name.
Definition: X509Decoder.h:136
@ Initials
Initials - Initials of a person's name.
Definition: X509Decoder.h:148
@ StateOrProvince
State or Province Name (ST) - State or province name.
Definition: X509Decoder.h:138
@ Pseudonym
Pseudonym - A person's nickname or alias.
Definition: X509Decoder.h:150
@ Surname
Surname (SN) - Family name of a person.
Definition: X509Decoder.h:130
@ Title
Title - Job title or position.
Definition: X509Decoder.h:144
@ StreetAddress
Street Address - Physical street address.
Definition: X509Decoder.h:162
@ DomainComponent
Domain Component (DC) - Domain component in domain names (e.g., "example" in "example....
Definition: X509Decoder.h:156
@ OrganizationalUnit
Organizational Unit (OU) - Department or division within an organization.
Definition: X509Decoder.h:142
@ PostalCode
Postal Code - Postal or ZIP code.
Definition: X509Decoder.h:160
@ GenerationQualifier
Generation Qualifier - A qualifier indicating a person's generation (e.g., Jr., Sr....
Definition: X509Decoder.h:152
std::string getShortName() const
std::string toString() const
A template helper class for reading and decoding cryptographic data in different formats (DER/PEM)
Definition: CryptoDataReader.h:23
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
X509Version
Definition: X509Decoder.h:14
@ V1
X.509 Version 1.
@ V3
X.509 Version 3.
@ V2
X.509 Version 2.
Definition: X509Decoder.h:658
bool operator==(const RDN &other) const
Equality comparison operator.
Definition: X509Decoder.h:663
X520DistinguishedName type
The type of the distinguished name.
Definition: X509Decoder.h:659
bool operator!=(const RDN &other) const
Inequality comparison operator.
Definition: X509Decoder.h:669
friend std::ostream & operator<<(std::ostream &os, const RDN &rdn)
Stream output operator for RDN.
Definition: X509Decoder.h:675
std::string value
The value of the distinguished name.
Definition: X509Decoder.h:660