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{
"os/exec"
"path/filepath"
"strconv"
+ "strings"
"testing"
"time"
)
}
}
}
+
+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)
+ }
+}