What DefaultConfig sets¶
DefaultConfig() returns a fresh *crypto/tls.Config with three fields set and
everything else left at its zero value. Every config the package hands out —
Pair.ServerConfig and ClientConfig — starts from this function, so these values
apply to both ends of a connection.
Each call returns a new config. Mutating one does not affect another.
The three fields it sets¶
| Field | Value |
|---|---|
MinVersion |
tls.VersionTLS12 (0x0303, decimal 771) |
CipherSuites |
six ECDHE-AEAD suites, listed below |
CurvePreferences |
tls.X25519, then tls.CurveP256 |
The cipher suite list, in the order the source declares it:
| Suite | Constant value |
|---|---|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 |
0xc02c |
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 |
0xc030 |
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 |
0xc02b |
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 |
0xc02f |
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 |
0xcca9 |
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 |
0xcca8 |
The reasoning behind each choice is in the threat model.
Which TLS version actually gets negotiated¶
MaxVersion is left at zero, which crypto/tls reads as "the highest version this
Go toolchain supports". Two configs built from DefaultConfig negotiate TLS 1.3;
MinVersion only sets the floor for peers that cannot do 1.3.
At TLS 1.3 the CipherSuites list has no effect — the 1.3 suites are fixed by the
protocol and chosen by the runtime. A connection between two DefaultConfig peers
therefore uses TLS_AES_128_GCM_SHA256, which is not in the list above and is not
meant to be. The list governs TLS 1.2 connections.
Go also picks the mutually preferred suite itself; the list says which suites are permitted, not a server-dictated order.
Which fields DefaultConfig deliberately leaves alone¶
Everything not in the table above is the crypto/tls zero value. The ones worth
knowing:
| Field | Left at | Consequence |
|---|---|---|
MaxVersion |
0 |
Highest supported version — TLS 1.3 today |
Certificates |
empty | ServerConfig and ApplyTo append; ClientConfig never does |
RootCAs |
nil |
Client trusts the system root store, unless ClientConfig was given CA files |
ClientCAs / ClientAuth |
nil / NoClientCert |
No client-certificate auth until a Pair supplies one |
InsecureSkipVerify |
false |
Certificate verification is on, and this package offers no way to turn it off |
NextProtos |
empty | No ALPN advertised until you pass protocols to ServerConfig or ApplyTo |
SessionTicketsDisabled |
false |
TLS 1.2 session tickets stay enabled; no ticket key rotation is configured |
ClientSessionCache |
nil |
The package configures no client-side session resumption |
Renegotiation |
RenegotiateNever |
Renegotiation refused, the crypto/tls default |
VerifyPeerCertificate / VerifyConnection |
nil |
No extra verification hooks; add your own and merge with ApplyTo |
GetCertificate |
nil |
One static certificate per config; no SNI selection and no reload |
Key exchange is weaker than Go's own default¶
Setting CurvePreferences explicitly opts out of the post-quantum hybrid key
exchange that Go enables by default. With a nil CurvePreferences, Go 1.26
negotiates X25519MLKEM768. A config from DefaultConfig negotiates plain
X25519, because that list does not include the hybrid.
This matters for traffic an attacker can record now and decrypt later, once a cryptographically relevant quantum computer exists. If that is in your threat model, clear the field on the config you get back:
Everything else — the TLS 1.2 floor and the AEAD-only suite list — survives, because they are separate fields.
What it is worth compared with a zero-value config¶
Go's own defaults have moved a long way, and much of what a hardened config used to
buy is now standard. On Go 1.26 a zero-value tls.Config already refuses TLS 1.0 and
1.1 on both sides, and already excludes static-RSA key exchange from the suites it
will negotiate.
Three things DefaultConfig still adds:
- No CBC suites. Go's default TLS 1.2 suite list still contains four ECDHE-CBC-SHA
suites (
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHAand relatives).DefaultConfigdrops them, leaving AEAD only. - A floor no GODEBUG can lower. Go's TLS 1.2 default floor is a default:
GODEBUG=tls10server=1restores TLS 1.0 on a zero-value server config. An explicitMinVersionis unaffected by that setting. - A fixed posture across toolchains. The stdlib default suite list changes between Go releases. This one changes when this package changes.
And one thing it costs: the post-quantum key exchange described above.