clienthellod

package module
v0.5.0-alpha2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2024 License: Apache-2.0 Imports: 22 Imported by: 0

README

clienthellod: TLS ClientHello/QUIC Initial Packet reflection service

Go Build Status Go Report Card FOSSA Status Go Doc

clienthellod, read as "client-hello-D", is a TLS ClientHello/QUIC Initial Packet reflection service. It can be used to parses TLS ClientHello messages and QUIC Initial Packets into human-readable and highly programmable formats such as JSON.

Is is a part of the TLS fingerprintability research project which spans tlsfingerprint.io and quic.tlsfingerprint.io. It parses the ClientHello messages sent by TLS clients and QUIC Client Initial Packets sent by QUIC clients and display the parsed information in a human-readable format with high programmability.

See tlsfingerprint.io and quic.tlsfingerprint.io for more details about the project.

Quick Start

clienthellod comes as a Go library, which can be used to parse both TLS and QUIC protocols.

TLS/QUIC Fingerprinter
    tlsFingerprinter := clienthellod.NewTLSFingerprinter()
    quicFingerprinter := clienthellod.NewQUICFingerprinter()
TLS ClientHello
From a net.Conn
    tcpLis, err := net.Listen("tcp", ":443")
    defer tcpLis.Close()

    conn, err := tcpLis.Accept()
	if err != nil {
        panic(err)
	}
    defer conn.Close()

	ch, err := clienthellod.ReadClientHello(conn) // reads ClientHello from the connection
    if err != nil {
        panic(err)
    }

    err := ch.ParseClientHello() // parses ClientHello's fields
    if err != nil {
        panic(err)
    }

    jsonB, err = json.MarshalIndent(ch, "", "  ")
    if err != nil {
        panic(err)
    }

    fmt.Println(string(jsonB))
    fmt.Println("ClientHello ID: " + ch.HexID) // prints ClientHello's original fingerprint ID calculated using observed TLS extension order
    fmt.Println("ClientHello NormID: " + ch.NormHexID) // prints ClientHello's normalized fingerprint ID calculated using sorted TLS extension list
From raw []byte
    ch, err := clienthellod.UnmarshalClientHello(raw)
    if err != nil {
        panic(err)
    }

    // err := ch.ParseClientHello() // no need to call again, UnmarshalClientHello automatically calls ParseClientHello
QUIC Initial Packets (Client-sourced)
Single packet
    udpConn, err := net.ListenUDP("udp", ":443")
    defer udpConn.Close()

    buf := make([]byte, 65535)
    n, addr, err := udpConn.ReadFromUDP(buf)
    if err != nil {
        panic(err)
    }

    ci, err := clienthellod.UnmarshalQUICClientInitialPacket(buf[:n]) // decodes QUIC Client Initial Packet
    if err != nil {
        panic(err)
    }

    jsonB, err = json.MarshalIndent(cip, "", "  ")
    if err != nil {
        panic(err)
    }

    fmt.Println(string(jsonB)) // including fingerprint IDs of: ClientInitialPacket, QUIC Header, QUIC ClientHello, QUIC Transport Parameters' combination
Multiple packets

Implementations including Chrome/Chromium sends oversized Client Hello which does not fit into one single QUIC packet, in which case multiple QUIC Initial Packets are sent.

    gci := GatherClientInitials() // Each GatherClientInitials reassembles one QUIC Client Initial Packets stream. Use a QUIC Fingerprinter for multiple potential senders, which automatically demultiplexes the packets based on the source address.

    udpConn, err := net.ListenUDP("udp", ":443")
    defer udpConn.Close()

    for {
        buf := make([]byte, 65535)
        n, addr, err := udpConn.ReadFromUDP(buf)
        if err != nil {
            panic(err)
        }

        if addr != knownSenderAddr {
            continue
        }

        ci, err := clienthellod.UnmarshalQUICClientInitialPacket(buf[:n]) // decodes QUIC Client Initial Packet
        if err != nil {
            panic(err)
        }

        err = gci.AddPacket(ci)
        if err != nil {
            panic(err)
        }
    }
