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
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.
        
nogotofail/mitm/util/ssl2/types/handshake.py