crypto/tls: add ALPN support.
Fixes #6736.
LGTM=mikioh.mikioh
R=bradfitz, mikioh.mikioh
CC=golang-codereviews
https://golang.org/cl/108710046
diff --git a/src/pkg/crypto/tls/handshake_client_test.go b/src/pkg/crypto/tls/handshake_client_test.go
index 0d73c8e..432308b 100644
--- a/src/pkg/crypto/tls/handshake_client_test.go
+++ b/src/pkg/crypto/tls/handshake_client_test.go
@@ -49,6 +49,10 @@
// key, if not nil, contains either a *rsa.PrivateKey or
// *ecdsa.PrivateKey which is the private key for the reference server.
key interface{}
+ // validate, if not nil, is a function that will be called with the
+ // ConnectionState of the resulting connection. It returns a non-nil
+ // error if the ConnectionState is unacceptable.
+ validate func(ConnectionState) error
}
var defaultServerCommand = []string{"openssl", "s_server"}
@@ -188,6 +192,11 @@
if _, err := client.Write([]byte("hello\n")); err != nil {
t.Logf("Client.Write failed: %s", err)
}
+ if test.validate != nil {
+ if err := test.validate(client.ConnectionState()); err != nil {
+ t.Logf("validate callback returned error: %s", err)
+ }
+ }
client.Close()
clientConn.Close()
doneChan <- true
@@ -437,3 +446,45 @@
t.Fatalf("failed to add nil entry to cache")
}
}
+
+func TestHandshakeClientALPNMatch(t *testing.T) {
+ config := *testConfig
+ config.NextProtos = []string{"proto2", "proto1"}
+
+ test := &clientTest{
+ name: "ALPN",
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -alpn flag.
+ command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"},
+ config: &config,
+ validate: func(state ConnectionState) error {
+ // The server's preferences should override the client.
+ if state.NegotiatedProtocol != "proto1" {
+ return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol)
+ }
+ return nil
+ },
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientALPNNoMatch(t *testing.T) {
+ config := *testConfig
+ config.NextProtos = []string{"proto3"}
+
+ test := &clientTest{
+ name: "ALPN-NoMatch",
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -alpn flag.
+ command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"},
+ config: &config,
+ validate: func(state ConnectionState) error {
+ // There's no overlap so OpenSSL will not select a protocol.
+ if state.NegotiatedProtocol != "" {
+ return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol)
+ }
+ return nil
+ },
+ }
+ runClientTestTLS12(t, test)
+}