The generic TLS Record message, based on section 6.2 of RFC 5246. When reading a TLS message, we try to parse as much as we can. In .pre_dissect(), according to the type of the current cipher algorithm (self.tls_session.rcs.cipher.type), we extract the 'iv', 'mac', 'pad' and 'p
| 232 | |
| 233 | |
| 234 | class TLS(_GenericTLSSessionInheritance): |
| 235 | """ |
| 236 | The generic TLS Record message, based on section 6.2 of RFC 5246. |
| 237 | |
| 238 | When reading a TLS message, we try to parse as much as we can. |
| 239 | In .pre_dissect(), according to the type of the current cipher algorithm |
| 240 | (self.tls_session.rcs.cipher.type), we extract the 'iv', 'mac', 'pad' and |
| 241 | 'padlen'. Some of these fields may remain blank: for instance, when using |
| 242 | a stream cipher, there is no IV nor any padding. The 'len' should always |
| 243 | hold the length of the ciphered message; for the plaintext version, you |
| 244 | should rely on the additional 'deciphered_len' attribute. |
| 245 | |
| 246 | XXX Fix 'deciphered_len' which should not be defined when failing with |
| 247 | AEAD decryption. This is related to the 'decryption_success' below. |
| 248 | Also, follow this behaviour in record_sslv2.py and record_tls13.py |
| 249 | |
| 250 | Once we have isolated the ciphered message aggregate (which should be one |
| 251 | or several TLS messages of the same type), we try to decipher it. Either we |
| 252 | succeed and store the clear data in 'msg', or we graciously fail with a |
| 253 | CipherError and store the ciphered data in 'msg'. |
| 254 | |
| 255 | Unless the user manually provides the session secrets through the passing |
| 256 | of a 'tls_session', obviously the ciphered messages will not be deciphered. |
| 257 | Indeed, the need for a proper context may also present itself when trying |
| 258 | to parse clear handshake messages. |
| 259 | |
| 260 | For instance, suppose you sniffed the beginning of a DHE-RSA negotiation:: |
| 261 | |
| 262 | t1 = TLS(<client_hello>) |
| 263 | t2 = TLS(<server_hello | certificate | server_key_exchange>) |
| 264 | t3 = TLS(<server_hello | certificate | server_key_exchange>, |
| 265 | tls_session=t1.tls_session) |
| 266 | |
| 267 | (Note that to do things properly, here 't1.tls_session' should actually be |
| 268 | 't1.tls_session.mirror()'. See session.py for explanations.) |
| 269 | |
| 270 | As no context was passed to t2, neither was any client_random. Hence Scapy |
| 271 | will not be able to verify the signature of the server_key_exchange inside |
| 272 | t2. However, it should be able to do so for t3, thanks to the tls_session. |
| 273 | The consequence of not having a complete TLS context is even more obvious |
| 274 | when trying to parse ciphered content, as we described before. |
| 275 | |
| 276 | Thus, in order to parse TLS-protected communications with Scapy: |
| 277 | _either Scapy reads every message from one side of the TLS connection and |
| 278 | builds every message from the other side (as such, it should know the |
| 279 | secrets needed for the generation of the pre_master_secret), while passing |
| 280 | the same tls_session context (this is how our automaton.py mostly works); |
| 281 | _or, if Scapy did not build any TLS message, it has to create a TLS context |
| 282 | and feed it with secrets retrieved by whatever technique. Note that the |
| 283 | knowing the private key of the server certificate will not be sufficient |
| 284 | if a PFS ciphersuite was used. However, if you got a master_secret somehow, |
| 285 | use it with tls_session.(w|r)cs.derive_keys() and leave the rest to Scapy. |
| 286 | |
| 287 | When building a TLS message with raw_stateful, we expect the tls_session to |
| 288 | have the right parameters for ciphering. Else, .post_build() might fail. |
| 289 | """ |
| 290 | __slots__ = ["deciphered_len"] |
| 291 | name = "TLS" |
no test coverage detected