/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 |