Beispiel #1
0
    def __init__(self,
                 connection_end="server",
                 read_or_write="read",
                 seq_num=0,
                 compression_alg=Comp_NULL,
                 ciphersuite=None,
                 tls_version=0x0303):

        self.tls_version = tls_version

        # It is the user's responsibility to keep the record seq_num
        # under 2**64-1. If this value gets maxed out, the TLS class in
        # record.py will crash when trying to encode it with struct.pack().
        self.seq_num = seq_num

        self.connection_end = connection_end
        self.row = read_or_write

        if ciphersuite is None:
            from scapy.layers.tls.crypto.suites import TLS_NULL_WITH_NULL_NULL
            ciphersuite = TLS_NULL_WITH_NULL_NULL
        self.ciphersuite = ciphersuite(tls_version=tls_version)

        if not self.ciphersuite.usable:
            warning(
                "TLS ciphersuite not usable. Is the cryptography Python module installed ?"
            )  # noqa: E501
            return

        self.compression = compression_alg()
        self.key_exchange = ciphersuite.kx_alg()
        self.cipher = ciphersuite.cipher_alg()
        self.hash = ciphersuite.hash_alg()

        if tls_version > 0x0200:
            if ciphersuite.cipher_alg.type == "aead":
                self.hmac = None
                self.mac_len = self.cipher.tag_len
            else:
                self.hmac = ciphersuite.hmac_alg()
                self.mac_len = self.hmac.hmac_len
        else:
            self.hmac = ciphersuite.hmac_alg()  # should be Hmac_NULL
            self.mac_len = self.hash.hash_len

        if tls_version >= 0x0304:
            self.hkdf = TLS13_HKDF(self.hash.name.lower())
        else:
            self.prf = PRF(ciphersuite.hash_alg.name, tls_version)
Beispiel #2
0
    def tls13_should_add_ClientHello(self):
        # we have to use the legacy, plaintext TLS record here
        supported_groups = ["secp256r1", "secp384r1"]
        if conf.crypto_valid_advanced:
            supported_groups.append("x25519")
        self.add_record(is_tls13=False)
        if self.client_hello:
            p = self.client_hello
        else:
            if self.ciphersuite is None:
                c = 0x1301
            else:
                c = self.ciphersuite
            p = TLS13ClientHello(ciphers=c)

        ext = []
        ext += TLS_Ext_SupportedVersion_CH(versions=["TLS 1.3"])

        if self.cur_session.tls13_psk_secret:
            if self.tls13_psk_mode == "psk_dhe_ke":
                ext += TLS_Ext_PSKKeyExchangeModes(kxmodes="psk_dhe_ke")
                ext += TLS_Ext_SupportedGroups(groups=supported_groups)
                ext += TLS_Ext_KeyShare_CH(
                    client_shares=[KeyShareEntry(group=self.curve)])
            else:
                ext += TLS_Ext_PSKKeyExchangeModes(kxmodes="psk_ke")
            # RFC844, section 4.2.11.
            # "The "pre_shared_key" extension MUST be the last extension
            # in the ClientHello "
            hkdf = TLS13_HKDF("sha256")
            hash_len = hkdf.hash.digest_size
            psk_id = PSKIdentity(identity='Client_identity')
            # XXX see how to not pass binder as argument
            psk_binder_entry = PSKBinderEntry(binder_len=hash_len,
                                              binder=b"\x00" * hash_len)

            ext += TLS_Ext_PreSharedKey_CH(identities=[psk_id],
                                           binders=[psk_binder_entry])
        else:
            ext += TLS_Ext_SupportedGroups(groups=supported_groups)
            ext += TLS_Ext_KeyShare_CH(
                client_shares=[KeyShareEntry(group=self.curve)])
            ext += TLS_Ext_SignatureAlgorithms(
                sig_algs=["sha256+rsaepss", "sha256+rsa"])
        p.ext = ext
        self.add_msg(p)
        raise self.TLS13_ADDED_CLIENTHELLO()
