I opted for adding a separate TLS13CipherSuites field to the Config
because library users that did not set Config.MaxVersion are
supposed to get TLS 1.3 support automatically, like it has been for
HTTP/2, but having set CipherSuites would effectively disable it.
Updates #9671
Change-Id: I26a2776b68374d6f5ee45629da09f9494fe723ad
The SignatureAndHashAlgorithm from TLS 1.2[1] is being changed to
SignatureScheme in TLS 1.3[2]. (The actual values are compatible
however.)
Since we expect to support TLS 1.3 in the future, we're already using
the name and style of SignatureScheme in the recently augmented
ClientHelloInfo. As this is public API, it seems that SignatureScheme
should have its own type and exported values, which is implemented in
this change.
[1] https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
[2] https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.3
Change-Id: I0482755d02bb9a04eaf075c012696103eb806645
Reviewed-on: https://go-review.googlesource.com/32119
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
VerifyPeerCertificate returns an error if the peer should not be
trusted. It will be called after the initial handshake and before
any other verification checks on the cert or chain are performed.
This provides the callee an opportunity to augment the certificate
verification.
If VerifyPeerCertificate is not nil and returns an error,
then the handshake will fail.
Fixes#16363
Change-Id: I6a22f199f0e81b6f5d5f37c54d85ab878216bb22
Reviewed-on: https://go-review.googlesource.com/26654
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
GetConfigForClient allows the tls.Config to be updated on a per-client
basis.
Fixes#16066.
Fixes#15707.
Fixes#15699.
Change-Id: I2c675a443d557f969441226729f98502b38901ea
Reviewed-on: https://go-review.googlesource.com/30790
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Add support for writing TLS client random and master secret
in NSS key log format.
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
Normally this is enabled by a developer debugging TLS based
applications, especially HTTP/2, by setting the KeyLogWriter
to an open file. The keys negotiated in handshake are then
logged and can be used to decrypt TLS sessions e.g. in Wireshark.
Applications may choose to add support similar to NSS where this
is enabled by environment variable, but no such mechanism is
built in to Go. Instead each application must explicitly enable.
Fixes#13057.
Change-Id: If6edd2d58999903e8390b1674ba4257ecc747ae1
Reviewed-on: https://go-review.googlesource.com/27434
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This change causes TLS handshake messages to be buffered and written in
a single Write to the underlying net.Conn.
There are two reasons to want to do this:
Firstly, it's slightly preferable to do this in order to save sending
several, small packets over the network where a single one will do.
Secondly, since 37c28759ca46cf381a466e32168a793165d9c9e9 errors from
Write have been returned from a handshake. This means that, if a peer
closes the connection during a handshake, a “broken pipe” error may
result from tls.Conn.Handshake(). This can mask any, more detailed,
fatal alerts that the peer may have sent because a read will never
happen.
Buffering handshake messages means that the peer will not receive, and
possibly reject, any of a flow while it's still being written.
Fixes#15709
Change-Id: I38dcff1abecc06e52b2de647ea98713ce0fb9a21
Reviewed-on: https://go-review.googlesource.com/23609
Reviewed-by: Andrew Gerrand <adg@golang.org>
Run-TryBot: Andrew Gerrand <adg@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Instead, decline the session and do a full handshake. The semantics of
cross-version resume are unclear, and all major client implementations
treat this as a fatal error. (This doesn't come up very much, mostly if
the client does the browser version fallback without sharding the
session cache.)
See BoringSSL's bdf5e72f50e25f0e45e825c156168766d8442dde and OpenSSL's
9e189b9dc10786c755919e6792e923c584c918a1.
Change-Id: I51ca95ac1691870dd0c148fd967739e2d4f58824
Reviewed-on: https://go-review.googlesource.com/21152
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This change adds Config.Renegotiation which controls whether a TLS
client will accept renegotiation requests from a server. This is used,
for example, by some web servers that wish to “add” a client certificate
to an HTTPS connection.
This is disabled by default because it significantly complicates the
state machine.
Originally, handshakeMutex was taken before locking either Conn.in or
Conn.out. However, if renegotiation is permitted then a handshake may
be triggered during a Read() call. If Conn.in were unlocked before
taking handshakeMutex then a concurrent Read() call could see an
intermediate state and trigger an error. Thus handshakeMutex is now
locked after Conn.in and the handshake functions assume that Conn.in is
locked for the duration of the handshake.
Additionally, handshakeMutex used to protect Conn.out also. With the
possibility of renegotiation that's no longer viable and so
writeRecordLocked has been split off.
Fixes#5742.
Change-Id: I935914db1f185d507ff39bba8274c148d756a1c8
Reviewed-on: https://go-review.googlesource.com/22475
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Error strings in this package were all over the place: some were
prefixed with “tls:”, some with “crypto/tls:” and some didn't have a
prefix.
This change makes everything use the prefix “tls:”.
Change-Id: Ie8b073c897764b691140412ecd6613da8c4e33a2
Reviewed-on: https://go-review.googlesource.com/21893
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
This promotes a connection hang during TLS handshake to a proper error.
This doesn't fully address #14539 because the error reported in that
case is a write-on-socket-not-connected error, which implies that an
earlier error during connection setup is not being checked, but it is
an improvement over the current behaviour.
Updates #14539.
Change-Id: I0571a752d32d5303db48149ab448226868b19495
Reviewed-on: https://go-review.googlesource.com/19990
Reviewed-by: Adam Langley <agl@golang.org>
The tree's pretty inconsistent about single space vs double space
after a period in documentation. Make it consistently a single space,
per earlier decisions. This means contributors won't be confused by
misleading precedence.
This CL doesn't use go/doc to parse. It only addresses // comments.
It was generated with:
$ perl -i -npe 's,^(\s*// .+[a-z]\.) +([A-Z]),$1 $2,' $(git grep -l -E '^\s*//(.+\.) +([A-Z])')
$ go test go/doc -update
Change-Id: Iccdb99c37c797ef1f804a94b22ba5ee4b500c4f7
Reviewed-on: https://go-review.googlesource.com/20022
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Dave Day <djd@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Previously we enforced both that the extended key usages of a client
certificate chain allowed for client authentication, and that the
client-auth EKU was in the leaf certificate.
This change removes the latter requirement. It's still the case that the
chain must be compatible with the client-auth EKU (i.e. that a parent
certificate isn't limited to another usage, like S/MIME), but we'll now
accept a leaf certificate with no EKUs for client-auth.
While it would be nice if all client certificates were explicit in their
intended purpose, I no longer feel that this battle is worthwhile.
Fixes#11087.
Change-Id: I777e695101cbeba069b730163533e2977f4dc1fc
Reviewed-on: https://go-review.googlesource.com/10806
Reviewed-by: Andrew Gerrand <adg@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
Prior to TLS 1.2, the handshake had a pleasing property that one could
incrementally hash it and, from that, get the needed hashes for both
the CertificateVerify and Finished messages.
TLS 1.2 introduced negotiation for the signature and hash and it became
possible for the handshake hash to be, say, SHA-384, but for the
CertificateVerify to sign the handshake with SHA-1. The problem is that
one doesn't know in advance which hashes will be needed and thus the
handshake needs to be buffered.
Go ignored this, always kept a single handshake hash, and any signatures
over the handshake had to use that hash.
However, there are a set of servers that inspect the client's offered
signature hash functions and will abort the handshake if one of the
server's certificates is signed with a hash function outside of that
set. https://robertsspaceindustries.com/ is an example of such a server.
Clearly not a lot of thought happened when that server code was written,
but its out there and we have to deal with it.
This change decouples the handshake hash from the CertificateVerify
hash. This lays the groundwork for advertising support for SHA-384 but
doesn't actually make that change in the interests of reviewability.
Updating the advertised hash functions will cause changes in many of the
testdata/ files and some errors might get lost in the noise. This change
only needs to update four testdata/ files: one because a SHA-384-based
handshake is now being signed with SHA-256 and the others because the
TLS 1.2 CertificateRequest message now includes SHA-1.
This change also has the effect of adding support for
client-certificates in SSLv3 servers. However, SSLv3 is now disabled by
default so this should be moot.
It would be possible to avoid much of this change and just support
SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces
and SKX params (a design mistake in TLS). However, that would leave Go
in the odd situation where it advertised support for SHA-384, but would
only use the handshake hash when signing client certificates. I fear
that'll just cause problems in the future.
Much of this code was written by davidben@ for the purposes of testing
BoringSSL.
Partly addresses #9757
Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485
Reviewed-on: https://go-review.googlesource.com/9415
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
This change causes the GetCertificate callback to be called if
Certificates is empty. Previously this configuration would result in an
error.
This allows people to have servers that depend entirely on dynamic
certificate selection, even when the client doesn't send SNI.
Fixes#9208.
Change-Id: I2f5a5551215958b88b154c64a114590300dfc461
Reviewed-on: https://go-review.googlesource.com/8792
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
This change adds a new method to tls.Config, SetSessionTicketKeys, that
changes the key used to encrypt session tickets while the server is
running. Additional keys may be provided that will be used to maintain
continuity while rotating keys. If a ticket encrypted with an old key is
provided by the client, the server will resume the session and provide
the client with a ticket encrypted using the new key.
Fixes#9994
Change-Id: Idbc16b10ff39616109a51ed39a6fa208faad5b4e
Reviewed-on: https://go-review.googlesource.com/9072
Reviewed-by: Jonathan Rudenberg <jonathan@titanous.com>
Reviewed-by: Adam Langley <agl@golang.org>
This change adds support for serving and receiving Signed Certificate
Timestamps as described in RFC 6962.
The server is now capable of serving SCTs listed in the Certificate
structure. The client now asks for SCTs and, if any are received,
they are exposed in the ConnectionState structure.
Fixes#10201
Change-Id: Ib3adae98cb4f173bc85cec04d2bdd3aa0fec70bb
Reviewed-on: https://go-review.googlesource.com/8988
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Jonathan Rudenberg <jonathan@titanous.com>
This is a follow on to 28f33b4a which removes one of the boolean flags
and adds a test for the key-driven cipher selection.
Change-Id: If2a400de807eb19110352912a9f467491cc8986c
Reviewed-on: https://go-review.googlesource.com/8428
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
Reviewed-by: Jacob Haven <jacob@cloudflare.com>
This change replaces all direct ECDSA/RSA sign and decrypt operations
with calls through the crypto.Signer and crypto.Decrypter interfaces.
This is a follow-up to https://go-review.googlesource.com/#/c/3900/
which added crypto.Decrypter and implemented it for RSA.
Change-Id: Ie0f3928448b285f329efcd3a93ca3fd5e3b3e42d
Reviewed-on: https://go-review.googlesource.com/7804
Reviewed-by: Adam Langley <agl@golang.org>
Only documentation / comment changes. Update references to
point to golang.org permalinks or go.googlesource.com/go.
References in historical release notes under doc are left as is.
Change-Id: Icfc14e4998723e2c2d48f9877a91c5abef6794ea
Reviewed-on: https://go-review.googlesource.com/4060
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Generalizes PRF calculation for TLS 1.2 to support arbitrary hashes (SHA-384 instead of SHA-256).
Testdata were all updated to correspond with the new cipher suites in the handshake.
Change-Id: I3d9fc48c19d1043899e38255a53c80dc952ee08f
Reviewed-on: https://go-review.googlesource.com/3265
Reviewed-by: Adam Langley <agl@golang.org>
Fix TLS_FALLBACK_SCSV check when comparing the client version to the
default max version. This enables the TLS_FALLBACK_SCSV check by default
in servers that do not explicitly set a max version in the tls config.
Change-Id: I5a51f9da6d71b79bc6c2ba45032be51d0f704b5e
Reviewed-on: https://go-review.googlesource.com/1776
Reviewed-by: Adam Langley <agl@golang.org>
A new attack on CBC padding in SSLv3 was released yesterday[1]. Go only
supports SSLv3 as a server, not as a client. An easy fix is to change
the default minimum version to TLS 1.0 but that seems a little much
this late in the 1.4 process as it may break some things.
Thus this patch adds server support for TLS_FALLBACK_SCSV[2] -- a
mechanism for solving the fallback problem overall. Chrome has
implemented this since February and Google has urged others to do so in
light of yesterday's news.
With this change, clients can indicate that they are doing a fallback
connection and Go servers will be able to correctly reject them.
[1] http://googleonlinesecurity.blogspot.com/2014/10/this-poodle-bites-exploiting-ssl-30.html
[2] https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/157090043
Currently a write error will cause future reads to return that same error.
However, there may have been extra information from a peer pending on
the read direction that is now unavailable.
This change splits the single connErr into errors for the read, write and
handshake. (Splitting off the handshake error is needed because both read
and write paths check the handshake error.)
Fixes#7414.
LGTM=bradfitz, r
R=golang-codereviews, r, bradfitz
CC=golang-codereviews
https://golang.org/cl/69090044
Currently an ECDHE handshake uses the client's curve preference. This
generally means that we use P-521. However, P-521's strength is
mismatched with the rest of the cipher suite in most cases and we have
a fast, constant-time implementation of P-256.
With this change, Go servers will use P-256 where the client supports
it although that can be overridden in the Config.
LGTM=bradfitz
R=bradfitz
CC=golang-codereviews
https://golang.org/cl/66060043
The renegotiation extension was introduced[1] due to an attack by Ray in
which a client's handshake was spliced into a connection that was
renegotiating, thus giving an attacker the ability to inject an
arbitary prefix into the connection.
Go has never supported renegotiation as a server and so this attack
doesn't apply. As a client, it's possible that at some point in the
future the population of servers will be sufficiently updated that
it'll be possible to reject connections where the server hasn't
demonstrated that it has been updated to address this problem.
We're not at that point yet, but it's good for Go servers to support
the extension so that it might be possible to do in the future.
[1] https://tools.ietf.org/search/rfc5746
R=golang-codereviews, mikioh.mikioh
CC=golang-codereviews
https://golang.org/cl/48580043
Despite SHA256 support being required for TLS 1.2 handshakes, some
servers are aborting handshakes that don't offer SHA1 support.
This change adds support for signing TLS 1.2 ServerKeyExchange messages
with SHA1. It does not add support for signing TLS 1.2 client
certificates with SHA1 as that would require the handshake to be
buffered.
Fixes#6618.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/15650043
AES-GCM cipher suites are only defined for TLS 1.2, although there's
nothing really version specific about them. However, development
versions of NSS (meaning Firefox and Chrome) have an issue where
they'll advertise TLS 1.2-only cipher suites in a TLS 1.1 ClientHello
but then balk when the server selects one.
This change causes Go clients not to advertise TLS 1.2 cipher suites
unless TLS 1.2 is being used, and prevents servers from selecting them
unless TLS 1.2 has been negotiated.
https://code.google.com/p/chromium/issues/detail?id=297151https://bugzilla.mozilla.org/show_bug.cgi?id=919677
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/13573047
47ec7a68b1a2 added support for ECDSA ciphersuites but didn't alter the
cipher suite selection to take that into account. Thus Go servers could
try and select an ECDSA cipher suite while only having an RSA
certificate, leading to connection failures.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/13239053
With TLS 1.2, when sending client certificates the code was omitting
the new (in TLS 1.2) signature and hash fields.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/13413050
AES-GCM is the only current TLS ciphersuite that doesn't have
cryptographic weaknesses (RC4), nor major construction issues (CBC mode
ciphers) and has some deployment (i.e. not-CCM).
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/13249044
Add support for ECDHE-ECDSA (RFC4492), which uses an ephemeral server
key pair to perform ECDH with ECDSA signatures. Like ECDHE-RSA,
ECDHE-ECDSA also provides PFS.
R=agl
CC=golang-dev
https://golang.org/cl/7006047
This does not include AES-GCM yet. Also, it assumes that the handshake and
certificate signature hash are always SHA-256, which is true of the ciphersuites
that we currently support.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/10762044