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