Commit graph

106 commits

Author SHA1 Message Date
Josh Bleecher Snyder
ad996144ff crypto/tls: move a defer out of a loop
Rhys Hiltner noted in #14939 that this defer was
syntactically inside a loop, but was only ever

executed once. Now that defer in a loop
is significantly slower, pull this one out.

name                                    old time/op   new time/op   delta
Throughput/MaxPacket/1MB/TLSv12-8        3.94ms ± 8%   3.93ms ±13%    ~     (p=0.967 n=15+15)
Throughput/MaxPacket/1MB/TLSv13-8        4.33ms ± 3%   4.51ms ± 7%  +4.00%  (p=0.000 n=14+14)
Throughput/MaxPacket/2MB/TLSv12-8        6.80ms ± 6%   7.01ms ± 4%  +3.15%  (p=0.000 n=14+14)
Throughput/MaxPacket/2MB/TLSv13-8        6.96ms ± 5%   6.80ms ± 5%  -2.43%  (p=0.006 n=15+14)
Throughput/MaxPacket/4MB/TLSv12-8        12.0ms ± 3%   11.7ms ± 2%  -2.88%  (p=0.000 n=15+13)
Throughput/MaxPacket/4MB/TLSv13-8        12.1ms ± 3%   11.7ms ± 2%  -3.54%  (p=0.000 n=13+13)
Throughput/MaxPacket/8MB/TLSv12-8        22.2ms ± 3%   21.6ms ± 3%  -2.97%  (p=0.000 n=15+15)
Throughput/MaxPacket/8MB/TLSv13-8        22.5ms ± 5%   22.0ms ± 3%  -2.34%  (p=0.004 n=15+15)
Throughput/MaxPacket/16MB/TLSv12-8       42.4ms ± 3%   41.3ms ± 3%  -2.49%  (p=0.001 n=15+15)
Throughput/MaxPacket/16MB/TLSv13-8       43.4ms ± 5%   42.3ms ± 3%  -2.33%  (p=0.006 n=15+14)
Throughput/MaxPacket/32MB/TLSv12-8       83.1ms ± 4%   80.6ms ± 3%  -2.98%  (p=0.000 n=15+15)
Throughput/MaxPacket/32MB/TLSv13-8       85.2ms ± 8%   82.6ms ± 4%  -3.02%  (p=0.005 n=15+15)
Throughput/MaxPacket/64MB/TLSv12-8        167ms ± 7%    158ms ± 2%  -5.21%  (p=0.000 n=15+15)
Throughput/MaxPacket/64MB/TLSv13-8        170ms ± 4%    162ms ± 3%  -4.83%  (p=0.000 n=15+15)
Throughput/DynamicPacket/1MB/TLSv12-8    4.13ms ± 7%   4.00ms ± 8%    ~     (p=0.061 n=15+15)
Throughput/DynamicPacket/1MB/TLSv13-8    4.72ms ± 6%   4.64ms ± 7%    ~     (p=0.377 n=14+15)
Throughput/DynamicPacket/2MB/TLSv12-8    7.29ms ± 7%   7.09ms ± 7%    ~     (p=0.070 n=15+14)
Throughput/DynamicPacket/2MB/TLSv13-8    7.18ms ± 5%   6.59ms ± 4%  -8.34%  (p=0.000 n=15+15)
Throughput/DynamicPacket/4MB/TLSv12-8    12.3ms ± 3%   11.9ms ± 4%  -3.31%  (p=0.000 n=15+14)
Throughput/DynamicPacket/4MB/TLSv13-8    12.2ms ± 4%   12.0ms ± 4%  -1.91%  (p=0.019 n=15+15)
Throughput/DynamicPacket/8MB/TLSv12-8    22.4ms ± 3%   21.9ms ± 3%  -2.18%  (p=0.000 n=15+15)
Throughput/DynamicPacket/8MB/TLSv13-8    22.7ms ± 3%   22.2ms ± 3%  -2.35%  (p=0.000 n=15+15)
Throughput/DynamicPacket/16MB/TLSv12-8   42.3ms ± 3%   42.1ms ± 3%    ~     (p=0.505 n=14+15)
Throughput/DynamicPacket/16MB/TLSv13-8   42.7ms ± 3%   43.3ms ± 7%    ~     (p=0.123 n=15+14)
Throughput/DynamicPacket/32MB/TLSv12-8   82.8ms ± 3%   81.9ms ± 3%    ~     (p=0.112 n=14+15)
Throughput/DynamicPacket/32MB/TLSv13-8   84.6ms ± 6%   83.9ms ± 4%    ~     (p=0.624 n=15+15)
Throughput/DynamicPacket/64MB/TLSv12-8    166ms ± 4%    163ms ± 6%    ~     (p=0.081 n=15+15)
Throughput/DynamicPacket/64MB/TLSv13-8    165ms ± 3%    168ms ± 3%  +1.56%  (p=0.029 n=15+15)

Change-Id: I22409b05afe761b8ed1912b15c67fc03f88d3d1f
Reviewed-on: https://go-review.googlesource.com/c/go/+/203481
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-10-26 15:17:28 +00:00
Brad Fitzpatrick
6b5dc9f4ba crypto/tls: remove NPN support
RELNOTE=yes

Fixes #28362

Change-Id: I43813c0c17bbe6c4cbb4d1f121518c434b3f5aa8
Reviewed-on: https://go-review.googlesource.com/c/go/+/174329
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2019-10-04 18:07:46 +00:00
Filippo Valsorda
018f13d1a3 crypto/tls: remove SSLv3 support
SSLv3 has been irreparably broken since the POODLE attack 5 years ago
and RFC 7568 (f.k.a. draft-ietf-tls-sslv3-diediedie) prohibits its use
in no uncertain terms.

