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
Exemple #4
0
    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