Coverage Report

Created: 2025-11-24 07:12

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