/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 | 505k | { |
16 | | // check the port map first |
17 | 505k | if (!ignorePorts && !isSSLPort(srcPort) && !isSSLPort(dstPort)) |
18 | 248k | return false; |
19 | | |
20 | 257k | if (dataLen < sizeof(ssl_tls_record_layer)) |
21 | 26.6k | return false; |
22 | | |
23 | 231k | ssl_tls_record_layer* recordLayer = (ssl_tls_record_layer*)data; |
24 | | |
25 | | // there is no SSL message with length 0 |
26 | 231k | if (recordLayer->length == 0) |
27 | 5.30k | return false; |
28 | | |
29 | 225k | if (recordLayer->recordType < 20 || recordLayer->recordType > 23) |
30 | 13.9k | return false; |
31 | | |
32 | 211k | SSLVersion::SSLVersionEnum recordVersion = SSLVersion(be16toh(recordLayer->recordVersion)).asEnum(true); |
33 | | |
34 | 211k | if (recordVersion == SSLVersion::TLS1_3 || recordVersion == SSLVersion::TLS1_2 || |
35 | 37.3k | recordVersion == SSLVersion::TLS1_1 || recordVersion == SSLVersion::TLS1_0 || |
36 | 3.42k | recordVersion == SSLVersion::SSL3) |
37 | 210k | return true; |
38 | 1.12k | else |
39 | 1.12k | return false; |
40 | 211k | } |
41 | | |
42 | | SSLLayer* SSLLayer::createSSLMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
43 | 210k | { |
44 | 210k | ssl_tls_record_layer* recordLayer = (ssl_tls_record_layer*)data; |
45 | 210k | switch (recordLayer->recordType) |
46 | 210k | { |
47 | 115k | case SSL_HANDSHAKE: |
48 | 115k | { |
49 | 115k | return new SSLHandshakeLayer(data, dataLen, prevLayer, packet); |
50 | 0 | } |
51 | | |
52 | 4.72k | case SSL_ALERT: |
53 | 4.72k | { |
54 | 4.72k | return new SSLAlertLayer(data, dataLen, prevLayer, packet); |
55 | 0 | } |
56 | | |
57 | 73.5k | case SSL_CHANGE_CIPHER_SPEC: |
58 | 73.5k | { |
59 | 73.5k | return new SSLChangeCipherSpecLayer(data, dataLen, prevLayer, packet); |
60 | 0 | } |
61 | | |
62 | 17.2k | case SSL_APPLICATION_DATA: |
63 | 17.2k | { |
64 | 17.2k | return new SSLApplicationDataLayer(data, dataLen, prevLayer, packet); |
65 | 0 | } |
66 | | |
67 | 0 | default: |
68 | 0 | return nullptr; |
69 | 210k | } |
70 | 210k | } |
71 | | |
72 | | SSLVersion SSLLayer::getRecordVersion() const |
73 | 67.7k | { |
74 | 67.7k | uint16_t recordVersion = be16toh(getRecordLayer()->recordVersion); |
75 | 67.7k | return SSLVersion(recordVersion); |
76 | 67.7k | } |
77 | | |
78 | | SSLRecordType SSLLayer::getRecordType() const |
79 | 0 | { |
80 | 0 | return (SSLRecordType)(getRecordLayer()->recordType); |
81 | 0 | } |
82 | | |
83 | | size_t SSLLayer::getHeaderLen() const |
84 | 244k | { |
85 | 244k | size_t len = sizeof(ssl_tls_record_layer) + be16toh(getRecordLayer()->length); |
86 | 244k | if (len > m_DataLen) |
87 | 39.4k | return m_DataLen; |
88 | 205k | return len; |
89 | 244k | } |
90 | | |
91 | | void SSLLayer::parseNextLayer() |
92 | 210k | { |
93 | 210k | size_t headerLen = getHeaderLen(); |
94 | 210k | if (m_DataLen <= headerLen) |
95 | 76.4k | return; |
96 | | |
97 | 134k | if (SSLLayer::IsSSLMessage(0, 0, m_Data + headerLen, m_DataLen - headerLen, true)) |
98 | 101k | m_NextLayer = SSLLayer::createSSLMessage(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet); |
99 | 134k | } |
100 | | |
101 | | // ------------------------- |
102 | | // SSLHandshakeLayer methods |
103 | | // ------------------------- |
104 | | |
105 | | std::string SSLHandshakeLayer::toString() const |
106 | 37.1k | { |
107 | 37.1k | std::stringstream result; |
108 | 37.1k | result << getRecordVersion().toString(true) << " Layer, Handshake:"; |
109 | 95.1k | for (size_t i = 0; i < m_MessageList.size(); i++) |
110 | 57.9k | { |
111 | 57.9k | if (i == 0) |
112 | 34.9k | result << " " << m_MessageList.at(i)->toString(); |
113 | 23.0k | else |
114 | 23.0k | result << ", " << m_MessageList.at(i)->toString(); |
115 | 57.9k | } |
116 | 37.1k | return result.str(); |
117 | 37.1k | } |
118 | | |
119 | | SSLHandshakeLayer::SSLHandshakeLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
120 | 115k | : SSLLayer(data, dataLen, prevLayer, packet) |
121 | 115k | { |
122 | 115k | uint8_t* curPos = m_Data + sizeof(ssl_tls_record_layer); |
123 | 115k | size_t recordDataLen = be16toh(getRecordLayer()->length); |
124 | 115k | if (recordDataLen > m_DataLen - sizeof(ssl_tls_record_layer)) |
125 | 26.8k | recordDataLen = m_DataLen - sizeof(ssl_tls_record_layer); |
126 | | |
127 | 115k | size_t curPosIndex = 0; |
128 | 293k | while (true) |
129 | 293k | { |
130 | 293k | SSLHandshakeMessage* message = |
131 | 293k | SSLHandshakeMessage::createHandshakeMessage(curPos, recordDataLen - curPosIndex, this); |
132 | 293k | if (message == nullptr) |
133 | 115k | break; |
134 | | |
135 | 178k | m_MessageList.pushBack(message); |
136 | 178k | curPos += message->getMessageLength(); |
137 | 178k | curPosIndex += message->getMessageLength(); |
138 | 178k | } |
139 | 115k | } |
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 | 23.1k | { |
155 | 23.1k | std::stringstream result; |
156 | 23.1k | result << getRecordVersion().toString(true) << " Layer, Change Cipher Spec"; |
157 | 23.1k | return result.str(); |
158 | 23.1k | } |
159 | | |
160 | | // --------------------- |
161 | | // SSLAlertLayer methods |
162 | | // --------------------- |
163 | | |
164 | | SSLAlertLevel SSLAlertLayer::getAlertLevel() const |
165 | 1.55k | { |
166 | 1.55k | uint8_t* pos = m_Data + sizeof(ssl_tls_record_layer); |
167 | 1.55k | uint8_t alertLevel = *pos; |
168 | 1.55k | if (alertLevel == SSL_ALERT_LEVEL_WARNING || alertLevel == SSL_ALERT_LEVEL_FATAL) |
169 | 882 | return (SSLAlertLevel)alertLevel; |
170 | 672 | else |
171 | 672 | return SSL_ALERT_LEVEL_ENCRYPTED; |
172 | 1.55k | } |
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.55k | { |
217 | 1.55k | std::stringstream result; |
218 | 1.55k | result << getRecordVersion().toString(true) << " Layer, "; |
219 | 1.55k | if (getAlertLevel() == SSL_ALERT_LEVEL_ENCRYPTED) |
220 | 672 | result << "Encrypted Alert"; |
221 | 882 | else |
222 | | // TODO: add alert level and description here |
223 | 882 | result << "Alert"; |
224 | 1.55k | return result.str(); |
225 | 1.55k | } |
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.87k | { |
250 | 5.87k | return getRecordVersion().toString(true) + " Layer, Application Data"; |
251 | 5.87k | } |
252 | | |
253 | | } // namespace pcpp |