1## This file is part of Scapy 2## Copyright (C) 2007, 2008, 2009 Arnaud Ebalard 3## 2015, 2016, 2017 Maxence Tury 4## This program is published under a GPLv2 license 5 6""" 7Common TLS fields & bindings. 8 9This module covers the record layer, along with the ChangeCipherSpec, Alert and 10ApplicationData submessages. For the Handshake type, see tls_handshake.py. 11 12See the TLS class documentation for more information. 13""" 14 15import struct, traceback 16 17from scapy.config import conf 18from scapy.error import log_runtime 19from scapy.fields import * 20from scapy.compat import * 21from scapy.packet import * 22from scapy.layers.inet import TCP 23from scapy.layers.tls.session import _GenericTLSSessionInheritance 24from scapy.layers.tls.handshake import (_tls_handshake_cls, _TLSHandshake, 25 TLS13ServerHello) 26from scapy.layers.tls.basefields import (_TLSVersionField, _tls_version, 27 _TLSIVField, _TLSMACField, 28 _TLSPadField, _TLSPadLenField, 29 _TLSLengthField, _tls_type) 30from scapy.layers.tls.crypto.pkcs1 import randstring, pkcs_i2osp 31from scapy.layers.tls.crypto.compression import Comp_NULL 32from scapy.layers.tls.crypto.cipher_aead import AEADTagError 33if conf.crypto_valid_advanced: 34 from scapy.layers.tls.crypto.cipher_aead import Cipher_CHACHA20_POLY1305 35from scapy.layers.tls.crypto.cipher_stream import Cipher_NULL 36from scapy.layers.tls.crypto.ciphers import CipherError 37from scapy.layers.tls.crypto.h_mac import HMACError 38 39# Util 40def _tls_version_check(version, min): 41 """Returns if version >= min, or False if version == None""" 42 if version == None: 43 return False 44 return version >= min 45 46############################################################################### 47### TLS Record Protocol ### 48############################################################################### 49 50class _TLSEncryptedContent(Raw): 51 """ 52 When the content of a TLS record (more precisely, a TLSCiphertext) could 53 not be deciphered, we use this class to represent the encrypted data. 54 The MAC will still be parsed from the whole message, even though it could 55 not been verified. When present (depending on cipher type and protocol 56 version), the nonce_explicit, IV and/or padding will also be parsed. 57 """ 58 name = "Encrypted Content" 59 60 61class _TLSMsgListField(PacketListField): 62 """ 63 This is the actual content of the TLS record. As a TLS record may pack 64 multiple sublayer messages (notably, several handshake messages), 65 we inherit from PacketListField. 66 """ 67 def __init__(self, name, default, length_from=None): 68 if not length_from: 69 length_from = self._get_length 70 super(_TLSMsgListField, self).__init__(name, default, cls=None, 71 length_from=length_from) 72 73 def _get_length(self, pkt): 74 if pkt.deciphered_len is None: 75 return pkt.len 76 return pkt.deciphered_len 77 78 def m2i(self, pkt, m): 79 """ 80 Try to parse one of the TLS subprotocols (ccs, alert, handshake or 81 application_data). This is used inside a loop managed by .getfield(). 82 """ 83 cls = Raw 84 if pkt.type == 22: 85 if len(m) >= 1: 86 msgtype = orb(m[0]) 87 cls = _tls_handshake_cls.get(msgtype, Raw) 88 elif pkt.type == 20: 89 cls = TLSChangeCipherSpec 90 elif pkt.type == 21: 91 cls = TLSAlert 92 elif pkt.type == 23: 93 cls = TLSApplicationData 94 95 if cls is Raw: 96 return Raw(m) 97 else: 98 try: 99 return cls(m, tls_session=pkt.tls_session) 100 except: 101 if conf.debug_dissector: 102 raise 103 return Raw(m) 104 105 def getfield(self, pkt, s): 106 """ 107 If the decryption of the content did not fail with a CipherError, 108 we begin a loop on the clear content in order to get as much messages 109 as possible, of the type advertised in the record header. This is 110 notably important for several TLS handshake implementations, which 111 may for instance pack a server_hello, a certificate, a 112 server_key_exchange and a server_hello_done, all in one record. 113 Each parsed message may update the TLS context throught their method 114 .post_dissection_tls_session_update(). 115 116 If the decryption failed with a CipherError, presumably because we 117 missed the session keys, we signal it by returning a 118 _TLSEncryptedContent packet which simply contains the ciphered data. 119 """ 120 l = self.length_from(pkt) 121 lst = [] 122 ret = b"" 123 remain = s 124 if l is not None: 125 remain, ret = s[:l], s[l:] 126 127 if remain == b"": 128 if (((pkt.tls_session.tls_version or 0x0303) > 0x0200) and 129 hasattr(pkt, "type") and pkt.type == 23): 130 return ret, [TLSApplicationData(data=b"")] 131 else: 132 return ret, [Raw(load=b"")] 133 134 if False in six.itervalues(pkt.tls_session.rcs.cipher.ready): 135 return ret, _TLSEncryptedContent(remain) 136 else: 137 while remain: 138 raw_msg = remain 139 p = self.m2i(pkt, remain) 140 if Padding in p: 141 pad = p[Padding] 142 remain = pad.load 143 del(pad.underlayer.payload) 144 if len(remain) != 0: 145 raw_msg = raw_msg[:-len(remain)] 146 else: 147 remain = b"" 148 149 if isinstance(p, _GenericTLSSessionInheritance): 150 if not p.tls_session.frozen: 151 p.post_dissection_tls_session_update(raw_msg) 152 153 lst.append(p) 154 return remain + ret, lst 155 156 def i2m(self, pkt, p): 157 """ 158 Update the context with information from the built packet. 159 If no type was given at the record layer, we try to infer it. 160 """ 161 cur = b"" 162 if isinstance(p, _GenericTLSSessionInheritance): 163 if pkt.type is None: 164 if isinstance(p, TLSChangeCipherSpec): 165 pkt.type = 20 166 elif isinstance(p, TLSAlert): 167 pkt.type = 21 168 elif isinstance(p, _TLSHandshake): 169 pkt.type = 22 170 elif isinstance(p, TLSApplicationData): 171 pkt.type = 23 172 p.tls_session = pkt.tls_session 173 if not pkt.tls_session.frozen: 174 cur = p.raw_stateful() 175 p.post_build_tls_session_update(cur) 176 else: 177 cur = raw(p) 178 else: 179 pkt.type = 23 180 cur = raw(p) 181 return cur 182 183 def addfield(self, pkt, s, val): 184 """ 185 Reconstruct the header because the TLS type may have been updated. 186 Then, append the content. 187 """ 188 res = b"" 189 for p in val: 190 res += self.i2m(pkt, p) 191 if (isinstance(pkt, _GenericTLSSessionInheritance) and 192 _tls_version_check(pkt.tls_session.tls_version, 0x0304) and 193 not isinstance(pkt, TLS13ServerHello)): 194 return s + res 195 if not pkt.type: 196 pkt.type = 0 197 hdr = struct.pack("!B", pkt.type) + s[1:5] 198 return hdr + res 199 200 201class TLS(_GenericTLSSessionInheritance): 202 """ 203 The generic TLS Record message, based on section 6.2 of RFC 5246. 204 205 When reading a TLS message, we try to parse as much as we can. 206 In .pre_dissect(), according to the type of the current cipher algorithm 207 (self.tls_session.rcs.cipher.type), we extract the 'iv', 'mac', 'pad' and 208 'padlen'. Some of these fields may remain blank: for instance, when using 209 a stream cipher, there is no IV nor any padding. The 'len' should always 210 hold the length of the ciphered message; for the plaintext version, you 211 should rely on the additional 'deciphered_len' attribute. 212 213 XXX Fix 'deciphered_len' which should not be defined when failing with 214 AEAD decryption. This is related to the 'decryption_success' below. 215 Also, follow this behaviour in record_sslv2.py and record_tls13.py 216 217 Once we have isolated the ciphered message aggregate (which should be one 218 or several TLS messages of the same type), we try to decipher it. Either we 219 succeed and store the clear data in 'msg', or we graciously fail with a 220 CipherError and store the ciphered data in 'msg'. 221 222 Unless the user manually provides the session secrets through the passing 223 of a 'tls_session', obviously the ciphered messages will not be deciphered. 224 Indeed, the need for a proper context may also present itself when trying 225 to parse clear handshake messages. 226 227 For instance, suppose you sniffed the beginning of a DHE-RSA negotiation: 228 t1 = TLS(<client_hello>) 229 t2 = TLS(<server_hello | certificate | server_key_exchange>) 230 t3 = TLS(<server_hello | certificate | server_key_exchange>, 231 tls_session=t1.tls_session) 232 (Note that to do things properly, here 't1.tls_session' should actually be 233 't1.tls_session.mirror()'. See session.py for explanations.) 234 235 As no context was passed to t2, neither was any client_random. Hence Scapy 236 will not be able to verify the signature of the server_key_exchange inside 237 t2. However, it should be able to do so for t3, thanks to the tls_session. 238 The consequence of not having a complete TLS context is even more obvious 239 when trying to parse ciphered content, as we decribed before. 240 241 Thus, in order to parse TLS-protected communications with Scapy: 242 _either Scapy reads every message from one side of the TLS connection and 243 builds every message from the other side (as such, it should know the 244 secrets needed for the generation of the pre_master_secret), while passing 245 the same tls_session context (this is how our automaton.py mostly works); 246 _or, if Scapy did not build any TLS message, it has to create a TLS context 247 and feed it with secrets retrieved by whatever technique. Note that the 248 knowing the private key of the server certificate will not be sufficient 249 if a PFS ciphersuite was used. However, if you got a master_secret somehow, 250 use it with tls_session.(w|r)cs.derive_keys() and leave the rest to Scapy. 251 252 When building a TLS message with raw_stateful, we expect the tls_session to 253 have the right parameters for ciphering. Else, .post_build() might fail. 254 """ 255 __slots__ = ["deciphered_len"] 256 name = "TLS" 257 fields_desc = [ ByteEnumField("type", None, _tls_type), 258 _TLSVersionField("version", None, _tls_version), 259 _TLSLengthField("len", None), 260 _TLSIVField("iv", None), 261 _TLSMsgListField("msg", []), 262 _TLSMACField("mac", None), 263 _TLSPadField("pad", None), 264 _TLSPadLenField("padlen", None) ] 265 266 def __init__(self, *args, **kargs): 267 self.deciphered_len = kargs.get("deciphered_len", None) 268 super(TLS, self).__init__(*args, **kargs) 269 270 @classmethod 271 def dispatch_hook(cls, _pkt=None, *args, **kargs): 272 """ 273 If the TLS class was called on raw SSLv2 data, we want to return an 274 SSLv2 record instance. We acknowledge the risk of SSLv2 packets with a 275 msglen of 0x1403, 0x1503, 0x1603 or 0x1703 which will never be casted 276 as SSLv2 records but TLS ones instead, but hey, we can't be held 277 responsible for low-minded extensibility choices. 278 """ 279 if _pkt and len(_pkt) >= 2: 280 byte0 = orb(_pkt[0]) 281 byte1 = orb(_pkt[1]) 282 if (byte0 not in _tls_type) or (byte1 != 3): 283 from scapy.layers.tls.record_sslv2 import SSLv2 284 return SSLv2 285 else: 286 s = kargs.get("tls_session", None) 287 if s and _tls_version_check(s.tls_version, 0x0304): 288 if s.rcs and not isinstance(s.rcs.cipher, Cipher_NULL): 289 from scapy.layers.tls.record_tls13 import TLS13 290 return TLS13 291 if _pkt and len(_pkt) < 5: 292 # Layer detected as TLS but too small to be a real packet (len<5). 293 # Those packets appear when sessions are interrupted or to flush buffers. 294 # Scapy should not try to decode them 295 return conf.raw_layer 296 return TLS 297 298 ### Parsing methods 299 300 def _tls_auth_decrypt(self, hdr, s): 301 """ 302 Provided with the record header and AEAD-ciphered data, return the 303 sliced and clear tuple (nonce, TLSCompressed.fragment, mac). Note that 304 we still return the slicing of the original input in case of decryption 305 failure. Also, if the integrity check fails, a warning will be issued, 306 but we still return the sliced (unauthenticated) plaintext. 307 """ 308 try: 309 read_seq_num = struct.pack("!Q", self.tls_session.rcs.seq_num) 310 self.tls_session.rcs.seq_num += 1 311 # self.type and self.version have not been parsed yet, 312 # this is why we need to look into the provided hdr. 313 add_data = read_seq_num + chb(hdr[0]) + hdr[1:3] 314 # Last two bytes of add_data are appended by the return function 315 return self.tls_session.rcs.cipher.auth_decrypt(add_data, s, 316 read_seq_num) 317 except CipherError as e: 318 return e.args 319 except AEADTagError as e: 320 pkt_info = self.firstlayer().summary() 321 log_runtime.info("TLS: record integrity check failed [%s]", pkt_info) 322 return e.args 323 324 def _tls_decrypt(self, s): 325 """ 326 Provided with stream- or block-ciphered data, return the clear version. 327 The cipher should have been updated with the right IV early on, 328 which should not be at the beginning of the input. 329 In case of decryption failure, a CipherError will be raised with 330 the slicing of the original input as first argument. 331 """ 332 return self.tls_session.rcs.cipher.decrypt(s) 333 334 def _tls_hmac_verify(self, hdr, msg, mac): 335 """ 336 Provided with the record header, the TLSCompressed.fragment and the 337 HMAC, return True if the HMAC is correct. If we could not compute the 338 HMAC because the key was missing, there is no sense in verifying 339 anything, thus we also return True. 340 341 Meant to be used with a block cipher or a stream cipher. 342 It would fail with an AEAD cipher, because rcs.hmac would be None. 343 See RFC 5246, section 6.2.3. 344 """ 345 read_seq_num = struct.pack("!Q", self.tls_session.rcs.seq_num) 346 self.tls_session.rcs.seq_num += 1 347 348 mac_len = self.tls_session.rcs.mac_len 349 if mac_len == 0: # should be TLS_NULL_WITH_NULL_NULL 350 return True 351 if len(mac) != mac_len: 352 return False 353 354 alg = self.tls_session.rcs.hmac 355 version = struct.unpack("!H", hdr[1:3])[0] 356 try: 357 if version > 0x300: 358 h = alg.digest(read_seq_num + hdr + msg) 359 elif version == 0x300: 360 h = alg.digest_sslv3(read_seq_num + hdr[:1] + hdr[3:5] + msg) 361 else: 362 raise Exception("Unrecognized version.") 363 except HMACError: 364 h = mac 365 return h == mac 366 367 def _tls_decompress(self, s): 368 """ 369 Provided with the TLSCompressed.fragment, 370 return the TLSPlaintext.fragment. 371 """ 372 alg = self.tls_session.rcs.compression 373 return alg.decompress(s) 374 375 def pre_dissect(self, s): 376 """ 377 Decrypt, verify and decompress the message, 378 i.e. apply the previous methods according to the reading cipher type. 379 If the decryption was successful, 'len' will be the length of the 380 TLSPlaintext.fragment. Else, it should be the length of the 381 _TLSEncryptedContent. 382 """ 383 if len(s) < 5: 384 raise Exception("Invalid record: header is too short.") 385 386 msglen = struct.unpack('!H', s[3:5])[0] 387 hdr, efrag, r = s[:5], s[5:5+msglen], s[msglen+5:] 388 389 iv = mac = pad = b"" 390 self.padlen = None 391 decryption_success = False 392 393 cipher_type = self.tls_session.rcs.cipher.type 394 395 if cipher_type == 'block': 396 version = struct.unpack("!H", s[1:3])[0] 397 398 # Decrypt 399 try: 400 if version >= 0x0302: 401 # Explicit IV for TLS 1.1 and 1.2 402 block_size = self.tls_session.rcs.cipher.block_size 403 iv, efrag = efrag[:block_size], efrag[block_size:] 404 self.tls_session.rcs.cipher.iv = iv 405 pfrag = self._tls_decrypt(efrag) 406 else: 407 # Implicit IV for SSLv3 and TLS 1.0 408 pfrag = self._tls_decrypt(efrag) 409 except CipherError as e: 410 # This will end up dissected as _TLSEncryptedContent. 411 cfrag = e.args[0] 412 else: 413 decryption_success = True 414 # Excerpt below better corresponds to TLS 1.1 IV definition, 415 # but the result is the same as with TLS 1.2 anyway. 416 # This leading *IV* has been decrypted by _tls_decrypt with a 417 # random IV, hence it does not correspond to anything. 418 # What actually matters is that we got the first encrypted block 419 # in order to decrypt the second block (first data block). 420 #if version >= 0x0302: 421 # block_size = self.tls_session.rcs.cipher.block_size 422 # iv, pfrag = pfrag[:block_size], pfrag[block_size:] 423 # l = struct.unpack('!H', hdr[3:5])[0] 424 # hdr = hdr[:3] + struct.pack('!H', l-block_size) 425 426 # Extract padding ('pad' actually includes the trailing padlen) 427 padlen = orb(pfrag[-1]) + 1 428 mfrag, pad = pfrag[:-padlen], pfrag[-padlen:] 429 self.padlen = padlen 430 431 # Extract MAC 432 l = self.tls_session.rcs.mac_len 433 if l != 0: 434 cfrag, mac = mfrag[:-l], mfrag[-l:] 435 else: 436 cfrag, mac = mfrag, b"" 437 438 # Verify integrity 439 chdr = hdr[:3] + struct.pack('!H', len(cfrag)) 440 is_mac_ok = self._tls_hmac_verify(chdr, cfrag, mac) 441 if not is_mac_ok: 442 pkt_info = self.firstlayer().summary() 443 log_runtime.info("TLS: record integrity check failed [%s]", pkt_info) 444 445 elif cipher_type == 'stream': 446 # Decrypt 447 try: 448 pfrag = self._tls_decrypt(efrag) 449 except CipherError as e: 450 # This will end up dissected as _TLSEncryptedContent. 451 cfrag = e.args[0] 452 else: 453 decryption_success = True 454 mfrag = pfrag 455 456 # Extract MAC 457 l = self.tls_session.rcs.mac_len 458 if l != 0: 459 cfrag, mac = mfrag[:-l], mfrag[-l:] 460 else: 461 cfrag, mac = mfrag, b"" 462 463 # Verify integrity 464 chdr = hdr[:3] + struct.pack('!H', len(cfrag)) 465 is_mac_ok = self._tls_hmac_verify(chdr, cfrag, mac) 466 if not is_mac_ok: 467 pkt_info = self.firstlayer().summary() 468 log_runtime.info("TLS: record integrity check failed [%s]", pkt_info) 469 470 elif cipher_type == 'aead': 471 # Authenticated encryption 472 # crypto/cipher_aead.py prints a warning for integrity failure 473 if (conf.crypto_valid_advanced and 474 isinstance(self.tls_session.rcs.cipher, Cipher_CHACHA20_POLY1305)): 475 iv = b"" 476 cfrag, mac = self._tls_auth_decrypt(hdr, efrag) 477 else: 478 iv, cfrag, mac = self._tls_auth_decrypt(hdr, efrag) 479 decryption_success = True # see XXX above 480 481 frag = self._tls_decompress(cfrag) 482 483 if (decryption_success and 484 not isinstance(self.tls_session.rcs.cipher, Cipher_NULL)): 485 self.deciphered_len = len(frag) 486 else: 487 self.deciphered_len = None 488 489 reconstructed_body = iv + frag + mac + pad 490 491 return hdr + reconstructed_body + r 492 493 def post_dissect(self, s): 494 """ 495 Commit the pending r/w state if it has been triggered (e.g. by an 496 underlying TLSChangeCipherSpec or a SSLv2ClientMasterKey). We update 497 nothing if the prcs was not set, as this probably means that we're 498 working out-of-context (and we need to keep the default rcs). 499 """ 500 if self.tls_session.triggered_prcs_commit: 501 if self.tls_session.prcs is not None: 502 self.tls_session.rcs = self.tls_session.prcs 503 self.tls_session.prcs = None 504 self.tls_session.triggered_prcs_commit = False 505 if self.tls_session.triggered_pwcs_commit: 506 if self.tls_session.pwcs is not None: 507 self.tls_session.wcs = self.tls_session.pwcs 508 self.tls_session.pwcs = None 509 self.tls_session.triggered_pwcs_commit = False 510 return s 511 512 def do_dissect_payload(self, s): 513 """ 514 Try to dissect the following data as a TLS message. 515 Note that overloading .guess_payload_class() would not be enough, 516 as the TLS session to be used would get lost. 517 """ 518 if s: 519 try: 520 p = TLS(s, _internal=1, _underlayer=self, 521 tls_session = self.tls_session) 522 except KeyboardInterrupt: 523 raise 524 except: 525 p = conf.raw_layer(s, _internal=1, _underlayer=self) 526 self.add_payload(p) 527 528 529 ### Building methods 530 531 def _tls_compress(self, s): 532 """ 533 Provided with the TLSPlaintext.fragment, 534 return the TLSCompressed.fragment. 535 """ 536 alg = self.tls_session.wcs.compression 537 return alg.compress(s) 538 539 def _tls_auth_encrypt(self, s): 540 """ 541 Return the TLSCiphertext.fragment for AEAD ciphers, i.e. the whole 542 GenericAEADCipher. Also, the additional data is computed right here. 543 """ 544 write_seq_num = struct.pack("!Q", self.tls_session.wcs.seq_num) 545 self.tls_session.wcs.seq_num += 1 546 add_data = (write_seq_num + 547 pkcs_i2osp(self.type, 1) + 548 pkcs_i2osp(self.version, 2) + 549 pkcs_i2osp(len(s), 2)) 550 return self.tls_session.wcs.cipher.auth_encrypt(s, add_data, 551 write_seq_num) 552 553 def _tls_hmac_add(self, hdr, msg): 554 """ 555 Provided with the record header (concatenation of the TLSCompressed 556 type, version and length fields) and the TLSCompressed.fragment, 557 return the concatenation of the TLSCompressed.fragment and the HMAC. 558 559 Meant to be used with a block cipher or a stream cipher. 560 It would fail with an AEAD cipher, because wcs.hmac would be None. 561 See RFC 5246, section 6.2.3. 562 """ 563 write_seq_num = struct.pack("!Q", self.tls_session.wcs.seq_num) 564 self.tls_session.wcs.seq_num += 1 565 566 alg = self.tls_session.wcs.hmac 567 version = struct.unpack("!H", hdr[1:3])[0] 568 if version > 0x300: 569 h = alg.digest(write_seq_num + hdr + msg) 570 elif version == 0x300: 571 h = alg.digest_sslv3(write_seq_num + hdr[:1] + hdr[3:5] + msg) 572 else: 573 raise Exception("Unrecognized version.") 574 return msg + h 575 576 def _tls_pad(self, s): 577 """ 578 Provided with the concatenation of the TLSCompressed.fragment and the 579 HMAC, append the right padding and return it as a whole. 580 This is the TLS-style padding: while SSL allowed for random padding, 581 TLS (misguidedly) specifies the repetition of the same byte all over, 582 and this byte must be equal to len(<entire padding>) - 1. 583 584 Meant to be used with a block cipher only. 585 """ 586 padding = b"" 587 block_size = self.tls_session.wcs.cipher.block_size 588 padlen = block_size - ((len(s) + 1) % block_size) 589 if padlen == block_size: 590 padlen = 0 591 pad_pattern = chb(padlen) 592 padding = pad_pattern * (padlen + 1) 593 return s + padding 594 595 def _tls_encrypt(self, s): 596 """ 597 Return the stream- or block-ciphered version of the concatenated input. 598 In case of GenericBlockCipher, no IV has been specifically prepended to 599 the output, so this might not be the whole TLSCiphertext.fragment yet. 600 """ 601 return self.tls_session.wcs.cipher.encrypt(s) 602 603 def post_build(self, pkt, pay): 604 """ 605 Apply the previous methods according to the writing cipher type. 606 """ 607 # Compute the length of TLSPlaintext fragment 608 hdr, frag = pkt[:5], pkt[5:] 609 l = len(frag) 610 hdr = hdr[:3] + struct.pack("!H", l) 611 612 # Compression 613 cfrag = self._tls_compress(frag) 614 l = len(cfrag) # Update the length as a result of compression 615 hdr = hdr[:3] + struct.pack("!H", l) 616 617 cipher_type = self.tls_session.wcs.cipher.type 618 619 if cipher_type == 'block': 620 # Integrity 621 mfrag = self._tls_hmac_add(hdr, cfrag) 622 623 # Excerpt below better corresponds to TLS 1.1 IV definition, 624 # but the result is the same as with TLS 1.2 anyway. 625 #if self.version >= 0x0302: 626 # l = self.tls_session.wcs.cipher.block_size 627 # iv = randstring(l) 628 # mfrag = iv + mfrag 629 630 # Add padding 631 pfrag = self._tls_pad(mfrag) 632 633 # Encryption 634 if self.version >= 0x0302: 635 # Explicit IV for TLS 1.1 and 1.2 636 l = self.tls_session.wcs.cipher.block_size 637 iv = randstring(l) 638 self.tls_session.wcs.cipher.iv = iv 639 efrag = self._tls_encrypt(pfrag) 640 efrag = iv + efrag 641 else: 642 # Implicit IV for SSLv3 and TLS 1.0 643 efrag = self._tls_encrypt(pfrag) 644 645 elif cipher_type == "stream": 646 # Integrity 647 mfrag = self._tls_hmac_add(hdr, cfrag) 648 # Encryption 649 efrag = self._tls_encrypt(mfrag) 650 651 elif cipher_type == "aead": 652 # Authenticated encryption (with nonce_explicit as header) 653 efrag = self._tls_auth_encrypt(cfrag) 654 655 if self.len is not None: 656 # The user gave us a 'len', let's respect this ultimately 657 hdr = hdr[:3] + struct.pack("!H", self.len) 658 else: 659 # Update header with the length of TLSCiphertext.fragment 660 hdr = hdr[:3] + struct.pack("!H", len(efrag)) 661 662 # Now we commit the pending write state if it has been triggered (e.g. 663 # by an underlying TLSChangeCipherSpec or a SSLv2ClientMasterKey). We 664 # update nothing if the pwcs was not set. This probably means that 665 # we're working out-of-context (and we need to keep the default wcs). 666 if self.tls_session.triggered_pwcs_commit: 667 if self.tls_session.pwcs is not None: 668 self.tls_session.wcs = self.tls_session.pwcs 669 self.tls_session.pwcs = None 670 self.tls_session.triggered_pwcs_commit = False 671 672 return hdr + efrag + pay 673 674 675############################################################################### 676### TLS ChangeCipherSpec ### 677############################################################################### 678 679_tls_changecipherspec_type = { 1: "change_cipher_spec" } 680 681class TLSChangeCipherSpec(_GenericTLSSessionInheritance): 682 """ 683 Note that, as they are not handshake messages, the ccs messages do not get 684 appended to the list of messages whose integrity gets verified through the 685 Finished messages. 686 """ 687 name = "TLS ChangeCipherSpec" 688 fields_desc = [ ByteEnumField("msgtype", 1, _tls_changecipherspec_type) ] 689 690 def post_dissection_tls_session_update(self, msg_str): 691 self.tls_session.triggered_prcs_commit = True 692 693 def post_build_tls_session_update(self, msg_str): 694 # Unlike for dissection case, we cannot commit pending write 695 # state as current write state. We need to delay this after 696 # the ChangeCipherSpec message has indeed been sent 697 self.tls_session.triggered_pwcs_commit = True 698 699 700############################################################################### 701### TLS Alert ### 702############################################################################### 703 704_tls_alert_level = { 1: "warning", 2: "fatal"} 705 706_tls_alert_description = { 707 0: "close_notify", 10: "unexpected_message", 708 20: "bad_record_mac", 21: "decryption_failed", 709 22: "record_overflow", 30: "decompression_failure", 710 40: "handshake_failure", 41: "no_certificate_RESERVED", 711 42: "bad_certificate", 43: "unsupported_certificate", 712 44: "certificate_revoked", 45: "certificate_expired", 713 46: "certificate_unknown", 47: "illegal_parameter", 714 48: "unknown_ca", 49: "access_denied", 715 50: "decode_error", 51: "decrypt_error", 716 60: "export_restriction_RESERVED", 70: "protocol_version", 717 71: "insufficient_security", 80: "internal_error", 718 90: "user_canceled", 100: "no_renegotiation", 719 110: "unsupported_extension", 111: "certificate_unobtainable", 720 112: "unrecognized_name", 113: "bad_certificate_status_response", 721 114: "bad_certificate_hash_value", 115: "unknown_psk_identity" } 722 723class TLSAlert(_GenericTLSSessionInheritance): 724 name = "TLS Alert" 725 fields_desc = [ ByteEnumField("level", None, _tls_alert_level), 726 ByteEnumField("descr", None, _tls_alert_description) ] 727 728 def post_dissection_tls_session_update(self, msg_str): 729 pass 730 731 def post_build_tls_session_update(self, msg_str): 732 pass 733 734 735############################################################################### 736### TLS Application Data ### 737############################################################################### 738 739class TLSApplicationData(_GenericTLSSessionInheritance): 740 name = "TLS Application Data" 741 fields_desc = [ StrField("data", "") ] 742 743 def post_dissection_tls_session_update(self, msg_str): 744 pass 745 746 def post_build_tls_session_update(self, msg_str): 747 pass 748 749 750############################################################################### 751### Bindings ### 752############################################################################### 753 754bind_layers(TCP, TLS, sport=443) 755bind_layers(TCP, TLS, dport=443) 756