Coverage Report

Created: 2023-01-17 06:15

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