Coverage Report

Created: 2026-08-31 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/SSLLayer.cpp
Line
Count
Source
1
#define LOG_MODULE PacketLogModuleSSLLayer
2
3
#include "SSLLayer.h"
4
#include "EndianPortable.h"
5
#include <sstream>
6
7
namespace pcpp
8
{
9
10
  // ----------------
11
  // SSLLayer methods
12
  // ----------------
13
14
  bool SSLLayer::IsSSLMessage(uint16_t srcPort, uint16_t dstPort, uint8_t* data, size_t dataLen, bool ignorePorts)
15
589k
  {
16
    // check the port map first
17
589k
    if (!ignorePorts && !isSSLPort(srcPort) && !isSSLPort(dstPort))
18
307k
      return false;
19
20
282k
    if (dataLen < sizeof(ssl_tls_record_layer))
21
36.7k
      return false;
22
23
246k
    ssl_tls_record_layer* recordLayer = (ssl_tls_record_layer*)data;
24
25
    // there is no SSL message with length 0
26
246k
    if (recordLayer->length == 0)
27
4.75k
      return false;
28
29
241k
    if (recordLayer->recordType < 20 || recordLayer->recordType > 23)
30
14.3k
      return false;
31
32
226k
    SSLVersion::SSLVersionEnum recordVersion = SSLVersion(be16toh(recordLayer->recordVersion)).asEnum(true);
33
34
226k
    if (recordVersion == SSLVersion::TLS1_3 || recordVersion == SSLVersion::TLS1_2 ||
35
45.7k
        recordVersion == SSLVersion::TLS1_1 || recordVersion == SSLVersion::TLS1_0 ||
36
4.81k
        recordVersion == SSLVersion::SSL3)
37
225k
      return true;
38
1.19k
    else
39
1.19k
      return false;
40
226k
  }
41
42
  SSLLayer* SSLLayer::createSSLMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
43
225k
  {
44
225k
    if (!canReinterpretAs<ssl_tls_record_layer>(data, dataLen))
45
0
    {
46
0
      return nullptr;
47
0
    }
48
49
225k
    ssl_tls_record_layer* recordLayer = (ssl_tls_record_layer*)data;
50
225k
    switch (recordLayer->recordType)
51
225k
    {
52
125k
    case SSL_HANDSHAKE:
53
125k
    {
54
125k
      return new SSLHandshakeLayer(data, dataLen, prevLayer, packet);
55
0
    }
56
57
5.95k
    case SSL_ALERT:
58
5.95k
    {
59
5.95k
      return new SSLAlertLayer(data, dataLen, prevLayer, packet);
60
0
    }
61
62
76.8k
    case SSL_CHANGE_CIPHER_SPEC:
63
76.8k
    {
64
76.8k
      return new SSLChangeCipherSpecLayer(data, dataLen, prevLayer, packet);
65
0
    }
66
67
17.7k
    case SSL_APPLICATION_DATA:
68
17.7k
    {
69
17.7k
      return new SSLApplicationDataLayer(data, dataLen, prevLayer, packet);
70
0
    }
71
72
0
    default:
73
0
      return nullptr;
74
225k
    }
75
225k
  }
76
77
  SSLVersion SSLLayer::getRecordVersion() const
78
73.0k
  {
79
73.0k
    uint16_t recordVersion = be16toh(getRecordLayer()->recordVersion);
80
73.0k
    return SSLVersion(recordVersion);
81
73.0k
  }
82
83
  SSLRecordType SSLLayer::getRecordType() const
84
0
  {
85
0
    return (SSLRecordType)(getRecordLayer()->recordType);
86
0
  }
87
88
  size_t SSLLayer::getHeaderLen() const
89
262k
  {
90
262k
    size_t len = sizeof(ssl_tls_record_layer) + be16toh(getRecordLayer()->length);
91
262k
    if (len > m_DataLen)
92
41.1k
      return m_DataLen;
93
221k
    return len;
94
262k
  }
95
96
  void SSLLayer::parseNextLayer()
97
225k
  {
98
225k
    size_t headerLen = getHeaderLen();
99
225k
    if (m_DataLen <= headerLen)
100
82.2k
      return;
101
102
143k
    if (SSLLayer::IsSSLMessage(0, 0, m_Data + headerLen, m_DataLen - headerLen, true))
103
102k
    {
104
102k
      constructNextLayerFromFactory(SSLLayer::createSSLMessage, m_Data + headerLen, m_DataLen - headerLen);
105
102k
    }
106
143k
  }
107
108
  // -------------------------
109
  // SSLHandshakeLayer methods
110
  // -------------------------
111
112
  std::string SSLHandshakeLayer::toString() const
113
40.7k
  {
114
40.7k
    std::stringstream result;
115
40.7k
    result << getRecordVersion().toString(true) << " Layer, Handshake:";
116
103k
    for (size_t i = 0; i < m_MessageList.size(); i++)
117
62.7k
    {
118
62.7k
      if (i == 0)
119
38.1k
        result << " " << m_MessageList.at(i)->toString();
120
24.5k
      else
121
24.5k
        result << ", " << m_MessageList.at(i)->toString();
122
62.7k
    }
123
40.7k
    return result.str();
124
40.7k
  }
125
126
  SSLHandshakeLayer::SSLHandshakeLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
127
125k
      : SSLLayer(data, dataLen, prevLayer, packet)
128
125k
  {
129
125k
    constexpr size_t baseTLSRecordSize = sizeof(ssl_tls_record_layer);
130
125k
    uint8_t* curPos = m_Data + baseTLSRecordSize;
131
125k
    size_t recordDataLen = be16toh(getRecordLayer()->length);
132
133
125k
    if (m_DataLen < recordDataLen + baseTLSRecordSize)
134
27.6k
    {
135
27.6k
      recordDataLen = m_DataLen >= baseTLSRecordSize ? m_DataLen - baseTLSRecordSize : 0;
136
27.6k
    }
137
138
125k
    size_t curPosIndex = 0;
139
316k
    while (true)
140
316k
    {
141
316k
      SSLHandshakeMessage* message =
142
316k
          SSLHandshakeMessage::createHandshakeMessage(curPos, recordDataLen - curPosIndex, this);
143
316k
      if (message == nullptr)
144
125k
        break;
145
146
191k
      m_MessageList.pushBack(message);
147
191k
      curPos += message->getMessageLength();
148
191k
      curPosIndex += message->getMessageLength();
149
191k
    }
150
125k
  }
151
152
  SSLHandshakeMessage* SSLHandshakeLayer::getHandshakeMessageAt(int index) const
153
0
  {
154
0
    if (index < 0 || index >= (int)(m_MessageList.size()))
155
0
      return nullptr;
156
157
0
    return const_cast<SSLHandshakeMessage*>(m_MessageList.at(index));
158
0
  }
159
160
  // --------------------------------
161
  // SSLChangeCipherSpecLayer methods
162
  // --------------------------------
163
164
  std::string SSLChangeCipherSpecLayer::toString() const
165
24.3k
  {
166
24.3k
    std::stringstream result;
167
24.3k
    result << getRecordVersion().toString(true) << " Layer, Change Cipher Spec";
168
24.3k
    return result.str();
169
24.3k
  }
170
171
  // ---------------------
172
  // SSLAlertLayer methods
173
  // ---------------------
174
175
  SSLAlertLevel SSLAlertLayer::getAlertLevel() const
176
1.98k
  {
177
1.98k
    uint8_t* pos = m_Data + sizeof(ssl_tls_record_layer);
178
1.98k
    uint8_t alertLevel = *pos;
179
1.98k
    if (alertLevel == SSL_ALERT_LEVEL_WARNING || alertLevel == SSL_ALERT_LEVEL_FATAL)
180
966
      return (SSLAlertLevel)alertLevel;
181
1.01k
    else
182
1.01k
      return SSL_ALERT_LEVEL_ENCRYPTED;
183
1.98k
  }
184
185
  SSLAlertDescription SSLAlertLayer::getAlertDescription()
186
0
  {
187
0
    if (getAlertLevel() == SSL_ALERT_LEVEL_ENCRYPTED)
188
0
      return SSL_ALERT_ENCRYPTED;
189
190
0
    uint8_t* pos = m_Data + sizeof(ssl_tls_record_layer) + sizeof(uint8_t);
191
0
    uint8_t alertDesc = *pos;
192
193
0
    switch (alertDesc)
194
0
    {
195
0
    case SSL_ALERT_CLOSE_NOTIFY:
196
0
    case SSL_ALERT_UNEXPECTED_MESSAGE:
197
0
    case SSL_ALERT_BAD_RECORD_MAC:
198
0
    case SSL_ALERT_DECRYPTION_FAILED:
199
0
    case SSL_ALERT_RECORD_OVERFLOW:
200
0
    case SSL_ALERT_DECOMPRESSION_FAILURE:
201
0
    case SSL_ALERT_HANDSHAKE_FAILURE:
202
0
    case SSL_ALERT_NO_CERTIFICATE:
203
0
    case SSL_ALERT_BAD_CERTIFICATE:
204
0
    case SSL_ALERT_UNSUPPORTED_CERTIFICATE:
205
0
    case SSL_ALERT_CERTIFICATE_REVOKED:
206
0
    case SSL_ALERT_CERTIFICATE_EXPIRED:
207
0
    case SSL_ALERT_CERTIFICATE_UNKNOWN:
208
0
    case SSL_ALERT_ILLEGAL_PARAMETER:
209
0
    case SSL_ALERT_UNKNOWN_CA:
210
0
    case SSL_ALERT_ACCESS_DENIED:
211
0
    case SSL_ALERT_DECODE_ERROR:
212
0
    case SSL_ALERT_DECRYPT_ERROR:
213
0
    case SSL_ALERT_EXPORT_RESTRICTION:
214
0
    case SSL_ALERT_PROTOCOL_VERSION:
215
0
    case SSL_ALERT_INSUFFICIENT_SECURITY:
216
0
    case SSL_ALERT_INTERNAL_ERROR:
217
0
    case SSL_ALERT_USER_CANCELLED:
218
0
    case SSL_ALERT_NO_RENEGOTIATION:
219
0
      return (SSLAlertDescription)alertDesc;
220
0
      break;
221
0
    default:
222
0
      return SSL_ALERT_ENCRYPTED;
223
0
    }
224
0
  }
225
226
  std::string SSLAlertLayer::toString() const
227
1.98k
  {
228
1.98k
    std::stringstream result;
229
1.98k
    result << getRecordVersion().toString(true) << " Layer, ";
230
1.98k
    if (getAlertLevel() == SSL_ALERT_LEVEL_ENCRYPTED)
231
1.01k
      result << "Encrypted Alert";
232
966
    else
233
      // TODO: add alert level and description here
234
966
      result << "Alert";
235
1.98k
    return result.str();
236
1.98k
  }
237
238
  // -------------------------------
239
  // SSLApplicationDataLayer methods
240
  // -------------------------------
241
242
  uint8_t* SSLApplicationDataLayer::getEncryptedData() const
243
0
  {
244
0
    if (getHeaderLen() <= sizeof(ssl_tls_record_layer))
245
0
      return nullptr;
246
247
0
    return m_Data + sizeof(ssl_tls_record_layer);
248
0
  }
249
250
  size_t SSLApplicationDataLayer::getEncryptedDataLen() const
251
0
  {
252
0
    int result = (int)getHeaderLen() - (int)sizeof(ssl_tls_record_layer);
253
0
    if (result < 0)
254
0
      return 0;
255
256
0
    return (size_t)result;
257
0
  }
258
259
  std::string SSLApplicationDataLayer::toString() const
260
6.04k
  {
261
6.04k
    return getRecordVersion().toString(true) + " Layer, Application Data";
262
6.04k
  }
263
264
}  // namespace pcpp