Use with Caddy

We also provide clienthellod as a Caddy Module in modcaddy, which you can use with Caddy to capture ClientHello messages and QUIC Client Initial Packets. See modcaddy for more details.

License

This project is developed and distributed under Apache-2.0 license.

FOSSA Status

Documentation

Index

Constants

View Source
const (
	DEFAULT_MAX_INITIAL_PACKET_NUMBER uint64 = 32
	DEFAULT_MAX_INITIAL_PACKET_COUNT  uint64 = 4
)
View Source
const (
	QUICFrame_PADDING uint64 = 0 // 0
	QUICFrame_PING    uint64 = 1 // 1
	QUICFrame_CRYPTO  uint64 = 6 // 6
)
View Source
const (
	TOKEN_ABSENT  uint32 = 0x00000000
	TOKEN_PRESENT uint32 = 0x00000001
)
View Source
const (
	QTP_GREASE = 27

	UNSET_VLI_BITS = true // if false, unsetVLIBits() will be nop
)
View Source
const DEFAULT_QUICFINGERPRINT_EXPIRY = 60 * time.Second
View Source
const DEFAULT_TLSFINGERPRINT_EXPIRY = 5 * time.Second

Variables

View Source
var (
	ErrGatheringExpired                                    = errors.New("ClientInitials gathering has expired")
	ErrPacketRejected                                      = errors.New("packet rejected based upon rules")
	ErrGatheredClientInitialsChannelClosedBeforeCompletion = errors.New("completion notification channel closed before setting completion flag")
)
View Source
var (
	ErrDuplicateFragment = errors.New("duplicate CRYPTO frame detected")
	ErrOverlapFragment   = errors.New("overlap CRYPTO frame detected")
	ErrTooManyFragments  = errors.New("too many CRYPTO fragments")
	ErrOffsetTooHigh     = errors.New("offset too high")
	ErrNeedMoreFrames    = errors.New("need more CRYPTO frames")
)
View Source
var (
	ErrNotQUICLongHeaderFormat = errors.New("not a QUIC Long Header Format Packet")
	ErrNotQUICInitialPacket    = errors.New("not a QUIC Initial Packet")
)

Functions

func ClientInitialKeysCalc

func ClientInitialKeysCalc(initialRandom []byte) (clientKey, clientIV, clientHpKey []byte, err error)

ClientInitialKeysCalc calculates the client key, IV and header protection key from the initial random.

func ComputeHeaderProtection

func ComputeHeaderProtection(clientHpKey, sample []byte) ([]byte, error)

ComputeHeaderProtection computes the header protection for the client.

func DecodeQUICHeaderAndFrames

func DecodeQUICHeaderAndFrames(p []byte) (hdr *QUICHeader, frames QUICFrames, err error)

DecodeQUICHeaderAndFrames decodes a QUIC initial packet and returns a QUICHeader.

func DecodeVLI

func DecodeVLI(vli []byte) (val uint64, err error)

DecodeVLI decodes a variable-length integer from the given byte slice.

func DecryptAES128GCM

func DecryptAES128GCM(iv []byte, recordNum uint64, key, ciphertext, recdata, authtag []byte) (plaintext []byte, err error)

DecryptAES128GCM decrypts the AES-128-GCM encrypted data.

func IsGREASETransportParameter

func IsGREASETransportParameter(paramType uint64) bool

IsGREASETransportParameter checks if the given transport parameter type is a GREASE value.

func ReadNextVLI

func ReadNextVLI(r io.Reader) (val uint64, n int, err error)

ReadNextVLI unpacks the next variable-length integer from the given io.Reader. It returns the decoded value and the number of bytes read. For example:

0x0a -> 0xa, 1
0x80 0x10 0x00 0x00 -> 0x100000, 4

