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>
Fix spelling of "original" and "occurred" in new gofmt docs. The same
misspelling of "occurred" was also present in crypto/tls, I fixed it there as
well.
Change-Id: I67b4f1c09bd1a2eb1844207d5514f08a9f525ff9
Reviewed-on: https://go-review.googlesource.com/33138
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
A paranoid go at constant time implementation of P256 curve.
This code relies on z13 SIMD instruction set. For zEC12 and below,
the fallback is the existing P256 implementation. To facilitate this
fallback mode, I've refactored the code so that implementations can
be picked at run-time.
Its 'slightly' difficult to grok, but there is ASCII art..
name old time/op new time/op delta
BaseMultP256 419µs ± 3% 27µs ± 1% -93.65% (p=0.000 n=10+8)
ScalarMultP256 1.05ms ±10% 0.09ms ± 1% -90.94% (p=0.000 n=10+8)
Change-Id: Ic1ded898a2ceab055b1c69570c03179c4b85b177
Reviewed-on: https://go-review.googlesource.com/31231
Run-TryBot: Michael Munday <munday@ca.ibm.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
CL 32871 updated the default cipher suites to use AES-GCM in
preference to ChaCha20-Poly1305 on platforms which have hardware
implementations of AES-GCM. This change makes BenchmarkThroughput
use the default cipher suites instead of the test cipher suites to
ensure that the recommended (fastest) algorithms are used.
Updates #17779.
Change-Id: Ib551223e4a00b5ea197d4d73748e1fdd8a47c32d
Reviewed-on: https://go-review.googlesource.com/32838
Run-TryBot: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
Support for ChaCha20-Poly1305 ciphers was recently added to crypto/tls.
These ciphers are preferable in software, but they cannot beat hardware
support for AES-GCM, if present.
This change moves detection for hardware AES-GCM support into
cipher/internal/cipherhw so that it can be used from crypto/tls. Then,
when AES-GCM hardware is present, the AES-GCM cipher suites are
prioritised by default in crypto/tls. (Some servers, such as Google,
respect the client's preference between AES-GCM and ChaCha20-Poly1305.)
Fixes#17779.
Change-Id: I50de2be486f0b0b8052c4628d3e3205a1d54a646
Reviewed-on: https://go-review.googlesource.com/32871
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reportedly, -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1060
is problematic.
It means min 10.6 and max 10.6, thus exactly 10.6. But we only support
10.8+.
It never caused us problems, because we build on Macs, but apparently
if you cross-compile from Linux with some Mac compiler SDK thing, then
things break?
This was added in https://golang.org/cl/5700083 for #3131, and the
intent at the time was to pin to exactly 10.6. So it wasn't a mistake,
but it is definitely outdated.
Given that we now support 10.8 as the min, update it to 1080.
Fixes#17732
Change-Id: I6cc8ab6ac62b8638a5025952b830f23e8822b2a6
Reviewed-on: https://go-review.googlesource.com/32580
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Quentin Smith <quentin@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
I used the slowtests.go tool as described in
https://golang.org/cl/32684 on packages that stood out.
go test -short std drops from ~56 to ~52 seconds.
This isn't a huge win, but it was mostly an exercise.
Updates #17751
Change-Id: I9f3402e36a038d71e662d06ce2c1d52f6c4b674d
Reviewed-on: https://go-review.googlesource.com/32751
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Adds an assembly implementation of sha256.block for ppc64le to improve its
performance. This implementation is largely based on the original amd64
implementation, which unrolls the 64 iterations of the inner loop.
Fixes#17652
benchmark old ns/op new ns/op delta
BenchmarkHash8Bytes 1263 767 -39.27%
BenchmarkHash1K 14048 7766 -44.72%
BenchmarkHash8K 102245 55626 -45.60%
benchmark old MB/s new MB/s speedup
BenchmarkHash8Bytes 6.33 10.43 1.65x
BenchmarkHash1K 72.89 131.85 1.81x
BenchmarkHash8K 80.12 147.27 1.84x
Change-Id: Ib4adf429423b20495580400be10bd7e171bcc70b
Reviewed-on: https://go-review.googlesource.com/32318
Reviewed-by: Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Adds an assembly implementation of sha512.block for ppc64le to improve its
performance. This implementation is largely based on the original amd64
implementation, unrolling the 80 iterations of the inner loop.
Fixes#17660
benchmark old ns/op new ns/op delta
BenchmarkHash8Bytes 1715 1133 -33.94%
BenchmarkHash1K 10098 5513 -45.41%
BenchmarkHash8K 68004 35278 -48.12%
benchmark old MB/s new MB/s speedup
BenchmarkHash8Bytes 4.66 7.06 1.52x
BenchmarkHash1K 101.40 185.72 1.83x
BenchmarkHash8K 120.46 232.21 1.93x
Change-Id: Ifd55a49a24cb159b3a09a8e928c3f37727aca103
Reviewed-on: https://go-review.googlesource.com/32320
Reviewed-by: Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Currently, the selection of a client certificate done internally based
on the limitations given by the server's request and the certifcates in
the Config. This means that it's not possible for an application to
control that selection based on details of the request.
This change adds a callback, GetClientCertificate, that is called by a
Client during the handshake and which allows applications to select the
best certificate at that time.
(Based on https://golang.org/cl/25570/ by Bernd Fix.)
Fixes#16626.
Change-Id: Ia4cea03235d2aa3c9fd49c99c227593c8e86ddd9
Reviewed-on: https://go-review.googlesource.com/32115
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
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>
Since a root certificate is self-signed, it's a valid child of itself.
If a root certificate appeared both in the pool of intermediates and
roots the verification code could find a chain which included it twice:
first as an intermediate and then as a root. (Existing checks prevented
the code from looping any more.)
This change stops the exact same certificate from appearing twice in a
chain. This simplifies the results in the face of the common
configuration error of a TLS server returning a root certificate.
(This should also stop two different versions of the “same” root
appearing in a chain because the self-signature on one will not validate
for the other.)
Fixes#16800.
Change-Id: I004853baa0eea27b44d47b9b34f96113a92ebac8
Reviewed-on: https://go-review.googlesource.com/32121
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
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>
By using these utility functions, the code can be made a little shorter.
Thanks to Omar Shafie for pointing this out in
https://golang.org/cl/27393/.
Change-Id: I33fd97cf7d60a31d0844ec16c12bba530dcc6f6d
Reviewed-on: https://go-review.googlesource.com/32120
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@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>
Now that we have the Clone method on tls.Config, net/http doesn't need
any custom functions to do that any more.
Change-Id: Ib60707d37f1a7f9a7d7723045f83e59eceffd026
Reviewed-on: https://go-review.googlesource.com/31595
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This change enables the ChaCha20-Poly1305 cipher suites by default. This
changes the default ClientHello and thus requires updating all the
tests.
Change-Id: I6683a2647caaff4a11f9e932babb6f07912cad94
Reviewed-on: https://go-review.googlesource.com/30958
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
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>
Although an AEAD, in general, can be used concurrently in both the seal
and open directions, TLS is easier. Since the transport keys are
different for different directions in TLS, an AEAD will only ever be
used in one direction. Thus we don't need separate buffers for seal and
open because they can never happen concurrently.
Also, fix the nonce size to twelve bytes since the fixed-prefix
construction for AEADs is superseded and will never be used for anything
else now.
Change-Id: Ibbf6c6b1da0e639f4ee0e3604410945dc7dcbb46
Reviewed-on: https://go-review.googlesource.com/30959
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This reverts commit c6185aa632. 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>
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>
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>
Adds a test to check that block cipher modes accept a zero-length
input.
Fixes#17435.
Change-Id: Ie093c4cdff756b5c2dcb79342e167b3de5622389
Reviewed-on: https://go-review.googlesource.com/31070
Run-TryBot: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Since this changes the offered curves in the ClientHello, all the test
data needs to be updated too.
Change-Id: I227934711104349c0f0eab11d854e5a2adcbc363
Reviewed-on: https://go-review.googlesource.com/30825
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
X25519 (RFC 7748) is now commonly used for key agreement in TLS
connections, as specified in
https://tools.ietf.org/html/draft-ietf-tls-curve25519-01.
This change adds support for that in crypto/tls, but does not enabled it
by default so that there's less test noise. A future change will enable
it by default and will update all the test data at the same time.
Change-Id: I91802ecd776d73aae5c65bcb653d12e23c413ed4
Reviewed-on: https://go-review.googlesource.com/30824
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
When updating the test data against OpenSSL, the handshake can fail and
the stdout/stderr output of OpenSSL is very useful in finding out why.
However, printing that output has been broken for some time because its
no longer sent to a byte.Buffer. This change fixes that.
Change-Id: I6f846c7dc80f1ccee9fa1be36f0b579b3754e05f
Reviewed-on: https://go-review.googlesource.com/30823
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
We will need OpenSSL 1.1.0 in order to test some of the features
expected for Go 1.8. However, 1.1.0 also disables (by default) some
things that we still want to test, such as RC4, 3DES and SSLv3. Thus
developers wanting to update the crypto/tls test data will need to build
OpenSSL from source.
This change updates the test data with transcripts generated by 1.1.0
(in order to reduce future diffs) and also causes a banner to be printed
if 1.1.0 is not used when updating.
(The test for an ALPN mismatch is removed because OpenSSL now terminates
the connection with a fatal alert if no known ALPN protocols are
offered. There's no point testing against this because it's an OpenSSL
behaviour.)
Change-Id: I957516975e0b8c7def84184f65c81d0b68f1c551
Reviewed-on: https://go-review.googlesource.com/30821
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
The Subject and Issuer names in a certificate look like they should be a
list of key-value pairs. However, they're actually a list of lists of
key-value pairs. Previously we only looked at the first element of each
sublist and the vast majority of certificates only have one element per
sublist.
However, it's possible to have multiple elements and some 360
certificates from the “Pilot” log are so constructed.
This change causes all elements of the sublists to be processed.
Fixes#16836.
Change-Id: Ie0a5159135b08226ec517fcf251aa17aada37857
Reviewed-on: https://go-review.googlesource.com/30810
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
RHEL 7 introduces a new tool, update-ca-trust(8), which places the
certificate bundle in a new location. Add this path to the list of
locations that are searched for the certificate bundle.
Fixes#15749
Change-Id: Idc97f885ee48ef085f1eb4dacbd1c2cf55f94ff5
Reviewed-on: https://go-review.googlesource.com/30375
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Also adds two tests: one to exercise the counter incrementing code
and one which checks the output of the optimized implementation
against that of the generic implementation for large/unaligned data
sizes.
Uses the KIMD instruction for GHASH and the KMCTR instruction for AES
in counter mode.
AESGCMSeal1K 75.0MB/s ± 2% 1008.7MB/s ± 1% +1245.71% (p=0.000 n=10+10)
AESGCMOpen1K 75.3MB/s ± 1% 1006.0MB/s ± 1% +1235.59% (p=0.000 n=10+9)
AESGCMSeal8K 78.5MB/s ± 1% 1748.4MB/s ± 1% +2127.34% (p=0.000 n=9+10)
AESGCMOpen8K 78.5MB/s ± 0% 1752.7MB/s ± 0% +2134.07% (p=0.000 n=10+9)
Change-Id: I88dbcfcb5988104bfd290ae15a60a2721c1338be
Reviewed-on: https://go-review.googlesource.com/30361
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
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>
The code comment mixed up max and min. In this case, min is correct
because this entropy is only used to make the signature scheme
probabilistic. (I.e. if it were fixed then the scheme would still be
secure except that key.Sign(foo) would always give the same result for a
fixed key and foo.)
For this purpose, 256-bits is plenty.
Fixes#16819.
Change-Id: I309bb312b775cf0c4b7463c980ba4b19ad412c36
Reviewed-on: https://go-review.googlesource.com/30153
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Currently, if a certificate contains no names (that we parsed),
verification will return the confusing error:
x509: certificate is valid for , not example.com.
This change improves the error for that situation.
Fixes#16834.
Change-Id: I2ed9ed08298d7d50df758e503bdb55277449bf55
Reviewed-on: https://go-review.googlesource.com/30152
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Since there's no aspect of key logging that OpenSSL can check for us,
the tests for it might as well just connect to another goroutine as this
is lower-maintainance.
Change-Id: I746d1dbad1b4bbfc8ef6ccf136ee4824dbda021e
Reviewed-on: https://go-review.googlesource.com/30089
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joonas Kuorilehto <joneskoo@derbian.fi>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
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>
After renegotiation support was added (af125a5193) 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>
If there are too few primes of the given length then it can be
impossible to generate an RSA key with n distinct primes.
This change approximates the expected number of candidate primes and
causes key generation to return an error if it's unlikely to succeed.
Fixes#16596.
Change-Id: I53b60d0cb90e2d0e6f0662befa64d13f24af51a7
Reviewed-on: https://go-review.googlesource.com/28969
Reviewed-by: Minux Ma <minux@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Minux Ma <minux@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>