/src/PcapPlusPlus/Packet++/header/SSLHandshake.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <utility> |
4 | | #include "SSLCommon.h" |
5 | | #include "PointerVector.h" |
6 | | #include "Asn1Codec.h" |
7 | | #include "X509Decoder.h" |
8 | | |
9 | | /// @file |
10 | | /// See detailed explanation of the TLS/SSL protocol support in PcapPlusPlus in SSLLayer.h |
11 | | |
12 | | /// @namespace pcpp |
13 | | /// @brief The main namespace for the PcapPlusPlus lib |
14 | | namespace pcpp |
15 | | { |
16 | | /// @class SSLCipherSuite |
17 | | /// Represents a cipher-suite and enables access all information about it such as all algorithms it encapsulates, |
18 | | /// its ID (as appears in the client-hello or server-hello messages), |
19 | | /// its name (e.g "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA") etc. PcapPlusPlus contains static instances of this type |
20 | | /// for all known cipher-suites and enables access to them through name or ID (see getCipherSuiteByID() and |
21 | | /// getCipherSuiteByName() ). List of cipher-suite was taken from here: |
22 | | /// http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml |
23 | | class SSLCipherSuite |
24 | | { |
25 | | public: |
26 | | /// A c'tor for this class, should never be used by a user |
27 | | /// @param[in] id Cipher-suite ID |
28 | | /// @param[in] keyExAlg Key-exchange algorithm used in this cipher-suite |
29 | | /// @param[in] authAlg Authentication algorithm used in this cipher-suite |
30 | | /// @param[in] symKeyAlg Symmetric key algorithm used in this cipher-suite |
31 | | /// @param[in] MACAlg MAC algorithm used in this cipher-suite |
32 | | /// @param[in] name String representation of this cipher-suite |
33 | | SSLCipherSuite(uint16_t id, SSLKeyExchangeAlgorithm keyExAlg, SSLAuthenticationAlgorithm authAlg, |
34 | | SSLSymetricEncryptionAlgorithm symKeyAlg, SSLHashingAlgorithm MACAlg, const char* name) |
35 | 658 | : m_Id(id), m_KeyExAlg(keyExAlg), m_AuthAlg(authAlg), m_SymKeyAlg(symKeyAlg), m_MACAlg(MACAlg), m_Name(name) |
36 | 658 | {} |
37 | | |
38 | | /// @return Cipher-suite ID |
39 | | uint16_t getID() const |
40 | 0 | { |
41 | 0 | return m_Id; |
42 | 0 | } |
43 | | |
44 | | /// @return String representation of this cipher-suite |
45 | | std::string asString() const |
46 | 0 | { |
47 | 0 | return m_Name; |
48 | 0 | } |
49 | | |
50 | | /// @return Key-exchange algorithm used in this cipher-suite |
51 | | SSLKeyExchangeAlgorithm getKeyExchangeAlg() const |
52 | 0 | { |
53 | 0 | return m_KeyExAlg; |
54 | 0 | } |
55 | | |
56 | | /// @return Authentication algorithm used in this cipher-suite |
57 | | SSLAuthenticationAlgorithm getAuthAlg() const |
58 | 0 | { |
59 | 0 | return m_AuthAlg; |
60 | 0 | } |
61 | | |
62 | | /// @return Symmetric key algorithm used in this cipher-suite |
63 | | SSLSymetricEncryptionAlgorithm getSymKeyAlg() const |
64 | 0 | { |
65 | 0 | return m_SymKeyAlg; |
66 | 0 | } |
67 | | |
68 | | /// @return MAC algorithm used in this cipher-suite |
69 | | SSLHashingAlgorithm getMACAlg() const |
70 | 0 | { |
71 | 0 | return m_MACAlg; |
72 | 0 | } |
73 | | |
74 | | /// A static method that returns a cipher-suite instance by ID |
75 | | /// @param[in] id Cipher-suite ID |
76 | | /// @return A cipher-suite instance matching this ID or nullptr if ID not found |
77 | | static SSLCipherSuite* getCipherSuiteByID(uint16_t id); |
78 | | |
79 | | /// A static method that returns a cipher-suite instance by name |
80 | | /// @param[in] name Cipher-suite name (e.g "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA") |
81 | | /// @return A cipher-suite instance matching this name or nullptr if name not found |
82 | | static SSLCipherSuite* getCipherSuiteByName(std::string name); |
83 | | |
84 | | private: |
85 | | uint16_t m_Id; |
86 | | SSLKeyExchangeAlgorithm m_KeyExAlg; |
87 | | SSLAuthenticationAlgorithm m_AuthAlg; |
88 | | SSLSymetricEncryptionAlgorithm m_SymKeyAlg; |
89 | | SSLHashingAlgorithm m_MACAlg; |
90 | | std::string m_Name; |
91 | | }; |
92 | | |
93 | | /// @class SSLExtension |
94 | | /// Represents a SSL/TLS extension. This is a base class that can represent any type of extension. Inherited classes |
95 | | /// may contain parsing logic for specific extensions. This class provides capabilities such as getting the |
96 | | /// extension type, length and viewing the extension data as raw (byte array) |
97 | | class SSLExtension |
98 | | { |
99 | | public: |
100 | | /// C'tor for this class |
101 | | /// @param[in] data The raw data for the extension |
102 | | explicit SSLExtension(uint8_t* data); |
103 | | |
104 | 276k | virtual ~SSLExtension() = default; |
105 | | |
106 | | /// @return The type of the extension as enum |
107 | | SSLExtensionType getType() const; |
108 | | |
109 | | /// @return The type of the extension as a numeric value |
110 | | uint16_t getTypeAsInt() const; |
111 | | |
112 | | /// @return The length of the extension data in bytes (not including the type and length fields) |
113 | | uint16_t getLength() const; |
114 | | |
115 | | /// @return The total length of the extension, including type and length fields and the extension data field |
116 | | uint16_t getTotalLength() const; |
117 | | |
118 | | /// @return A pointer to the raw data of the extension |
119 | | uint8_t* getData() const; |
120 | | |
121 | | protected: |
122 | | /// @struct SSLExtensionStruct |
123 | | /// Represents the common fields of the extension |
124 | | struct SSLExtensionStruct |
125 | | { |
126 | | /// Extension type |
127 | | uint16_t extensionType; |
128 | | /// Extension length |
129 | | uint16_t extensionDataLength; |
130 | | /// Extension data as raw (byte array) |
131 | | uint8_t extensionData[]; |
132 | | }; |
133 | | |
134 | | uint8_t* m_RawData; |
135 | | |
136 | | SSLExtensionStruct* getExtensionStruct() const |
137 | 656k | { |
138 | 656k | return reinterpret_cast<SSLExtensionStruct*>(m_RawData); |
139 | 656k | } |
140 | | }; |
141 | | |
142 | | /// @class SSLServerNameIndicationExtension |
143 | | /// Represents SSL/TLS Server Name Indication extension. Inherits from SSLExtension and add parsing of the hostname |
144 | | /// written in the extension data |
145 | | class SSLServerNameIndicationExtension : public SSLExtension |
146 | | { |
147 | | public: |
148 | | /// C'tor for this class |
149 | | /// @param[in] data The raw data for the extension |
150 | 114k | explicit SSLServerNameIndicationExtension(uint8_t* data) : SSLExtension(data) |
151 | 114k | {} |
152 | | |
153 | | /// @return The hostname written in the extension data |
154 | | std::string getHostName() const; |
155 | | }; |
156 | | |
157 | | /// @class SSLSupportedVersionsExtension |
158 | | /// Represents TLS Supported Versions extension. Inherits from SSLExtension and adds parsing of the list |
159 | | /// of supported versions mentioned in the extension data |
160 | | class SSLSupportedVersionsExtension : public SSLExtension |
161 | | { |
162 | | public: |
163 | | /// C'tor for this class |
164 | | /// @param[in] data The raw data for the extension |
165 | 4.21k | explicit SSLSupportedVersionsExtension(uint8_t* data) : SSLExtension(data) |
166 | 4.21k | {} |
167 | | |
168 | | /// @return The list of supported versions mentioned in the extension data |
169 | | std::vector<SSLVersion> getSupportedVersions() const; |
170 | | }; |
171 | | |
172 | | /// @class TLSSupportedGroupsExtension |
173 | | /// Represents TLS Supported Groups extension. Inherits from SSLExtension and adds parsing of the |
174 | | /// supported groups (Elliptic Curves) mentioned in the extension data |
175 | | class TLSSupportedGroupsExtension : public SSLExtension |
176 | | { |
177 | | public: |
178 | | /// C'tor for this class |
179 | | /// @param[in] data The raw data for the extension |
180 | 11.4k | explicit TLSSupportedGroupsExtension(uint8_t* data) : SSLExtension(data) |
181 | 11.4k | {} |
182 | | |
183 | | /// @return A vector of the supported groups (also known as "Elliptic Curves") |
184 | | std::vector<uint16_t> getSupportedGroups() const; |
185 | | }; |
186 | | |
187 | | /// @class TLSECPointFormatExtension |
188 | | /// Represents TLS EC (Elliptic Curves) Point Format extension. Inherits from SSLExtension and adds parsing of the |
189 | | /// EC point formats mentioned in the extension data |
190 | | class TLSECPointFormatExtension : public SSLExtension |
191 | | { |
192 | | public: |
193 | | /// C'tor for this class |
194 | | /// @param[in] data The raw data for the extension |
195 | 13.0k | explicit TLSECPointFormatExtension(uint8_t* data) : SSLExtension(data) |
196 | 13.0k | {} |
197 | | |
198 | | /// @return A vector of the elliptic curves point formats |
199 | | std::vector<uint8_t> getECPointFormatList() const; |
200 | | }; |
201 | | |
202 | | /// @class SSLx509Certificate |
203 | | /// Represents a x509v3 certificate. the SSLCertificateMessage class returns an instance of this class as the |
204 | | /// certificate. Currently this class doesn't do much as it doesn't parse the certificate. It only acts as container |
205 | | /// to the raw data and returns general info as data as raw, length, etc. In the future I may add full parsing of |
206 | | /// the certificate |
207 | | class SSLx509Certificate |
208 | | { |
209 | | public: |
210 | | /// C'tor for this class |
211 | | /// @param[in] data The raw data of the certificate |
212 | | /// @param[in] dataLen The length in bytes of the raw data |
213 | | /// @param[in] allDataExists Certificate messages usually spread on more than 1 packet. So a certificate is |
214 | | /// likely to split between 2 packets or more. This field indicates whether the raw data contains all |
215 | | /// certificate data of just a part of it |
216 | | SSLx509Certificate(uint8_t* data, size_t dataLen, bool allDataExists) |
217 | 22.4k | : m_Data(data), m_DataLen(dataLen), m_AllDataExists(allDataExists) |
218 | 22.4k | {} |
219 | | |
220 | | /// @return A pointer to the raw data |
221 | | uint8_t* getData() const |
222 | 0 | { |
223 | 0 | return m_Data; |
224 | 0 | } |
225 | | |
226 | | /// @return Raw data length |
227 | | size_t getDataLength() const |
228 | 0 | { |
229 | 0 | return m_DataLen; |
230 | 0 | } |
231 | | |
232 | | /// @return The root ASN.1 record of the certificate data. All the certificate data will be under this |
233 | | /// record. If the certificate data isn't complete, this method will return nullptr. If the Root ASN.1 record |
234 | | /// is malformed, an exception is thrown |
235 | | Asn1SequenceRecord* getRootAsn1Record(); |
236 | | |
237 | | /// Parse the certificate data as X509 certificate. If the certificate data isn't complete, this method will |
238 | | /// return nullptr |
239 | | /// @return A unique pointer to the parsed X509 certificate |
240 | | std::unique_ptr<X509Certificate> getX509Certificate(); |
241 | | |
242 | | /// Certificate messages usually spread on more than 1 packet. So a certificate is likely to split between 2 |
243 | | /// packets or more. This method provides an indication whether all certificate data exists or only part of it |
244 | | /// @return True if this data contains all certificate data, false otherwise |
245 | | bool allDataExists() const |
246 | 0 | { |
247 | 0 | return m_AllDataExists; |
248 | 0 | } |
249 | | |
250 | | private: |
251 | | std::unique_ptr<Asn1Record> m_Asn1Record; |
252 | | uint8_t* m_Data; |
253 | | size_t m_DataLen; |
254 | | bool m_AllDataExists; |
255 | | }; |
256 | | |
257 | | class SSLHandshakeLayer; |
258 | | |
259 | | /// @class SSLHandshakeMessage |
260 | | /// A base class for SSL/TLS handshake messages. This is an abstract class and cannot be instantiated. SSL/TLS |
261 | | /// handshake messages are contained in SSLHandshakeLayer, meaning a SSLHandshakeLayer instance can contain one or |
262 | | /// more SSLHandshakeMessage instances. For example: one SSLHandshakeLayer may contain a server-hello, certificate, |
263 | | /// server-key-exchange, and server-hello-done messages (although it's not such a common case, most handshake layers |
264 | | /// contain 1 handshake message only) |
265 | | class SSLHandshakeMessage |
266 | | { |
267 | | public: |
268 | 139k | virtual ~SSLHandshakeMessage() = default; |
269 | | |
270 | | /// A factory method for creating instances of handshake messages from raw data |
271 | | /// @param[in] data The raw data containing 1 handshake message |
272 | | /// @param[in] dataLen Raw data length in bytes |
273 | | /// @param[in] container A pointer to the SSLHandshakeLayer instance which will contain the created message. |
274 | | /// This parameter is required because the handshake message includes a pointer to its container |
275 | | static SSLHandshakeMessage* createHandshakeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); |
276 | | |
277 | | /// @return The handshake message type |
278 | | virtual SSLHandshakeType getHandshakeType() const; |
279 | | |
280 | | /// @return The handshake message length in bytes. Notice that sometimes the handshake message is divided |
281 | | /// between several packets, in this case this method will return the length of part of the message in the |
282 | | /// current packet |
283 | | virtual size_t getMessageLength() const; |
284 | | |
285 | | /// @return True if current packet contains the entire message or false otherwise. This method is important |
286 | | /// because sometimes handshake messages are divided in consequent packets (happens a lot in certificate |
287 | | /// messages which usually contain several KB of data which is larger than standard packet size, so the message |
288 | | /// is divided between several packets) |
289 | | virtual bool isMessageComplete() const; |
290 | | |
291 | | /// @return A pointer to the SSLHandshakeLayer instance containing this message |
292 | | SSLHandshakeLayer* getContainingLayer() const |
293 | 0 | { |
294 | 0 | return m_Container; |
295 | 0 | } |
296 | | |
297 | | /// @return A string representation of the message type (e.g "Client Hello message") |
298 | | virtual std::string toString() const = 0; |
299 | | |
300 | | protected: |
301 | | SSLHandshakeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); |
302 | | |
303 | | uint8_t* m_Data; |
304 | | size_t m_DataLen; |
305 | | SSLHandshakeLayer* m_Container; |
306 | | }; |
307 | | |
308 | | /// @class SSLClientHelloMessage |
309 | | /// Represents a client-hello message (type 1). Inherits from SSLHandshakeMessage and adds parsing of all fields |
310 | | /// of this message including the message extensions, cipher-suite list, etc. |
311 | | class SSLClientHelloMessage : public SSLHandshakeMessage |
312 | | { |
313 | | public: |
314 | | /// @struct ClientHelloTLSFingerprint |
315 | | /// A struct that contains all the elements needed for creating a Client Hello TLS fingerprinting: |
316 | | /// TLS version, a list of Cipher Suite IDs, a list of Extensions IDs, a list of support groups and a list of |
317 | | /// EC point formats. |
318 | | /// You can read more about this in SSLClientHelloMessage#generateTLSFingerprint(). |
319 | | /// This struct contains methods to extract the TLS fingerprint itself: toString() and toMD5() |
320 | | struct ClientHelloTLSFingerprint |
321 | | { |
322 | | /// TLS version |
323 | | uint16_t tlsVersion; |
324 | | /// A list of Cipher Suite IDs |
325 | | std::vector<uint16_t> cipherSuites; |
326 | | /// A list of extension IDs |
327 | | std::vector<uint16_t> extensions; |
328 | | /// A list of Suppotred Groups taken from the "supported groups" TLS extension (if exist in the message) |
329 | | std::vector<uint16_t> supportedGroups; |
330 | | /// A list of EC point formats taken from the "EC point formats" TLS extension (if exist in the message) |
331 | | std::vector<uint8_t> ecPointFormats; |
332 | | |
333 | | /// @return A string representing the TLS fingerprint, for example: |
334 | | /// <b>771,4866-4867-4865-255,0-11-10-35-22-23-13-43-45-51,29-23-30-25-24,0-1-2</b> |
335 | | /// |
336 | | /// This string has the following format: |
337 | | /// <b>TLSVersion,CipherSuiteIDs,ExtensionIDs,SupportedGroups,ECPointFormats</b> |
338 | | /// |
339 | | /// The extension IDs, supported groups and EC point formats are each separated by a "-". |
340 | | /// If the message doesn't include the "supported groups" or "EC point formats" extensions, they will be |
341 | | /// replaced by an empty string for example: <b>771,4866-4867-4865-255,0-11-10-35-22-23-13-43-45-51,,</b> |
342 | | std::string toString(); |
343 | | |
344 | | /// @return An MD5 hash of the string generated by toString() |
345 | | std::string toMD5(); |
346 | | |
347 | | /// @return A pair of the string and MD5 hash (string is first, MD5 is second). |
348 | | /// If you want both this method is more efficient than calling toString() and toMD5() separately |
349 | | std::pair<std::string, std::string> toStringAndMD5(); |
350 | | }; |
351 | | |
352 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and shouldn't |
353 | | /// be used by a user |
354 | | /// @param[in] data The message as raw data |
355 | | /// @param[in] dataLen Message raw data length in bytes |
356 | | /// @param[in] container The SSL handshake layer which shall contain this message |
357 | | SSLClientHelloMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); |
358 | | |
359 | 24.0k | ~SSLClientHelloMessage() override = default; |
360 | | |
361 | | /// @return A struct containing common fields for client-hello and server-hello messages. Notice this points |
362 | | /// directly to the data, so every change will change the actual packet data |
363 | | ssl_tls_client_server_hello* getClientHelloHeader() const |
364 | 8.91k | { |
365 | 8.91k | return reinterpret_cast<ssl_tls_client_server_hello*>(m_Data); |
366 | 8.91k | } |
367 | | |
368 | | /// @return Handshake SSL/TLS version (notice it may be different than SSLLayer#getRecordVersion(). Each |
369 | | /// client-hello or server-hello message has both record version and handshake version and they may differ from |
370 | | /// one another) |
371 | | SSLVersion getHandshakeVersion() const; |
372 | | |
373 | | /// @return Session ID length in bytes. If server-hello message doesn't include session ID 0 will be returned |
374 | | uint8_t getSessionIDLength() const; |
375 | | |
376 | | /// @return Session ID as byte array. If server-hello message doesn't include session ID nullptr will be |
377 | | /// returned |
378 | | uint8_t* getSessionID() const; |
379 | | |
380 | | /// @return The number of cipher-suites included in this message |
381 | | int getCipherSuiteCount() const; |
382 | | |
383 | | /// Get a pointer to a cipher-suite by index. The cipher-suites are numbered according to their order of |
384 | | /// appearance in the message. If index is out of bounds (less than 0 or larger than total amount of cipher |
385 | | /// suites) nullptr will be returned. nullptr will also be returned if the cipher-suite ID is unknown. If you |
386 | | /// still want to get the cipher-suite ID you can use getCipherSuiteID() |
387 | | /// @param[in] index The index of the cipher-suite to return |
388 | | /// @return The pointer to the cipher-suite object or nullptr if index is out of bounds |
389 | | SSLCipherSuite* getCipherSuite(int index) const; |
390 | | |
391 | | /// Get the cipher-suite ID by index. This method just parses the ID from the client-hello message and returns |
392 | | /// it. To get more information on the cipher-suite you can use the getCipherSuite() method |
393 | | /// @param[in] index The index of the cipher-suite to return |
394 | | /// @param[out] isValid Set to "true" if parsing succeeded and the return value is valid or "false" if: |
395 | | /// (1) the index is out-of-bounds (less than 0 or larger than total amount of cipher suites) or (2) the parsing |
396 | | /// failed. If the value is "false" the return value can be ignored |
397 | | /// @return The cipher-suite ID if "isValid" is set to "true". If "isValid" is set to "false" the return value |
398 | | /// can be ignored |
399 | | uint16_t getCipherSuiteID(int index, bool& isValid) const; |
400 | | |
401 | | /// @return The value of the compression method byte |
402 | | uint8_t getCompressionMethodsValue() const; |
403 | | |
404 | | /// @return The number of extensions in this message |
405 | | int getExtensionCount() const; |
406 | | |
407 | | /// @return The size (in bytes) of all extensions data in this message. Extracted from the "extensions length" |
408 | | /// field |
409 | | uint16_t getExtensionsLength() const; |
410 | | |
411 | | /// Get a pointer to an extension by index. The extensions are numbered according to their order of appearance |
412 | | /// in the message. If index is out of bounds (less than 0 or larger than total amount of extensions) nullptr |
413 | | /// will be returned |
414 | | /// @param[in] index The index of the extension to return |
415 | | /// @return The pointer to the extension or nullptr if index is out of bounds |
416 | | SSLExtension* getExtension(int index) const; |
417 | | |
418 | | /// Get a pointer to an extension by numeric type field. Every extension has a 2-byte numeric value representing |
419 | | /// its type (for example: renegotiation info extension type is 0x1ff). This method gets the type and returns a |
420 | | /// pointer to the extension object |
421 | | /// @param[in] type The 2-byte numeric type of the extension |
422 | | /// @return A pointer to the extension object of nullptr if this type doesn't exist in this message |
423 | | SSLExtension* getExtensionOfType(uint16_t type) const; |
424 | | |
425 | | /// Get a pointer to an extension by its enum type |
426 | | /// @param[in] type The type of extension to return |
427 | | /// @return A pointer to the extension object or nullptr if this type doesn't exist in this message |
428 | | SSLExtension* getExtensionOfType(SSLExtensionType type) const; |
429 | | |
430 | | /// Get a pointer to an extension by its class type. This is a templated method that is used with the type of |
431 | | /// the requested extension and returns the first extension instance of this type |
432 | | /// @return A pointer to the extension object or nullptr if this extension type doesn't exist in this message |
433 | | template <class TExtension> TExtension* getExtensionOfType() const; |
434 | | |
435 | | /// TLS fingerprinting is a way to identify client applications using the details in the TLS Client Hello |
436 | | /// packet. It was initially introduced by Lee Brotherston in his 2015 research: |
437 | | /// <https://blog.squarelemon.com/tls-fingerprinting/> This implementation of TLS fingerprint is a C++ version |
438 | | /// of Salesforce's JA3 open source project (originally written in Python and Zeek): |
439 | | /// <https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967> |
440 | | /// @return A SSLClientHelloMessage#ClientHelloTLSFingerprint struct that contains all the elements needed for |
441 | | /// creating a TLS fingerprint out of this Client Hello message. This struct has also methods to extract the TLS |
442 | | /// fingerprint itself in a string or MD5 formats |
443 | | ClientHelloTLSFingerprint generateTLSFingerprint() const; |
444 | | |
445 | | // implement abstract methods |
446 | | |
447 | | std::string toString() const override; |
448 | | |
449 | | private: |
450 | | PointerVector<SSLExtension> m_ExtensionList; |
451 | | }; |
452 | | |
453 | | /// @class SSLServerHelloMessage |
454 | | /// Represents SSL/TLS server-hello message (type 2). Inherits from SSLHandshakeMessage and adds parsing of all |
455 | | /// fields of this message including the message extensions, cipher-suite, etc. |
456 | | class SSLServerHelloMessage : public SSLHandshakeMessage |
457 | | { |
458 | | public: |
459 | | /// @struct ServerHelloTLSFingerprint |
460 | | /// A struct that contains all the elements needed for creating a Server Hello TLS fingerprinting: |
461 | | /// TLS version, Cipher Suite ID, and a list of Extensions IDs. |
462 | | /// You can read more about this in SSLServerHelloMessage#generateTLSFingerprint(). |
463 | | /// This struct contains methods to extract the TLS fingerprint itself: toString() and toMD5() |
464 | | struct ServerHelloTLSFingerprint |
465 | | { |
466 | | /// TLS version |
467 | | uint16_t tlsVersion; |
468 | | /// Cipher Suite ID |
469 | | uint16_t cipherSuite; |
470 | | /// A list of extension IDs |
471 | | std::vector<uint16_t> extensions; |
472 | | |
473 | | /// @return A string representing the TLS fingerprint, for example: <b>771,49195,65281-16-11</b> |
474 | | /// |
475 | | /// This string has the following format: <b>TLSVersion,Cipher,Extensions</b> |
476 | | /// |
477 | | /// The extension ID are separated with a "-" |
478 | | std::string toString(); |
479 | | |
480 | | /// @return An MD5 hash of the string generated by toString() |
481 | | std::string toMD5(); |
482 | | |
483 | | /// @return A pair of the string and MD5 hash (string is first, MD5 is second). |
484 | | /// If you want both this method is more efficient than calling toString() and toMD5() separately |
485 | | std::pair<std::string, std::string> toStringAndMD5(); |
486 | | }; |
487 | | |
488 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and shouldn't |
489 | | /// be used by a user |
490 | | /// @param[in] data The message as raw data |
491 | | /// @param[in] dataLen Message raw data length in bytes |
492 | | /// @param[in] container The SSL handshake layer which shall contain this message |
493 | | SSLServerHelloMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); |
494 | | |
495 | 22.4k | ~SSLServerHelloMessage() override = default; |
496 | | |
497 | | /// @return A struct containing common fields for client-hello and server-hello messages. Notice this points |
498 | | /// directly to the data, so every change will change the actual packet data |
499 | | ssl_tls_client_server_hello* getServerHelloHeader() const |
500 | 6.51k | { |
501 | 6.51k | return reinterpret_cast<ssl_tls_client_server_hello*>(m_Data); |
502 | 6.51k | } |
503 | | |
504 | | /// @return Handshake SSL/TLS version (notice it may be different than SSLLayer#getRecordVersion(). Each |
505 | | /// client-hello or server-hello message has both record version and handshake version and they may differ from |
506 | | /// one another). |
507 | | /// |
508 | | /// <b>NOTE:</b> for TLS 1.3 the handshake version written in ssl_tls_client_server_hello::handshakeVersion is |
509 | | /// still TLS 1.2, so a special check is made here see if a SupportedVersions extension exists and if so extract |
510 | | /// the version from it. This is the most straight-forward way to detect TLS 1.3. |
511 | | SSLVersion getHandshakeVersion() const; |
512 | | |
513 | | /// @return Session ID length in bytes. If server-hello message doesn't include session ID 0 will be returned |
514 | | uint8_t getSessionIDLength() const; |
515 | | |
516 | | /// @return Session ID as byte array. If server-hello message doesn't include session ID nullptr will be |
517 | | /// returned |
518 | | uint8_t* getSessionID() const; |
519 | | |
520 | | /// @return A pointer to the cipher suite encapsulated in this message (server-hello message contains one |
521 | | /// cipher-suite, the one that will be used to for encryption between client and server). May return nullptr |
522 | | /// if the parsing of the message failed or the cipher-suite ID is unknown. If you still want to get the |
523 | | /// cipher-suite ID you can use the getCipherSuiteID() method |
524 | | SSLCipherSuite* getCipherSuite() const; |
525 | | |
526 | | /// Get the cipher-suite ID. This method just parses the ID from the server-hello message and returns it. |
527 | | /// To get more information on the cipher-suite you can use the getCipherSuite() method |
528 | | /// @param[out] isValid Set to "true" if parsing succeeded and the return value is valid or "false" otherwise. |
529 | | /// If the value is "false" the return value can be ignored |
530 | | /// @return The cipher-suite ID if "isValid" is set to "true". If "isValid" is set to "false" the return value |
531 | | /// can be ignored |
532 | | uint16_t getCipherSuiteID(bool& isValid) const; |
533 | | |
534 | | /// @return The value of the compression method byte |
535 | | uint8_t getCompressionMethodsValue() const; |
536 | | |
537 | | /// @return The number of extensions in this message |
538 | | int getExtensionCount() const; |
539 | | |
540 | | /// @return The size (in bytes) of all extensions data in this message. Extracted from the "extensions length" |
541 | | /// field |
542 | | uint16_t getExtensionsLength() const; |
543 | | |
544 | | /// Get a pointer to an extension by index. The extensions are numbered according to their order of appearance |
545 | | /// in the message. If index is out of bounds (less than 0 or larger than total amount of extensions) nullptr |
546 | | /// will be returned |
547 | | /// @param[in] index The index of the extension to return |
548 | | /// @return The pointer to the extension or nullptr if index is out of bounds |
549 | | SSLExtension* getExtension(int index) const; |
550 | | |
551 | | /// Get a pointer to an extension by numeric type field. Every extension has a 2-byte numeric value representing |
552 | | /// its type (for example: renegotiation info extension type is 0x1ff). This method gets the type and returns a |
553 | | /// pointer to the extension object |
554 | | /// @param[in] type The 2-byte numeric type of the extension |
555 | | /// @return A pointer to the extension object of nullptr if this type doesn't exist in this message |
556 | | SSLExtension* getExtensionOfType(uint16_t type) const; |
557 | | |
558 | | /// Get a pointer to an extension by its enum type |
559 | | /// @param[in] type The type of extension to return |
560 | | /// @return A pointer to the extension object or nullptr if this type doesn't exist in this message |
561 | | SSLExtension* getExtensionOfType(SSLExtensionType type) const; |
562 | | |
563 | | /// Get a pointer to an extension by its class type. This is a templated method that is used with the type of |
564 | | /// the requested extension and returns the first extension instance of this type |
565 | | /// @return A pointer to the extension object or nullptr if this extension type doesn't exist in this message |
566 | | template <class TExtension> TExtension* getExtensionOfType() const; |
567 | | |
568 | | /// ServerHello TLS fingerprinting is a way to fingerprint TLS Server Hello messages. In conjunction with |
569 | | /// ClientHello TLS fingerprinting it can assist in identifying specific client-server communication (for |
570 | | /// example: a malware connecting to its backend server). |
571 | | /// ServerHello TLS fingerprinting was introduced in Salesforce's JA3S open source project: |
572 | | /// <https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967> |
573 | | /// This implementation is a C++ version of Salesforce's JAS3 (originally written in Python and Zeek) |
574 | | /// @return A SSLServerHelloMessage#ServerHelloTLSFingerprint struct that contains all the elements needed for |
575 | | /// creating a TLS fingerprint out of this Server Hello message. This struct has also methods to extract the TLS |
576 | | /// fingerprint itself in a string or MD5 formats |
577 | | ServerHelloTLSFingerprint generateTLSFingerprint() const; |
578 | | |
579 | | // implement abstract methods |
580 | | |
581 | | std::string toString() const override; |
582 | | |
583 | | private: |
584 | | PointerVector<SSLExtension> m_ExtensionList; |
585 | | }; |
586 | | |
587 | | /// @class SSLCertificateMessage |
588 | | /// Represents SSL/TLS certificate message (type 11). Inherits from SSLHandshakeMessage and adds parsing |
589 | | /// functionality such as extracting the certificates data. Notice that in most cases this message is spread over |
590 | | /// more than 1 packet as its size is too big for a single packet. So SSLCertificateMessage instance will be created |
591 | | /// just for the first part of the message - the one encapsulated in the first packet. Other parts (encapsulated in |
592 | | /// the following packets) won't be recognized as SSLCertificateMessage messages |
593 | | class SSLCertificateMessage : public SSLHandshakeMessage |
594 | | { |
595 | | public: |
596 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
597 | | /// used by a user |
598 | | /// @param[in] data The message as raw data |
599 | | /// @param[in] dataLen Message raw data length in bytes |
600 | | /// @param[in] container The SSL handshake layer which shall contain this message |
601 | | SSLCertificateMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); |
602 | | |
603 | 8.30k | ~SSLCertificateMessage() override = default; |
604 | | |
605 | | /// @return The number of certificates encapsulated in this message (as written in the 'length' field of the |
606 | | /// message). Notice that because the message may spread over several packets, not all certificates will |
607 | | /// necessarily be in this packet. So, for example, there may be a case where this method return 3 (message |
608 | | /// contains 3 certificates) but this message actually contains only 1 certificate as the other 2 are spread |
609 | | /// over the other packets |
610 | | int getNumOfCertificates() const; |
611 | | |
612 | | /// Get a certificate by index |
613 | | /// @param[in] index The index of the certificate to retrieve |
614 | | /// @return A pointer to the certificate object. Notice that if index < 0 or index > num of certificates |
615 | | /// encapsulated in current packet a nullptr value will be returned |
616 | | SSLx509Certificate* getCertificate(int index) const; |
617 | | |
618 | | // implement abstract methods |
619 | | |
620 | | std::string toString() const override; |
621 | | |
622 | | private: |
623 | | PointerVector<SSLx509Certificate> m_CertificateList; |
624 | | }; |
625 | | |
626 | | /// @class SSLHelloRequestMessage |
627 | | /// Represents SSL/TLS hello-request message (type 0). This message has no additional payload except for the common |
628 | | /// payload described in SSLHandshakeMessage |
629 | | class SSLHelloRequestMessage : public SSLHandshakeMessage |
630 | | { |
631 | | public: |
632 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
633 | | /// used by a user |
634 | | /// @param[in] data The message as raw data |
635 | | /// @param[in] dataLen Message raw data length in bytes |
636 | | /// @param[in] container The SSL handshake layer which shall contain this message |
637 | | SSLHelloRequestMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) |
638 | 25.1k | : SSLHandshakeMessage(data, dataLen, container) |
639 | 25.1k | {} |
640 | | |
641 | | ~SSLHelloRequestMessage() override = default; |
642 | | |
643 | | // implement abstract methods |
644 | | |
645 | | std::string toString() const override; |
646 | | }; |
647 | | |
648 | | /// @class SSLServerKeyExchangeMessage |
649 | | /// Represents SSL/TLS server-key-exchange message (type 12). Inherits from SSLHandshakeMessage and adds parsing |
650 | | /// functionality such as getting the server key exchange params as raw data (parsing of this may be added in the |
651 | | /// future) |
652 | | class SSLServerKeyExchangeMessage : public SSLHandshakeMessage |
653 | | { |
654 | | public: |
655 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
656 | | /// used by a user |
657 | | /// @param[in] data The message as raw data |
658 | | /// @param[in] dataLen Message raw data length in bytes |
659 | | /// @param[in] container The SSL handshake layer which shall contain this message |
660 | | SSLServerKeyExchangeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) |
661 | 4.34k | : SSLHandshakeMessage(data, dataLen, container) |
662 | 4.34k | {} |
663 | | |
664 | | ~SSLServerKeyExchangeMessage() override = default; |
665 | | |
666 | | /// @return A pointer to the raw data of the server key exchange params. Currently this data can only returned |
667 | | /// as raw, parsing may be added in the future. Notice that if the message is spread over more than 1 packet in |
668 | | /// a way params doesn't exist in the first packet, nullptr will be returned |
669 | | uint8_t* getServerKeyExchangeParams() const; |
670 | | |
671 | | /// @return The size of the params field. Notice that if the message is spread over more than 1 packet in a way |
672 | | /// the ssl_tls_handshake_layer cannot be parsed from the packet, 0 will be returned. Also, if only part of the |
673 | | /// params exist in current packet (and the rest are on consequent packets), the size that will be returned is |
674 | | /// the size of the part that exists in the current packet (and not total size of params) |
675 | | size_t getServerKeyExchangeParamsLength() const; |
676 | | |
677 | | // implement abstract methods |
678 | | |
679 | | std::string toString() const override; |
680 | | }; |
681 | | |
682 | | /// @class SSLClientKeyExchangeMessage |
683 | | /// Represents SSL/TLS client-key-exchange message (type 16). Inherits from SSLHandshakeMessage and adds parsing |
684 | | /// functionality such as getting the server key exchange params as raw data (parsing of this may be added in the |
685 | | /// future) |
686 | | class SSLClientKeyExchangeMessage : public SSLHandshakeMessage |
687 | | { |
688 | | public: |
689 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
690 | | /// used by a user |
691 | | /// @param[in] data The message as raw data |
692 | | /// @param[in] dataLen Message raw data length in bytes |
693 | | /// @param[in] container The SSL handshake layer which shall contain this message |
694 | | SSLClientKeyExchangeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) |
695 | 2.11k | : SSLHandshakeMessage(data, dataLen, container) |
696 | 2.11k | {} |
697 | | |
698 | | ~SSLClientKeyExchangeMessage() override = default; |
699 | | |
700 | | /// @return A pointer to the raw data of the server key exchange params. Currently this data can only be |
701 | | /// returned as raw, parsing may be added in the future. Notice that if the message is spread over more than 1 |
702 | | /// packet in a way params doesn't exist in the first packet, nullptr will be returned |
703 | | uint8_t* getClientKeyExchangeParams() const; |
704 | | |
705 | | /// @return The size of the params field. Notice that if the message is spread over more than 1 packet in a way |
706 | | /// the ssl_tls_handshake_layer cannot be parsed from the packet, 0 will be returned. Also, if only part of the |
707 | | /// params exist in current packet (and the rest are on consequent packets), the size that will be returned is |
708 | | /// the size of the part that exists in the current packet (and not the total size of params) |
709 | | size_t getClientKeyExchangeParamsLength() const; |
710 | | |
711 | | // implement abstract methods |
712 | | |
713 | | std::string toString() const override; |
714 | | }; |
715 | | |
716 | | /// @class SSLCertificateRequestMessage |
717 | | /// Represents SSL/TLS certificate-request message (type 13). Inherits from SSLHandshakeMessage and adds parsing |
718 | | /// functionality such as retrieving client certificate types and authority data |
719 | | class SSLCertificateRequestMessage : public SSLHandshakeMessage |
720 | | { |
721 | | public: |
722 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
723 | | /// used by a user |
724 | | /// @param[in] data The message as raw data |
725 | | /// @param[in] dataLen Message raw data length in bytes |
726 | | /// @param[in] container The SSL handshake layer which shall contain this message |
727 | | SSLCertificateRequestMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); |
728 | | |
729 | 13.4k | ~SSLCertificateRequestMessage() override = default; |
730 | | |
731 | | /// @return A reference to a vector containing all client certificate types exist in this message |
732 | | std::vector<SSLClientCertificateType>& getCertificateTypes(); |
733 | | |
734 | | /// @return A pointer to the certificate authority data as raw data (byte array). Parsing of this data may be |
735 | | /// added in the future. Notice that if this message is spread over several packets in a way none of the |
736 | | /// certificate authority data exists in this packet, nullptr will be returned |
737 | | uint8_t* getCertificateAuthorityData() const; |
738 | | |
739 | | /// @return The length of certificate authority data returned by getCertificateAuthorityData(). Notice that if |
740 | | /// this message is spread over several packets in a way none of certificate authority data exists in the |
741 | | /// current packet, 0 will be returned. Also, if some of the data exists in the consequent packets, the length |
742 | | /// that will be returned is the length of data exists in the current packet only (and not the total length) |
743 | | size_t getCertificateAuthorityLength() const; |
744 | | |
745 | | // implement abstract methods |
746 | | |
747 | | std::string toString() const override; |
748 | | |
749 | | private: |
750 | | std::vector<SSLClientCertificateType> m_ClientCertificateTypes; |
751 | | }; |
752 | | |
753 | | /// @class SSLServerHelloDoneMessage |
754 | | /// Represents SSL/TLS server-hello-done message (type 14). This message has no additional payload except for the |
755 | | /// common payload described in SSLHandshakeMessage |
756 | | class SSLServerHelloDoneMessage : public SSLHandshakeMessage |
757 | | { |
758 | | public: |
759 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
760 | | /// used by a user |
761 | | /// @param[in] data The message as raw data |
762 | | /// @param[in] dataLen Message raw data length in bytes |
763 | | /// @param[in] container The SSL handshake layer which shall contain this message |
764 | | SSLServerHelloDoneMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) |
765 | 1.31k | : SSLHandshakeMessage(data, dataLen, container) |
766 | 1.31k | {} |
767 | | |
768 | | ~SSLServerHelloDoneMessage() override = default; |
769 | | |
770 | | // implement abstract methods |
771 | | |
772 | | std::string toString() const override; |
773 | | }; |
774 | | |
775 | | /// @class SSLCertificateVerifyMessage |
776 | | /// Represents SSL/TLS certificate-verify message (type 15). Inherits from SSLHandshakeMessage and adds parsing |
777 | | /// functionality such as retrieving signed hash data as raw data (parsing may be added in the future) |
778 | | /// @todo This message type wasn't tested in unit-tests |
779 | | class SSLCertificateVerifyMessage : public SSLHandshakeMessage |
780 | | { |
781 | | public: |
782 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
783 | | /// used by a user |
784 | | /// @param[in] data The message as raw data |
785 | | /// @param[in] dataLen Message raw data length in bytes |
786 | | /// @param[in] container The SSL handshake layer which shall contain this message |
787 | | SSLCertificateVerifyMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) |
788 | 150 | : SSLHandshakeMessage(data, dataLen, container) |
789 | 150 | {} |
790 | | |
791 | | ~SSLCertificateVerifyMessage() override = default; |
792 | | |
793 | | /// @return A pointer to the signed hash data as raw data (byte array). Parsing of this data may be added |
794 | | /// in the future. Notice that if this message is spread over several packets in a way none of the signed hash |
795 | | /// data exists in this packet, nullptr will be returned |
796 | | uint8_t* getSignedHash() const; |
797 | | |
798 | | /// @return The length of signed hash data returned by getSignedHash(). Notice that if this message is spread |
799 | | /// over several packets in a way none of this data exists in the current packet, 0 will be returned. Also, if |
800 | | /// some of the data exists in the consequent packets, the length that will be returned will be the length of |
801 | | /// data exists in the current packet only (and not the total length) |
802 | | size_t getSignedHashLength() const; |
803 | | |
804 | | // implement abstract methods |
805 | | |
806 | | std::string toString() const override; |
807 | | }; |
808 | | |
809 | | /// @class SSLFinishedMessage |
810 | | /// Represents SSL/TLS finished message (type 20). Inherits from SSLHandshakeMessage and adds parsing |
811 | | /// functionality such as retrieving signed hash data as raw data (parsing may be added in the future) |
812 | | /// @todo This message type wasn't tested in unit-tests |
813 | | class SSLFinishedMessage : public SSLHandshakeMessage |
814 | | { |
815 | | public: |
816 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
817 | | /// used by a user |
818 | | /// @param[in] data The message as raw data |
819 | | /// @param[in] dataLen Message raw data length in bytes |
820 | | /// @param[in] container The SSL handshake layer which shall contain this message |
821 | | SSLFinishedMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) |
822 | 1.22k | : SSLHandshakeMessage(data, dataLen, container) |
823 | 1.22k | {} |
824 | | |
825 | | ~SSLFinishedMessage() override = default; |
826 | | |
827 | | /// @return A pointer to the signed hash data as raw data (byte array). Parsing of this data may be added |
828 | | /// in the future. Notice that if this message is spread over several packets in a way none of the signed hash |
829 | | /// data exists in this packet, nullptr will be returned |
830 | | uint8_t* getSignedHash() const; |
831 | | |
832 | | /// @return The length of signed hash data returned by getSignedHash(). Notice that if the message is spread |
833 | | /// over several packets in a way none of this data exists in the current packet, 0 will be returned. Also, if |
834 | | /// some of the data exists in the consequent packets, the length that will be returned will be the length of |
835 | | /// data exists in the current packet only (and not the total length) |
836 | | size_t getSignedHashLength() const; |
837 | | |
838 | | // implement abstract methods |
839 | | |
840 | | std::string toString() const override; |
841 | | }; |
842 | | |
843 | | /// @class SSLNewSessionTicketMessage |
844 | | /// Represents SSL/TLS new-session-ticket message (type 4). Inherits from SSLHandshakeMessage and adds parsing |
845 | | /// functionality such as retrieving session ticket data as raw data (parsing may be added in the future) |
846 | | class SSLNewSessionTicketMessage : public SSLHandshakeMessage |
847 | | { |
848 | | public: |
849 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
850 | | /// used by a user |
851 | | /// @param[in] data The message as raw data |
852 | | /// @param[in] dataLen Message raw data length in bytes |
853 | | /// @param[in] container The SSL handshake layer which shall contain this message |
854 | | SSLNewSessionTicketMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) |
855 | 1.78k | : SSLHandshakeMessage(data, dataLen, container) |
856 | 1.78k | {} |
857 | | |
858 | | ~SSLNewSessionTicketMessage() override = default; |
859 | | |
860 | | /// @return A pointer to the session ticket data as raw data (byte array). Parsing of this data may be added |
861 | | /// in the future. Notice that if this message is spread over several packets in a way none of the signed hash |
862 | | /// data exists in current packet, nullptr will be returned |
863 | | uint8_t* getSessionTicketData() const; |
864 | | |
865 | | /// @return The length of session ticket data returned by getSessionTicketData(). Notice that if this message is |
866 | | /// spread over several packets in a way none of this data exists in the current packet, 0 will be returned. |
867 | | /// Also, if some of the data exist in the consequent packets, the length that will be returned will be the |
868 | | /// length of the data existing in the current packet only (and not the total length) |
869 | | size_t getSessionTicketDataLength() const; |
870 | | |
871 | | // implement abstract methods |
872 | | |
873 | | std::string toString() const override; |
874 | | }; |
875 | | |
876 | | /// @class SSLUnknownMessage |
877 | | /// Represents an unknown type of message or an encrypted message that PcapPlusPlus can't determine its type. In |
878 | | /// these cases length can't always be determined from the message itself (especially if the message is encrypted), |
879 | | /// so the length of this message will always be the size counted from message start until the end of the layer |
880 | | class SSLUnknownMessage : public SSLHandshakeMessage |
881 | | { |
882 | | public: |
883 | | /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be |
884 | | /// used by a user |
885 | | /// @param[in] data The message as raw data |
886 | | /// @param[in] dataLen Message raw data length in bytes |
887 | | /// @param[in] container The SSL handshake layer which shall contain this message |
888 | | SSLUnknownMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) |
889 | 34.9k | : SSLHandshakeMessage(data, dataLen, container) |
890 | 34.9k | {} |
891 | | |
892 | | ~SSLUnknownMessage() override = default; |
893 | | |
894 | | // implement virtual and abstract methods |
895 | | |
896 | | /// @return Always ::SSL_HANDSHAKE_UNKNOWN (overridden from SSLHandshakeMessage) |
897 | | SSLHandshakeType getHandshakeType() const override; |
898 | | |
899 | | /// @return The length of the data from message start until the end of the layer. Since it's an unknown type |
900 | | /// or an encrypted message the length parsed from the message can't be guaranteed to be the correct length. |
901 | | /// That's why the length returned is the size until the end of the layer |
902 | | size_t getMessageLength() const override; |
903 | | |
904 | | std::string toString() const override; |
905 | | }; |
906 | | |
907 | | template <class TExtension> TExtension* SSLClientHelloMessage::getExtensionOfType() const |
908 | 17.8k | { |
909 | 17.8k | size_t vecSize = m_ExtensionList.size(); |
910 | 121k | for (size_t i = 0; i < vecSize; i++) |
911 | 111k | { |
912 | 111k | SSLExtension* curElem = const_cast<SSLExtension*>(m_ExtensionList.at(i)); |
913 | 111k | if (dynamic_cast<TExtension*>(curElem) != nullptr) |
914 | 7.39k | return static_cast<TExtension*>(curElem); |
915 | 111k | } |
916 | | |
917 | 10.4k | return nullptr; |
918 | 17.8k | } pcpp::SSLServerNameIndicationExtension* pcpp::SSLClientHelloMessage::getExtensionOfType<pcpp::SSLServerNameIndicationExtension>() const Line | Count | Source | 908 | 4.45k | { | 909 | 4.45k | size_t vecSize = m_ExtensionList.size(); | 910 | 9.24k | for (size_t i = 0; i < vecSize; i++) | 911 | 7.44k | { | 912 | 7.44k | SSLExtension* curElem = const_cast<SSLExtension*>(m_ExtensionList.at(i)); | 913 | 7.44k | if (dynamic_cast<TExtension*>(curElem) != nullptr) | 914 | 2.65k | return static_cast<TExtension*>(curElem); | 915 | 7.44k | } | 916 | | | 917 | 1.80k | return nullptr; | 918 | 4.45k | } |
pcpp::SSLSupportedVersionsExtension* pcpp::SSLClientHelloMessage::getExtensionOfType<pcpp::SSLSupportedVersionsExtension>() const Line | Count | Source | 908 | 4.45k | { | 909 | 4.45k | size_t vecSize = m_ExtensionList.size(); | 910 | 50.6k | for (size_t i = 0; i < vecSize; i++) | 911 | 46.4k | { | 912 | 46.4k | SSLExtension* curElem = const_cast<SSLExtension*>(m_ExtensionList.at(i)); | 913 | 46.4k | if (dynamic_cast<TExtension*>(curElem) != nullptr) | 914 | 288 | return static_cast<TExtension*>(curElem); | 915 | 46.4k | } | 916 | | | 917 | 4.16k | return nullptr; | 918 | 4.45k | } |
pcpp::TLSSupportedGroupsExtension* pcpp::SSLClientHelloMessage::getExtensionOfType<pcpp::TLSSupportedGroupsExtension>() const Line | Count | Source | 908 | 4.45k | { | 909 | 4.45k | size_t vecSize = m_ExtensionList.size(); | 910 | 31.3k | for (size_t i = 0; i < vecSize; i++) | 911 | 29.0k | { | 912 | 29.0k | SSLExtension* curElem = const_cast<SSLExtension*>(m_ExtensionList.at(i)); | 913 | 29.0k | if (dynamic_cast<TExtension*>(curElem) != nullptr) | 914 | 2.17k | return static_cast<TExtension*>(curElem); | 915 | 29.0k | } | 916 | | | 917 | 2.28k | return nullptr; | 918 | 4.45k | } |
pcpp::TLSECPointFormatExtension* pcpp::SSLClientHelloMessage::getExtensionOfType<pcpp::TLSECPointFormatExtension>() const Line | Count | Source | 908 | 4.45k | { | 909 | 4.45k | size_t vecSize = m_ExtensionList.size(); | 910 | 30.4k | for (size_t i = 0; i < vecSize; i++) | 911 | 28.2k | { | 912 | 28.2k | SSLExtension* curElem = const_cast<SSLExtension*>(m_ExtensionList.at(i)); | 913 | 28.2k | if (dynamic_cast<TExtension*>(curElem) != nullptr) | 914 | 2.27k | return static_cast<TExtension*>(curElem); | 915 | 28.2k | } | 916 | | | 917 | 2.17k | return nullptr; | 918 | 4.45k | } |
|
919 | | |
920 | | template <class TExtension> TExtension* SSLServerHelloMessage::getExtensionOfType() const |
921 | 10.1k | { |
922 | 10.1k | size_t vecSize = m_ExtensionList.size(); |
923 | 20.9k | for (size_t i = 0; i < vecSize; i++) |
924 | 12.1k | { |
925 | 12.1k | SSLExtension* curElem = const_cast<SSLExtension*>(m_ExtensionList.at(i)); |
926 | 12.1k | if (dynamic_cast<TExtension*>(curElem) != nullptr) |
927 | 1.41k | return static_cast<TExtension*>(curElem); |
928 | 12.1k | } |
929 | | |
930 | 8.72k | return nullptr; |
931 | 10.1k | } pcpp::SSLServerNameIndicationExtension* pcpp::SSLServerHelloMessage::getExtensionOfType<pcpp::SSLServerNameIndicationExtension>() const Line | Count | Source | 921 | 3.37k | { | 922 | 3.37k | size_t vecSize = m_ExtensionList.size(); | 923 | 6.23k | for (size_t i = 0; i < vecSize; i++) | 924 | 3.49k | { | 925 | 3.49k | SSLExtension* curElem = const_cast<SSLExtension*>(m_ExtensionList.at(i)); | 926 | 3.49k | if (dynamic_cast<TExtension*>(curElem) != nullptr) | 927 | 636 | return static_cast<TExtension*>(curElem); | 928 | 3.49k | } | 929 | | | 930 | 2.74k | return nullptr; | 931 | 3.37k | } |
pcpp::SSLSupportedVersionsExtension* pcpp::SSLServerHelloMessage::getExtensionOfType<pcpp::SSLSupportedVersionsExtension>() const Line | Count | Source | 921 | 6.75k | { | 922 | 6.75k | size_t vecSize = m_ExtensionList.size(); | 923 | 14.6k | for (size_t i = 0; i < vecSize; i++) | 924 | 8.68k | { | 925 | 8.68k | SSLExtension* curElem = const_cast<SSLExtension*>(m_ExtensionList.at(i)); | 926 | 8.68k | if (dynamic_cast<TExtension*>(curElem) != nullptr) | 927 | 778 | return static_cast<TExtension*>(curElem); | 928 | 8.68k | } | 929 | | | 930 | 5.97k | return nullptr; | 931 | 6.75k | } |
|
932 | | } // namespace pcpp |