예제 #1
0
class TLSEncryptedExtensions(_TLSHandshake):
    name = "TLS 1.3 Handshake - Encrypted Extensions"
    fields_desc = [
        ByteEnumField("msgtype", 8, _tls_handshake_type),
        ThreeBytesField("msglen", None),
        _ExtensionsLenField("extlen", None, length_of="ext"),
        _ExtensionsField("ext", None, length_from=lambda pkt: pkt.msglen - 2)
    ]
예제 #2
0
class TLSHelloRetryRequest(_TLSHandshake):
    name = "TLS 1.3 Handshake - Hello Retry Request"
    fields_desc = [
        ByteEnumField("msgtype", 6, _tls_handshake_type),
        ThreeBytesField("msglen", None),
        _TLSVersionField("version", None, _tls_version),
        _ExtensionsLenField("extlen", None, length_of="ext"),
        _ExtensionsField("ext", None, length_from=lambda pkt: pkt.msglen - 4)
    ]
예제 #3
0
class _ASN1CertAndExt(_GenericTLSSessionInheritance):
    name = "Certificate and Extensions"
    fields_desc = [
        _ASN1CertField("cert", ""),
        FieldLenField("extlen", None, length_of="ext"),
        _ExtensionsField("ext", [], length_from=lambda pkt: pkt.extlen)
    ]

    def extract_padding(self, s):
        return "", s
예제 #4
0
class TLS13ServerHello(TLSClientHello):
    """ TLS 1.3 ServerHello """
    name = "TLS 1.3 Handshake - Server Hello"
    fields_desc = [
        ByteEnumField("msgtype", 2, _tls_handshake_type),
        ThreeBytesField("msglen", None),
        _TLSVersionField("version", None, _tls_version),
        _TLSRandomBytesField("random_bytes", None, 32),
        EnumField("cipher", None, _tls_cipher_suites),
        _ExtensionsLenField("extlen", None, length_of="ext"),
        _ExtensionsField("ext",
                         None,
                         length_from=lambda pkt: (pkt.msglen - 38))
    ]

    def tls_session_update(self, msg_str):
        """
        Either for parsing or building, we store the server_random along with
        the raw string representing this handshake message. We also store the
        cipher suite (if recognized), and finally we instantiate the write and
        read connection states.
        """
        super(TLSClientHello, self).tls_session_update(msg_str)

        s = self.tls_session
        s.tls_version = self.version
        s.server_random = self.random_bytes

        cs_cls = None
        if self.cipher:
            cs_val = self.cipher
            if cs_val not in _tls_cipher_suites_cls:
                warning("Unknown cipher suite %d from ServerHello" % cs_val)
                # we do not try to set a default nor stop the execution
            else:
                cs_cls = _tls_cipher_suites_cls[cs_val]

        connection_end = s.connection_end
        s.pwcs = writeConnState(ciphersuite=cs_cls,
                                connection_end=connection_end,
                                tls_version=self.version)
        s.triggered_pwcs_commit = True
        s.prcs = readConnState(ciphersuite=cs_cls,
                               connection_end=connection_end,
                               tls_version=self.version)
        s.triggered_prcs_commit = True

        if self.tls_session.tls13_early_secret is None:
            # In case the connState was not pre-initialized, we could not
            # compute the early secrets at the ClientHello, so we do it here.
            self.tls_session.compute_tls13_early_secrets()
        s.compute_tls13_handshake_secrets()
예제 #5
0
class TLS13NewSessionTicket(_TLSHandshake):
    """
    Uncomment the TicketField line for parsing a RFC 5077 ticket.
    """
    name = "TLS Handshake - New Session Ticket"
    fields_desc = [
        ByteEnumField("msgtype", 4, _tls_handshake_type),
        ThreeBytesField("msglen", None),
        IntField("ticket_lifetime", 0xffffffff),
        IntField("ticket_age_add", 0),
        FieldLenField("ticketlen", None, length_of="ticket"),
        #TicketField("ticket", "",
        StrLenField("ticket", "", length_from=lambda pkt: pkt.ticketlen),
        _ExtensionsLenField("extlen", None, length_of="ext"),
        _ExtensionsField("ext",
                         None,
                         length_from=lambda pkt: (pkt.msglen -
                                                  (pkt.ticketlen or 0) - 12))
    ]

    def post_dissection_tls_session_update(self, msg_str):
        self.tls_session_update(msg_str)
        if self.tls_session.connection_end == "client":
            self.tls_session.client_session_ticket = self.ticket
예제 #6
0
class TLSServerHello(TLSClientHello):
    """
    TLS ServerHello, 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 - Server Hello"
    fields_desc = [
        ByteEnumField("msgtype", 2, _tls_handshake_type),
        ThreeBytesField("msglen", None),
        _TLSVersionField("version", None, _tls_version),

        #_TLSRandomBytesField("random_bytes", None, 32),
        _GMTUnixTimeField("gmt_unix_time", None),
        _TLSRandomBytesField("random_bytes", None, 28),
        FieldLenField("sidlen", None, length_of="sid", fmt="B"),
        _SessionIDField("sid", "", length_from=lambda pkt: pkt.sidlen),
        EnumField("cipher", None, _tls_cipher_suites),
        _CompressionMethodsField("comp", [0],
                                 _tls_compression_algs,
                                 itemfmt="B",
                                 length_from=lambda pkt: 1),
        _ExtensionsLenField("extlen", None, length_of="ext"),
        _ExtensionsField("ext",
                         None,
                         length_from=lambda pkt: (pkt.msglen -
                                                  (pkt.sidlen or 0) - 38))
    ]
    #40)) ]

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt and len(_pkt) >= 6:
            version = struct.unpack("!H", _pkt[4:6])[0]
            if version == 0x0304 or version > 0x7f00:
                return TLS13ServerHello
        return TLSServerHello

    def tls_session_update(self, msg_str):
        """
        Either for parsing or building, we store the server_random
        along with the raw string representing this handshake message.
        We also store the session_id, the cipher suite (if recognized),
        the compression method, and finally we instantiate the pending write
        and read connection states. Usually they get updated later on in the
        negotiation when we learn the session keys, and eventually they
        are committed once a ChangeCipherSpec has been sent/received.
        """
        super(TLSClientHello, self).tls_session_update(msg_str)

        self.tls_session.tls_version = self.version
        self.random_bytes = msg_str[10:38]
        self.tls_session.server_random = (
            struct.pack('!I', self.gmt_unix_time) + self.random_bytes)
        self.tls_session.sid = self.sid

        cs_cls = None
        if self.cipher:
            cs_val = self.cipher
            if cs_val not in _tls_cipher_suites_cls:
                warning("Unknown cipher suite %d from ServerHello" % cs_val)
                # we do not try to set a default nor stop the execution
            else:
                cs_cls = _tls_cipher_suites_cls[cs_val]

        comp_cls = Comp_NULL
        if self.comp:
            comp_val = self.comp[0]
            if comp_val not in _tls_compression_algs_cls:
                err = "Unknown compression alg %d from ServerHello" % comp_val
                warning(err)
                comp_val = 0
            comp_cls = _tls_compression_algs_cls[comp_val]

        connection_end = self.tls_session.connection_end
        self.tls_session.pwcs = writeConnState(ciphersuite=cs_cls,
                                               compression_alg=comp_cls,
                                               connection_end=connection_end,
                                               tls_version=self.version)
        self.tls_session.prcs = readConnState(ciphersuite=cs_cls,
                                              compression_alg=comp_cls,
                                              connection_end=connection_end,
                                              tls_version=self.version)
예제 #7
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