示例#1
0
class EncryptedPreMasterSecret(_GenericTLSSessionInheritance):
    """
    Pay attention to implementation notes in section 7.4.7.1 of RFC 5246.
    """
    name = "RSA Encrypted PreMaster Secret"
    fields_desc = [
        _TLSClientVersionField("client_version", None, _tls_version),
        StrFixedLenField("random", None, 46)
    ]

    def pre_dissect(self, m):
        s = self.tls_session
        tbd = m
        if s.tls_version >= 0x0301:
            if len(m) < 2:  # Should not happen
                return m
            l = struct.unpack("!H", m[:2])[0]
            if len(m) != l + 2:
                err = "TLS 1.0+, but RSA Encrypted PMS with no explicit length"
                warning(err)
            else:
                tbd = m[2:]
        if s.server_tmp_rsa_key is not None:
            # priority is given to the tmp_key, if there is one
            decrypted = s.server_tmp_rsa_key.decrypt(tbd)
            pms = decrypted[-48:]
        elif s.server_rsa_key is not None:
            decrypted = s.server_rsa_key.decrypt(tbd)
            pms = decrypted[-48:]
        else:
            pms = b"\x00" * 48  # Hack but we should not be there anyway
            err = "No server RSA key to decrypt Pre Master Secret. Skipping."
            warning(err)

        s.pre_master_secret = pms
        s.compute_ms_and_derive_keys()

        return pms

    def post_build(self, pkt, pay):
        """
        We encrypt the premaster secret (the 48 bytes) with either the server
        certificate or the temporary RSA key provided in a server key exchange
        message. After that step, we add the 2 bytes to provide the length, as
        described in implementation notes at the end of section 7.4.7.1.
        """
        enc = pkt

        s = self.tls_session
        s.pre_master_secret = enc
        s.compute_ms_and_derive_keys()

        if s.server_tmp_rsa_key is not None:
            enc = s.server_tmp_rsa_key.encrypt(pkt, "pkcs")
        elif s.server_certs is not None and len(s.server_certs) > 0:
            enc = s.server_certs[0].encrypt(pkt, "pkcs")
        else:
            warning("No material to encrypt Pre Master Secret")

        l = ""
        if s.tls_version >= 0x0301:
            l = struct.pack("!H", len(enc))
        return "%s%s%s" % (l, enc, pay)

    def guess_payload_class(self, p):
        return Padding
示例#2
0
class EncryptedPreMasterSecret(_GenericTLSSessionInheritance):
    """
    Pay attention to implementation notes in section 7.4.7.1 of RFC 5246.
    """
    name = "RSA Encrypted PreMaster Secret"
    fields_desc = [_TLSClientVersionField("client_version", None,
                                          _tls_version),
                   StrFixedLenField("random", None, 46)]

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt and 'tls_session' in kargs:
            s = kargs['tls_session']
            if s.server_tmp_rsa_key is None and s.server_rsa_key is None:
                return _UnEncryptedPreMasterSecret
        return EncryptedPreMasterSecret

    def pre_dissect(self, m):
        s = self.tls_session
        tbd = m
        tls_version = s.tls_version
        if tls_version is None:
            tls_version = s.advertised_tls_version
        if tls_version >= 0x0301:
            if len(m) < 2:      # Should not happen
                return m
            tmp_len = struct.unpack("!H", m[:2])[0]
            if len(m) != tmp_len + 2:
                err = "TLS 1.0+, but RSA Encrypted PMS with no explicit length"
                warning(err)
            else:
                tbd = m[2:]
        if s.server_tmp_rsa_key is not None:
            # priority is given to the tmp_key, if there is one
            decrypted = s.server_tmp_rsa_key.decrypt(tbd)
            pms = decrypted[-48:]
        elif s.server_rsa_key is not None:
            decrypted = s.server_rsa_key.decrypt(tbd)
            pms = decrypted[-48:]
        else:
            # the dispatch_hook is supposed to prevent this case
            pms = b"\x00" * 48
            err = "No server RSA key to decrypt Pre Master Secret. Skipping."
            warning(err)

        s.pre_master_secret = pms
        if not s.extms or s.session_hash:
            s.compute_ms_and_derive_keys()

        return pms

    def post_build(self, pkt, pay):
        """
        We encrypt the premaster secret (the 48 bytes) with either the server
        certificate or the temporary RSA key provided in a server key exchange
        message. After that step, we add the 2 bytes to provide the length, as
        described in implementation notes at the end of section 7.4.7.1.
        """
        enc = pkt

        s = self.tls_session
        s.pre_master_secret = enc
        if not s.extms or s.session_hash:
            s.compute_ms_and_derive_keys()

        if s.server_tmp_rsa_key is not None:
            enc = s.server_tmp_rsa_key.encrypt(pkt, t="pkcs")
        elif s.server_certs is not None and len(s.server_certs) > 0:
            enc = s.server_certs[0].encrypt(pkt, t="pkcs")
        else:
            warning("No material to encrypt Pre Master Secret")

        tmp_len = b""
        tls_version = s.tls_version
        if tls_version is None:
            tls_version = s.advertised_tls_version
        if tls_version >= 0x0301:
            tmp_len = struct.pack("!H", len(enc))
        return tmp_len + enc + pay

    def guess_payload_class(self, p):
        return Padding