Beispiel #3
0
    def tls13_should_add_ClientHello(self):
        # we have to use the legacy, plaintext TLS record here
        supported_groups = ["secp256r1", "secp384r1"]
        if conf.crypto_valid_advanced:
            supported_groups.append("x25519")
        self.add_record(is_tls13=False)
        if self.client_hello:
            p = self.client_hello
        else:
            if self.ciphersuite is None:
                c = 0x1301
            else:
                c = self.ciphersuite
            p = TLS13ClientHello(ciphers=c)

        ext = []
        ext += TLS_Ext_SupportedVersion_CH(versions=["TLS 1.3"])

        s = self.cur_session

        if s.tls13_psk_secret:
            # Check if DHE is need (both for out of band and resumption PSK)
            if self.tls13_psk_mode == "psk_dhe_ke":
                ext += TLS_Ext_PSKKeyExchangeModes(kxmodes="psk_dhe_ke")
                ext += TLS_Ext_SupportedGroups(groups=supported_groups)
                ext += TLS_Ext_KeyShare_CH(
                    client_shares=[KeyShareEntry(group=self.curve)])
            else:
                ext += TLS_Ext_PSKKeyExchangeModes(kxmodes="psk_ke")

            # RFC844, section 4.2.11.
            # "The "pre_shared_key" extension MUST be the last extension
            # in the ClientHello "
            # Compute the pre_shared_key extension for resumption PSK
            if s.client_session_ticket:
                cs_cls = _tls_cipher_suites_cls[
                    s.tls13_ticket_ciphersuite]  # noqa: E501
                hkdf = TLS13_HKDF(cs_cls.hash_alg.name.lower())
                hash_len = hkdf.hash.digest_size
                # We compute the client's view of the age of the ticket (ie
                # the time since the receipt of the ticket) in ms
                agems = int((time.time() - s.client_ticket_age) * 1000)
                # Then we compute the obfuscated version of the ticket age
                # by adding the "ticket_age_add" value included in the
                # ticket (modulo 2^32)
                obfuscated_age = ((agems + s.client_session_ticket_age_add)
                                  & 0xffffffff)

                psk_id = PSKIdentity(identity=s.client_session_ticket,
                                     obfuscated_ticket_age=obfuscated_age)

                psk_binder_entry = PSKBinderEntry(binder_len=hash_len,
                                                  binder=b"\x00" * hash_len)

                ext += TLS_Ext_PreSharedKey_CH(identities=[psk_id],
                                               binders=[psk_binder_entry])
            else:
                # Compute the pre_shared_key extension for out of band PSK
                # (SHA256 is used as default hash function for HKDF for out
                # of band PSK)
                hkdf = TLS13_HKDF("sha256")
                hash_len = hkdf.hash.digest_size
                psk_id = PSKIdentity(identity='Client_identity')
                # XXX see how to not pass binder as argument
                psk_binder_entry = PSKBinderEntry(binder_len=hash_len,
                                                  binder=b"\x00" * hash_len)

                ext += TLS_Ext_PreSharedKey_CH(identities=[psk_id],
                                               binders=[psk_binder_entry])
        else:
            ext += TLS_Ext_SupportedGroups(groups=supported_groups)
            ext += TLS_Ext_KeyShare_CH(
                client_shares=[KeyShareEntry(group=self.curve)])
            ext += TLS_Ext_SignatureAlgorithms(
                sig_algs=["sha256+rsaepss", "sha256+rsa"])
        p.ext = ext
        self.add_msg(p)
        raise self.TLS13_ADDED_CLIENTHELLO()
Beispiel #4
0
    def INIT_TLS_SESSION(self):
        self.cur_session = tlsSession(connection_end="client")
        s = self.cur_session
        s.client_certs = self.mycert
        s.client_key = self.mykey
        v = self.advertised_tls_version
        if v:
            s.advertised_tls_version = v
        else:
            default_version = s.advertised_tls_version
            self.advertised_tls_version = default_version

        if s.advertised_tls_version >= 0x0304:
            # For out of band PSK, the PSK is given as an argument
            # to the automaton
            if self.tls13_psk_secret:
                s.tls13_psk_secret = binascii.unhexlify(self.tls13_psk_secret)

            # For resumed PSK, the PSK is computed from
            if self.session_ticket_file_in:
                with open(self.session_ticket_file_in, 'rb') as f:

                    resumed_ciphersuite_len = struct.unpack("B", f.read(1))[0]
                    s.tls13_ticket_ciphersuite = \
                        struct.unpack("!H", f.read(resumed_ciphersuite_len))[0]

                    ticket_nonce_len = struct.unpack("B", f.read(1))[0]
                    # XXX add client_session_nonce member in tlsSession
                    s.client_session_nonce = f.read(ticket_nonce_len)

                    client_ticket_age_len = struct.unpack("!H", f.read(2))[0]
                    tmp = f.read(client_ticket_age_len)
                    s.client_ticket_age = struct.unpack("!I", tmp)[0]

                    client_ticket_age_add_len = struct.unpack("!H",
                                                              f.read(2))[0]
                    tmp = f.read(client_ticket_age_add_len)
                    s.client_session_ticket_age_add = struct.unpack("!I",
                                                                    tmp)[0]

                    ticket_len = struct.unpack("!H", f.read(2))[0]
                    s.client_session_ticket = f.read(ticket_len)

                if self.resumption_master_secret:

                    if s.tls13_ticket_ciphersuite not in _tls_cipher_suites_cls:  # noqa: E501
                        warning("Unknown cipher suite %d" %
                                s.tls13_ticket_ciphersuite)  # noqa: E501
                        # we do not try to set a default nor stop the execution
                    else:
                        cs_cls = _tls_cipher_suites_cls[
                            s.tls13_ticket_ciphersuite]  # noqa: E501

                    hkdf = TLS13_HKDF(cs_cls.hash_alg.name.lower())
                    hash_len = hkdf.hash.digest_size

                    s.tls13_psk_secret = hkdf.expand_label(
                        binascii.unhexlify(
                            self.resumption_master_secret),  # noqa: E501
                        b"resumption",
                        s.client_session_nonce,  # noqa: E501
                        hash_len)
        raise self.CONNECT()
