tlsdecode

package
v0.331.0 Latest Latest
Warning

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

Go to latest
Published: May 21, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package tlsdecode decodes the cleartext portion of a TLS handshake — the ClientHello and ServerHello records that every TLS connection emits in the clear before encryption is negotiated. This is the workhorse pcap-and-paste tool for SOC blue-team analysis (JA3 / JA4 fingerprinting, plaintext SNI extraction, ALPN inspection), threat-intel triage (cipher-suite weakness scanning, version downgrade detection), and offensive recon (server preference fingerprinting, client-stack identification).

Wrap-vs-native judgement

Native. The TLS record layer and handshake messages are fully published in RFC 5246 (TLS 1.2), RFC 8446 (TLS 1.3), and the IANA TLS registries. Every field is a fixed-length integer, length-prefixed byte string, or list. Extension dispatch is a switch over a 2-byte type. Pasting a hex blob extracted from a Wireshark TLS frame, a tcpdump-of- 443 capture, or a tshark `tls.handshake` field is enough — no cryptography (the cleartext portion is the entire scope), no key material, no live network attach.

What this package covers

  • TLS record layer envelope: ContentType (Handshake / ChangeCipherSpec / Alert / ApplicationData), Version (major + minor, with TLS 1.0..1.3 name lookup), Length. Multiple back-to-back records in one buffer are supported.
  • Handshake message dispatch: ClientHello, ServerHello, HelloRetryRequest, NewSessionTicket, EndOfEarlyData, EncryptedExtensions, Certificate, CertificateRequest, CertificateVerify, Finished, KeyUpdate, MessageHash. Bodies for non-ClientHello / non-ServerHello messages are surfaced as raw hex.
  • ClientHello body: legacy_version, random (32 bytes), legacy_session_id, cipher_suites (with IANA name lookup for ~80 suites covering all current TLS 1.3 suites + the most-deployed TLS 1.2 suites including ECDHE-RSA-AES, ECDHE-ECDSA-AES, ChaCha20-Poly1305, and the deprecated-but-still-seen RSA / 3DES / CBC legacy suites), compression_methods, extensions.
  • ServerHello body: same field layout as ClientHello but with single selected cipher suite + compression method.
  • Extension dispatch with type-name lookup for ~30 IANA- registered extensions. Deep decode for the operationally-important ones:
  • server_name (type 0): extracts the SNI value (only host_name name_type 0 is in scope).
  • supported_groups (type 10): list of named curves / DH groups with name lookup.
  • signature_algorithms (type 13): list of SignatureScheme codes with name lookup.
  • application_layer_protocol_negotiation (type 16, ALPN): list of protocol strings (h2, http/1.1, etc.).
  • supported_versions (type 43): the canonical TLS 1.3 version-negotiation extension.
  • key_share (type 51): list of (group, key) pairs with the group name surfaced.
  • **JA3 fingerprint** (per the Salesforce / John Althouse spec): the comma-separated string "version,cipher_suites,extensions,curves, ec_point_formats" with hyphens between list members, plus its MD5 hash. The standard JA3 client fingerprint identifies the TLS client stack (browser, library, malware family) across thousands of distinct signatures.

