Example #1
0
    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
Example #3
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
Example #4
0
 def parse_data(type, data):
     data = "".join(data)
     # currently only parsing SNI
     if type != 0:
         return data
     if len(data) == 0:
         return ""
     # parse out the SNI list
     size = struct.unpack_from("!H", data, 0)[0]
     snis = parse.parse_tls_list(data[2:], size, _parse_sni)[0]
     for sni in snis:
         if sni[0] == 0:
             return sni[1]
     # Didn't parse out a server name?
     return ""
Example #5
0
 def parse_data(type, data):
     data = "".join(data)
     # currently only parsing SNI
     if type != 0:
         return data
     if len(data) == 0:
         return ""
     # parse out the SNI list
     size = struct.unpack_from("!H", data, 0)[0]
     snis = parse.parse_tls_list(data[2:], size, _parse_sni)[0]
     for sni in snis:
         if sni[0] == 0:
             return sni[1]
     # Didn't parse out a server name?
     return ""
    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
Example #7
0
 def from_stream(body):
     extension_type = struct.unpack_from("!H", body, 0)[0]
     data_length = struct.unpack_from("!H", body, 2)[0]
     extension_data, read_amt = parse.parse_tls_list(
         body[4:], data_length, parse.parse_opaque)
     return Extension(extension_type, list(extension_data)), 4 + read_amt
Example #8
0
def _parse_sni(data):
    type = struct.unpack_from("B", data, 0)[0]
    size = struct.unpack_from("!H", data, 1)[0]
    name = parse.parse_tls_list(data[3:], size, parse.parse_opaque)[0]
    return (type, "".join(name)), size + 3
Example #9
0
 def from_stream(body):
     # length is 24 bits, pad so struct will parse it as an int
     num_certificates = struct.unpack_from("!I", "\x00" + body[:3])[0]
     certificates, read_amt = parse.parse_tls_list(body[3:], num_certificates, Certificate._parse_certificate)
     return Certificate(certificates), read_amt + 3
Example #10
0
def _parse_sni(data):
    type = struct.unpack_from("B", data, 0)[0]
    size = struct.unpack_from("!H", data, 1)[0]
    name = parse.parse_tls_list(data[3:], size, parse.parse_opaque)[0]
    return (type, "".join(name)), size + 3
Example #11
0
 def from_stream(body):
     extension_type = struct.unpack_from("!H", body, 0)[0]
     data_length = struct.unpack_from("!H", body, 2)[0]
     extension_data, read_amt = parse.parse_tls_list(
         body[4:], data_length, parse.parse_opaque)
     return Extension(extension_type, list(extension_data)), 4 + read_amt
 def from_stream(body):
     # length is 24 bits, pad so struct will parse it as an int
     num_certificates = struct.unpack_from("!I", "\x00" + body[:3])[0]
     certificates, read_amt = parse.parse_tls_list(
         body[3:], num_certificates, Certificate._parse_certificate)
     return Certificate(certificates), read_amt + 3