summaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
authorRalph Corderoy <ralph@inputplus.co.uk>2015-11-07 12:18:36 +0000
committerRuss Cox <rsc@golang.org>2015-11-26 17:22:57 +0000
commitdb4ef216cc8d9c17f6d10d8682a46d8077b203d0 (patch)
tree65ea4927ac6ae3ecf5fabaab6b18a2fa105ceda2 /src/crypto
parentb717090e018a6dc68c19bdca4c1cea0f5dbf3b16 (diff)
downloadgo-git-db4ef216cc8d9c17f6d10d8682a46d8077b203d0.tar.gz
crypto/tls: Server can specify an unadvertised cipher suite
During the TLS handshake, check the cipher suite the server selects is one of those offered in the ClientHello. The code was checking it was in the larger list that was sometimes whittled down for the ClientHello. Fixes #13174 Change-Id: Iad8eebbcfa5027f30403b9700c43cfa949e135bb Reviewed-on: https://go-review.googlesource.com/16698 Reviewed-by: Adam Langley <agl@golang.org> Run-TryBot: Adam Langley <agl@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/tls/handshake_client.go4
-rw-r--r--src/crypto/tls/handshake_client_test.go51
2 files changed, 53 insertions, 2 deletions
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index 462acfd1a1..3c996acf87 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -165,10 +165,10 @@ NextCipherSuite:
c.vers = vers
c.haveVers = true
- suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
+ suite := mutualCipherSuite(hello.cipherSuites, serverHello.cipherSuite)
if suite == nil {
c.sendAlert(alertHandshakeFailure)
- return fmt.Errorf("tls: server selected an unsupported cipher suite")
+ return errors.New("tls: server chose an unconfigured cipher suite")
}
hs := &clientHandshakeState{
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
index 31ddac6192..f78cc46935 100644
--- a/src/crypto/tls/handshake_client_test.go
+++ b/src/crypto/tls/handshake_client_test.go
@@ -19,6 +19,7 @@ import (
"os/exec"
"path/filepath"
"strconv"
+ "strings"
"testing"
"time"
)
@@ -643,3 +644,53 @@ func TestNoIPAddressesInSNI(t *testing.T) {
}
}
}
+
+func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) {
+ // This checks that the server can't select a cipher suite that the
+ // client didn't offer. See #13174.
+
+ c, s := net.Pipe()
+ errChan := make(chan error, 1)
+
+ go func() {
+ client := Client(c, &Config{
+ ServerName: "foo",
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ })
+ errChan <- client.Handshake()
+ }()
+
+ var header [5]byte
+ if _, err := io.ReadFull(s, header[:]); err != nil {
+ t.Fatal(err)
+ }
+ recordLen := int(header[3])<<8 | int(header[4])
+
+ record := make([]byte, recordLen)
+ if _, err := io.ReadFull(s, record); err != nil {
+ t.Fatal(err)
+ }
+
+ // Create a ServerHello that selects a different cipher suite than the
+ // sole one that the client offered.
+ serverHello := &serverHelloMsg{
+ vers: VersionTLS12,
+ random: make([]byte, 32),
+ cipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384,
+ }
+ serverHelloBytes := serverHello.marshal()
+
+ s.Write([]byte{
+ byte(recordTypeHandshake),
+ byte(VersionTLS12 >> 8),
+ byte(VersionTLS12 & 0xff),
+ byte(len(serverHelloBytes) >> 8),
+ byte(len(serverHelloBytes)),
+ })
+ s.Write(serverHelloBytes)
+ s.Close()
+
+ if err := <-errChan; !strings.Contains(err.Error(), "unconfigured cipher") {
+ t.Fatalf("Expected error about unconfigured cipher suite but got %q", err)
+ }
+}