Add tlsenum package and add version/cipher enumeration into the checker
tlsenum package probes a remote endpoint with one ClientHello per (version, cipher) pair via utls, so the checker can report the exact set the server accepts rather than only the suite Go's stdlib happens to negotiate. Probe accepts an Upgrader callback so STARTTLS dialects plug in without tlsenum learning about them; the checker bridges its existing dialect registry through upgraderFor.
This commit is contained in:
parent
8a7f9feaf7
commit
a9f37c79cf
18 changed files with 1569 additions and 5 deletions
|
|
@ -22,13 +22,20 @@ func starttlsXMPPServer(conn net.Conn, sni string) error {
|
|||
return starttlsXMPP(conn, sni, "jabber:server")
|
||||
}
|
||||
|
||||
// xmppPreTLSReadLimit caps the bytes the XML decoder may pull from an
|
||||
// untrusted peer before the TLS handshake. The legitimate pre-TLS exchange
|
||||
// (<stream:stream> opening + <stream:features> + <proceed/>) is well under
|
||||
// 1 KiB; 64 KiB is generous for non-malicious servers while bounding memory
|
||||
// against a peer that streams unbounded XML to exhaust the prober.
|
||||
const xmppPreTLSReadLimit = 64 * 1024
|
||||
|
||||
func starttlsXMPP(conn net.Conn, sni, ns string) error {
|
||||
header := fmt.Sprintf(`<?xml version='1.0'?><stream:stream xmlns='%s' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='%s'>`, ns, sni)
|
||||
if _, err := io.WriteString(conn, header); err != nil {
|
||||
return fmt.Errorf("write stream header: %w", err)
|
||||
}
|
||||
|
||||
dec := xml.NewDecoder(conn)
|
||||
dec := xml.NewDecoder(&io.LimitedReader{R: conn, N: xmppPreTLSReadLimit})
|
||||
|
||||
// Read the inbound <stream:stream> opening and its <stream:features>.
|
||||
// A peer that opens with <stream:error/> (or anything other than features)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue