Coverage Report

Created: 2025-08-26 07:54

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