Coverage Report

Created: 2025-07-11 07:47

/src/PcapPlusPlus/Packet++/header/SSLLayer.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include "PointerVector.h"
4
#include "Layer.h"
5
#include "SSLCommon.h"
6
#include "SSLHandshake.h"
7
8
#ifdef __GNUC__
9
# pragma GCC diagnostic push
10
# pragma GCC diagnostic ignored "-Wcomment"
11
#endif
12
/// @file
13
/// This file as well as SSLCommon.h and SSLHandshake.h provide structures that represent SSL/TLS protocol.
14
/// Main features:
15
/// - All common SSL/TLS version are supported from SSL 3.0 to TLS 1.3
16
/// - All SSL/TLS message types are supported (at least the message types that are not encrypted)
17
/// - More than 300 cipher-suites are supported
18
/// - Only parsing capabilities exist, editing and creation of messages are not supported
19
/// - X509 certificate parsing is not supported
20
///
21
/// <BR><BR>
22
///
23
/// __SSL Records:__   <BR>
24
///
25
/// The SSL/TLS protocol has 4 types of records:
26
/// - Handshake record type
27
/// - Change cipher spec record type
28
/// - Alert record type
29
/// - Application data record type
30
///
31
/// Each record type corresponds to a layer class, and these classes inherit from one base class which is
32
/// pcpp::SSLLayer. The pcpp::SSLLayer is an abstract class which cannot be instantiated. Only its 4 derived classes can
33
/// be instantiated. This means you'll never see a layer of type pcpp::SSLLayer, you'll only see the type of the derived
34
/// classes. A basic class diagram looks like this:
35
/// @code{.unparsed}
36
///                              +----------------------------+
37
///                          +---|     SSLHandshakeLayer      | ===> Handshake record type
38
///                          |   +----------------------------+
39
///                          |
40
///                          |   +----------------------------+
41
///                          +---|  SSLChangeCipherSpecLayer  | ===> Change cipher spec record type
42
///                          |   +----------------------------+
43
///                          |
44
///  +------------+          |   +----------------------------+
45
///  |  SSLLayer  |----------+---|      SSLAlertLayer         | ===> Alert record type
46
///  | (abstract) |          |   +----------------------------+
47
///  +------------+          |
48
///                          |   +----------------------------+
49
///                          +---|   SSLApplicationDataLayer  | ===> Application data record type
50
///                              +----------------------------+
51
/// @endcode
52
///
53
/// A single packet may include several SSL/TLS records, meaning
54
/// several layer instances of these types, for example:
55
///
56
/// @code{.unparsed}
57
///  +--------------------------+
58
///  |          EthLayer        |
59
///  +--------------------------+
60
///  |          IPv4Layer       |
61
///  +--------------------------+
62
///  |          TcpLayer        |
63
///  +--------------------------+
64
///  |    SSLHandshakeLayer     | --+
65
///  +--------------------------+   |
66
///  | SSLChangeCipherSpecLayer | --+----- 3 SSL/TLS records in the same packet!
67
///  +--------------------------+   |
68
///  |    SSLHandshakeLayer     | --+
69
///  +--------------------------+
70
/// @endcode
71
///
72
/// <BR><BR>
73
///
74
/// __SSL/TLS Handshake records:__    <BR>
75
///
76
/// The SSL/TLS handshake records are the most complex ones. These type
77
/// of records encapsulate all messages between client and server during
78
/// SSL/TLS connection establishment. To accomplish that a SSL/TLS
79
/// handshake record holds zero or more handshake messages (usually it
80
/// holds 1 message). These messages form the handshake negotiation
81
/// between the client and the server. There are several types of
82
/// handshake messages. Some of the are sent from client to server and
83
/// some from server to client. PcapPlusPlus supports 11 of these types
84
/// (definitely the most common ones). For each message there is a
85
/// designated class which parses the message and exposes its attributes
86
/// in an easy-to-use manner. Here are the list of supported messages:
87
/// - Client-hello
88
/// - Server-hello
89
/// - Certificate
90
/// - Hello-request
91
/// - Server-key-exchange
92
/// - Client-key-exchange
93
/// - Certificate-request
94
/// - Server-hello-done
95
/// - Certificate-verify
96
/// - Finished
97
/// - New-session-ticket
98
///
99
/// All handshake messages classes inherit from a base abstract class:
100
/// pcpp::SSLHandshakeMessage which cannot be instantiated. Also, all of
101
/// them reside in SSLHandshake.h. Following is a simple diagram of these
102
/// classes:
103
///
104
/// @code{.unparsed}
105
///                                            SSLHandshakeMessage
106
///                                               |
107
///   +-------------------------------+           |--- SSLClientHelloMessage        ==> Client-hello message
108
///   |       SSLHandshakeLayer       |           |
109
///   +-------------------------------+           |--- SSLServerHelloMessage        ==> Server-hello message
110
///   | -List of SSLHandshakeMessage  |           |
111
///   |     Message1                  |           |---SSLCertificateMessage         ==> Certificate message
112
///   |     Message2                  |           |
113
///   |     ...                       |           |---SSLHelloRequestMessage        ==> Hello-request message
114
///   |                               |           |
115
///   +-------------------------------+           |---SSLServerKeyExchangeMessage   ==> Server-key-exchange message
116
///                                               |
117
///                                               |---SSLClientKeyExchangeMessage   ==> Client-key-exchange message
118
///                                               |
119
///                                               |---SSLCertificateRequestMessage  ==> Certificate-request message
120
///                                               |
121
///                                               |---SSLServerHelloDoneMessage     ==> Server-hello-done message
122
///                                               |
123
///                                               |---SSLCertificateVerifyMessage   ==> Certificate-verify message
124
///                                               |
125
///                                               |---SSLFinishedMessage            ==> Finished message
126
///                                               |
127
///                                               |---SSLNewSessionTicketMessage    ==> New-session-ticket message
128
/// @endcode
129
///
130
/// In addition, for all handshake messages which aren't supported in PcapPlusPlus or for encrypted
131
/// handshake messages There is another class: pcpp::SSLUnknownMessage
132
///
133
/// <BR><BR>
134
///
135
/// __Cipher suites:__    <BR>
136
///
137
/// Cipher suites are named combinations of authentication, encryption, message authentication code
138
/// (MAC) and key exchange algorithms used to negotiate the security settings for a network connection
139
/// using SSL/TLS. There are many known cipher-suites. PcapPlusPlus support above 300 of them,
140
/// according to this list: http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml There
141
/// is a designated class in PcapPlusPlus called pcpp::SSLCipherSuite which represents the
142
/// cipher-suites and provides access to their attributes. Then there is a static instance of this
143
/// class for each one of the supported cipher-suites. This means there are 300+ static instances of
144
/// pcpp::SSLCipherSuite representing the different cipher suites. The user can access them through
145
/// static methods in pcpp::SSLCipherSuite or from client-hello and server-hello messages where they
146
/// appear.
147
///
148
/// <BR><BR>
149
///
150
/// __SSL/TLS extensions:__    <BR>
151
///
152
/// SSL/TLS handshake messages, specifically client-hello and server-hello usually include extensions.
153
/// There are various types of extensions - some are more broadly used, some are less. In PcapPlusPlus
154
/// there is a base class for all extensions: pcpp::SSLExtension. This class is instantiable and
155
/// represents a generic extension, which means extension data isn't parsed and given to the user as
156
/// raw data. Currently there are only two extension that are fully parsed which are
157
/// server-name-indication (pcpp::SSLServerNameIndicationExtension) and SupportedVersions
158
/// (pcpp::SSLSupportedVersionsExtension).
159
/// Both inherit from pcpp::SSLExtension and add additional parsing relevant for the specific
160
/// extension. All other extensions aren't parsed and are represented by instance of
161
/// pcpp::SSLExtension. Access to extensions is done through the handshake messages classes,
162
/// specifically pcpp::SSLClientHelloMessage and pcpp::SSLServerHelloMessage
163
#ifdef __GNUC__
164
# pragma GCC diagnostic pop
165
#endif
166
167
/// @namespace pcpp
168
/// @brief The main namespace for the PcapPlusPlus lib
169
namespace pcpp
170
{
171
172
  /// @class SSLLayer
173
  /// The base class for the 4 record type classes. Each record type is represented as a layer. See SSLLayer.h for
174
  /// detailed explanation of the TLS/SSL protocol support in PcapPlusPlus.
175
  /// This class provides the common functionality used by all record types and also contains static methods for
176
  /// identifying an creating SSL/TLS record type layers
177
  class SSLLayer : public Layer
178
  {
179
  public:
180
    /// A static method that checks whether the port is considered as SSL/TLS
181
    /// @param[in] port The port number to be checked
182
    static inline bool isSSLPort(uint16_t port);
183
184
    /// A static methods that gets raw data of a layer and checks whether this data is a SSL/TLS record or not. This
185
    /// check is done using the source/dest port and matching of a legal record type in the raw data. The list of
186
    /// ports identified as SSL/TLS is hard-coded and includes the following ports:
187
    /// - Port 443 [HTTPS]
188
    /// - Port 261 [NSIIOPS]
189
    /// - Port 448 [DDM-SSL]
190
    /// - Port 563 [NNTPS]
191
    /// - Port 614 [SSHELL]
192
    /// - Port 465 [SMTPS]
193
    /// - Port 636 [LDAPS]
194
    /// - Port 989 [FTPS - data]
195
    /// - Port 990 [FTPS - control]
196
    /// - Port 992 [Telnet over TLS/SSL]
197
    /// - Port 993 [IMAPS]
198
    /// - Port 994 [IRCS]
199
    /// - Port 995 [POP3S]
200
    /// @param[in] srcPort The source port of the packet that contains the raw data. Source port (or dest port) are
201
    /// a criteria to identify SSL/TLS packets
202
    /// @param[in] dstPort The dest port of the packet that contains the raw data. Dest port (or source port) are a
203
    /// criteria to identify SSL/TLS packets
204
    /// @param[in] data The data to check
205
    /// @param[in] dataLen Length (in bytes) of the data
206
    /// @param[in] ignorePorts SSL/TLS ports are only relevant for parsing the first SSL/TLS message, but are not
207
    /// relevant for parsing subsequent messages. This parameter can be set to "true" to skip SSL/TLS ports check.
208
    /// This is an optional parameter and its default is "false"
209
    static bool IsSSLMessage(uint16_t srcPort, uint16_t dstPort, uint8_t* data, size_t dataLen,
210
                             bool ignorePorts = false);
211
212
    /// A static method that creates SSL/TLS layers by raw data. This method parses the raw data, finds if and which
213
    /// SSL/TLS record it is and creates the corresponding record layer. It's the responsibility of the user to free
214
    /// the created object when done using it
215
    /// @param[in] data A pointer to the raw data
216
    /// @param[in] dataLen Size of the data in bytes
217
    /// @param[in] prevLayer A pointer to the previous layer
218
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
219
    /// @return A pointer to the newly created record layer. If no SSL/TLS record could be identified from the raw
220
    /// data nullptr is returned
221
    static SSLLayer* createSSLMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
222
223
    /// Get a pointer to the record header. Notice this points directly to the data, so every change will change the
224
    /// actual packet data
225
    /// @return A pointer to the @ref ssl_tls_record_layer
226
    ssl_tls_record_layer* getRecordLayer() const
227
147k
    {
228
147k
      return reinterpret_cast<ssl_tls_record_layer*>(m_Data);
229
147k
    }
230
231
    /// @return The SSL/TLS version used in this record (parsed from the record)
232
    SSLVersion getRecordVersion() const;
233
234
    /// @return The SSL/TLS record type as parsed from the record
235
    SSLRecordType getRecordType() const;
236
237
    // implement abstract methods
238
239
    /// @return The record size as extracted from the record data (in ssl_tls_record_layer#length)
240
    size_t getHeaderLen() const override;
241
242
    /// Several SSL/TLS records can reside in a single packets. So this method checks the remaining data and if it's
243
    /// identified as SSL/TLS it creates another SSL/TLS record layer as the next layer
244
    void parseNextLayer() override;
245
246
    OsiModelLayer getOsiModelLayer() const override
247
11.6k
    {
248
11.6k
      return OsiModelPresentationLayer;
249
11.6k
    }
250
251
  protected:
252
    SSLLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
253
72.6k
        : Layer(data, dataLen, prevLayer, packet, SSL)
254
72.6k
    {}
255
256
  };  // class SSLLayer
257
258
  // The graph below will break the code formatting, so it's disabled.
259
  // clang-format off
260
  /// @class SSLHandshakeLayer
261
  /// Represents SSL/TLS handshake layer. This layer may contain one or more handshake messages (all of them inherit
262
  /// from the base class SSLHandshakeMessage) which are the SSL/TLS handshake message sent between a client and a
263
  /// server until they establish a secure connection (e.g client-hello, server-hello, certificate,
264
  /// client-key-exchange, server-key-exchange, etc.).
265
  /// Usually this layer will contain just one message (as the first example below
266
  /// demonstrates). But there are cases a layer may contain more than 1 message. To better explain this layer
267
  /// structure. We'll use 2 examples. The first will be client-hello message. The layer structure will look like this:
268
  ///
269
  /// @code{.unparsed}
270
  ///  |----------------------------- SSLHandshakeLayer ----------------------------------------|
271
  ///  +--------------------------------+-------------------------------------------------------+
272
  ///  |      ssl_tls_record_layer      |       SSLClientHelloMessage                           |
273
  ///  |             struct             |                                                       |
274
  ///  +--------------------------------+-------------------------------------------------------+
275
  ///  |          /     |       \               |          \         \      \                   |
276
  ///  |         /    version    \      |   handshake       \         \      \                  |
277
  ///  |        /     TLS1_0      \            type          \         \     rest of            |
278
  ///  |     type                  \    | SSL_CLIENT_HELLO    \         \    message fields...  |
279
  ///  | SSL_HANDSHAKE           length                   handshake      \                      |
280
  ///  |     (22)                 xxx   |                  version      message                 |
281
  ///  |                                                   TLS1_2      length                   |
282
  ///  |                                |                                yyy                    |
283
  /// @endcode
284
  ///
285
  /// Second example is a multiple-message handshake layer comprises of server-hello, certificate and
286
  /// server-key-exchange messages:
287
  ///
288
  /// @code{.unparsed}
289
  ///  |------------------------------------------------------- SSLHandshakeLayer ------------------------------------------------------|
290
  ///  +--------------------------------+-------------------------------------+---------------------------+-----------------------------+
291
  ///  |      ssl_tls_record_layer      |       SSLServerHelloMessage         |   SSLCertificateMessage   | SSLServerKeyExchangeMessage |
292
  ///  |             struct             |                                     |                           |                             |
293
  ///  +--------------------------------+-------------------------------------+---------------------------+-----------------------------+
294
  ///  |          /     |       \               |          \         \               |           \               |            \         |
295
  ///  |         /    version    \      |   handshake       \        rest of  |      |          rest      |      |            rest      |
296
  ///  |        /     TLS1_0      \            type          \       message      handshake   of fields...   handshake    of fields...  |
297
  ///  |     type                  \    | SSL_SERVER_HELLO    \      fields...|     type                  |     type                    |
298
  ///  | SSL_HANDSHAKE           length                   handshake             SSL_CERTIFICATE             SSL_SERVER_KEY_EXCHANGE     |
299
  ///  |     (22)                 xxx   |               version,length        |                           |                             |
300
  /// @endcode
301
  // clang-format on
302
  class SSLHandshakeLayer : public SSLLayer
303
  {
304
  public:
305
    /// C'tor for this class that creates the layer from an existing packet raw data
306
    /// @param[in] data A pointer to the raw data
307
    /// @param[in] dataLen Size of the data in bytes
308
    /// @param[in] prevLayer A pointer to the previous layer
309
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
310
    SSLHandshakeLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
311
312
    /// @return The number of messages in this layer instance
313
    size_t getHandshakeMessagesCount() const
314
0
    {
315
0
      return m_MessageList.size();
316
0
    }
317
318
    /// Get a pointer to an handshake message by index. The message are numbered according to their order of
319
    /// appearance in the layer. If index is out of bounds (less than 0 or larger than total amount of message)
320
    /// nullptr will be returned
321
    /// @param[in] index The index of the message to return
322
    /// @return The pointer to the message object or nullptr if index is out of bounds
323
    SSLHandshakeMessage* getHandshakeMessageAt(int index) const;
324
325
    /// A templated method to get a message of a certain type. If no message of such type is found, nullptr is
326
    /// returned
327
    /// @return A pointer to the message of the requested type, nullptr if not found
328
    template <class THandshakeMessage> THandshakeMessage* getHandshakeMessageOfType() const;
329
330
    /// A templated method to get the first message of a certain type, starting to search from a certain message.
331
    /// For example: if the layer looks like: HelloRequest(1) -> HelloRequest(2)
332
    /// and the user put HelloRequest(1) as a parameter and wishes to search for an HelloRequest message, the
333
    /// HelloRequest(2) will be returned.<BR>
334
    /// If no layer of such type is found, nullptr is returned
335
    /// @param[in] after A pointer to the message to start search from
336
    /// @return A pointer to the message of the requested type, nullptr if not found
337
    template <class THandshakeMessage>
338
    THandshakeMessage* getNextHandshakeMessageOfType(const SSLHandshakeMessage* after) const;
339
340
    // implement abstract methods
341
342
    std::string toString() const override;
343
344
    /// There are no calculated fields for this layer
345
    void computeCalculateFields() override
346
6.43k
    {}
347
348
  private:
349
    PointerVector<SSLHandshakeMessage> m_MessageList;
350
  };  // class SSLHandshakeLayer
351
352
  /// @class SSLChangeCipherSpecLayer
353
  /// Represents SSL/TLS change-cipher-spec layer. This layer has no additional fields besides common fields described
354
  /// in SSLLayer
355
  class SSLChangeCipherSpecLayer : public SSLLayer
356
  {
357
  public:
358
    /// C'tor for this class that creates the layer from an existing packet raw data
359
    /// @param[in] data A pointer to the raw data
360
    /// @param[in] dataLen Size of the data in bytes
361
    /// @param[in] prevLayer A pointer to the previous layer
362
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
363
    SSLChangeCipherSpecLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
364
22.6k
        : SSLLayer(data, dataLen, prevLayer, packet)
365
22.6k
    {}
366
367
    ~SSLChangeCipherSpecLayer() override = default;
368
369
    // implement abstract methods
370
371
    std::string toString() const override;
372
373
    /// There are no calculated fields for this layer
374
    void computeCalculateFields() override
375
3.51k
    {}
376
  };  // class SSLChangeCipherSpecLayer
377
378
  /// @class SSLAlertLayer
379
  /// Represents SSL/TLS alert layer. Inherits from SSLLayer and adds parsing functionality such as retrieving the
380
  /// alert level and description
381
  class SSLAlertLayer : public SSLLayer
382
  {
383
  public:
384
    /// C'tor for this class that creates the layer from an existing packet raw data
385
    /// @param[in] data A pointer to the raw data
386
    /// @param[in] dataLen Size of the data in bytes
387
    /// @param[in] prevLayer A pointer to the previous layer
388
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
389
    SSLAlertLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
390
2.04k
        : SSLLayer(data, dataLen, prevLayer, packet)
391
2.04k
    {}
392
393
    ~SSLAlertLayer() override = default;
394
395
    /// @return SSL/TLS alert level. Will return ::SSL_ALERT_LEVEL_ENCRYPTED if alert is encrypted
396
    SSLAlertLevel getAlertLevel() const;
397
398
    /// @return SSL/TLS alert description. Will return ::SSL_ALERT_ENCRYPTED if alert is encrypted
399
    SSLAlertDescription getAlertDescription();
400
401
    // implement abstract methods
402
403
    std::string toString() const override;
404
405
    /// There are no calculated fields for this layer
406
    void computeCalculateFields() override
407
324
    {}
408
  };  // class SSLAlertLayer
409
410
  /// @class SSLApplicationDataLayer
411
  /// Represents SSL/TLS application data layer. This message contains the encrypted data transferred from client to
412
  /// server and vice-versa after the SSL/TLS handshake was completed successfully
413
  class SSLApplicationDataLayer : public SSLLayer
414
  {
415
  public:
416
    /// C'tor for this class that creates the layer from an existing packet raw data
417
    /// @param[in] data A pointer to the raw data
418
    /// @param[in] dataLen Size of the data in bytes
419
    /// @param[in] prevLayer A pointer to the previous layer
420
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
421
    SSLApplicationDataLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
422
7.90k
        : SSLLayer(data, dataLen, prevLayer, packet)
423
7.90k
    {}
424
425
    ~SSLApplicationDataLayer() override = default;
426
427
    /// @return A pointer to the encrypted data. This data can be decrypted only if you have the symmetric key
428
    /// that was agreed between the client and the server during SSL/TLS handshake process
429
    uint8_t* getEncryptedData() const;
430
431
    /// @return The length in bytes of the encrypted data returned in getEncryptedData()
432
    size_t getEncryptedDataLen() const;
433
434
    // implement abstract methods
435
436
    std::string toString() const override;
437
438
    /// There are no calculated fields for this layer
439
    void computeCalculateFields() override
440
1.37k
    {}
441
  };  // class SSLApplicationDataLayer
442
443
  template <class THandshakeMessage> THandshakeMessage* SSLHandshakeLayer::getHandshakeMessageOfType() const
444
19.2k
  {
445
19.2k
    size_t vecSize = m_MessageList.size();
446
31.3k
    for (size_t i = 0; i < vecSize; i++)
447
21.1k
    {
448
21.1k
      SSLHandshakeMessage* curElem = const_cast<SSLHandshakeMessage*>(m_MessageList.at(i));
449
21.1k
      if (dynamic_cast<THandshakeMessage*>(curElem) != nullptr)
450
9.04k
        return (THandshakeMessage*)curElem;
451
21.1k
    }
452
453
    // element not found
454
10.2k
    return nullptr;
455
19.2k
  }  // getHandshakeMessageOfType
pcpp::SSLClientHelloMessage* pcpp::SSLHandshakeLayer::getHandshakeMessageOfType<pcpp::SSLClientHelloMessage>() const
Line
Count
Source
444
6.43k
  {
445
6.43k
    size_t vecSize = m_MessageList.size();
446
12.1k
    for (size_t i = 0; i < vecSize; i++)
447
7.57k
    {
448
7.57k
      SSLHandshakeMessage* curElem = const_cast<SSLHandshakeMessage*>(m_MessageList.at(i));
449
7.57k
      if (dynamic_cast<THandshakeMessage*>(curElem) != nullptr)
450
1.89k
        return (THandshakeMessage*)curElem;
451
7.57k
    }
452
453
    // element not found
454
4.54k
    return nullptr;
455
6.43k
  }  // getHandshakeMessageOfType
pcpp::SSLServerHelloMessage* pcpp::SSLHandshakeLayer::getHandshakeMessageOfType<pcpp::SSLServerHelloMessage>() const
Line
Count
Source
444
6.43k
  {
445
6.43k
    size_t vecSize = m_MessageList.size();
446
12.8k
    for (size_t i = 0; i < vecSize; i++)
447
7.77k
    {
448
7.77k
      SSLHandshakeMessage* curElem = const_cast<SSLHandshakeMessage*>(m_MessageList.at(i));
449
7.77k
      if (dynamic_cast<THandshakeMessage*>(curElem) != nullptr)
450
1.38k
        return (THandshakeMessage*)curElem;
451
7.77k
    }
452
453
    // element not found
454
5.04k
    return nullptr;
455
6.43k
  }  // getHandshakeMessageOfType
pcpp::SSLHandshakeMessage* pcpp::SSLHandshakeLayer::getHandshakeMessageOfType<pcpp::SSLHandshakeMessage>() const
Line
Count
Source
444
6.43k
  {
445
6.43k
    size_t vecSize = m_MessageList.size();
446
6.43k
    for (size_t i = 0; i < vecSize; i++)
447
5.76k
    {
448
5.76k
      SSLHandshakeMessage* curElem = const_cast<SSLHandshakeMessage*>(m_MessageList.at(i));
449
5.76k
      if (dynamic_cast<THandshakeMessage*>(curElem) != nullptr)
450
5.76k
        return (THandshakeMessage*)curElem;
451
5.76k
    }
452
453
    // element not found
454
667
    return nullptr;
455
6.43k
  }  // getHandshakeMessageOfType
456
457
  template <class THandshakeMessage>
458
  THandshakeMessage* SSLHandshakeLayer::getNextHandshakeMessageOfType(const SSLHandshakeMessage* after) const
459
  {
460
    size_t vecSize = m_MessageList.size();
461
    size_t afterIndex;
462
463
    // find the index of "after"
464
    for (afterIndex = 0; afterIndex < vecSize; afterIndex++)
465
    {
466
      SSLHandshakeMessage* curElem = const_cast<SSLHandshakeMessage*>(m_MessageList.at(afterIndex));
467
      if (curElem == after)
468
        break;
469
    }
470
471
    // "after" not found
472
    if (afterIndex == vecSize)
473
      return nullptr;
474
475
    for (size_t i = afterIndex + 1; i < vecSize; i++)
476
    {
477
      SSLHandshakeMessage* curElem = const_cast<SSLHandshakeMessage*>(m_MessageList.at(i));
478
      if (dynamic_cast<THandshakeMessage*>(curElem) != nullptr)
479
        return (THandshakeMessage*)curElem;
480
    }
481
482
    // element not found
483
    return nullptr;
484
  }  // getNextHandshakeMessageOfType
485
486
  // implementation of inline methods
487
488
  bool SSLLayer::isSSLPort(uint16_t port)
489
0
  {
490
0
    if (port == 443)  // HTTPS, this is likely case
491
0
      return true;
492
0
493
0
    switch (port)
494
0
    {
495
0
    case 261:  // NSIIOPS
496
0
    case 448:  // DDM-SSL
497
0
    case 465:  // SMTPS
498
0
    case 563:  // NNTPS
499
0
    case 614:  // SSHELL
500
0
    case 636:  // LDAPS
501
0
    case 989:  // FTPS - data
502
0
    case 990:  // FTPS - control
503
0
    case 992:  // Telnet over TLS/SSL
504
0
    case 993:  // IMAPS
505
0
    case 994:  // IRCS
506
0
    case 995:  // POP3S
507
0
      return true;
508
0
    default:
509
0
      return false;
510
0
    }
511
0
  }  // isSSLPort
512
}  // namespace pcpp