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