PcapPlusPlus  Next
CryptoKeyDecoder.h
Go to the documentation of this file.
1 #pragma once
2 
4 
5 #include "CryptoDataReader.h"
6 #include "Asn1Codec.h"
7 #include <string>
8 #include <memory>
9 #include <utility>
10 
13 namespace pcpp
14 {
15  namespace internal
16  {
20  {
21  protected:
22  explicit PrivateKeyDataView(Asn1SequenceRecord* root, std::string decoderType)
23  : m_Root(root), m_DecoderType(std::move(decoderType))
24  {}
25 
26  ~PrivateKeyDataView() = default;
27 
28  template <class Asn1RecordType>
29  Asn1RecordType* castSubRecordAs(int index, const std::string& fieldName) const
30  {
31  try
32  {
33  return m_Root->getSubRecords().at(index)->template castAs<Asn1RecordType>();
34  }
35  catch (const std::exception&)
36  {
37  throw std::runtime_error("Invalid " + m_DecoderType + " data: " + fieldName);
38  }
39  }
40 
41  private:
42  Asn1SequenceRecord* m_Root;
43  std::string m_DecoderType;
44  };
45 
49  {
50  public:
52  uint8_t getVersion() const;
53 
55  std::string getModulus() const;
56 
58  uint64_t getPublicExponent() const;
59 
61  std::string getPrivateExponent() const;
62 
64  std::string getPrime1() const;
65 
67  std::string getPrime2() const;
68 
70  std::string getExponent1() const;
71 
73  std::string getExponent2() const;
74 
76  std::string getCoefficient() const;
77 
78  protected:
79  explicit RSAPrivateKeyDataView(Asn1SequenceRecord* root, std::string decoderType)
80  : PrivateKeyDataView(root, decoderType)
81  {}
82 
83  ~RSAPrivateKeyDataView() = default;
84 
85  private:
86  static constexpr int versionOffset = 0;
87  static constexpr int modulusOffset = 1;
88  static constexpr int publicExponentOffset = 2;
89  static constexpr int privateExponentOffset = 3;
90  static constexpr int prime1Offset = 4;
91  static constexpr int prime2Offset = 5;
92  static constexpr int exponent1Offset = 6;
93  static constexpr int exponent2Offset = 7;
94  static constexpr int coefficientOffset = 8;
95  };
96 
100  {
101  public:
103  uint8_t getVersion() const;
104 
106  std::string getPrivateKey() const;
107 
109  std::unique_ptr<Asn1ObjectIdentifier> getParameters() const;
110 
112  std::string getPublicKey() const;
113 
114  protected:
115  explicit ECPrivateKeyDataView(Asn1SequenceRecord* root, std::string decoderType);
116 
117  ~ECPrivateKeyDataView() = default;
118 
119  private:
120  static constexpr int versionOffset = 0;
121  static constexpr int privateKeyOffset = 1;
122 
123  int m_ParametersOffset = -1;
124  int m_PublicKeyOffset = -1;
125  };
126 
129  template <typename CryptoKey> class CryptographicKey
130  {
131  public:
134  std::vector<uint8_t> toDER() const
135  {
136  return m_Root->encode();
137  }
138 
141  std::string toPEM() const
142  {
143  return PemCodec::encode(m_Root->encode(), CryptoKey::pemLabel);
144  }
145 
146  protected:
147  CryptographicKey(std::unique_ptr<uint8_t[]> derData, size_t derDataLen)
148  : m_DerData(std::move(derData)), m_Root(Asn1Record::decode(m_DerData.get(), derDataLen))
149  {}
150 
151  CryptographicKey(uint8_t* derData, size_t derDataLen, bool ownDerData)
152  {
153  m_Root = Asn1Record::decode(derData, derDataLen);
154  if (ownDerData)
155  {
156  m_DerData.reset(derData);
157  }
158  }
159 
160  ~CryptographicKey() = default;
161 
162  Asn1SequenceRecord* getRoot() const
163  {
164  try
165  {
166  return m_Root->castAs<Asn1SequenceRecord>();
167  }
168  catch (const std::bad_cast&)
169  {
170  throw std::runtime_error("Invalid " + std::string(CryptoKey::keyType) + " data");
171  }
172  }
173 
174  template <class Asn1RecordType>
175  Asn1RecordType* castSubRecordAs(int index, const std::string& fieldName) const
176  {
177  try
178  {
179  return getRoot()->getSubRecords().at(index)->template castAs<Asn1RecordType>();
180  }
181  catch (const std::exception&)
182  {
183  throw std::runtime_error("Invalid " + std::string(CryptoKey::keyType) + " data: " + fieldName);
184  }
185  }
186 
187  private:
188  std::unique_ptr<uint8_t[]> m_DerData;
189  std::unique_ptr<Asn1Record> m_Root;
190  };
191  } // namespace internal
192 
198  {
199  public:
201  enum Value : uint8_t
202  {
219  };
220 
221  CryptographicKeyAlgorithm() = default;
222 
223  // cppcheck-suppress noExplicitConstructor
226  constexpr CryptographicKeyAlgorithm(Value value) : m_Value(value)
227  {}
228 
230  std::string toString() const;
231 
233  std::string getOidValue() const;
234 
240 
241  // Allow switch and comparisons.
242  constexpr operator Value() const
243  {
244  return m_Value;
245  }
246 
247  // Prevent usage: if(LdapOperationType)
248  explicit operator bool() const = delete;
249 
250  private:
251  Value m_Value = Unknown;
252  };
253 
257  class RSAPrivateKey : public internal::CryptographicKey<RSAPrivateKey>,
258  public internal::CryptoDataReader<RSAPrivateKey>,
260  {
261  protected:
262  RSAPrivateKey(std::unique_ptr<uint8_t[]> derData, size_t derDataLen)
263  : CryptographicKey(std::move(derData), derDataLen), RSAPrivateKeyDataView(getRoot(), keyType)
264  {}
265 
266  RSAPrivateKey(uint8_t* derData, size_t derDataLen, bool ownDerData)
267  : CryptographicKey(derData, derDataLen, ownDerData), RSAPrivateKeyDataView(getRoot(), keyType)
268  {}
269 
270  private:
271  static constexpr const char* pemLabel = "RSA PRIVATE KEY";
272  static constexpr const char* keyType = "RSA private key";
273 
274  using CryptographicKey::CryptographicKey;
277  };
278 
282  class ECPrivateKey : public internal::CryptographicKey<ECPrivateKey>,
283  public internal::CryptoDataReader<ECPrivateKey>,
285  {
286  protected:
287  ECPrivateKey(std::unique_ptr<uint8_t[]> derData, size_t derDataLen)
288  : CryptographicKey(std::move(derData), derDataLen), ECPrivateKeyDataView(getRoot(), keyType)
289  {}
290 
291  ECPrivateKey(uint8_t* derData, size_t derDataLen, bool ownDerData)
292  : CryptographicKey(derData, derDataLen, ownDerData), ECPrivateKeyDataView(getRoot(), keyType)
293  {}
294 
295  private:
296  static constexpr const char* pemLabel = "EC PRIVATE KEY";
297  static constexpr const char* keyType = "EC private key";
298 
299  using CryptographicKey::CryptographicKey;
302  };
303 
307  class PKCS8PrivateKey : public internal::CryptographicKey<PKCS8PrivateKey>,
308  public internal::CryptoDataReader<PKCS8PrivateKey>
309  {
310  public:
316  {
317  public:
319  virtual ~PrivateKeyData() = default;
320 
325  template <class PrivateKeyDataType> PrivateKeyDataType* castAs()
326  {
327  auto privateKeyData = dynamic_cast<PrivateKeyDataType*>(this);
328  if (privateKeyData == nullptr)
329  {
330  throw std::runtime_error("Trying to PKCS#8 private key data to the wrong type");
331  }
332  return privateKeyData;
333  }
334 
335  protected:
336  explicit PrivateKeyData(const std::string& rawData);
337 
338  Asn1SequenceRecord* getRoot() const
339  {
340  return m_Root->castAs<Asn1SequenceRecord>();
341  }
342 
343  std::vector<uint8_t> m_DerData;
344  std::unique_ptr<Asn1Record> m_Root;
345  };
346 
352  {
353  friend class PKCS8PrivateKey;
354  explicit RSAPrivateKeyData(const std::string& rawData);
355  };
356 
362  {
363  friend class PKCS8PrivateKey;
364  explicit ECPrivateKeyData(const std::string& rawData);
365  };
366 
372  {
373  friend class PKCS8PrivateKey;
374  explicit Ed25519PrivateKeyData(const std::string& rawData);
375 
376  public:
378  std::string getPrivateKey() const;
379  };
380 
382  uint8_t getVersion() const;
383 
386 
390  std::unique_ptr<PrivateKeyData> getPrivateKey() const;
391 
395  template <typename PrivateKeyDataType> std::unique_ptr<PrivateKeyDataType> getPrivateKeyAs() const
396  {
397  auto privateKey = getPrivateKey();
398  if (privateKey == nullptr)
399  {
400  return nullptr;
401  }
402 
403  if (auto* specificPrivateKey = dynamic_cast<PrivateKeyDataType*>(privateKey.get()))
404  {
405  privateKey.release();
406  return std::unique_ptr<PrivateKeyDataType>(specificPrivateKey);
407  }
408 
409  return nullptr;
410  }
411 
412  private:
413  static constexpr const char* pemLabel = "PRIVATE KEY";
414  static constexpr const char* keyType = "PKCS#8 private key";
415  static constexpr int versionOffset = 0;
416  static constexpr int privateKeyAlgorithmOffset = 1;
417  static constexpr int privateKeyOffset = 2;
418 
419  using CryptographicKey::CryptographicKey;
422  };
423 
427  class RSAPublicKey : public internal::CryptographicKey<RSAPublicKey>,
428  public internal::CryptoDataReader<RSAPublicKey>
429  {
430  public:
432  std::string getModulus() const;
433 
435  uint64_t getPublicExponent() const;
436 
437  private:
438  static constexpr const char* pemLabel = "RSA PUBLIC KEY";
439  static constexpr const char* keyType = "RSA public key";
440  static constexpr int modulusOffset = 0;
441  static constexpr int publicExponentOffset = 1;
442 
443  using CryptographicKey::CryptographicKey;
446  };
447 
452  class SubjectPublicKeyInfo : public internal::CryptographicKey<SubjectPublicKeyInfo>,
453  public internal::CryptoDataReader<SubjectPublicKeyInfo>
454  {
455  public:
458 
460  std::string getSubjectPublicKey() const;
461 
462  private:
463  static constexpr const char* pemLabel = "PUBLIC KEY";
464  static constexpr const char* keyType = "public key";
465  static constexpr int algorithmOffset = 0;
466  static constexpr int subjectPublicKeyOffset = 1;
467 
468  using CryptographicKey::CryptographicKey;
471  };
472 } // namespace pcpp
PointerVector< Asn1Record > & getSubRecords()
Definition: Asn1Codec.h:312
Definition: Asn1Codec.h:699
Definition: Asn1Codec.h:131
static std::unique_ptr< Asn1Record > decode(const uint8_t *data, size_t dataLen, bool lazy=true)
Definition: Asn1Codec.h:355
Definition: CryptoKeyDecoder.h:198
static CryptographicKeyAlgorithm fromOidValue(const Asn1ObjectIdentifier &value)
Creates a CryptographicKeyAlgorithm object from an OID value.
std::string toString() const
constexpr CryptographicKeyAlgorithm(Value value)
Constructs a CryptographicKeyAlgorithm object from a Value enum.
Definition: CryptoKeyDecoder.h:226
std::string getOidValue() const
Value
Define enum types and the corresponding int values.
Definition: CryptoKeyDecoder.h:202
@ X448
Diffie-Hellman using Curve448 (Goldilocks curve)
Definition: CryptoKeyDecoder.h:216
@ ED25519
EdDSA using Curve25519 (Ed25519)
Definition: CryptoKeyDecoder.h:210
@ ECDSA
Elliptic Curve Digital Signature Algorithm.
Definition: CryptoKeyDecoder.h:208
@ DiffieHellman
Diffie-Hellman key exchange algorithm.
Definition: CryptoKeyDecoder.h:214
@ ED448
EdDSA using Curve448 (Ed448)
Definition: CryptoKeyDecoder.h:212
@ RSA
RSA encryption/signature algorithm.
Definition: CryptoKeyDecoder.h:204
@ Unknown
Unknown or unsupported algorithm.
Definition: CryptoKeyDecoder.h:218
@ DSA
Digital Signature Algorithm.
Definition: CryptoKeyDecoder.h:206
Represents an EC private key in SEC1 format This class provides methods to decode and access the comp...
Definition: CryptoKeyDecoder.h:285
Contains EC private key data extracted from PKCS#8 format This class provides access to the component...
Definition: CryptoKeyDecoder.h:362
Contains Ed25519 private key data extracted from PKCS#8 format This class provides access to the comp...
Definition: CryptoKeyDecoder.h:372
Base class for private key data in PKCS#8 format This class serves as a base for different types of p...
Definition: CryptoKeyDecoder.h:316
virtual ~PrivateKeyData()=default
Virtual destructor.
PrivateKeyDataType * castAs()
Casts the private key data to a specific type.
Definition: CryptoKeyDecoder.h:325
Contains RSA private key data extracted from PKCS#8 format This class provides access to the componen...
Definition: CryptoKeyDecoder.h:352
Represents a private key in PKCS#8 format This class provides methods to decode and access the compon...
Definition: CryptoKeyDecoder.h:309
uint8_t getVersion() const
std::unique_ptr< PrivateKeyData > getPrivateKey() const
Gets the private key data.
std::unique_ptr< PrivateKeyDataType > getPrivateKeyAs() const
Gets the private key data cast to a requested type.
Definition: CryptoKeyDecoder.h:395
CryptographicKeyAlgorithm getPrivateKeyAlgorithm() const
static std::string encode(const std::vector< uint8_t > &data, const std::string &label)
Represents an RSA private key in PKCS#1 format This class provides methods to decode and access the c...
Definition: CryptoKeyDecoder.h:260
Represents an RSA public key in PKCS#1 format This class provides methods to decode and access the co...
Definition: CryptoKeyDecoder.h:429
std::string getModulus() const
uint64_t getPublicExponent() const
Represents a Subject Public Key Info (SPKI) structure This class provides methods to decode and acces...
Definition: CryptoKeyDecoder.h:454
CryptographicKeyAlgorithm getAlgorithm() const
std::string getSubjectPublicKey() const
A template helper class for reading and decoding cryptographic data in different formats (DER/PEM)
Definition: CryptoDataReader.h:23
Definition: CryptoKeyDecoder.h:130
std::string toPEM() const
Definition: CryptoKeyDecoder.h:141
std::vector< uint8_t > toDER() const
Definition: CryptoKeyDecoder.h:134
Definition: CryptoKeyDecoder.h:100
std::unique_ptr< Asn1ObjectIdentifier > getParameters() const
Definition: CryptoKeyDecoder.h:20
Definition: CryptoKeyDecoder.h:49
std::string getPrivateExponent() const
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19