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