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