/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 |