Documentation
¶
Overview ¶
Package scanner enumerates TLS protocol versions, cipher suites and key exchange groups by sending its own ClientHello messages and reading only the server's reply. It does not depend on which algorithms the local TLS library implements, so it can detect SSLv2, export and NULL ciphers that no modern client would negotiate. Probes never complete a handshake and send no application data.
Index ¶
- Constants
- Variables
- func AlertName(d byte) string
- func ExtensionName(t uint16) string
- func GroupBits(g uint16) int
- func GroupName(g uint16) string
- func LegacySuites() []uint16
- func TLS13Suites() []uint16
- func VersionName(v uint16) string
- type AcceptedSuite
- type AlertError
- type CipherResult
- type Dialer
- type Extras
- type GroupResult
- type Hello
- type KeyExchange
- type Prober
- func (p *Prober) CheckExtras(ctx context.Context, minLegacy, maxLegacy uint16) Extras
- func (p *Prober) Ciphers(ctx context.Context, v uint16) CipherResult
- func (p *Prober) CiphersAll(ctx context.Context, versions []uint16) []CipherResult
- func (p *Prober) Curves12(ctx context.Context, v uint16, ecdheSuites []uint16) []string
- func (p *Prober) Groups13(ctx context.Context) []string
- func (p *Prober) ProbeVersion(ctx context.Context, v uint16) VersionResult
- func (p *Prober) Send(ctx context.Context, h *Hello, wantMore bool) (*ServerHello, error)
- func (p *Prober) Versions(ctx context.Context) []VersionResult
- type ServerHello
- type Suite
- type VersionResult
Constants ¶
const ( VersionSSL2 uint16 = 0x0002 VersionSSL3 uint16 = 0x0300 VersionTLS10 uint16 = 0x0301 VersionTLS11 uint16 = 0x0302 VersionTLS12 uint16 = 0x0303 VersionTLS13 uint16 = 0x0304 )
Protocol version codes.
const ( GroupSecp256r1 uint16 = 23 GroupSecp384r1 uint16 = 24 GroupSecp521r1 uint16 = 25 GroupX25519 uint16 = 29 GroupX448 uint16 = 30 GroupFFDHE2048 uint16 = 256 GroupFFDHE3072 uint16 = 257 GroupFFDHE4096 uint16 = 258 GroupFFDHE6144 uint16 = 259 GroupFFDHE8192 uint16 = 260 GroupX25519MLKEM768 uint16 = 0x11EC GroupP256MLKEM768 uint16 = 0x11EB GroupP384MLKEM1024 uint16 = 0x11ED )
Named groups.
Variables ¶
var AllVersions = []uint16{VersionSSL2, VersionSSL3, VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13}
AllVersions is the probe order.
var ErrNotTLS = errors.New("server response is not TLS")
ErrNotTLS means the peer answered with something that is not TLS.
var ErrRejected = errors.New("rejected by server")
ErrRejected means the server refused the offered parameters (alert, or closed the connection) — i.e. "not supported".
var TLS13Groups = []uint16{GroupX25519MLKEM768, GroupP256MLKEM768, GroupP384MLKEM1024, GroupX25519, GroupSecp256r1, GroupSecp384r1, GroupSecp521r1, GroupX448, GroupFFDHE2048, GroupFFDHE3072, GroupFFDHE4096, GroupFFDHE6144, GroupFFDHE8192}
TLS13Groups are probed individually in TLS 1.3 group enumeration.
Functions ¶
func TLS13Suites ¶
func TLS13Suites() []uint16
TLS13Suites returns the TLS 1.3 suites in registry order.
Types ¶
type AcceptedSuite ¶
type AcceptedSuite struct {
Suite
KeyExchange *KeyExchange `json:"key_exchange_params,omitempty"`
}
AcceptedSuite is a cipher suite the server negotiated.
type AlertError ¶
AlertError is a TLS alert received instead of a ServerHello.
func (*AlertError) Error ¶
func (e *AlertError) Error() string
type CipherResult ¶
type CipherResult struct {
Version string `json:"version"`
ID uint16 `json:"id"`
Suites []AcceptedSuite `json:"suites"`
ServerPreferred *bool `json:"server_order,omitempty"` // nil when fewer than two suites
Error string `json:"error,omitempty"`
}
CipherResult lists the suites accepted for one version.
type Dialer ¶
Dialer returns a connection that is ready for a ClientHello: for STARTTLS protocols the plaintext upgrade has already happened.
type Extras ¶
type Extras struct {
SecureRenegotiation *bool `json:"secure_renegotiation,omitempty"` // RFC 5746
FallbackSCSV *bool `json:"fallback_scsv,omitempty"` // RFC 7507; nil if not testable
Compression *bool `json:"compression,omitempty"` // TLS compression accepted (CRIME)
SessionTickets *bool `json:"session_tickets,omitempty"`
ExtendedMasterSecret *bool `json:"extended_master_secret,omitempty"`
EncryptThenMAC *bool `json:"encrypt_then_mac,omitempty"`
Extensions []string `json:"server_extensions,omitempty"` // at the highest TLS ≤1.2 version
}
Extras holds protocol behaviour checks.
type GroupResult ¶
type GroupResult struct {
TLS13 []string `json:"tls13,omitempty"`
TLS12 []string `json:"tls12,omitempty"` // ECDHE curves accepted with TLS ≤1.2
}
GroupResult lists supported key exchange groups.
type Hello ¶
type Hello struct {
Version uint16 // legacy_version field
RecordVersion uint16 // record layer version; 0 = min(Version, TLS 1.0)
Suites []uint16 // cipher suites in preference order
ServerName string // SNI; omitted for IP addresses and when empty
SupportedVersions []uint16 // TLS 1.3 supported_versions; nil omits the extension
Groups []uint16 // supported_groups; nil = default for the version
Compression []byte // compression methods; nil = null only
ALPN []string
Fallback bool // append TLS_FALLBACK_SCSV
NoRenegotiation bool // omit TLS_EMPTY_RENEGOTIATION_INFO_SCSV
}
Hello describes a ClientHello to send.
type KeyExchange ¶
type KeyExchange struct {
Kind string `json:"kind"` // ECDH or DH
Group string `json:"group,omitempty"`
GroupID uint16 `json:"group_id,omitempty"`
Bits int `json:"bits"`
}
KeyExchange describes the server's ephemeral parameters (TLS ≤1.2).
func (*KeyExchange) String ¶
func (k *KeyExchange) String() string
String formats e.g. "ECDH x25519" or "DH 2048 bits".
type Prober ¶
type Prober struct {
Dial Dialer
ServerName string
Timeout time.Duration // per probe; default 10s
Concurrency int // parallel probes; default 8
}
Prober sends ClientHello probes to one endpoint.
func (*Prober) CheckExtras ¶
CheckExtras runs behaviour probes. maxLegacy is the highest supported version ≤ TLS 1.2 (0 if none); minLegacy the lowest ≥ TLS 1.0.
func (*Prober) Ciphers ¶
func (p *Prober) Ciphers(ctx context.Context, v uint16) CipherResult
Ciphers enumerates the suites accepted with version v by repeatedly offering every not-yet-accepted suite. When the server enforces its own order the result is in server preference order.
func (*Prober) CiphersAll ¶
func (p *Prober) CiphersAll(ctx context.Context, versions []uint16) []CipherResult
CiphersAll enumerates suites for each supported version concurrently.
func (*Prober) Curves12 ¶
Curves12 finds ECDHE curves accepted with TLS ≤1.2 using the given ECDHE suites (from cipher enumeration).
func (*Prober) Groups13 ¶
Groups13 finds the TLS 1.3 groups the server accepts. Each probe offers a single group with no key share; a supporting server must answer with a HelloRetryRequest naming that group.
func (*Prober) ProbeVersion ¶
func (p *Prober) ProbeVersion(ctx context.Context, v uint16) VersionResult
ProbeVersion tests whether the server accepts version v.
type ServerHello ¶
type ServerHello struct {
LegacyVersion uint16
Version uint16 // negotiated version (supported_versions if present)
CipherSuite uint16
Compression byte
SessionIDLen int
Extensions []uint16 // extension types in order received
HelloRetry bool
// Filled from later handshake messages for TLS ≤1.2 when requested.
Certificates [][]byte // DER, as sent
KeyExchange *KeyExchange
// contains filtered or unexported fields
}
ServerHello is the parsed server response to a probe.
func (*ServerHello) ExtensionData ¶
func (s *ServerHello) ExtensionData(t uint16) []byte
ExtensionData returns the raw body of extension t.
func (*ServerHello) HasExtension ¶
func (s *ServerHello) HasExtension(t uint16) bool
HasExtension reports whether the server sent extension t.
type Suite ¶
type Suite struct {
ID uint16 `json:"id"`
Name string `json:"name"`
KeyExch string `json:"key_exchange"` // ECDHE, DHE, RSA, ECDH, DH, PSK, SRP, TLS1.3, NULL
Auth string `json:"authentication"` // RSA, ECDSA, DSS, anon, PSK, SRP, any, NULL
Cipher string `json:"cipher"` // AES, 3DES, RC4, CHACHA20, ...
Bits int `json:"bits"`
Mode string `json:"mode"` // GCM, CCM, CCM8, CBC, POLY1305, stream, none
MAC string `json:"mac"` // AEAD, SHA, SHA256, SHA384, MD5
Export bool `json:"export"`
TLS13 bool `json:"tls13"`
Strength string `json:"strength"` // modern, deprecated, weak, insecure
Reasons []string `json:"reasons,omitempty"`
}
Suite describes one cipher suite.
func (Suite) ForwardSecret ¶
ForwardSecret reports whether the key exchange is ephemeral.