func ReassembleCRYPTOFrames

func ReassembleCRYPTOFrames(frames []QUICFrame) ([]byte, error)

ReassembleCRYPTOFrames reassembles CRYPTO frames into a single byte slice that consists of the entire CRYPTO data.

Types

type CRYPTO

type CRYPTO struct {
	Offset uint64 `json:"offset,omitempty"` // offset of crypto data, from VLI
	Length uint64 `json:"length,omitempty"` // length of crypto data, from VLI
	// contains filtered or unexported fields
}

CRYPTO frame

func (*CRYPTO) Data

func (f *CRYPTO) Data() []byte

Data returns a copy of the crypto data.

func (*CRYPTO) FrameType

func (*CRYPTO) FrameType() uint64

FrameType implements QUICFrame interface.

func (*CRYPTO) ReadReader

func (f *CRYPTO) ReadReader(r io.Reader) (rr io.Reader, err error)

ReadFrom implements QUICFrame interface. It reads the offset, length and crypto data from the input reader.

type ClientHello

type ClientHello struct {
	TLSRecordVersion    uint16 `json:"tls_record_version"`    // TLS record version (major, minor)
	TLSHandshakeVersion uint16 `json:"tls_handshake_version"` // TLS handshake version (major, minor)

	CipherSuites         []uint16       `json:"cipher_suites"`
	CompressionMethods   utils.Uint8Arr `json:"compression_methods"`
	Extensions           []uint16       `json:"extensions"`            // extension IDs in original order
	ExtensionsNormalized []uint16       `json:"extensions_normalized"` // sorted extension IDs

	ServerName          string         `json:"server_name"`            // server_name(0)
	NamedGroupList      []uint16       `json:"supported_groups"`       // supported_groups(10) a.k.a elliptic_curves
	ECPointFormatList   utils.Uint8Arr `json:"ec_point_formats"`       // ec_point_formats(11)
	SignatureSchemeList []uint16       `json:"signature_algorithms"`   // signature_algorithms(13)
	ALPN                []string       `json:"alpn"`                   // alpn(16)
	CertCompressAlgo    []uint16       `json:"compress_certificate"`   // compress_certificate(27)
	RecordSizeLimit     utils.Uint8Arr `json:"record_size_limit"`      // record_size_limit(28)
	SupportedVersions   []uint16       `json:"supported_versions"`     // supported_versions(43)
	PSKKeyExchangeModes utils.Uint8Arr `json:"psk_key_exchange_modes"` // psk_key_exchange_modes(45)
	KeyShare            []uint16       `json:"key_share"`              // key_share(51)
	ApplicationSettings []string       `json:"application_settings"`   // application_settings(17513) a.k.a ALPS

	UserAgent string `json:"user_agent,omitempty"` // User-Agent header, set by the caller

	NumID     int64  `json:"num_id,omitempty"`      // NID of the fingerprint
	NormNumID int64  `json:"norm_num_id,omitempty"` // Normalized NID of the fingerprint
	HexID     string `json:"hex_id,omitempty"`      // ID of the fingerprint (hex string)
	NormHexID string `json:"norm_hex_id,omitempty"` // Normalized ID of the fingerprint (hex string)
	// contains filtered or unexported fields
}

ClientHello represents a captured ClientHello message with all fingerprintable fields.

func ReadClientHello

func ReadClientHello(r io.Reader) (ch *ClientHello, err error)

ReadClientHello reads a ClientHello from a connection (io.Reader) and returns a ClientHello struct.

It will return an error if the reader does not give a stream of bytes representing a valid ClientHello. But all bytes read from the reader will be stored in the ClientHello struct to be rewinded by the caller if ever needed.

This function does not automatically call ClientHello.ParseClientHello.

func UnmarshalClientHello

func UnmarshalClientHello(p []byte) (ch *ClientHello, err error)

UnmarshalClientHello unmarshals a ClientHello from a byte slice and returns a ClientHello struct. Any extra bytes after the ClientHello message will be ignored.