What this package does NOT cover (deliberately out of scope)

  • Certificate body decode (X.509 ASN.1 — that's a separate ~600 LoC walker that warrants its own iteration). The Certificate handshake message is labeled but the cert bytes are surfaced as raw hex.
  • Encrypted ApplicationData / CCS / Alert bodies: the record envelope is decoded but the post-handshake ciphertext is opaque without key material.
  • JA4 / JA4S / JA4H / JA4X fingerprinting: the newer fingerprint family (FoxIO LLC, 2023) uses a different scheme; deferred until operators show real demand.
  • TLS 1.3 inner handshake (EncryptedExtensions onward) is encrypted on the wire and requires session-key material that this Spec deliberately does not handle.
  • DTLS (Datagram TLS over UDP) — slight envelope differences (record sequence number); deferred.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CipherSuite

type CipherSuite struct {
	Value uint16 `json:"value"`
	Hex   string `json:"hex"`
	Name  string `json:"name,omitempty"`
}

CipherSuite is one TLS cipher suite reference.

type ClientHello

type ClientHello struct {
	VersionMajor        int           `json:"version_major"`
	VersionMinor        int           `json:"version_minor"`
	VersionName         string        `json:"version_name"`
	RandomHex           string        `json:"random_hex"`
	SessionIDHex        string        `json:"session_id_hex"`
	CipherSuites        []CipherSuite `json:"cipher_suites"`
	CompressionMethods  []int         `json:"compression_methods"`
	Extensions          []*Extension  `json:"extensions,omitempty"`
	ServerName          string        `json:"server_name,omitempty"`
	ALPNProtocols       []string      `json:"alpn_protocols,omitempty"`
	SupportedVersions   []string      `json:"supported_versions,omitempty"`
	SupportedGroups     []string      `json:"supported_groups,omitempty"`
	SignatureAlgorithms []string      `json:"signature_algorithms,omitempty"`
	KeyShareGroups      []string      `json:"key_share_groups,omitempty"`
	JA3                 string        `json:"ja3,omitempty"`
	JA3Hash             string        `json:"ja3_hash,omitempty"`
}

ClientHello is the decoded TLS ClientHello body.

type Extension

type Extension struct {
	Type     int    `json:"type"`
	TypeName string `json:"type_name"`
	Length   int    `json:"length"`
	DataHex  string `json:"data_hex,omitempty"`
}

Extension is one TLS extension.

type Frame

type Frame struct {
	Records []*Record `json:"records"`
}

Frame is a list of decoded TLS records — TCP segments often pack multiple back-to-back records, so the top-level result is always a slice.

func Decode

func Decode(hexBlob string) (*Frame, error)

Decode parses a hex-encoded buffer of one or more TLS records.

func DecodeBytes

func DecodeBytes(b []byte) (*Frame, error)

DecodeBytes parses raw TLS record bytes — one or more back-to-back records.

type Handshake

type Handshake struct {
	MessageType int          `json:"message_type"`
	MessageName string       `json:"message_name"`
	Length      int          `json:"length"`
	ClientHello *ClientHello `json:"client_hello,omitempty"`
	ServerHello *ServerHello `json:"server_hello,omitempty"`
	BodyHex     string       `json:"body_hex,omitempty"`
}

Handshake is one TLS handshake message inside a record.

type Record

type Record struct {
	ContentType  int          `json:"content_type"`
	ContentName  string       `json:"content_name"`
	VersionMajor int          `json:"version_major"`
	VersionMinor int          `json:"version_minor"`
	VersionName  string       `json:"version_name"`
	Length       int          `json:"length"`
	Handshakes   []*Handshake `json:"handshakes,omitempty"`
	BodyHex      string       `json:"body_hex,omitempty"`
}

Record is one TLS record-layer frame.

type ServerHello

type ServerHello struct {
	VersionMajor      int          `json:"version_major"`
	VersionMinor      int          `json:"version_minor"`
	VersionName       string       `json:"version_name"`
	RandomHex         string       `json:"random_hex"`
	SessionIDHex      string       `json:"session_id_hex"`
	CipherSuite       CipherSuite  `json:"cipher_suite"`
	CompressionMethod int          `json:"compression_method"`
	Extensions        []*Extension `json:"extensions,omitempty"`
	NegotiatedALPN    string       `json:"negotiated_alpn,omitempty"`
	NegotiatedVersion string       `json:"negotiated_version,omitempty"`
}

ServerHello is the decoded TLS ServerHello body. Same shape as ClientHello but with a single selected cipher suite + compression method.

Jump to

Keyboard shortcuts

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