As announced in the Go 1.13 release notes, remove support for it
entirely in Go 1.14.

Updates #32716

Change-Id: Id653557961d8f75f484a01e6afd2e104a4ccceaf
Reviewed-on: https://go-review.googlesource.com/c/go/+/191976
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-08-27 22:24:05 +00:00
David Benjamin
1f8aa21cce crypto/tls: fix a minor MAC vs padding leak
The CBC mode ciphers in TLS are a disaster. By ordering authentication
and encryption wrong, they are very subtly dependent on details and
implementation of the padding check, admitting attacks such as POODLE
and Lucky13.

crypto/tls does not promise full countermeasures for Lucky13 and still
contains some timing variations. This change fixes one of the easy ones:
by checking the MAC, then the padding, rather than all at once, there is
a very small timing variation between bad MAC and (good MAC, bad
padding).

The consequences depend on the effective padding value used in the MAC
when the padding is bad. extractPadding simply uses the last byte's
value, leaving the padding bytes effectively unchecked. This is the
scenario in SSL 3.0 that led to POODLE. Specifically, the attacker can
take an input record which uses 16 bytes of padding (a full block) and
replace the final block with some interesting block. The MAC check will
succeed with 1/256 probability due to the final byte being 16. This
again means that after 256 queries, the attacker can decrypt one byte.

To fix this, bitwise AND the two values so they may be checked with one
branch. Additionally, zero the padding if the padding check failed, to
make things more robust.

Updates #27071

Change-Id: I332b14d215078928ffafe3cfeba1a68189f08db3
Reviewed-on: https://go-review.googlesource.com/c/go/+/170701
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-04-16 23:10:02 +00:00
Filippo Valsorda
07b241c4b9 crypto/tls: set ServerName and unset TLSUnique in ConnectionState in TLS 1.3
Fix a couple overlooked ConnectionState fields noticed by net/http
tests, and add a test in crypto/tls. Spun off CL 147638 to keep that one
cleanly about enabling TLS 1.3.

Change-Id: I9a6c2e68d64518a44be2a5d7b0b7b8d78c98c95d
Reviewed-on: https://go-review.googlesource.com/c/148900
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Andrew Bonventre <andybons@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-11-12 20:44:22 +00:00
Filippo Valsorda
b523d280e4 crypto/tls: implement TLS 1.3 client authentication
Note that the SignatureSchemes passed to GetClientCertificate in TLS 1.2
are now filtered by the requested certificate type. This feels like an
improvement anyway, and the full list can be surfaced as well when
support for signature_algorithms_cert is added, which actually matches
the semantics of the CertificateRequest signature_algorithms in TLS 1.2.

Also, note a subtle behavior change in server side resumption: if a
certificate is requested but not required, and the resumed session did
not include one, it used not to invoke VerifyPeerCertificate. However,
if the resumed session did include a certificate, it would. (If a
certificate was required but not in the session, the session is rejected
in checkForResumption.) This inconsistency could be unexpected, even
dangerous, so now VerifyPeerCertificate is always invoked. Still not
consistent with the client behavior, which does not ever invoke
VerifyPeerCertificate on resumption, but it felt too surprising to
entirely change either.

Updates #9671

Change-Id: Ib2b0dbc30e659208dca3ac07d6c687a407d7aaaf
Reviewed-on: https://go-review.googlesource.com/c/147599
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-12 20:43:55 +00:00
Filippo Valsorda
dc9021e679 crypto/tls: implement TLS 1.3 PSK authentication (client side)
Also check original certificate validity when resuming TLS 1.0–1.2. Will
refuse to resume a session if the certificate is expired or if the
original connection had InsecureSkipVerify and the resumed one doesn't.

Support only PSK+DHE to protect forward secrecy even with lack of a
strong session ticket rotation story.

Tested with NSS because s_server does not provide any way of getting the
same session ticket key across invocations. Will self-test like TLS
1.0–1.2 once server side is implemented.

Incorporates CL 128477 by @santoshankr.

Fixes #24919
Updates #9671

Change-Id: Id3eaa5b6c77544a1357668bf9ff255f3420ecc34
Reviewed-on: https://go-review.googlesource.com/c/147420
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-12 20:43:23 +00:00
Filippo Valsorda
5b79a7c982 crypto/tls: implement TLS 1.3 middlebox compatibility mode
Looks like the introduction of CCS records in the client second flight
gave time to s_server to send NewSessionTicket messages in between the
client application data and close_notify. There seems to be no way of
turning NewSessionTicket messages off, neither by not sending a
psk_key_exchange_modes extension, nor by command line flag.

Interleaving the client write like that tickled an issue akin to #18701:
on Windows, the client reaches Close() before the last record is drained
from the send buffer, the kernel notices and resets the connection,
cutting short the last flow. There is no good way of synchronizing this,
so we sleep for a RTT before calling close, like in CL 75210. Sigh.

Updates #9671

Change-Id: I44dc1cca17b373695b5a18c2741f218af2990bd1
Reviewed-on: https://go-review.googlesource.com/c/147419
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-12 20:43:06 +00:00
Filippo Valsorda
e04a8ac694 crypto/tls: implement TLS 1.3 KeyUpdate messages
Since TLS 1.3 delivers handshake messages (including KeyUpdate) after
the handshake, the want argument to readRecord had became almost
pointless: it only meant something when set to recordTypeChangeCipherSpec.
Replaced it with a bool to reflect that, and added two shorthands to
avoid anonymous bools in calls.

Took the occasion to simplify and formalize the invariants of readRecord.

The maxConsecutiveEmptyRecords loop became useless when readRecord
started retrying on any non-advancing record in CL 145297.

Replaced panics with errors, because failure is better than undefined
behavior, but contained failure is better than a DoS vulnerability. For
example, I suspect the panic at the top of readRecord was reachable from
handleRenegotiation, which calls readHandshake with handshakeComplete
false. Thankfully it was not a panic in 1.11, and it's allowed now.