This function automatically calls ClientHello.ParseClientHello.

func (*ClientHello) ParseClientHello

func (ch *ClientHello) ParseClientHello() error

ParseClientHello parses the raw bytes of a ClientHello into a ClientHello struct.

func (*ClientHello) Raw

func (ch *ClientHello) Raw() []byte

type ClientInitial

type ClientInitial struct {
	Header     *QUICHeader `json:"header,omitempty"` // QUIC header
	FrameTypes []uint64    `json:"frames,omitempty"` // frames ID in order
	// contains filtered or unexported fields
}

ClientInitial represents a QUIC Initial Packet sent by the Client.

func UnmarshalQUICClientInitialPacket

func UnmarshalQUICClientInitialPacket(p []byte) (ci *ClientInitial, err error)

UnmarshalQUICClientInitialPacket is similar to ParseQUICCIP, but on error such as ClientHello cannot be parsed, it returns a partially completed ClientInitialPacket instead of nil.

type FingerprintID

type FingerprintID int64

FingerprintID is the type of fingerprint ID.

func (FingerprintID) AsHex

func (id FingerprintID) AsHex() string

AsHex returns the hex representation of this fingerprint ID.

type Frame deprecated

type Frame = QUICFrame

This is an old name reserved for compatibility purpose, it is equivalent to QUICFrame.

Deprecated: use the new name QUICFrame instead.

type GatheredClientInitials

type GatheredClientInitials struct {
	Packets []*ClientInitial `json:"packets,omitempty"` // sorted by ClientInitial.PacketNumber

	ClientHello         *QUICClientHello         `json:"client_hello,omitempty"`         // TLS ClientHello
	TransportParameters *QUICTransportParameters `json:"transport_parameters,omitempty"` // QUIC Transport Parameters extracted from the extension in ClientHello

	HexID string `json:"hex_id,omitempty"`
	NumID uint64 `json:"num_id,omitempty"`
	// contains filtered or unexported fields
}

GatheredClientInitials represents a series of Initial Packets sent by the Client to initiate the QUIC handshake.

func GatherClientInitials

func GatherClientInitials() *GatheredClientInitials

GatherClientInitialPackets reads a series of Client Initial Packets from the input channel and returns the result of the gathered packets.

func GatherClientInitialsWithDeadline

func GatherClientInitialsWithDeadline(deadline time.Time) *GatheredClientInitials

GatherClientInitialsWithDeadline is a helper function to create a GatheredClientInitials with a deadline.

func (*GatheredClientInitials) AddPacket

func (gci *GatheredClientInitials) AddPacket(cip *ClientInitial) error

func (*GatheredClientInitials) Completed

func (gci *GatheredClientInitials) Completed() bool

Completed returns true if the GatheredClientInitials is complete.

func (*GatheredClientInitials) Expired

func (gci *GatheredClientInitials) Expired() bool

Expired returns true if the GatheredClientInitials has expired.

func (*GatheredClientInitials) SetDeadline

func (gci *GatheredClientInitials) SetDeadline(deadline time.Time)

SetDeadline sets the deadline for the GatheredClientInitials to complete.

func (*GatheredClientInitials) SetMaxPacketCount

func (gci *GatheredClientInitials) SetMaxPacketCount(maxPacketCount uint64)

SetMaxPacketCount sets the maximum number of packets to be gathered. If more Client Initial packets are received, they will be rejected.

This function can be used as a precaution against memory exhaustion attacks.

func (*GatheredClientInitials) SetMaxPacketNumber

func (gci *GatheredClientInitials) SetMaxPacketNumber(maxPacketNumber uint64)

SetMaxPacketNumber sets the maximum packet number to be gathered. If a Client Initial packet with a higher packet number is received, it will be rejected.

This function can be used as a precaution against memory exhaustion attacks.

func (*GatheredClientInitials) Wait

func (gci *GatheredClientInitials) Wait() error

