Ejemplo n.º 1
0
    def compute_tls13_early_secrets(self, external=False):
        """
        This function computes the Early Secret, the binder_key,
        the client_early_traffic_secret and the
        early_exporter_master_secret (See RFC8446, section 7.1).

        The parameter external is used for the computation of the
        binder_key:

        - For external PSK provisioned outside out of TLS, the parameter
          external must be True.
        - For resumption PSK, the parameter external must be False.

        If no argument is specified, the label "res binder" will be
        used by default.

        Ciphers key and IV are updated accordingly for 0-RTT data.
        self.handshake_messages should be ClientHello only.
        """

        # if no hash algorithm is set, default to SHA-256
        if self.prcs and self.prcs.hkdf:
            hkdf = self.prcs.hkdf
        elif self.pwcs and self.pwcs.hkdf:
            hkdf = self.pwcs.hkdf
        else:
            hkdf = TLS13_HKDF("sha256")

        if self.tls13_early_secret is None:
            self.tls13_early_secret = hkdf.extract(None,
                                                   self.tls13_psk_secret)

        if "binder_key" not in self.tls13_derived_secrets:
            if external:
                bk = hkdf.derive_secret(self.tls13_early_secret,
                                        b"ext binder",
                                        b"")
            else:
                bk = hkdf.derive_secret(self.tls13_early_secret,
                                        b"res binder",
                                        b"")

            self.tls13_derived_secrets["binder_key"] = bk

        cets = hkdf.derive_secret(self.tls13_early_secret,
                                  b"c e traffic",
                                  b"".join(self.handshake_messages))

        self.tls13_derived_secrets["client_early_traffic_secret"] = cets
        ees = hkdf.derive_secret(self.tls13_early_secret,
                                 b"e exp master",
                                 b"".join(self.handshake_messages))
        self.tls13_derived_secrets["early_exporter_secret"] = ees

        if self.connection_end == "server":
            if self.prcs:
                self.prcs.tls13_derive_keys(cets)
        elif self.connection_end == "client":
            if self.pwcs:
                self.pwcs.tls13_derive_keys(cets)
Ejemplo n.º 2
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")

            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()
Ejemplo n.º 3
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)
Ejemplo n.º 4
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()
Ejemplo n.º 5
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()
Ejemplo n.º 6
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()
Ejemplo n.º 7
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()