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