Wait blocks until the GatheredClientInitials is complete or expired.

type PADDING

type PADDING struct {
	Length uint64 `json:"length,omitempty"` // count 0x00 bytes until not 0x00
}

PADDING frame

func (*PADDING) FrameType

func (*PADDING) FrameType() uint64

FrameType implements QUICFrame interface.

func (*PADDING) ReadReader

func (f *PADDING) ReadReader(r io.Reader) (rr io.Reader, err error)

ReadFrom implements QUICFrame interface. It keeps reading until it finds a non-zero byte, then the non-zero byte is rewinded back to the reader and the reader is returned.

type PING

type PING struct{}

PING frame

func (*PING) FrameType

func (*PING) FrameType() uint64

FrameType implements QUICFrame interface.

func (*PING) ReadReader

func (*PING) ReadReader(r io.Reader) (rr io.Reader, err error)

ReadFrom implements QUICFrame interface. It does nothing and returns the input reader.

type QUICClientHello

type QUICClientHello struct {
	ClientHello
}

QUICClientHello represents a QUIC ClientHello.

func ParseQUICClientHello

func ParseQUICClientHello(p []byte) (*QUICClientHello, error)

ParseQUICClientHello parses a QUIC ClientHello from a QUIC Initial Packet.

func (*QUICClientHello) Raw

func (qch *QUICClientHello) Raw() []byte

Raw returns the raw bytes of the QUIC ClientHello.

type QUICClientHelloReconstructor

type QUICClientHelloReconstructor struct {
	// contains filtered or unexported fields
}

QUICClientHello can be used to parse fragments of a QUIC ClientHello.

func NewQUICClientHelloReconstructor

func NewQUICClientHelloReconstructor() *QUICClientHelloReconstructor

NewQUICClientHelloReconstructor creates a new QUICClientHelloReconstructor.

func (*QUICClientHelloReconstructor) AddCRYPTOFragment

func (qchr *QUICClientHelloReconstructor) AddCRYPTOFragment(offset uint64, frag []byte) error

AddCRYPTOFragment adds a CRYPTO frame fragment to the reconstructor. By default, all fragments are saved into an internal map as a pending fragment, UNLESS all fragments before it have been reassembled. If the fragment is the last one, it will return io.EOF.

func (*QUICClientHelloReconstructor) FromFrames

func (qr *QUICClientHelloReconstructor) FromFrames(frames []Frame) error

FromFrames reassembles the ClientHello from the CRYPTO frames

func (*QUICClientHelloReconstructor) Reconstruct

func (qchr *QUICClientHelloReconstructor) Reconstruct() (*QUICClientHello, error)

Reconstruct reassembles the ClientHello as a QUICClientHello struct.

func (*QUICClientHelloReconstructor) ReconstructAsBytes

func (qchr *QUICClientHelloReconstructor) ReconstructAsBytes() []byte

ReconstructAsBytes reassembles the ClientHello as bytes.

type QUICFingerprint

type QUICFingerprint struct {
	ClientInitials *GatheredClientInitials

	HexID string `json:"hex_id,omitempty"`
	NumID uint64 `json:"num_id,omitempty"`

	UserAgent string `json:"user_agent,omitempty"` // User-Agent header, set by the caller
}

QUICFingerprint can be used to generate a fingerprint of a QUIC connection.

func GenerateQUICFingerprint

func GenerateQUICFingerprint(gci *GatheredClientInitials) (*QUICFingerprint, error)

GenerateQUICFingerprint generates a QUICFingerprint from the gathered ClientInitials.

type QUICFingerprinter

type QUICFingerprinter struct {
	// contains filtered or unexported fields
}

QUICFingerprinter can be used to fingerprint QUIC connections.

func NewQUICFingerprinter

func NewQUICFingerprinter() *QUICFingerprinter

NewQUICFingerprinter creates a new QUICFingerprinter.

func NewQUICFingerprinterWithTimeout