Removed Client-TLSv13-RenegotiationRejected because OpenSSL isn't
actually willing to ask for renegotiation over TLS 1.3, the expected
error was due to NewSessionTicket messages, which didn't break the rest
of the tests because they stop too soon.

Updates #9671

Change-Id: I297a81bde5c8020a962a92891b70d6d70b90f5e3
Reviewed-on: https://go-review.googlesource.com/c/147418
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-12 20:42:36 +00:00
Filippo Valsorda
b85722092b crypto/tls: remove a forgotten note to future self
Now, this is embarrassing. While preparing CL 142818, I noticed a
possible vulnerability in the existing code which I was rewriting. I
took a note to go back and assess if it was indeed an issue, and in case
start the security release process. The note unintentionally slipped
into the commit. Fortunately, there was no vulnerability.

What caught my eye was that I had fixed the calculation of the minimum
encrypted payload length from

    roundUp(explicitIVLen+macSize+1, blockSize)

to (using the same variable names)

    explicitIVLen + roundUp(macSize+1, blockSize)

The explicit nonce sits outside of the encrypted payload, so it should
not be part of the value rounded up to the CBC block size.

You can see that for some values of the above, the old result could be
lower than the correct value. An unexpectedly short payload might cause
a panic during decryption (a DoS vulnerability) or even more serious
issues due to the constant time code that follows it (see for example
Yet Another Padding Oracle in OpenSSL CBC Ciphersuites [1]).

In practice, explicitIVLen is either zero or equal to blockSize, so it
does not change the amount of rounding up necessary and the two
formulations happen to be identical. Nothing to see here.

It looked more suspicious than it is in part due to the fact that the
explicitIVLen definition moved farther into hc.explicitNonceLen() and
changed name from IV (which suggests a block length) to nonce (which
doesn't necessarily). But anyway it was never meant to surface or be
noted, except it slipped, so here we are for a boring explanation.

[1] https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/

Change-Id: I365560dfe006513200fa877551ce7afec9115fdf
Reviewed-on: https://go-review.googlesource.com/c/147637
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-08 06:13:12 +00:00
Filippo Valsorda
2c3ff7ba06 crypto/tls: implement TLS 1.3 client handshake (base)
Implement a basic TLS 1.3 client handshake, only enabled if explicitly
requested with MaxVersion.

This CL intentionally leaves for future CLs:
  - PSK modes and resumption
  - client authentication
  - post-handshake messages
  - downgrade protection
  - KeyLogWriter support

Updates #9671

Change-Id: Ieb6130fb6f25aea4f0d39e3a2448dfc942e1de7a
Reviewed-on: https://go-review.googlesource.com/c/146559
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 22:07:02 +00:00
Filippo Valsorda
d4e9432552 crypto/tls: implement TLS 1.3 version-specific messages
Note that there is significant code duplication due to extensions with
the same format appearing in different messages in TLS 1.3. This will be
cleaned up in a future refactor once CL 145317 is merged.

Enforcing the presence/absence of each extension in each message is left
to the upper layer, based on both protocol version and extensions
advertised in CH and CR. Duplicated extensions and unknown extensions in
SH, EE, HRR, and CT will be tightened up in a future CL.

The TLS 1.2 CertificateStatus message was restricted to accepting only
type OCSP as any other type (none of which are specified so far) would
have to be negotiated.

Updates #9671

Change-Id: I7c42394c5cc0af01faa84b9b9f25fdc6e7cfbb9e
Reviewed-on: https://go-review.googlesource.com/c/145477
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 22:04:51 +00:00
Filippo Valsorda
34eda04c4f crypto/tls: implement TLS 1.3 record layer and cipher suites
Updates #9671

Change-Id: I1ea7b724975c0841d01f4536eebb23956b30d5ea
Reviewed-on: https://go-review.googlesource.com/c/145297
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 21:54:38 +00:00
Filippo Valsorda
8d011ce74c crypto/tls: rewrite some messages with golang.org/x/crypto/cryptobyte
As a first round, rewrite those handshake message types which can be
reused in TLS 1.3 with golang.org/x/crypto/cryptobyte. All other types
changed significantly in TLS 1.3 and will require separate
implementations. They will be ported to cryptobyte in a later CL.

The only semantic changes should be enforcing the random length on the
marshaling side, enforcing a couple more "must not be empty" on the
unmarshaling side, and checking the rest of the SNI list even if we only
take the first.

Change-Id: Idd2ced60c558fafcf02ee489195b6f3b4735fe22
Reviewed-on: https://go-review.googlesource.com/c/144115
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-10-29 17:05:55 +00:00
Brad Fitzpatrick
9986f57938 crypto/tls, net/http: reject HTTP requests to HTTPS server
This adds a crypto/tls.RecordHeaderError.Conn field containing the TLS
underlying net.Conn for non-TLS handshake errors, and then uses it in
the net/http Server to return plaintext HTTP 400 errors when a client
mistakenly sends a plaintext HTTP request to an HTTPS server. This is the
same behavior as Apache.

Also in crypto/tls: swap two error paths to not use a value before
it's valid, and don't send a alert record when a handshake contains a
bogus TLS record (a TLS record in response won't help a non-TLS
client).

Fixes #23689

Change-Id: Ife774b1e3886beb66f25ae4587c62123ccefe847
Reviewed-on: https://go-review.googlesource.com/c/143177
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2018-10-24 22:49:50 +00:00
Filippo Valsorda
5d617aac88 crypto/tls: replace custom *block with standard buffers
The crypto/tls record layer used a custom buffer implementation with its
own semantics, freelist, and offset management. Replace it all with
per-task bytes.Buffer, bytes.Reader and byte slices, along with a
refactor of all the encrypt and decrypt code.

The main quirk of *block was to do a best-effort read past the record
boundary, so that if a closeNotify was waiting it would be peeked and
surfaced along with the last Read. Address that with atLeastReader and
ReadFrom to avoid a useless copy (instead of a LimitReader or CopyN).

There was also an optimization to split blocks along record boundary
lines without having to copy in and out the data. Replicate that by
aliasing c.input into consumed c.rawInput (after an in-place decrypt
operation). This is safe because c.rawInput is not used until c.input is
drained.

The benchmarks are noisy but look like an improvement across the board,
which is a nice side effect :)

