def parse_tls_int_list(data: bytes,
                       entry_size: int,
                       header_size: int = 2,
                       replace_grease=True):
    """Parse a TLS-encoded list of integers.

    This list format is common in TLS packets.
    It consists of a two-byte header indicating the total length
    of the list, with the entries following.

    The entries may be one of TLS_GREASE_VALUES, in which case they
    are replaced with the constant TLS_GREASE (unless replace_grease=False).

    Returns
    -------
    entries : list[int]
        List of entries extracted from the TLS-encoded list.
    size : int
        Total size, in bytes, of the list.
    """

    off = 0
    h = "!H" if header_size == 2 else "!B"
    (list_length, ) = struct.unpack_from(h, data, off)
    off += struct.calcsize(h)
    if list_length > len(data) - off:
        raise Exception(f"TLS list of integers too long: {list_length} bytes")

    entries = []
    s = "!H" if entry_size == 2 else "!B"
    for i in range(list_length // entry_size):
        (entry, ) = struct.unpack_from(s, data, off)
        off += struct.calcsize(s)
        if replace_grease and entry in TLS_GREASE_VALUES:
            entry = TLS_GREASE
        entries.append(entry)

    return entries, struct.calcsize(h) + list_length
Parse a TLS-encoded list of integers.

    This list format is common in TLS packets.
    It consists of a two-byte header indicating the total length
    of the list, with the entries following.

    The entries may be one of TLS_GREASE_VALUES, in which case they
    are replaced with the constant TLS_GREASE (unless replace_grease=False).

    Returns
    -------
    entries : list[int]
        List of entries extracted from the TLS-encoded list.
    size : int
        Total size, in bytes, of the list.
    
tests/signature.py