1# $Id: ssl.py 90 2014-04-02 22:06:23Z andrewflnr@gmail.com $ 2# Portion Copyright 2012 Google Inc. All rights reserved. 3# -*- coding: utf-8 -*- 4"""Secure Sockets Layer / Transport Layer Security.""" 5from __future__ import absolute_import 6 7import struct 8import binascii 9 10from . import dpkt 11from . import ssl_ciphersuites 12from .compat import compat_ord 13 14# 15# Note from April 2011: cde...@gmail.com added code that parses SSL3/TLS messages more in depth. 16# 17# Jul 2012: afleenor@google.com modified and extended SSL support further. 18# 19 20 21# SSL 2.0 is deprecated in RFC 6176 22class SSL2(dpkt.Packet): 23 __hdr__ = ( 24 ('len', 'H', 0), 25 ) 26 27 def unpack(self, buf): 28 dpkt.Packet.unpack(self, buf) 29 # In SSL, all data sent is encapsulated in a record, an object which is 30 # composed of a header and some non-zero amount of data. Each record header 31 # contains a two or three byte length code. If the most significant bit is 32 # set in the first byte of the record length code then the record has 33 # no padding and the total header length will be 2 bytes, otherwise the 34 # record has padding and the total header length will be 3 bytes. The 35 # record header is transmitted before the data portion of the record. 36 if self.len & 0x8000: 37 n = self.len = self.len & 0x7FFF 38 self.msg, self.data = self.data[:n], self.data[n:] 39 else: 40 # Note that in the long header case (3 bytes total), the second most 41 # significant bit in the first byte has special meaning. When zero, 42 # the record being sent is a data record. When one, the record 43 # being sent is a security escape (there are currently no examples 44 # of security escapes; this is reserved for future versions of the 45 # protocol). In either case, the length code describes how much 46 # data is in the record. 47 n = self.len = self.len & 0x3FFF 48 padlen = compat_ord(self.data[0]) 49 50 self.msg = self.data[1:1 + n] 51 self.pad = self.data[1 + n:1 + n + padlen] 52 self.data = self.data[1 + n + padlen:] 53 54 55# SSL 3.0 is deprecated in RFC 7568 56# Use class TLS for >= SSL 3.0 57class TLS(dpkt.Packet): 58 __hdr__ = ( 59 ('type', 'B', ''), 60 ('version', 'H', ''), 61 ('len', 'H', ''), 62 ) 63 64 def __init__(self, *args, **kwargs): 65 self.records = [] 66 dpkt.Packet.__init__(self, *args, **kwargs) 67 68 def unpack(self, buf): 69 dpkt.Packet.unpack(self, buf) 70 pointer = 0 71 while len(self.data[pointer:]) > 0: 72 end = pointer + 5 + struct.unpack("!H", buf[pointer + 3:pointer + 5])[0] 73 self.records.append(TLSRecord(buf[pointer:end])) 74 pointer = end 75 self.data = self.data[pointer:] 76 77 78# SSLv3/TLS versions 79SSL3_V = 0x0300 80TLS1_V = 0x0301 81TLS11_V = 0x0302 82TLS12_V = 0x0303 83 84ssl3_versions_str = { 85 SSL3_V: 'SSL3', 86 TLS1_V: 'TLS 1.0', 87 TLS11_V: 'TLS 1.1', 88 TLS12_V: 'TLS 1.2' 89} 90 91SSL3_VERSION_BYTES = set((b'\x03\x00', b'\x03\x01', b'\x03\x02', b'\x03\x03')) 92 93 94# Alert levels 95SSL3_AD_WARNING = 1 96SSL3_AD_FATAL = 2 97alert_level_str = { 98 SSL3_AD_WARNING: 'SSL3_AD_WARNING', 99 SSL3_AD_FATAL: 'SSL3_AD_FATAL' 100} 101 102# SSL3 alert descriptions 103SSL3_AD_CLOSE_NOTIFY = 0 104SSL3_AD_UNEXPECTED_MESSAGE = 10 # fatal 105SSL3_AD_BAD_RECORD_MAC = 20 # fatal 106SSL3_AD_DECOMPRESSION_FAILURE = 30 # fatal 107SSL3_AD_HANDSHAKE_FAILURE = 40 # fatal 108SSL3_AD_NO_CERTIFICATE = 41 109SSL3_AD_BAD_CERTIFICATE = 42 110SSL3_AD_UNSUPPORTED_CERTIFICATE = 43 111SSL3_AD_CERTIFICATE_REVOKED = 44 112SSL3_AD_CERTIFICATE_EXPIRED = 45 113SSL3_AD_CERTIFICATE_UNKNOWN = 46 114SSL3_AD_ILLEGAL_PARAMETER = 47 # fatal 115 116# TLS1 alert descriptions 117TLS1_AD_DECRYPTION_FAILED = 21 118TLS1_AD_RECORD_OVERFLOW = 22 119TLS1_AD_UNKNOWN_CA = 48 # fatal 120TLS1_AD_ACCESS_DENIED = 49 # fatal 121TLS1_AD_DECODE_ERROR = 50 # fatal 122TLS1_AD_DECRYPT_ERROR = 51 123TLS1_AD_EXPORT_RESTRICTION = 60 # fatal 124TLS1_AD_PROTOCOL_VERSION = 70 # fatal 125TLS1_AD_INSUFFICIENT_SECURITY = 71 # fatal 126TLS1_AD_INTERNAL_ERROR = 80 # fatal 127TLS1_AD_USER_CANCELLED = 90 128TLS1_AD_NO_RENEGOTIATION = 100 129# /* codes 110-114 are from RFC3546 */ 130TLS1_AD_UNSUPPORTED_EXTENSION = 110 131TLS1_AD_CERTIFICATE_UNOBTAINABLE = 111 132TLS1_AD_UNRECOGNIZED_NAME = 112 133TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE = 113 134TLS1_AD_BAD_CERTIFICATE_HASH_VALUE = 114 135TLS1_AD_UNKNOWN_PSK_IDENTITY = 115 # fatal 136 137 138# Mapping alert types to strings 139alert_description_str = { 140 SSL3_AD_CLOSE_NOTIFY: 'SSL3_AD_CLOSE_NOTIFY', 141 SSL3_AD_UNEXPECTED_MESSAGE: 'SSL3_AD_UNEXPECTED_MESSAGE', 142 SSL3_AD_BAD_RECORD_MAC: 'SSL3_AD_BAD_RECORD_MAC', 143 SSL3_AD_DECOMPRESSION_FAILURE: 'SSL3_AD_DECOMPRESSION_FAILURE', 144 SSL3_AD_HANDSHAKE_FAILURE: 'SSL3_AD_HANDSHAKE_FAILURE', 145 SSL3_AD_NO_CERTIFICATE: 'SSL3_AD_NO_CERTIFICATE', 146 SSL3_AD_BAD_CERTIFICATE: 'SSL3_AD_BAD_CERTIFICATE', 147 SSL3_AD_UNSUPPORTED_CERTIFICATE: 'SSL3_AD_UNSUPPORTED_CERTIFICATE', 148 SSL3_AD_CERTIFICATE_REVOKED: 'SSL3_AD_CERTIFICATE_REVOKED', 149 SSL3_AD_CERTIFICATE_EXPIRED: 'SSL3_AD_CERTIFICATE_EXPIRED', 150 SSL3_AD_CERTIFICATE_UNKNOWN: 'SSL3_AD_CERTIFICATE_UNKNOWN', 151 SSL3_AD_ILLEGAL_PARAMETER: 'SSL3_AD_ILLEGAL_PARAMETER', 152 TLS1_AD_DECRYPTION_FAILED: 'TLS1_AD_DECRYPTION_FAILED', 153 TLS1_AD_RECORD_OVERFLOW: 'TLS1_AD_RECORD_OVERFLOW', 154 TLS1_AD_UNKNOWN_CA: 'TLS1_AD_UNKNOWN_CA', 155 TLS1_AD_ACCESS_DENIED: 'TLS1_AD_ACCESS_DENIED', 156 TLS1_AD_DECODE_ERROR: 'TLS1_AD_DECODE_ERROR', 157 TLS1_AD_DECRYPT_ERROR: 'TLS1_AD_DECRYPT_ERROR', 158 TLS1_AD_EXPORT_RESTRICTION: 'TLS1_AD_EXPORT_RESTRICTION', 159 TLS1_AD_PROTOCOL_VERSION: 'TLS1_AD_PROTOCOL_VERSION', 160 TLS1_AD_INSUFFICIENT_SECURITY: 'TLS1_AD_INSUFFICIENT_SECURITY', 161 TLS1_AD_INTERNAL_ERROR: 'TLS1_AD_INTERNAL_ERROR', 162 TLS1_AD_USER_CANCELLED: 'TLS1_AD_USER_CANCELLED', 163 TLS1_AD_NO_RENEGOTIATION: 'TLS1_AD_NO_RENEGOTIATION', 164 TLS1_AD_UNSUPPORTED_EXTENSION: 'TLS1_AD_UNSUPPORTED_EXTENSION', 165 TLS1_AD_CERTIFICATE_UNOBTAINABLE: 'TLS1_AD_CERTIFICATE_UNOBTAINABLE', 166 TLS1_AD_UNRECOGNIZED_NAME: 'TLS1_AD_UNRECOGNIZED_NAME', 167 TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: 'TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE', 168 TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: 'TLS1_AD_BAD_CERTIFICATE_HASH_VALUE', 169 TLS1_AD_UNKNOWN_PSK_IDENTITY: 'TLS1_AD_UNKNOWN_PSK_IDENTITY' 170} 171 172 173# struct format strings for parsing buffer lengths 174# don't forget, you have to pad a 3-byte value with \x00 175_SIZE_FORMATS = ['!B', '!H', '!I', '!I'] 176 177 178def parse_variable_array(buf, lenbytes): 179 """ 180 Parse an array described using the 'Type name<x..y>' syntax from the spec 181 Read a length at the start of buf, and returns that many bytes 182 after, in a tuple with the TOTAL bytes consumed (including the size). This 183 does not check that the array is the right length for any given datatype. 184 """ 185 # first have to figure out how to parse length 186 assert lenbytes <= 4 # pretty sure 4 is impossible, too 187 size_format = _SIZE_FORMATS[lenbytes - 1] 188 padding = b'\x00' if lenbytes == 3 else b'' 189 # read off the length 190 size = struct.unpack(size_format, padding + buf[:lenbytes])[0] 191 # read the actual data 192 data = buf[lenbytes:lenbytes + size] 193 # if len(data) != size: insufficient data 194 return data, size + lenbytes 195 196 197def parse_extensions(buf): 198 """ 199 Parse TLS extensions in passed buf. Returns an ordered list of extension tuples with 200 ordinal extension type as first value and extension data as second value. 201 Passed buf must start with the 2-byte extensions length TLV. 202 http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml 203 """ 204 extensions_length = struct.unpack('!H', buf[:2])[0] 205 extensions = [] 206 207 pointer = 2 208 while pointer < extensions_length: 209 ext_type = struct.unpack('!H', buf[pointer:pointer + 2])[0] 210 pointer += 2 211 ext_data, parsed = parse_variable_array(buf[pointer:], 2) 212 extensions.append((ext_type, ext_data)) 213 pointer += parsed 214 return extensions 215 216 217class SSL3Exception(Exception): 218 pass 219 220 221class TLSRecord(dpkt.Packet): 222 """ 223 SSLv3 or TLSv1+ packet. 224 225 In addition to the fields specified in the header, there are 226 compressed and decrypted fields, indicating whether, in the language 227 of the spec, this is a TLSPlaintext, TLSCompressed, or 228 TLSCiphertext. The application will have to figure out when it's 229 appropriate to change these values. 230 """ 231 232 __hdr__ = ( 233 ('type', 'B', 0), 234 ('version', 'H', 0), 235 ('length', 'H', 0), 236 ) 237 238 def __init__(self, *args, **kwargs): 239 # assume plaintext unless specified otherwise in arguments 240 self.compressed = kwargs.pop('compressed', False) 241 self.encrypted = kwargs.pop('encrypted', False) 242 # parent constructor 243 dpkt.Packet.__init__(self, *args, **kwargs) 244 # make sure length and data are consistent 245 self.length = len(self.data) 246 247 def unpack(self, buf): 248 dpkt.Packet.unpack(self, buf) 249 header_length = self.__hdr_len__ 250 self.data = buf[header_length:header_length + self.length] 251 # make sure buffer was long enough 252 if len(self.data) != self.length: 253 raise dpkt.NeedData('TLSRecord data was too short.') 254 # assume compressed and encrypted when it's been parsed from 255 # raw data 256 self.compressed = True 257 self.encrypted = True 258 259 260class TLSChangeCipherSpec(dpkt.Packet): 261 """ 262 ChangeCipherSpec message is just a single byte with value 1 263 """ 264 __hdr__ = (('type', 'B', 1),) 265 266 267class TLSAppData(str): 268 """ 269 As far as TLSRecord is concerned, AppData is just an opaque blob. 270 """ 271 pass 272 273 274class TLSAlert(dpkt.Packet): 275 __hdr__ = ( 276 ('level', 'B', 1), 277 ('description', 'B', 0), 278 ) 279 280 281class TLSHelloRequest(dpkt.Packet): 282 __hdr__ = tuple() 283 284 285class TLSClientHello(dpkt.Packet): 286 __hdr__ = ( 287 ('version', 'H', 0x0301), 288 ('random', '32s', '\x00' * 32), 289 ) # the rest is variable-length and has to be done manually 290 291 def unpack(self, buf): 292 dpkt.Packet.unpack(self, buf) 293 # now session, cipher suites, extensions are in self.data 294 self.session_id, pointer = parse_variable_array(self.data, 1) 295 # print 'pointer',pointer 296 # handle ciphersuites 297 ciphersuites, parsed = parse_variable_array(self.data[pointer:], 2) 298 pointer += parsed 299 num_ciphersuites = int(len(ciphersuites) / 2) 300 try: 301 self.ciphersuites = [ 302 ssl_ciphersuites.BY_CODE[code] for code in struct.unpack('!' + num_ciphersuites * 'H', ciphersuites)] 303 except KeyError as e: 304 raise SSL3Exception('Unknown or invalid cipher suite type %x' % int(e.args[0])) 305 # check len(ciphersuites) % 2 == 0 ? 306 # compression methods 307 compression_methods, parsed = parse_variable_array(self.data[pointer:], 1) 308 pointer += parsed 309 self.compression_methods = struct.unpack('{0}B'.format(len(compression_methods)), compression_methods) 310 # Parse extensions if present 311 if len(self.data[pointer:]) >= 6: 312 self.extensions = parse_extensions(self.data[pointer:]) 313 314 315class TLSServerHello(dpkt.Packet): 316 __hdr__ = ( 317 ('version', 'H', '0x0301'), 318 ('random', '32s', '\x00' * 32), 319 ) # session is variable, forcing rest to be manual 320 321 def unpack(self, buf): 322 try: 323 dpkt.Packet.unpack(self, buf) 324 self.session_id, pointer = parse_variable_array(self.data, 1) 325 # single cipher suite 326 try: 327 code = struct.unpack('!H', self.data[pointer:pointer + 2])[0] 328 self.cipher_suite = ssl_ciphersuites.BY_CODE[code] 329 except KeyError as e: 330 raise SSL3Exception('Unknown or invalid cipher suite type %x' % int(e.args[0])) 331 pointer += 2 332 # single compression method 333 self.compression = struct.unpack('!B', self.data[pointer:pointer + 1])[0] 334 pointer += 1 335 # Parse extensions if present 336 if len(self.data[pointer:]) >= 6: 337 self.extensions = parse_extensions(self.data[pointer:]) 338 except struct.error: 339 # probably data too short 340 raise dpkt.NeedData 341 342 343class TLSCertificate(dpkt.Packet): 344 __hdr__ = tuple() 345 346 def unpack(self, buf): 347 try: 348 dpkt.Packet.unpack(self, buf) 349 all_certs, all_certs_len = parse_variable_array(self.data, 3) 350 self.certificates = [] 351 pointer = 3 352 while pointer < all_certs_len: 353 cert, parsed = parse_variable_array(self.data[pointer:], 3) 354 self.certificates.append((cert)) 355 pointer += parsed 356 except struct.error: 357 raise dpkt.NeedData 358 359 360class TLSUnknownHandshake(dpkt.Packet): 361 __hdr__ = tuple() 362 363 364TLSNewSessionTicket = TLSUnknownHandshake 365TLSServerKeyExchange = TLSUnknownHandshake 366TLSCertificateRequest = TLSUnknownHandshake 367TLSServerHelloDone = TLSUnknownHandshake 368TLSCertificateVerify = TLSUnknownHandshake 369TLSClientKeyExchange = TLSUnknownHandshake 370TLSFinished = TLSUnknownHandshake 371 372 373# mapping of handshake type ids to their names 374# and the classes that implement them 375HANDSHAKE_TYPES = { 376 0: ('HelloRequest', TLSHelloRequest), 377 1: ('ClientHello', TLSClientHello), 378 2: ('ServerHello', TLSServerHello), 379 4: ('NewSessionTicket', TLSNewSessionTicket), 380 11: ('Certificate', TLSCertificate), 381 12: ('ServerKeyExchange', TLSServerKeyExchange), 382 13: ('CertificateRequest', TLSCertificateRequest), 383 14: ('ServerHelloDone', TLSServerHelloDone), 384 15: ('CertificateVerify', TLSCertificateVerify), 385 16: ('ClientKeyExchange', TLSClientKeyExchange), 386 20: ('Finished', TLSFinished), 387} 388 389 390class TLSHandshake(dpkt.Packet): 391 """ 392 A TLS Handshake message 393 394 This goes for all messages encapsulated in the Record layer, but especially 395 important for handshakes and app data: A message may be spread across a 396 number of TLSRecords, in addition to the possibility of there being more 397 than one in a given Record. You have to put together the contents of 398 TLSRecord's yourself. 399 """ 400 401 # struct.unpack can't handle the 3-byte int, so we parse it as bytes 402 # (and store it as bytes so dpkt doesn't get confused), and turn it into 403 # an int in a user-facing property 404 __hdr__ = ( 405 ('type', 'B', 0), 406 ('length_bytes', '3s', 0), 407 ) 408 409 def unpack(self, buf): 410 dpkt.Packet.unpack(self, buf) 411 # Wait, might there be more than one message of self.type? 412 embedded_type = HANDSHAKE_TYPES.get(self.type, None) 413 if embedded_type is None: 414 raise SSL3Exception('Unknown or invalid handshake type %d' % 415 self.type) 416 # only take the right number of bytes 417 self.data = self.data[:self.length] 418 if len(self.data) != self.length: 419 raise dpkt.NeedData 420 # get class out of embedded_type tuple 421 self.data = embedded_type[1](self.data) 422 423 @property 424 def length(self): 425 return struct.unpack('!I', b'\x00' + self.length_bytes)[0] 426 427 428RECORD_TYPES = { 429 20: TLSChangeCipherSpec, 430 21: TLSAlert, 431 22: TLSHandshake, 432 23: TLSAppData, 433} 434 435 436class SSLFactory(object): 437 def __new__(cls, buf): 438 v = buf[1:3] 439 if v in SSL3_VERSION_BYTES: 440 return TLSRecord(buf) 441 # SSL2 has no characteristic header or magic bytes, so we just assume 442 # that the msg is an SSL2 msg if it is not detected as SSL3+ 443 return SSL2(buf) 444 445 446def tls_multi_factory(buf): 447 """ 448 Attempt to parse one or more TLSRecord's out of buf 449 450 Args: 451 buf: string containing SSL/TLS messages. May have an incomplete record 452 on the end 453 454 Returns: 455 [TLSRecord] 456 int, total bytes consumed, != len(buf) if an incomplete record was left at 457 the end. 458 459 Raises SSL3Exception. 460 """ 461 i, n = 0, len(buf) 462 msgs = [] 463 while i + 5 <= n: 464 v = buf[i + 1:i + 3] 465 if v in SSL3_VERSION_BYTES: 466 try: 467 msg = TLSRecord(buf[i:]) 468 msgs.append(msg) 469 except dpkt.NeedData: 470 break 471 else: 472 raise SSL3Exception('Bad TLS version in buf: %r' % buf[i:i + 5]) 473 i += len(msg) 474 return msgs, i 475 476 477_hexdecode = binascii.a2b_hex 478 479 480class TestTLS(object): 481 """ 482 Test basic TLS functionality. 483 Test that each TLSRecord is correctly discovered and added to TLS.records 484 """ 485 486 @classmethod 487 def setup_class(cls): 488 cls.p = TLS( 489 b'\x16\x03\x00\x02\x06\x01\x00\x02\x02\x03\x03\x58\x5c\x2f\xf7\x2a\x65\x99\x49\x87\x71\xf5' 490 b'\x95\x14\xf1\x0a\xf6\x8c\x68\xf9\xef\x30\xd0\xda\xdc\x9e\x1a\xf6\x4d\x10\x91\x47\x6a\x00' 491 b'\x00\x84\xc0\x2b\xc0\x2c\xc0\x86\xc0\x87\xc0\x09\xc0\x23\xc0\x0a\xc0\x24\xc0\x72\xc0\x73' 492 b'\xc0\x08\xc0\x07\xc0\x2f\xc0\x30\xc0\x8a\xc0\x8b\xc0\x13\xc0\x27\xc0\x14\xc0\x28\xc0\x76' 493 b'\xc0\x77\xc0\x12\xc0\x11\x00\x9c\x00\x9d\xc0\x7a\xc0\x7b\x00\x2f\x00\x3c\x00\x35\x00\x3d' 494 b'\x00\x41\x00\xba\x00\x84\x00\xc0\x00\x0a\x00\x05\x00\x04\x00\x9e\x00\x9f\xc0\x7c\xc0\x7d' 495 b'\x00\x33\x00\x67\x00\x39\x00\x6b\x00\x45\x00\xbe\x00\x88\x00\xc4\x00\x16\x00\xa2\x00\xa3' 496 b'\xc0\x80\xc0\x81\x00\x32\x00\x40\x00\x38\x00\x6a\x00\x44\x00\xbd\x00\x87\x00\xc3\x00\x13' 497 b'\x00\x66\x01\x00\x01\x55\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\x00\x00\x11\x00\x0f\x00' 498 b'\x00\x0c\x77\x77\x77\x2e\x69\x61\x6e\x61\x2e\x6f\x72\x67\xff\x01\x00\x01\x00\x00\x23\x00' 499 b'\x00\x00\x0a\x00\x0c\x00\x0a\x00\x13\x00\x15\x00\x17\x00\x18\x00\x19\x00\x0b\x00\x02\x01' 500 b'\x00\x00\x0d\x00\x1c\x00\x1a\x04\x01\x04\x02\x04\x03\x05\x01\x05\x03\x06\x01\x06\x03\x03' 501 b'\x01\x03\x02\x03\x03\x02\x01\x02\x02\x02\x03\x00\x15\x00\xf4\x00\xf2\x00\x00\x00\x00\x00' 502 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 503 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 504 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 505 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 506 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 507 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 508 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 509 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 510 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 511 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 512 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 513 ) 514 515 def test_records_length(self): 516 assert (len(self.p.records) == 1) 517 518 def test_record_type(self): 519 assert (self.p.records[0].type == 22) 520 521 def test_record_version(self): 522 assert (self.p.records[0].version == 768) 523 524 525class TestTLSRecord(object): 526 """ 527 Test basic TLSRecord functionality 528 For this test, the contents of the record doesn't matter, since we're not parsing the next layer. 529 """ 530 531 @classmethod 532 def setup_class(cls): 533 # add some extra data, to make sure length is parsed correctly 534 cls.p = TLSRecord(b'\x17\x03\x01\x00\x08abcdefghzzzzzzzzzzz') 535 536 def test_content_type(self): 537 assert (self.p.type == 23) 538 539 def test_version(self): 540 assert (self.p.version == 0x0301) 541 542 def test_length(self): 543 assert (self.p.length == 8) 544 545 def test_data(self): 546 assert (self.p.data == b'abcdefgh') 547 548 def test_initial_flags(self): 549 assert (self.p.compressed is True) 550 assert (self.p.encrypted is True) 551 552 def test_repack(self): 553 p2 = TLSRecord(type=23, version=0x0301, data=b'abcdefgh') 554 assert (p2.type == 23) 555 assert (p2.version == 0x0301) 556 assert (p2.length == 8) 557 assert (p2.data == b'abcdefgh') 558 assert (p2.pack() == self.p.pack()) 559 560 def test_total_length(self): 561 # that len(p) includes header 562 assert (len(self.p) == 13) 563 564 def test_raises_need_data_when_buf_is_short(self): 565 import pytest 566 pytest.raises(dpkt.NeedData, TLSRecord, b'\x16\x03\x01\x00\x10abc') 567 568 569class TestTLSChangeCipherSpec(object): 570 """It's just a byte. This will be quick, I promise""" 571 572 @classmethod 573 def setup_class(cls): 574 cls.p = TLSChangeCipherSpec(b'\x01') 575 576 def test_parses(self): 577 assert (self.p.type == 1) 578 579 def test_total_length(self): 580 assert (len(self.p) == 1) 581 582 583class TestTLSAppData(object): 584 """AppData is basically just a string""" 585 586 def test_value(self): 587 d = TLSAppData('abcdefgh') 588 assert (d == 'abcdefgh') 589 590 591class TestTLSHandshake(object): 592 @classmethod 593 def setup_class(cls): 594 cls.h = TLSHandshake(b'\x00\x00\x00\x01\xff') 595 596 def test_created_inside_message(self): 597 assert (isinstance(self.h.data, TLSHelloRequest) is True) 598 599 def test_length(self): 600 assert (self.h.length == 0x01) 601 602 def test_raises_need_data(self): 603 import pytest 604 pytest.raises(dpkt.NeedData, TLSHandshake, b'\x00\x00\x01\x01') 605 606 607class TestClientHello(object): 608 """This data is extracted from and verified by Wireshark""" 609 610 @classmethod 611 def setup_class(cls): 612 cls.data = _hexdecode( 613 b"01000199" # handshake header 614 b"0301" # version 615 b"5008220ce5e0e78b6891afe204498c9363feffbe03235a2d9e05b7d990eb708d" # rand 616 b"2009bc0192e008e6fa8fe47998fca91311ba30ddde14a9587dc674b11c3d3e5ed1" # session id 617 # cipher suites 618 b"005200ffc00ac0140088008700390038c00fc00500840035c007c009c011c0130045004400330032" 619 b"c00cc00ec002c0040096004100050004002fc008c01200160013c00dc003000ac006c010c00bc00100020001" 620 b"0100" # compresssion methods 621 # extensions 622 b"00fc0000000e000c0000096c6f63616c686f7374000a00080006001700180019000b000201000023" 623 b"00d0a50b2e9f618a9ea9bf493ef49b421835cd2f6b05bbe1179d8edf70d58c33d656e8696d36d7e7" 624 b"e0b9d3ecc0e4de339552fa06c64c0fcb550a334bc43944e2739ca342d15a9ebbe981ac87a0d38160" 625 b"507d47af09bdc16c5f0ee4cdceea551539382333226048a026d3a90a0535f4a64236467db8fee22b" 626 b"041af986ad0f253bc369137cd8d8cd061925461d7f4d7895ca9a4181ab554dad50360ac31860e971" 627 b"483877c9335ac1300c5e78f3e56f3b8e0fc16358fcaceefd5c8d8aaae7b35be116f8832856ca6114" 628 b"4fcdd95e071b94d0cf7233740000" 629 b"FFFFFFFFFFFFFFFF") # random garbage 630 cls.p = TLSHandshake(cls.data) 631 632 def test_client_hello_constructed(self): 633 """Make sure the correct class was constructed""" 634 # print self.p 635 assert (isinstance(self.p.data, TLSClientHello) is True) 636 637 # def testClientDateCorrect(self): 638 # self.assertEqual(self.p.random_unixtime, 1342710284) 639 640 def test_client_random_correct(self): 641 assert (self.p.data.random == _hexdecode(b'5008220ce5e0e78b6891afe204498c9363feffbe03235a2d9e05b7d990eb708d')) 642 643 def test_cipher_suite(self): 644 assert (tuple([c.code for c in self.p.data.ciphersuites]) == struct.unpack('!{0}H'.format( 645 len(self.p.data.ciphersuites)), _hexdecode( 646 b'00ffc00ac0140088008700390038c00fc00500840035c007c009c011c0130045004400330032c00c' 647 b'c00ec002c0040096004100050004002fc008c01200160013c00dc003000ac006c010c00bc00100020001'))) 648 assert (len(self.p.data.ciphersuites) == 41) 649 650 def test_session_id(self): 651 assert (self.p.data.session_id == _hexdecode(b'09bc0192e008e6fa8fe47998fca91311ba30ddde14a9587dc674b11c3d3e5ed1')) 652 653 def test_compression_methods(self): 654 assert (list(self.p.data.compression_methods) == [0x00, ]) 655 656 def test_total_length(self): 657 assert (len(self.p) == 413) 658 659 660class TestServerHello(object): 661 """Again, from Wireshark""" 662 663 @classmethod 664 def setup_class(cls): 665 cls.data = _hexdecode( 666 b'0200004d03015008220c8ec43c5462315a7c99f5d5b6bff009ad285b51dc18485f352e9fdecd2009' 667 b'bc0192e008e6fa8fe47998fca91311ba30ddde14a9587dc674b11c3d3e5ed10002000005ff01000100') 668 cls.p = TLSHandshake(cls.data) 669 670 def test_constructed(self): 671 assert (isinstance(self.p.data, TLSServerHello) is True) 672 673 # def testDateCorrect(self): 674 # self.assertEqual(self.p.random_unixtime, 1342710284) 675 676 def test_random_correct(self): 677 assert (self.p.data.random == _hexdecode(b'5008220c8ec43c5462315a7c99f5d5b6bff009ad285b51dc18485f352e9fdecd')) 678 679 def test_cipher_suite(self): 680 assert (self.p.data.cipher_suite.name == 'TLS_RSA_WITH_NULL_SHA') 681 682 def test_total_length(self): 683 assert (len(self.p) == 81) 684 685 686class TestTLSCertificate(object): 687 """We use a 2016 certificate record from iana.org as test data.""" 688 689 @classmethod 690 def setup_class(cls): 691 cls.p = TLSHandshake( 692 b'\x0b\x00\x0b\x45\x00\x0b\x42\x00\x06\x87\x30\x82\x06\x83\x30\x82\x05\x6b\xa0\x03\x02\x01\x02\x02\x10\x09\xca' 693 b'\xbb\xe2\x19\x1c\x8f\x56\x9d\xd4\xb6\xdd\x25\x0f\x21\xd8\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b' 694 b'\x05\x00\x30\x70\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x15\x30\x13\x06\x03\x55\x04\x0a\x13' 695 b'\x0c\x44\x69\x67\x69\x43\x65\x72\x74\x20\x49\x6e\x63\x31\x19\x30\x17\x06\x03\x55\x04\x0b\x13\x10\x77\x77\x77' 696 b'\x2e\x64\x69\x67\x69\x63\x65\x72\x74\x2e\x63\x6f\x6d\x31\x2f\x30\x2d\x06\x03\x55\x04\x03\x13\x26\x44\x69\x67' 697 b'\x69\x43\x65\x72\x74\x20\x53\x48\x41\x32\x20\x48\x69\x67\x68\x20\x41\x73\x73\x75\x72\x61\x6e\x63\x65\x20\x53' 698 b'\x65\x72\x76\x65\x72\x20\x43\x41\x30\x1e\x17\x0d\x31\x34\x31\x30\x32\x37\x30\x30\x30\x30\x30\x30\x5a\x17\x0d' 699 b'\x31\x38\x30\x31\x30\x33\x31\x32\x30\x30\x30\x30\x5a\x30\x81\xa3\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02' 700 b'\x55\x53\x31\x13\x30\x11\x06\x03\x55\x04\x08\x13\x0a\x43\x61\x6c\x69\x66\x6f\x72\x6e\x69\x61\x31\x14\x30\x12' 701 b'\x06\x03\x55\x04\x07\x13\x0b\x4c\x6f\x73\x20\x41\x6e\x67\x65\x6c\x65\x73\x31\x3c\x30\x3a\x06\x03\x55\x04\x0a' 702 b'\x13\x33\x49\x6e\x74\x65\x72\x6e\x65\x74\x20\x43\x6f\x72\x70\x6f\x72\x61\x74\x69\x6f\x6e\x20\x66\x6f\x72\x20' 703 b'\x41\x73\x73\x69\x67\x6e\x65\x64\x20\x4e\x61\x6d\x65\x73\x20\x61\x6e\x64\x20\x4e\x75\x6d\x62\x65\x72\x73\x31' 704 b'\x16\x30\x14\x06\x03\x55\x04\x0b\x13\x0d\x49\x54\x20\x4f\x70\x65\x72\x61\x74\x69\x6f\x6e\x73\x31\x13\x30\x11' 705 b'\x06\x03\x55\x04\x03\x0c\x0a\x2a\x2e\x69\x61\x6e\x61\x2e\x6f\x72\x67\x30\x82\x02\x22\x30\x0d\x06\x09\x2a\x86' 706 b'\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x02\x0f\x00\x30\x82\x02\x0a\x02\x82\x02\x01\x00\x9d\xbd\xfd\xde' 707 b'\xb5\xca\xe5\x3a\x55\x97\x47\xe2\xfd\xa6\x37\x28\xe4\xab\xa6\x0f\x18\xb7\x9a\x69\xf0\x33\x10\xbf\x01\x64\xe5' 708 b'\xee\x7d\xb6\xb1\x5b\xf5\x6d\xf2\x3f\xdd\xba\xe6\xa1\xbb\x38\x44\x9b\x8c\x88\x3f\x18\x10\x2b\xbd\x8b\xb6\x55' 709 b'\xac\x0e\x2d\xac\x2e\xe3\xed\x5c\xf4\x31\x58\x68\xd2\xc5\x98\x06\x82\x84\x85\x4b\x24\x89\x4d\xcd\x4b\xd3\x78' 710 b'\x11\xf0\xad\x3a\x28\x2c\xd4\xb4\xe5\x99\xff\xd0\x7d\x8d\x2d\x3f\x24\x78\x55\x4f\x81\x02\x0b\x32\x0e\xe1\x2f' 711 b'\x44\x94\x8e\x2e\xa1\xed\xbc\x99\x0b\x83\x0c\xa5\xcc\xa6\xb4\xa8\x39\xfb\x27\xb5\x18\x50\xc9\x84\x7e\xac\x74' 712 b'\xf2\x66\x09\xeb\x24\x36\x5b\x97\x51\xfb\x1c\x32\x08\xf5\x69\x13\xba\xcb\xca\xe4\x92\x01\x34\x7c\x78\xb7\xe5' 713 b'\x4a\x9d\x99\x97\x94\x04\xc3\x7f\x00\xfb\x65\xdb\x84\x9f\xd7\x5e\x3a\x68\x77\x0c\x30\xf2\xab\xe6\x5b\x33\x25' 714 b'\x6f\xb5\x9b\x45\x00\x50\xb0\x0d\x81\x39\xd4\xd8\x0d\x36\xf7\xbc\x46\xda\xf3\x03\xe4\x8f\x0f\x07\x91\xb2\xfd' 715 b'\xd7\x2e\xc6\x0b\x2c\xb3\xad\x53\x3c\x3f\x28\x8c\x9c\x19\x4e\x49\x33\x7a\x69\xc4\x96\x73\x1f\x08\x6d\x4f\x1f' 716 b'\x98\x25\x90\x07\x13\xe2\xa5\x51\xd0\x5c\xb6\x05\x75\x67\x85\x0d\x91\xe6\x00\x1c\x4c\xe2\x71\x76\xf0\x95\x78' 717 b'\x73\xa9\x5b\x88\x0a\xcb\xec\x19\xe7\xbd\x9b\xcf\x12\x86\xd0\x45\x2b\x73\x78\x9c\x41\x90\x5d\xd4\x70\x97\x1c' 718 b'\xd7\x3a\xea\x52\xc7\x7b\x08\x0c\xd7\x79\xaf\x58\x23\x4f\x33\x72\x25\xc2\x6f\x87\xa8\xc1\x3e\x2a\x65\xe9\xdd' 719 b'\x4e\x03\xa5\xb4\x1d\x7e\x06\xb3\x35\x3f\x38\x12\x9b\x23\x27\xa5\x31\xec\x96\x27\xa2\x1d\xc4\x23\x73\x3a\xa0' 720 b'\x29\xd4\x98\x94\x48\xba\x33\x22\x89\x1c\x1a\x56\x90\xdd\xf2\xd2\x5c\x8e\xc8\xaa\xa8\x94\xb1\x4a\xa9\x21\x30' 721 b'\xc6\xb6\xd9\x69\xa2\x1f\xf6\x71\xb6\x0c\x4c\x92\x3a\x94\xa9\x3e\xa1\xdd\x04\x92\xc9\x33\x93\xca\x6e\xdd\x61' 722 b'\xf3\x3c\xa7\x7e\x92\x08\xd0\x1d\x6b\xd1\x51\x07\x66\x2e\xc0\x88\x73\x3d\xf4\xc8\x76\xa7\xe1\x60\x8b\x82\x97' 723 b'\x3a\x0f\x75\x92\xe8\x4e\xd1\x55\x79\xd1\x81\xe7\x90\x24\xae\x8a\x7e\x4b\x9f\x00\x78\xeb\x20\x05\xb2\x3f\x9d' 724 b'\x09\xa1\xdf\x1b\xbc\x7d\xe2\xa5\xa6\x08\x5a\x36\x46\xd9\xfa\xdb\x0e\x9d\xa2\x73\xa5\xf4\x03\xcd\xd4\x28\x31' 725 b'\xce\x6f\x0c\xa4\x68\x89\x58\x56\x02\xbb\x8b\xc3\x6b\xb3\xbe\x86\x1f\xf6\xd1\xa6\x2e\x35\x02\x03\x01\x00\x01' 726 b'\xa3\x82\x01\xe3\x30\x82\x01\xdf\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x51\x68\xff\x90\xaf\x02' 727 b'\x07\x75\x3c\xcc\xd9\x65\x64\x62\xa2\x12\xb8\x59\x72\x3b\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\xc7\xd0' 728 b'\xac\xef\x89\x8b\x20\xe4\xb9\x14\x66\x89\x33\x03\x23\x94\xf6\xbf\x3a\x61\x30\x1f\x06\x03\x55\x1d\x11\x04\x18' 729 b'\x30\x16\x82\x0a\x2a\x2e\x69\x61\x6e\x61\x2e\x6f\x72\x67\x82\x08\x69\x61\x6e\x61\x2e\x6f\x72\x67\x30\x0e\x06' 730 b'\x03\x55\x1d\x0f\x01\x01\xff\x04\x04\x03\x02\x05\xa0\x30\x1d\x06\x03\x55\x1d\x25\x04\x16\x30\x14\x06\x08\x2b' 731 b'\x06\x01\x05\x05\x07\x03\x01\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x02\x30\x75\x06\x03\x55\x1d\x1f\x04\x6e\x30' 732 b'\x6c\x30\x34\xa0\x32\xa0\x30\x86\x2e\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x6c\x33\x2e\x64\x69\x67\x69\x63\x65' 733 b'\x72\x74\x2e\x63\x6f\x6d\x2f\x73\x68\x61\x32\x2d\x68\x61\x2d\x73\x65\x72\x76\x65\x72\x2d\x67\x33\x2e\x63\x72' 734 b'\x6c\x30\x34\xa0\x32\xa0\x30\x86\x2e\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x6c\x34\x2e\x64\x69\x67\x69\x63\x65' 735 b'\x72\x74\x2e\x63\x6f\x6d\x2f\x73\x68\x61\x32\x2d\x68\x61\x2d\x73\x65\x72\x76\x65\x72\x2d\x67\x33\x2e\x63\x72' 736 b'\x6c\x30\x42\x06\x03\x55\x1d\x20\x04\x3b\x30\x39\x30\x37\x06\x09\x60\x86\x48\x01\x86\xfd\x6c\x01\x01\x30\x2a' 737 b'\x30\x28\x06\x08\x2b\x06\x01\x05\x05\x07\x02\x01\x16\x1c\x68\x74\x74\x70\x73\x3a\x2f\x2f\x77\x77\x77\x2e\x64' 738 b'\x69\x67\x69\x63\x65\x72\x74\x2e\x63\x6f\x6d\x2f\x43\x50\x53\x30\x81\x83\x06\x08\x2b\x06\x01\x05\x05\x07\x01' 739 b'\x01\x04\x77\x30\x75\x30\x24\x06\x08\x2b\x06\x01\x05\x05\x07\x30\x01\x86\x18\x68\x74\x74\x70\x3a\x2f\x2f\x6f' 740 b'\x63\x73\x70\x2e\x64\x69\x67\x69\x63\x65\x72\x74\x2e\x63\x6f\x6d\x30\x4d\x06\x08\x2b\x06\x01\x05\x05\x07\x30' 741 b'\x02\x86\x41\x68\x74\x74\x70\x3a\x2f\x2f\x63\x61\x63\x65\x72\x74\x73\x2e\x64\x69\x67\x69\x63\x65\x72\x74\x2e' 742 b'\x63\x6f\x6d\x2f\x44\x69\x67\x69\x43\x65\x72\x74\x53\x48\x41\x32\x48\x69\x67\x68\x41\x73\x73\x75\x72\x61\x6e' 743 b'\x63\x65\x53\x65\x72\x76\x65\x72\x43\x41\x2e\x63\x72\x74\x30\x0c\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x02\x30' 744 b'\x00\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x70\x31\x4c\x38\xe7\xc0' 745 b'\x2f\xd8\x08\x10\x50\x0b\x9d\xf6\xda\xe8\x5d\xe9\xb2\x3e\x29\xfb\xd6\x8b\xfd\xb5\xf2\x34\x11\xc8\x9a\xcf\xaf' 746 b'\x9a\xe0\x5a\xf9\x12\x3a\x8a\xa6\xbc\xe6\x95\x4a\x4e\x68\xdc\x7c\xfc\x48\x0a\x65\xd7\x6f\x22\x9c\x4b\xd5\xf5' 747 b'\x67\x4b\x0c\x9a\xc6\xd0\x6a\x37\xa1\xa1\xc1\x45\xc3\x95\x61\x20\xb8\xef\xe6\x7c\x88\x7a\xb4\xff\x7d\x6a\xa9' 748 b'\x50\xff\x36\x98\xf2\x7c\x4a\x19\xd5\x9d\x93\xa3\x9a\xca\x5a\x7b\x6d\x6c\x75\xe3\x49\x74\xe5\x0f\x5a\x59\x00' 749 b'\x05\xb3\xcb\x66\x5d\xdb\xd7\x07\x4f\x9f\xcb\xcb\xf9\xc5\x02\x28\xd5\xe2\x55\x96\xb6\x4a\xda\x16\x0b\x48\xf7' 750 b'\x7a\x93\xaa\xce\xd2\x26\x17\xbf\xe0\x05\xe0\x0f\xe2\x0a\x53\x2a\x0a\xdc\xb8\x18\xc8\x78\xdc\x5d\x66\x49\x27' 751 b'\x77\x77\xca\x1a\x81\x4e\x21\xd0\xb5\x33\x08\xaf\x40\x78\xbe\x45\x54\x71\x5e\x4c\xe4\x82\x8b\x01\x2f\x25\xff' 752 b'\xa1\x3a\x6c\xeb\x30\xd2\x0a\x75\xde\xba\x8a\x34\x4e\x41\xd6\x27\xfa\x63\x8f\xef\xf3\x8a\x30\x63\xa0\x18\x75' 753 b'\x19\xb3\x9b\x05\x3f\x71\x34\xd9\xcd\x83\xe6\x09\x1a\xcc\xf5\xd2\xe3\xa0\x5e\xdf\xa1\xdf\xbe\x18\x1a\x87\xad' 754 b'\x86\xba\x24\xfe\x6b\x97\xfe\x00\x04\xb5\x30\x82\x04\xb1\x30\x82\x03\x99\xa0\x03\x02\x01\x02\x02\x10\x04\xe1' 755 b'\xe7\xa4\xdc\x5c\xf2\xf3\x6d\xc0\x2b\x42\xb8\x5d\x15\x9f\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b' 756 b'\x05\x00\x30\x6c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x15\x30\x13\x06\x03\x55\x04\x0a\x13' 757 b'\x0c\x44\x69\x67\x69\x43\x65\x72\x74\x20\x49\x6e\x63\x31\x19\x30\x17\x06\x03\x55\x04\x0b\x13\x10\x77\x77\x77' 758 b'\x2e\x64\x69\x67\x69\x63\x65\x72\x74\x2e\x63\x6f\x6d\x31\x2b\x30\x29\x06\x03\x55\x04\x03\x13\x22\x44\x69\x67' 759 b'\x69\x43\x65\x72\x74\x20\x48\x69\x67\x68\x20\x41\x73\x73\x75\x72\x61\x6e\x63\x65\x20\x45\x56\x20\x52\x6f\x6f' 760 b'\x74\x20\x43\x41\x30\x1e\x17\x0d\x31\x33\x31\x30\x32\x32\x31\x32\x30\x30\x30\x30\x5a\x17\x0d\x32\x38\x31\x30' 761 b'\x32\x32\x31\x32\x30\x30\x30\x30\x5a\x30\x70\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x15\x30' 762 b'\x13\x06\x03\x55\x04\x0a\x13\x0c\x44\x69\x67\x69\x43\x65\x72\x74\x20\x49\x6e\x63\x31\x19\x30\x17\x06\x03\x55' 763 b'\x04\x0b\x13\x10\x77\x77\x77\x2e\x64\x69\x67\x69\x63\x65\x72\x74\x2e\x63\x6f\x6d\x31\x2f\x30\x2d\x06\x03\x55' 764 b'\x04\x03\x13\x26\x44\x69\x67\x69\x43\x65\x72\x74\x20\x53\x48\x41\x32\x20\x48\x69\x67\x68\x20\x41\x73\x73\x75' 765 b'\x72\x61\x6e\x63\x65\x20\x53\x65\x72\x76\x65\x72\x20\x43\x41\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86' 766 b'\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xb6\xe0\x2f\xc2\x24\x06' 767 b'\xc8\x6d\x04\x5f\xd7\xef\x0a\x64\x06\xb2\x7d\x22\x26\x65\x16\xae\x42\x40\x9b\xce\xdc\x9f\x9f\x76\x07\x3e\xc3' 768 b'\x30\x55\x87\x19\xb9\x4f\x94\x0e\x5a\x94\x1f\x55\x56\xb4\xc2\x02\x2a\xaf\xd0\x98\xee\x0b\x40\xd7\xc4\xd0\x3b' 769 b'\x72\xc8\x14\x9e\xef\x90\xb1\x11\xa9\xae\xd2\xc8\xb8\x43\x3a\xd9\x0b\x0b\xd5\xd5\x95\xf5\x40\xaf\xc8\x1d\xed' 770 b'\x4d\x9c\x5f\x57\xb7\x86\x50\x68\x99\xf5\x8a\xda\xd2\xc7\x05\x1f\xa8\x97\xc9\xdc\xa4\xb1\x82\x84\x2d\xc6\xad' 771 b'\xa5\x9c\xc7\x19\x82\xa6\x85\x0f\x5e\x44\x58\x2a\x37\x8f\xfd\x35\xf1\x0b\x08\x27\x32\x5a\xf5\xbb\x8b\x9e\xa4' 772 b'\xbd\x51\xd0\x27\xe2\xdd\x3b\x42\x33\xa3\x05\x28\xc4\xbb\x28\xcc\x9a\xac\x2b\x23\x0d\x78\xc6\x7b\xe6\x5e\x71' 773 b'\xb7\x4a\x3e\x08\xfb\x81\xb7\x16\x16\xa1\x9d\x23\x12\x4d\xe5\xd7\x92\x08\xac\x75\xa4\x9c\xba\xcd\x17\xb2\x1e' 774 b'\x44\x35\x65\x7f\x53\x25\x39\xd1\x1c\x0a\x9a\x63\x1b\x19\x92\x74\x68\x0a\x37\xc2\xc2\x52\x48\xcb\x39\x5a\xa2' 775 b'\xb6\xe1\x5d\xc1\xdd\xa0\x20\xb8\x21\xa2\x93\x26\x6f\x14\x4a\x21\x41\xc7\xed\x6d\x9b\xf2\x48\x2f\xf3\x03\xf5' 776 b'\xa2\x68\x92\x53\x2f\x5e\xe3\x02\x03\x01\x00\x01\xa3\x82\x01\x49\x30\x82\x01\x45\x30\x12\x06\x03\x55\x1d\x13' 777 b'\x01\x01\xff\x04\x08\x30\x06\x01\x01\xff\x02\x01\x00\x30\x0e\x06\x03\x55\x1d\x0f\x01\x01\xff\x04\x04\x03\x02' 778 b'\x01\x86\x30\x1d\x06\x03\x55\x1d\x25\x04\x16\x30\x14\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x01\x06\x08\x2b\x06' 779 b'\x01\x05\x05\x07\x03\x02\x30\x34\x06\x08\x2b\x06\x01\x05\x05\x07\x01\x01\x04\x28\x30\x26\x30\x24\x06\x08\x2b' 780 b'\x06\x01\x05\x05\x07\x30\x01\x86\x18\x68\x74\x74\x70\x3a\x2f\x2f\x6f\x63\x73\x70\x2e\x64\x69\x67\x69\x63\x65' 781 b'\x72\x74\x2e\x63\x6f\x6d\x30\x4b\x06\x03\x55\x1d\x1f\x04\x44\x30\x42\x30\x40\xa0\x3e\xa0\x3c\x86\x3a\x68\x74' 782 b'\x74\x70\x3a\x2f\x2f\x63\x72\x6c\x34\x2e\x64\x69\x67\x69\x63\x65\x72\x74\x2e\x63\x6f\x6d\x2f\x44\x69\x67\x69' 783 b'\x43\x65\x72\x74\x48\x69\x67\x68\x41\x73\x73\x75\x72\x61\x6e\x63\x65\x45\x56\x52\x6f\x6f\x74\x43\x41\x2e\x63' 784 b'\x72\x6c\x30\x3d\x06\x03\x55\x1d\x20\x04\x36\x30\x34\x30\x32\x06\x04\x55\x1d\x20\x00\x30\x2a\x30\x28\x06\x08' 785 b'\x2b\x06\x01\x05\x05\x07\x02\x01\x16\x1c\x68\x74\x74\x70\x73\x3a\x2f\x2f\x77\x77\x77\x2e\x64\x69\x67\x69\x63' 786 b'\x65\x72\x74\x2e\x63\x6f\x6d\x2f\x43\x50\x53\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x51\x68\xff\x90\xaf' 787 b'\x02\x07\x75\x3c\xcc\xd9\x65\x64\x62\xa2\x12\xb8\x59\x72\x3b\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80' 788 b'\x14\xb1\x3e\xc3\x69\x03\xf8\xbf\x47\x01\xd4\x98\x26\x1a\x08\x02\xef\x63\x64\x2b\xc3\x30\x0d\x06\x09\x2a\x86' 789 b'\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x18\x8a\x95\x89\x03\xe6\x6d\xdf\x5c\xfc\x1d\x68\xea' 790 b'\x4a\x8f\x83\xd6\x51\x2f\x8d\x6b\x44\x16\x9e\xac\x63\xf5\xd2\x6e\x6c\x84\x99\x8b\xaa\x81\x71\x84\x5b\xed\x34' 791 b'\x4e\xb0\xb7\x79\x92\x29\xcc\x2d\x80\x6a\xf0\x8e\x20\xe1\x79\xa4\xfe\x03\x47\x13\xea\xf5\x86\xca\x59\x71\x7d' 792 b'\xf4\x04\x96\x6b\xd3\x59\x58\x3d\xfe\xd3\x31\x25\x5c\x18\x38\x84\xa3\xe6\x9f\x82\xfd\x8c\x5b\x98\x31\x4e\xcd' 793 b'\x78\x9e\x1a\xfd\x85\xcb\x49\xaa\xf2\x27\x8b\x99\x72\xfc\x3e\xaa\xd5\x41\x0b\xda\xd5\x36\xa1\xbf\x1c\x6e\x47' 794 b'\x49\x7f\x5e\xd9\x48\x7c\x03\xd9\xfd\x8b\x49\xa0\x98\x26\x42\x40\xeb\xd6\x92\x11\xa4\x64\x0a\x57\x54\xc4\xf5' 795 b'\x1d\xd6\x02\x5e\x6b\xac\xee\xc4\x80\x9a\x12\x72\xfa\x56\x93\xd7\xff\xbf\x30\x85\x06\x30\xbf\x0b\x7f\x4e\xff' 796 b'\x57\x05\x9d\x24\xed\x85\xc3\x2b\xfb\xa6\x75\xa8\xac\x2d\x16\xef\x7d\x79\x27\xb2\xeb\xc2\x9d\x0b\x07\xea\xaa' 797 b'\x85\xd3\x01\xa3\x20\x28\x41\x59\x43\x28\xd2\x81\xe3\xaa\xf6\xec\x7b\x3b\x77\xb6\x40\x62\x80\x05\x41\x45\x01' 798 b'\xef\x17\x06\x3e\xde\xc0\x33\x9b\x67\xd3\x61\x2e\x72\x87\xe4\x69\xfc\x12\x00\x57\x40\x1e\x70\xf5\x1e\xc9\xb4' 799 ) 800 801 def test_num_certs(self): 802 assert (len(self.p.data.certificates) == 2) 803 804 805class TestTLSMultiFactory(object): 806 """Made up test data""" 807 @classmethod 808 def setup_class(cls): 809 cls.data = _hexdecode(b'1703010010' # header 1 810 b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' # data 1 811 b'1703010010' # header 2 812 b'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' # data 2 813 b'1703010010' # header 3 814 b'CCCCCCCC') # data 3 (incomplete) 815 cls.msgs, cls.bytes_parsed = tls_multi_factory(cls.data) 816 817 def test_num_messages(self): 818 # only complete messages should be parsed, incomplete ones left 819 # in buffer 820 assert (len(self.msgs) == 2) 821 822 def test_bytes_parsed(self): 823 assert (self.bytes_parsed == (5 + 16) * 2) 824 825 def test_first_msg_data(self): 826 assert (self.msgs[0].data == _hexdecode(b'AA' * 16)) 827 828 def test_second_msg_data(self): 829 assert (self.msgs[1].data == _hexdecode(b'BB' * 16)) 830 831 def test_incomplete(self): 832 import pytest 833 834 msgs, n = tls_multi_factory(_hexdecode(b'17')) 835 assert (len(msgs) == 0) 836 assert (n == 0) 837 msgs, n = tls_multi_factory(_hexdecode(b'1703')) 838 assert (len(msgs) == 0) 839 assert (n == 0) 840 msgs, n = tls_multi_factory(_hexdecode(b'170301')) 841 assert (len(msgs) == 0) 842 assert (n == 0) 843 msgs, n = tls_multi_factory(_hexdecode(b'17030100')) 844 assert (len(msgs) == 0) 845 assert (n == 0) 846 msgs, n = tls_multi_factory(_hexdecode(b'1703010000')) 847 assert (len(msgs) == 1) 848 assert (n == 5) 849 850 with pytest.raises(SSL3Exception, match='Bad TLS version in buf: '): 851 tls_multi_factory(_hexdecode(b'000000000000')) 852 853 854def test_ssl2(): 855 from binascii import unhexlify 856 buf_padding = unhexlify( 857 '0001' # len 858 '02' # padlen 859 '03' # msg 860 '0405' # pad 861 '0607' # data 862 ) 863 ssl2 = SSL2(buf_padding) 864 assert ssl2.len == 1 865 assert ssl2.msg == b'\x03' 866 assert ssl2.pad == b'\x04\x05' 867 assert ssl2.data == b'\x06\x07' 868 869 buf_no_padding = unhexlify( 870 '8001' # len 871 '03' # msg 872 '0607' # data 873 ) 874 ssl2 = SSL2(buf_no_padding) 875 assert ssl2.len == 1 876 assert ssl2.msg == b'\x03' 877 assert ssl2.data == b'\x06\x07' 878 879 880def test_clienthello_invalidcipher(): 881 # NOTE: this test relies on ciphersuite 0x001c not being in ssl_ciphersuites.py CIPHERSUITES. 882 # IANA has reserved this value to avoid conflict with SSLv3, but if it gets reassigned, 883 # a new value should be chosen to fix this test. 884 import pytest 885 from binascii import unhexlify 886 887 buf = unhexlify( 888 '0301' # version 889 '0000000000000000000000000000000000000000000000000000000000000000' # random 890 '01' # session_id length 891 '02' # session_id 892 '0002' # ciphersuites len 893 '001c' # ciphersuite (reserved; not implemented 894 ) 895 with pytest.raises(SSL3Exception, match='Unknown or invalid cipher suite type 1c'): 896 TLSClientHello(buf) 897 898 899def test_serverhello_invalidcipher(): 900 # NOTE: this test relies on ciphersuite 0x001c not being in ssl_ciphersuites.py CIPHERSUITES. 901 # IANA has reserved this value to avoid conflict with SSLv3, but if it gets reassigned, 902 # a new value should be chosen to fix this test. 903 import pytest 904 from binascii import unhexlify 905 906 buf = unhexlify( 907 '0301' # version 908 '0000000000000000000000000000000000000000000000000000000000000000' # random 909 '01' # session_id length 910 '02' # session_id 911 '001c' # ciphersuite (reserved; not implemented 912 ) 913 with pytest.raises(SSL3Exception, match='Unknown or invalid cipher suite type 1c'): 914 TLSServerHello(buf) 915 916 # remove the final byte from the ciphersuite so it will fail unpacking 917 buf = buf[:-1] 918 with pytest.raises(dpkt.NeedData): 919 TLSServerHello(buf) 920 921 922def test_tlscertificate_unpacking_error(): 923 import pytest 924 from binascii import unhexlify 925 buf = unhexlify( 926 '000003' # certs len 927 '0000' # certs (invalid, as size < 3) 928 ) 929 with pytest.raises(dpkt.NeedData): 930 TLSCertificate(buf) 931 932 933def test_tlshandshake_invalid_type(): 934 import pytest 935 from binascii import unhexlify 936 buf = unhexlify( 937 '7b' # type (invalid) 938 '000000' # length_bytes 939 ) 940 with pytest.raises(SSL3Exception, match='Unknown or invalid handshake type 123'): 941 TLSHandshake(buf) 942 943 944def test_sslfactory(): 945 from binascii import unhexlify 946 buf_tls31 = unhexlify( 947 '00' # type 948 '0301' # version 949 '0000' # length 950 ) 951 tls = SSLFactory(buf_tls31) 952 assert isinstance(tls, TLSRecord) 953 954 buf_ssl2 = unhexlify( 955 '00' # type 956 '0000' # not an SSL3+ version 957 ) 958 ssl2 = SSLFactory(buf_ssl2) 959 assert isinstance(ssl2, SSL2) 960