name                                       old time/op   new time/op   delta
HandshakeServer/RSA-8                        817µs ± 2%    797µs ± 2%  -2.52%  (p=0.000 n=10+9)
HandshakeServer/ECDHE-P256-RSA-8             984µs ±11%    897µs ± 0%  -8.89%  (p=0.000 n=10+9)
HandshakeServer/ECDHE-P256-ECDSA-P256-8      206µs ±10%    199µs ± 3%    ~     (p=0.113 n=10+9)
HandshakeServer/ECDHE-X25519-ECDSA-P256-8    204µs ± 3%    202µs ± 1%  -1.06%  (p=0.013 n=10+9)
HandshakeServer/ECDHE-P521-ECDSA-P521-8     15.5ms ± 0%   15.6ms ± 1%    ~     (p=0.095 n=9+10)
Throughput/MaxPacket/1MB-8                  5.35ms ±19%   5.39ms ±36%    ~     (p=1.000 n=9+10)
Throughput/MaxPacket/2MB-8                  9.20ms ±15%   8.30ms ± 8%  -9.79%  (p=0.035 n=10+9)
Throughput/MaxPacket/4MB-8                  13.8ms ± 7%   13.6ms ± 8%    ~     (p=0.315 n=10+10)
Throughput/MaxPacket/8MB-8                  25.1ms ± 3%   23.2ms ± 2%  -7.66%  (p=0.000 n=10+9)
Throughput/MaxPacket/16MB-8                 46.9ms ± 1%   43.0ms ± 3%  -8.29%  (p=0.000 n=9+10)
Throughput/MaxPacket/32MB-8                 88.9ms ± 2%   82.3ms ± 2%  -7.40%  (p=0.000 n=9+9)
Throughput/MaxPacket/64MB-8                  175ms ± 2%    164ms ± 4%  -6.18%  (p=0.000 n=10+10)
Throughput/DynamicPacket/1MB-8              5.79ms ±26%   5.82ms ±22%    ~     (p=0.912 n=10+10)
Throughput/DynamicPacket/2MB-8              9.23ms ±14%   9.50ms ±23%    ~     (p=0.971 n=10+10)
Throughput/DynamicPacket/4MB-8              14.5ms ±11%   13.8ms ± 6%  -4.66%  (p=0.019 n=10+10)
Throughput/DynamicPacket/8MB-8              25.6ms ± 4%   23.5ms ± 3%  -8.33%  (p=0.000 n=10+10)
Throughput/DynamicPacket/16MB-8             47.3ms ± 3%   44.6ms ± 7%  -5.65%  (p=0.000 n=10+10)
Throughput/DynamicPacket/32MB-8             91.9ms ±14%   85.0ms ± 4%  -7.55%  (p=0.000 n=10+10)
Throughput/DynamicPacket/64MB-8              177ms ± 2%    168ms ± 4%  -4.97%  (p=0.000 n=8+10)
Latency/MaxPacket/200kbps-8                  694ms ± 0%    694ms ± 0%    ~     (p=0.315 n=10+9)
Latency/MaxPacket/500kbps-8                  279ms ± 0%    279ms ± 0%    ~     (p=0.447 n=9+10)
Latency/MaxPacket/1000kbps-8                 140ms ± 0%    140ms ± 0%    ~     (p=0.661 n=9+10)
Latency/MaxPacket/2000kbps-8                71.1ms ± 0%   71.1ms ± 0%  +0.05%  (p=0.019 n=9+9)
Latency/MaxPacket/5000kbps-8                30.4ms ± 7%   30.5ms ± 4%    ~     (p=0.720 n=9+10)
Latency/DynamicPacket/200kbps-8              134ms ± 0%    134ms ± 0%    ~     (p=0.075 n=10+10)
Latency/DynamicPacket/500kbps-8             54.8ms ± 0%   54.8ms ± 0%    ~     (p=0.631 n=10+10)
Latency/DynamicPacket/1000kbps-8            28.5ms ± 0%   28.5ms ± 0%    ~     (p=1.000 n=8+8)
Latency/DynamicPacket/2000kbps-8            15.7ms ±12%   16.1ms ± 0%    ~     (p=0.109 n=10+7)
Latency/DynamicPacket/5000kbps-8            8.20ms ±26%   8.17ms ±13%    ~     (p=1.000 n=9+9)