Beispiel #5
0
    def tls13_should_add_ClientHello_Retry(self):
        s = self.cur_session
        s.tls13_retry = True
        # we have to use the legacy, plaintext TLS record here
        self.add_record(is_tls13=False)
        # We retrieve the group to be used and the selected version from the
        # previous message
        hrr = s.handshake_messages_parsed[-1]
        if isinstance(hrr, TLS13HelloRetryRequest):
            pass
        ciphersuite = hrr.cipher
        if hrr.ext:
            for e in hrr.ext:
                if isinstance(e, TLS_Ext_KeyShare_HRR):
                    selected_group = e.selected_group
                if isinstance(e, TLS_Ext_SupportedVersion_SH):
                    selected_version = e.version
        if not selected_group or not selected_version:
            raise self.CLOSE_NOTIFY()

        ext = []
        ext += TLS_Ext_SupportedVersion_CH(
            versions=[_tls_version[selected_version]])  # noqa: E501

        if s.tls13_psk_secret:
            if self.tls13_psk_mode == "psk_dhe_ke":
                ext += TLS_Ext_PSKKeyExchangeModes(kxmodes="psk_dhe_ke"),
                ext += TLS_Ext_SupportedGroups(
                    groups=[_tls_named_groups[selected_group]])  # noqa: E501
                ext += TLS_Ext_KeyShare_CH(client_shares=[
                    KeyShareEntry(group=selected_group)
                ])  # noqa: E501
            else:
                ext += TLS_Ext_PSKKeyExchangeModes(kxmodes="psk_ke")

            if s.client_session_ticket:

                # XXX Retrieve parameters from first ClientHello...
                cs_cls = _tls_cipher_suites_cls[s.tls13_ticket_ciphersuite]
                hkdf = TLS13_HKDF(cs_cls.hash_alg.name.lower())
                hash_len = hkdf.hash.digest_size

                # We compute the client's view of the age of the ticket (ie
                # the time since the receipt of the ticket) in ms
                agems = int((time.time() - s.client_ticket_age) * 1000)

                # Then we compute the obfuscated version of the ticket age by
                # adding the "ticket_age_add" value included in the ticket
                # (modulo 2^32)
                obfuscated_age = ((agems + s.client_session_ticket_age_add)
                                  & 0xffffffff)

                psk_id = PSKIdentity(identity=s.client_session_ticket,
                                     obfuscated_ticket_age=obfuscated_age)

                psk_binder_entry = PSKBinderEntry(binder_len=hash_len,
                                                  binder=b"\x00" * hash_len)

                ext += TLS_Ext_PreSharedKey_CH(identities=[psk_id],
                                               binders=[psk_binder_entry])
            else:
                hkdf = TLS13_HKDF("sha256")
                hash_len = hkdf.hash.digest_size
                psk_id = PSKIdentity(identity='Client_identity')
                psk_binder_entry = PSKBinderEntry(binder_len=hash_len,
                                                  binder=b"\x00" * hash_len)

                ext += TLS_Ext_PreSharedKey_CH(identities=[psk_id],
                                               binders=[psk_binder_entry])

        else:
            ext += TLS_Ext_SupportedGroups(
                groups=[_tls_named_groups[selected_group]])  # noqa: E501
            ext += TLS_Ext_KeyShare_CH(client_shares=[
                KeyShareEntry(group=selected_group)
            ])  # noqa: E501
            ext += TLS_Ext_SignatureAlgorithms(sig_algs=["sha256+rsaepss"])

        p = TLS13ClientHello(ciphers=ciphersuite, ext=ext)
        self.add_msg(p)
        raise self.TLS13_ADDED_CLIENTHELLO()