diff --git a/ssl/test/CMakeLists.txt b/ssl/test/CMakeLists.txt
new file mode 100644
index 0000000..7d073c1
--- /dev/null
+++ b/ssl/test/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_executable(
+	client_shim
+
+	client_shim.cc
+)
+
+target_link_libraries(client_shim ssl crypto)
diff --git a/ssl/test/client_shim.cc b/ssl/test/client_shim.cc
new file mode 100644
index 0000000..9beaf59
--- /dev/null
+++ b/ssl/test/client_shim.cc
@@ -0,0 +1,93 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+
+
+SSL *setup_test() {
+  if (!SSL_library_init()) {
+    return NULL;
+  }
+
+  SSL_CTX *client_ctx = NULL;
+  SSL *client = NULL;
+  BIO *bio = NULL;
+
+  client_ctx = SSL_CTX_new(SSLv23_client_method());
+  if (client_ctx == NULL) {
+    goto err;
+  }
+
+  if (!SSL_CTX_set_cipher_list(client_ctx, "ALL")) {
+    goto err;
+  }
+
+  client = SSL_new(client_ctx);
+  if (client == NULL) {
+    goto err;
+  }
+
+  bio = BIO_new_fd(3, 1 /* take ownership */);
+  if (bio == NULL) {
+    goto err;
+  }
+
+  SSL_set_bio(client, bio, bio);
+  SSL_CTX_free(client_ctx);
+
+  return client;
+
+err:
+  if (bio != NULL) {
+    BIO_free(bio);
+  }
+  if (client != NULL) {
+    SSL_free(client);
+  }
+  if (client_ctx != NULL) {
+    SSL_CTX_free(client_ctx);
+  }
+  return NULL;
+}
+
+int main() {
+  SSL *client = setup_test();
+  if (client == NULL) {
+    BIO_print_errors_fp(stdout);
+    return 1;
+  }
+
+  if (SSL_connect(client) != 1) {
+    SSL_free(client);
+    BIO_print_errors_fp(stdout);
+    return 2;
+  }
+
+  for (;;) {
+    uint8_t buf[512];
+    int n = SSL_read(client, buf, sizeof(buf));
+    if (n < 0) {
+      SSL_free(client);
+      BIO_print_errors_fp(stdout);
+      return 3;
+    } else if (n == 0) {
+      break;
+    } else {
+      for (int i = 0; i < n; i++) {
+        buf[i] ^= 0xff;
+      }
+      int w = SSL_write(client, buf, n);
+      if (w != n) {
+        SSL_free(client);
+        BIO_print_errors_fp(stdout);
+        return 4;
+      }
+    }
+  }
+
+  SSL_free(client);
+  return 0;
+}
diff --git a/ssl/test/runner/alert.go b/ssl/test/runner/alert.go
new file mode 100644
index 0000000..b48ab2a
--- /dev/null
+++ b/ssl/test/runner/alert.go
@@ -0,0 +1,77 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strconv"
+
+type alert uint8
+
+const (
+	// alert level
+	alertLevelWarning = 1
+	alertLevelError   = 2
+)
+
+const (
+	alertCloseNotify            alert = 0
+	alertUnexpectedMessage      alert = 10
+	alertBadRecordMAC           alert = 20
+	alertDecryptionFailed       alert = 21
+	alertRecordOverflow         alert = 22
+	alertDecompressionFailure   alert = 30
+	alertHandshakeFailure       alert = 40
+	alertBadCertificate         alert = 42
+	alertUnsupportedCertificate alert = 43
+	alertCertificateRevoked     alert = 44
+	alertCertificateExpired     alert = 45
+	alertCertificateUnknown     alert = 46
+	alertIllegalParameter       alert = 47
+	alertUnknownCA              alert = 48
+	alertAccessDenied           alert = 49
+	alertDecodeError            alert = 50
+	alertDecryptError           alert = 51
+	alertProtocolVersion        alert = 70
+	alertInsufficientSecurity   alert = 71
+	alertInternalError          alert = 80
+	alertUserCanceled           alert = 90
+	alertNoRenegotiation        alert = 100
+)
+
+var alertText = map[alert]string{
+	alertCloseNotify:            "close notify",
+	alertUnexpectedMessage:      "unexpected message",
+	alertBadRecordMAC:           "bad record MAC",
+	alertDecryptionFailed:       "decryption failed",
+	alertRecordOverflow:         "record overflow",
+	alertDecompressionFailure:   "decompression failure",
+	alertHandshakeFailure:       "handshake failure",
+	alertBadCertificate:         "bad certificate",
+	alertUnsupportedCertificate: "unsupported certificate",
+	alertCertificateRevoked:     "revoked certificate",
+	alertCertificateExpired:     "expired certificate",
+	alertCertificateUnknown:     "unknown certificate",
+	alertIllegalParameter:       "illegal parameter",
+	alertUnknownCA:              "unknown certificate authority",
+	alertAccessDenied:           "access denied",
+	alertDecodeError:            "error decoding message",
+	alertDecryptError:           "error decrypting message",
+	alertProtocolVersion:        "protocol version not supported",
+	alertInsufficientSecurity:   "insufficient security level",
+	alertInternalError:          "internal error",
+	alertUserCanceled:           "user canceled",
+	alertNoRenegotiation:        "no renegotiation",
+}
+
+func (e alert) String() string {
+	s, ok := alertText[e]
+	if ok {
+		return s
+	}
+	return "alert(" + strconv.Itoa(int(e)) + ")"
+}
+
+func (e alert) Error() string {
+	return e.String()
+}
diff --git a/ssl/test/runner/cert.pem b/ssl/test/runner/cert.pem
new file mode 100644
index 0000000..4de4f49
--- /dev/null
+++ b/ssl/test/runner/cert.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci
+HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV
+W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV
+HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f
+Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht
+ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr
+T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f
+j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==
+-----END CERTIFICATE-----
diff --git a/ssl/test/runner/cipher_suites.go b/ssl/test/runner/cipher_suites.go
new file mode 100644
index 0000000..11c8bdd
--- /dev/null
+++ b/ssl/test/runner/cipher_suites.go
@@ -0,0 +1,290 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/des"
+	"crypto/hmac"
+	"crypto/md5"
+	"crypto/rc4"
+	"crypto/sha1"
+	"crypto/x509"
+	"hash"
+)
+
+// a keyAgreement implements the client and server side of a TLS key agreement
+// protocol by generating and processing key exchange messages.
+type keyAgreement interface {
+	// On the server side, the first two methods are called in order.
+
+	// In the case that the key agreement protocol doesn't use a
+	// ServerKeyExchange message, generateServerKeyExchange can return nil,
+	// nil.
+	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
+	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
+
+	// On the client side, the next two methods are called in order.
+
+	// This method may not be called if the server doesn't send a
+	// ServerKeyExchange message.
+	processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
+	generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
+}
+
+const (
+	// suiteECDH indicates that the cipher suite involves elliptic curve
+	// Diffie-Hellman. This means that it should only be selected when the
+	// client indicates that it supports ECC with a curve and point format
+	// that we're happy with.
+	suiteECDHE = 1 << iota
+	// suiteECDSA indicates that the cipher suite involves an ECDSA
+	// signature and therefore may only be selected when the server's
+	// certificate is ECDSA. If this is not set then the cipher suite is
+	// RSA based.
+	suiteECDSA
+	// suiteTLS12 indicates that the cipher suite should only be advertised
+	// and accepted when using TLS 1.2.
+	suiteTLS12
+	// suiteSHA384 indicates that the cipher suite uses SHA384 as the
+	// handshake hash.
+	suiteSHA384
+)
+
+// A cipherSuite is a specific combination of key agreement, cipher and MAC
+// function. All cipher suites currently assume RSA key agreement.
+type cipherSuite struct {
+	id uint16
+	// the lengths, in bytes, of the key material needed for each component.
+	keyLen int
+	macLen int
+	ivLen  int
+	ka     func(version uint16) keyAgreement
+	// flags is a bitmask of the suite* values, above.
+	flags  int
+	cipher func(key, iv []byte, isRead bool) interface{}
+	mac    func(version uint16, macKey []byte) macFunction
+	aead   func(key, fixedNonce []byte) cipher.AEAD
+}
+
+var cipherSuites = []*cipherSuite{
+	// Ciphersuite order is chosen so that ECDHE comes before plain RSA
+	// and RC4 comes before AES (because of the Lucky13 attack).
+	{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
+	{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
+	{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
+	{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherRC4, macSHA1, nil},
+	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
+	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
+	{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
+	{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
+	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
+	{TLS_RSA_WITH_RC4_128_MD5, 16, 16, 0, rsaKA, 0, cipherRC4, macMD5, nil},
+	{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
+	{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
+	{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
+	{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
+}
+
+func cipherRC4(key, iv []byte, isRead bool) interface{} {
+	cipher, _ := rc4.NewCipher(key)
+	return cipher
+}
+
+func cipher3DES(key, iv []byte, isRead bool) interface{} {
+	block, _ := des.NewTripleDESCipher(key)
+	if isRead {
+		return cipher.NewCBCDecrypter(block, iv)
+	}
+	return cipher.NewCBCEncrypter(block, iv)
+}
+
+func cipherAES(key, iv []byte, isRead bool) interface{} {
+	block, _ := aes.NewCipher(key)
+	if isRead {
+		return cipher.NewCBCDecrypter(block, iv)
+	}
+	return cipher.NewCBCEncrypter(block, iv)
+}
+
+// macSHA1 returns a macFunction for the given protocol version.
+func macSHA1(version uint16, key []byte) macFunction {
+	if version == VersionSSL30 {
+		mac := ssl30MAC{
+			h:   sha1.New(),
+			key: make([]byte, len(key)),
+		}
+		copy(mac.key, key)
+		return mac
+	}
+	return tls10MAC{hmac.New(sha1.New, key)}
+}
+
+func macMD5(version uint16, key []byte) macFunction {
+	if version == VersionSSL30 {
+		mac := ssl30MAC{
+			h:   md5.New(),
+			key: make([]byte, len(key)),
+		}
+		copy(mac.key, key)
+		return mac
+	}
+	return tls10MAC{hmac.New(md5.New, key)}
+}
+
+type macFunction interface {
+	Size() int
+	MAC(digestBuf, seq, header, data []byte) []byte
+}
+
+// fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
+// each call.
+type fixedNonceAEAD struct {
+	// sealNonce and openNonce are buffers where the larger nonce will be
+	// constructed. Since a seal and open operation may be running
+	// concurrently, there is a separate buffer for each.
+	sealNonce, openNonce []byte
+	aead                 cipher.AEAD
+}
+
+func (f *fixedNonceAEAD) NonceSize() int { return 8 }
+func (f *fixedNonceAEAD) Overhead() int  { return f.aead.Overhead() }
+
+func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
+	copy(f.sealNonce[len(f.sealNonce)-8:], nonce)
+	return f.aead.Seal(out, f.sealNonce, plaintext, additionalData)
+}
+
+func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) {
+	copy(f.openNonce[len(f.openNonce)-8:], nonce)
+	return f.aead.Open(out, f.openNonce, plaintext, additionalData)
+}
+
+func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD {
+	aes, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+	aead, err := cipher.NewGCM(aes)
+	if err != nil {
+		panic(err)
+	}
+
+	nonce1, nonce2 := make([]byte, 12), make([]byte, 12)
+	copy(nonce1, fixedNonce)
+	copy(nonce2, fixedNonce)
+
+	return &fixedNonceAEAD{nonce1, nonce2, aead}
+}
+
+// ssl30MAC implements the SSLv3 MAC function, as defined in
+// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
+type ssl30MAC struct {
+	h   hash.Hash
+	key []byte
+}
+
+func (s ssl30MAC) Size() int {
+	return s.h.Size()
+}
+
+var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
+
+var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
+
+func (s ssl30MAC) MAC(digestBuf, seq, header, data []byte) []byte {
+	padLength := 48
+	if s.h.Size() == 20 {
+		padLength = 40
+	}
+
+	s.h.Reset()
+	s.h.Write(s.key)
+	s.h.Write(ssl30Pad1[:padLength])
+	s.h.Write(seq)
+	s.h.Write(header[:1])
+	s.h.Write(header[3:5])
+	s.h.Write(data)
+	digestBuf = s.h.Sum(digestBuf[:0])
+
+	s.h.Reset()
+	s.h.Write(s.key)
+	s.h.Write(ssl30Pad2[:padLength])
+	s.h.Write(digestBuf)
+	return s.h.Sum(digestBuf[:0])
+}
+
+// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
+type tls10MAC struct {
+	h hash.Hash
+}
+
+func (s tls10MAC) Size() int {
+	return s.h.Size()
+}
+
+func (s tls10MAC) MAC(digestBuf, seq, header, data []byte) []byte {
+	s.h.Reset()
+	s.h.Write(seq)
+	s.h.Write(header)
+	s.h.Write(data)
+	return s.h.Sum(digestBuf[:0])
+}
+
+func rsaKA(version uint16) keyAgreement {
+	return rsaKeyAgreement{}
+}
+
+func ecdheECDSAKA(version uint16) keyAgreement {
+	return &ecdheKeyAgreement{
+		sigType: signatureECDSA,
+		version: version,
+	}
+}
+
+func ecdheRSAKA(version uint16) keyAgreement {
+	return &ecdheKeyAgreement{
+		sigType: signatureRSA,
+		version: version,
+	}
+}
+
+// mutualCipherSuite returns a cipherSuite given a list of supported
+// ciphersuites and the id requested by the peer.
+func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
+	for _, id := range have {
+		if id == want {
+			for _, suite := range cipherSuites {
+				if suite.id == want {
+					return suite
+				}
+			}
+			return nil
+		}
+	}
+	return nil
+}
+
+// A list of the possible cipher suite ids. Taken from
+// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
+const (
+	TLS_RSA_WITH_RC4_128_MD5                uint16 = 0x0004
+	TLS_RSA_WITH_RC4_128_SHA                uint16 = 0x0005
+	TLS_RSA_WITH_3DES_EDE_CBC_SHA           uint16 = 0x000a
+	TLS_RSA_WITH_AES_128_CBC_SHA            uint16 = 0x002f
+	TLS_RSA_WITH_AES_256_CBC_SHA            uint16 = 0x0035
+	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA        uint16 = 0xc007
+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA    uint16 = 0xc009
+	TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA    uint16 = 0xc00a
+	TLS_ECDHE_RSA_WITH_RC4_128_SHA          uint16 = 0xc011
+	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA     uint16 = 0xc012
+	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA      uint16 = 0xc013
+	TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA      uint16 = 0xc014
+	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   uint16 = 0xc02f
+	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
+	TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   uint16 = 0xc030
+)
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
new file mode 100644
index 0000000..9812bde
--- /dev/null
+++ b/ssl/test/runner/common.go
@@ -0,0 +1,598 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"container/list"
+	"crypto"
+	"crypto/rand"
+	"crypto/x509"
+	"fmt"
+	"io"
+	"math/big"
+	"strings"
+	"sync"
+	"time"
+)
+
+const (
+	VersionSSL30 = 0x0300
+	VersionTLS10 = 0x0301
+	VersionTLS11 = 0x0302
+	VersionTLS12 = 0x0303
+)
+
+const (
+	maxPlaintext    = 16384        // maximum plaintext payload length
+	maxCiphertext   = 16384 + 2048 // maximum ciphertext payload length
+	recordHeaderLen = 5            // record header length
+	maxHandshake    = 65536        // maximum handshake we support (protocol max is 16 MB)
+
+	minVersion = VersionSSL30
+	maxVersion = VersionTLS12
+)
+
+// TLS record types.
+type recordType uint8
+
+const (
+	recordTypeChangeCipherSpec recordType = 20
+	recordTypeAlert            recordType = 21
+	recordTypeHandshake        recordType = 22
+	recordTypeApplicationData  recordType = 23
+)
+
+// TLS handshake message types.
+const (
+	typeClientHello        uint8 = 1
+	typeServerHello        uint8 = 2
+	typeNewSessionTicket   uint8 = 4
+	typeCertificate        uint8 = 11
+	typeServerKeyExchange  uint8 = 12
+	typeCertificateRequest uint8 = 13
+	typeServerHelloDone    uint8 = 14
+	typeCertificateVerify  uint8 = 15
+	typeClientKeyExchange  uint8 = 16
+	typeFinished           uint8 = 20
+	typeCertificateStatus  uint8 = 22
+	typeNextProtocol       uint8 = 67 // Not IANA assigned
+)
+
+// TLS compression types.
+const (
+	compressionNone uint8 = 0
+)
+
+// TLS extension numbers
+const (
+	extensionServerName          uint16 = 0
+	extensionStatusRequest       uint16 = 5
+	extensionSupportedCurves     uint16 = 10
+	extensionSupportedPoints     uint16 = 11
+	extensionSignatureAlgorithms uint16 = 13
+	extensionSessionTicket       uint16 = 35
+	extensionNextProtoNeg        uint16 = 13172 // not IANA assigned
+	extensionRenegotiationInfo   uint16 = 0xff01
+)
+
+// TLS signaling cipher suite values
+const (
+	scsvRenegotiation uint16 = 0x00ff
+)
+
+// CurveID is the type of a TLS identifier for an elliptic curve. See
+// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
+type CurveID uint16
+
+const (
+	CurveP256 CurveID = 23
+	CurveP384 CurveID = 24
+	CurveP521 CurveID = 25
+)
+
+// TLS Elliptic Curve Point Formats
+// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
+const (
+	pointFormatUncompressed uint8 = 0
+)
+
+// TLS CertificateStatusType (RFC 3546)
+const (
+	statusTypeOCSP uint8 = 1
+)
+
+// Certificate types (for certificateRequestMsg)
+const (
+	certTypeRSASign    = 1 // A certificate containing an RSA key
+	certTypeDSSSign    = 2 // A certificate containing a DSA key
+	certTypeRSAFixedDH = 3 // A certificate containing a static DH key
+	certTypeDSSFixedDH = 4 // A certificate containing a static DH key
+
+	// See RFC4492 sections 3 and 5.5.
+	certTypeECDSASign      = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA.
+	certTypeRSAFixedECDH   = 65 // A certificate containing an ECDH-capable public key, signed with RSA.
+	certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA.
+
+	// Rest of these are reserved by the TLS spec
+)
+
+// Hash functions for TLS 1.2 (See RFC 5246, section A.4.1)
+const (
+	hashSHA1   uint8 = 2
+	hashSHA256 uint8 = 4
+)
+
+// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1)
+const (
+	signatureRSA   uint8 = 1
+	signatureECDSA uint8 = 3
+)
+
+// signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See
+// RFC 5246, section A.4.1.
+type signatureAndHash struct {
+	hash, signature uint8
+}
+
+// supportedSKXSignatureAlgorithms contains the signature and hash algorithms
+// that the code advertises as supported in a TLS 1.2 ClientHello.
+var supportedSKXSignatureAlgorithms = []signatureAndHash{
+	{hashSHA256, signatureRSA},
+	{hashSHA256, signatureECDSA},
+	{hashSHA1, signatureRSA},
+	{hashSHA1, signatureECDSA},
+}
+
+// supportedClientCertSignatureAlgorithms contains the signature and hash
+// algorithms that the code advertises as supported in a TLS 1.2
+// CertificateRequest.
+var supportedClientCertSignatureAlgorithms = []signatureAndHash{
+	{hashSHA256, signatureRSA},
+	{hashSHA256, signatureECDSA},
+}
+
+// ConnectionState records basic TLS details about the connection.
+type ConnectionState struct {
+	Version                    uint16                // TLS version used by the connection (e.g. VersionTLS12)
+	HandshakeComplete          bool                  // TLS handshake is complete
+	DidResume                  bool                  // connection resumes a previous TLS connection
+	CipherSuite                uint16                // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
+	NegotiatedProtocol         string                // negotiated next protocol (from Config.NextProtos)
+	NegotiatedProtocolIsMutual bool                  // negotiated protocol was advertised by server
+	ServerName                 string                // server name requested by client, if any (server side only)
+	PeerCertificates           []*x509.Certificate   // certificate chain presented by remote peer
+	VerifiedChains             [][]*x509.Certificate // verified chains built from PeerCertificates
+}
+
+// ClientAuthType declares the policy the server will follow for
+// TLS Client Authentication.
+type ClientAuthType int
+
+const (
+	NoClientCert ClientAuthType = iota
+	RequestClientCert
+	RequireAnyClientCert
+	VerifyClientCertIfGiven
+	RequireAndVerifyClientCert
+)
+
+// ClientSessionState contains the state needed by clients to resume TLS
+// sessions.
+type ClientSessionState struct {
+	sessionTicket      []uint8             // Encrypted ticket used for session resumption with server
+	vers               uint16              // SSL/TLS version negotiated for the session
+	cipherSuite        uint16              // Ciphersuite negotiated for the session
+	masterSecret       []byte              // MasterSecret generated by client on a full handshake
+	serverCertificates []*x509.Certificate // Certificate chain presented by the server
+}
+
+// ClientSessionCache is a cache of ClientSessionState objects that can be used
+// by a client to resume a TLS session with a given server. ClientSessionCache
+// implementations should expect to be called concurrently from different
+// goroutines.
+type ClientSessionCache interface {
+	// Get searches for a ClientSessionState associated with the given key.
+	// On return, ok is true if one was found.
+	Get(sessionKey string) (session *ClientSessionState, ok bool)
+
+	// Put adds the ClientSessionState to the cache with the given key.
+	Put(sessionKey string, cs *ClientSessionState)
+}
+
+// A Config structure is used to configure a TLS client or server.
+// After one has been passed to a TLS function it must not be
+// modified. A Config may be reused; the tls package will also not
+// modify it.
+type Config struct {
+	// Rand provides the source of entropy for nonces and RSA blinding.
+	// If Rand is nil, TLS uses the cryptographic random reader in package
+	// crypto/rand.
+	// The Reader must be safe for use by multiple goroutines.
+	Rand io.Reader
+
+	// Time returns the current time as the number of seconds since the epoch.
+	// If Time is nil, TLS uses time.Now.
+	Time func() time.Time
+
+	// Certificates contains one or more certificate chains
+	// to present to the other side of the connection.
+	// Server configurations must include at least one certificate.
+	Certificates []Certificate
+
+	// NameToCertificate maps from a certificate name to an element of
+	// Certificates. Note that a certificate name can be of the form
+	// '*.example.com' and so doesn't have to be a domain name as such.
+	// See Config.BuildNameToCertificate
+	// The nil value causes the first element of Certificates to be used
+	// for all connections.
+	NameToCertificate map[string]*Certificate
+
+	// RootCAs defines the set of root certificate authorities
+	// that clients use when verifying server certificates.
+	// If RootCAs is nil, TLS uses the host's root CA set.
+	RootCAs *x509.CertPool
+
+	// NextProtos is a list of supported, application level protocols.
+	NextProtos []string
+
+	// ServerName is used to verify the hostname on the returned
+	// certificates unless InsecureSkipVerify is given. It is also included
+	// in the client's handshake to support virtual hosting.
+	ServerName string
+
+	// ClientAuth determines the server's policy for
+	// TLS Client Authentication. The default is NoClientCert.
+	ClientAuth ClientAuthType
+
+	// ClientCAs defines the set of root certificate authorities
+	// that servers use if required to verify a client certificate
+	// by the policy in ClientAuth.
+	ClientCAs *x509.CertPool
+
+	// InsecureSkipVerify controls whether a client verifies the
+	// server's certificate chain and host name.
+	// If InsecureSkipVerify is true, TLS accepts any certificate
+	// presented by the server and any host name in that certificate.
+	// In this mode, TLS is susceptible to man-in-the-middle attacks.
+	// This should be used only for testing.
+	InsecureSkipVerify bool
+
+	// CipherSuites is a list of supported cipher suites. If CipherSuites
+	// is nil, TLS uses a list of suites supported by the implementation.
+	CipherSuites []uint16
+
+	// PreferServerCipherSuites controls whether the server selects the
+	// client's most preferred ciphersuite, or the server's most preferred
+	// ciphersuite. If true then the server's preference, as expressed in
+	// the order of elements in CipherSuites, is used.
+	PreferServerCipherSuites bool
+
+	// SessionTicketsDisabled may be set to true to disable session ticket
+	// (resumption) support.
+	SessionTicketsDisabled bool
+
+	// SessionTicketKey is used by TLS servers to provide session
+	// resumption. See RFC 5077. If zero, it will be filled with
+	// random data before the first server handshake.
+	//
+	// If multiple servers are terminating connections for the same host
+	// they should all have the same SessionTicketKey. If the
+	// SessionTicketKey leaks, previously recorded and future TLS
+	// connections using that key are compromised.
+	SessionTicketKey [32]byte
+
+	// SessionCache is a cache of ClientSessionState entries for TLS session
+	// resumption.
+	ClientSessionCache ClientSessionCache
+
+	// MinVersion contains the minimum SSL/TLS version that is acceptable.
+	// If zero, then SSLv3 is taken as the minimum.
+	MinVersion uint16
+
+	// MaxVersion contains the maximum SSL/TLS version that is acceptable.
+	// If zero, then the maximum version supported by this package is used,
+	// which is currently TLS 1.2.
+	MaxVersion uint16
+
+	// CurvePreferences contains the elliptic curves that will be used in
+	// an ECDHE handshake, in preference order. If empty, the default will
+	// be used.
+	CurvePreferences []CurveID
+
+	// Bugs specifies optional misbehaviour to be used for testing other
+	// implementations.
+	Bugs ProtocolBugs
+
+	serverInitOnce sync.Once // guards calling (*Config).serverInit
+}
+
+type BadValue int
+
+const (
+	BadValueNone BadValue = iota
+	BadValueNegative
+	BadValueZero
+	BadValueLimit
+	BadValueLarge
+	NumBadValues
+)
+
+type ProtocolBugs struct {
+	// InvalidSKXSignature specifies that the signature in a
+	// ServerKeyExchange message should be invalid.
+	InvalidSKXSignature bool
+
+	// InvalidSKXCurve causes the curve ID in the ServerKeyExchange message
+	// to be wrong.
+	InvalidSKXCurve bool
+
+	// BadECDSAR controls ways in which the 'r' value of an ECDSA signature
+	// can be invalid.
+	BadECDSAR BadValue
+	BadECDSAS BadValue
+}
+
+func (c *Config) serverInit() {
+	if c.SessionTicketsDisabled {
+		return
+	}
+
+	// If the key has already been set then we have nothing to do.
+	for _, b := range c.SessionTicketKey {
+		if b != 0 {
+			return
+		}
+	}
+
+	if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
+		c.SessionTicketsDisabled = true
+	}
+}
+
+func (c *Config) rand() io.Reader {
+	r := c.Rand
+	if r == nil {
+		return rand.Reader
+	}
+	return r
+}
+
+func (c *Config) time() time.Time {
+	t := c.Time
+	if t == nil {
+		t = time.Now
+	}
+	return t()
+}
+
+func (c *Config) cipherSuites() []uint16 {
+	s := c.CipherSuites
+	if s == nil {
+		s = defaultCipherSuites()
+	}
+	return s
+}
+
+func (c *Config) minVersion() uint16 {
+	if c == nil || c.MinVersion == 0 {
+		return minVersion
+	}
+	return c.MinVersion
+}
+
+func (c *Config) maxVersion() uint16 {
+	if c == nil || c.MaxVersion == 0 {
+		return maxVersion
+	}
+	return c.MaxVersion
+}
+
+var defaultCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}
+
+func (c *Config) curvePreferences() []CurveID {
+	if c == nil || len(c.CurvePreferences) == 0 {
+		return defaultCurvePreferences
+	}
+	return c.CurvePreferences
+}
+
+// mutualVersion returns the protocol version to use given the advertised
+// version of the peer.
+func (c *Config) mutualVersion(vers uint16) (uint16, bool) {
+	minVersion := c.minVersion()
+	maxVersion := c.maxVersion()
+
+	if vers < minVersion {
+		return 0, false
+	}
+	if vers > maxVersion {
+		vers = maxVersion
+	}
+	return vers, true
+}
+
+// getCertificateForName returns the best certificate for the given name,
+// defaulting to the first element of c.Certificates if there are no good
+// options.
+func (c *Config) getCertificateForName(name string) *Certificate {
+	if len(c.Certificates) == 1 || c.NameToCertificate == nil {
+		// There's only one choice, so no point doing any work.
+		return &c.Certificates[0]
+	}
+
+	name = strings.ToLower(name)
+	for len(name) > 0 && name[len(name)-1] == '.' {
+		name = name[:len(name)-1]
+	}
+
+	if cert, ok := c.NameToCertificate[name]; ok {
+		return cert
+	}
+
+	// try replacing labels in the name with wildcards until we get a
+	// match.
+	labels := strings.Split(name, ".")
+	for i := range labels {
+		labels[i] = "*"
+		candidate := strings.Join(labels, ".")
+		if cert, ok := c.NameToCertificate[candidate]; ok {
+			return cert
+		}
+	}
+
+	// If nothing matches, return the first certificate.
+	return &c.Certificates[0]
+}
+
+// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
+// from the CommonName and SubjectAlternateName fields of each of the leaf
+// certificates.
+func (c *Config) BuildNameToCertificate() {
+	c.NameToCertificate = make(map[string]*Certificate)
+	for i := range c.Certificates {
+		cert := &c.Certificates[i]
+		x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
+		if err != nil {
+			continue
+		}
+		if len(x509Cert.Subject.CommonName) > 0 {
+			c.NameToCertificate[x509Cert.Subject.CommonName] = cert
+		}
+		for _, san := range x509Cert.DNSNames {
+			c.NameToCertificate[san] = cert
+		}
+	}
+}
+
+// A Certificate is a chain of one or more certificates, leaf first.
+type Certificate struct {
+	Certificate [][]byte
+	PrivateKey  crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey
+	// OCSPStaple contains an optional OCSP response which will be served
+	// to clients that request it.
+	OCSPStaple []byte
+	// Leaf is the parsed form of the leaf certificate, which may be
+	// initialized using x509.ParseCertificate to reduce per-handshake
+	// processing for TLS clients doing client authentication. If nil, the
+	// leaf certificate will be parsed as needed.
+	Leaf *x509.Certificate
+}
+
+// A TLS record.
+type record struct {
+	contentType  recordType
+	major, minor uint8
+	payload      []byte
+}
+
+type handshakeMessage interface {
+	marshal() []byte
+	unmarshal([]byte) bool
+}
+
+// lruSessionCache is a ClientSessionCache implementation that uses an LRU
+// caching strategy.
+type lruSessionCache struct {
+	sync.Mutex
+
+	m        map[string]*list.Element
+	q        *list.List
+	capacity int
+}
+
+type lruSessionCacheEntry struct {
+	sessionKey string
+	state      *ClientSessionState
+}
+
+// NewLRUClientSessionCache returns a ClientSessionCache with the given
+// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
+// is used instead.
+func NewLRUClientSessionCache(capacity int) ClientSessionCache {
+	const defaultSessionCacheCapacity = 64
+
+	if capacity < 1 {
+		capacity = defaultSessionCacheCapacity
+	}
+	return &lruSessionCache{
+		m:        make(map[string]*list.Element),
+		q:        list.New(),
+		capacity: capacity,
+	}
+}
+
+// Put adds the provided (sessionKey, cs) pair to the cache.
+func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
+	c.Lock()
+	defer c.Unlock()
+
+	if elem, ok := c.m[sessionKey]; ok {
+		entry := elem.Value.(*lruSessionCacheEntry)
+		entry.state = cs
+		c.q.MoveToFront(elem)
+		return
+	}
+
+	if c.q.Len() < c.capacity {
+		entry := &lruSessionCacheEntry{sessionKey, cs}
+		c.m[sessionKey] = c.q.PushFront(entry)
+		return
+	}
+
+	elem := c.q.Back()
+	entry := elem.Value.(*lruSessionCacheEntry)
+	delete(c.m, entry.sessionKey)
+	entry.sessionKey = sessionKey
+	entry.state = cs
+	c.q.MoveToFront(elem)
+	c.m[sessionKey] = elem
+}
+
+// Get returns the ClientSessionState value associated with a given key. It
+// returns (nil, false) if no value is found.
+func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
+	c.Lock()
+	defer c.Unlock()
+
+	if elem, ok := c.m[sessionKey]; ok {
+		c.q.MoveToFront(elem)
+		return elem.Value.(*lruSessionCacheEntry).state, true
+	}
+	return nil, false
+}
+
+// TODO(jsing): Make these available to both crypto/x509 and crypto/tls.
+type dsaSignature struct {
+	R, S *big.Int
+}
+
+type ecdsaSignature dsaSignature
+
+var emptyConfig Config
+
+func defaultConfig() *Config {
+	return &emptyConfig
+}
+
+var (
+	once                   sync.Once
+	varDefaultCipherSuites []uint16
+)
+
+func defaultCipherSuites() []uint16 {
+	once.Do(initDefaultCipherSuites)
+	return varDefaultCipherSuites
+}
+
+func initDefaultCipherSuites() {
+	varDefaultCipherSuites = make([]uint16, len(cipherSuites))
+	for i, suite := range cipherSuites {
+		varDefaultCipherSuites[i] = suite.id
+	}
+}
+
+func unexpectedMessageError(wanted, got interface{}) error {
+	return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
+}
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
new file mode 100644
index 0000000..d130895
--- /dev/null
+++ b/ssl/test/runner/conn.go
@@ -0,0 +1,1019 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TLS low level connection and record layer
+
+package main
+
+import (
+	"bytes"
+	"crypto/cipher"
+	"crypto/subtle"
+	"crypto/x509"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"sync"
+	"time"
+)
+
+// A Conn represents a secured connection.
+// It implements the net.Conn interface.
+type Conn struct {
+	// constant
+	conn     net.Conn
+	isClient bool
+
+	// constant after handshake; protected by handshakeMutex
+	handshakeMutex    sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
+	handshakeErr      error      // error resulting from handshake
+	vers              uint16     // TLS version
+	haveVers          bool       // version has been negotiated
+	config            *Config    // configuration passed to constructor
+	handshakeComplete bool
+	didResume         bool // whether this connection was a session resumption
+	cipherSuite       uint16
+	ocspResponse      []byte // stapled OCSP response
+	peerCertificates  []*x509.Certificate
+	// verifiedChains contains the certificate chains that we built, as
+	// opposed to the ones presented by the server.
+	verifiedChains [][]*x509.Certificate
+	// serverName contains the server name indicated by the client, if any.
+	serverName string
+
+	clientProtocol         string
+	clientProtocolFallback bool
+
+	// input/output
+	in, out  halfConn     // in.Mutex < out.Mutex
+	rawInput *block       // raw input, right off the wire
+	input    *block       // application data waiting to be read
+	hand     bytes.Buffer // handshake data waiting to be read
+
+	tmp [16]byte
+}
+
+// Access to net.Conn methods.
+// Cannot just embed net.Conn because that would
+// export the struct field too.
+
+// LocalAddr returns the local network address.
+func (c *Conn) LocalAddr() net.Addr {
+	return c.conn.LocalAddr()
+}
+
+// RemoteAddr returns the remote network address.
+func (c *Conn) RemoteAddr() net.Addr {
+	return c.conn.RemoteAddr()
+}
+
+// SetDeadline sets the read and write deadlines associated with the connection.
+// A zero value for t means Read and Write will not time out.
+// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
+func (c *Conn) SetDeadline(t time.Time) error {
+	return c.conn.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline on the underlying connection.
+// A zero value for t means Read will not time out.
+func (c *Conn) SetReadDeadline(t time.Time) error {
+	return c.conn.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline on the underlying conneciton.
+// A zero value for t means Write will not time out.
+// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
+func (c *Conn) SetWriteDeadline(t time.Time) error {
+	return c.conn.SetWriteDeadline(t)
+}
+
+// A halfConn represents one direction of the record layer
+// connection, either sending or receiving.
+type halfConn struct {
+	sync.Mutex
+
+	err     error       // first permanent error
+	version uint16      // protocol version
+	cipher  interface{} // cipher algorithm
+	mac     macFunction
+	seq     [8]byte // 64-bit sequence number
+	bfree   *block  // list of free blocks
+
+	nextCipher interface{} // next encryption state
+	nextMac    macFunction // next MAC algorithm
+
+	// used to save allocating a new buffer for each MAC.
+	inDigestBuf, outDigestBuf []byte
+}
+
+func (hc *halfConn) setErrorLocked(err error) error {
+	hc.err = err
+	return err
+}
+
+func (hc *halfConn) error() error {
+	hc.Lock()
+	err := hc.err
+	hc.Unlock()
+	return err
+}
+
+// prepareCipherSpec sets the encryption and MAC states
+// that a subsequent changeCipherSpec will use.
+func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) {
+	hc.version = version
+	hc.nextCipher = cipher
+	hc.nextMac = mac
+}
+
+// changeCipherSpec changes the encryption and MAC states
+// to the ones previously passed to prepareCipherSpec.
+func (hc *halfConn) changeCipherSpec() error {
+	if hc.nextCipher == nil {
+		return alertInternalError
+	}
+	hc.cipher = hc.nextCipher
+	hc.mac = hc.nextMac
+	hc.nextCipher = nil
+	hc.nextMac = nil
+	for i := range hc.seq {
+		hc.seq[i] = 0
+	}
+	return nil
+}
+
+// incSeq increments the sequence number.
+func (hc *halfConn) incSeq() {
+	for i := 7; i >= 0; i-- {
+		hc.seq[i]++
+		if hc.seq[i] != 0 {
+			return
+		}
+	}
+
+	// Not allowed to let sequence number wrap.
+	// Instead, must renegotiate before it does.
+	// Not likely enough to bother.
+	panic("TLS: sequence number wraparound")
+}
+
+// resetSeq resets the sequence number to zero.
+func (hc *halfConn) resetSeq() {
+	for i := range hc.seq {
+		hc.seq[i] = 0
+	}
+}
+
+// removePadding returns an unpadded slice, in constant time, which is a prefix
+// of the input. It also returns a byte which is equal to 255 if the padding
+// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2
+func removePadding(payload []byte) ([]byte, byte) {
+	if len(payload) < 1 {
+		return payload, 0
+	}
+
+	paddingLen := payload[len(payload)-1]
+	t := uint(len(payload)-1) - uint(paddingLen)
+	// if len(payload) >= (paddingLen - 1) then the MSB of t is zero
+	good := byte(int32(^t) >> 31)
+
+	toCheck := 255 // the maximum possible padding length
+	// The length of the padded data is public, so we can use an if here
+	if toCheck+1 > len(payload) {
+		toCheck = len(payload) - 1
+	}
+
+	for i := 0; i < toCheck; i++ {
+		t := uint(paddingLen) - uint(i)
+		// if i <= paddingLen then the MSB of t is zero
+		mask := byte(int32(^t) >> 31)
+		b := payload[len(payload)-1-i]
+		good &^= mask&paddingLen ^ mask&b
+	}
+
+	// We AND together the bits of good and replicate the result across
+	// all the bits.
+	good &= good << 4
+	good &= good << 2
+	good &= good << 1
+	good = uint8(int8(good) >> 7)
+
+	toRemove := good&paddingLen + 1
+	return payload[:len(payload)-int(toRemove)], good
+}
+
+// removePaddingSSL30 is a replacement for removePadding in the case that the
+// protocol version is SSLv3. In this version, the contents of the padding
+// are random and cannot be checked.
+func removePaddingSSL30(payload []byte) ([]byte, byte) {
+	if len(payload) < 1 {
+		return payload, 0
+	}
+
+	paddingLen := int(payload[len(payload)-1]) + 1
+	if paddingLen > len(payload) {
+		return payload, 0
+	}
+
+	return payload[:len(payload)-paddingLen], 255
+}
+
+func roundUp(a, b int) int {
+	return a + (b-a%b)%b
+}
+
+// cbcMode is an interface for block ciphers using cipher block chaining.
+type cbcMode interface {
+	cipher.BlockMode
+	SetIV([]byte)
+}
+
+// decrypt checks and strips the mac and decrypts the data in b. Returns a
+// success boolean, the number of bytes to skip from the start of the record in
+// order to get the application payload, and an optional alert value.
+func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) {
+	// pull out payload
+	payload := b.data[recordHeaderLen:]
+
+	macSize := 0
+	if hc.mac != nil {
+		macSize = hc.mac.Size()
+	}
+
+	paddingGood := byte(255)
+	explicitIVLen := 0
+
+	// decrypt
+	if hc.cipher != nil {
+		switch c := hc.cipher.(type) {
+		case cipher.Stream:
+			c.XORKeyStream(payload, payload)
+		case cipher.AEAD:
+			explicitIVLen = 8
+			if len(payload) < explicitIVLen {
+				return false, 0, alertBadRecordMAC
+			}
+			nonce := payload[:8]
+			payload = payload[8:]
+
+			var additionalData [13]byte
+			copy(additionalData[:], hc.seq[:])
+			copy(additionalData[8:], b.data[:3])
+			n := len(payload) - c.Overhead()
+			additionalData[11] = byte(n >> 8)
+			additionalData[12] = byte(n)
+			var err error
+			payload, err = c.Open(payload[:0], nonce, payload, additionalData[:])
+			if err != nil {
+				return false, 0, alertBadRecordMAC
+			}
+			b.resize(recordHeaderLen + explicitIVLen + len(payload))
+		case cbcMode:
+			blockSize := c.BlockSize()
+			if hc.version >= VersionTLS11 {
+				explicitIVLen = blockSize
+			}
+
+			if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) {
+				return false, 0, alertBadRecordMAC
+			}
+
+			if explicitIVLen > 0 {
+				c.SetIV(payload[:explicitIVLen])
+				payload = payload[explicitIVLen:]
+			}
+			c.CryptBlocks(payload, payload)
+			if hc.version == VersionSSL30 {
+				payload, paddingGood = removePaddingSSL30(payload)
+			} else {
+				payload, paddingGood = removePadding(payload)
+			}
+			b.resize(recordHeaderLen + explicitIVLen + len(payload))
+
+			// note that we still have a timing side-channel in the
+			// MAC check, below. An attacker can align the record
+			// so that a correct padding will cause one less hash
+			// block to be calculated. Then they can iteratively
+			// decrypt a record by breaking each byte. See
+			// "Password Interception in a SSL/TLS Channel", Brice
+			// Canvel et al.
+			//
+			// However, our behavior matches OpenSSL, so we leak
+			// only as much as they do.
+		default:
+			panic("unknown cipher type")
+		}
+	}
+
+	// check, strip mac
+	if hc.mac != nil {
+		if len(payload) < macSize {
+			return false, 0, alertBadRecordMAC
+		}
+
+		// strip mac off payload, b.data
+		n := len(payload) - macSize
+		b.data[3] = byte(n >> 8)
+		b.data[4] = byte(n)
+		b.resize(recordHeaderLen + explicitIVLen + n)
+		remoteMAC := payload[n:]
+		localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], payload[:n])
+
+		if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 {
+			return false, 0, alertBadRecordMAC
+		}
+		hc.inDigestBuf = localMAC
+	}
+	hc.incSeq()
+
+	return true, recordHeaderLen + explicitIVLen, 0
+}
+
+// padToBlockSize calculates the needed padding block, if any, for a payload.
+// On exit, prefix aliases payload and extends to the end of the last full
+// block of payload. finalBlock is a fresh slice which contains the contents of
+// any suffix of payload as well as the needed padding to make finalBlock a
+// full block.
+func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) {
+	overrun := len(payload) % blockSize
+	paddingLen := blockSize - overrun
+	prefix = payload[:len(payload)-overrun]
+	finalBlock = make([]byte, blockSize)
+	copy(finalBlock, payload[len(payload)-overrun:])
+	for i := overrun; i < blockSize; i++ {
+		finalBlock[i] = byte(paddingLen - 1)
+	}
+	return
+}
+
+// encrypt encrypts and macs the data in b.
+func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
+	// mac
+	if hc.mac != nil {
+		mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:])
+
+		n := len(b.data)
+		b.resize(n + len(mac))
+		copy(b.data[n:], mac)
+		hc.outDigestBuf = mac
+	}
+
+	payload := b.data[recordHeaderLen:]
+
+	// encrypt
+	if hc.cipher != nil {
+		switch c := hc.cipher.(type) {
+		case cipher.Stream:
+			c.XORKeyStream(payload, payload)
+		case cipher.AEAD:
+			payloadLen := len(b.data) - recordHeaderLen - explicitIVLen
+			b.resize(len(b.data) + c.Overhead())
+			nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
+			payload := b.data[recordHeaderLen+explicitIVLen:]
+			payload = payload[:payloadLen]
+
+			var additionalData [13]byte
+			copy(additionalData[:], hc.seq[:])
+			copy(additionalData[8:], b.data[:3])
+			additionalData[11] = byte(payloadLen >> 8)
+			additionalData[12] = byte(payloadLen)
+
+			c.Seal(payload[:0], nonce, payload, additionalData[:])
+		case cbcMode:
+			blockSize := c.BlockSize()
+			if explicitIVLen > 0 {
+				c.SetIV(payload[:explicitIVLen])
+				payload = payload[explicitIVLen:]
+			}
+			prefix, finalBlock := padToBlockSize(payload, blockSize)
+			b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock))
+			c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix)
+			c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock)
+		default:
+			panic("unknown cipher type")
+		}
+	}
+
+	// update length to include MAC and any block padding needed.
+	n := len(b.data) - recordHeaderLen
+	b.data[3] = byte(n >> 8)
+	b.data[4] = byte(n)
+	hc.incSeq()
+
+	return true, 0
+}
+
+// A block is a simple data buffer.
+type block struct {
+	data []byte
+	off  int // index for Read
+	link *block
+}
+
+// resize resizes block to be n bytes, growing if necessary.
+func (b *block) resize(n int) {
+	if n > cap(b.data) {
+		b.reserve(n)
+	}
+	b.data = b.data[0:n]
+}
+
+// reserve makes sure that block contains a capacity of at least n bytes.
+func (b *block) reserve(n int) {
+	if cap(b.data) >= n {
+		return
+	}
+	m := cap(b.data)
+	if m == 0 {
+		m = 1024
+	}
+	for m < n {
+		m *= 2
+	}
+	data := make([]byte, len(b.data), m)
+	copy(data, b.data)
+	b.data = data
+}
+
+// readFromUntil reads from r into b until b contains at least n bytes
+// or else returns an error.
+func (b *block) readFromUntil(r io.Reader, n int) error {
+	// quick case
+	if len(b.data) >= n {
+		return nil
+	}
+
+	// read until have enough.
+	b.reserve(n)
+	for {
+		m, err := r.Read(b.data[len(b.data):cap(b.data)])
+		b.data = b.data[0 : len(b.data)+m]
+		if len(b.data) >= n {
+			// TODO(bradfitz,agl): slightly suspicious
+			// that we're throwing away r.Read's err here.
+			break
+		}
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (b *block) Read(p []byte) (n int, err error) {
+	n = copy(p, b.data[b.off:])
+	b.off += n
+	return
+}
+
+// newBlock allocates a new block, from hc's free list if possible.
+func (hc *halfConn) newBlock() *block {
+	b := hc.bfree
+	if b == nil {
+		return new(block)
+	}
+	hc.bfree = b.link
+	b.link = nil
+	b.resize(0)
+	return b
+}
+
+// freeBlock returns a block to hc's free list.
+// The protocol is such that each side only has a block or two on
+// its free list at a time, so there's no need to worry about
+// trimming the list, etc.
+func (hc *halfConn) freeBlock(b *block) {
+	b.link = hc.bfree
+	hc.bfree = b
+}
+
+// splitBlock splits a block after the first n bytes,
+// returning a block with those n bytes and a
+// block with the remainder.  the latter may be nil.
+func (hc *halfConn) splitBlock(b *block, n int) (*block, *block) {
+	if len(b.data) <= n {
+		return b, nil
+	}
+	bb := hc.newBlock()
+	bb.resize(len(b.data) - n)
+	copy(bb.data, b.data[n:])
+	b.data = b.data[0:n]
+	return b, bb
+}
+
+// readRecord reads the next TLS record from the connection
+// and updates the record layer state.
+// c.in.Mutex <= L; c.input == nil.
+func (c *Conn) readRecord(want recordType) error {
+	// Caller must be in sync with connection:
+	// handshake data if handshake not yet completed,
+	// else application data.  (We don't support renegotiation.)
+	switch want {
+	default:
+		c.sendAlert(alertInternalError)
+		return c.in.setErrorLocked(errors.New("tls: unknown record type requested"))
+	case recordTypeHandshake, recordTypeChangeCipherSpec:
+		if c.handshakeComplete {
+			c.sendAlert(alertInternalError)
+			return c.in.setErrorLocked(errors.New("tls: handshake or ChangeCipherSpec requested after handshake complete"))
+		}
+	case recordTypeApplicationData:
+		if !c.handshakeComplete {
+			c.sendAlert(alertInternalError)
+			return c.in.setErrorLocked(errors.New("tls: application data record requested before handshake complete"))
+		}
+	}
+
+Again:
+	if c.rawInput == nil {
+		c.rawInput = c.in.newBlock()
+	}
+	b := c.rawInput
+
+	// Read header, payload.
+	if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil {
+		// RFC suggests that EOF without an alertCloseNotify is
+		// an error, but popular web sites seem to do this,
+		// so we can't make it an error.
+		// if err == io.EOF {
+		// 	err = io.ErrUnexpectedEOF
+		// }
+		if e, ok := err.(net.Error); !ok || !e.Temporary() {
+			c.in.setErrorLocked(err)
+		}
+		return err
+	}
+	typ := recordType(b.data[0])
+
+	// No valid TLS record has a type of 0x80, however SSLv2 handshakes
+	// start with a uint16 length where the MSB is set and the first record
+	// is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
+	// an SSLv2 client.
+	if want == recordTypeHandshake && typ == 0x80 {
+		c.sendAlert(alertProtocolVersion)
+		return c.in.setErrorLocked(errors.New("tls: unsupported SSLv2 handshake received"))
+	}
+
+	vers := uint16(b.data[1])<<8 | uint16(b.data[2])
+	n := int(b.data[3])<<8 | int(b.data[4])
+	if c.haveVers && vers != c.vers {
+		c.sendAlert(alertProtocolVersion)
+		return c.in.setErrorLocked(fmt.Errorf("tls: received record with version %x when expecting version %x", vers, c.vers))
+	}
+	if n > maxCiphertext {
+		c.sendAlert(alertRecordOverflow)
+		return c.in.setErrorLocked(fmt.Errorf("tls: oversized record received with length %d", n))
+	}
+	if !c.haveVers {
+		// First message, be extra suspicious:
+		// this might not be a TLS client.
+		// Bail out before reading a full 'body', if possible.
+		// The current max version is 3.1.
+		// If the version is >= 16.0, it's probably not real.
+		// Similarly, a clientHello message encodes in
+		// well under a kilobyte.  If the length is >= 12 kB,
+		// it's probably not real.
+		if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 {
+			c.sendAlert(alertUnexpectedMessage)
+			return c.in.setErrorLocked(fmt.Errorf("tls: first record does not look like a TLS handshake"))
+		}
+	}
+	if err := b.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		if e, ok := err.(net.Error); !ok || !e.Temporary() {
+			c.in.setErrorLocked(err)
+		}
+		return err
+	}
+
+	// Process message.
+	b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n)
+	ok, off, err := c.in.decrypt(b)
+	if !ok {
+		c.in.setErrorLocked(c.sendAlert(err))
+	}
+	b.off = off
+	data := b.data[b.off:]
+	if len(data) > maxPlaintext {
+		err := c.sendAlert(alertRecordOverflow)
+		c.in.freeBlock(b)
+		return c.in.setErrorLocked(err)
+	}
+
+	switch typ {
+	default:
+		c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+
+	case recordTypeAlert:
+		if len(data) != 2 {
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+			break
+		}
+		if alert(data[1]) == alertCloseNotify {
+			c.in.setErrorLocked(io.EOF)
+			break
+		}
+		switch data[0] {
+		case alertLevelWarning:
+			// drop on the floor
+			c.in.freeBlock(b)
+			goto Again
+		case alertLevelError:
+			c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
+		default:
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+		}
+
+	case recordTypeChangeCipherSpec:
+		if typ != want || len(data) != 1 || data[0] != 1 {
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+			break
+		}
+		err := c.in.changeCipherSpec()
+		if err != nil {
+			c.in.setErrorLocked(c.sendAlert(err.(alert)))
+		}
+
+	case recordTypeApplicationData:
+		if typ != want {
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+			break
+		}
+		c.input = b
+		b = nil
+
+	case recordTypeHandshake:
+		// TODO(rsc): Should at least pick off connection close.
+		if typ != want {
+			return c.in.setErrorLocked(c.sendAlert(alertNoRenegotiation))
+		}
+		c.hand.Write(data)
+	}
+
+	if b != nil {
+		c.in.freeBlock(b)
+	}
+	return c.in.err
+}
+
+// sendAlert sends a TLS alert message.
+// c.out.Mutex <= L.
+func (c *Conn) sendAlertLocked(err alert) error {
+	switch err {
+	case alertNoRenegotiation, alertCloseNotify:
+		c.tmp[0] = alertLevelWarning
+	default:
+		c.tmp[0] = alertLevelError
+	}
+	c.tmp[1] = byte(err)
+	c.writeRecord(recordTypeAlert, c.tmp[0:2])
+	// closeNotify is a special case in that it isn't an error:
+	if err != alertCloseNotify {
+		return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+	}
+	return nil
+}
+
+// sendAlert sends a TLS alert message.
+// L < c.out.Mutex.
+func (c *Conn) sendAlert(err alert) error {
+	c.out.Lock()
+	defer c.out.Unlock()
+	return c.sendAlertLocked(err)
+}
+
+// writeRecord writes a TLS record with the given type and payload
+// to the connection and updates the record layer state.
+// c.out.Mutex <= L.
+func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
+	b := c.out.newBlock()
+	for len(data) > 0 {
+		m := len(data)
+		if m > maxPlaintext {
+			m = maxPlaintext
+		}
+		explicitIVLen := 0
+		explicitIVIsSeq := false
+
+		var cbc cbcMode
+		if c.out.version >= VersionTLS11 {
+			var ok bool
+			if cbc, ok = c.out.cipher.(cbcMode); ok {
+				explicitIVLen = cbc.BlockSize()
+			}
+		}
+		if explicitIVLen == 0 {
+			if _, ok := c.out.cipher.(cipher.AEAD); ok {
+				explicitIVLen = 8
+				// The AES-GCM construction in TLS has an
+				// explicit nonce so that the nonce can be
+				// random. However, the nonce is only 8 bytes
+				// which is too small for a secure, random
+				// nonce. Therefore we use the sequence number
+				// as the nonce.
+				explicitIVIsSeq = true
+			}
+		}
+		b.resize(recordHeaderLen + explicitIVLen + m)
+		b.data[0] = byte(typ)
+		vers := c.vers
+		if vers == 0 {
+			// Some TLS servers fail if the record version is
+			// greater than TLS 1.0 for the initial ClientHello.
+			vers = VersionTLS10
+		}
+		b.data[1] = byte(vers >> 8)
+		b.data[2] = byte(vers)
+		b.data[3] = byte(m >> 8)
+		b.data[4] = byte(m)
+		if explicitIVLen > 0 {
+			explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
+			if explicitIVIsSeq {
+				copy(explicitIV, c.out.seq[:])
+			} else {
+				if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil {
+					break
+				}
+			}
+		}
+		copy(b.data[recordHeaderLen+explicitIVLen:], data)
+		c.out.encrypt(b, explicitIVLen)
+		_, err = c.conn.Write(b.data)
+		if err != nil {
+			break
+		}
+		n += m
+		data = data[m:]
+	}
+	c.out.freeBlock(b)
+
+	if typ == recordTypeChangeCipherSpec {
+		err = c.out.changeCipherSpec()
+		if err != nil {
+			// Cannot call sendAlert directly,
+			// because we already hold c.out.Mutex.
+			c.tmp[0] = alertLevelError
+			c.tmp[1] = byte(err.(alert))
+			c.writeRecord(recordTypeAlert, c.tmp[0:2])
+			return n, c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+		}
+	}
+	return
+}
+
+// readHandshake reads the next handshake message from
+// the record layer.
+// c.in.Mutex < L; c.out.Mutex < L.
+func (c *Conn) readHandshake() (interface{}, error) {
+	for c.hand.Len() < 4 {
+		if err := c.in.err; err != nil {
+			return nil, err
+		}
+		if err := c.readRecord(recordTypeHandshake); err != nil {
+			return nil, err
+		}
+	}
+
+	data := c.hand.Bytes()
+	n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+	if n > maxHandshake {
+		return nil, c.in.setErrorLocked(c.sendAlert(alertInternalError))
+	}
+	for c.hand.Len() < 4+n {
+		if err := c.in.err; err != nil {
+			return nil, err
+		}
+		if err := c.readRecord(recordTypeHandshake); err != nil {
+			return nil, err
+		}
+	}
+	data = c.hand.Next(4 + n)
+	var m handshakeMessage
+	switch data[0] {
+	case typeClientHello:
+		m = new(clientHelloMsg)
+	case typeServerHello:
+		m = new(serverHelloMsg)
+	case typeNewSessionTicket:
+		m = new(newSessionTicketMsg)
+	case typeCertificate:
+		m = new(certificateMsg)
+	case typeCertificateRequest:
+		m = &certificateRequestMsg{
+			hasSignatureAndHash: c.vers >= VersionTLS12,
+		}
+	case typeCertificateStatus:
+		m = new(certificateStatusMsg)
+	case typeServerKeyExchange:
+		m = new(serverKeyExchangeMsg)
+	case typeServerHelloDone:
+		m = new(serverHelloDoneMsg)
+	case typeClientKeyExchange:
+		m = new(clientKeyExchangeMsg)
+	case typeCertificateVerify:
+		m = &certificateVerifyMsg{
+			hasSignatureAndHash: c.vers >= VersionTLS12,
+		}
+	case typeNextProtocol:
+		m = new(nextProtoMsg)
+	case typeFinished:
+		m = new(finishedMsg)
+	default:
+		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+	}
+
+	// The handshake message unmarshallers
+	// expect to be able to keep references to data,
+	// so pass in a fresh copy that won't be overwritten.
+	data = append([]byte(nil), data...)
+
+	if !m.unmarshal(data) {
+		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+	}
+	return m, nil
+}
+
+// Write writes data to the connection.
+func (c *Conn) Write(b []byte) (int, error) {
+	if err := c.Handshake(); err != nil {
+		return 0, err
+	}
+
+	c.out.Lock()
+	defer c.out.Unlock()
+
+	if err := c.out.err; err != nil {
+		return 0, err
+	}
+
+	if !c.handshakeComplete {
+		return 0, alertInternalError
+	}
+
+	// SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
+	// attack when using block mode ciphers due to predictable IVs.
+	// This can be prevented by splitting each Application Data
+	// record into two records, effectively randomizing the IV.
+	//
+	// http://www.openssl.org/~bodo/tls-cbc.txt
+	// https://bugzilla.mozilla.org/show_bug.cgi?id=665814
+	// http://www.imperialviolet.org/2012/01/15/beastfollowup.html
+
+	var m int
+	if len(b) > 1 && c.vers <= VersionTLS10 {
+		if _, ok := c.out.cipher.(cipher.BlockMode); ok {
+			n, err := c.writeRecord(recordTypeApplicationData, b[:1])
+			if err != nil {
+				return n, c.out.setErrorLocked(err)
+			}
+			m, b = 1, b[1:]
+		}
+	}
+
+	n, err := c.writeRecord(recordTypeApplicationData, b)
+	return n + m, c.out.setErrorLocked(err)
+}
+
+// Read can be made to time out and return a net.Error with Timeout() == true
+// after a fixed time limit; see SetDeadline and SetReadDeadline.
+func (c *Conn) Read(b []byte) (n int, err error) {
+	if err = c.Handshake(); err != nil {
+		return
+	}
+
+	c.in.Lock()
+	defer c.in.Unlock()
+
+	// Some OpenSSL servers send empty records in order to randomize the
+	// CBC IV. So this loop ignores a limited number of empty records.
+	const maxConsecutiveEmptyRecords = 100
+	for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ {
+		for c.input == nil && c.in.err == nil {
+			if err := c.readRecord(recordTypeApplicationData); err != nil {
+				// Soft error, like EAGAIN
+				return 0, err
+			}
+		}
+		if err := c.in.err; err != nil {
+			return 0, err
+		}
+
+		n, err = c.input.Read(b)
+		if c.input.off >= len(c.input.data) {
+			c.in.freeBlock(c.input)
+			c.input = nil
+		}
+
+		// If a close-notify alert is waiting, read it so that
+		// we can return (n, EOF) instead of (n, nil), to signal
+		// to the HTTP response reading goroutine that the
+		// connection is now closed. This eliminates a race
+		// where the HTTP response reading goroutine would
+		// otherwise not observe the EOF until its next read,
+		// by which time a client goroutine might have already
+		// tried to reuse the HTTP connection for a new
+		// request.
+		// See https://codereview.appspot.com/76400046
+		// and http://golang.org/issue/3514
+		if ri := c.rawInput; ri != nil &&
+			n != 0 && err == nil &&
+			c.input == nil && len(ri.data) > 0 && recordType(ri.data[0]) == recordTypeAlert {
+			if recErr := c.readRecord(recordTypeApplicationData); recErr != nil {
+				err = recErr // will be io.EOF on closeNotify
+			}
+		}
+
+		if n != 0 || err != nil {
+			return n, err
+		}
+	}
+
+	return 0, io.ErrNoProgress
+}
+
+// Close closes the connection.
+func (c *Conn) Close() error {
+	var alertErr error
+
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+	if c.handshakeComplete {
+		alertErr = c.sendAlert(alertCloseNotify)
+	}
+
+	if err := c.conn.Close(); err != nil {
+		return err
+	}
+	return alertErr
+}
+
+// Handshake runs the client or server handshake
+// protocol if it has not yet been run.
+// Most uses of this package need not call Handshake
+// explicitly: the first Read or Write will call it automatically.
+func (c *Conn) Handshake() error {
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+	if err := c.handshakeErr; err != nil {
+		return err
+	}
+	if c.handshakeComplete {
+		return nil
+	}
+
+	if c.isClient {
+		c.handshakeErr = c.clientHandshake()
+	} else {
+		c.handshakeErr = c.serverHandshake()
+	}
+	return c.handshakeErr
+}
+
+// ConnectionState returns basic TLS details about the connection.
+func (c *Conn) ConnectionState() ConnectionState {
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+
+	var state ConnectionState
+	state.HandshakeComplete = c.handshakeComplete
+	if c.handshakeComplete {
+		state.Version = c.vers
+		state.NegotiatedProtocol = c.clientProtocol
+		state.DidResume = c.didResume
+		state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback
+		state.CipherSuite = c.cipherSuite
+		state.PeerCertificates = c.peerCertificates
+		state.VerifiedChains = c.verifiedChains
+		state.ServerName = c.serverName
+	}
+
+	return state
+}
+
+// OCSPResponse returns the stapled OCSP response from the TLS server, if
+// any. (Only valid for client connections.)
+func (c *Conn) OCSPResponse() []byte {
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+
+	return c.ocspResponse
+}
+
+// VerifyHostname checks that the peer certificate chain is valid for
+// connecting to host.  If so, it returns nil; if not, it returns an error
+// describing the problem.
+func (c *Conn) VerifyHostname(host string) error {
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+	if !c.isClient {
+		return errors.New("tls: VerifyHostname called on TLS server connection")
+	}
+	if !c.handshakeComplete {
+		return errors.New("tls: handshake has not yet been performed")
+	}
+	return c.peerCertificates[0].VerifyHostname(host)
+}
diff --git a/ssl/test/runner/ecdsa_cert.pem b/ssl/test/runner/ecdsa_cert.pem
new file mode 100644
index 0000000..50bcbf5
--- /dev/null
+++ b/ssl/test/runner/ecdsa_cert.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC
+QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp
+dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ
+BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
+dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni
+v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa
+HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw
+HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ
+BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E
+BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=
+-----END CERTIFICATE-----
diff --git a/ssl/test/runner/ecdsa_key.pem b/ssl/test/runner/ecdsa_key.pem
new file mode 100644
index 0000000..b9116f0
--- /dev/null
+++ b/ssl/test/runner/ecdsa_key.pem
@@ -0,0 +1,8 @@
+-----BEGIN EC PARAMETERS-----
+BggqhkjOPQMBBw==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIAcPCHJ61KBKnN1ZyU2JaHcItW/JXTB3DujRyc4Ki7RqoAoGCCqGSM49
+AwEHoUQDQgAE5itp4r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY
++cPEox5W4nyDSNsWGhz1HX7xlC1Lz3IiwQ==
+-----END EC PRIVATE KEY-----
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
new file mode 100644
index 0000000..f335d03
--- /dev/null
+++ b/ssl/test/runner/handshake_client.go
@@ -0,0 +1,601 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"bytes"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/subtle"
+	"crypto/x509"
+	"encoding/asn1"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"strconv"
+)
+
+type clientHandshakeState struct {
+	c            *Conn
+	serverHello  *serverHelloMsg
+	hello        *clientHelloMsg
+	suite        *cipherSuite
+	finishedHash finishedHash
+	masterSecret []byte
+	session      *ClientSessionState
+}
+
+func (c *Conn) clientHandshake() error {
+	if c.config == nil {
+		c.config = defaultConfig()
+	}
+
+	if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
+		return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
+	}
+
+	hello := &clientHelloMsg{
+		vers:                c.config.maxVersion(),
+		compressionMethods:  []uint8{compressionNone},
+		random:              make([]byte, 32),
+		ocspStapling:        true,
+		serverName:          c.config.ServerName,
+		supportedCurves:     c.config.curvePreferences(),
+		supportedPoints:     []uint8{pointFormatUncompressed},
+		nextProtoNeg:        len(c.config.NextProtos) > 0,
+		secureRenegotiation: true,
+	}
+
+	possibleCipherSuites := c.config.cipherSuites()
+	hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
+
+NextCipherSuite:
+	for _, suiteId := range possibleCipherSuites {
+		for _, suite := range cipherSuites {
+			if suite.id != suiteId {
+				continue
+			}
+			// Don't advertise TLS 1.2-only cipher suites unless
+			// we're attempting TLS 1.2.
+			if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
+				continue
+			}
+			hello.cipherSuites = append(hello.cipherSuites, suiteId)
+			continue NextCipherSuite
+		}
+	}
+
+	_, err := io.ReadFull(c.config.rand(), hello.random)
+	if err != nil {
+		c.sendAlert(alertInternalError)
+		return errors.New("tls: short read from Rand: " + err.Error())
+	}
+
+	if hello.vers >= VersionTLS12 {
+		hello.signatureAndHashes = supportedSKXSignatureAlgorithms
+	}
+
+	var session *ClientSessionState
+	var cacheKey string
+	sessionCache := c.config.ClientSessionCache
+	if c.config.SessionTicketsDisabled {
+		sessionCache = nil
+	}
+
+	if sessionCache != nil {
+		hello.ticketSupported = true
+
+		// Try to resume a previously negotiated TLS session, if
+		// available.
+		cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
+		candidateSession, ok := sessionCache.Get(cacheKey)
+		if ok {
+			// Check that the ciphersuite/version used for the
+			// previous session are still valid.
+			cipherSuiteOk := false
+			for _, id := range hello.cipherSuites {
+				if id == candidateSession.cipherSuite {
+					cipherSuiteOk = true
+					break
+				}
+			}
+
+			versOk := candidateSession.vers >= c.config.minVersion() &&
+				candidateSession.vers <= c.config.maxVersion()
+			if versOk && cipherSuiteOk {
+				session = candidateSession
+			}
+		}
+	}
+
+	if session != nil {
+		hello.sessionTicket = session.sessionTicket
+		// A random session ID is used to detect when the
+		// server accepted the ticket and is resuming a session
+		// (see RFC 5077).
+		hello.sessionId = make([]byte, 16)
+		if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
+			c.sendAlert(alertInternalError)
+			return errors.New("tls: short read from Rand: " + err.Error())
+		}
+	}
+
+	c.writeRecord(recordTypeHandshake, hello.marshal())
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	serverHello, ok := msg.(*serverHelloMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(serverHello, msg)
+	}
+
+	vers, ok := c.config.mutualVersion(serverHello.vers)
+	if !ok || vers < VersionTLS10 {
+		// TLS 1.0 is the minimum version supported as a client.
+		c.sendAlert(alertProtocolVersion)
+		return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers)
+	}
+	c.vers = vers
+	c.haveVers = true
+
+	suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
+	if suite == nil {
+		c.sendAlert(alertHandshakeFailure)
+		return fmt.Errorf("tls: server selected an unsupported cipher suite")
+	}
+
+	hs := &clientHandshakeState{
+		c:            c,
+		serverHello:  serverHello,
+		hello:        hello,
+		suite:        suite,
+		finishedHash: newFinishedHash(c.vers, suite),
+		session:      session,
+	}
+
+	hs.finishedHash.Write(hs.hello.marshal())
+	hs.finishedHash.Write(hs.serverHello.marshal())
+
+	isResume, err := hs.processServerHello()
+	if err != nil {
+		return err
+	}
+
+	if isResume {
+		if err := hs.establishKeys(); err != nil {
+			return err
+		}
+		if err := hs.readSessionTicket(); err != nil {
+			return err
+		}
+		if err := hs.readFinished(); err != nil {
+			return err
+		}
+		if err := hs.sendFinished(); err != nil {
+			return err
+		}
+	} else {
+		if err := hs.doFullHandshake(); err != nil {
+			return err
+		}
+		if err := hs.establishKeys(); err != nil {
+			return err
+		}
+		if err := hs.sendFinished(); err != nil {
+			return err
+		}
+		if err := hs.readSessionTicket(); err != nil {
+			return err
+		}
+		if err := hs.readFinished(); err != nil {
+			return err
+		}
+	}
+
+	if sessionCache != nil && hs.session != nil && session != hs.session {
+		sessionCache.Put(cacheKey, hs.session)
+	}
+
+	c.didResume = isResume
+	c.handshakeComplete = true
+	c.cipherSuite = suite.id
+	return nil
+}
+
+func (hs *clientHandshakeState) doFullHandshake() error {
+	c := hs.c
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	certMsg, ok := msg.(*certificateMsg)
+	if !ok || len(certMsg.certificates) == 0 {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(certMsg, msg)
+	}
+	hs.finishedHash.Write(certMsg.marshal())
+
+	certs := make([]*x509.Certificate, len(certMsg.certificates))
+	for i, asn1Data := range certMsg.certificates {
+		cert, err := x509.ParseCertificate(asn1Data)
+		if err != nil {
+			c.sendAlert(alertBadCertificate)
+			return errors.New("tls: failed to parse certificate from server: " + err.Error())
+		}
+		certs[i] = cert
+	}
+
+	if !c.config.InsecureSkipVerify {
+		opts := x509.VerifyOptions{
+			Roots:         c.config.RootCAs,
+			CurrentTime:   c.config.time(),
+			DNSName:       c.config.ServerName,
+			Intermediates: x509.NewCertPool(),
+		}
+
+		for i, cert := range certs {
+			if i == 0 {
+				continue
+			}
+			opts.Intermediates.AddCert(cert)
+		}
+		c.verifiedChains, err = certs[0].Verify(opts)
+		if err != nil {
+			c.sendAlert(alertBadCertificate)
+			return err
+		}
+	}
+
+	switch certs[0].PublicKey.(type) {
+	case *rsa.PublicKey, *ecdsa.PublicKey:
+		break
+	default:
+		c.sendAlert(alertUnsupportedCertificate)
+		return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
+	}
+
+	c.peerCertificates = certs
+
+	if hs.serverHello.ocspStapling {
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+		cs, ok := msg.(*certificateStatusMsg)
+		if !ok {
+			c.sendAlert(alertUnexpectedMessage)
+			return unexpectedMessageError(cs, msg)
+		}
+		hs.finishedHash.Write(cs.marshal())
+
+		if cs.statusType == statusTypeOCSP {
+			c.ocspResponse = cs.response
+		}
+	}
+
+	msg, err = c.readHandshake()
+	if err != nil {
+		return err
+	}
+
+	keyAgreement := hs.suite.ka(c.vers)
+
+	skx, ok := msg.(*serverKeyExchangeMsg)
+	if ok {
+		hs.finishedHash.Write(skx.marshal())
+		err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx)
+		if err != nil {
+			c.sendAlert(alertUnexpectedMessage)
+			return err
+		}
+
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+	}
+
+	var chainToSend *Certificate
+	var certRequested bool
+	certReq, ok := msg.(*certificateRequestMsg)
+	if ok {
+		certRequested = true
+
+		// RFC 4346 on the certificateAuthorities field:
+		// A list of the distinguished names of acceptable certificate
+		// authorities. These distinguished names may specify a desired
+		// distinguished name for a root CA or for a subordinate CA;
+		// thus, this message can be used to describe both known roots
+		// and a desired authorization space. If the
+		// certificate_authorities list is empty then the client MAY
+		// send any certificate of the appropriate
+		// ClientCertificateType, unless there is some external
+		// arrangement to the contrary.
+
+		hs.finishedHash.Write(certReq.marshal())
+
+		var rsaAvail, ecdsaAvail bool
+		for _, certType := range certReq.certificateTypes {
+			switch certType {
+			case certTypeRSASign:
+				rsaAvail = true
+			case certTypeECDSASign:
+				ecdsaAvail = true
+			}
+		}
+
+		// We need to search our list of client certs for one
+		// where SignatureAlgorithm is RSA and the Issuer is in
+		// certReq.certificateAuthorities
+	findCert:
+		for i, chain := range c.config.Certificates {
+			if !rsaAvail && !ecdsaAvail {
+				continue
+			}
+
+			for j, cert := range chain.Certificate {
+				x509Cert := chain.Leaf
+				// parse the certificate if this isn't the leaf
+				// node, or if chain.Leaf was nil
+				if j != 0 || x509Cert == nil {
+					if x509Cert, err = x509.ParseCertificate(cert); err != nil {
+						c.sendAlert(alertInternalError)
+						return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
+					}
+				}
+
+				switch {
+				case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
+				case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
+				default:
+					continue findCert
+				}
+
+				if len(certReq.certificateAuthorities) == 0 {
+					// they gave us an empty list, so just take the
+					// first RSA cert from c.config.Certificates
+					chainToSend = &chain
+					break findCert
+				}
+
+				for _, ca := range certReq.certificateAuthorities {
+					if bytes.Equal(x509Cert.RawIssuer, ca) {
+						chainToSend = &chain
+						break findCert
+					}
+				}
+			}
+		}
+
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+	}
+
+	shd, ok := msg.(*serverHelloDoneMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(shd, msg)
+	}
+	hs.finishedHash.Write(shd.marshal())
+
+	// If the server requested a certificate then we have to send a
+	// Certificate message, even if it's empty because we don't have a
+	// certificate to send.
+	if certRequested {
+		certMsg = new(certificateMsg)
+		if chainToSend != nil {
+			certMsg.certificates = chainToSend.Certificate
+		}
+		hs.finishedHash.Write(certMsg.marshal())
+		c.writeRecord(recordTypeHandshake, certMsg.marshal())
+	}
+
+	preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0])
+	if err != nil {
+		c.sendAlert(alertInternalError)
+		return err
+	}
+	if ckx != nil {
+		hs.finishedHash.Write(ckx.marshal())
+		c.writeRecord(recordTypeHandshake, ckx.marshal())
+	}
+
+	if chainToSend != nil {
+		var signed []byte
+		certVerify := &certificateVerifyMsg{
+			hasSignatureAndHash: c.vers >= VersionTLS12,
+		}
+
+		switch key := c.config.Certificates[0].PrivateKey.(type) {
+		case *ecdsa.PrivateKey:
+			digest, _, hashId := hs.finishedHash.hashForClientCertificate(signatureECDSA)
+			r, s, err := ecdsa.Sign(c.config.rand(), key, digest)
+			if err == nil {
+				signed, err = asn1.Marshal(ecdsaSignature{r, s})
+			}
+			certVerify.signatureAndHash.signature = signatureECDSA
+			certVerify.signatureAndHash.hash = hashId
+		case *rsa.PrivateKey:
+			digest, hashFunc, hashId := hs.finishedHash.hashForClientCertificate(signatureRSA)
+			signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest)
+			certVerify.signatureAndHash.signature = signatureRSA
+			certVerify.signatureAndHash.hash = hashId
+		default:
+			err = errors.New("unknown private key type")
+		}
+		if err != nil {
+			c.sendAlert(alertInternalError)
+			return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
+		}
+		certVerify.signature = signed
+
+		hs.finishedHash.Write(certVerify.marshal())
+		c.writeRecord(recordTypeHandshake, certVerify.marshal())
+	}
+
+	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
+	return nil
+}
+
+func (hs *clientHandshakeState) establishKeys() error {
+	c := hs.c
+
+	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+		keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+	var clientCipher, serverCipher interface{}
+	var clientHash, serverHash macFunction
+	if hs.suite.cipher != nil {
+		clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
+		clientHash = hs.suite.mac(c.vers, clientMAC)
+		serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
+		serverHash = hs.suite.mac(c.vers, serverMAC)
+	} else {
+		clientCipher = hs.suite.aead(clientKey, clientIV)
+		serverCipher = hs.suite.aead(serverKey, serverIV)
+	}
+
+	c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
+	c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
+	return nil
+}
+
+func (hs *clientHandshakeState) serverResumedSession() bool {
+	// If the server responded with the same sessionId then it means the
+	// sessionTicket is being used to resume a TLS session.
+	return hs.session != nil && hs.hello.sessionId != nil &&
+		bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
+}
+
+func (hs *clientHandshakeState) processServerHello() (bool, error) {
+	c := hs.c
+
+	if hs.serverHello.compressionMethod != compressionNone {
+		c.sendAlert(alertUnexpectedMessage)
+		return false, errors.New("tls: server selected unsupported compression format")
+	}
+
+	if !hs.hello.nextProtoNeg && hs.serverHello.nextProtoNeg {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("server advertised unrequested NPN extension")
+	}
+
+	if hs.serverResumedSession() {
+		// Restore masterSecret and peerCerts from previous state
+		hs.masterSecret = hs.session.masterSecret
+		c.peerCertificates = hs.session.serverCertificates
+		return true, nil
+	}
+	return false, nil
+}
+
+func (hs *clientHandshakeState) readFinished() error {
+	c := hs.c
+
+	c.readRecord(recordTypeChangeCipherSpec)
+	if err := c.in.error(); err != nil {
+		return err
+	}
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	serverFinished, ok := msg.(*finishedMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(serverFinished, msg)
+	}
+
+	verify := hs.finishedHash.serverSum(hs.masterSecret)
+	if len(verify) != len(serverFinished.verifyData) ||
+		subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
+		c.sendAlert(alertHandshakeFailure)
+		return errors.New("tls: server's Finished message was incorrect")
+	}
+	hs.finishedHash.Write(serverFinished.marshal())
+	return nil
+}
+
+func (hs *clientHandshakeState) readSessionTicket() error {
+	if !hs.serverHello.ticketSupported {
+		return nil
+	}
+
+	c := hs.c
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(sessionTicketMsg, msg)
+	}
+	hs.finishedHash.Write(sessionTicketMsg.marshal())
+
+	hs.session = &ClientSessionState{
+		sessionTicket:      sessionTicketMsg.ticket,
+		vers:               c.vers,
+		cipherSuite:        hs.suite.id,
+		masterSecret:       hs.masterSecret,
+		serverCertificates: c.peerCertificates,
+	}
+
+	return nil
+}
+
+func (hs *clientHandshakeState) sendFinished() error {
+	c := hs.c
+
+	c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+	if hs.serverHello.nextProtoNeg {
+		nextProto := new(nextProtoMsg)
+		proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
+		nextProto.proto = proto
+		c.clientProtocol = proto
+		c.clientProtocolFallback = fallback
+
+		hs.finishedHash.Write(nextProto.marshal())
+		c.writeRecord(recordTypeHandshake, nextProto.marshal())
+	}
+
+	finished := new(finishedMsg)
+	finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
+	hs.finishedHash.Write(finished.marshal())
+	c.writeRecord(recordTypeHandshake, finished.marshal())
+	return nil
+}
+
+// clientSessionCacheKey returns a key used to cache sessionTickets that could
+// be used to resume previously negotiated TLS sessions with a server.
+func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
+	if len(config.ServerName) > 0 {
+		return config.ServerName
+	}
+	return serverAddr.String()
+}
+
+// mutualProtocol finds the mutual Next Protocol Negotiation protocol given the
+// set of client and server supported protocols. The set of client supported
+// protocols must not be empty. It returns the resulting protocol and flag
+// indicating if the fallback case was reached.
+func mutualProtocol(clientProtos, serverProtos []string) (string, bool) {
+	for _, s := range serverProtos {
+		for _, c := range clientProtos {
+			if s == c {
+				return s, false
+			}
+		}
+	}
+
+	return clientProtos[0], true
+}
diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go
new file mode 100644
index 0000000..e31f47b
--- /dev/null
+++ b/ssl/test/runner/handshake_messages.go
@@ -0,0 +1,1344 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "bytes"
+
+type clientHelloMsg struct {
+	raw                 []byte
+	vers                uint16
+	random              []byte
+	sessionId           []byte
+	cipherSuites        []uint16
+	compressionMethods  []uint8
+	nextProtoNeg        bool
+	serverName          string
+	ocspStapling        bool
+	supportedCurves     []CurveID
+	supportedPoints     []uint8
+	ticketSupported     bool
+	sessionTicket       []uint8
+	signatureAndHashes  []signatureAndHash
+	secureRenegotiation bool
+}
+
+func (m *clientHelloMsg) equal(i interface{}) bool {
+	m1, ok := i.(*clientHelloMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.vers == m1.vers &&
+		bytes.Equal(m.random, m1.random) &&
+		bytes.Equal(m.sessionId, m1.sessionId) &&
+		eqUint16s(m.cipherSuites, m1.cipherSuites) &&
+		bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
+		m.nextProtoNeg == m1.nextProtoNeg &&
+		m.serverName == m1.serverName &&
+		m.ocspStapling == m1.ocspStapling &&
+		eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
+		bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
+		m.ticketSupported == m1.ticketSupported &&
+		bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
+		eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
+		m.secureRenegotiation == m1.secureRenegotiation
+}
+
+func (m *clientHelloMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
+	numExtensions := 0
+	extensionsLength := 0
+	if m.nextProtoNeg {
+		numExtensions++
+	}
+	if m.ocspStapling {
+		extensionsLength += 1 + 2 + 2
+		numExtensions++
+	}
+	if len(m.serverName) > 0 {
+		extensionsLength += 5 + len(m.serverName)
+		numExtensions++
+	}
+	if len(m.supportedCurves) > 0 {
+		extensionsLength += 2 + 2*len(m.supportedCurves)
+		numExtensions++
+	}
+	if len(m.supportedPoints) > 0 {
+		extensionsLength += 1 + len(m.supportedPoints)
+		numExtensions++
+	}
+	if m.ticketSupported {
+		extensionsLength += len(m.sessionTicket)
+		numExtensions++
+	}
+	if len(m.signatureAndHashes) > 0 {
+		extensionsLength += 2 + 2*len(m.signatureAndHashes)
+		numExtensions++
+	}
+	if m.secureRenegotiation {
+		extensionsLength += 1
+		numExtensions++
+	}
+	if numExtensions > 0 {
+		extensionsLength += 4 * numExtensions
+		length += 2 + extensionsLength
+	}
+
+	x := make([]byte, 4+length)
+	x[0] = typeClientHello
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	x[4] = uint8(m.vers >> 8)
+	x[5] = uint8(m.vers)
+	copy(x[6:38], m.random)
+	x[38] = uint8(len(m.sessionId))
+	copy(x[39:39+len(m.sessionId)], m.sessionId)
+	y := x[39+len(m.sessionId):]
+	y[0] = uint8(len(m.cipherSuites) >> 7)
+	y[1] = uint8(len(m.cipherSuites) << 1)
+	for i, suite := range m.cipherSuites {
+		y[2+i*2] = uint8(suite >> 8)
+		y[3+i*2] = uint8(suite)
+	}
+	z := y[2+len(m.cipherSuites)*2:]
+	z[0] = uint8(len(m.compressionMethods))
+	copy(z[1:], m.compressionMethods)
+
+	z = z[1+len(m.compressionMethods):]
+	if numExtensions > 0 {
+		z[0] = byte(extensionsLength >> 8)
+		z[1] = byte(extensionsLength)
+		z = z[2:]
+	}
+	if m.nextProtoNeg {
+		z[0] = byte(extensionNextProtoNeg >> 8)
+		z[1] = byte(extensionNextProtoNeg & 0xff)
+		// The length is always 0
+		z = z[4:]
+	}
+	if len(m.serverName) > 0 {
+		z[0] = byte(extensionServerName >> 8)
+		z[1] = byte(extensionServerName & 0xff)
+		l := len(m.serverName) + 5
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		z = z[4:]
+
+		// RFC 3546, section 3.1
+		//
+		// struct {
+		//     NameType name_type;
+		//     select (name_type) {
+		//         case host_name: HostName;
+		//     } name;
+		// } ServerName;
+		//
+		// enum {
+		//     host_name(0), (255)
+		// } NameType;
+		//
+		// opaque HostName<1..2^16-1>;
+		//
+		// struct {
+		//     ServerName server_name_list<1..2^16-1>
+		// } ServerNameList;
+
+		z[0] = byte((len(m.serverName) + 3) >> 8)
+		z[1] = byte(len(m.serverName) + 3)
+		z[3] = byte(len(m.serverName) >> 8)
+		z[4] = byte(len(m.serverName))
+		copy(z[5:], []byte(m.serverName))
+		z = z[l:]
+	}
+	if m.ocspStapling {
+		// RFC 4366, section 3.6
+		z[0] = byte(extensionStatusRequest >> 8)
+		z[1] = byte(extensionStatusRequest)
+		z[2] = 0
+		z[3] = 5
+		z[4] = 1 // OCSP type
+		// Two zero valued uint16s for the two lengths.
+		z = z[9:]
+	}
+	if len(m.supportedCurves) > 0 {
+		// http://tools.ietf.org/html/rfc4492#section-5.5.1
+		z[0] = byte(extensionSupportedCurves >> 8)
+		z[1] = byte(extensionSupportedCurves)
+		l := 2 + 2*len(m.supportedCurves)
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		l -= 2
+		z[4] = byte(l >> 8)
+		z[5] = byte(l)
+		z = z[6:]
+		for _, curve := range m.supportedCurves {
+			z[0] = byte(curve >> 8)
+			z[1] = byte(curve)
+			z = z[2:]
+		}
+	}
+	if len(m.supportedPoints) > 0 {
+		// http://tools.ietf.org/html/rfc4492#section-5.5.2
+		z[0] = byte(extensionSupportedPoints >> 8)
+		z[1] = byte(extensionSupportedPoints)
+		l := 1 + len(m.supportedPoints)
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		l--
+		z[4] = byte(l)
+		z = z[5:]
+		for _, pointFormat := range m.supportedPoints {
+			z[0] = byte(pointFormat)
+			z = z[1:]
+		}
+	}
+	if m.ticketSupported {
+		// http://tools.ietf.org/html/rfc5077#section-3.2
+		z[0] = byte(extensionSessionTicket >> 8)
+		z[1] = byte(extensionSessionTicket)
+		l := len(m.sessionTicket)
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		z = z[4:]
+		copy(z, m.sessionTicket)
+		z = z[len(m.sessionTicket):]
+	}
+	if len(m.signatureAndHashes) > 0 {
+		// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+		z[0] = byte(extensionSignatureAlgorithms >> 8)
+		z[1] = byte(extensionSignatureAlgorithms)
+		l := 2 + 2*len(m.signatureAndHashes)
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		z = z[4:]
+
+		l -= 2
+		z[0] = byte(l >> 8)
+		z[1] = byte(l)
+		z = z[2:]
+		for _, sigAndHash := range m.signatureAndHashes {
+			z[0] = sigAndHash.hash
+			z[1] = sigAndHash.signature
+			z = z[2:]
+		}
+	}
+	if m.secureRenegotiation {
+		z[0] = byte(extensionRenegotiationInfo >> 8)
+		z[1] = byte(extensionRenegotiationInfo & 0xff)
+		z[2] = 0
+		z[3] = 1
+		z = z[5:]
+	}
+
+	m.raw = x
+
+	return x
+}
+
+func (m *clientHelloMsg) unmarshal(data []byte) bool {
+	if len(data) < 42 {
+		return false
+	}
+	m.raw = data
+	m.vers = uint16(data[4])<<8 | uint16(data[5])
+	m.random = data[6:38]
+	sessionIdLen := int(data[38])
+	if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
+		return false
+	}
+	m.sessionId = data[39 : 39+sessionIdLen]
+	data = data[39+sessionIdLen:]
+	if len(data) < 2 {
+		return false
+	}
+	// cipherSuiteLen is the number of bytes of cipher suite numbers. Since
+	// they are uint16s, the number must be even.
+	cipherSuiteLen := int(data[0])<<8 | int(data[1])
+	if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
+		return false
+	}
+	numCipherSuites := cipherSuiteLen / 2
+	m.cipherSuites = make([]uint16, numCipherSuites)
+	for i := 0; i < numCipherSuites; i++ {
+		m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
+		if m.cipherSuites[i] == scsvRenegotiation {
+			m.secureRenegotiation = true
+		}
+	}
+	data = data[2+cipherSuiteLen:]
+	if len(data) < 1 {
+		return false
+	}
+	compressionMethodsLen := int(data[0])
+	if len(data) < 1+compressionMethodsLen {
+		return false
+	}
+	m.compressionMethods = data[1 : 1+compressionMethodsLen]
+
+	data = data[1+compressionMethodsLen:]
+
+	m.nextProtoNeg = false
+	m.serverName = ""
+	m.ocspStapling = false
+	m.ticketSupported = false
+	m.sessionTicket = nil
+	m.signatureAndHashes = nil
+
+	if len(data) == 0 {
+		// ClientHello is optionally followed by extension data
+		return true
+	}
+	if len(data) < 2 {
+		return false
+	}
+
+	extensionsLength := int(data[0])<<8 | int(data[1])
+	data = data[2:]
+	if extensionsLength != len(data) {
+		return false
+	}
+
+	for len(data) != 0 {
+		if len(data) < 4 {
+			return false
+		}
+		extension := uint16(data[0])<<8 | uint16(data[1])
+		length := int(data[2])<<8 | int(data[3])
+		data = data[4:]
+		if len(data) < length {
+			return false
+		}
+
+		switch extension {
+		case extensionServerName:
+			if length < 2 {
+				return false
+			}
+			numNames := int(data[0])<<8 | int(data[1])
+			d := data[2:]
+			for i := 0; i < numNames; i++ {
+				if len(d) < 3 {
+					return false
+				}
+				nameType := d[0]
+				nameLen := int(d[1])<<8 | int(d[2])
+				d = d[3:]
+				if len(d) < nameLen {
+					return false
+				}
+				if nameType == 0 {
+					m.serverName = string(d[0:nameLen])
+					break
+				}
+				d = d[nameLen:]
+			}
+		case extensionNextProtoNeg:
+			if length > 0 {
+				return false
+			}
+			m.nextProtoNeg = true
+		case extensionStatusRequest:
+			m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
+		case extensionSupportedCurves:
+			// http://tools.ietf.org/html/rfc4492#section-5.5.1
+			if length < 2 {
+				return false
+			}
+			l := int(data[0])<<8 | int(data[1])
+			if l%2 == 1 || length != l+2 {
+				return false
+			}
+			numCurves := l / 2
+			m.supportedCurves = make([]CurveID, numCurves)
+			d := data[2:]
+			for i := 0; i < numCurves; i++ {
+				m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
+				d = d[2:]
+			}
+		case extensionSupportedPoints:
+			// http://tools.ietf.org/html/rfc4492#section-5.5.2
+			if length < 1 {
+				return false
+			}
+			l := int(data[0])
+			if length != l+1 {
+				return false
+			}
+			m.supportedPoints = make([]uint8, l)
+			copy(m.supportedPoints, data[1:])
+		case extensionSessionTicket:
+			// http://tools.ietf.org/html/rfc5077#section-3.2
+			m.ticketSupported = true
+			m.sessionTicket = data[:length]
+		case extensionSignatureAlgorithms:
+			// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+			if length < 2 || length&1 != 0 {
+				return false
+			}
+			l := int(data[0])<<8 | int(data[1])
+			if l != length-2 {
+				return false
+			}
+			n := l / 2
+			d := data[2:]
+			m.signatureAndHashes = make([]signatureAndHash, n)
+			for i := range m.signatureAndHashes {
+				m.signatureAndHashes[i].hash = d[0]
+				m.signatureAndHashes[i].signature = d[1]
+				d = d[2:]
+			}
+		case extensionRenegotiationInfo + 1:
+			if length != 1 || data[0] != 0 {
+				return false
+			}
+			m.secureRenegotiation = true
+		}
+		data = data[length:]
+	}
+
+	return true
+}
+
+type serverHelloMsg struct {
+	raw                 []byte
+	vers                uint16
+	random              []byte
+	sessionId           []byte
+	cipherSuite         uint16
+	compressionMethod   uint8
+	nextProtoNeg        bool
+	nextProtos          []string
+	ocspStapling        bool
+	ticketSupported     bool
+	secureRenegotiation bool
+}
+
+func (m *serverHelloMsg) equal(i interface{}) bool {
+	m1, ok := i.(*serverHelloMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.vers == m1.vers &&
+		bytes.Equal(m.random, m1.random) &&
+		bytes.Equal(m.sessionId, m1.sessionId) &&
+		m.cipherSuite == m1.cipherSuite &&
+		m.compressionMethod == m1.compressionMethod &&
+		m.nextProtoNeg == m1.nextProtoNeg &&
+		eqStrings(m.nextProtos, m1.nextProtos) &&
+		m.ocspStapling == m1.ocspStapling &&
+		m.ticketSupported == m1.ticketSupported &&
+		m.secureRenegotiation == m1.secureRenegotiation
+}
+
+func (m *serverHelloMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	length := 38 + len(m.sessionId)
+	numExtensions := 0
+	extensionsLength := 0
+
+	nextProtoLen := 0
+	if m.nextProtoNeg {
+		numExtensions++
+		for _, v := range m.nextProtos {
+			nextProtoLen += len(v)
+		}
+		nextProtoLen += len(m.nextProtos)
+		extensionsLength += nextProtoLen
+	}
+	if m.ocspStapling {
+		numExtensions++
+	}
+	if m.ticketSupported {
+		numExtensions++
+	}
+	if m.secureRenegotiation {
+		extensionsLength += 1
+		numExtensions++
+	}
+	if numExtensions > 0 {
+		extensionsLength += 4 * numExtensions
+		length += 2 + extensionsLength
+	}
+
+	x := make([]byte, 4+length)
+	x[0] = typeServerHello
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	x[4] = uint8(m.vers >> 8)
+	x[5] = uint8(m.vers)
+	copy(x[6:38], m.random)
+	x[38] = uint8(len(m.sessionId))
+	copy(x[39:39+len(m.sessionId)], m.sessionId)
+	z := x[39+len(m.sessionId):]
+	z[0] = uint8(m.cipherSuite >> 8)
+	z[1] = uint8(m.cipherSuite)
+	z[2] = uint8(m.compressionMethod)
+
+	z = z[3:]
+	if numExtensions > 0 {
+		z[0] = byte(extensionsLength >> 8)
+		z[1] = byte(extensionsLength)
+		z = z[2:]
+	}
+	if m.nextProtoNeg {
+		z[0] = byte(extensionNextProtoNeg >> 8)
+		z[1] = byte(extensionNextProtoNeg & 0xff)
+		z[2] = byte(nextProtoLen >> 8)
+		z[3] = byte(nextProtoLen)
+		z = z[4:]
+
+		for _, v := range m.nextProtos {
+			l := len(v)
+			if l > 255 {
+				l = 255
+			}
+			z[0] = byte(l)
+			copy(z[1:], []byte(v[0:l]))
+			z = z[1+l:]
+		}
+	}
+	if m.ocspStapling {
+		z[0] = byte(extensionStatusRequest >> 8)
+		z[1] = byte(extensionStatusRequest)
+		z = z[4:]
+	}
+	if m.ticketSupported {
+		z[0] = byte(extensionSessionTicket >> 8)
+		z[1] = byte(extensionSessionTicket)
+		z = z[4:]
+	}
+	if m.secureRenegotiation {
+		z[0] = byte(extensionRenegotiationInfo >> 8)
+		z[1] = byte(extensionRenegotiationInfo & 0xff)
+		z[2] = 0
+		z[3] = 1
+		z = z[5:]
+	}
+
+	m.raw = x
+
+	return x
+}
+
+func (m *serverHelloMsg) unmarshal(data []byte) bool {
+	if len(data) < 42 {
+		return false
+	}
+	m.raw = data
+	m.vers = uint16(data[4])<<8 | uint16(data[5])
+	m.random = data[6:38]
+	sessionIdLen := int(data[38])
+	if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
+		return false
+	}
+	m.sessionId = data[39 : 39+sessionIdLen]
+	data = data[39+sessionIdLen:]
+	if len(data) < 3 {
+		return false
+	}
+	m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
+	m.compressionMethod = data[2]
+	data = data[3:]
+
+	m.nextProtoNeg = false
+	m.nextProtos = nil
+	m.ocspStapling = false
+	m.ticketSupported = false
+
+	if len(data) == 0 {
+		// ServerHello is optionally followed by extension data
+		return true
+	}
+	if len(data) < 2 {
+		return false
+	}
+
+	extensionsLength := int(data[0])<<8 | int(data[1])
+	data = data[2:]
+	if len(data) != extensionsLength {
+		return false
+	}
+
+	for len(data) != 0 {
+		if len(data) < 4 {
+			return false
+		}
+		extension := uint16(data[0])<<8 | uint16(data[1])
+		length := int(data[2])<<8 | int(data[3])
+		data = data[4:]
+		if len(data) < length {
+			return false
+		}
+
+		switch extension {
+		case extensionNextProtoNeg:
+			m.nextProtoNeg = true
+			d := data[:length]
+			for len(d) > 0 {
+				l := int(d[0])
+				d = d[1:]
+				if l == 0 || l > len(d) {
+					return false
+				}
+				m.nextProtos = append(m.nextProtos, string(d[:l]))
+				d = d[l:]
+			}
+		case extensionStatusRequest:
+			if length > 0 {
+				return false
+			}
+			m.ocspStapling = true
+		case extensionSessionTicket:
+			if length > 0 {
+				return false
+			}
+			m.ticketSupported = true
+		case extensionRenegotiationInfo:
+			if length != 1 || data[0] != 0 {
+				return false
+			}
+			m.secureRenegotiation = true
+		}
+		data = data[length:]
+	}
+
+	return true
+}
+
+type certificateMsg struct {
+	raw          []byte
+	certificates [][]byte
+}
+
+func (m *certificateMsg) equal(i interface{}) bool {
+	m1, ok := i.(*certificateMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		eqByteSlices(m.certificates, m1.certificates)
+}
+
+func (m *certificateMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	var i int
+	for _, slice := range m.certificates {
+		i += len(slice)
+	}
+
+	length := 3 + 3*len(m.certificates) + i
+	x = make([]byte, 4+length)
+	x[0] = typeCertificate
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+
+	certificateOctets := length - 3
+	x[4] = uint8(certificateOctets >> 16)
+	x[5] = uint8(certificateOctets >> 8)
+	x[6] = uint8(certificateOctets)
+
+	y := x[7:]
+	for _, slice := range m.certificates {
+		y[0] = uint8(len(slice) >> 16)
+		y[1] = uint8(len(slice) >> 8)
+		y[2] = uint8(len(slice))
+		copy(y[3:], slice)
+		y = y[3+len(slice):]
+	}
+
+	m.raw = x
+	return
+}
+
+func (m *certificateMsg) unmarshal(data []byte) bool {
+	if len(data) < 7 {
+		return false
+	}
+
+	m.raw = data
+	certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
+	if uint32(len(data)) != certsLen+7 {
+		return false
+	}
+
+	numCerts := 0
+	d := data[7:]
+	for certsLen > 0 {
+		if len(d) < 4 {
+			return false
+		}
+		certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
+		if uint32(len(d)) < 3+certLen {
+			return false
+		}
+		d = d[3+certLen:]
+		certsLen -= 3 + certLen
+		numCerts++
+	}
+
+	m.certificates = make([][]byte, numCerts)
+	d = data[7:]
+	for i := 0; i < numCerts; i++ {
+		certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
+		m.certificates[i] = d[3 : 3+certLen]
+		d = d[3+certLen:]
+	}
+
+	return true
+}
+
+type serverKeyExchangeMsg struct {
+	raw []byte
+	key []byte
+}
+
+func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
+	m1, ok := i.(*serverKeyExchangeMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.key, m1.key)
+}
+
+func (m *serverKeyExchangeMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+	length := len(m.key)
+	x := make([]byte, length+4)
+	x[0] = typeServerKeyExchange
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	copy(x[4:], m.key)
+
+	m.raw = x
+	return x
+}
+
+func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
+	m.raw = data
+	if len(data) < 4 {
+		return false
+	}
+	m.key = data[4:]
+	return true
+}
+
+type certificateStatusMsg struct {
+	raw        []byte
+	statusType uint8
+	response   []byte
+}
+
+func (m *certificateStatusMsg) equal(i interface{}) bool {
+	m1, ok := i.(*certificateStatusMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.statusType == m1.statusType &&
+		bytes.Equal(m.response, m1.response)
+}
+
+func (m *certificateStatusMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	var x []byte
+	if m.statusType == statusTypeOCSP {
+		x = make([]byte, 4+4+len(m.response))
+		x[0] = typeCertificateStatus
+		l := len(m.response) + 4
+		x[1] = byte(l >> 16)
+		x[2] = byte(l >> 8)
+		x[3] = byte(l)
+		x[4] = statusTypeOCSP
+
+		l -= 4
+		x[5] = byte(l >> 16)
+		x[6] = byte(l >> 8)
+		x[7] = byte(l)
+		copy(x[8:], m.response)
+	} else {
+		x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
+	}
+
+	m.raw = x
+	return x
+}
+
+func (m *certificateStatusMsg) unmarshal(data []byte) bool {
+	m.raw = data
+	if len(data) < 5 {
+		return false
+	}
+	m.statusType = data[4]
+
+	m.response = nil
+	if m.statusType == statusTypeOCSP {
+		if len(data) < 8 {
+			return false
+		}
+		respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
+		if uint32(len(data)) != 4+4+respLen {
+			return false
+		}
+		m.response = data[8:]
+	}
+	return true
+}
+
+type serverHelloDoneMsg struct{}
+
+func (m *serverHelloDoneMsg) equal(i interface{}) bool {
+	_, ok := i.(*serverHelloDoneMsg)
+	return ok
+}
+
+func (m *serverHelloDoneMsg) marshal() []byte {
+	x := make([]byte, 4)
+	x[0] = typeServerHelloDone
+	return x
+}
+
+func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
+	return len(data) == 4
+}
+
+type clientKeyExchangeMsg struct {
+	raw        []byte
+	ciphertext []byte
+}
+
+func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
+	m1, ok := i.(*clientKeyExchangeMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.ciphertext, m1.ciphertext)
+}
+
+func (m *clientKeyExchangeMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+	length := len(m.ciphertext)
+	x := make([]byte, length+4)
+	x[0] = typeClientKeyExchange
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	copy(x[4:], m.ciphertext)
+
+	m.raw = x
+	return x
+}
+
+func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
+	m.raw = data
+	if len(data) < 4 {
+		return false
+	}
+	l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+	if l != len(data)-4 {
+		return false
+	}
+	m.ciphertext = data[4:]
+	return true
+}
+
+type finishedMsg struct {
+	raw        []byte
+	verifyData []byte
+}
+
+func (m *finishedMsg) equal(i interface{}) bool {
+	m1, ok := i.(*finishedMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.verifyData, m1.verifyData)
+}
+
+func (m *finishedMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	x = make([]byte, 4+len(m.verifyData))
+	x[0] = typeFinished
+	x[3] = byte(len(m.verifyData))
+	copy(x[4:], m.verifyData)
+	m.raw = x
+	return
+}
+
+func (m *finishedMsg) unmarshal(data []byte) bool {
+	m.raw = data
+	if len(data) < 4 {
+		return false
+	}
+	m.verifyData = data[4:]
+	return true
+}
+
+type nextProtoMsg struct {
+	raw   []byte
+	proto string
+}
+
+func (m *nextProtoMsg) equal(i interface{}) bool {
+	m1, ok := i.(*nextProtoMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.proto == m1.proto
+}
+
+func (m *nextProtoMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+	l := len(m.proto)
+	if l > 255 {
+		l = 255
+	}
+
+	padding := 32 - (l+2)%32
+	length := l + padding + 2
+	x := make([]byte, length+4)
+	x[0] = typeNextProtocol
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+
+	y := x[4:]
+	y[0] = byte(l)
+	copy(y[1:], []byte(m.proto[0:l]))
+	y = y[1+l:]
+	y[0] = byte(padding)
+
+	m.raw = x
+
+	return x
+}
+
+func (m *nextProtoMsg) unmarshal(data []byte) bool {
+	m.raw = data
+
+	if len(data) < 5 {
+		return false
+	}
+	data = data[4:]
+	protoLen := int(data[0])
+	data = data[1:]
+	if len(data) < protoLen {
+		return false
+	}
+	m.proto = string(data[0:protoLen])
+	data = data[protoLen:]
+
+	if len(data) < 1 {
+		return false
+	}
+	paddingLen := int(data[0])
+	data = data[1:]
+	if len(data) != paddingLen {
+		return false
+	}
+
+	return true
+}
+
+type certificateRequestMsg struct {
+	raw []byte
+	// hasSignatureAndHash indicates whether this message includes a list
+	// of signature and hash functions. This change was introduced with TLS
+	// 1.2.
+	hasSignatureAndHash bool
+
+	certificateTypes       []byte
+	signatureAndHashes     []signatureAndHash
+	certificateAuthorities [][]byte
+}
+
+func (m *certificateRequestMsg) equal(i interface{}) bool {
+	m1, ok := i.(*certificateRequestMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
+		eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
+		eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
+}
+
+func (m *certificateRequestMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	// See http://tools.ietf.org/html/rfc4346#section-7.4.4
+	length := 1 + len(m.certificateTypes) + 2
+	casLength := 0
+	for _, ca := range m.certificateAuthorities {
+		casLength += 2 + len(ca)
+	}
+	length += casLength
+
+	if m.hasSignatureAndHash {
+		length += 2 + 2*len(m.signatureAndHashes)
+	}
+
+	x = make([]byte, 4+length)
+	x[0] = typeCertificateRequest
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+
+	x[4] = uint8(len(m.certificateTypes))
+
+	copy(x[5:], m.certificateTypes)
+	y := x[5+len(m.certificateTypes):]
+
+	if m.hasSignatureAndHash {
+		n := len(m.signatureAndHashes) * 2
+		y[0] = uint8(n >> 8)
+		y[1] = uint8(n)
+		y = y[2:]
+		for _, sigAndHash := range m.signatureAndHashes {
+			y[0] = sigAndHash.hash
+			y[1] = sigAndHash.signature
+			y = y[2:]
+		}
+	}
+
+	y[0] = uint8(casLength >> 8)
+	y[1] = uint8(casLength)
+	y = y[2:]
+	for _, ca := range m.certificateAuthorities {
+		y[0] = uint8(len(ca) >> 8)
+		y[1] = uint8(len(ca))
+		y = y[2:]
+		copy(y, ca)
+		y = y[len(ca):]
+	}
+
+	m.raw = x
+	return
+}
+
+func (m *certificateRequestMsg) unmarshal(data []byte) bool {
+	m.raw = data
+
+	if len(data) < 5 {
+		return false
+	}
+
+	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+	if uint32(len(data))-4 != length {
+		return false
+	}
+
+	numCertTypes := int(data[4])
+	data = data[5:]
+	if numCertTypes == 0 || len(data) <= numCertTypes {
+		return false
+	}
+
+	m.certificateTypes = make([]byte, numCertTypes)
+	if copy(m.certificateTypes, data) != numCertTypes {
+		return false
+	}
+
+	data = data[numCertTypes:]
+
+	if m.hasSignatureAndHash {
+		if len(data) < 2 {
+			return false
+		}
+		sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
+		data = data[2:]
+		if sigAndHashLen&1 != 0 {
+			return false
+		}
+		if len(data) < int(sigAndHashLen) {
+			return false
+		}
+		numSigAndHash := sigAndHashLen / 2
+		m.signatureAndHashes = make([]signatureAndHash, numSigAndHash)
+		for i := range m.signatureAndHashes {
+			m.signatureAndHashes[i].hash = data[0]
+			m.signatureAndHashes[i].signature = data[1]
+			data = data[2:]
+		}
+	}
+
+	if len(data) < 2 {
+		return false
+	}
+	casLength := uint16(data[0])<<8 | uint16(data[1])
+	data = data[2:]
+	if len(data) < int(casLength) {
+		return false
+	}
+	cas := make([]byte, casLength)
+	copy(cas, data)
+	data = data[casLength:]
+
+	m.certificateAuthorities = nil
+	for len(cas) > 0 {
+		if len(cas) < 2 {
+			return false
+		}
+		caLen := uint16(cas[0])<<8 | uint16(cas[1])
+		cas = cas[2:]
+
+		if len(cas) < int(caLen) {
+			return false
+		}
+
+		m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
+		cas = cas[caLen:]
+	}
+	if len(data) > 0 {
+		return false
+	}
+
+	return true
+}
+
+type certificateVerifyMsg struct {
+	raw                 []byte
+	hasSignatureAndHash bool
+	signatureAndHash    signatureAndHash
+	signature           []byte
+}
+
+func (m *certificateVerifyMsg) equal(i interface{}) bool {
+	m1, ok := i.(*certificateVerifyMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.hasSignatureAndHash == m1.hasSignatureAndHash &&
+		m.signatureAndHash.hash == m1.signatureAndHash.hash &&
+		m.signatureAndHash.signature == m1.signatureAndHash.signature &&
+		bytes.Equal(m.signature, m1.signature)
+}
+
+func (m *certificateVerifyMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	// See http://tools.ietf.org/html/rfc4346#section-7.4.8
+	siglength := len(m.signature)
+	length := 2 + siglength
+	if m.hasSignatureAndHash {
+		length += 2
+	}
+	x = make([]byte, 4+length)
+	x[0] = typeCertificateVerify
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	y := x[4:]
+	if m.hasSignatureAndHash {
+		y[0] = m.signatureAndHash.hash
+		y[1] = m.signatureAndHash.signature
+		y = y[2:]
+	}
+	y[0] = uint8(siglength >> 8)
+	y[1] = uint8(siglength)
+	copy(y[2:], m.signature)
+
+	m.raw = x
+
+	return
+}
+
+func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
+	m.raw = data
+
+	if len(data) < 6 {
+		return false
+	}
+
+	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+	if uint32(len(data))-4 != length {
+		return false
+	}
+
+	data = data[4:]
+	if m.hasSignatureAndHash {
+		m.signatureAndHash.hash = data[0]
+		m.signatureAndHash.signature = data[1]
+		data = data[2:]
+	}
+
+	if len(data) < 2 {
+		return false
+	}
+	siglength := int(data[0])<<8 + int(data[1])
+	data = data[2:]
+	if len(data) != siglength {
+		return false
+	}
+
+	m.signature = data
+
+	return true
+}
+
+type newSessionTicketMsg struct {
+	raw    []byte
+	ticket []byte
+}
+
+func (m *newSessionTicketMsg) equal(i interface{}) bool {
+	m1, ok := i.(*newSessionTicketMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.ticket, m1.ticket)
+}
+
+func (m *newSessionTicketMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	// See http://tools.ietf.org/html/rfc5077#section-3.3
+	ticketLen := len(m.ticket)
+	length := 2 + 4 + ticketLen
+	x = make([]byte, 4+length)
+	x[0] = typeNewSessionTicket
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	x[8] = uint8(ticketLen >> 8)
+	x[9] = uint8(ticketLen)
+	copy(x[10:], m.ticket)
+
+	m.raw = x
+
+	return
+}
+
+func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
+	m.raw = data
+
+	if len(data) < 10 {
+		return false
+	}
+
+	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+	if uint32(len(data))-4 != length {
+		return false
+	}
+
+	ticketLen := int(data[8])<<8 + int(data[9])
+	if len(data)-10 != ticketLen {
+		return false
+	}
+
+	m.ticket = data[10:]
+
+	return true
+}
+
+func eqUint16s(x, y []uint16) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		if y[i] != v {
+			return false
+		}
+	}
+	return true
+}
+
+func eqCurveIDs(x, y []CurveID) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		if y[i] != v {
+			return false
+		}
+	}
+	return true
+}
+
+func eqStrings(x, y []string) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		if y[i] != v {
+			return false
+		}
+	}
+	return true
+}
+
+func eqByteSlices(x, y [][]byte) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		if !bytes.Equal(v, y[i]) {
+			return false
+		}
+	}
+	return true
+}
+
+func eqSignatureAndHashes(x, y []signatureAndHash) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		v2 := y[i]
+		if v.hash != v2.hash || v.signature != v2.signature {
+			return false
+		}
+	}
+	return true
+}
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
new file mode 100644
index 0000000..7a44a94
--- /dev/null
+++ b/ssl/test/runner/handshake_server.go
@@ -0,0 +1,659 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/subtle"
+	"crypto/x509"
+	"encoding/asn1"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// serverHandshakeState contains details of a server handshake in progress.
+// It's discarded once the handshake has completed.
+type serverHandshakeState struct {
+	c               *Conn
+	clientHello     *clientHelloMsg
+	hello           *serverHelloMsg
+	suite           *cipherSuite
+	ellipticOk      bool
+	ecdsaOk         bool
+	sessionState    *sessionState
+	finishedHash    finishedHash
+	masterSecret    []byte
+	certsFromClient [][]byte
+	cert            *Certificate
+}
+
+// serverHandshake performs a TLS handshake as a server.
+func (c *Conn) serverHandshake() error {
+	config := c.config
+
+	// If this is the first server handshake, we generate a random key to
+	// encrypt the tickets with.
+	config.serverInitOnce.Do(config.serverInit)
+
+	hs := serverHandshakeState{
+		c: c,
+	}
+	isResume, err := hs.readClientHello()
+	if err != nil {
+		return err
+	}
+
+	// For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
+	if isResume {
+		// The client has included a session ticket and so we do an abbreviated handshake.
+		if err := hs.doResumeHandshake(); err != nil {
+			return err
+		}
+		if err := hs.establishKeys(); err != nil {
+			return err
+		}
+		if err := hs.sendFinished(); err != nil {
+			return err
+		}
+		if err := hs.readFinished(); err != nil {
+			return err
+		}
+		c.didResume = true
+	} else {
+		// The client didn't include a session ticket, or it wasn't
+		// valid so we do a full handshake.
+		if err := hs.doFullHandshake(); err != nil {
+			return err
+		}
+		if err := hs.establishKeys(); err != nil {
+			return err
+		}
+		if err := hs.readFinished(); err != nil {
+			return err
+		}
+		if err := hs.sendSessionTicket(); err != nil {
+			return err
+		}
+		if err := hs.sendFinished(); err != nil {
+			return err
+		}
+	}
+	c.handshakeComplete = true
+
+	return nil
+}
+
+// readClientHello reads a ClientHello message from the client and decides
+// whether we will perform session resumption.
+func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
+	config := hs.c.config
+	c := hs.c
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return false, err
+	}
+	var ok bool
+	hs.clientHello, ok = msg.(*clientHelloMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return false, unexpectedMessageError(hs.clientHello, msg)
+	}
+	c.vers, ok = config.mutualVersion(hs.clientHello.vers)
+	if !ok {
+		c.sendAlert(alertProtocolVersion)
+		return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
+	}
+	c.haveVers = true
+
+	hs.hello = new(serverHelloMsg)
+
+	supportedCurve := false
+	preferredCurves := config.curvePreferences()
+Curves:
+	for _, curve := range hs.clientHello.supportedCurves {
+		for _, supported := range preferredCurves {
+			if supported == curve {
+				supportedCurve = true
+				break Curves
+			}
+		}
+	}
+
+	supportedPointFormat := false
+	for _, pointFormat := range hs.clientHello.supportedPoints {
+		if pointFormat == pointFormatUncompressed {
+			supportedPointFormat = true
+			break
+		}
+	}
+	hs.ellipticOk = supportedCurve && supportedPointFormat
+
+	foundCompression := false
+	// We only support null compression, so check that the client offered it.
+	for _, compression := range hs.clientHello.compressionMethods {
+		if compression == compressionNone {
+			foundCompression = true
+			break
+		}
+	}
+
+	if !foundCompression {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("tls: client does not support uncompressed connections")
+	}
+
+	hs.hello.vers = c.vers
+	hs.hello.random = make([]byte, 32)
+	_, err = io.ReadFull(config.rand(), hs.hello.random)
+	if err != nil {
+		c.sendAlert(alertInternalError)
+		return false, err
+	}
+	hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
+	hs.hello.compressionMethod = compressionNone
+	if len(hs.clientHello.serverName) > 0 {
+		c.serverName = hs.clientHello.serverName
+	}
+	// Although sending an empty NPN extension is reasonable, Firefox has
+	// had a bug around this. Best to send nothing at all if
+	// config.NextProtos is empty. See
+	// https://code.google.com/p/go/issues/detail?id=5445.
+	if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 {
+		hs.hello.nextProtoNeg = true
+		hs.hello.nextProtos = config.NextProtos
+	}
+
+	if len(config.Certificates) == 0 {
+		c.sendAlert(alertInternalError)
+		return false, errors.New("tls: no certificates configured")
+	}
+	hs.cert = &config.Certificates[0]
+	if len(hs.clientHello.serverName) > 0 {
+		hs.cert = config.getCertificateForName(hs.clientHello.serverName)
+	}
+
+	_, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey)
+
+	if hs.checkForResumption() {
+		return true, nil
+	}
+
+	var preferenceList, supportedList []uint16
+	if c.config.PreferServerCipherSuites {
+		preferenceList = c.config.cipherSuites()
+		supportedList = hs.clientHello.cipherSuites
+	} else {
+		preferenceList = hs.clientHello.cipherSuites
+		supportedList = c.config.cipherSuites()
+	}
+
+	for _, id := range preferenceList {
+		if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil {
+			break
+		}
+	}
+
+	if hs.suite == nil {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("tls: no cipher suite supported by both client and server")
+	}
+
+	return false, nil
+}
+
+// checkForResumption returns true if we should perform resumption on this connection.
+func (hs *serverHandshakeState) checkForResumption() bool {
+	c := hs.c
+
+	var ok bool
+	if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok {
+		return false
+	}
+
+	if hs.sessionState.vers > hs.clientHello.vers {
+		return false
+	}
+	if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers {
+		return false
+	}
+
+	cipherSuiteOk := false
+	// Check that the client is still offering the ciphersuite in the session.
+	for _, id := range hs.clientHello.cipherSuites {
+		if id == hs.sessionState.cipherSuite {
+			cipherSuiteOk = true
+			break
+		}
+	}
+	if !cipherSuiteOk {
+		return false
+	}
+
+	// Check that we also support the ciphersuite from the session.
+	hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers, hs.ellipticOk, hs.ecdsaOk)
+	if hs.suite == nil {
+		return false
+	}
+
+	sessionHasClientCerts := len(hs.sessionState.certificates) != 0
+	needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert
+	if needClientCerts && !sessionHasClientCerts {
+		return false
+	}
+	if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
+		return false
+	}
+
+	return true
+}
+
+func (hs *serverHandshakeState) doResumeHandshake() error {
+	c := hs.c
+
+	hs.hello.cipherSuite = hs.suite.id
+	// We echo the client's session ID in the ServerHello to let it know
+	// that we're doing a resumption.
+	hs.hello.sessionId = hs.clientHello.sessionId
+
+	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
+	hs.finishedHash.Write(hs.clientHello.marshal())
+	hs.finishedHash.Write(hs.hello.marshal())
+
+	c.writeRecord(recordTypeHandshake, hs.hello.marshal())
+
+	if len(hs.sessionState.certificates) > 0 {
+		if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
+			return err
+		}
+	}
+
+	hs.masterSecret = hs.sessionState.masterSecret
+
+	return nil
+}
+
+func (hs *serverHandshakeState) doFullHandshake() error {
+	config := hs.c.config
+	c := hs.c
+
+	if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
+		hs.hello.ocspStapling = true
+	}
+
+	hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled
+	hs.hello.cipherSuite = hs.suite.id
+
+	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
+	hs.finishedHash.Write(hs.clientHello.marshal())
+	hs.finishedHash.Write(hs.hello.marshal())
+
+	c.writeRecord(recordTypeHandshake, hs.hello.marshal())
+
+	certMsg := new(certificateMsg)
+	certMsg.certificates = hs.cert.Certificate
+	hs.finishedHash.Write(certMsg.marshal())
+	c.writeRecord(recordTypeHandshake, certMsg.marshal())
+
+	if hs.hello.ocspStapling {
+		certStatus := new(certificateStatusMsg)
+		certStatus.statusType = statusTypeOCSP
+		certStatus.response = hs.cert.OCSPStaple
+		hs.finishedHash.Write(certStatus.marshal())
+		c.writeRecord(recordTypeHandshake, certStatus.marshal())
+	}
+
+	keyAgreement := hs.suite.ka(c.vers)
+	skx, err := keyAgreement.generateServerKeyExchange(config, hs.cert, hs.clientHello, hs.hello)
+	if err != nil {
+		c.sendAlert(alertHandshakeFailure)
+		return err
+	}
+	if skx != nil {
+		hs.finishedHash.Write(skx.marshal())
+		c.writeRecord(recordTypeHandshake, skx.marshal())
+	}
+
+	if config.ClientAuth >= RequestClientCert {
+		// Request a client certificate
+		certReq := new(certificateRequestMsg)
+		certReq.certificateTypes = []byte{
+			byte(certTypeRSASign),
+			byte(certTypeECDSASign),
+		}
+		if c.vers >= VersionTLS12 {
+			certReq.hasSignatureAndHash = true
+			certReq.signatureAndHashes = supportedClientCertSignatureAlgorithms
+		}
+
+		// An empty list of certificateAuthorities signals to
+		// the client that it may send any certificate in response
+		// to our request. When we know the CAs we trust, then
+		// we can send them down, so that the client can choose
+		// an appropriate certificate to give to us.
+		if config.ClientCAs != nil {
+			certReq.certificateAuthorities = config.ClientCAs.Subjects()
+		}
+		hs.finishedHash.Write(certReq.marshal())
+		c.writeRecord(recordTypeHandshake, certReq.marshal())
+	}
+
+	helloDone := new(serverHelloDoneMsg)
+	hs.finishedHash.Write(helloDone.marshal())
+	c.writeRecord(recordTypeHandshake, helloDone.marshal())
+
+	var pub crypto.PublicKey // public key for client auth, if any
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+
+	var ok bool
+	// If we requested a client certificate, then the client must send a
+	// certificate message, even if it's empty.
+	if config.ClientAuth >= RequestClientCert {
+		if certMsg, ok = msg.(*certificateMsg); !ok {
+			c.sendAlert(alertUnexpectedMessage)
+			return unexpectedMessageError(certMsg, msg)
+		}
+		hs.finishedHash.Write(certMsg.marshal())
+
+		if len(certMsg.certificates) == 0 {
+			// The client didn't actually send a certificate
+			switch config.ClientAuth {
+			case RequireAnyClientCert, RequireAndVerifyClientCert:
+				c.sendAlert(alertBadCertificate)
+				return errors.New("tls: client didn't provide a certificate")
+			}
+		}
+
+		pub, err = hs.processCertsFromClient(certMsg.certificates)
+		if err != nil {
+			return err
+		}
+
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+	}
+
+	// Get client key exchange
+	ckx, ok := msg.(*clientKeyExchangeMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(ckx, msg)
+	}
+	hs.finishedHash.Write(ckx.marshal())
+
+	// If we received a client cert in response to our certificate request message,
+	// the client will send us a certificateVerifyMsg immediately after the
+	// clientKeyExchangeMsg.  This message is a digest of all preceding
+	// handshake-layer messages that is signed using the private key corresponding
+	// to the client's certificate. This allows us to verify that the client is in
+	// possession of the private key of the certificate.
+	if len(c.peerCertificates) > 0 {
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+		certVerify, ok := msg.(*certificateVerifyMsg)
+		if !ok {
+			c.sendAlert(alertUnexpectedMessage)
+			return unexpectedMessageError(certVerify, msg)
+		}
+
+		switch key := pub.(type) {
+		case *ecdsa.PublicKey:
+			ecdsaSig := new(ecdsaSignature)
+			if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
+				break
+			}
+			if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
+				err = errors.New("ECDSA signature contained zero or negative values")
+				break
+			}
+			digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA)
+			if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
+				err = errors.New("ECDSA verification failure")
+				break
+			}
+		case *rsa.PublicKey:
+			digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA)
+			err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
+		}
+		if err != nil {
+			c.sendAlert(alertBadCertificate)
+			return errors.New("could not validate signature of connection nonces: " + err.Error())
+		}
+
+		hs.finishedHash.Write(certVerify.marshal())
+	}
+
+	preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers)
+	if err != nil {
+		c.sendAlert(alertHandshakeFailure)
+		return err
+	}
+	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
+
+	return nil
+}
+
+func (hs *serverHandshakeState) establishKeys() error {
+	c := hs.c
+
+	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+		keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+
+	var clientCipher, serverCipher interface{}
+	var clientHash, serverHash macFunction
+
+	if hs.suite.aead == nil {
+		clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
+		clientHash = hs.suite.mac(c.vers, clientMAC)
+		serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
+		serverHash = hs.suite.mac(c.vers, serverMAC)
+	} else {
+		clientCipher = hs.suite.aead(clientKey, clientIV)
+		serverCipher = hs.suite.aead(serverKey, serverIV)
+	}
+
+	c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
+	c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
+
+	return nil
+}
+
+func (hs *serverHandshakeState) readFinished() error {
+	c := hs.c
+
+	c.readRecord(recordTypeChangeCipherSpec)
+	if err := c.in.error(); err != nil {
+		return err
+	}
+
+	if hs.hello.nextProtoNeg {
+		msg, err := c.readHandshake()
+		if err != nil {
+			return err
+		}
+		nextProto, ok := msg.(*nextProtoMsg)
+		if !ok {
+			c.sendAlert(alertUnexpectedMessage)
+			return unexpectedMessageError(nextProto, msg)
+		}
+		hs.finishedHash.Write(nextProto.marshal())
+		c.clientProtocol = nextProto.proto
+	}
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	clientFinished, ok := msg.(*finishedMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(clientFinished, msg)
+	}
+
+	verify := hs.finishedHash.clientSum(hs.masterSecret)
+	if len(verify) != len(clientFinished.verifyData) ||
+		subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
+		c.sendAlert(alertHandshakeFailure)
+		return errors.New("tls: client's Finished message is incorrect")
+	}
+
+	hs.finishedHash.Write(clientFinished.marshal())
+	return nil
+}
+
+func (hs *serverHandshakeState) sendSessionTicket() error {
+	if !hs.hello.ticketSupported {
+		return nil
+	}
+
+	c := hs.c
+	m := new(newSessionTicketMsg)
+
+	var err error
+	state := sessionState{
+		vers:         c.vers,
+		cipherSuite:  hs.suite.id,
+		masterSecret: hs.masterSecret,
+		certificates: hs.certsFromClient,
+	}
+	m.ticket, err = c.encryptTicket(&state)
+	if err != nil {
+		return err
+	}
+	m.ticket = make([]byte, 16105+62)
+	for i := range m.ticket {
+		m.ticket[i] = 'A'
+	}
+
+	hs.finishedHash.Write(m.marshal())
+	c.writeRecord(recordTypeHandshake, m.marshal())
+
+	return nil
+}
+
+func (hs *serverHandshakeState) sendFinished() error {
+	c := hs.c
+
+	c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+
+	finished := new(finishedMsg)
+	finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
+	hs.finishedHash.Write(finished.marshal())
+	c.writeRecord(recordTypeHandshake, finished.marshal())
+
+	c.cipherSuite = hs.suite.id
+
+	return nil
+}
+
+// processCertsFromClient takes a chain of client certificates either from a
+// Certificates message or from a sessionState and verifies them. It returns
+// the public key of the leaf certificate.
+func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
+	c := hs.c
+
+	hs.certsFromClient = certificates
+	certs := make([]*x509.Certificate, len(certificates))
+	var err error
+	for i, asn1Data := range certificates {
+		if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
+			c.sendAlert(alertBadCertificate)
+			return nil, errors.New("tls: failed to parse client certificate: " + err.Error())
+		}
+	}
+
+	if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
+		opts := x509.VerifyOptions{
+			Roots:         c.config.ClientCAs,
+			CurrentTime:   c.config.time(),
+			Intermediates: x509.NewCertPool(),
+			KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
+		}
+
+		for _, cert := range certs[1:] {
+			opts.Intermediates.AddCert(cert)
+		}
+
+		chains, err := certs[0].Verify(opts)
+		if err != nil {
+			c.sendAlert(alertBadCertificate)
+			return nil, errors.New("tls: failed to verify client's certificate: " + err.Error())
+		}
+
+		ok := false
+		for _, ku := range certs[0].ExtKeyUsage {
+			if ku == x509.ExtKeyUsageClientAuth {
+				ok = true
+				break
+			}
+		}
+		if !ok {
+			c.sendAlert(alertHandshakeFailure)
+			return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication")
+		}
+
+		c.verifiedChains = chains
+	}
+
+	if len(certs) > 0 {
+		var pub crypto.PublicKey
+		switch key := certs[0].PublicKey.(type) {
+		case *ecdsa.PublicKey, *rsa.PublicKey:
+			pub = key
+		default:
+			c.sendAlert(alertUnsupportedCertificate)
+			return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
+		}
+		c.peerCertificates = certs
+		return pub, nil
+	}
+
+	return nil, nil
+}
+
+// tryCipherSuite returns a cipherSuite with the given id if that cipher suite
+// is acceptable to use.
+func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk bool) *cipherSuite {
+	for _, supported := range supportedCipherSuites {
+		if id == supported {
+			var candidate *cipherSuite
+
+			for _, s := range cipherSuites {
+				if s.id == id {
+					candidate = s
+					break
+				}
+			}
+			if candidate == nil {
+				continue
+			}
+			// Don't select a ciphersuite which we can't
+			// support for this client.
+			if (candidate.flags&suiteECDHE != 0) && !ellipticOk {
+				continue
+			}
+			if (candidate.flags&suiteECDSA != 0) != ecdsaOk {
+				continue
+			}
+			if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
+				continue
+			}
+			return candidate
+		}
+	}
+
+	return nil
+}
diff --git a/ssl/test/runner/key.pem b/ssl/test/runner/key.pem
new file mode 100644
index 0000000..e9107bf
--- /dev/null
+++ b/ssl/test/runner/key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92
+kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF
+KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB
+AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe
+i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+
+WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ
+m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj
+QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk
+aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj
+LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk
+104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/
+tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd
+moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==
+-----END RSA PRIVATE KEY-----
diff --git a/ssl/test/runner/key_agreement.go b/ssl/test/runner/key_agreement.go
new file mode 100644
index 0000000..991a91d
--- /dev/null
+++ b/ssl/test/runner/key_agreement.go
@@ -0,0 +1,436 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/md5"
+	"crypto/rsa"
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/x509"
+	"encoding/asn1"
+	"errors"
+	"io"
+	"math/big"
+)
+
+var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
+var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
+
+// rsaKeyAgreement implements the standard TLS key agreement where the client
+// encrypts the pre-master secret to the server's public key.
+type rsaKeyAgreement struct{}
+
+func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
+	return nil, nil
+}
+
+func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
+	preMasterSecret := make([]byte, 48)
+	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
+	if err != nil {
+		return nil, err
+	}
+
+	if len(ckx.ciphertext) < 2 {
+		return nil, errClientKeyExchange
+	}
+
+	ciphertext := ckx.ciphertext
+	if version != VersionSSL30 {
+		ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
+		if ciphertextLen != len(ckx.ciphertext)-2 {
+			return nil, errClientKeyExchange
+		}
+		ciphertext = ckx.ciphertext[2:]
+	}
+
+	err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
+	if err != nil {
+		return nil, err
+	}
+	// We don't check the version number in the premaster secret.  For one,
+	// by checking it, we would leak information about the validity of the
+	// encrypted pre-master secret. Secondly, it provides only a small
+	// benefit against a downgrade attack and some implementations send the
+	// wrong version anyway. See the discussion at the end of section
+	// 7.4.7.1 of RFC 4346.
+	return preMasterSecret, nil
+}
+
+func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
+	return errors.New("tls: unexpected ServerKeyExchange")
+}
+
+func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+	preMasterSecret := make([]byte, 48)
+	preMasterSecret[0] = byte(clientHello.vers >> 8)
+	preMasterSecret[1] = byte(clientHello.vers)
+	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
+	if err != nil {
+		return nil, nil, err
+	}
+
+	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
+	if err != nil {
+		return nil, nil, err
+	}
+	ckx := new(clientKeyExchangeMsg)
+	ckx.ciphertext = make([]byte, len(encrypted)+2)
+	ckx.ciphertext[0] = byte(len(encrypted) >> 8)
+	ckx.ciphertext[1] = byte(len(encrypted))
+	copy(ckx.ciphertext[2:], encrypted)
+	return preMasterSecret, ckx, nil
+}
+
+// sha1Hash calculates a SHA1 hash over the given byte slices.
+func sha1Hash(slices [][]byte) []byte {
+	hsha1 := sha1.New()
+	for _, slice := range slices {
+		hsha1.Write(slice)
+	}
+	return hsha1.Sum(nil)
+}
+
+// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
+// concatenation of an MD5 and SHA1 hash.
+func md5SHA1Hash(slices [][]byte) []byte {
+	md5sha1 := make([]byte, md5.Size+sha1.Size)
+	hmd5 := md5.New()
+	for _, slice := range slices {
+		hmd5.Write(slice)
+	}
+	copy(md5sha1, hmd5.Sum(nil))
+	copy(md5sha1[md5.Size:], sha1Hash(slices))
+	return md5sha1
+}
+
+// sha256Hash implements TLS 1.2's hash function.
+func sha256Hash(slices [][]byte) []byte {
+	h := sha256.New()
+	for _, slice := range slices {
+		h.Write(slice)
+	}
+	return h.Sum(nil)
+}
+
+// hashForServerKeyExchange hashes the given slices and returns their digest
+// and the identifier of the hash function used. The hashFunc argument is only
+// used for >= TLS 1.2 and precisely identifies the hash function to use.
+func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
+	if version >= VersionTLS12 {
+		switch hashFunc {
+		case hashSHA256:
+			return sha256Hash(slices), crypto.SHA256, nil
+		case hashSHA1:
+			return sha1Hash(slices), crypto.SHA1, nil
+		default:
+			return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer")
+		}
+	}
+	if sigType == signatureECDSA {
+		return sha1Hash(slices), crypto.SHA1, nil
+	}
+	return md5SHA1Hash(slices), crypto.MD5SHA1, nil
+}
+
+// pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a
+// ServerKeyExchange given the signature type being used and the client's
+// advertized list of supported signature and hash combinations.
+func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) {
+	if len(clientSignatureAndHashes) == 0 {
+		// If the client didn't specify any signature_algorithms
+		// extension then we can assume that it supports SHA1. See
+		// http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+		return hashSHA1, nil
+	}
+
+	for _, sigAndHash := range clientSignatureAndHashes {
+		if sigAndHash.signature != sigType {
+			continue
+		}
+		switch sigAndHash.hash {
+		case hashSHA1, hashSHA256:
+			return sigAndHash.hash, nil
+		}
+	}
+
+	return 0, errors.New("tls: client doesn't support any common hash functions")
+}
+
+func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
+	switch id {
+	case CurveP256:
+		return elliptic.P256(), true
+	case CurveP384:
+		return elliptic.P384(), true
+	case CurveP521:
+		return elliptic.P521(), true
+	default:
+		return nil, false
+	}
+
+}
+
+// ecdheRSAKeyAgreement implements a TLS key agreement where the server
+// generates a ephemeral EC public/private key pair and signs it. The
+// pre-master secret is then calculated using ECDH. The signature may
+// either be ECDSA or RSA.
+type ecdheKeyAgreement struct {
+	version    uint16
+	sigType    uint8
+	privateKey []byte
+	curve      elliptic.Curve
+	x, y       *big.Int
+}
+
+func maybeCorruptECDSAValue(n *big.Int, typeOfCorruption BadValue, limit *big.Int) *big.Int {
+	switch typeOfCorruption {
+	case BadValueNone:
+		return n
+	case BadValueNegative:
+		return new(big.Int).Neg(n)
+	case BadValueZero:
+		return big.NewInt(0)
+	case BadValueLimit:
+		return limit
+	case BadValueLarge:
+		bad := new(big.Int).Set(limit)
+		return bad.Lsh(bad, 20)
+	default:
+		panic("unknown BadValue type")
+	}
+}
+
+func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
+	var curveid CurveID
+	preferredCurves := config.curvePreferences()
+
+NextCandidate:
+	for _, candidate := range preferredCurves {
+		for _, c := range clientHello.supportedCurves {
+			if candidate == c {
+				curveid = c
+				break NextCandidate
+			}
+		}
+	}
+
+	if curveid == 0 {
+		return nil, errors.New("tls: no supported elliptic curves offered")
+	}
+
+	var ok bool
+	if ka.curve, ok = curveForCurveID(curveid); !ok {
+		return nil, errors.New("tls: preferredCurves includes unsupported curve")
+	}
+
+	var x, y *big.Int
+	var err error
+	ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
+	if err != nil {
+		return nil, err
+	}
+	ecdhePublic := elliptic.Marshal(ka.curve, x, y)
+
+	// http://tools.ietf.org/html/rfc4492#section-5.4
+	serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
+	serverECDHParams[0] = 3 // named curve
+	serverECDHParams[1] = byte(curveid >> 8)
+	serverECDHParams[2] = byte(curveid)
+	if config.Bugs.InvalidSKXCurve {
+		serverECDHParams[2] ^= 0xff
+	}
+	serverECDHParams[3] = byte(len(ecdhePublic))
+	copy(serverECDHParams[4:], ecdhePublic)
+
+	var tls12HashId uint8
+	if ka.version >= VersionTLS12 {
+		if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
+			return nil, err
+		}
+	}
+
+	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams)
+	if err != nil {
+		return nil, err
+	}
+
+	if config.Bugs.InvalidSKXSignature {
+		digest[0] ^= 0x80
+	}
+
+	var sig []byte
+	switch ka.sigType {
+	case signatureECDSA:
+		privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
+		if !ok {
+			return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
+		}
+		r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
+		if err != nil {
+			return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
+		}
+		order := privKey.Curve.Params().N
+		r = maybeCorruptECDSAValue(r, config.Bugs.BadECDSAR, order)
+		s = maybeCorruptECDSAValue(s, config.Bugs.BadECDSAS, order)
+		sig, err = asn1.Marshal(ecdsaSignature{r, s})
+	case signatureRSA:
+		privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
+		if !ok {
+			return nil, errors.New("ECDHE RSA requires a RSA server private key")
+		}
+		sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
+		if err != nil {
+			return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
+		}
+	default:
+		return nil, errors.New("unknown ECDHE signature algorithm")
+	}
+
+	skx := new(serverKeyExchangeMsg)
+	sigAndHashLen := 0
+	if ka.version >= VersionTLS12 {
+		sigAndHashLen = 2
+	}
+	skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig))
+	copy(skx.key, serverECDHParams)
+	k := skx.key[len(serverECDHParams):]
+	if ka.version >= VersionTLS12 {
+		k[0] = tls12HashId
+		k[1] = ka.sigType
+		k = k[2:]
+	}
+	k[0] = byte(len(sig) >> 8)
+	k[1] = byte(len(sig))
+	copy(k[2:], sig)
+
+	return skx, nil
+}
+
+func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
+	if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
+		return nil, errClientKeyExchange
+	}
+	x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
+	if x == nil {
+		return nil, errClientKeyExchange
+	}
+	x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
+	preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
+	xBytes := x.Bytes()
+	copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
+
+	return preMasterSecret, nil
+}
+
+func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
+	if len(skx.key) < 4 {
+		return errServerKeyExchange
+	}
+	if skx.key[0] != 3 { // named curve
+		return errors.New("tls: server selected unsupported curve")
+	}
+	curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
+
+	var ok bool
+	if ka.curve, ok = curveForCurveID(curveid); !ok {
+		return errors.New("tls: server selected unsupported curve")
+	}
+
+	publicLen := int(skx.key[3])
+	if publicLen+4 > len(skx.key) {
+		return errServerKeyExchange
+	}
+	ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
+	if ka.x == nil {
+		return errServerKeyExchange
+	}
+	serverECDHParams := skx.key[:4+publicLen]
+
+	sig := skx.key[4+publicLen:]
+	if len(sig) < 2 {
+		return errServerKeyExchange
+	}
+
+	var tls12HashId uint8
+	if ka.version >= VersionTLS12 {
+		// handle SignatureAndHashAlgorithm
+		var sigAndHash []uint8
+		sigAndHash, sig = sig[:2], sig[2:]
+		if sigAndHash[1] != ka.sigType {
+			return errServerKeyExchange
+		}
+		tls12HashId = sigAndHash[0]
+		if len(sig) < 2 {
+			return errServerKeyExchange
+		}
+	}
+	sigLen := int(sig[0])<<8 | int(sig[1])
+	if sigLen+2 != len(sig) {
+		return errServerKeyExchange
+	}
+	sig = sig[2:]
+
+	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, serverECDHParams)
+	if err != nil {
+		return err
+	}
+	switch ka.sigType {
+	case signatureECDSA:
+		pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
+		if !ok {
+			return errors.New("ECDHE ECDSA requires a ECDSA server public key")
+		}
+		ecdsaSig := new(ecdsaSignature)
+		if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
+			return err
+		}
+		if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
+			return errors.New("ECDSA signature contained zero or negative values")
+		}
+		if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
+			return errors.New("ECDSA verification failure")
+		}
+	case signatureRSA:
+		pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
+		if !ok {
+			return errors.New("ECDHE RSA requires a RSA server public key")
+		}
+		if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
+			return err
+		}
+	default:
+		return errors.New("unknown ECDHE signature algorithm")
+	}
+
+	return nil
+}
+
+func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+	if ka.curve == nil {
+		return nil, nil, errors.New("missing ServerKeyExchange message")
+	}
+	priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
+	if err != nil {
+		return nil, nil, err
+	}
+	x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
+	preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
+	xBytes := x.Bytes()
+	copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
+
+	serialized := elliptic.Marshal(ka.curve, mx, my)
+
+	ckx := new(clientKeyExchangeMsg)
+	ckx.ciphertext = make([]byte, 1+len(serialized))
+	ckx.ciphertext[0] = byte(len(serialized))
+	copy(ckx.ciphertext[1:], serialized)
+
+	return preMasterSecret, ckx, nil
+}
diff --git a/ssl/test/runner/prf.go b/ssl/test/runner/prf.go
new file mode 100644
index 0000000..acb9654
--- /dev/null
+++ b/ssl/test/runner/prf.go
@@ -0,0 +1,303 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"crypto"
+	"crypto/hmac"
+	"crypto/md5"
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/sha512"
+	"hash"
+)
+
+// Split a premaster secret in two as specified in RFC 4346, section 5.
+func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
+	s1 = secret[0 : (len(secret)+1)/2]
+	s2 = secret[len(secret)/2:]
+	return
+}
+
+// pHash implements the P_hash function, as defined in RFC 4346, section 5.
+func pHash(result, secret, seed []byte, hash func() hash.Hash) {
+	h := hmac.New(hash, secret)
+	h.Write(seed)
+	a := h.Sum(nil)
+
+	j := 0
+	for j < len(result) {
+		h.Reset()
+		h.Write(a)
+		h.Write(seed)
+		b := h.Sum(nil)
+		todo := len(b)
+		if j+todo > len(result) {
+			todo = len(result) - j
+		}
+		copy(result[j:j+todo], b)
+		j += todo
+
+		h.Reset()
+		h.Write(a)
+		a = h.Sum(nil)
+	}
+}
+
+// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5.
+func prf10(result, secret, label, seed []byte) {
+	hashSHA1 := sha1.New
+	hashMD5 := md5.New
+
+	labelAndSeed := make([]byte, len(label)+len(seed))
+	copy(labelAndSeed, label)
+	copy(labelAndSeed[len(label):], seed)
+
+	s1, s2 := splitPreMasterSecret(secret)
+	pHash(result, s1, labelAndSeed, hashMD5)
+	result2 := make([]byte, len(result))
+	pHash(result2, s2, labelAndSeed, hashSHA1)
+
+	for i, b := range result2 {
+		result[i] ^= b
+	}
+}
+
+// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5.
+func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) {
+	return func(result, secret, label, seed []byte) {
+		labelAndSeed := make([]byte, len(label)+len(seed))
+		copy(labelAndSeed, label)
+		copy(labelAndSeed[len(label):], seed)
+
+		pHash(result, secret, labelAndSeed, hashFunc)
+	}
+}
+
+// prf30 implements the SSL 3.0 pseudo-random function, as defined in
+// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6.
+func prf30(result, secret, label, seed []byte) {
+	hashSHA1 := sha1.New()
+	hashMD5 := md5.New()
+
+	done := 0
+	i := 0
+	// RFC5246 section 6.3 says that the largest PRF output needed is 128
+	// bytes. Since no more ciphersuites will be added to SSLv3, this will
+	// remain true. Each iteration gives us 16 bytes so 10 iterations will
+	// be sufficient.
+	var b [11]byte
+	for done < len(result) {
+		for j := 0; j <= i; j++ {
+			b[j] = 'A' + byte(i)
+		}
+
+		hashSHA1.Reset()
+		hashSHA1.Write(b[:i+1])
+		hashSHA1.Write(secret)
+		hashSHA1.Write(seed)
+		digest := hashSHA1.Sum(nil)
+
+		hashMD5.Reset()
+		hashMD5.Write(secret)
+		hashMD5.Write(digest)
+
+		done += copy(result[done:], hashMD5.Sum(nil))
+		i++
+	}
+}
+
+const (
+	tlsRandomLength      = 32 // Length of a random nonce in TLS 1.1.
+	masterSecretLength   = 48 // Length of a master secret in TLS 1.1.
+	finishedVerifyLength = 12 // Length of verify_data in a Finished message.
+)
+
+var masterSecretLabel = []byte("master secret")
+var keyExpansionLabel = []byte("key expansion")
+var clientFinishedLabel = []byte("client finished")
+var serverFinishedLabel = []byte("server finished")
+
+func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) {
+	switch version {
+	case VersionSSL30:
+		return prf30
+	case VersionTLS10, VersionTLS11:
+		return prf10
+	case VersionTLS12:
+		if suite.flags&suiteSHA384 != 0 {
+			return prf12(sha512.New384)
+		}
+		return prf12(sha256.New)
+	default:
+		panic("unknown version")
+	}
+}
+
+// masterFromPreMasterSecret generates the master secret from the pre-master
+// secret. See http://tools.ietf.org/html/rfc5246#section-8.1
+func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte {
+	var seed [tlsRandomLength * 2]byte
+	copy(seed[0:len(clientRandom)], clientRandom)
+	copy(seed[len(clientRandom):], serverRandom)
+	masterSecret := make([]byte, masterSecretLength)
+	prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:])
+	return masterSecret
+}
+
+// keysFromMasterSecret generates the connection keys from the master
+// secret, given the lengths of the MAC key, cipher key and IV, as defined in
+// RFC 2246, section 6.3.
+func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
+	var seed [tlsRandomLength * 2]byte
+	copy(seed[0:len(clientRandom)], serverRandom)
+	copy(seed[len(serverRandom):], clientRandom)
+
+	n := 2*macLen + 2*keyLen + 2*ivLen
+	keyMaterial := make([]byte, n)
+	prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:])
+	clientMAC = keyMaterial[:macLen]
+	keyMaterial = keyMaterial[macLen:]
+	serverMAC = keyMaterial[:macLen]
+	keyMaterial = keyMaterial[macLen:]
+	clientKey = keyMaterial[:keyLen]
+	keyMaterial = keyMaterial[keyLen:]
+	serverKey = keyMaterial[:keyLen]
+	keyMaterial = keyMaterial[keyLen:]
+	clientIV = keyMaterial[:ivLen]
+	keyMaterial = keyMaterial[ivLen:]
+	serverIV = keyMaterial[:ivLen]
+	return
+}
+
+func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
+	if version >= VersionTLS12 {
+		newHash := sha256.New
+		if cipherSuite.flags&suiteSHA384 != 0 {
+			newHash = sha512.New384
+		}
+
+		return finishedHash{newHash(), newHash(), nil, nil, version, prf12(newHash)}
+	}
+	return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), version, prf10}
+}
+
+// A finishedHash calculates the hash of a set of handshake messages suitable
+// for including in a Finished message.
+type finishedHash struct {
+	client hash.Hash
+	server hash.Hash
+
+	// Prior to TLS 1.2, an additional MD5 hash is required.
+	clientMD5 hash.Hash
+	serverMD5 hash.Hash
+
+	version uint16
+	prf     func(result, secret, label, seed []byte)
+}
+
+func (h finishedHash) Write(msg []byte) (n int, err error) {
+	h.client.Write(msg)
+	h.server.Write(msg)
+
+	if h.version < VersionTLS12 {
+		h.clientMD5.Write(msg)
+		h.serverMD5.Write(msg)
+	}
+	return len(msg), nil
+}
+
+// finishedSum30 calculates the contents of the verify_data member of a SSLv3
+// Finished message given the MD5 and SHA1 hashes of a set of handshake
+// messages.
+func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []byte {
+	md5.Write(magic[:])
+	md5.Write(masterSecret)
+	md5.Write(ssl30Pad1[:])
+	md5Digest := md5.Sum(nil)
+
+	md5.Reset()
+	md5.Write(masterSecret)
+	md5.Write(ssl30Pad2[:])
+	md5.Write(md5Digest)
+	md5Digest = md5.Sum(nil)
+
+	sha1.Write(magic[:])
+	sha1.Write(masterSecret)
+	sha1.Write(ssl30Pad1[:40])
+	sha1Digest := sha1.Sum(nil)
+
+	sha1.Reset()
+	sha1.Write(masterSecret)
+	sha1.Write(ssl30Pad2[:40])
+	sha1.Write(sha1Digest)
+	sha1Digest = sha1.Sum(nil)
+
+	ret := make([]byte, len(md5Digest)+len(sha1Digest))
+	copy(ret, md5Digest)
+	copy(ret[len(md5Digest):], sha1Digest)
+	return ret
+}
+
+var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54}
+var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52}
+
+// clientSum returns the contents of the verify_data member of a client's
+// Finished message.
+func (h finishedHash) clientSum(masterSecret []byte) []byte {
+	if h.version == VersionSSL30 {
+		return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic)
+	}
+
+	out := make([]byte, finishedVerifyLength)
+	if h.version >= VersionTLS12 {
+		seed := h.client.Sum(nil)
+		h.prf(out, masterSecret, clientFinishedLabel, seed)
+	} else {
+		seed := make([]byte, 0, md5.Size+sha1.Size)
+		seed = h.clientMD5.Sum(seed)
+		seed = h.client.Sum(seed)
+		h.prf(out, masterSecret, clientFinishedLabel, seed)
+	}
+	return out
+}
+
+// serverSum returns the contents of the verify_data member of a server's
+// Finished message.
+func (h finishedHash) serverSum(masterSecret []byte) []byte {
+	if h.version == VersionSSL30 {
+		return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic)
+	}
+
+	out := make([]byte, finishedVerifyLength)
+	if h.version >= VersionTLS12 {
+		seed := h.server.Sum(nil)
+		h.prf(out, masterSecret, serverFinishedLabel, seed)
+	} else {
+		seed := make([]byte, 0, md5.Size+sha1.Size)
+		seed = h.serverMD5.Sum(seed)
+		seed = h.server.Sum(seed)
+		h.prf(out, masterSecret, serverFinishedLabel, seed)
+	}
+	return out
+}
+
+// hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash
+// id suitable for signing by a TLS client certificate.
+func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash, uint8) {
+	if h.version >= VersionTLS12 {
+		digest := h.server.Sum(nil)
+		return digest, crypto.SHA256, hashSHA256
+	}
+	if sigType == signatureECDSA {
+		digest := h.server.Sum(nil)
+		return digest, crypto.SHA1, hashSHA1
+	}
+
+	digest := make([]byte, 0, 36)
+	digest = h.serverMD5.Sum(digest)
+	digest = h.server.Sum(digest)
+	return digest, crypto.MD5SHA1, 0 /* not specified in TLS 1.2. */
+}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
new file mode 100644
index 0000000..1edd00b
--- /dev/null
+++ b/ssl/test/runner/runner.go
@@ -0,0 +1,365 @@
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"io"
+	"net"
+	"os"
+	"os/exec"
+	"strings"
+	"sync"
+	"syscall"
+)
+
+var useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
+
+var rsaCertificate, ecdsaCertificate Certificate
+
+func initCertificates() {
+	var err error
+	rsaCertificate, err = LoadX509KeyPair("cert.pem", "key.pem")
+	if err != nil {
+		panic(err)
+	}
+
+	ecdsaCertificate, err = LoadX509KeyPair("ecdsa_cert.pem", "ecdsa_key.pem")
+	if err != nil {
+		panic(err)
+	}
+}
+
+var certificateOnce sync.Once
+
+func getRSACertificate() Certificate {
+	certificateOnce.Do(initCertificates)
+	return rsaCertificate
+}
+
+func getECDSACertificate() Certificate {
+	certificateOnce.Do(initCertificates)
+	return ecdsaCertificate
+}
+
+type testCase struct {
+	name          string
+	config        Config
+	shouldFail    bool
+	expectedError string
+}
+
+var clientTests = []testCase{
+	{
+		name: "BadRSASignature",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+			Bugs: ProtocolBugs{
+				InvalidSKXSignature: true,
+			},
+		},
+		shouldFail:    true,
+		expectedError: ":BAD_SIGNATURE:",
+	},
+	{
+		name: "BadECDSASignature",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+			Bugs: ProtocolBugs{
+				InvalidSKXSignature: true,
+			},
+			Certificates: []Certificate{getECDSACertificate()},
+		},
+		shouldFail:    true,
+		expectedError: ":BAD_SIGNATURE:",
+	},
+	{
+		name: "BadECDSACurve",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+			Bugs: ProtocolBugs{
+				InvalidSKXCurve: true,
+			},
+			Certificates: []Certificate{getECDSACertificate()},
+		},
+		shouldFail:    true,
+		expectedError: ":WRONG_CURVE:",
+	},
+}
+
+var testMessage = []byte("testing")
+
+func doExchange(tlsConn *Conn) error {
+	if err := tlsConn.Handshake(); err != nil {
+		return err
+	}
+	tlsConn.Write(testMessage)
+
+	buf := make([]byte, len(testMessage))
+	_, err := io.ReadFull(tlsConn, buf)
+	if err != nil {
+		return err
+	}
+
+	for i, v := range buf {
+		if v != testMessage[i]^0xff {
+			return fmt.Errorf("bad reply contents at byte %d", i)
+		}
+	}
+
+	return nil
+}
+
+func valgrindOf(dbAttach bool, baseArgs ...string) *exec.Cmd {
+	args := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full"}
+	if dbAttach {
+		args = append(args, "--db-attach=yes", "--db-command=xterm -e gdb -nw %f %p")
+	}
+	args = append(args, baseArgs...)
+
+	return exec.Command("valgrind", args...)
+}
+
+func gdbOf(baseArgs ...string) *exec.Cmd {
+	args := []string{"-e", "gdb", "--args"}
+	args = append(args, baseArgs...)
+
+	return exec.Command("xterm", args...)
+}
+
+func runTest(test *testCase) error {
+	socks, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
+	if err != nil {
+		panic(err)
+	}
+
+	syscall.CloseOnExec(socks[0])
+	syscall.CloseOnExec(socks[1])
+	clientEnd := os.NewFile(uintptr(socks[0]), "client end")
+	connFile := os.NewFile(uintptr(socks[1]), "our end")
+	conn, err := net.FileConn(connFile)
+	connFile.Close()
+	if err != nil {
+		panic(err)
+	}
+
+	const shim_path = "../../../build/ssl/test/client_shim"
+	var client *exec.Cmd
+	if *useValgrind {
+		client = valgrindOf(false, shim_path)
+	} else {
+		client = exec.Command(shim_path)
+	}
+	//client := gdbOf(shim_path)
+	client.ExtraFiles = []*os.File{clientEnd}
+	client.Stdin = os.Stdin
+	var stdoutBuf, stderrBuf bytes.Buffer
+	client.Stdout = &stdoutBuf
+	client.Stderr = &stderrBuf
+
+	if err := client.Start(); err != nil {
+		panic(err)
+	}
+	clientEnd.Close()
+
+	config := test.config
+	if len(config.Certificates) == 0 {
+		config.Certificates = []Certificate{getRSACertificate()}
+	}
+
+	tlsConn := Server(conn, &config)
+	err = doExchange(tlsConn)
+
+	conn.Close()
+	childErr := client.Wait()
+
+	stdout := string(stdoutBuf.Bytes())
+	stderr := string(stderrBuf.Bytes())
+	failed := err != nil || childErr != nil
+	correctFailure := len(test.expectedError) == 0 || strings.Contains(stdout, test.expectedError)
+
+	if failed != test.shouldFail || failed && !correctFailure {
+		localError := "none"
+		childError := "none"
+		if err != nil {
+			localError = err.Error()
+		}
+		if childErr != nil {
+			childError = childErr.Error()
+		}
+
+		var msg string
+		switch {
+		case failed && !test.shouldFail:
+			msg = "unexpected failure"
+		case !failed && test.shouldFail:
+			msg = "unexpected success"
+		case failed && !correctFailure:
+			msg = "bad error (wanted '" + test.expectedError + "')"
+		default:
+			panic("internal error")
+		}
+
+		return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s", msg, localError, childError, string(stdoutBuf.Bytes()), stderr)
+	}
+
+	if !*useValgrind && len(stderr) > 0 {
+		println(stderr)
+	}
+
+	return nil
+}
+
+var tlsVersions = []struct {
+	name    string
+	version uint16
+}{
+	{"SSL3", VersionSSL30},
+	{"TLS1", VersionTLS10},
+	{"TLS11", VersionTLS11},
+	{"TLS12", VersionTLS12},
+}
+
+var testCipherSuites = []struct {
+	name string
+	id   uint16
+}{
+	{"3DES-SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
+	{"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA},
+	{"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA},
+	{"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+	{"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
+	{"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
+	{"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
+	{"ECDHE-RSA-3DES-SHA", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
+	{"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+	{"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
+	{"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+	{"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
+	{"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+	{"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
+	{"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
+}
+
+func addCipherSuiteTests() {
+	for _, suite := range testCipherSuites {
+		var cert Certificate
+		if strings.Contains(suite.name, "ECDSA") {
+			cert = getECDSACertificate()
+		} else {
+			cert = getRSACertificate()
+		}
+
+		for _, ver := range tlsVersions {
+			if ver.version != VersionTLS12 && strings.HasSuffix(suite.name, "-GCM") {
+				continue
+			}
+
+			clientTests = append(clientTests, testCase{
+				name: ver.name + "-" + suite.name,
+				config: Config{
+					MinVersion:   ver.version,
+					MaxVersion:   ver.version,
+					CipherSuites: []uint16{suite.id},
+					Certificates: []Certificate{cert},
+				},
+			})
+		}
+	}
+}
+
+func addBadECDSASignatureTests() {
+	for badR := BadValue(1); badR < NumBadValues; badR++ {
+		for badS := BadValue(1); badS < NumBadValues; badS++ {
+			clientTests = append(clientTests, testCase{
+				name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
+				config: Config{
+					CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+					Certificates: []Certificate{getECDSACertificate()},
+					Bugs: ProtocolBugs{
+						BadECDSAR: badR,
+						BadECDSAS: badS,
+					},
+				},
+				shouldFail:    true,
+				expectedError: "SIGNATURE",
+			})
+		}
+	}
+}
+
+func worker(statusChan chan statusMsg, c chan *testCase, wg *sync.WaitGroup) {
+	defer wg.Done()
+
+	for test := range c {
+		statusChan <- statusMsg{test: test, started: true}
+		err := runTest(test)
+		statusChan <- statusMsg{test: test, err: err}
+	}
+}
+
+type statusMsg struct {
+	test    *testCase
+	started bool
+	err     error
+}
+
+func statusPrinter(doneChan chan struct{}, statusChan chan statusMsg, total int) {
+	var started, done, failed, lineLen int
+	defer close(doneChan)
+
+	for msg := range statusChan {
+		if msg.started {
+			started++
+		} else {
+			done++
+		}
+
+		fmt.Printf("\x1b[%dD\x1b[K", lineLen)
+
+		if msg.err != nil {
+			fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
+			failed++
+		}
+		line := fmt.Sprintf("%d/%d/%d/%d", failed, done, started, total)
+		lineLen = len(line)
+		os.Stdout.WriteString(line)
+	}
+}
+
+func main() {
+	var flagTest *string = flag.String("test", "", "The name of a test to run, or empty to run all tests")
+
+	flag.Parse()
+
+	addCipherSuiteTests()
+	addBadECDSASignatureTests()
+
+	var wg sync.WaitGroup
+
+	const numWorkers = 64
+
+	statusChan := make(chan statusMsg, numWorkers)
+	testChan := make(chan *testCase, numWorkers)
+	doneChan := make(chan struct{})
+
+	go statusPrinter(doneChan, statusChan, len(clientTests))
+
+	for i := 0; i < numWorkers; i++ {
+		wg.Add(1)
+		go worker(statusChan, testChan, &wg)
+	}
+
+	for i := range clientTests {
+		if len(*flagTest) == 0 || *flagTest == clientTests[i].name {
+			testChan <- &clientTests[i]
+		}
+	}
+
+	close(testChan)
+	wg.Wait()
+	close(statusChan)
+	<-doneChan
+
+	fmt.Printf("\n")
+}
diff --git a/ssl/test/runner/ticket.go b/ssl/test/runner/ticket.go
new file mode 100644
index 0000000..70e91cf
--- /dev/null
+++ b/ssl/test/runner/ticket.go
@@ -0,0 +1,182 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/hmac"
+	"crypto/sha256"
+	"crypto/subtle"
+	"errors"
+	"io"
+)
+
+// sessionState contains the information that is serialized into a session
+// ticket in order to later resume a connection.
+type sessionState struct {
+	vers         uint16
+	cipherSuite  uint16
+	masterSecret []byte
+	certificates [][]byte
+}
+
+func (s *sessionState) equal(i interface{}) bool {
+	s1, ok := i.(*sessionState)
+	if !ok {
+		return false
+	}
+
+	if s.vers != s1.vers ||
+		s.cipherSuite != s1.cipherSuite ||
+		!bytes.Equal(s.masterSecret, s1.masterSecret) {
+		return false
+	}
+
+	if len(s.certificates) != len(s1.certificates) {
+		return false
+	}
+
+	for i := range s.certificates {
+		if !bytes.Equal(s.certificates[i], s1.certificates[i]) {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (s *sessionState) marshal() []byte {
+	length := 2 + 2 + 2 + len(s.masterSecret) + 2
+	for _, cert := range s.certificates {
+		length += 4 + len(cert)
+	}
+
+	ret := make([]byte, length)
+	x := ret
+	x[0] = byte(s.vers >> 8)
+	x[1] = byte(s.vers)
+	x[2] = byte(s.cipherSuite >> 8)
+	x[3] = byte(s.cipherSuite)
+	x[4] = byte(len(s.masterSecret) >> 8)
+	x[5] = byte(len(s.masterSecret))
+	x = x[6:]
+	copy(x, s.masterSecret)
+	x = x[len(s.masterSecret):]
+
+	x[0] = byte(len(s.certificates) >> 8)
+	x[1] = byte(len(s.certificates))
+	x = x[2:]
+
+	for _, cert := range s.certificates {
+		x[0] = byte(len(cert) >> 24)
+		x[1] = byte(len(cert) >> 16)
+		x[2] = byte(len(cert) >> 8)
+		x[3] = byte(len(cert))
+		copy(x[4:], cert)
+		x = x[4+len(cert):]
+	}
+
+	return ret
+}
+
+func (s *sessionState) unmarshal(data []byte) bool {
+	if len(data) < 8 {
+		return false
+	}
+
+	s.vers = uint16(data[0])<<8 | uint16(data[1])
+	s.cipherSuite = uint16(data[2])<<8 | uint16(data[3])
+	masterSecretLen := int(data[4])<<8 | int(data[5])
+	data = data[6:]
+	if len(data) < masterSecretLen {
+		return false
+	}
+
+	s.masterSecret = data[:masterSecretLen]
+	data = data[masterSecretLen:]
+
+	if len(data) < 2 {
+		return false
+	}
+
+	numCerts := int(data[0])<<8 | int(data[1])
+	data = data[2:]
+
+	s.certificates = make([][]byte, numCerts)
+	for i := range s.certificates {
+		if len(data) < 4 {
+			return false
+		}
+		certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+		data = data[4:]
+		if certLen < 0 {
+			return false
+		}
+		if len(data) < certLen {
+			return false
+		}
+		s.certificates[i] = data[:certLen]
+		data = data[certLen:]
+	}
+
+	if len(data) > 0 {
+		return false
+	}
+
+	return true
+}
+
+func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) {
+	serialized := state.marshal()
+	encrypted := make([]byte, aes.BlockSize+len(serialized)+sha256.Size)
+	iv := encrypted[:aes.BlockSize]
+	macBytes := encrypted[len(encrypted)-sha256.Size:]
+
+	if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
+		return nil, err
+	}
+	block, err := aes.NewCipher(c.config.SessionTicketKey[:16])
+	if err != nil {
+		return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
+	}
+	cipher.NewCTR(block, iv).XORKeyStream(encrypted[aes.BlockSize:], serialized)
+
+	mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32])
+	mac.Write(encrypted[:len(encrypted)-sha256.Size])
+	mac.Sum(macBytes[:0])
+
+	return encrypted, nil
+}
+
+func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) {
+	if len(encrypted) < aes.BlockSize+sha256.Size {
+		return nil, false
+	}
+
+	iv := encrypted[:aes.BlockSize]
+	macBytes := encrypted[len(encrypted)-sha256.Size:]
+
+	mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32])
+	mac.Write(encrypted[:len(encrypted)-sha256.Size])
+	expected := mac.Sum(nil)
+
+	if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
+		return nil, false
+	}
+
+	block, err := aes.NewCipher(c.config.SessionTicketKey[:16])
+	if err != nil {
+		return nil, false
+	}
+	ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
+	plaintext := ciphertext
+	cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
+
+	state := new(sessionState)
+	ok := state.unmarshal(plaintext)
+	return state, ok
+}
diff --git a/ssl/test/runner/tls.go b/ssl/test/runner/tls.go
new file mode 100644
index 0000000..c062a41
--- /dev/null
+++ b/ssl/test/runner/tls.go
@@ -0,0 +1,275 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package tls partially implements TLS 1.2, as specified in RFC 5246.
+package main
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/pem"
+	"errors"
+	"io/ioutil"
+	"net"
+	"strings"
+	"time"
+)
+
+// Server returns a new TLS server side connection
+// using conn as the underlying transport.
+// The configuration config must be non-nil and must have
+// at least one certificate.
+func Server(conn net.Conn, config *Config) *Conn {
+	return &Conn{conn: conn, config: config}
+}
+
+// Client returns a new TLS client side connection
+// using conn as the underlying transport.
+// The config cannot be nil: users must set either ServerHostname or
+// InsecureSkipVerify in the config.
+func Client(conn net.Conn, config *Config) *Conn {
+	return &Conn{conn: conn, config: config, isClient: true}
+}
+
+// A listener implements a network listener (net.Listener) for TLS connections.
+type listener struct {
+	net.Listener
+	config *Config
+}
+
+// Accept waits for and returns the next incoming TLS connection.
+// The returned connection c is a *tls.Conn.
+func (l *listener) Accept() (c net.Conn, err error) {
+	c, err = l.Listener.Accept()
+	if err != nil {
+		return
+	}
+	c = Server(c, l.config)
+	return
+}
+
+// NewListener creates a Listener which accepts connections from an inner
+// Listener and wraps each connection with Server.
+// The configuration config must be non-nil and must have
+// at least one certificate.
+func NewListener(inner net.Listener, config *Config) net.Listener {
+	l := new(listener)
+	l.Listener = inner
+	l.config = config
+	return l
+}
+
+// Listen creates a TLS listener accepting connections on the
+// given network address using net.Listen.
+// The configuration config must be non-nil and must have
+// at least one certificate.
+func Listen(network, laddr string, config *Config) (net.Listener, error) {
+	if config == nil || len(config.Certificates) == 0 {
+		return nil, errors.New("tls.Listen: no certificates in configuration")
+	}
+	l, err := net.Listen(network, laddr)
+	if err != nil {
+		return nil, err
+	}
+	return NewListener(l, config), nil
+}
+
+type timeoutError struct{}
+
+func (timeoutError) Error() string   { return "tls: DialWithDialer timed out" }
+func (timeoutError) Timeout() bool   { return true }
+func (timeoutError) Temporary() bool { return true }
+
+// DialWithDialer connects to the given network address using dialer.Dial and
+// then initiates a TLS handshake, returning the resulting TLS connection. Any
+// timeout or deadline given in the dialer apply to connection and TLS
+// handshake as a whole.
+//
+// DialWithDialer interprets a nil configuration as equivalent to the zero
+// configuration; see the documentation of Config for the defaults.
+func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
+	// We want the Timeout and Deadline values from dialer to cover the
+	// whole process: TCP connection and TLS handshake. This means that we
+	// also need to start our own timers now.
+	timeout := dialer.Timeout
+
+	if !dialer.Deadline.IsZero() {
+		deadlineTimeout := dialer.Deadline.Sub(time.Now())
+		if timeout == 0 || deadlineTimeout < timeout {
+			timeout = deadlineTimeout
+		}
+	}
+
+	var errChannel chan error
+
+	if timeout != 0 {
+		errChannel = make(chan error, 2)
+		time.AfterFunc(timeout, func() {
+			errChannel <- timeoutError{}
+		})
+	}
+
+	rawConn, err := dialer.Dial(network, addr)
+	if err != nil {
+		return nil, err
+	}
+
+	colonPos := strings.LastIndex(addr, ":")
+	if colonPos == -1 {
+		colonPos = len(addr)
+	}
+	hostname := addr[:colonPos]
+
+	if config == nil {
+		config = defaultConfig()
+	}
+	// If no ServerName is set, infer the ServerName
+	// from the hostname we're connecting to.
+	if config.ServerName == "" {
+		// Make a copy to avoid polluting argument or default.
+		c := *config
+		c.ServerName = hostname
+		config = &c
+	}
+
+	conn := Client(rawConn, config)
+
+	if timeout == 0 {
+		err = conn.Handshake()
+	} else {
+		go func() {
+			errChannel <- conn.Handshake()
+		}()
+
+		err = <-errChannel
+	}
+
+	if err != nil {
+		rawConn.Close()
+		return nil, err
+	}
+
+	return conn, nil
+}
+
+// Dial connects to the given network address using net.Dial
+// and then initiates a TLS handshake, returning the resulting
+// TLS connection.
+// Dial interprets a nil configuration as equivalent to
+// the zero configuration; see the documentation of Config
+// for the defaults.
+func Dial(network, addr string, config *Config) (*Conn, error) {
+	return DialWithDialer(new(net.Dialer), network, addr, config)
+}
+
+// LoadX509KeyPair reads and parses a public/private key pair from a pair of
+// files. The files must contain PEM encoded data.
+func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) {
+	certPEMBlock, err := ioutil.ReadFile(certFile)
+	if err != nil {
+		return
+	}
+	keyPEMBlock, err := ioutil.ReadFile(keyFile)
+	if err != nil {
+		return
+	}
+	return X509KeyPair(certPEMBlock, keyPEMBlock)
+}
+
+// X509KeyPair parses a public/private key pair from a pair of
+// PEM encoded data.
+func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) {
+	var certDERBlock *pem.Block
+	for {
+		certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
+		if certDERBlock == nil {
+			break
+		}
+		if certDERBlock.Type == "CERTIFICATE" {
+			cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
+		}
+	}
+
+	if len(cert.Certificate) == 0 {
+		err = errors.New("crypto/tls: failed to parse certificate PEM data")
+		return
+	}
+
+	var keyDERBlock *pem.Block
+	for {
+		keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
+		if keyDERBlock == nil {
+			err = errors.New("crypto/tls: failed to parse key PEM data")
+			return
+		}
+		if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
+			break
+		}
+	}
+
+	cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
+	if err != nil {
+		return
+	}
+
+	// We don't need to parse the public key for TLS, but we so do anyway
+	// to check that it looks sane and matches the private key.
+	x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
+	if err != nil {
+		return
+	}
+
+	switch pub := x509Cert.PublicKey.(type) {
+	case *rsa.PublicKey:
+		priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
+		if !ok {
+			err = errors.New("crypto/tls: private key type does not match public key type")
+			return
+		}
+		if pub.N.Cmp(priv.N) != 0 {
+			err = errors.New("crypto/tls: private key does not match public key")
+			return
+		}
+	case *ecdsa.PublicKey:
+		priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
+		if !ok {
+			err = errors.New("crypto/tls: private key type does not match public key type")
+			return
+
+		}
+		if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
+			err = errors.New("crypto/tls: private key does not match public key")
+			return
+		}
+	default:
+		err = errors.New("crypto/tls: unknown public key algorithm")
+		return
+	}
+
+	return
+}
+
+// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
+// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
+// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
+func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
+	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
+		return key, nil
+	}
+	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
+		switch key := key.(type) {
+		case *rsa.PrivateKey, *ecdsa.PrivateKey:
+			return key, nil
+		default:
+			return nil, errors.New("crypto/tls: found unknown private key type in PKCS#8 wrapping")
+		}
+	}
+	if key, err := x509.ParseECPrivateKey(der); err == nil {
+		return key, nil
+	}
+
+	return nil, errors.New("crypto/tls: failed to parse private key")
+}