name                                       old speed     new speed     delta
Throughput/MaxPacket/1MB-8                 193MB/s ±14%  202MB/s ±30%    ~     (p=0.897 n=8+10)
Throughput/MaxPacket/2MB-8                 230MB/s ±14%  249MB/s ±17%    ~     (p=0.089 n=10+10)
Throughput/MaxPacket/4MB-8                 304MB/s ± 6%  309MB/s ± 7%    ~     (p=0.315 n=10+10)
Throughput/MaxPacket/8MB-8                 334MB/s ± 3%  362MB/s ± 2%  +8.29%  (p=0.000 n=10+9)
Throughput/MaxPacket/16MB-8                358MB/s ± 1%  390MB/s ± 3%  +9.08%  (p=0.000 n=9+10)
Throughput/MaxPacket/32MB-8                378MB/s ± 2%  408MB/s ± 2%  +8.00%  (p=0.000 n=9+9)
Throughput/MaxPacket/64MB-8                384MB/s ± 2%  410MB/s ± 4%  +6.61%  (p=0.000 n=10+10)
Throughput/DynamicPacket/1MB-8             178MB/s ±24%  182MB/s ±24%    ~     (p=0.604 n=9+10)
Throughput/DynamicPacket/2MB-8             228MB/s ±13%  225MB/s ±20%    ~     (p=0.971 n=10+10)
Throughput/DynamicPacket/4MB-8             291MB/s ±10%  305MB/s ± 6%  +4.83%  (p=0.019 n=10+10)
Throughput/DynamicPacket/8MB-8             327MB/s ± 4%  357MB/s ± 3%  +9.08%  (p=0.000 n=10+10)
Throughput/DynamicPacket/16MB-8            355MB/s ± 3%  376MB/s ± 6%  +6.07%  (p=0.000 n=10+10)
Throughput/DynamicPacket/32MB-8            366MB/s ±12%  395MB/s ± 4%  +7.91%  (p=0.000 n=10+10)
Throughput/DynamicPacket/64MB-8            380MB/s ± 2%  400MB/s ± 4%  +5.26%  (p=0.000 n=8+10)

Note that this reduced the buffer for the first read from 1024 to 5+512,
so it triggered the issue described at #24198 when using a synchronous
net.Pipe: the first server flight was not being consumed entirely by the
first read anymore, causing a deadlock as both the client and the server
were trying to send (the client a reply to the ServerHello, the server
the rest of the buffer). Fixed by rebasing on top of CL 142817.

Change-Id: Ie31b0a572b2ad37878469877798d5c6a5276f931
Reviewed-on: https://go-review.googlesource.com/c/142818
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-10-24 10:03:23 +00:00
Filippo Valsorda
db3edf68fa crypto/tls,crypto/x509: normalize RFC references
Use the format "RFC XXXX, Section X.X" (or "Appendix Y.X") as it fits
more properly in prose than a link, is more future-proof, and as there
are multiple ways to render an RFC. Capital "S" to follow the quoting
standard of RFCs themselves.

Applied the new goimports grouping to all files in those packages, too.

Change-Id: I01267bb3a3b02664f8f822e97b129075bb14d404
Reviewed-on: https://go-review.googlesource.com/c/141918
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2018-10-17 03:58:03 +00:00
Filippo Valsorda
0a9fc9c88a crypto/tls: make ConnectionState.ExportKeyingMaterial a method
The unexported field is hidden from reflect based marshalers, which
would break otherwise. Also, make it return an error, as there are
multiple reasons it might fail.

Fixes #27125

Change-Id: I92adade2fe456103d2d5c0315629ca0256953764
Reviewed-on: https://go-review.googlesource.com/130535
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-08-22 03:48:56 +00:00
Minaev Mike
6d965709ab crypto/tls: fix deadlock when Read and Close called concurrently
The existing implementation of TLS connection has a deadlock. It occurs
when client connects to TLS server and doesn't send data for
handshake, so server calls Close on this connection. This is because
server reads data under locked mutex, while Close method tries to
lock the same mutex.

Fixes #23518

Change-Id: I4fb0a2a770f3d911036bfd9a7da7cc41c1b27e19
Reviewed-on: https://go-review.googlesource.com/90155
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2018-07-25 23:53:54 +00:00
Tim Cooper
99371c4e8c all: update comment URLs from HTTP to HTTPS, where possible
Each URL was manually verified to ensure it did not serve up incorrect
content.

Change-Id: I4dc846227af95a73ee9a3074d0c379ff0fa955df
Reviewed-on: https://go-review.googlesource.com/115798
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
2018-06-01 21:52:00 +00:00
Filippo Valsorda
d8f27b6eac crypto/tls: simplify the Handshake locking strategy
If in.Mutex is never locked by Handshake when c.handshakeComplete is
true, and since c.handshakeComplete is unset and then set back by
handleRenegotiation all under both in.Mutex and handshakeMutex, we can
significantly simplify the locking strategy by removing the sync.Cond.

See also https://groups.google.com/forum/#!topic/golang-dev/Xxiai-R_jH0
and a more complete analysis at https://go-review.googlesource.com/c/go/+/33776#message-223a3ccc819f7015cc773d214c65bad70de5dfd7

Change-Id: I6052695ece9aff9e3112c2fb176596fde8aa9cb2
Reviewed-on: https://go-review.googlesource.com/33776
Reviewed-by: Adam Langley <agl@golang.org>
2018-04-03 16:44:55 +00:00
Mike Danese
a6e50819c2 crypto/tls: support keying material export
This change implement keying material export as described in:

https://tools.ietf.org/html/rfc5705

I verified the implementation against openssl s_client and openssl
s_server.

Change-Id: I4dcdd2fb929c63ab4e92054616beab6dae7b1c55
Signed-off-by: Mike Danese <mikedanese@google.com>
Reviewed-on: https://go-review.googlesource.com/85115
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-03-22 18:48:49 +00:00
filewalkwithme
3fe5088752 crypto/tls: limit number of consecutive warning alerts
In the current implementation, it is possible for a client to
continuously send warning alerts, which are just dropped on the floor
inside readRecord.

This can enable scenarios in where someone can try to continuously
send warning alerts to the server just to keep it busy.

This CL implements a simple counter that triggers an error if
we hit the warning alert limit.

Fixes #22543

