Commit 5ddc9d94 authored by Szilárd Pfeiffer's avatar Szilárd Pfeiffer
Browse files

Merge branch '2-ja3-tag-generation'

Closes: #2
parents 575a7b36 6f81fa77
Loading
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -68,6 +68,36 @@ Operating systems
* macOS
* Windows

Protocol Specific Features
--------------------------

Transport Layer Security (TLS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Only features that cannot be or difficultly implemented by some of the most popular SSL/TLS implementations (eg:
`GnuTls <https://www.gnutls.org/>`_, `LibreSSL <https://www.libressl.org/>`_, `OpenSSL <https://www.openssl.org/>`_,
`wolfSSL <https://www.wolfssl.com/>`_, ...) are listed.

Generic
"""""""

#. supports `Generate Random Extensions And Sustain Extensibility <https://tools.ietf.org/html/draft-ietf-tls-grease-04>`_
   (GREASE) values for

   * protocol version
   * extension type
   * ciphers suite
   * signature algorithms
   * named group

#. supports easy `JA3 fingerprint <https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967>`_
   generation

Cipher Suites
"""""""""""""

#. supports each cipher suites discussed on `ciphersuite.info <https://ciphersuite.info>`_

License
-------

+12 −0
Original line number Diff line number Diff line
@@ -80,6 +80,10 @@ class Authentication(enum.Enum):
        name='SRP',
        anonymous=False,
    )
    EDDSA = AuthenticationParams(
        name='EdDSA',
        anonymous=False,
    )


class BlockCipher(enum.Enum):
@@ -232,6 +236,14 @@ class MAC(enum.Enum):
        name='SHA512',
        digest_size=512
    )
    ED25519PH = MACParams(
        name='Ed25519ph',
        digest_size=255
    )
    ED448PH = MACParams(
        name='Ed448ph',
        digest_size=448
    )


class NamedGroupType(enum.IntEnum):
+19 −1
Original line number Diff line number Diff line
@@ -205,7 +205,8 @@ class VectorParsable(VectorBase):
            parser.parse_parsable_array(
                'items',
                items_size=parser['item_byte_num'],
                item_class=vector_param.item_class
                item_class=vector_param.item_class,
                fallback_class=vector_param.fallback_class
            )
        except NotEnoughData as e:
            raise NotEnoughData(e.bytes_needed)
@@ -306,6 +307,17 @@ class NByteEnumParsable(ParsableBase):
        raise NotImplementedError()


class OneByteEnumParsable(NByteEnumParsable):
    @classmethod
    def get_byte_num(cls):
        return 1

    @classmethod
    @abc.abstractmethod
    def get_enum_class(cls):
        raise NotImplementedError()


class TwoByteEnumParsable(NByteEnumParsable):
    @classmethod
    def get_byte_num(cls):
@@ -345,6 +357,12 @@ class NByteEnumComposer(object):
        raise NotImplementedError()


class OneByteEnumComposer(NByteEnumComposer):
    @classmethod
    def get_byte_num(cls):
        return 1


class TwoByteEnumComposer(NByteEnumComposer):
    @classmethod
    def get_byte_num(cls):
+10 −1
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-

import enum


class InvalidDataLength(Exception):
    def __init__(self, bytes_needed=None):
@@ -18,7 +20,14 @@ class TooMuchData(InvalidDataLength):

class InvalidValue(Exception):
    def __init__(self, value, type_class, class_member=None):
        message = hex(value) if isinstance(value, int) else '{}'.format(value)
        if isinstance(value, enum.IntEnum):
            message = hex(value.value)
        elif isinstance(value, enum.Enum):
            message = hex(value.value.code)
        elif isinstance(value, int):
            message = hex(value)
        else:
            message = '{}'.format(value)
        message = '{} is not a valid {}'.format(message, type_class.__name__)
        if class_member is not None:
            message = '{} {} value'.format(message, class_member)
+2 −2
Original line number Diff line number Diff line
@@ -136,12 +136,12 @@ class ParserBinary(object):
        self._parsed_values[name] = items
        self._parsed_length += items_size

    def parse_parsable_array(self, name, items_size, item_class):
    def parse_parsable_array(self, name, items_size, item_class, fallback_class=None):
        if self.unparsed_length < items_size:
            raise NotEnoughData(items_size)

        try:
            return self._parse_parsable_array(name, items_size, [item_class, ])
            return self._parse_parsable_array(name, items_size, [item_class, ], fallback_class)
        except ValueError as e:
            raise InvalidValue(e.args[0], item_class, name)

Loading