Coverage Report

Created: 2026-09-28 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/header/X509ExtensionDataDecoder.h
Line
Count
Source
1
#pragma once
2
#include "Asn1Codec.h"
3
4
/// @namespace pcpp
5
/// The main namespace for the PcapPlusPlus lib
6
namespace pcpp
7
{
8
  /// @class X509ExtendedKeyUsagePurpose
9
  /// Represents an extended key usage purpose
10
  class X509ExtendedKeyUsagePurpose
11
  {
12
  public:
13
    /// Define enum types for extended key usage purposes
14
    enum Value : uint8_t
15
    {
16
      /// Server authentication
17
      ServerAuth,
18
      /// Client authentication
19
      ClientAuth,
20
      /// Code signing
21
      CodeSigning,
22
      /// Email protection
23
      EmailProtection,
24
      /// Time stamping
25
      TimeStamping,
26
      /// OCSP signing
27
      OCSPSigning,
28
      /// IPsec end system
29
      IPSecEndSystem,
30
      /// IPsec tunnel
31
      IPSecTunnel,
32
      /// IPsec user
33
      IPSecUser,
34
      // Any extended key usage
35
      AnyExtendedKeyUsage,
36
      /// Smart card logon
37
      SmartCardLogon,
38
      /// Encrypted file system
39
      EncryptedFileSystem,
40
      /// Document signing
41
      DocumentSigning,
42
      /// Unknown purpose value
43
      Unknown,
44
    };
45
46
    X509ExtendedKeyUsagePurpose() = default;
47
48
    // cppcheck-suppress noExplicitConstructor
49
    constexpr X509ExtendedKeyUsagePurpose(Value value) : m_Value(value)
50
0
    {}
51
52
    /// @return A string representation of the purpose type
53
    std::string toString() const;
54
55
    /// @return The OID value of the purpose type
56
    std::string getOidValue() const;
57
58
    /// Creates an X509ExtendedKeyUsagePurpose from an OID value
59
    /// @param[in] value The ASN.1 object identifier
60
    /// @return The corresponding X509ExtendedKeyUsagePurpose value, or Unknown if no match is found
61
    static X509ExtendedKeyUsagePurpose fromOidValue(const Asn1ObjectIdentifier& value);
62
63
    // Allow switch and comparisons.
64
    constexpr operator Value() const
65
0
    {
66
0
      return m_Value;
67
0
    }
68
69
    // Prevent usage: if(X509ExtendedKeyUsagePurpose)
70
    explicit operator bool() const = delete;
71
72
  private:
73
    Value m_Value = Unknown;
74
  };
75
76
  /// @namespace X509Internal
77
  /// Internal implementation details for X.509 certificate parsing
78
  namespace X509Internal
79
  {
80
    /// @class X509ExtensionDataDecoder
81
    /// Base class for X.509 extension data decoders
82
    class X509ExtensionDataDecoder
83
    {
84
    protected:
85
      static std::unique_ptr<Asn1Record> decodeAsn1Data(const std::string& rawData,
86
                                                        std::vector<uint8_t>& rawDataBytes);
87
    };
88
89
    /// @class X509BasicConstraintsDataDecoder
90
    /// Represents the data decoder for the basic constraints extension
91
    class X509BasicConstraintsDataDecoder : public X509ExtensionDataDecoder
92
    {
93
    public:
94
      /// A factory method that creates an instance of X509BasicConstraintsDataDecoder from raw data
95
      /// @param[in] rawData The raw data of the extension
96
      /// @return A unique pointer to an instance of X509BasicConstraintsDataDecoder
97
      static std::unique_ptr<X509BasicConstraintsDataDecoder> create(const std::string& rawData);
98
99
      /// @return True if the certificate is a CA, false otherwise
100
      bool isCA() const
101
0
      {
102
0
        return m_IsCA;
103
0
      }
104
105
      /// @return The path length constraint of the certificate
106
      int getPathLenConstraint() const
107
0
      {
108
0
        return m_PathLenConstraint;
109
0
      }
110
111
    private:
112
      X509BasicConstraintsDataDecoder(bool isCA, int pathLenConstraint)
113
          : m_IsCA(isCA), m_PathLenConstraint(pathLenConstraint)
114
0
      {}
115
      static constexpr int isCAOffset = 0;
116
      static constexpr int pathLenConstraintOffset = 1;
117
118
      bool m_IsCA = false;
119
      int m_PathLenConstraint = 0;
120
    };
121
122
    /// @class X509SubjectKeyIdentifierDataDecoder
123
    /// Represents the data decoder for the subject key identifier extension
124
    class X509SubjectKeyIdentifierDataDecoder : public X509ExtensionDataDecoder
125
    {
126
    public:
127
      /// A factory method that creates an instance of X509SubjectKeyIdentifierDataDecoder from raw data
128
      /// @param[in] rawData The raw data of the extension
129
      /// @return A unique pointer to an instance of X509SubjectKeyIdentifierDataDecoder
130
      static std::unique_ptr<X509SubjectKeyIdentifierDataDecoder> create(const std::string& rawData);
131
132
      /// @return The subject key identifier value
133
      const std::string& getKeyIdentifier() const
134
0
      {
135
0
        return m_KeyIdentifier;
136
0
      }
137
138
    private:
139
      explicit X509SubjectKeyIdentifierDataDecoder(const std::string& keyIdentifier)
140
          : m_KeyIdentifier(keyIdentifier)
141
0
      {}
142
      std::string m_KeyIdentifier;
143
    };
144
145
    /// @class X509KeyUsageDataDecoder
146
    /// Represents the data decoder for the key usage extension
147
    class X509KeyUsageDataDecoder : public X509ExtensionDataDecoder
148
    {
149
    public:
150
      /// A factory method that creates an instance of X509KeyUsageDataDecoder from raw data
151
      /// @param[in] rawData The raw data of the extension
152
      /// @return A unique pointer to an instance of X509KeyUsageDataDecoder
153
      static std::unique_ptr<X509KeyUsageDataDecoder> create(const std::string& rawData);
154
155
      /// @return The key usage value
156
      const std::string& getKeyUsage() const
157
0
      {
158
0
        return m_KeyUsage;
159
0
      }
160
161
    private:
162
      explicit X509KeyUsageDataDecoder(const std::string& keyUsage) : m_KeyUsage(keyUsage)
163
0
      {}
164
      std::string m_KeyUsage;
165
    };
166
167
    /// @class X509ExtendedKeyUsageDataDecoder
168
    /// Represents the data decoder for the extended key usage extension
169
    class X509ExtendedKeyUsageDataDecoder : public X509ExtensionDataDecoder
170
    {
171
    public:
172
      /// A factory method that creates an instance of X509ExtendedKeyUsageDataDecoder from raw data
173
      /// @param[in] rawData The raw data of the extension
174
      /// @return A unique pointer to an instance of X509ExtendedKeyUsageDataDecoder
175
      static std::unique_ptr<X509ExtendedKeyUsageDataDecoder> create(const std::string& rawData);
176
177
      /// @return The extended key usage purpose list
178
      const std::vector<Asn1ObjectIdentifier>& getExtendedKeyUsagePurposes() const
179
0
      {
180
0
        return m_ExtendedKeyUsagePurposes;
181
0
      }
182
183
    private:
184
      X509ExtendedKeyUsageDataDecoder()
185
0
      {}
186
      std::vector<Asn1ObjectIdentifier> m_ExtendedKeyUsagePurposes;
187
    };
188
  }  // namespace X509Internal
189
190
  // Forward declarations
191
  class X509Extension;
192
193
  /// @class X509ExtensionData
194
  /// A base class for X509 extension data
195
  class X509ExtensionData
196
  {
197
    friend class X509Extension;
198
199
  public:
200
0
    virtual ~X509ExtensionData() = default;
201
202
    /// A templated method that accepts a class derived from X509ExtensionData as its template argument and attempts
203
    /// to cast the current instance to that type
204
    /// @tparam X509ExtensionDataType The type to cast to
205
    /// @return A pointer to the type after casting
206
    /// @throw std::runtime_error if the cast fails
207
    template <class X509ExtensionDataType> X509ExtensionDataType* castAs()
208
    {
209
      auto castedExtension = dynamic_cast<X509ExtensionDataType*>(this);
210
      if (castedExtension == nullptr)
211
      {
212
        throw std::runtime_error("Trying to cast X509 extension data to the wrong type");
213
      }
214
      return castedExtension;
215
    }
216
  };
217
218
  /// @class X509BasicConstraintsExtension
219
  /// Represents the data for the basic constraints extension
220
  class X509BasicConstraintsExtension : public X509ExtensionData
221
  {
222
    friend class X509Extension;
223
224
  public:
225
    /// @return True if the extension is a CA, false otherwise
226
    bool isCA() const
227
0
    {
228
0
      return m_IsCA;
229
0
    }
230
231
    /// @return The path length constraint
232
    int getPathLenConstraint() const
233
0
    {
234
0
      return m_PathLenConstraint;
235
0
    }
236
237
  private:
238
    explicit X509BasicConstraintsExtension(const std::string& rawExtensionData);
239
    bool m_IsCA = false;
240
    int m_PathLenConstraint = 0;
241
  };
242
243
  /// @class X509SubjectKeyIdentifierExtension
244
  /// Represents the data for the subject key identifier extension
245
  class X509SubjectKeyIdentifierExtension : public X509ExtensionData
246
  {
247
    friend class X509Extension;
248
249
  public:
250
    /// @return The subject key identifier value
251
    std::string getKeyIdentifier() const
252
0
    {
253
0
      return m_KeyIdentifier;
254
0
    };
255
256
  private:
257
    explicit X509SubjectKeyIdentifierExtension(const std::string& rawExtensionData);
258
    std::string m_KeyIdentifier;
259
  };
260
261
  /// @class X509KeyUsageExtension
262
  /// Represents the data for the key usage extension
263
  class X509KeyUsageExtension : public X509ExtensionData
264
  {
265
    friend class X509Extension;
266
267
  public:
268
    /// @return True if the digital signature bit is set, false otherwise
269
    bool isDigitalSignature() const;
270
271
    /// @return True if the non-repudiation bit is set, false otherwise
272
    bool isNonRepudiation() const;
273
274
    /// @return True if the key encipherment bit is set, false otherwise
275
    bool isKeyEncipherment() const;
276
277
    /// @return True if the data encipherment bit is set, false otherwise
278
    bool isDataEncipherment() const;
279
280
    /// @return True if the key agreement bit is set, false otherwise
281
    bool isKeyAgreement() const;
282
283
    /// @return True if the key certificate signing bit is set, false otherwise
284
    bool isKeyCertSign() const;
285
286
    /// @return True if the CRL signing bit is set, false otherwise
287
    bool isCRLSign() const;
288
289
    /// @return True if the encipher-only bit is set, false otherwise
290
    bool isEncipherOnly() const;
291
292
    /// @return True if the decipher-only bit is set, false otherwise
293
    bool isDecipherOnly() const;
294
295
  private:
296
    explicit X509KeyUsageExtension(const std::string& rawExtensionData);
297
298
    static constexpr int digitalSignatureLocation = 0;
299
    static constexpr int nonRepudiationLocation = 1;
300
    static constexpr int keyEnciphermentLocation = 2;
301
    static constexpr int dataEnciphermentLocation = 3;
302
    static constexpr int keyAgreementLocation = 4;
303
    static constexpr int keyCertSignLocation = 5;
304
    static constexpr int crlSignLocation = 6;
305
    static constexpr int encipherOnlyLocation = 7;
306
    static constexpr int decipherOnlyLocation = 8;
307
308
    bool isBitSet(size_t location) const;
309
    std::string m_BitString;
310
  };
311
312
  /// @class X509ExtendedKeyUsageExtension
313
  /// Represents the data for the extended key usage extension
314
  class X509ExtendedKeyUsageExtension : public X509ExtensionData
315
  {
316
    friend class X509Extension;
317
318
  public:
319
    /// @return A vector of extended key usage purposes
320
    const std::vector<X509ExtendedKeyUsagePurpose>& getPurposes() const
321
0
    {
322
0
      return m_Purposes;
323
0
    }
324
325
  private:
326
    explicit X509ExtendedKeyUsageExtension(const std::string& rawExtensionData);
327
    std::vector<X509ExtendedKeyUsagePurpose> m_Purposes;
328
  };
329
}  // namespace pcpp