Change-Id: Ief0ca10308cf5a4dea21a5a67d3e8f6501912da6
Reviewed-on: https://go-review.googlesource.com/75750
Reviewed-by: Adam Langley <agl@golang.org>
Reviewed-by: Filippo Valsorda <hi@filippo.io>
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-11-08 23:18:52 +00:00
Peter Wu
e3522a12ad crypto/tls: fix first byte test for 255 CBC padding bytes
The BadCBCPadding255 test from bogo failed because at most 255 trailing
bytes were checked, but for a padding of 255 there are 255 padding bytes
plus 1 length byte with value 255.

Change-Id: I7dd237c013d2c7c8599067246e31b7ba93106cf7
Reviewed-on: https://go-review.googlesource.com/68070
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-10-06 18:07:04 +00:00
Filippo Valsorda
f3b1bbce00 crypto/tls: disallow handshake messages fragmented across CCS
Detected by BoGo test FragmentAcrossChangeCipherSpec-Server-Packed.

Change-Id: I9a76697b9cdeb010642766041971de5c7e533481
Reviewed-on: https://go-review.googlesource.com/48811
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
2017-08-15 18:45:06 +00:00
Adam Langley
0fc02e2b6f crypto/tls: don't hold lock when closing underlying net.Conn.
There's no need to hold the handshake lock across this call and it can
lead to deadlocks if the net.Conn calls back into the tls.Conn.

Fixes #18426.

Change-Id: Ib1b2813cce385949d970f8ad2e52cfbd1390e624
Reviewed-on: https://go-review.googlesource.com/36561
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-09 19:02:55 +00:00
Mikio Hara
1f09c8cb85 crypto/tls: fix a typo
Change-Id: Id0044c45c23c12ee0bca362a9cdd25369ed7776c
Reviewed-on: https://go-review.googlesource.com/34533
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-12-19 06:01:04 +00:00
Dmitri Shuralyov
902c1b2b47 all: spell "marshal" and "unmarshal" consistently
The tree is inconsistent about single l vs double l in those
words in documentation, test messages, and one error value text.

	$ git grep -E '[Mm]arshall(|s|er|ers|ed|ing)' | wc -l
	      42
	$ git grep -E '[Mm]arshal(|s|er|ers|ed|ing)' | wc -l
	    1694

Make it consistently a single l, per earlier decisions. This means
contributors won't be confused by misleading precedence, and it helps
consistency.

Change the spelling in one error value text in newRawAttributes of
crypto/x509 package to be consistent.

This change was generated with:

	perl -i -npe 's,([Mm]arshal)l(|s|er|ers|ed|ing),$1$2,' $(git grep -l -E '[Mm]arshall' | grep -v AUTHORS | grep -v CONTRIBUTORS)

Updates #12431.
Follows https://golang.org/cl/14150.

Change-Id: I85d28a2d7692862ccb02d6a09f5d18538b6049a2
Reviewed-on: https://go-review.googlesource.com/33017
Run-TryBot: Minux Ma <minux@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-11-12 00:13:35 +00:00
Ben Burkert
d313432832 crypto/tls: add CloseWrite method to Conn
The CloseWrite method sends a close_notify alert record to the other
side of the connection. This record indicates that the sender has
finished sending on the connection. Unlike the Close method, the sender
may still read from the connection until it recieves a close_notify
record (or the underlying connection is closed). This is analogous to a
TCP half-close.

This is a rework of CL 25159 with fixes for the unstable test.

Updates #8579

Change-Id: I47608d2f82a88baff07a90fd64c280ed16a60d5e
Reviewed-on: https://go-review.googlesource.com/31318
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-26 23:05:40 +00:00
Adam Langley
46ef9b9ab3 Revert "crypto/tls: add CloseWrite method to Conn"
This reverts commit c6185aa63217c84a1a73c578c155e7d4dec6cec8. That
commit seems to be causing flaky failures on the builders. See
discussion on the original thread: https://golang.org/cl/25159.

Change-Id: I26e72d962d4efdcee28a0bc61a53f246b046df77
Reviewed-on: https://go-review.googlesource.com/31316
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2016-10-17 21:33:09 +00:00
Adam Langley
7f2a0090ec crypto/tls: support ChaCha20-Poly1305.
This change adds support for the ChaCha20-Poly1305 AEAD to crypto/tls,
as specified in https://tools.ietf.org/html/rfc7905.

Fixes #15499.

Change-Id: Iaa689be90e03f208c40b574eca399e56f3c7ecf1
Reviewed-on: https://go-review.googlesource.com/30957
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-17 21:05:26 +00:00
Ben Burkert
53121dd61c crypto/tls: add CloseWrite method to Conn
The CloseWrite method sends a close_notify alert record to the other
side of the connection. This record indicates that the sender has
finished sending on the connection. Unlike the Close method, the sender
may still read from the connection until it recieves a close_notify
record (or the underlying connection is closed). This is analogous to a
TCP half-close.

Updates #8579

Change-Id: I9c6bc193efcb25cc187f7735ee07170afa7fdde3
Reviewed-on: https://go-review.googlesource.com/25159
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-17 14:26:55 +00:00
Filippo Valsorda
4536ac70b0 crypto/tls: implement countermeasures against CBC padding oracles
The aim is to make the decrypt() timing profile constant, irrespective of
the CBC padding length or correctness.  The old algorithm, on valid padding,
would only MAC bytes up to the padding length threshold, making CBC
ciphersuites vulnerable to plaintext recovery attacks as presented in the
"Lucky Thirteen" paper.

The new algorithm Write()s to the MAC all supposed payload, performs a
constant time Sum()---which required implementing a constant time Sum() in
crypto/sha1, see the "Lucky Microseconds" paper---and then Write()s the rest
of the data. This is performed whether the padding is good or not.

This should have no explicit secret-dependent timings, but it does NOT
attempt to normalize memory accesses to prevent cache timing leaks.

Updates #13385

