Coverage Report

Created: 2026-11-12 06:49

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