github.com/fjballest/golang@v0.0.0-20151209143359-e4c5fe594ca8/src/crypto/tls/handshake_client_test.go (about)

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tls
     6  
     7  import (
     8  	"bytes"
     9  	"crypto/ecdsa"
    10  	"crypto/rsa"
    11  	"crypto/x509"
    12  	"encoding/base64"
    13  	"encoding/binary"
    14  	"encoding/pem"
    15  	"fmt"
    16  	"io"
    17  	"net"
    18  	"os"
    19  	"os/exec"
    20  	"path/filepath"
    21  	"strconv"
    22  	"strings"
    23  	"testing"
    24  	"time"
    25  )
    26  
    27  // Note: see comment in handshake_test.go for details of how the reference
    28  // tests work.
    29  
    30  // blockingSource is an io.Reader that blocks a Read call until it's closed.
    31  type blockingSource chan bool
    32  
    33  func (b blockingSource) Read([]byte) (n int, err error) {
    34  	<-b
    35  	return 0, io.EOF
    36  }
    37  
    38  // clientTest represents a test of the TLS client handshake against a reference
    39  // implementation.
    40  type clientTest struct {
    41  	// name is a freeform string identifying the test and the file in which
    42  	// the expected results will be stored.
    43  	name string
    44  	// command, if not empty, contains a series of arguments for the
    45  	// command to run for the reference server.
    46  	command []string
    47  	// config, if not nil, contains a custom Config to use for this test.
    48  	config *Config
    49  	// cert, if not empty, contains a DER-encoded certificate for the
    50  	// reference server.
    51  	cert []byte
    52  	// key, if not nil, contains either a *rsa.PrivateKey or
    53  	// *ecdsa.PrivateKey which is the private key for the reference server.
    54  	key interface{}
    55  	// extensions, if not nil, contains a list of extension data to be returned
    56  	// from the ServerHello. The data should be in standard TLS format with
    57  	// a 2-byte uint16 type, 2-byte data length, followed by the extension data.
    58  	extensions [][]byte
    59  	// validate, if not nil, is a function that will be called with the
    60  	// ConnectionState of the resulting connection. It returns a non-nil
    61  	// error if the ConnectionState is unacceptable.
    62  	validate func(ConnectionState) error
    63  }
    64  
    65  var defaultServerCommand = []string{"openssl", "s_server"}
    66  
    67  // connFromCommand starts the reference server process, connects to it and
    68  // returns a recordingConn for the connection. The stdin return value is a
    69  // blockingSource for the stdin of the child process. It must be closed before
    70  // Waiting for child.
    71  func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, stdin blockingSource, err error) {
    72  	cert := testRSACertificate
    73  	if len(test.cert) > 0 {
    74  		cert = test.cert
    75  	}
    76  	certPath := tempFile(string(cert))
    77  	defer os.Remove(certPath)
    78  
    79  	var key interface{} = testRSAPrivateKey
    80  	if test.key != nil {
    81  		key = test.key
    82  	}
    83  	var pemType string
    84  	var derBytes []byte
    85  	switch key := key.(type) {
    86  	case *rsa.PrivateKey:
    87  		pemType = "RSA"
    88  		derBytes = x509.MarshalPKCS1PrivateKey(key)
    89  	case *ecdsa.PrivateKey:
    90  		pemType = "EC"
    91  		var err error
    92  		derBytes, err = x509.MarshalECPrivateKey(key)
    93  		if err != nil {
    94  			panic(err)
    95  		}
    96  	default:
    97  		panic("unknown key type")
    98  	}
    99  
   100  	var pemOut bytes.Buffer
   101  	pem.Encode(&pemOut, &pem.Block{Type: pemType + " PRIVATE KEY", Bytes: derBytes})
   102  
   103  	keyPath := tempFile(string(pemOut.Bytes()))
   104  	defer os.Remove(keyPath)
   105  
   106  	var command []string
   107  	if len(test.command) > 0 {
   108  		command = append(command, test.command...)
   109  	} else {
   110  		command = append(command, defaultServerCommand...)
   111  	}
   112  	command = append(command, "-cert", certPath, "-certform", "DER", "-key", keyPath)
   113  	// serverPort contains the port that OpenSSL will listen on. OpenSSL
   114  	// can't take "0" as an argument here so we have to pick a number and
   115  	// hope that it's not in use on the machine. Since this only occurs
   116  	// when -update is given and thus when there's a human watching the
   117  	// test, this isn't too bad.
   118  	const serverPort = 24323
   119  	command = append(command, "-accept", strconv.Itoa(serverPort))
   120  
   121  	if len(test.extensions) > 0 {
   122  		var serverInfo bytes.Buffer
   123  		for _, ext := range test.extensions {
   124  			pem.Encode(&serverInfo, &pem.Block{
   125  				Type:  fmt.Sprintf("SERVERINFO FOR EXTENSION %d", binary.BigEndian.Uint16(ext)),
   126  				Bytes: ext,
   127  			})
   128  		}
   129  		serverInfoPath := tempFile(serverInfo.String())
   130  		defer os.Remove(serverInfoPath)
   131  		command = append(command, "-serverinfo", serverInfoPath)
   132  	}
   133  
   134  	cmd := exec.Command(command[0], command[1:]...)
   135  	stdin = blockingSource(make(chan bool))
   136  	cmd.Stdin = stdin
   137  	var out bytes.Buffer
   138  	cmd.Stdout = &out
   139  	cmd.Stderr = &out
   140  	if err := cmd.Start(); err != nil {
   141  		return nil, nil, nil, err
   142  	}
   143  
   144  	// OpenSSL does print an "ACCEPT" banner, but it does so *before*
   145  	// opening the listening socket, so we can't use that to wait until it
   146  	// has started listening. Thus we are forced to poll until we get a
   147  	// connection.
   148  	var tcpConn net.Conn
   149  	for i := uint(0); i < 5; i++ {
   150  		tcpConn, err = net.DialTCP("tcp", nil, &net.TCPAddr{
   151  			IP:   net.IPv4(127, 0, 0, 1),
   152  			Port: serverPort,
   153  		})
   154  		if err == nil {
   155  			break
   156  		}
   157  		time.Sleep((1 << i) * 5 * time.Millisecond)
   158  	}
   159  	if err != nil {
   160  		close(stdin)
   161  		out.WriteTo(os.Stdout)
   162  		cmd.Process.Kill()
   163  		return nil, nil, nil, cmd.Wait()
   164  	}
   165  
   166  	record := &recordingConn{
   167  		Conn: tcpConn,
   168  	}
   169  
   170  	return record, cmd, stdin, nil
   171  }
   172  
   173  func (test *clientTest) dataPath() string {
   174  	return filepath.Join("testdata", "Client-"+test.name)
   175  }
   176  
   177  func (test *clientTest) loadData() (flows [][]byte, err error) {
   178  	in, err := os.Open(test.dataPath())
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  	defer in.Close()
   183  	return parseTestData(in)
   184  }
   185  
   186  func (test *clientTest) run(t *testing.T, write bool) {
   187  	var clientConn, serverConn net.Conn
   188  	var recordingConn *recordingConn
   189  	var childProcess *exec.Cmd
   190  	var stdin blockingSource
   191  
   192  	if write {
   193  		var err error
   194  		recordingConn, childProcess, stdin, err = test.connFromCommand()
   195  		if err != nil {
   196  			t.Fatalf("Failed to start subcommand: %s", err)
   197  		}
   198  		clientConn = recordingConn
   199  	} else {
   200  		clientConn, serverConn = net.Pipe()
   201  	}
   202  
   203  	config := test.config
   204  	if config == nil {
   205  		config = testConfig
   206  	}
   207  	client := Client(clientConn, config)
   208  
   209  	doneChan := make(chan bool)
   210  	go func() {
   211  		if _, err := client.Write([]byte("hello\n")); err != nil {
   212  			t.Errorf("Client.Write failed: %s", err)
   213  		}
   214  		if test.validate != nil {
   215  			if err := test.validate(client.ConnectionState()); err != nil {
   216  				t.Errorf("validate callback returned error: %s", err)
   217  			}
   218  		}
   219  		client.Close()
   220  		clientConn.Close()
   221  		doneChan <- true
   222  	}()
   223  
   224  	if !write {
   225  		flows, err := test.loadData()
   226  		if err != nil {
   227  			t.Fatalf("%s: failed to load data from %s: %v", test.name, test.dataPath(), err)
   228  		}
   229  		for i, b := range flows {
   230  			if i%2 == 1 {
   231  				serverConn.Write(b)
   232  				continue
   233  			}
   234  			bb := make([]byte, len(b))
   235  			_, err := io.ReadFull(serverConn, bb)
   236  			if err != nil {
   237  				t.Fatalf("%s #%d: %s", test.name, i, err)
   238  			}
   239  			if !bytes.Equal(b, bb) {
   240  				t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i, bb, b)
   241  			}
   242  		}
   243  		serverConn.Close()
   244  	}
   245  
   246  	<-doneChan
   247  
   248  	if write {
   249  		path := test.dataPath()
   250  		out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
   251  		if err != nil {
   252  			t.Fatalf("Failed to create output file: %s", err)
   253  		}
   254  		defer out.Close()
   255  		recordingConn.Close()
   256  		close(stdin)
   257  		childProcess.Process.Kill()
   258  		childProcess.Wait()
   259  		if len(recordingConn.flows) < 3 {
   260  			childProcess.Stdout.(*bytes.Buffer).WriteTo(os.Stdout)
   261  			t.Fatalf("Client connection didn't work")
   262  		}
   263  		recordingConn.WriteTo(out)
   264  		fmt.Printf("Wrote %s\n", path)
   265  	}
   266  }
   267  
   268  func runClientTestForVersion(t *testing.T, template *clientTest, prefix, option string) {
   269  	test := *template
   270  	test.name = prefix + test.name
   271  	if len(test.command) == 0 {
   272  		test.command = defaultClientCommand
   273  	}
   274  	test.command = append([]string(nil), test.command...)
   275  	test.command = append(test.command, option)
   276  	test.run(t, *update)
   277  }
   278  
   279  func runClientTestTLS10(t *testing.T, template *clientTest) {
   280  	runClientTestForVersion(t, template, "TLSv10-", "-tls1")
   281  }
   282  
   283  func runClientTestTLS11(t *testing.T, template *clientTest) {
   284  	runClientTestForVersion(t, template, "TLSv11-", "-tls1_1")
   285  }
   286  
   287  func runClientTestTLS12(t *testing.T, template *clientTest) {
   288  	runClientTestForVersion(t, template, "TLSv12-", "-tls1_2")
   289  }
   290  
   291  func TestHandshakeClientRSARC4(t *testing.T) {
   292  	test := &clientTest{
   293  		name:    "RSA-RC4",
   294  		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA"},
   295  	}
   296  	runClientTestTLS10(t, test)
   297  	runClientTestTLS11(t, test)
   298  	runClientTestTLS12(t, test)
   299  }
   300  
   301  func TestHandshakeClientRSAAES128GCM(t *testing.T) {
   302  	test := &clientTest{
   303  		name:    "AES128-GCM-SHA256",
   304  		command: []string{"openssl", "s_server", "-cipher", "AES128-GCM-SHA256"},
   305  	}
   306  	runClientTestTLS12(t, test)
   307  }
   308  
   309  func TestHandshakeClientRSAAES256GCM(t *testing.T) {
   310  	test := &clientTest{
   311  		name:    "AES256-GCM-SHA384",
   312  		command: []string{"openssl", "s_server", "-cipher", "AES256-GCM-SHA384"},
   313  	}
   314  	runClientTestTLS12(t, test)
   315  }
   316  
   317  func TestHandshakeClientECDHERSAAES(t *testing.T) {
   318  	test := &clientTest{
   319  		name:    "ECDHE-RSA-AES",
   320  		command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES128-SHA"},
   321  	}
   322  	runClientTestTLS10(t, test)
   323  	runClientTestTLS11(t, test)
   324  	runClientTestTLS12(t, test)
   325  }
   326  
   327  func TestHandshakeClientECDHEECDSAAES(t *testing.T) {
   328  	test := &clientTest{
   329  		name:    "ECDHE-ECDSA-AES",
   330  		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA"},
   331  		cert:    testECDSACertificate,
   332  		key:     testECDSAPrivateKey,
   333  	}
   334  	runClientTestTLS10(t, test)
   335  	runClientTestTLS11(t, test)
   336  	runClientTestTLS12(t, test)
   337  }
   338  
   339  func TestHandshakeClientECDHEECDSAAESGCM(t *testing.T) {
   340  	test := &clientTest{
   341  		name:    "ECDHE-ECDSA-AES-GCM",
   342  		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-GCM-SHA256"},
   343  		cert:    testECDSACertificate,
   344  		key:     testECDSAPrivateKey,
   345  	}
   346  	runClientTestTLS12(t, test)
   347  }
   348  
   349  func TestHandshakeClientAES256GCMSHA384(t *testing.T) {
   350  	test := &clientTest{
   351  		name:    "ECDHE-ECDSA-AES256-GCM-SHA384",
   352  		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES256-GCM-SHA384"},
   353  		cert:    testECDSACertificate,
   354  		key:     testECDSAPrivateKey,
   355  	}
   356  	runClientTestTLS12(t, test)
   357  }
   358  
   359  func TestHandshakeClientCertRSA(t *testing.T) {
   360  	config := *testConfig
   361  	cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
   362  	config.Certificates = []Certificate{cert}
   363  
   364  	test := &clientTest{
   365  		name:    "ClientCert-RSA-RSA",
   366  		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"},
   367  		config:  &config,
   368  	}
   369  
   370  	runClientTestTLS10(t, test)
   371  	runClientTestTLS12(t, test)
   372  
   373  	test = &clientTest{
   374  		name:    "ClientCert-RSA-ECDSA",
   375  		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"},
   376  		config:  &config,
   377  		cert:    testECDSACertificate,
   378  		key:     testECDSAPrivateKey,
   379  	}
   380  
   381  	runClientTestTLS10(t, test)
   382  	runClientTestTLS12(t, test)
   383  
   384  	test = &clientTest{
   385  		name:    "ClientCert-RSA-AES256-GCM-SHA384",
   386  		command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384", "-verify", "1"},
   387  		config:  &config,
   388  		cert:    testRSACertificate,
   389  		key:     testRSAPrivateKey,
   390  	}
   391  
   392  	runClientTestTLS12(t, test)
   393  }
   394  
   395  func TestHandshakeClientCertECDSA(t *testing.T) {
   396  	config := *testConfig
   397  	cert, _ := X509KeyPair([]byte(clientECDSACertificatePEM), []byte(clientECDSAKeyPEM))
   398  	config.Certificates = []Certificate{cert}
   399  
   400  	test := &clientTest{
   401  		name:    "ClientCert-ECDSA-RSA",
   402  		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"},
   403  		config:  &config,
   404  	}
   405  
   406  	runClientTestTLS10(t, test)
   407  	runClientTestTLS12(t, test)
   408  
   409  	test = &clientTest{
   410  		name:    "ClientCert-ECDSA-ECDSA",
   411  		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"},
   412  		config:  &config,
   413  		cert:    testECDSACertificate,
   414  		key:     testECDSAPrivateKey,
   415  	}
   416  
   417  	runClientTestTLS10(t, test)
   418  	runClientTestTLS12(t, test)
   419  }
   420  
   421  func TestClientResumption(t *testing.T) {
   422  	serverConfig := &Config{
   423  		CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
   424  		Certificates: testConfig.Certificates,
   425  	}
   426  
   427  	issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
   428  	if err != nil {
   429  		panic(err)
   430  	}
   431  
   432  	rootCAs := x509.NewCertPool()
   433  	rootCAs.AddCert(issuer)
   434  
   435  	clientConfig := &Config{
   436  		CipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
   437  		ClientSessionCache: NewLRUClientSessionCache(32),
   438  		RootCAs:            rootCAs,
   439  		ServerName:         "example.golang",
   440  	}
   441  
   442  	testResumeState := func(test string, didResume bool) {
   443  		_, hs, err := testHandshake(clientConfig, serverConfig)
   444  		if err != nil {
   445  			t.Fatalf("%s: handshake failed: %s", test, err)
   446  		}
   447  		if hs.DidResume != didResume {
   448  			t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume)
   449  		}
   450  		if didResume && (hs.PeerCertificates == nil || hs.VerifiedChains == nil) {
   451  			t.Fatalf("expected non-nil certificates after resumption. Got peerCertificates: %#v, verifedCertificates: %#v", hs.PeerCertificates, hs.VerifiedChains)
   452  		}
   453  	}
   454  
   455  	getTicket := func() []byte {
   456  		return clientConfig.ClientSessionCache.(*lruSessionCache).q.Front().Value.(*lruSessionCacheEntry).state.sessionTicket
   457  	}
   458  	randomKey := func() [32]byte {
   459  		var k [32]byte
   460  		if _, err := io.ReadFull(serverConfig.rand(), k[:]); err != nil {
   461  			t.Fatalf("Failed to read new SessionTicketKey: %s", err)
   462  		}
   463  		return k
   464  	}
   465  
   466  	testResumeState("Handshake", false)
   467  	ticket := getTicket()
   468  	testResumeState("Resume", true)
   469  	if !bytes.Equal(ticket, getTicket()) {
   470  		t.Fatal("first ticket doesn't match ticket after resumption")
   471  	}
   472  
   473  	key2 := randomKey()
   474  	serverConfig.SetSessionTicketKeys([][32]byte{key2})
   475  
   476  	testResumeState("InvalidSessionTicketKey", false)
   477  	testResumeState("ResumeAfterInvalidSessionTicketKey", true)
   478  
   479  	serverConfig.SetSessionTicketKeys([][32]byte{randomKey(), key2})
   480  	ticket = getTicket()
   481  	testResumeState("KeyChange", true)
   482  	if bytes.Equal(ticket, getTicket()) {
   483  		t.Fatal("new ticket wasn't included while resuming")
   484  	}
   485  	testResumeState("KeyChangeFinish", true)
   486  
   487  	clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}
   488  	testResumeState("DifferentCipherSuite", false)
   489  	testResumeState("DifferentCipherSuiteRecovers", true)
   490  
   491  	clientConfig.ClientSessionCache = nil
   492  	testResumeState("WithoutSessionCache", false)
   493  }
   494  
   495  func TestLRUClientSessionCache(t *testing.T) {
   496  	// Initialize cache of capacity 4.
   497  	cache := NewLRUClientSessionCache(4)
   498  	cs := make([]ClientSessionState, 6)
   499  	keys := []string{"0", "1", "2", "3", "4", "5", "6"}
   500  
   501  	// Add 4 entries to the cache and look them up.
   502  	for i := 0; i < 4; i++ {
   503  		cache.Put(keys[i], &cs[i])
   504  	}
   505  	for i := 0; i < 4; i++ {
   506  		if s, ok := cache.Get(keys[i]); !ok || s != &cs[i] {
   507  			t.Fatalf("session cache failed lookup for added key: %s", keys[i])
   508  		}
   509  	}
   510  
   511  	// Add 2 more entries to the cache. First 2 should be evicted.
   512  	for i := 4; i < 6; i++ {
   513  		cache.Put(keys[i], &cs[i])
   514  	}
   515  	for i := 0; i < 2; i++ {
   516  		if s, ok := cache.Get(keys[i]); ok || s != nil {
   517  			t.Fatalf("session cache should have evicted key: %s", keys[i])
   518  		}
   519  	}
   520  
   521  	// Touch entry 2. LRU should evict 3 next.
   522  	cache.Get(keys[2])
   523  	cache.Put(keys[0], &cs[0])
   524  	if s, ok := cache.Get(keys[3]); ok || s != nil {
   525  		t.Fatalf("session cache should have evicted key 3")
   526  	}
   527  
   528  	// Update entry 0 in place.
   529  	cache.Put(keys[0], &cs[3])
   530  	if s, ok := cache.Get(keys[0]); !ok || s != &cs[3] {
   531  		t.Fatalf("session cache failed update for key 0")
   532  	}
   533  
   534  	// Adding a nil entry is valid.
   535  	cache.Put(keys[0], nil)
   536  	if s, ok := cache.Get(keys[0]); !ok || s != nil {
   537  		t.Fatalf("failed to add nil entry to cache")
   538  	}
   539  }
   540  
   541  func TestHandshakeClientALPNMatch(t *testing.T) {
   542  	config := *testConfig
   543  	config.NextProtos = []string{"proto2", "proto1"}
   544  
   545  	test := &clientTest{
   546  		name: "ALPN",
   547  		// Note that this needs OpenSSL 1.0.2 because that is the first
   548  		// version that supports the -alpn flag.
   549  		command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"},
   550  		config:  &config,
   551  		validate: func(state ConnectionState) error {
   552  			// The server's preferences should override the client.
   553  			if state.NegotiatedProtocol != "proto1" {
   554  				return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol)
   555  			}
   556  			return nil
   557  		},
   558  	}
   559  	runClientTestTLS12(t, test)
   560  }
   561  
   562  func TestHandshakeClientALPNNoMatch(t *testing.T) {
   563  	config := *testConfig
   564  	config.NextProtos = []string{"proto3"}
   565  
   566  	test := &clientTest{
   567  		name: "ALPN-NoMatch",
   568  		// Note that this needs OpenSSL 1.0.2 because that is the first
   569  		// version that supports the -alpn flag.
   570  		command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"},
   571  		config:  &config,
   572  		validate: func(state ConnectionState) error {
   573  			// There's no overlap so OpenSSL will not select a protocol.
   574  			if state.NegotiatedProtocol != "" {
   575  				return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol)
   576  			}
   577  			return nil
   578  		},
   579  	}
   580  	runClientTestTLS12(t, test)
   581  }
   582  
   583  // sctsBase64 contains data from `openssl s_client -serverinfo 18 -connect ritter.vg:443`
   584  const sctsBase64 = "ABIBaQFnAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFHl5nuFgAABAMARjBEAiAcS4JdlW5nW9sElUv2zvQyPoZ6ejKrGGB03gjaBZFMLwIgc1Qbbn+hsH0RvObzhS+XZhr3iuQQJY8S9G85D9KeGPAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAUeX4bVwAAAEAwBHMEUCIDIhFDgG2HIuADBkGuLobU5a4dlCHoJLliWJ1SYT05z6AiEAjxIoZFFPRNWMGGIjskOTMwXzQ1Wh2e7NxXE1kd1J0QsAdgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAUhcZIqHAAAEAwBHMEUCICmJ1rBT09LpkbzxtUC+Hi7nXLR0J+2PmwLp+sJMuqK+AiEAr0NkUnEVKVhAkccIFpYDqHOlZaBsuEhWWrYpg2RtKp0="
   585  
   586  func TestHandshakClientSCTs(t *testing.T) {
   587  	config := *testConfig
   588  
   589  	scts, err := base64.StdEncoding.DecodeString(sctsBase64)
   590  	if err != nil {
   591  		t.Fatal(err)
   592  	}
   593  
   594  	test := &clientTest{
   595  		name: "SCT",
   596  		// Note that this needs OpenSSL 1.0.2 because that is the first
   597  		// version that supports the -serverinfo flag.
   598  		command:    []string{"openssl", "s_server"},
   599  		config:     &config,
   600  		extensions: [][]byte{scts},
   601  		validate: func(state ConnectionState) error {
   602  			expectedSCTs := [][]byte{
   603  				scts[8:125],
   604  				scts[127:245],
   605  				scts[247:],
   606  			}
   607  			if n := len(state.SignedCertificateTimestamps); n != len(expectedSCTs) {
   608  				return fmt.Errorf("Got %d scts, wanted %d", n, len(expectedSCTs))
   609  			}
   610  			for i, expected := range expectedSCTs {
   611  				if sct := state.SignedCertificateTimestamps[i]; !bytes.Equal(sct, expected) {
   612  					return fmt.Errorf("SCT #%d contained %x, expected %x", i, sct, expected)
   613  				}
   614  			}
   615  			return nil
   616  		},
   617  	}
   618  	runClientTestTLS12(t, test)
   619  }
   620  
   621  func TestNoIPAddressesInSNI(t *testing.T) {
   622  	for _, ipLiteral := range []string{"1.2.3.4", "::1"} {
   623  		c, s := net.Pipe()
   624  
   625  		go func() {
   626  			client := Client(c, &Config{ServerName: ipLiteral})
   627  			client.Handshake()
   628  		}()
   629  
   630  		var header [5]byte
   631  		if _, err := io.ReadFull(s, header[:]); err != nil {
   632  			t.Fatal(err)
   633  		}
   634  		recordLen := int(header[3])<<8 | int(header[4])
   635  
   636  		record := make([]byte, recordLen)
   637  		if _, err := io.ReadFull(s, record[:]); err != nil {
   638  			t.Fatal(err)
   639  		}
   640  		s.Close()
   641  
   642  		if bytes.Index(record, []byte(ipLiteral)) != -1 {
   643  			t.Errorf("IP literal %q found in ClientHello: %x", ipLiteral, record)
   644  		}
   645  	}
   646  }
   647  
   648  func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) {
   649  	// This checks that the server can't select a cipher suite that the
   650  	// client didn't offer. See #13174.
   651  
   652  	c, s := net.Pipe()
   653  	errChan := make(chan error, 1)
   654  
   655  	go func() {
   656  		client := Client(c, &Config{
   657  			ServerName:   "foo",
   658  			CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
   659  		})
   660  		errChan <- client.Handshake()
   661  	}()
   662  
   663  	var header [5]byte
   664  	if _, err := io.ReadFull(s, header[:]); err != nil {
   665  		t.Fatal(err)
   666  	}
   667  	recordLen := int(header[3])<<8 | int(header[4])
   668  
   669  	record := make([]byte, recordLen)
   670  	if _, err := io.ReadFull(s, record); err != nil {
   671  		t.Fatal(err)
   672  	}
   673  
   674  	// Create a ServerHello that selects a different cipher suite than the
   675  	// sole one that the client offered.
   676  	serverHello := &serverHelloMsg{
   677  		vers:        VersionTLS12,
   678  		random:      make([]byte, 32),
   679  		cipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384,
   680  	}
   681  	serverHelloBytes := serverHello.marshal()
   682  
   683  	s.Write([]byte{
   684  		byte(recordTypeHandshake),
   685  		byte(VersionTLS12 >> 8),
   686  		byte(VersionTLS12 & 0xff),
   687  		byte(len(serverHelloBytes) >> 8),
   688  		byte(len(serverHelloBytes)),
   689  	})
   690  	s.Write(serverHelloBytes)
   691  	s.Close()
   692  
   693  	if err := <-errChan; !strings.Contains(err.Error(), "unconfigured cipher") {
   694  		t.Fatalf("Expected error about unconfigured cipher suite but got %q", err)
   695  	}
   696  }