def from_stream(body): """Parse a Client Hello record from body. Body should start with the byte representation of an RFC 5246 struct ClientHello Returns a ClientHello and the number of bytes read from body Throws a struct.error or IndexError if there is not enough data to parse properly. """ version, index = Version.from_stream(body) random, read_amt = Random.from_stream(body[index:]) index += read_amt sessionid_length = struct.unpack_from("B", body, index)[0] index += 1 session_id, read_amt = ( parse.parse_tls_list( body[index:], sessionid_length, parse.parse_opaque)) index += read_amt cipher_length = struct.unpack_from("!H", body, index)[0] index += 2 ciphers, read_amt = ( parse.parse_tls_list( body[index:], cipher_length, Cipher.from_stream)) index += read_amt compression_length = struct.unpack_from("B", body, index)[0] index += 1 compression_methods, read_amt = ( parse.parse_tls_list( body[index:], compression_length, CompressionMethod.from_stream)) index += read_amt extensions = [] # Check if there are extensions present if index != len(body): extensions_length = struct.unpack_from("!H", body, index)[0] index += 2 extensions, read_amt = ( parse.parse_tls_list( body[index:], extensions_length, Extension.from_stream)) index += read_amt return ClientHello( version, random, session_id, ciphers, compression_methods, extensions), index
def from_stream(body): """Parse a Client Hello record from body. Body should start with the byte representation of an RFC 5246 struct ClientHello Returns a ClientHello and the number of bytes read from body Throws a struct.error or IndexError if there is not enough data to parse properly. """ version, index = Version.from_stream(body) random, read_amt = Random.from_stream(body[index:]) index += read_amt sessionid_length = struct.unpack_from("B", body, index)[0] index += 1 session_id, read_amt = (parse.parse_tls_list(body[index:], sessionid_length, parse.parse_opaque)) index += read_amt cipher_length = struct.unpack_from("!H", body, index)[0] index += 2 ciphers, read_amt = (parse.parse_tls_list(body[index:], cipher_length, Cipher.from_stream)) index += read_amt compression_length = struct.unpack_from("B", body, index)[0] index += 1 compression_methods, read_amt = (parse.parse_tls_list( body[index:], compression_length, CompressionMethod.from_stream)) index += read_amt extensions = [] # Check if there are extensions present if index != len(body): extensions_length = struct.unpack_from("!H", body, index)[0] index += 2 extensions, read_amt = (parse.parse_tls_list( body[index:], extensions_length, Extension.from_stream)) index += read_amt return ClientHello(version, random, session_id, ciphers, compression_methods, extensions), index
def from_stream(body): # Parse the TLS Record content_type, version_major, version_minor, length = ( struct.unpack_from("!BBBH", body, 0)) fragment = body[5:5 + length] # Sanity check if length != len(fragment): raise ValueError("Not enough data in fragment") # Check this is a Handshake message type = TlsRecord.type_map.get(content_type, OpaqueFragment) objs = [] if fragment == "": obj, size = type.from_stream(fragment) objs.append(obj) while fragment != "": obj, size = type.from_stream(fragment) objs.append(obj) fragment = fragment[size:] return TlsRecord(content_type, Version(version_major, version_minor), objs), 5 + length
def from_stream(body): """Parse a SSLv2 Client Hello record from body. Body should start with the byte representation struct ClientHello starting at the version field. See http://tools.ietf.org/html/rfc5246#appendix-E.2 Returns a ClientHello and the number of bytes read from body Throws a struct.error or IndexError if there is not enough data to parse properly. """ version, index = Version.from_stream(body) ciphers_length, sessionid_length, random_length = struct.unpack_from( "!HHH", body, index) index += 6; if ciphers_length % 3 != 0: raise ValueError("Cipher spec list length not a multiple of 3") if ciphers_length + sessionid_length + random_length \ != len(body) - index: raise ValueError("Not enough data or too much data") if random_length < 16 or random_length > 32: raise ValueError("Random challenge too short or too long") ciphers, read_amt = ( parse.parse_tls_list( body[index:], ciphers_length, Cipher.from_stream)) index += read_amt session_id, read_amt = ( parse.parse_tls_list( body[index:], sessionid_length, parse.parse_opaque)) index += read_amt random = body[index:index + random_length] index += random_length return ClientHello( version, random, session_id, ciphers), index
def from_stream(body): """Parse a SSLv2 Client Hello record from body. Body should start with the byte representation struct ClientHello starting at the version field. See http://tools.ietf.org/html/rfc5246#appendix-E.2 Returns a ClientHello and the number of bytes read from body Throws a struct.error or IndexError if there is not enough data to parse properly. """ version, index = Version.from_stream(body) ciphers_length, sessionid_length, random_length = struct.unpack_from( "!HHH", body, index) index += 6 if ciphers_length % 3 != 0: raise ValueError("Cipher spec list length not a multiple of 3") if ciphers_length + sessionid_length + random_length \ != len(body) - index: raise ValueError("Not enough data or too much data") if random_length < 16 or random_length > 32: raise ValueError("Random challenge too short or too long") ciphers, read_amt = (parse.parse_tls_list(body[index:], ciphers_length, Cipher.from_stream)) index += read_amt session_id, read_amt = (parse.parse_tls_list(body[index:], sessionid_length, parse.parse_opaque)) index += read_amt random = body[index:index + random_length] index += random_length return ClientHello(version, random, session_id, ciphers), index