示例#3
0
class TLSClientHello(_TLSHandshake):
    """
    TLS ClientHello, with abilities to handle extensions.

    The Random structure follows the RFC 5246: while it is 32-byte long,
    many implementations use the first 4 bytes as a gmt_unix_time, and then
    the remaining 28 byts should be completely random. This was designed in
    order to (sort of) mitigate broken RNGs. If you prefer to show the full
    32 random bytes without any GMT time, just comment in/out the lines below.
    """
    name = "TLS Handshake - Client Hello"
    fields_desc = [
        ByteEnumField("msgtype", 1, _tls_handshake_type),
        ThreeBytesField("msglen", None),
        _TLSClientVersionField("version", None, _tls_version),

        #_TLSRandomBytesField("random_bytes", None, 32),
        _GMTUnixTimeField("gmt_unix_time", None),
        _TLSRandomBytesField("random_bytes", None, 28),
        FieldLenField("sidlen", None, fmt="B", length_of="sid"),
        _SessionIDField("sid", "", length_from=lambda pkt: pkt.sidlen),
        FieldLenField("cipherslen", None, fmt="!H", length_of="ciphers"),
        _CipherSuitesField("ciphers", [TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256],
                           _tls_cipher_suites,
                           itemfmt="!H",
                           length_from=lambda pkt: pkt.cipherslen),
        FieldLenField("complen", None, fmt="B", length_of="comp"),
        _CompressionMethodsField("comp", [0],
                                 _tls_compression_algs,
                                 itemfmt="B",
                                 length_from=lambda pkt: pkt.complen),
        _ExtensionsLenField("extlen", None, length_of="ext"),
        _ExtensionsField("ext",
                         None,
                         length_from=lambda pkt:
                         (pkt.msglen - (pkt.sidlen or 0) -
                          (pkt.cipherslen or 0) - (pkt.complen or 0) - 40))
    ]

    def post_build(self, p, pay):
        if self.random_bytes is None:
            p = p[:10] + randstring(28) + p[10 + 28:]
        return super(TLSClientHello, self).post_build(p, pay)

    def tls_session_update(self, msg_str):
        """
        Either for parsing or building, we store the client_random
        along with the raw string representing this handshake message.
        """
        super(TLSClientHello, self).tls_session_update(msg_str)

        self.tls_session.advertised_tls_version = self.version
        self.random_bytes = msg_str[10:38]
        self.tls_session.client_random = (
            struct.pack('!I', self.gmt_unix_time) + self.random_bytes)
        if self.ext:
            for e in self.ext:
                if isinstance(e, TLS_Ext_SupportedVersions):
                    if self.tls_session.tls13_early_secret is None:
                        # this is not recomputed if there was a TLS 1.3 HRR
                        self.tls_session.compute_tls13_early_secrets()
                    break