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  // cppcheck-suppress noExplicitConstructor
172  constexpr X520DistinguishedName(Value value) : m_Value(value)
173  {}
174 
176  std::string toString() const;
177 
180  std::string getShortName() const;
181 
183  std::string getOidValue() const;
184 
189 
190  // Allow switch and comparisons.
191  constexpr operator Value() const
192  {
193  return m_Value;
194  }
195  explicit operator bool() const = delete;
196 
197  private:
198  Value m_Value = Unknown;
199  };
200 
204  {
205  public:
208  enum Value : uint8_t
209  {
255  Unknown
256  };
257 
258  X509ExtensionType() = default;
259 
260  // cppcheck-suppress noExplicitConstructor
263  constexpr X509ExtensionType(Value value) : m_Value(value)
264  {}
265 
267  std::string toString() const;
268 
270  std::string getOidValue() const;
271 
276 
277  // Allow switch and comparisons.
278  constexpr operator Value() const
279  {
280  return m_Value;
281  }
282  explicit operator bool() const = delete;
283 
284  private:
285  Value m_Value = Unknown;
286  };
287 
291  {
292  public:
295  explicit X509SerialNumber(const std::string& serialNumber) : m_SerialNumber(serialNumber)
296  {}
297 
301  std::string toString(const std::string& delimiter = ":") const;
302 
303  private:
304  std::string m_SerialNumber;
305  };
306 
310  {
311  public:
315  explicit X509Timestamp(Asn1TimeRecord* timeRecord) : m_Record(timeRecord)
316  {}
317 
324  std::string toString(const std::string& format = "%Y-%m-%d %H:%M:%S", const std::string& timezone = "Z",
325  bool includeMilliseconds = false) const;
326 
331  std::chrono::system_clock::time_point getTimestamp(const std::string& timezone = "Z") const;
332 
333  private:
334  Asn1TimeRecord* m_Record;
335  };
336 
339  class X509Key
340  {
341  public:
344  explicit X509Key(const std::vector<uint8_t>& key) : m_Key(key)
345  {}
346 
350  std::string toString(const std::string& delimiter = ":") const;
351 
354  const std::vector<uint8_t>& getBytes() const;
355 
356  private:
357  std::vector<uint8_t> m_Key;
358  };
359 
362  namespace X509Internal
363  {
364  // Forward declarations
365  class X509Certificate;
366  class X509TBSCertificate;
367  class X509Name;
368  class X509SubjectPublicKeyInfo;
369  class X509Extension;
370  class X509Extensions;
371 
375  template <typename Asn1RecordType> class X509Base
376  {
377  protected:
378  explicit X509Base(Asn1RecordType* root) : m_Root(root)
379  {}
380 
381  Asn1RecordType* m_Root;
382  };
383 
386  class X509VersionRecord : public X509Base<Asn1ConstructedRecord>
387  {
388  using X509Base::X509Base;
389  friend class X509TBSCertificate;
390 
391  public:
395 
399  static bool isValidVersionRecord(const Asn1Record* record);
400 
401  private:
402  static constexpr int versionOffset = 0;
403  };
404 
407  class X509RelativeDistinguishedName : public X509Base<Asn1SetRecord>
408  {
409  using X509Base::X509Base;
410  friend class X509Name;
411 
412  public:
416 
419  std::string getValue() const;
420 
421  private:
422  static constexpr int typeOffset = 0;
423  static constexpr int valueOffset = 1;
424 
425  Asn1Record* getRecord(int index) const;
426  };
427 
430  class X509Name : public X509Base<Asn1SequenceRecord>
431  {
432  using X509Base::X509Base;
433  friend class X509TBSCertificate;
434 
435  public:
438  std::vector<X509RelativeDistinguishedName> getRDNs() const;
439  };
440 
443  class X509AlgorithmIdentifier : public X509Base<Asn1SequenceRecord>
444  {
445  using X509Base::X509Base;
446  friend class X509SubjectPublicKeyInfo;
447  friend class X509TBSCertificate;
448  friend class X509Certificate;
449 
450  public:
454 
455  private:
456  static constexpr int algorithmOffset = 0;
457  };
458 
461  class X509Validity : public X509Base<Asn1SequenceRecord>
462  {
463  using X509Base::X509Base;
464  friend class X509TBSCertificate;
465 
466  public:
470 
474 
475  private:
476  static constexpr int notBeforeOffset = 0;
477  static constexpr int notAfterOffset = 1;
478  };
479 
482  class X509SubjectPublicKeyInfo : public X509Base<Asn1SequenceRecord>
483  {
484  using X509Base::X509Base;
485  friend class X509TBSCertificate;
486 
487  public:
491 
495 
496  private:
497  static constexpr int algorithmOffset = 0;
498  static constexpr int subjectPublicKeyOffset = 1;
499  };
500 
503  class X509Extension : public X509Base<Asn1SequenceRecord>
504  {
505  friend class X509Extensions;
506  using X509Base::X509Base;
507 
508  public:
512 
515  bool isCritical() const;
516 
519  std::string getValue() const;
520 
521  private:
522  static constexpr int extensionIdOffset = 0;
523 
524  int m_CriticalOffset = -1;
525  int m_ExtensionValueOffset = 1;
526 
527  explicit X509Extension(Asn1SequenceRecord* root);
528  };
529 
532  class X509Extensions : public X509Base<Asn1ConstructedRecord>
533  {
534  using X509Base::X509Base;
535  friend class X509TBSCertificate;
536 
537  public:
540  std::vector<X509Extension> getExtensions() const;
541 
545  static bool isValidExtensionsRecord(const Asn1Record* record);
546  };
547 
550  class X509TBSCertificate : public X509Base<Asn1SequenceRecord>
551  {
552  using X509Base::X509Base;
553  friend class X509Certificate;
554 
555  public:
559 
563 
567 
571 
575 
579 
583 
586  std::unique_ptr<X509Extensions> getExtensions() const;
587 
588  private:
589  int m_VersionOffset = -1;
590  int m_SerialNumberOffset = 0;
591  int m_SignatureOffset = 1;
592  int m_IssuerOffset = 2;
593  int m_ValidityOffset = 3;
594  int m_SubjectOffset = 4;
595  int m_SubjectPublicKeyInfoOffset = 5;
596  int m_IssuerUniqueID = -1;
597  int m_SubjectUniqueID = -1;
598  int m_ExtensionsOffset = -1;
599 
600  explicit X509TBSCertificate(Asn1SequenceRecord* root);
601  };
602 
606  {
607  public:
611 
615 
619 
623 
628  static std::unique_ptr<X509Certificate> decode(const uint8_t* data, size_t dataLen);
629 
632  std::vector<uint8_t> encode();
633 
634  private:
635  static constexpr int tbsCertificateOffset = 0;
636  static constexpr int signatureAlgorithmOffset = 1;
637  static constexpr int signatureOffset = 2;
638 
639  explicit X509Certificate(std::unique_ptr<Asn1Record> root) : m_Root(std::move(root))
640  {}
641 
642  std::unique_ptr<Asn1Record> m_Root;
643  };
644  } // namespace X509Internal
645 
646  // Forward declarations
647  class X509Certificate;
648 
651  class X509Name
652  {
653  friend class X509Certificate;
654 
655  public:
658  struct RDN
659  {
661  std::string value;
662 
664  bool operator==(const RDN& other) const
665  {
666  return type == other.type && value == other.value;
667  }
668 
670  bool operator!=(const RDN& other) const
671  {
672  return !(*this == other);
673  }
674 
676  friend std::ostream& operator<<(std::ostream& os, const RDN& rdn)
677  {
678  os << "RDN{type=" << rdn.type.getShortName() << ", value=" << rdn.value << "}";
679  return os;
680  }
681  };
682 
686  std::string toString(const std::string& delimiter = ", ") const;
687 
690  const std::vector<RDN>& getRDNs() const
691  {
692  return m_RDNs;
693  }
694 
695  private:
696  explicit X509Name(const X509Internal::X509Name& internalName);
697  std::vector<RDN> m_RDNs;
698  };
699 
703  {
704  friend class X509Certificate;
705 
706  public:
710  {
711  return m_Type;
712  }
713 
716  bool isCritical() const
717  {
718  return m_IsCritical;
719  }
720 
724  std::unique_ptr<X509ExtensionData> getData() const;
725 
728  std::string getRawDataAsHexString() const
729  {
730  return m_Data;
731  }
732 
733  private:
734  explicit X509Extension(const X509Internal::X509Extension& internalExtension);
735 
736  bool m_IsCritical;
737  X509ExtensionType m_Type;
738  std::string m_Data;
739  };
740 
743  class X509Certificate : public internal::CryptoDataReader<X509Certificate>
744  {
745  public:
749 
753 
757 
761 
765 
769 
773 
777 
781 
785 
788  const std::vector<X509Extension>& getExtensions() const;
789 
793  bool hasExtension(const X509ExtensionType& extensionType) const;
794 
798  const X509Extension* getExtension(X509ExtensionType extensionType) const;
799 
802  std::vector<uint8_t> toDER() const;
803 
806  std::string toPEM() const;
807 
811  std::string toJson(int indent = -1) const;
812 
816 
817  // Prevent copying
818  X509Certificate(const X509Certificate&) = delete;
819  X509Certificate& operator=(const X509Certificate&) = delete;
820 
821  private:
822  // Constructor/Destructor
823  X509Certificate(uint8_t* derData, size_t derDataLen, bool ownDerData);
824  X509Certificate(std::unique_ptr<uint8_t[]> derData, size_t derDataLen);
825 
827 
828  std::unique_ptr<X509Internal::X509Certificate> m_X509Internal;
829  X509Internal::X509TBSCertificate m_TBSCertificate;
830  mutable std::vector<X509Extension> m_Extensions;
831  mutable bool m_ExtensionsParsed = false;
832  std::unique_ptr<uint8_t[]> m_DerData;
833 
834  static constexpr const char* pemLabel = "CERTIFICATE";
835  };
836 } // namespace pcpp
Definition: Asn1Codec.h:698
Definition: Asn1Codec.h:131
Definition: Asn1Codec.h:355
Definition: Asn1Codec.h:786
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:744
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:703
X509ExtensionType getType() const
Definition: X509Decoder.h:709
std::unique_ptr< X509ExtensionData > getData() const
bool isCritical() const
Definition: X509Decoder.h:716
std::string getRawDataAsHexString() const
Definition: X509Decoder.h:728
Definition: X509Decoder.h:204
std::string toString() const
constexpr X509ExtensionType(Value value)
Definition: X509Decoder.h:263
Value
Definition: X509Decoder.h:209
@ Unknown
Unknown or unsupported extension type.
Definition: X509Decoder.h:255
@ AuthorityKeyIdentifier
Authority Key Identifier - Identifies the public key used to verify the signature on this certificate...
Definition: X509Decoder.h:220
@ SubjectAltName
Subject Alternative Name - Allows identities to be bound to the subject of the certificate.
Definition: X509Decoder.h:222
@ CertificatePolicies
Certificate Policies - Contains a sequence of one or more policy terms.
Definition: X509Decoder.h:230
@ PolicyMappings
Definition: X509Decoder.h:233
@ InhibitAnyPolicy
Definition: X509Decoder.h:241
@ CTPrecertificateSCTs
Signed Certificate Timestamp - Contains a list of SCTs from Certificate Transparency logs.
Definition: X509Decoder.h:243
@ NameConstraints
Definition: X509Decoder.h:238
@ KeyUsage
Key Usage - Defines the purpose of the key contained in the certificate.
Definition: X509Decoder.h:213
@ AuthorityInfoAccess
Authority Information Access - Describes how to access CA information and services.
Definition: X509Decoder.h:228
@ ExtendedKeyUsage
Extended Key Usage - Indicates one or more purposes for which the certified public key may be used.
Definition: X509Decoder.h:215
@ BasicConstraints
Basic Constraints - Indicates if the subject is a CA and the maximum path length.
Definition: X509Decoder.h:211
@ SubjectKeyIdentifier
Definition: X509Decoder.h:218
@ IssuerAltName
Issuer Alternative Name - Allows additional identities to be associated with the issuer.
Definition: X509Decoder.h:224
@ CrlDistributionPoints
CRL Distribution Points - Identifies how CRL information is obtained.
Definition: X509Decoder.h:226
@ PolicyConstraints
Policy Constraints - Specifies constraints on path validation.
Definition: X509Decoder.h:235
@ TLSFeature
TLS Feature - Indicates which TLS features are required for the certificate to be used.
Definition: X509Decoder.h:249
@ SubjectInfoAccess
Subject Information Access - Describes how to access additional information about the subject.
Definition: X509Decoder.h:245
@ SubjectDirectoryAttributes
Subject Directory Attributes - Conveys identification attributes of the subject.
Definition: X509Decoder.h:253
@ FreshestCRL
Freshest CRL - Identifies how delta CRL information is obtained.
Definition: X509Decoder.h:247
@ OcspNoCheck
OCSP No Check - Indicates that an OCSP client should trust the certificate for OCSP signing.
Definition: X509Decoder.h:251
std::string getOidValue() const
static X509ExtensionType fromOidValue(const Asn1ObjectIdentifier &value)
Definition: X509Decoder.h:444
Definition: X509Decoder.h:376
Definition: X509Decoder.h:606
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:504
X509ExtensionType getType() const
Definition: X509Decoder.h:533
static bool isValidExtensionsRecord(const Asn1Record *record)
std::vector< X509Extension > getExtensions() const
Definition: X509Decoder.h:431
std::vector< X509RelativeDistinguishedName > getRDNs() const
X509AlgorithmIdentifier getAlgorithm() const
Definition: X509Decoder.h:551
X509SubjectPublicKeyInfo getSubjectPublicKeyInfo() const
X509AlgorithmIdentifier getSignature() const
X509SerialNumber getSerialNumber() const
std::unique_ptr< X509Extensions > getExtensions() const
Definition: X509Decoder.h:462
X509Timestamp getNotBefore() const
X509Timestamp getNotAfter() const
Definition: X509Decoder.h:387
static bool isValidVersionRecord(const Asn1Record *record)
Definition: X509Decoder.h:340
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:344
Definition: X509Decoder.h:652
const std::vector< RDN > & getRDNs() const
Definition: X509Decoder.h:690
std::string toString(const std::string &delimiter=", ") const
Definition: X509Decoder.h:291
X509SerialNumber(const std::string &serialNumber)
Definition: X509Decoder.h:295
std::string toString(const std::string &delimiter=":") const
Definition: X509Decoder.h:310
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:315
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:659
bool operator==(const RDN &other) const
Equality comparison operator.
Definition: X509Decoder.h:664
X520DistinguishedName type
The type of the distinguished name.
Definition: X509Decoder.h:660
bool operator!=(const RDN &other) const
Inequality comparison operator.
Definition: X509Decoder.h:670
friend std::ostream & operator<<(std::ostream &os, const RDN &rdn)
Stream output operator for RDN.
Definition: X509Decoder.h:676
std::string value
The value of the distinguished name.
Definition: X509Decoder.h:661