]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: Server can specify an unadvertised cipher suite
authorRalph Corderoy <ralph@inputplus.co.uk>
Sat, 7 Nov 2015 12:18:36 +0000 (12:18 +0000)
committerRuss Cox <rsc@golang.org>
Thu, 26 Nov 2015 17:22:57 +0000 (17:22 +0000)
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>
src/crypto/tls/handshake_client.go
src/crypto/tls/handshake_client_test.go

index 462acfd1a121ac12eebcd6a89db622355347fe36..3c996acf8785b414e8efb630bdca3b6747b05c21 100644 (file)
@@ -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{
index 31ddac61929182b95b16f7d917f1ee12fcf6c10e..f78cc4693550f504e55422d7611dce3e097bca46 100644 (file)
@@ -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)
+       }
+}