Change-Id: I15d91dc3cc6eefc1d44f317f72ff8feb0a9888f7
Reviewed-on: https://go-review.googlesource.com/18130
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2016-10-04 13:21:02 +00:00
David Benjamin
ee3af31d0e crypto/tls: Fix c.in.decrypt error handling.
readRecord was not returning early if c.in.decrypt failed and ran
through the rest of the function. It does set c.in.err, so the various
checks in the callers do ultimately notice before acting on the result,
but we should avoid running the rest of the function at all.

Also rename 'err' to 'alertValue' since it isn't actually an error.

Change-Id: I6660924716a85af704bd3fe81521b34766238695
Reviewed-on: https://go-review.googlesource.com/24709
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2016-09-30 18:44:37 +00:00
Adam Langley
f432a667f2 crypto/tls: fix deadlock when racing to complete handshake.
After renegotiation support was added (af125a5193c) it's possible for a
Write to block on a Read when racing to complete the handshake:
   1. The Write determines that a handshake is needed and tries to
      take the neccesary locks in the correct order.
   2. The Read also determines that a handshake is needed and wins
      the race to take the locks.
   3. The Read goroutine completes the handshake and wins a race
      to unlock and relock c.in, which it'll hold when waiting for
      more network data.

If the application-level protocol requires the Write to complete before
data can be read then the system as a whole will deadlock.

Unfortunately it doesn't appear possible to reverse the locking order of
c.in and handshakeMutex because we might read a renegotiation request at
any point and need to be able to do a handshake without unlocking.

So this change adds a sync.Cond that indicates that a goroutine has
committed to doing a handshake. Other interested goroutines can wait on
that Cond when needed.

The test for this isn't great. I was able to reproduce the deadlock with
it only when building with -race. (Because -race happened to alter the
timing just enough.)

Fixes #17101.

Change-Id: I4e8757f7b82a84e46c9963a977d089f0fb675495
Reviewed-on: https://go-review.googlesource.com/29164
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-22 18:36:58 +00:00
Filippo Valsorda
985a9ac907 crypto/tls: flush the buffer on handshake errors
Since 2a8c81ff handshake messages are not written directly to wire but
buffered.  If an error happens at the wrong time the alert will be
written to the buffer but never flushed, causing an EOF on the client
instead of a more descriptive alert.

Thanks to Brendan McMillion for reporting this.

Fixes #17037

Change-Id: Ie093648aa3f754f4bc61c2e98c79962005dd6aa2
Reviewed-on: https://go-review.googlesource.com/28818
Reviewed-by: Adam Langley <agl@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-09-11 23:29:03 +00:00
Atin M
4b4493f2d9 crypto/tls: set Conn.ConnectionState.ServerName unconditionally
Moves the state.ServerName assignment to outside the if
statement that checks for handshakeComplete.

Fixes #15571

Change-Id: I6c4131ddb16389aed1c410a975f9aa3b52816965
Reviewed-on: https://go-review.googlesource.com/22862
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2016-08-17 20:21:08 +00:00
Adam Langley
a85f1570a7 crypto/tls: buffer handshake messages.
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>
2016-06-01 23:26:04 +00:00
Austin Clements
fb096a6d0c crypto/tls: gofmt
Commit fa3543e introduced formatting errors.

Change-Id: I4b921f391a9b463cefca4318ad63b70ae6ce6865
Reviewed-on: https://go-review.googlesource.com/23514
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
2016-05-27 19:11:48 +00:00
Russ Cox
590d5ab971 crypto/tls: adjust dynamic record sizes to grow arithmetically
The current code, introduced after Go 1.6 to improve latency on
low-bandwidth connections, sends 1 kB packets until 1 MB has been sent,
and then sends 16 kB packets (the maximum record size).

Unfortunately this decreases throughput for 1-16 MB responses by 20% or so.

Following discussion on #15713, change cutoff to 128 kB sent
and also grow the size allowed for successive packets:
1 kB, 2 kB, 3 kB, ..., 15 kB, 16 kB.
This fixes the throughput problems: the overhead is now closer to 2%.

I hope this still helps with latency but I don't have a great way to test it.
At the least, it's not worse than Go 1.6.

Comparing MaxPacket vs DynamicPacket benchmarks:

name              maxpkt time/op  dyn. time/op delta
Throughput/1MB-8    5.07ms ± 7%   5.21ms ± 7%  +2.73%  (p=0.023 n=16+16)
Throughput/2MB-8   15.7ms ±201%    8.4ms ± 5%    ~     (p=0.604 n=20+16)
Throughput/4MB-8    14.3ms ± 1%   14.5ms ± 1%  +1.53%  (p=0.000 n=16+16)
Throughput/8MB-8    26.6ms ± 1%   26.8ms ± 1%  +0.47%  (p=0.003 n=19+18)
Throughput/16MB-8   51.0ms ± 1%   51.3ms ± 1%  +0.47%  (p=0.000 n=20+20)
Throughput/32MB-8    100ms ± 1%    100ms ± 1%  +0.24%  (p=0.033 n=20+20)
Throughput/64MB-8    197ms ± 0%    198ms ± 0%  +0.56%   (p=0.000 n=18+7)

The small MB runs are bimodal in both cases, probably GC pauses.
But there's clearly no general slowdown anymore.

Fixes #15713.

Change-Id: I5fc44680ba71812d24baac142bceee0e23f2e382
Reviewed-on: https://go-review.googlesource.com/23487
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-05-27 16:34:57 +00:00
Adam Langley
e041919535 crypto/tls: allow renegotiation to be handled by a client.
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>
2016-04-28 17:56:28 +00:00
Adam Langley
a9f79c9828 crypto/tls: make error prefix uniform.
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>
2016-04-14 16:28:53 +00:00
Dominik Honnef
af0eaf503f all: delete dead non-test code
This change removes a lot of dead code. Some of the code has never been
used, not even when it was first commited. The rest shouldn't have
survived refactors.