func NewQUICFingerprinterWithTimeout(timeout time.Duration) *QUICFingerprinter

NewQUICFingerprinterWithTimeout creates a new QUICFingerprinter with a timeout.

func (*QUICFingerprinter) Close

func (qfp *QUICFingerprinter) Close()

Close closes the QUICFingerprinter.

func (*QUICFingerprinter) HandleIPConn

func (qfp *QUICFingerprinter) HandleIPConn(ipc *net.IPConn) error

HandleIPConn handles a QUIC connection over IP.

func (*QUICFingerprinter) HandlePacket

func (qfp *QUICFingerprinter) HandlePacket(from string, p []byte) error

HandlePacket handles a QUIC packet.

func (*QUICFingerprinter) HandleUDPConn

func (qfp *QUICFingerprinter) HandleUDPConn(pc net.PacketConn) error

HandleUDPConn handles a QUIC connection over UDP.

func (*QUICFingerprinter) Peek

func (qfp *QUICFingerprinter) Peek(from string) *QUICFingerprint

Peek looks up a QUICFingerprint for a given key.

func (*QUICFingerprinter) PeekAwait

func (qfp *QUICFingerprinter) PeekAwait(from string) (*QUICFingerprint, error)

PeekAwait looks up a QUICFingerprint for a given key. It will wait for the gathering to complete if the key exists but the gathering is not yet complete, e.g., when CRYPTO frames spread across multiple initial packets and some but not all of them are received.

func (*QUICFingerprinter) Pop

func (qfp *QUICFingerprinter) Pop(from string) *QUICFingerprint

Pop looks up a QUICFingerprint for a given key and deletes it from the fingerprinter if found.

func (*QUICFingerprinter) PopAwait

func (qfp *QUICFingerprinter) PopAwait(from string) (*QUICFingerprint, error)

PopAwait looks up a QUICFingerprint for a given key and deletes it from the fingerprinter if found. It will wait for the gathering to complete if the key exists but the gathering is not yet complete, e.g., when CRYPTO frames spread across multiple initial packets and some but not all of them are received.

func (*QUICFingerprinter) SetTimeout

func (qfp *QUICFingerprinter) SetTimeout(timeout time.Duration)

SetTimeout sets the timeout for gathering ClientInitials.

type QUICFrame

type QUICFrame interface {
	// FrameType returns the type of the frame.
	FrameType() uint64

	// ReadReader takes a Reader and reads the rest of the frame from it,
	// starting from the first byte after the frame type.
	//
	// The returned io.Reader contains the rest of the frame, it could be
	// the input Reader itself (if no extra bytes are read) or a rewinded
	// Reader (if extra bytes are read and rewinding is needed).
	ReadReader(io.Reader) (io.Reader, error)
}

QUICFrame is the interface that wraps the basic methods of a QUIC frame.

func ReadAllFrames

func ReadAllFrames(r io.Reader) ([]QUICFrame, error)

ReadAllFrames reads all QUIC frames from the input reader.

type QUICFrames

type QUICFrames []QUICFrame

QUICFrames is a slice of QUICFrame.

func (QUICFrames) FrameTypes

func (qfs QUICFrames) FrameTypes() []uint64

FrameTypes returns the frame types of all QUIC frames.

func (QUICFrames) FrameTypesUint8

func (qfs QUICFrames) FrameTypesUint8() []uint8

FrameTypesUint8 returns the frame types of all QUIC frames as uint8.

type QUICHeader

type QUICHeader struct {
	Version      utils.Uint8Arr `json:"version,omitempty"` // 4-byte version
	DCIDLength   uint32         `json:"dest_conn_id_len,omitempty"`
	SCIDLength   uint32         `json:"source_conn_id_len,omitempty"`
	PacketNumber utils.Uint8Arr `json:"packet_number,omitempty"` // VLI

	HasToken bool `json:"token,omitempty"`
	// contains filtered or unexported fields
}

