Documentation
¶
Index ¶
- Constants
- Variables
- func ClientInitialKeysCalc(initialRandom []byte) (clientKey, clientIV, clientHpKey []byte, err error)
- func ComputeHeaderProtection(clientHpKey, sample []byte) ([]byte, error)
- func DecodeVLI(vli []byte) (val uint64, err error)
- func DecryptAES128GCM(iv []byte, recordNum uint64, key, ciphertext, recdata, authtag []byte) (plaintext []byte, err error)
- func IsGREASETransportParameter(paramType uint64) bool
- func ReadNextVLI(r io.Reader) (val uint64, n int, err error)
- func ReassembleCRYPTOFrames(frames []Frame) ([]byte, error)
- type CRYPTO
- type ClientHello
- type ClientInitialPacket
- type Frame
- type PADDING
- type PING
- type QUICClientHello
- type QUICHeader
- type QUICTransportParameters
Constants ¶
const ( QUICFrame_PADDING uint64 = 0 // 0 QUICFrame_PING uint64 = 1 // 1 QUICFrame_CRYPTO uint64 = 6 // 6 )
const ( QTP_GREASE = 27 UNSET_VLI_BITS = true // if false, unsetVLIBits() will be nop )
Variables ¶
var ( ErrNotQUICLongHeaderFormat = errors.New("packet is not in QUIC Long Header Format") ErrNotQUICInitialPacket = errors.New("packet is not a QUIC Initial Packet") )
var (
ErrNoQUICClientHello = errors.New("no QUIC ClientHello found in the packet")
)
Functions ¶
func ClientInitialKeysCalc ¶ added in v0.3.0
func ComputeHeaderProtection ¶ added in v0.3.0
func DecryptAES128GCM ¶ added in v0.3.0
func IsGREASETransportParameter ¶ added in v0.3.0
func ReadNextVLI ¶ added in v0.3.0
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 ¶ added in v0.3.0
Types ¶
type CRYPTO ¶ added in v0.3.0
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
Data []byte `json:"data,omitempty"` // crypto data
}
CRYPTO frame
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)
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
NID int64 `json:"nid,omitempty"` // NID of the fingerprint
NormNID int64 `json:"norm_nid,omitempty"` // Normalized NID of the fingerprint
ID string `json:"id,omitempty"` // ID of the fingerprint (hex string)
NormID string `json:"norm_id,omitempty"` // Normalized ID of the fingerprint (hex string)
// contains filtered or unexported 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.
func (*ClientHello) FingerprintID ¶
func (ch *ClientHello) FingerprintID(normalized bool) string
FingerprintID calculates fingerprint ID of ClientHello and represents it as hexadecimal string.
func (*ClientHello) FingerprintNID ¶
func (ch *ClientHello) FingerprintNID(normalized bool) int64
FingerprintNID calculates fingerprint Numerical ID of ClientHello. Fingerprint is defined by
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 ClientInitialPacket ¶ added in v0.3.0
type ClientInitialPacket struct {
QHdr *QUICHeader `json:"quic_header,omitempty"` // QUIC header, set by the caller
QCH *QUICClientHello `json:"quic_client_hello,omitempty"` // TLS ClientHello, set by the caller
QTP *QUICTransportParameters `json:"quic_transport_parameters,omitempty"` // QUIC Transport Parameters, set by the caller
UserAgent string `json:"user_agent,omitempty"` // User-Agent header, set by the caller
// contains filtered or unexported fields
}
func ParseQUICCIP ¶ added in v0.3.0
func ParseQUICCIP(p []byte) (*ClientInitialPacket, error)
type Frame ¶ added in v0.3.0
type Frame 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)
}
type PADDING ¶ added in v0.3.0
type PADDING struct {
Length uint64 `json:"length,omitempty"` // count 0x00 bytes until not 0x00
}
PADDING frame
type PING ¶ added in v0.3.0
type PING struct{}
PING frame
type QUICClientHello ¶ added in v0.3.0
type QUICClientHello struct {
ClientHello
}
func ParseQUICClientHello ¶ added in v0.3.0
func ParseQUICClientHello(p []byte) (*QUICClientHello, error)
func (*QUICClientHello) Raw ¶ added in v0.3.0
func (qch *QUICClientHello) Raw() []byte
type QUICHeader ¶ added in v0.3.0
type QUICHeader struct {
InitialPacketNumberLength uint32 `json:"pn_len,omitempty"` // TODO: from Packet Header Byte, +1 or not?
VersionLength uint32 `json:"ver_len,omitempty"` // TODO: is it not fixed 4-byte?
Version utils.Uint8Arr `json:"version,omitempty"` // 4-byte version
DCIDLength uint32 `json:"dcid_len,omitempty"`
SCIDLength uint32 `json:"scid_len,omitempty"`
TokenLength uint32 `json:"token_len,omitempty"`
InitialPacketNumber uint32 `json:"pn,omitempty"` // TODO: protected or unprotected?
// These two fields are not strictly part of QUIC header, but we need them before parsing QUIC ClientHello
FramesPresentLength uint32 `json:"frames_present_len,omitempty"` // TODO: length of all frames OR number of frames?
FrameIDs []uint32 `json:"frame_id,omitempty"` // sorted
// contains filtered or unexported fields
}
func DecodeQUICHeaderAndFrames ¶ added in v0.3.0
func DecodeQUICHeaderAndFrames(p []byte) (*QUICHeader, error)
type QUICTransportParameters ¶ added in v0.3.0
type QUICTransportParameters struct {
MaxIdleTimeoutLength uint32 `json:"max_idle_timeout_len,omitempty"`
MaxIdleTimeout utils.Uint8Arr `json:"max_idle_timeout,omitempty"`
MaxUDPPayloadSizeLength uint32 `json:"max_udp_payload_size_len,omitempty"`
MaxUDPPayloadSize utils.Uint8Arr `json:"max_udp_payload_size,omitempty"`
InitialMaxDataLength uint32 `json:"initial_max_data_len,omitempty"`
InitialMaxData utils.Uint8Arr `json:"initial_max_data,omitempty"`
InitialMaxStreamDataBidiLocalLength uint32 `json:"initial_max_stream_data_bidi_local_len,omitempty"`
InitialMaxStreamDataBidiLocal utils.Uint8Arr `json:"initial_max_stream_data_bidi_local,omitempty"`
InitialMaxStreamDataBidiRemoteLength uint32 `json:"initial_max_stream_data_bidi_remote_len,omitempty"`
InitialMaxStreamDataBidiRemote utils.Uint8Arr `json:"initial_max_stream_data_bidi_remote,omitempty"`
InitialMaxStreamDataUniLength uint32 `json:"initial_max_stream_data_uni_len,omitempty"`
InitialMaxStreamDataUni utils.Uint8Arr `json:"initial_max_stream_data_uni,omitempty"`
InitialMaxStreamsBidiLength uint32 `json:"initial_max_streams_bidi_len,omitempty"`
InitialMaxStreamsBidi utils.Uint8Arr `json:"initial_max_streams_bidi,omitempty"`
InitialMaxStreamsUniLength uint32 `json:"initial_max_streams_uni_len,omitempty"`
InitialMaxStreamsUni utils.Uint8Arr `json:"initial_max_streams_uni,omitempty"`
AckDelayExponentLength uint32 `json:"ack_delay_exponent_len,omitempty"`
AckDelayExponent utils.Uint8Arr `json:"ack_delay_exponent,omitempty"`
MaxAckDelayLength uint32 `json:"max_ack_delay_len,omitempty"`
MaxAckDelay utils.Uint8Arr `json:"max_ack_delay,omitempty"`
ActiveConnectionIDLimitLength uint32 `json:"active_connection_id_limit_len,omitempty"`
ActiveConnectionIDLimit utils.Uint8Arr `json:"active_connection_id_limit,omitempty"`
QTPIDs []uint64 `json:"qtpid,omitempty"` // sorted
QTPIDSum uint64 `json:"qtpid_sum,omitempty"`
// contains filtered or unexported fields
}
func ParseQUICTransportParameters ¶ added in v0.3.0
func ParseQUICTransportParameters(extData []byte) *QUICTransportParameters