This change doesn't remove unused routines helpful for debugging, nor
does it remove code that's used in commented out blocks of code that are
only unused temporarily. Furthermore, unused constants weren't removed
when they were part of a set of constants from specifications.

One noteworthy omission from this CL are about 1000 lines of unused code
in cmd/fix, 700 lines of which are the typechecker, which hasn't been
used ever since the pre-Go 1 fixes have been removed. I wasn't sure if
this code should stick around for future uses of cmd/fix or be culled as
well.

Change-Id: Ib714bc7e487edc11ad23ba1c3222d1fd02e4a549
Reviewed-on: https://go-review.googlesource.com/20926
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-25 06:28:13 +00:00
Tom Bergan
ed447ce705 crypto/tls: implement dynamic record sizing
Currently, if a client of crypto/tls (e.g., net/http, http2) calls
tls.Conn.Write with a 33KB buffer, that ends up writing three TLS
records: 16KB, 16KB, and 1KB. Slow clients (such as 2G phones) must
download the first 16KB record before they can decrypt the first byte.
To improve latency, it's better to send smaller TLS records. However,
sending smaller records adds overhead (more overhead bytes and more
crypto calls), which slightly hurts throughput.

A simple heuristic, implemented in this change, is to send small
records for new connections, then boost to large records after the
first 1MB has been written on the connection.

Fixes #14376

Change-Id: Ice0f6279325be6775aa55351809f88e07dd700cd
Reviewed-on: https://go-review.googlesource.com/19591
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tom Bergan <tombergan@google.com>
Reviewed-by: Adam Langley <agl@golang.org>
2016-03-12 00:47:13 +00:00
Adam Langley
d2c9dbe16e crypto/tls: better error for oversized handshake messages.
This change improves the error message when encountering a TLS handshake
message that is larger than our limit (64KB). Previously the error was
just “local error: internal error”.

Updates #13401.

Change-Id: I86127112045ae33e51079e3bc047dd7386ddc71a
Reviewed-on: https://go-review.googlesource.com/20547
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-12 00:13:02 +00:00
Tamir Duberstein
02385a0059 crypto/tls: check errors from (*Conn).writeRecord
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>
2016-03-02 18:20:46 +00:00
Brad Fitzpatrick
4876af71fc all: single space after period.
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>
2016-03-02 00:13:47 +00:00
Brad Fitzpatrick
859c1a1ff8 crypto/tls: don't block in Conn.Close if Writes are in-flight
Conn.Close sends an encrypted "close notify" to signal secure EOF.
But writing that involves acquiring mutexes (handshake mutex + the
c.out mutex) and writing to the network. But if the reason we're
calling Conn.Close is because the network is already being
problematic, then Close might block, waiting for one of those mutexes.

Instead of blocking, and instead of introducing new API (at least for
now), distinguish between a normal Close (one that sends a secure EOF)
and a resource-releasing destructor-style Close based on whether there
are existing Write calls in-flight.

Because io.Writer and io.Closer aren't defined with respect to
concurrent usage, a Close with active Writes is already undefined, and
should only be used during teardown after failures (e.g. deadlines or
cancelations by HTTP users). A normal user will do a Write then
serially do a Close, and things are unchanged for that case.

This should fix the leaked goroutines and hung net/http.Transport
requests when there are network errors while making TLS requests.

Change-Id: If3f8c69d6fdcebf8c70227f41ad042ccc3f20ac9
Reviewed-on: https://go-review.googlesource.com/18572
Reviewed-by: Adam Langley <agl@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-01-13 04:49:19 +00:00
Caleb Spare
127fd5c432 crypto/tls: return a typed error on invalid record headers
The user can inspect the record data to detect that the other side is
not using the TLS protocol.

This will be used by the net/http client (in a follow-on CL) to detect
when an HTTPS client is speaking to an HTTP server.

Updates #11111.

Change-Id: I872f78717aa8e8e98cebd8075436209a52039a73
Reviewed-on: https://go-review.googlesource.com/16078
Reviewed-by: Adam Langley <agl@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-11-16 21:54:44 +00:00
Brad Fitzpatrick
b324d1ea77 crypto/tls, crypto/aes: remove allocations when Writing & Reading
benchmark          old ns/op     new ns/op     delta
BenchmarkTLS-4     8571          7938          -7.39%

benchmark          old MB/s     new MB/s     speedup
BenchmarkTLS-4     119.46       128.98       1.08x

benchmark          old allocs     new allocs     delta
BenchmarkTLS-4     8              0              -100.00%

benchmark          old bytes     new bytes     delta
BenchmarkTLS-4     128           0             -100.00%

On:

func BenchmarkTLS(b *testing.B) {
        b.ReportAllocs()
        b.SetBytes(1024)
        ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                io.Copy(ioutil.Discard, r.Body)
        }))
        defer ts.Close()
        buf := make([]byte, 1024)
        for i := range buf {
                buf[i] = byte(i)
        }
        c, err := tls.Dial("tcp", ts.Listener.Addr().String(), &tls.Config{
                InsecureSkipVerify: true,
        })
        if err != nil {
                b.Fatal(err)
        }
        defer c.Close()
        clen := int64(b.N) * 1024
        if _, err := c.Write([]byte(
            "POST / HTTP/1.1\r\nHost: foo\r\nContent-Length: " +
            fmt.Sprint(clen) + "\r\n\r\n")); err != nil {
                b.Fatal(err)
        }
        b.ResetTimer()
        for i := 0; i < b.N; i++ {
                if _, err := c.Write(buf); err != nil {
                        b.Fatal(err)
                }
        }
}

Change-Id: I206e7e2118b97148f9751b740d8470895634d3f5
Reviewed-on: https://go-review.googlesource.com/16828
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-11-14 13:12:47 +00:00