QUICHeader includes header fields of a QUIC packet and the following frames. It is used to calculate the fingerprint of a QUIC Header.

type QUICTransportParameters

type QUICTransportParameters struct {
	MaxIdleTimeout                 utils.Uint8Arr `json:"max_idle_timeout,omitempty"`
	MaxUDPPayloadSize              utils.Uint8Arr `json:"max_udp_payload_size,omitempty"`
	InitialMaxData                 utils.Uint8Arr `json:"initial_max_data,omitempty"`
	InitialMaxStreamDataBidiLocal  utils.Uint8Arr `json:"initial_max_stream_data_bidi_local,omitempty"`
	InitialMaxStreamDataBidiRemote utils.Uint8Arr `json:"initial_max_stream_data_bidi_remote,omitempty"`
	InitialMaxStreamDataUni        utils.Uint8Arr `json:"initial_max_stream_data_uni,omitempty"`
	InitialMaxStreamsBidi          utils.Uint8Arr `json:"initial_max_streams_bidi,omitempty"`
	InitialMaxStreamsUni           utils.Uint8Arr `json:"initial_max_streams_uni,omitempty"`
	AckDelayExponent               utils.Uint8Arr `json:"ack_delay_exponent,omitempty"`
	MaxAckDelay                    utils.Uint8Arr `json:"max_ack_delay,omitempty"`

	ActiveConnectionIDLimit utils.Uint8Arr `json:"active_connection_id_limit,omitempty"`
	QTPIDs                  []uint64       `json:"tpids,omitempty"` // sorted

	HexID string `json:"hex_id,omitempty"`
	NumID uint64 `json:"num_id,omitempty"`
	// contains filtered or unexported fields
}

QUICTransportParameters is a struct to hold the parsed QUIC transport parameters as a combination.

func ParseQUICTransportParameters

func ParseQUICTransportParameters(extData []byte) *QUICTransportParameters

ParseQUICTransportParameters parses the transport parameters from the extension data of TLS Extension "QUIC Transport Parameters" (57)

If any error occurs, the returned struct will have parseError set to the error.

func (*QUICTransportParameters) ParseError

func (qtp *QUICTransportParameters) ParseError() error

ParseError returns the error that occurred during parsing, if any.

type TLSFingerprinter

type TLSFingerprinter struct {
	// contains filtered or unexported fields
}

TLSFingerprinter can be used to fingerprint TLS connections.

func NewTLSFingerprinter

func NewTLSFingerprinter() *TLSFingerprinter

NewTLSFingerprinter creates a new TLSFingerprinter.

func NewTLSFingerprinterWithTimeout

func NewTLSFingerprinterWithTimeout(timeout time.Duration) *TLSFingerprinter

NewTLSFingerprinterWithTimeout creates a new TLSFingerprinter with a timeout.

func (*TLSFingerprinter) Close

func (tfp *TLSFingerprinter) Close()

Close closes the TLSFingerprinter.

func (*TLSFingerprinter) HandleMessage

func (tfp *TLSFingerprinter) HandleMessage(from string, p []byte) error

HandleMessage handles a message.

func (*TLSFingerprinter) HandleTCPConn

func (tfp *TLSFingerprinter) HandleTCPConn(conn net.Conn) (rewindConn net.Conn, err error)

HandleTCPConn handles a TCP connection.

func (*TLSFingerprinter) Peek

func (tfp *TLSFingerprinter) Peek(from string) *ClientHello

Peek looks up a ClientHello for a given key.

func (*TLSFingerprinter) Pop

func (tfp *TLSFingerprinter) Pop(from string) *ClientHello

Pop looks up a ClientHello for a given key and deletes it from the fingerprinter if found.

func (*TLSFingerprinter) SetTimeout

func (tfp *TLSFingerprinter) SetTimeout(timeout time.Duration)

SetTimeout sets the timeout for the TLSFingerprinter.

Directories

Path Synopsis
internal
app

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL