From df1304ee03f41aed179545d1e8b4684cfd22bbdf Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor <ian@gcc.gnu.org>
Date: Wed, 25 Jan 2012 20:56:26 +0000
Subject: libgo: Update to weekly.2012-01-15.

From-SVN: r183539
---
 libgo/go/crypto/openpgp/armor/armor.go             |   4 +-
 libgo/go/crypto/openpgp/error/error.go             |  64 --
 libgo/go/crypto/openpgp/errors/errors.go           |  64 ++
 libgo/go/crypto/openpgp/keys.go                    |  55 +-
 libgo/go/crypto/openpgp/packet/compressed.go       |   4 +-
 libgo/go/crypto/openpgp/packet/encrypted_key.go    |  16 +-
 .../go/crypto/openpgp/packet/one_pass_signature.go |   8 +-
 libgo/go/crypto/openpgp/packet/packet.go           |   6 +-
 libgo/go/crypto/openpgp/packet/packet_test.go      |   4 +-
 libgo/go/crypto/openpgp/packet/private_key.go      |  35 +-
 libgo/go/crypto/openpgp/packet/public_key.go       |  48 +-
 libgo/go/crypto/openpgp/packet/reader.go           |   4 +-
 libgo/go/crypto/openpgp/packet/signature.go        | 117 +++-
 .../openpgp/packet/symmetric_key_encrypted.go      |  14 +-
 .../openpgp/packet/symmetrically_encrypted.go      |  27 +-
 .../openpgp/packet/symmetrically_encrypted_test.go |   7 +-
 libgo/go/crypto/openpgp/read.go                    |  30 +-
 libgo/go/crypto/openpgp/read_test.go               |  22 +-
 libgo/go/crypto/openpgp/s2k/s2k.go                 |   8 +-
 libgo/go/crypto/openpgp/write.go                   |  20 +-
 libgo/go/crypto/openpgp/write_test.go              |   2 +-
 libgo/go/crypto/tls/common.go                      |  32 +-
 libgo/go/crypto/tls/generate_cert.go               |   6 +-
 libgo/go/crypto/tls/handshake_client.go            |  83 ++-
 libgo/go/crypto/tls/handshake_messages.go          |  40 +-
 libgo/go/crypto/tls/handshake_server.go            |  96 ++-
 libgo/go/crypto/tls/handshake_server_test.go       | 780 +++++++++++++++++++--
 libgo/go/crypto/tls/tls.go                         |   2 +-
 libgo/go/crypto/x509/cert_pool.go                  |  10 +
 29 files changed, 1247 insertions(+), 361 deletions(-)
 delete mode 100644 libgo/go/crypto/openpgp/error/error.go
 create mode 100644 libgo/go/crypto/openpgp/errors/errors.go

(limited to 'libgo/go/crypto')

diff --git a/libgo/go/crypto/openpgp/armor/armor.go b/libgo/go/crypto/openpgp/armor/armor.go
index 3bbb5dc..96957ab 100644
--- a/libgo/go/crypto/openpgp/armor/armor.go
+++ b/libgo/go/crypto/openpgp/armor/armor.go
@@ -9,7 +9,7 @@ package armor
 import (
 	"bufio"
 	"bytes"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"encoding/base64"
 	"io"
 )
@@ -35,7 +35,7 @@ type Block struct {
 	oReader openpgpReader
 }
 
-var ArmorCorrupt error = error_.StructuralError("armor invalid")
+var ArmorCorrupt error = errors.StructuralError("armor invalid")
 
 const crc24Init = 0xb704ce
 const crc24Poly = 0x1864cfb
diff --git a/libgo/go/crypto/openpgp/error/error.go b/libgo/go/crypto/openpgp/error/error.go
deleted file mode 100644
index ceeb054..0000000
--- a/libgo/go/crypto/openpgp/error/error.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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 error contains common error types for the OpenPGP packages.
-package error
-
-import (
-	"strconv"
-)
-
-// A StructuralError is returned when OpenPGP data is found to be syntactically
-// invalid.
-type StructuralError string
-
-func (s StructuralError) Error() string {
-	return "OpenPGP data invalid: " + string(s)
-}
-
-// UnsupportedError indicates that, although the OpenPGP data is valid, it
-// makes use of currently unimplemented features.
-type UnsupportedError string
-
-func (s UnsupportedError) Error() string {
-	return "OpenPGP feature unsupported: " + string(s)
-}
-
-// InvalidArgumentError indicates that the caller is in error and passed an
-// incorrect value.
-type InvalidArgumentError string
-
-func (i InvalidArgumentError) Error() string {
-	return "OpenPGP argument invalid: " + string(i)
-}
-
-// SignatureError indicates that a syntactically valid signature failed to
-// validate.
-type SignatureError string
-
-func (b SignatureError) Error() string {
-	return "OpenPGP signature invalid: " + string(b)
-}
-
-type keyIncorrectError int
-
-func (ki keyIncorrectError) Error() string {
-	return "the given key was incorrect"
-}
-
-var KeyIncorrectError = keyIncorrectError(0)
-
-type unknownIssuerError int
-
-func (unknownIssuerError) Error() string {
-	return "signature make by unknown entity"
-}
-
-var UnknownIssuerError = unknownIssuerError(0)
-
-type UnknownPacketTypeError uint8
-
-func (upte UnknownPacketTypeError) Error() string {
-	return "unknown OpenPGP packet type: " + strconv.Itoa(int(upte))
-}
diff --git a/libgo/go/crypto/openpgp/errors/errors.go b/libgo/go/crypto/openpgp/errors/errors.go
new file mode 100644
index 0000000..c434b76
--- /dev/null
+++ b/libgo/go/crypto/openpgp/errors/errors.go
@@ -0,0 +1,64 @@
+// 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 errors contains common error types for the OpenPGP packages.
+package errors
+
+import (
+	"strconv"
+)
+
+// A StructuralError is returned when OpenPGP data is found to be syntactically
+// invalid.
+type StructuralError string
+
+func (s StructuralError) Error() string {
+	return "OpenPGP data invalid: " + string(s)
+}
+
+// UnsupportedError indicates that, although the OpenPGP data is valid, it
+// makes use of currently unimplemented features.
+type UnsupportedError string
+
+func (s UnsupportedError) Error() string {
+	return "OpenPGP feature unsupported: " + string(s)
+}
+
+// InvalidArgumentError indicates that the caller is in error and passed an
+// incorrect value.
+type InvalidArgumentError string
+
+func (i InvalidArgumentError) Error() string {
+	return "OpenPGP argument invalid: " + string(i)
+}
+
+// SignatureError indicates that a syntactically valid signature failed to
+// validate.
+type SignatureError string
+
+func (b SignatureError) Error() string {
+	return "OpenPGP signature invalid: " + string(b)
+}
+
+type keyIncorrectError int
+
+func (ki keyIncorrectError) Error() string {
+	return "the given key was incorrect"
+}
+
+var KeyIncorrectError = keyIncorrectError(0)
+
+type unknownIssuerError int
+
+func (unknownIssuerError) Error() string {
+	return "signature make by unknown entity"
+}
+
+var UnknownIssuerError = unknownIssuerError(0)
+
+type UnknownPacketTypeError uint8
+
+func (upte UnknownPacketTypeError) Error() string {
+	return "unknown OpenPGP packet type: " + strconv.Itoa(int(upte))
+}
diff --git a/libgo/go/crypto/openpgp/keys.go b/libgo/go/crypto/openpgp/keys.go
index 74e7d23..624a5ea 100644
--- a/libgo/go/crypto/openpgp/keys.go
+++ b/libgo/go/crypto/openpgp/keys.go
@@ -7,8 +7,9 @@ package openpgp
 import (
 	"crypto"
 	"crypto/openpgp/armor"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/openpgp/packet"
+	"crypto/rand"
 	"crypto/rsa"
 	"io"
 	"time"
@@ -181,13 +182,13 @@ func (el EntityList) DecryptionKeys() (keys []Key) {
 func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
 	block, err := armor.Decode(r)
 	if err == io.EOF {
-		return nil, error_.InvalidArgumentError("no armored data found")
+		return nil, errors.InvalidArgumentError("no armored data found")
 	}
 	if err != nil {
 		return nil, err
 	}
 	if block.Type != PublicKeyType && block.Type != PrivateKeyType {
-		return nil, error_.InvalidArgumentError("expected public or private key block, got: " + block.Type)
+		return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type)
 	}
 
 	return ReadKeyRing(block.Body)
@@ -203,7 +204,7 @@ func ReadKeyRing(r io.Reader) (el EntityList, err error) {
 		var e *Entity
 		e, err = readEntity(packets)
 		if err != nil {
-			if _, ok := err.(error_.UnsupportedError); ok {
+			if _, ok := err.(errors.UnsupportedError); ok {
 				lastUnsupportedError = err
 				err = readToNextPublicKey(packets)
 			}
@@ -235,7 +236,7 @@ func readToNextPublicKey(packets *packet.Reader) (err error) {
 		if err == io.EOF {
 			return
 		} else if err != nil {
-			if _, ok := err.(error_.UnsupportedError); ok {
+			if _, ok := err.(errors.UnsupportedError); ok {
 				err = nil
 				continue
 			}
@@ -266,14 +267,14 @@ func readEntity(packets *packet.Reader) (*Entity, error) {
 	if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
 		if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
 			packets.Unread(p)
-			return nil, error_.StructuralError("first packet was not a public/private key")
+			return nil, errors.StructuralError("first packet was not a public/private key")
 		} else {
 			e.PrimaryKey = &e.PrivateKey.PublicKey
 		}
 	}
 
 	if !e.PrimaryKey.PubKeyAlgo.CanSign() {
-		return nil, error_.StructuralError("primary key cannot be used for signatures")
+		return nil, errors.StructuralError("primary key cannot be used for signatures")
 	}
 
 	var current *Identity
@@ -303,12 +304,12 @@ EachPacket:
 
 				sig, ok := p.(*packet.Signature)
 				if !ok {
-					return nil, error_.StructuralError("user ID packet not followed by self-signature")
+					return nil, errors.StructuralError("user ID packet not followed by self-signature")
 				}
 
 				if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
 					if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, sig); err != nil {
-						return nil, error_.StructuralError("user ID self-signature invalid: " + err.Error())
+						return nil, errors.StructuralError("user ID self-signature invalid: " + err.Error())
 					}
 					current.SelfSignature = sig
 					break
@@ -317,7 +318,7 @@ EachPacket:
 			}
 		case *packet.Signature:
 			if current == nil {
-				return nil, error_.StructuralError("signature packet found before user id packet")
+				return nil, errors.StructuralError("signature packet found before user id packet")
 			}
 			current.Signatures = append(current.Signatures, pkt)
 		case *packet.PrivateKey:
@@ -344,7 +345,7 @@ EachPacket:
 	}
 
 	if len(e.Identities) == 0 {
-		return nil, error_.StructuralError("entity without any identities")
+		return nil, errors.StructuralError("entity without any identities")
 	}
 
 	return e, nil
@@ -359,19 +360,19 @@ func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *p
 		return io.ErrUnexpectedEOF
 	}
 	if err != nil {
-		return error_.StructuralError("subkey signature invalid: " + err.Error())
+		return errors.StructuralError("subkey signature invalid: " + err.Error())
 	}
 	var ok bool
 	subKey.Sig, ok = p.(*packet.Signature)
 	if !ok {
-		return error_.StructuralError("subkey packet not followed by signature")
+		return errors.StructuralError("subkey packet not followed by signature")
 	}
 	if subKey.Sig.SigType != packet.SigTypeSubkeyBinding {
-		return error_.StructuralError("subkey signature with wrong type")
+		return errors.StructuralError("subkey signature with wrong type")
 	}
 	err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig)
 	if err != nil {
-		return error_.StructuralError("subkey signature invalid: " + err.Error())
+		return errors.StructuralError("subkey signature invalid: " + err.Error())
 	}
 	e.Subkeys = append(e.Subkeys, subKey)
 	return nil
@@ -385,7 +386,7 @@ const defaultRSAKeyBits = 2048
 func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email string) (*Entity, error) {
 	uid := packet.NewUserId(name, comment, email)
 	if uid == nil {
-		return nil, error_.InvalidArgumentError("user id field contained invalid characters")
+		return nil, errors.InvalidArgumentError("user id field contained invalid characters")
 	}
 	signingPriv, err := rsa.GenerateKey(rand, defaultRSAKeyBits)
 	if err != nil {
@@ -397,8 +398,8 @@ func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email strin
 	}
 
 	e := &Entity{
-		PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey, false /* not a subkey */ ),
-		PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv, false /* not a subkey */ ),
+		PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey),
+		PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv),
 		Identities: make(map[string]*Identity),
 	}
 	isPrimaryId := true
@@ -420,8 +421,8 @@ func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email strin
 
 	e.Subkeys = make([]Subkey, 1)
 	e.Subkeys[0] = Subkey{
-		PublicKey:  packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey, true /* is a subkey */ ),
-		PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv, true /* is a subkey */ ),
+		PublicKey:  packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
+		PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv),
 		Sig: &packet.Signature{
 			CreationTime:              currentTime,
 			SigType:                   packet.SigTypeSubkeyBinding,
@@ -433,6 +434,8 @@ func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email strin
 			IssuerKeyId:               &e.PrimaryKey.KeyId,
 		},
 	}
+	e.Subkeys[0].PublicKey.IsSubkey = true
+	e.Subkeys[0].PrivateKey.IsSubkey = true
 
 	return e, nil
 }
@@ -450,7 +453,7 @@ func (e *Entity) SerializePrivate(w io.Writer) (err error) {
 		if err != nil {
 			return
 		}
-		err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey)
+		err = ident.SelfSignature.SignUserId(rand.Reader, ident.UserId.Id, e.PrimaryKey, e.PrivateKey)
 		if err != nil {
 			return
 		}
@@ -464,7 +467,7 @@ func (e *Entity) SerializePrivate(w io.Writer) (err error) {
 		if err != nil {
 			return
 		}
-		err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey)
+		err = subkey.Sig.SignKey(rand.Reader, subkey.PublicKey, e.PrivateKey)
 		if err != nil {
 			return
 		}
@@ -518,14 +521,14 @@ func (e *Entity) Serialize(w io.Writer) error {
 // necessary.
 func (e *Entity) SignIdentity(identity string, signer *Entity) error {
 	if signer.PrivateKey == nil {
-		return error_.InvalidArgumentError("signing Entity must have a private key")
+		return errors.InvalidArgumentError("signing Entity must have a private key")
 	}
 	if signer.PrivateKey.Encrypted {
-		return error_.InvalidArgumentError("signing Entity's private key must be decrypted")
+		return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
 	}
 	ident, ok := e.Identities[identity]
 	if !ok {
-		return error_.InvalidArgumentError("given identity string not found in Entity")
+		return errors.InvalidArgumentError("given identity string not found in Entity")
 	}
 
 	sig := &packet.Signature{
@@ -535,7 +538,7 @@ func (e *Entity) SignIdentity(identity string, signer *Entity) error {
 		CreationTime: time.Now(),
 		IssuerKeyId:  &signer.PrivateKey.KeyId,
 	}
-	if err := sig.SignKey(e.PrimaryKey, signer.PrivateKey); err != nil {
+	if err := sig.SignKey(rand.Reader, e.PrimaryKey, signer.PrivateKey); err != nil {
 		return err
 	}
 	ident.Signatures = append(ident.Signatures, sig)
diff --git a/libgo/go/crypto/openpgp/packet/compressed.go b/libgo/go/crypto/openpgp/packet/compressed.go
index f80d798..36736e3 100644
--- a/libgo/go/crypto/openpgp/packet/compressed.go
+++ b/libgo/go/crypto/openpgp/packet/compressed.go
@@ -7,7 +7,7 @@ package packet
 import (
 	"compress/flate"
 	"compress/zlib"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"io"
 	"strconv"
 )
@@ -31,7 +31,7 @@ func (c *Compressed) parse(r io.Reader) error {
 	case 2:
 		c.Body, err = zlib.NewReader(r)
 	default:
-		err = error_.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0])))
+		err = errors.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0])))
 	}
 
 	return err
diff --git a/libgo/go/crypto/openpgp/packet/encrypted_key.go b/libgo/go/crypto/openpgp/packet/encrypted_key.go
index b24fa3a..479a643 100644
--- a/libgo/go/crypto/openpgp/packet/encrypted_key.go
+++ b/libgo/go/crypto/openpgp/packet/encrypted_key.go
@@ -6,7 +6,7 @@ package packet
 
 import (
 	"crypto/openpgp/elgamal"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/rand"
 	"crypto/rsa"
 	"encoding/binary"
@@ -35,7 +35,7 @@ func (e *EncryptedKey) parse(r io.Reader) (err error) {
 		return
 	}
 	if buf[0] != encryptedKeyVersion {
-		return error_.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
+		return errors.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
 	}
 	e.KeyId = binary.BigEndian.Uint64(buf[1:9])
 	e.Algo = PublicKeyAlgorithm(buf[9])
@@ -77,7 +77,7 @@ func (e *EncryptedKey) Decrypt(priv *PrivateKey) error {
 		c2 := new(big.Int).SetBytes(e.encryptedMPI2)
 		b, err = elgamal.Decrypt(priv.PrivateKey.(*elgamal.PrivateKey), c1, c2)
 	default:
-		err = error_.InvalidArgumentError("cannot decrypted encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
+		err = errors.InvalidArgumentError("cannot decrypted encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
 	}
 
 	if err != nil {
@@ -89,7 +89,7 @@ func (e *EncryptedKey) Decrypt(priv *PrivateKey) error {
 	expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
 	checksum := checksumKeyMaterial(e.Key)
 	if checksum != expectedChecksum {
-		return error_.StructuralError("EncryptedKey checksum incorrect")
+		return errors.StructuralError("EncryptedKey checksum incorrect")
 	}
 
 	return nil
@@ -116,16 +116,16 @@ func SerializeEncryptedKey(w io.Writer, rand io.Reader, pub *PublicKey, cipherFu
 	case PubKeyAlgoElGamal:
 		return serializeEncryptedKeyElGamal(w, rand, buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
 	case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly:
-		return error_.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
+		return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
 	}
 
-	return error_.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
+	return errors.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
 }
 
 func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub *rsa.PublicKey, keyBlock []byte) error {
 	cipherText, err := rsa.EncryptPKCS1v15(rand, pub, keyBlock)
 	if err != nil {
-		return error_.InvalidArgumentError("RSA encryption failed: " + err.Error())
+		return errors.InvalidArgumentError("RSA encryption failed: " + err.Error())
 	}
 
 	packetLen := 10 /* header length */ + 2 /* mpi size */ + len(cipherText)
@@ -144,7 +144,7 @@ func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub
 func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, pub *elgamal.PublicKey, keyBlock []byte) error {
 	c1, c2, err := elgamal.Encrypt(rand, pub, keyBlock)
 	if err != nil {
-		return error_.InvalidArgumentError("ElGamal encryption failed: " + err.Error())
+		return errors.InvalidArgumentError("ElGamal encryption failed: " + err.Error())
 	}
 
 	packetLen := 10 /* header length */
diff --git a/libgo/go/crypto/openpgp/packet/one_pass_signature.go b/libgo/go/crypto/openpgp/packet/one_pass_signature.go
index 13e6aa5..822cfe9 100644
--- a/libgo/go/crypto/openpgp/packet/one_pass_signature.go
+++ b/libgo/go/crypto/openpgp/packet/one_pass_signature.go
@@ -6,7 +6,7 @@ package packet
 
 import (
 	"crypto"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/openpgp/s2k"
 	"encoding/binary"
 	"io"
@@ -33,13 +33,13 @@ func (ops *OnePassSignature) parse(r io.Reader) (err error) {
 		return
 	}
 	if buf[0] != onePassSignatureVersion {
-		err = error_.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0])))
+		err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0])))
 	}
 
 	var ok bool
 	ops.Hash, ok = s2k.HashIdToHash(buf[2])
 	if !ok {
-		return error_.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2])))
+		return errors.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2])))
 	}
 
 	ops.SigType = SignatureType(buf[1])
@@ -57,7 +57,7 @@ func (ops *OnePassSignature) Serialize(w io.Writer) error {
 	var ok bool
 	buf[2], ok = s2k.HashToHashId(ops.Hash)
 	if !ok {
-		return error_.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash)))
+		return errors.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash)))
 	}
 	buf[3] = uint8(ops.PubKeyAlgo)
 	binary.BigEndian.PutUint64(buf[4:12], ops.KeyId)
diff --git a/libgo/go/crypto/openpgp/packet/packet.go b/libgo/go/crypto/openpgp/packet/packet.go
index 778df15..f7c1964 100644
--- a/libgo/go/crypto/openpgp/packet/packet.go
+++ b/libgo/go/crypto/openpgp/packet/packet.go
@@ -10,7 +10,7 @@ import (
 	"crypto/aes"
 	"crypto/cast5"
 	"crypto/cipher"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"io"
 	"math/big"
 )
@@ -162,7 +162,7 @@ func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader,
 		return
 	}
 	if buf[0]&0x80 == 0 {
-		err = error_.StructuralError("tag byte does not have MSB set")
+		err = errors.StructuralError("tag byte does not have MSB set")
 		return
 	}
 	if buf[0]&0x40 == 0 {
@@ -337,7 +337,7 @@ func Read(r io.Reader) (p Packet, err error) {
 		se.MDC = true
 		p = se
 	default:
-		err = error_.UnknownPacketTypeError(tag)
+		err = errors.UnknownPacketTypeError(tag)
 	}
 	if p != nil {
 		err = p.parse(contents)
diff --git a/libgo/go/crypto/openpgp/packet/packet_test.go b/libgo/go/crypto/openpgp/packet/packet_test.go
index 5326641..e4b8691 100644
--- a/libgo/go/crypto/openpgp/packet/packet_test.go
+++ b/libgo/go/crypto/openpgp/packet/packet_test.go
@@ -6,7 +6,7 @@ package packet
 
 import (
 	"bytes"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"encoding/hex"
 	"fmt"
 	"io"
@@ -152,7 +152,7 @@ func TestReadHeader(t *testing.T) {
 	for i, test := range readHeaderTests {
 		tag, length, contents, err := readHeader(readerFromHex(test.hexInput))
 		if test.structuralError {
-			if _, ok := err.(error_.StructuralError); ok {
+			if _, ok := err.(errors.StructuralError); ok {
 				continue
 			}
 			t.Errorf("%d: expected StructuralError, got:%s", i, err)
diff --git a/libgo/go/crypto/openpgp/packet/private_key.go b/libgo/go/crypto/openpgp/packet/private_key.go
index d67e968..5a90d06 100644
--- a/libgo/go/crypto/openpgp/packet/private_key.go
+++ b/libgo/go/crypto/openpgp/packet/private_key.go
@@ -9,7 +9,7 @@ import (
 	"crypto/cipher"
 	"crypto/dsa"
 	"crypto/openpgp/elgamal"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/openpgp/s2k"
 	"crypto/rsa"
 	"crypto/sha1"
@@ -28,14 +28,21 @@ type PrivateKey struct {
 	encryptedData []byte
 	cipher        CipherFunction
 	s2k           func(out, in []byte)
-	PrivateKey    interface{} // An *rsa.PrivateKey.
+	PrivateKey    interface{} // An *rsa.PrivateKey or *dsa.PrivateKey.
 	sha1Checksum  bool
 	iv            []byte
 }
 
-func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey, isSubkey bool) *PrivateKey {
+func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
 	pk := new(PrivateKey)
-	pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey, isSubkey)
+	pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey)
+	pk.PrivateKey = priv
+	return pk
+}
+
+func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
+	pk := new(PrivateKey)
+	pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey)
 	pk.PrivateKey = priv
 	return pk
 }
@@ -72,13 +79,13 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) {
 			pk.sha1Checksum = true
 		}
 	default:
-		return error_.UnsupportedError("deprecated s2k function in private key")
+		return errors.UnsupportedError("deprecated s2k function in private key")
 	}
 
 	if pk.Encrypted {
 		blockSize := pk.cipher.blockSize()
 		if blockSize == 0 {
-			return error_.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
+			return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
 		}
 		pk.iv = make([]byte, blockSize)
 		_, err = readFull(r, pk.iv)
@@ -121,8 +128,10 @@ func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
 	switch priv := pk.PrivateKey.(type) {
 	case *rsa.PrivateKey:
 		err = serializeRSAPrivateKey(privateKeyBuf, priv)
+	case *dsa.PrivateKey:
+		err = serializeDSAPrivateKey(privateKeyBuf, priv)
 	default:
-		err = error_.InvalidArgumentError("non-RSA private key")
+		err = errors.InvalidArgumentError("unknown private key type")
 	}
 	if err != nil {
 		return
@@ -172,6 +181,10 @@ func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
 	return writeBig(w, priv.Precomputed.Qinv)
 }
 
+func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
+	return writeBig(w, priv.X)
+}
+
 // Decrypt decrypts an encrypted private key using a passphrase.
 func (pk *PrivateKey) Decrypt(passphrase []byte) error {
 	if !pk.Encrypted {
@@ -188,18 +201,18 @@ func (pk *PrivateKey) Decrypt(passphrase []byte) error {
 
 	if pk.sha1Checksum {
 		if len(data) < sha1.Size {
-			return error_.StructuralError("truncated private key data")
+			return errors.StructuralError("truncated private key data")
 		}
 		h := sha1.New()
 		h.Write(data[:len(data)-sha1.Size])
 		sum := h.Sum(nil)
 		if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
-			return error_.StructuralError("private key checksum failure")
+			return errors.StructuralError("private key checksum failure")
 		}
 		data = data[:len(data)-sha1.Size]
 	} else {
 		if len(data) < 2 {
-			return error_.StructuralError("truncated private key data")
+			return errors.StructuralError("truncated private key data")
 		}
 		var sum uint16
 		for i := 0; i < len(data)-2; i++ {
@@ -207,7 +220,7 @@ func (pk *PrivateKey) Decrypt(passphrase []byte) error {
 		}
 		if data[len(data)-2] != uint8(sum>>8) ||
 			data[len(data)-1] != uint8(sum) {
-			return error_.StructuralError("private key checksum failure")
+			return errors.StructuralError("private key checksum failure")
 		}
 		data = data[:len(data)-2]
 	}
diff --git a/libgo/go/crypto/openpgp/packet/public_key.go b/libgo/go/crypto/openpgp/packet/public_key.go
index 9aa30e0..ba178b5 100644
--- a/libgo/go/crypto/openpgp/packet/public_key.go
+++ b/libgo/go/crypto/openpgp/packet/public_key.go
@@ -7,7 +7,7 @@ package packet
 import (
 	"crypto/dsa"
 	"crypto/openpgp/elgamal"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/rsa"
 	"crypto/sha1"
 	"encoding/binary"
@@ -39,12 +39,11 @@ func fromBig(n *big.Int) parsedMPI {
 }
 
 // NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
-func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey, isSubkey bool) *PublicKey {
+func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
 	pk := &PublicKey{
 		CreationTime: creationTime,
 		PubKeyAlgo:   PubKeyAlgoRSA,
 		PublicKey:    pub,
-		IsSubkey:     isSubkey,
 		n:            fromBig(pub.N),
 		e:            fromBig(big.NewInt(int64(pub.E))),
 	}
@@ -53,6 +52,22 @@ func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey, isSubkey bool)
 	return pk
 }
 
+// NewDSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
+func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
+	pk := &PublicKey{
+		CreationTime: creationTime,
+		PubKeyAlgo:   PubKeyAlgoDSA,
+		PublicKey:    pub,
+		p:            fromBig(pub.P),
+		q:            fromBig(pub.Q),
+		g:            fromBig(pub.G),
+		y:            fromBig(pub.Y),
+	}
+
+	pk.setFingerPrintAndKeyId()
+	return pk
+}
+
 func (pk *PublicKey) parse(r io.Reader) (err error) {
 	// RFC 4880, section 5.5.2
 	var buf [6]byte
@@ -61,7 +76,7 @@ func (pk *PublicKey) parse(r io.Reader) (err error) {
 		return
 	}
 	if buf[0] != 4 {
-		return error_.UnsupportedError("public key version")
+		return errors.UnsupportedError("public key version")
 	}
 	pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
 	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
@@ -73,7 +88,7 @@ func (pk *PublicKey) parse(r io.Reader) (err error) {
 	case PubKeyAlgoElGamal:
 		err = pk.parseElGamal(r)
 	default:
-		err = error_.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
+		err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
 	}
 	if err != nil {
 		return
@@ -105,7 +120,7 @@ func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
 	}
 
 	if len(pk.e.bytes) > 3 {
-		err = error_.UnsupportedError("large public exponent")
+		err = errors.UnsupportedError("large public exponent")
 		return
 	}
 	rsa := &rsa.PublicKey{
@@ -255,7 +270,7 @@ func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
 	case PubKeyAlgoElGamal:
 		return writeMPIs(w, pk.p, pk.g, pk.y)
 	}
-	return error_.InvalidArgumentError("bad public-key algorithm")
+	return errors.InvalidArgumentError("bad public-key algorithm")
 }
 
 // CanSign returns true iff this public key can generate signatures
@@ -267,18 +282,18 @@ func (pk *PublicKey) CanSign() bool {
 // public key, of the data hashed into signed. signed is mutated by this call.
 func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
 	if !pk.CanSign() {
-		return error_.InvalidArgumentError("public key cannot generate signatures")
+		return errors.InvalidArgumentError("public key cannot generate signatures")
 	}
 
 	signed.Write(sig.HashSuffix)
 	hashBytes := signed.Sum(nil)
 
 	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
-		return error_.SignatureError("hash tag doesn't match")
+		return errors.SignatureError("hash tag doesn't match")
 	}
 
 	if pk.PubKeyAlgo != sig.PubKeyAlgo {
-		return error_.InvalidArgumentError("public key and signature use different algorithms")
+		return errors.InvalidArgumentError("public key and signature use different algorithms")
 	}
 
 	switch pk.PubKeyAlgo {
@@ -286,13 +301,18 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro
 		rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
 		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes)
 		if err != nil {
-			return error_.SignatureError("RSA verification failure")
+			return errors.SignatureError("RSA verification failure")
 		}
 		return nil
 	case PubKeyAlgoDSA:
 		dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
+		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
+		if len(hashBytes) > subgroupSize {
+			hashBytes = hashBytes[:subgroupSize]
+		}
 		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
-			return error_.SignatureError("DSA verification failure")
+			return errors.SignatureError("DSA verification failure")
 		}
 		return nil
 	default:
@@ -306,7 +326,7 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro
 func keySignatureHash(pk, signed *PublicKey, sig *Signature) (h hash.Hash, err error) {
 	h = sig.Hash.New()
 	if h == nil {
-		return nil, error_.UnsupportedError("hash function")
+		return nil, errors.UnsupportedError("hash function")
 	}
 
 	// RFC 4880, section 5.2.4
@@ -332,7 +352,7 @@ func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) (err
 func userIdSignatureHash(id string, pk *PublicKey, sig *Signature) (h hash.Hash, err error) {
 	h = sig.Hash.New()
 	if h == nil {
-		return nil, error_.UnsupportedError("hash function")
+		return nil, errors.UnsupportedError("hash function")
 	}
 
 	// RFC 4880, section 5.2.4
diff --git a/libgo/go/crypto/openpgp/packet/reader.go b/libgo/go/crypto/openpgp/packet/reader.go
index e3d733c..1a3e8e2 100644
--- a/libgo/go/crypto/openpgp/packet/reader.go
+++ b/libgo/go/crypto/openpgp/packet/reader.go
@@ -5,7 +5,7 @@
 package packet
 
 import (
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"io"
 )
 
@@ -34,7 +34,7 @@ func (r *Reader) Next() (p Packet, err error) {
 			r.readers = r.readers[:len(r.readers)-1]
 			continue
 		}
-		if _, ok := err.(error_.UnknownPacketTypeError); !ok {
+		if _, ok := err.(errors.UnknownPacketTypeError); !ok {
 			return nil, err
 		}
 	}
diff --git a/libgo/go/crypto/openpgp/packet/signature.go b/libgo/go/crypto/openpgp/packet/signature.go
index 1cdc1ee..c3ffb3a 100644
--- a/libgo/go/crypto/openpgp/packet/signature.go
+++ b/libgo/go/crypto/openpgp/packet/signature.go
@@ -7,9 +7,8 @@ package packet
 import (
 	"crypto"
 	"crypto/dsa"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/openpgp/s2k"
-	"crypto/rand"
 	"crypto/rsa"
 	"encoding/binary"
 	"hash"
@@ -61,7 +60,7 @@ func (sig *Signature) parse(r io.Reader) (err error) {
 		return
 	}
 	if buf[0] != 4 {
-		err = error_.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
+		err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
 		return
 	}
 
@@ -74,14 +73,14 @@ func (sig *Signature) parse(r io.Reader) (err error) {
 	switch sig.PubKeyAlgo {
 	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA:
 	default:
-		err = error_.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
+		err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
 		return
 	}
 
 	var ok bool
 	sig.Hash, ok = s2k.HashIdToHash(buf[2])
 	if !ok {
-		return error_.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
+		return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
 	}
 
 	hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4])
@@ -153,7 +152,7 @@ func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool)
 	}
 
 	if sig.CreationTime.IsZero() {
-		err = error_.StructuralError("no creation time in signature")
+		err = errors.StructuralError("no creation time in signature")
 	}
 
 	return
@@ -164,7 +163,7 @@ type signatureSubpacketType uint8
 const (
 	creationTimeSubpacket        signatureSubpacketType = 2
 	signatureExpirationSubpacket signatureSubpacketType = 3
-	keyExpirySubpacket           signatureSubpacketType = 9
+	keyExpirationSubpacket       signatureSubpacketType = 9
 	prefSymmetricAlgosSubpacket  signatureSubpacketType = 11
 	issuerSubpacket              signatureSubpacketType = 16
 	prefHashAlgosSubpacket       signatureSubpacketType = 21
@@ -207,7 +206,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
 	rest = subpacket[length:]
 	subpacket = subpacket[:length]
 	if len(subpacket) == 0 {
-		err = error_.StructuralError("zero length signature subpacket")
+		err = errors.StructuralError("zero length signature subpacket")
 		return
 	}
 	packetType = signatureSubpacketType(subpacket[0] & 0x7f)
@@ -217,37 +216,33 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
 	switch packetType {
 	case creationTimeSubpacket:
 		if !isHashed {
-			err = error_.StructuralError("signature creation time in non-hashed area")
+			err = errors.StructuralError("signature creation time in non-hashed area")
 			return
 		}
 		if len(subpacket) != 4 {
-			err = error_.StructuralError("signature creation time not four bytes")
+			err = errors.StructuralError("signature creation time not four bytes")
 			return
 		}
 		t := binary.BigEndian.Uint32(subpacket)
-		if t == 0 {
-			sig.CreationTime = time.Time{}
-		} else {
-			sig.CreationTime = time.Unix(int64(t), 0)
-		}
+		sig.CreationTime = time.Unix(int64(t), 0)
 	case signatureExpirationSubpacket:
 		// Signature expiration time, section 5.2.3.10
 		if !isHashed {
 			return
 		}
 		if len(subpacket) != 4 {
-			err = error_.StructuralError("expiration subpacket with bad length")
+			err = errors.StructuralError("expiration subpacket with bad length")
 			return
 		}
 		sig.SigLifetimeSecs = new(uint32)
 		*sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
-	case keyExpirySubpacket:
+	case keyExpirationSubpacket:
 		// Key expiration time, section 5.2.3.6
 		if !isHashed {
 			return
 		}
 		if len(subpacket) != 4 {
-			err = error_.StructuralError("key expiration subpacket with bad length")
+			err = errors.StructuralError("key expiration subpacket with bad length")
 			return
 		}
 		sig.KeyLifetimeSecs = new(uint32)
@@ -262,7 +257,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
 	case issuerSubpacket:
 		// Issuer, section 5.2.3.5
 		if len(subpacket) != 8 {
-			err = error_.StructuralError("issuer subpacket with bad length")
+			err = errors.StructuralError("issuer subpacket with bad length")
 			return
 		}
 		sig.IssuerKeyId = new(uint64)
@@ -287,7 +282,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
 			return
 		}
 		if len(subpacket) != 1 {
-			err = error_.StructuralError("primary user id subpacket with bad length")
+			err = errors.StructuralError("primary user id subpacket with bad length")
 			return
 		}
 		sig.IsPrimaryId = new(bool)
@@ -300,7 +295,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
 			return
 		}
 		if len(subpacket) == 0 {
-			err = error_.StructuralError("empty key flags subpacket")
+			err = errors.StructuralError("empty key flags subpacket")
 			return
 		}
 		sig.FlagsValid = true
@@ -319,14 +314,14 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
 
 	default:
 		if isCritical {
-			err = error_.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
+			err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
 			return
 		}
 	}
 	return
 
 Truncated:
-	err = error_.StructuralError("signature subpacket truncated")
+	err = errors.StructuralError("signature subpacket truncated")
 	return
 }
 
@@ -401,7 +396,7 @@ func (sig *Signature) buildHashSuffix() (err error) {
 	sig.HashSuffix[3], ok = s2k.HashToHashId(sig.Hash)
 	if !ok {
 		sig.HashSuffix = nil
-		return error_.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
+		return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
 	}
 	sig.HashSuffix[4] = byte(hashedSubpacketsLen >> 8)
 	sig.HashSuffix[5] = byte(hashedSubpacketsLen)
@@ -431,7 +426,7 @@ func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
 // Sign signs a message with a private key. The hash, h, must contain
 // the hash of the message to be signed and will be mutated by this function.
 // On success, the signature is stored in sig. Call Serialize to write it out.
-func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey) (err error) {
+func (sig *Signature) Sign(rand io.Reader, h hash.Hash, priv *PrivateKey) (err error) {
 	sig.outSubpackets = sig.buildSubpackets()
 	digest, err := sig.signPrepareHash(h)
 	if err != nil {
@@ -440,10 +435,17 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey) (err error) {
 
 	switch priv.PubKeyAlgo {
 	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
-		sig.RSASignature.bytes, err = rsa.SignPKCS1v15(rand.Reader, priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest)
+		sig.RSASignature.bytes, err = rsa.SignPKCS1v15(rand, priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest)
 		sig.RSASignature.bitLength = uint16(8 * len(sig.RSASignature.bytes))
 	case PubKeyAlgoDSA:
-		r, s, err := dsa.Sign(rand.Reader, priv.PrivateKey.(*dsa.PrivateKey), digest)
+		dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
+
+		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+		subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8
+		if len(digest) > subgroupSize {
+			digest = digest[:subgroupSize]
+		}
+		r, s, err := dsa.Sign(rand, dsaPriv, digest)
 		if err == nil {
 			sig.DSASigR.bytes = r.Bytes()
 			sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes))
@@ -451,7 +453,7 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey) (err error) {
 			sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes))
 		}
 	default:
-		err = error_.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
+		err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
 	}
 
 	return
@@ -460,22 +462,22 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey) (err error) {
 // SignUserId computes a signature from priv, asserting that pub is a valid
 // key for the identity id.  On success, the signature is stored in sig. Call
 // Serialize to write it out.
-func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey) error {
+func (sig *Signature) SignUserId(rand io.Reader, id string, pub *PublicKey, priv *PrivateKey) error {
 	h, err := userIdSignatureHash(id, pub, sig)
 	if err != nil {
 		return nil
 	}
-	return sig.Sign(h, priv)
+	return sig.Sign(rand, h, priv)
 }
 
 // SignKey computes a signature from priv, asserting that pub is a subkey.  On
 // success, the signature is stored in sig. Call Serialize to write it out.
-func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey) error {
+func (sig *Signature) SignKey(rand io.Reader, pub *PublicKey, priv *PrivateKey) error {
 	h, err := keySignatureHash(&priv.PublicKey, pub, sig)
 	if err != nil {
 		return err
 	}
-	return sig.Sign(h, priv)
+	return sig.Sign(rand, h, priv)
 }
 
 // Serialize marshals sig to w. SignRSA or SignDSA must have been called first.
@@ -484,7 +486,7 @@ func (sig *Signature) Serialize(w io.Writer) (err error) {
 		sig.outSubpackets = sig.rawSubpackets
 	}
 	if sig.RSASignature.bytes == nil && sig.DSASigR.bytes == nil {
-		return error_.InvalidArgumentError("Signature: need to call SignRSA or SignDSA before Serialize")
+		return errors.InvalidArgumentError("Signature: need to call SignRSA or SignDSA before Serialize")
 	}
 
 	sigLength := 0
@@ -556,5 +558,54 @@ func (sig *Signature) buildSubpackets() (subpackets []outputSubpacket) {
 		subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
 	}
 
+	if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
+		sigLifetime := make([]byte, 4)
+		binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
+		subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
+	}
+
+	// Key flags may only appear in self-signatures or certification signatures.
+
+	if sig.FlagsValid {
+		var flags byte
+		if sig.FlagCertify {
+			flags |= 1
+		}
+		if sig.FlagSign {
+			flags |= 2
+		}
+		if sig.FlagEncryptCommunications {
+			flags |= 4
+		}
+		if sig.FlagEncryptStorage {
+			flags |= 8
+		}
+		subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, false, []byte{flags}})
+	}
+
+	// The following subpackets may only appear in self-signatures
+
+	if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
+		keyLifetime := make([]byte, 4)
+		binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
+		subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
+	}
+
+	if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
+		subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
+	}
+
+	if len(sig.PreferredSymmetric) > 0 {
+		subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
+	}
+
+	if len(sig.PreferredHash) > 0 {
+		subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
+	}
+
+	if len(sig.PreferredCompression) > 0 {
+		subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
+	}
+
 	return
 }
diff --git a/libgo/go/crypto/openpgp/packet/symmetric_key_encrypted.go b/libgo/go/crypto/openpgp/packet/symmetric_key_encrypted.go
index 76d5151..94e0705 100644
--- a/libgo/go/crypto/openpgp/packet/symmetric_key_encrypted.go
+++ b/libgo/go/crypto/openpgp/packet/symmetric_key_encrypted.go
@@ -7,7 +7,7 @@ package packet
 import (
 	"bytes"
 	"crypto/cipher"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/openpgp/s2k"
 	"io"
 	"strconv"
@@ -37,12 +37,12 @@ func (ske *SymmetricKeyEncrypted) parse(r io.Reader) (err error) {
 		return
 	}
 	if buf[0] != symmetricKeyEncryptedVersion {
-		return error_.UnsupportedError("SymmetricKeyEncrypted version")
+		return errors.UnsupportedError("SymmetricKeyEncrypted version")
 	}
 	ske.CipherFunc = CipherFunction(buf[1])
 
 	if ske.CipherFunc.KeySize() == 0 {
-		return error_.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[1])))
+		return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[1])))
 	}
 
 	ske.s2k, err = s2k.Parse(r)
@@ -60,7 +60,7 @@ func (ske *SymmetricKeyEncrypted) parse(r io.Reader) (err error) {
 	err = nil
 	if n != 0 {
 		if n == maxSessionKeySizeInBytes {
-			return error_.UnsupportedError("oversized encrypted session key")
+			return errors.UnsupportedError("oversized encrypted session key")
 		}
 		ske.encryptedKey = encryptedKey[:n]
 	}
@@ -89,13 +89,13 @@ func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) error {
 		c.XORKeyStream(ske.encryptedKey, ske.encryptedKey)
 		ske.CipherFunc = CipherFunction(ske.encryptedKey[0])
 		if ske.CipherFunc.blockSize() == 0 {
-			return error_.UnsupportedError("unknown cipher: " + strconv.Itoa(int(ske.CipherFunc)))
+			return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(ske.CipherFunc)))
 		}
 		ske.CipherFunc = CipherFunction(ske.encryptedKey[0])
 		ske.Key = ske.encryptedKey[1:]
 		if len(ske.Key)%ske.CipherFunc.blockSize() != 0 {
 			ske.Key = nil
-			return error_.StructuralError("length of decrypted key not a multiple of block size")
+			return errors.StructuralError("length of decrypted key not a multiple of block size")
 		}
 	}
 
@@ -110,7 +110,7 @@ func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) error {
 func SerializeSymmetricKeyEncrypted(w io.Writer, rand io.Reader, passphrase []byte, cipherFunc CipherFunction) (key []byte, err error) {
 	keySize := cipherFunc.KeySize()
 	if keySize == 0 {
-		return nil, error_.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc)))
+		return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc)))
 	}
 
 	s2kBuf := new(bytes.Buffer)
diff --git a/libgo/go/crypto/openpgp/packet/symmetrically_encrypted.go b/libgo/go/crypto/openpgp/packet/symmetrically_encrypted.go
index dff776e..e99a23b 100644
--- a/libgo/go/crypto/openpgp/packet/symmetrically_encrypted.go
+++ b/libgo/go/crypto/openpgp/packet/symmetrically_encrypted.go
@@ -6,8 +6,7 @@ package packet
 
 import (
 	"crypto/cipher"
-	error_ "crypto/openpgp/error"
-	"crypto/rand"
+	"crypto/openpgp/errors"
 	"crypto/sha1"
 	"crypto/subtle"
 	"hash"
@@ -35,7 +34,7 @@ func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
 			return err
 		}
 		if buf[0] != symmetricallyEncryptedVersion {
-			return error_.UnsupportedError("unknown SymmetricallyEncrypted version")
+			return errors.UnsupportedError("unknown SymmetricallyEncrypted version")
 		}
 	}
 	se.contents = r
@@ -48,10 +47,10 @@ func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
 func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) {
 	keySize := c.KeySize()
 	if keySize == 0 {
-		return nil, error_.UnsupportedError("unknown cipher: " + strconv.Itoa(int(c)))
+		return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(c)))
 	}
 	if len(key) != keySize {
-		return nil, error_.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
+		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
 	}
 
 	if se.prefix == nil {
@@ -61,7 +60,7 @@ func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.Read
 			return nil, err
 		}
 	} else if len(se.prefix) != c.blockSize()+2 {
-		return nil, error_.InvalidArgumentError("can't try ciphers with different block lengths")
+		return nil, errors.InvalidArgumentError("can't try ciphers with different block lengths")
 	}
 
 	ocfbResync := cipher.OCFBResync
@@ -72,7 +71,7 @@ func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.Read
 
 	s := cipher.NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync)
 	if s == nil {
-		return nil, error_.KeyIncorrectError
+		return nil, errors.KeyIncorrectError
 	}
 
 	plaintext := cipher.StreamReader{S: s, R: se.contents}
@@ -181,7 +180,7 @@ const mdcPacketTagByte = byte(0x80) | 0x40 | 19
 
 func (ser *seMDCReader) Close() error {
 	if ser.error {
-		return error_.SignatureError("error during reading")
+		return errors.SignatureError("error during reading")
 	}
 
 	for !ser.eof {
@@ -192,18 +191,18 @@ func (ser *seMDCReader) Close() error {
 			break
 		}
 		if err != nil {
-			return error_.SignatureError("error during reading")
+			return errors.SignatureError("error during reading")
 		}
 	}
 
 	if ser.trailer[0] != mdcPacketTagByte || ser.trailer[1] != sha1.Size {
-		return error_.SignatureError("MDC packet not found")
+		return errors.SignatureError("MDC packet not found")
 	}
 	ser.h.Write(ser.trailer[:2])
 
 	final := ser.h.Sum(nil)
 	if subtle.ConstantTimeCompare(final, ser.trailer[2:]) != 1 {
-		return error_.SignatureError("hash mismatch")
+		return errors.SignatureError("hash mismatch")
 	}
 	return nil
 }
@@ -253,9 +252,9 @@ func (c noOpCloser) Close() error {
 // SerializeSymmetricallyEncrypted serializes a symmetrically encrypted packet
 // to w and returns a WriteCloser to which the to-be-encrypted packets can be
 // written.
-func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte) (contents io.WriteCloser, err error) {
+func SerializeSymmetricallyEncrypted(w io.Writer, rand io.Reader, c CipherFunction, key []byte) (contents io.WriteCloser, err error) {
 	if c.KeySize() != len(key) {
-		return nil, error_.InvalidArgumentError("SymmetricallyEncrypted.Serialize: bad key length")
+		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted.Serialize: bad key length")
 	}
 	writeCloser := noOpCloser{w}
 	ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedMDC)
@@ -271,7 +270,7 @@ func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte)
 	block := c.new(key)
 	blockSize := block.BlockSize()
 	iv := make([]byte, blockSize)
-	_, err = rand.Reader.Read(iv)
+	_, err = rand.Read(iv)
 	if err != nil {
 		return
 	}
diff --git a/libgo/go/crypto/openpgp/packet/symmetrically_encrypted_test.go b/libgo/go/crypto/openpgp/packet/symmetrically_encrypted_test.go
index 8eee971..f7d133d 100644
--- a/libgo/go/crypto/openpgp/packet/symmetrically_encrypted_test.go
+++ b/libgo/go/crypto/openpgp/packet/symmetrically_encrypted_test.go
@@ -6,7 +6,8 @@ package packet
 
 import (
 	"bytes"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
+	"crypto/rand"
 	"crypto/sha1"
 	"encoding/hex"
 	"io"
@@ -70,7 +71,7 @@ func testMDCReader(t *testing.T) {
 	err = mdcReader.Close()
 	if err == nil {
 		t.Error("corruption: no error")
-	} else if _, ok := err.(*error_.SignatureError); !ok {
+	} else if _, ok := err.(*errors.SignatureError); !ok {
 		t.Errorf("corruption: expected SignatureError, got: %s", err)
 	}
 }
@@ -82,7 +83,7 @@ func TestSerialize(t *testing.T) {
 	c := CipherAES128
 	key := make([]byte, c.KeySize())
 
-	w, err := SerializeSymmetricallyEncrypted(buf, c, key)
+	w, err := SerializeSymmetricallyEncrypted(buf, rand.Reader, c, key)
 	if err != nil {
 		t.Errorf("error from SerializeSymmetricallyEncrypted: %s", err)
 		return
diff --git a/libgo/go/crypto/openpgp/read.go b/libgo/go/crypto/openpgp/read.go
index 76fb1ea..1d23434 100644
--- a/libgo/go/crypto/openpgp/read.go
+++ b/libgo/go/crypto/openpgp/read.go
@@ -8,7 +8,7 @@ package openpgp
 import (
 	"crypto"
 	"crypto/openpgp/armor"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/openpgp/packet"
 	_ "crypto/sha256"
 	"hash"
@@ -27,7 +27,7 @@ func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) {
 	}
 
 	if block.Type != expectedType {
-		return nil, error_.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
+		return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
 	}
 
 	return block.Body, nil
@@ -130,7 +130,7 @@ ParsePackets:
 		case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
 			// This message isn't encrypted.
 			if len(symKeys) != 0 || len(pubKeys) != 0 {
-				return nil, error_.StructuralError("key material not followed by encrypted message")
+				return nil, errors.StructuralError("key material not followed by encrypted message")
 			}
 			packets.Unread(p)
 			return readSignedMessage(packets, nil, keyring)
@@ -161,7 +161,7 @@ FindKey:
 					continue
 				}
 				decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
-				if err != nil && err != error_.KeyIncorrectError {
+				if err != nil && err != errors.KeyIncorrectError {
 					return nil, err
 				}
 				if decrypted != nil {
@@ -179,11 +179,11 @@ FindKey:
 		}
 
 		if len(candidates) == 0 && len(symKeys) == 0 {
-			return nil, error_.KeyIncorrectError
+			return nil, errors.KeyIncorrectError
 		}
 
 		if prompt == nil {
-			return nil, error_.KeyIncorrectError
+			return nil, errors.KeyIncorrectError
 		}
 
 		passphrase, err := prompt(candidates, len(symKeys) != 0)
@@ -197,7 +197,7 @@ FindKey:
 				err = s.Decrypt(passphrase)
 				if err == nil && !s.Encrypted {
 					decrypted, err = se.Decrypt(s.CipherFunc, s.Key)
-					if err != nil && err != error_.KeyIncorrectError {
+					if err != nil && err != errors.KeyIncorrectError {
 						return nil, err
 					}
 					if decrypted != nil {
@@ -237,7 +237,7 @@ FindLiteralData:
 			packets.Push(p.Body)
 		case *packet.OnePassSignature:
 			if !p.IsLast {
-				return nil, error_.UnsupportedError("nested signatures")
+				return nil, errors.UnsupportedError("nested signatures")
 			}
 
 			h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
@@ -281,7 +281,7 @@ FindLiteralData:
 func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
 	h := hashId.New()
 	if h == nil {
-		return nil, nil, error_.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId)))
+		return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId)))
 	}
 
 	switch sigType {
@@ -291,7 +291,7 @@ func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Ha
 		return h, NewCanonicalTextHash(h), nil
 	}
 
-	return nil, nil, error_.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
+	return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
 }
 
 // checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
@@ -333,7 +333,7 @@ func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) {
 
 		var ok bool
 		if scr.md.Signature, ok = p.(*packet.Signature); !ok {
-			scr.md.SignatureError = error_.StructuralError("LiteralData not followed by Signature")
+			scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature")
 			return
 		}
 
@@ -363,16 +363,16 @@ func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signe
 
 	sig, ok := p.(*packet.Signature)
 	if !ok {
-		return nil, error_.StructuralError("non signature packet found")
+		return nil, errors.StructuralError("non signature packet found")
 	}
 
 	if sig.IssuerKeyId == nil {
-		return nil, error_.StructuralError("signature doesn't have an issuer")
+		return nil, errors.StructuralError("signature doesn't have an issuer")
 	}
 
 	keys := keyring.KeysById(*sig.IssuerKeyId)
 	if len(keys) == 0 {
-		return nil, error_.UnknownIssuerError
+		return nil, errors.UnknownIssuerError
 	}
 
 	h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
@@ -399,7 +399,7 @@ func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signe
 		return
 	}
 
-	return nil, error_.UnknownIssuerError
+	return nil, errors.UnknownIssuerError
 }
 
 // CheckArmoredDetachedSignature performs the same actions as
diff --git a/libgo/go/crypto/openpgp/read_test.go b/libgo/go/crypto/openpgp/read_test.go
index e8a6bf5..d1ecad3 100644
--- a/libgo/go/crypto/openpgp/read_test.go
+++ b/libgo/go/crypto/openpgp/read_test.go
@@ -6,7 +6,8 @@ package openpgp
 
 import (
 	"bytes"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
+	_ "crypto/sha512"
 	"encoding/hex"
 	"io"
 	"io/ioutil"
@@ -77,6 +78,15 @@ func TestReadDSAKey(t *testing.T) {
 	}
 }
 
+func TestDSAHashTruncatation(t *testing.T) {
+	// dsaKeyWithSHA512 was generated with GnuPG and --cert-digest-algo
+	// SHA512 in order to require DSA hash truncation to verify correctly.
+	_, err := ReadKeyRing(readerFromHex(dsaKeyWithSHA512))
+	if err != nil {
+		t.Error(err)
+	}
+}
+
 func TestGetKeyById(t *testing.T) {
 	kring, _ := ReadKeyRing(readerFromHex(testKeys1And2Hex))
 
@@ -151,18 +161,18 @@ func TestSignedEncryptedMessage(t *testing.T) {
 		prompt := func(keys []Key, symmetric bool) ([]byte, error) {
 			if symmetric {
 				t.Errorf("prompt: message was marked as symmetrically encrypted")
-				return nil, error_.KeyIncorrectError
+				return nil, errors.KeyIncorrectError
 			}
 
 			if len(keys) == 0 {
 				t.Error("prompt: no keys requested")
-				return nil, error_.KeyIncorrectError
+				return nil, errors.KeyIncorrectError
 			}
 
 			err := keys[0].PrivateKey.Decrypt([]byte("passphrase"))
 			if err != nil {
 				t.Errorf("prompt: error decrypting key: %s", err)
-				return nil, error_.KeyIncorrectError
+				return nil, errors.KeyIncorrectError
 			}
 
 			return nil, nil
@@ -286,7 +296,7 @@ func TestReadingArmoredPrivateKey(t *testing.T) {
 
 func TestNoArmoredData(t *testing.T) {
 	_, err := ReadArmoredKeyRing(bytes.NewBufferString("foo"))
-	if _, ok := err.(error_.InvalidArgumentError); !ok {
+	if _, ok := err.(errors.InvalidArgumentError); !ok {
 		t.Errorf("error was not an InvalidArgumentError: %s", err)
 	}
 }
@@ -358,3 +368,5 @@ AHcVnXjtxrULkQFGbGvhKURLvS9WnzD/m1K2zzwxzkPTzT9/Yf06O6Mal5AdugPL
 VrM0m72/jnpKo04=
 =zNCn
 -----END PGP PRIVATE KEY BLOCK-----`
+
+const dsaKeyWithSHA512 = `9901a2044f04b07f110400db244efecc7316553ee08d179972aab87bb1214de7692593fcf5b6feb1c80fba268722dd464748539b85b81d574cd2d7ad0ca2444de4d849b8756bad7768c486c83a824f9bba4af773d11742bdfb4ac3b89ef8cc9452d4aad31a37e4b630d33927bff68e879284a1672659b8b298222fc68f370f3e24dccacc4a862442b9438b00a0ea444a24088dc23e26df7daf8f43cba3bffc4fe703fe3d6cd7fdca199d54ed8ae501c30e3ec7871ea9cdd4cf63cfe6fc82281d70a5b8bb493f922cd99fba5f088935596af087c8d818d5ec4d0b9afa7f070b3d7c1dd32a84fca08d8280b4890c8da1dde334de8e3cad8450eed2a4a4fcc2db7b8e5528b869a74a7f0189e11ef097ef1253582348de072bb07a9fa8ab838e993cef0ee203ff49298723e2d1f549b00559f886cd417a41692ce58d0ac1307dc71d85a8af21b0cf6eaa14baf2922d3a70389bedf17cc514ba0febbd107675a372fe84b90162a9e88b14d4b1c6be855b96b33fb198c46f058568817780435b6936167ebb3724b680f32bf27382ada2e37a879b3d9de2abe0c3f399350afd1ad438883f4791e2e3b4184453412068617368207472756e636174696f6e207465737488620413110a002205024f04b07f021b03060b090807030206150802090a0b0416020301021e01021780000a0910ef20e0cefca131581318009e2bf3bf047a44d75a9bacd00161ee04d435522397009a03a60d51bd8a568c6c021c8d7cf1be8d990d6417b0020003`
diff --git a/libgo/go/crypto/openpgp/s2k/s2k.go b/libgo/go/crypto/openpgp/s2k/s2k.go
index 8bc0bb3..39479a1 100644
--- a/libgo/go/crypto/openpgp/s2k/s2k.go
+++ b/libgo/go/crypto/openpgp/s2k/s2k.go
@@ -8,7 +8,7 @@ package s2k
 
 import (
 	"crypto"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"hash"
 	"io"
 	"strconv"
@@ -89,11 +89,11 @@ func Parse(r io.Reader) (f func(out, in []byte), err error) {
 
 	hash, ok := HashIdToHash(buf[1])
 	if !ok {
-		return nil, error_.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
+		return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
 	}
 	h := hash.New()
 	if h == nil {
-		return nil, error_.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
+		return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
 	}
 
 	switch buf[0] {
@@ -123,7 +123,7 @@ func Parse(r io.Reader) (f func(out, in []byte), err error) {
 		return f, nil
 	}
 
-	return nil, error_.UnsupportedError("S2K function")
+	return nil, errors.UnsupportedError("S2K function")
 }
 
 // Serialize salts and stretches the given passphrase and writes the resulting
diff --git a/libgo/go/crypto/openpgp/write.go b/libgo/go/crypto/openpgp/write.go
index bdee57d..73daa11 100644
--- a/libgo/go/crypto/openpgp/write.go
+++ b/libgo/go/crypto/openpgp/write.go
@@ -7,7 +7,7 @@ package openpgp
 import (
 	"crypto"
 	"crypto/openpgp/armor"
-	error_ "crypto/openpgp/error"
+	"crypto/openpgp/errors"
 	"crypto/openpgp/packet"
 	"crypto/openpgp/s2k"
 	"crypto/rand"
@@ -58,10 +58,10 @@ func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType p
 
 func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType) (err error) {
 	if signer.PrivateKey == nil {
-		return error_.InvalidArgumentError("signing key doesn't have a private key")
+		return errors.InvalidArgumentError("signing key doesn't have a private key")
 	}
 	if signer.PrivateKey.Encrypted {
-		return error_.InvalidArgumentError("signing key is encrypted")
+		return errors.InvalidArgumentError("signing key is encrypted")
 	}
 
 	sig := new(packet.Signature)
@@ -77,7 +77,7 @@ func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.S
 	}
 	io.Copy(wrappedHash, message)
 
-	err = sig.Sign(h, signer.PrivateKey)
+	err = sig.Sign(rand.Reader, h, signer.PrivateKey)
 	if err != nil {
 		return
 	}
@@ -111,7 +111,7 @@ func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHi
 	if err != nil {
 		return
 	}
-	w, err := packet.SerializeSymmetricallyEncrypted(ciphertext, packet.CipherAES128, key)
+	w, err := packet.SerializeSymmetricallyEncrypted(ciphertext, rand.Reader, packet.CipherAES128, key)
 	if err != nil {
 		return
 	}
@@ -156,7 +156,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
 	if signed != nil {
 		signer = signed.signingKey().PrivateKey
 		if signer == nil || signer.Encrypted {
-			return nil, error_.InvalidArgumentError("signing key must be decrypted")
+			return nil, errors.InvalidArgumentError("signing key must be decrypted")
 		}
 	}
 
@@ -183,7 +183,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
 	for i := range to {
 		encryptKeys[i] = to[i].encryptionKey()
 		if encryptKeys[i].PublicKey == nil {
-			return nil, error_.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys")
+			return nil, errors.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys")
 		}
 
 		sig := to[i].primaryIdentity().SelfSignature
@@ -201,7 +201,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
 	}
 
 	if len(candidateCiphers) == 0 || len(candidateHashes) == 0 {
-		return nil, error_.InvalidArgumentError("cannot encrypt because recipient set shares no common algorithms")
+		return nil, errors.InvalidArgumentError("cannot encrypt because recipient set shares no common algorithms")
 	}
 
 	cipher := packet.CipherFunction(candidateCiphers[0])
@@ -217,7 +217,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
 		}
 	}
 
-	encryptedData, err := packet.SerializeSymmetricallyEncrypted(ciphertext, cipher, symKey)
+	encryptedData, err := packet.SerializeSymmetricallyEncrypted(ciphertext, rand.Reader, cipher, symKey)
 	if err != nil {
 		return
 	}
@@ -287,7 +287,7 @@ func (s signatureWriter) Close() error {
 		IssuerKeyId:  &s.signer.KeyId,
 	}
 
-	if err := sig.Sign(s.h, s.signer); err != nil {
+	if err := sig.Sign(rand.Reader, s.h, s.signer); err != nil {
 		return err
 	}
 	if err := s.literalData.Close(); err != nil {
diff --git a/libgo/go/crypto/openpgp/write_test.go b/libgo/go/crypto/openpgp/write_test.go
index 02fa5b7..7df02e7 100644
--- a/libgo/go/crypto/openpgp/write_test.go
+++ b/libgo/go/crypto/openpgp/write_test.go
@@ -222,7 +222,7 @@ func TestEncryption(t *testing.T) {
 
 		if test.isSigned {
 			if md.SignatureError != nil {
-				t.Errorf("#%d: signature error: %s", i, err)
+				t.Errorf("#%d: signature error: %s", i, md.SignatureError)
 			}
 			if md.Signature == nil {
 				t.Error("signature missing")
diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go
index a461ad9..25f7a92 100644
--- a/libgo/go/crypto/tls/common.go
+++ b/libgo/go/crypto/tls/common.go
@@ -111,6 +111,18 @@ type ConnectionState struct {
 	VerifiedChains [][]*x509.Certificate
 }
 
+// ClientAuthType declares the policy the server will follow for
+// TLS Client Authentication.
+type ClientAuthType int
+
+const (
+	NoClientCert ClientAuthType = iota
+	RequestClientCert
+	RequireAnyClientCert
+	VerifyClientCertIfGiven
+	RequireAndVerifyClientCert
+)
+
 // 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.
 type Config struct {
@@ -120,7 +132,7 @@ type Config struct {
 	Rand io.Reader
 
 	// Time returns the current time as the number of seconds since the epoch.
-	// If Time is nil, TLS uses the system time.Seconds.
+	// If Time is nil, TLS uses time.Now.
 	Time func() time.Time
 
 	// Certificates contains one or more certificate chains
@@ -148,11 +160,14 @@ type Config struct {
 	// hosting.
 	ServerName string
 
-	// AuthenticateClient controls whether a server will request a certificate
-	// from the client. It does not require that the client send a
-	// certificate nor does it require that the certificate sent be
-	// anything more than self-signed.
-	AuthenticateClient bool
+	// 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.
@@ -259,6 +274,11 @@ type Certificate struct {
 	// 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.
diff --git a/libgo/go/crypto/tls/generate_cert.go b/libgo/go/crypto/tls/generate_cert.go
index c4463ff..7c0718b 100644
--- a/libgo/go/crypto/tls/generate_cert.go
+++ b/libgo/go/crypto/tls/generate_cert.go
@@ -31,7 +31,7 @@ func main() {
 		return
 	}
 
-	now := time.Seconds()
+	now := time.Now()
 
 	template := x509.Certificate{
 		SerialNumber: new(big.Int).SetInt64(0),
@@ -39,8 +39,8 @@ func main() {
 			CommonName:   *hostName,
 			Organization: []string{"Acme Co"},
 		},
-		NotBefore: time.SecondsToUTC(now - 300),
-		NotAfter:  time.SecondsToUTC(now + 60*60*24*365), // valid for 1 year.
+		NotBefore: now.Add(-5 * time.Minute).UTC(),
+		NotAfter:  now.AddDate(1, 0, 0).UTC(), // valid for 1 year.
 
 		SubjectKeyId: []byte{1, 2, 3, 4},
 		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go
index 7364800..632ceea 100644
--- a/libgo/go/crypto/tls/handshake_client.go
+++ b/libgo/go/crypto/tls/handshake_client.go
@@ -5,12 +5,14 @@
 package tls
 
 import (
+	"bytes"
 	"crypto"
 	"crypto/rsa"
 	"crypto/subtle"
 	"crypto/x509"
 	"errors"
 	"io"
+	"strconv"
 )
 
 func (c *Conn) clientHandshake() error {
@@ -162,10 +164,23 @@ func (c *Conn) clientHandshake() error {
 		}
 	}
 
-	transmitCert := false
+	var certToSend *Certificate
 	certReq, ok := msg.(*certificateRequestMsg)
 	if ok {
-		// We only accept certificates with RSA keys.
+		// 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.
+
+		finishedHash.Write(certReq.marshal())
+
+		// For now, we only know how to sign challenges with RSA
 		rsaAvail := false
 		for _, certType := range certReq.certificateTypes {
 			if certType == certTypeRSASign {
@@ -174,23 +189,41 @@ func (c *Conn) clientHandshake() error {
 			}
 		}
 
-		// For now, only send a certificate back if the server gives us an
-		// empty list of certificateAuthorities.
-		//
-		// 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.
-		if rsaAvail && len(certReq.certificateAuthorities) == 0 {
-			transmitCert = 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, cert := range c.config.Certificates {
+			if !rsaAvail {
+				continue
+			}
 
-		finishedHash.Write(certReq.marshal())
+			leaf := cert.Leaf
+			if leaf == nil {
+				if leaf, err = x509.ParseCertificate(cert.Certificate[0]); err != nil {
+					c.sendAlert(alertInternalError)
+					return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
+				}
+			}
+
+			if leaf.PublicKeyAlgorithm != x509.RSA {
+				continue
+			}
+
+			if len(certReq.certificateAuthorities) == 0 {
+				// they gave us an empty list, so just take the
+				// first RSA cert from c.config.Certificates
+				certToSend = &cert
+				break
+			}
+
+			for _, ca := range certReq.certificateAuthorities {
+				if bytes.Equal(leaf.RawIssuer, ca) {
+					certToSend = &cert
+					break findCert
+				}
+			}
+		}
 
 		msg, err = c.readHandshake()
 		if err != nil {
@@ -204,17 +237,9 @@ func (c *Conn) clientHandshake() error {
 	}
 	finishedHash.Write(shd.marshal())
 
-	var cert *x509.Certificate
-	if transmitCert {
+	if certToSend != nil {
 		certMsg = new(certificateMsg)
-		if len(c.config.Certificates) > 0 {
-			cert, err = x509.ParseCertificate(c.config.Certificates[0].Certificate[0])
-			if err == nil && cert.PublicKeyAlgorithm == x509.RSA {
-				certMsg.certificates = c.config.Certificates[0].Certificate
-			} else {
-				cert = nil
-			}
-		}
+		certMsg.certificates = certToSend.Certificate
 		finishedHash.Write(certMsg.marshal())
 		c.writeRecord(recordTypeHandshake, certMsg.marshal())
 	}
@@ -229,7 +254,7 @@ func (c *Conn) clientHandshake() error {
 		c.writeRecord(recordTypeHandshake, ckx.marshal())
 	}
 
-	if cert != nil {
+	if certToSend != nil {
 		certVerify := new(certificateVerifyMsg)
 		digest := make([]byte, 0, 36)
 		digest = finishedHash.serverMD5.Sum(digest)
diff --git a/libgo/go/crypto/tls/handshake_messages.go b/libgo/go/crypto/tls/handshake_messages.go
index 5438e74..e1517cc 100644
--- a/libgo/go/crypto/tls/handshake_messages.go
+++ b/libgo/go/crypto/tls/handshake_messages.go
@@ -881,9 +881,11 @@ func (m *certificateRequestMsg) marshal() (x []byte) {
 
 	// See http://tools.ietf.org/html/rfc4346#section-7.4.4
 	length := 1 + len(m.certificateTypes) + 2
+	casLength := 0
 	for _, ca := range m.certificateAuthorities {
-		length += 2 + len(ca)
+		casLength += 2 + len(ca)
 	}
+	length += casLength
 
 	x = make([]byte, 4+length)
 	x[0] = typeCertificateRequest
@@ -895,10 +897,8 @@ func (m *certificateRequestMsg) marshal() (x []byte) {
 
 	copy(x[5:], m.certificateTypes)
 	y := x[5+len(m.certificateTypes):]
-
-	numCA := len(m.certificateAuthorities)
-	y[0] = uint8(numCA >> 8)
-	y[1] = uint8(numCA)
+	y[0] = uint8(casLength >> 8)
+	y[1] = uint8(casLength)
 	y = y[2:]
 	for _, ca := range m.certificateAuthorities {
 		y[0] = uint8(len(ca) >> 8)
@@ -909,7 +909,6 @@ func (m *certificateRequestMsg) marshal() (x []byte) {
 	}
 
 	m.raw = x
-
 	return
 }
 
@@ -937,31 +936,34 @@ func (m *certificateRequestMsg) unmarshal(data []byte) bool {
 	}
 
 	data = data[numCertTypes:]
+
 	if len(data) < 2 {
 		return false
 	}
-
-	numCAs := uint16(data[0])<<16 | uint16(data[1])
+	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 = make([][]byte, numCAs)
-	for i := uint16(0); i < numCAs; i++ {
-		if len(data) < 2 {
+	m.certificateAuthorities = nil
+	for len(cas) > 0 {
+		if len(cas) < 2 {
 			return false
 		}
-		caLen := uint16(data[0])<<16 | uint16(data[1])
+		caLen := uint16(cas[0])<<8 | uint16(cas[1])
+		cas = cas[2:]
 
-		data = data[2:]
-		if len(data) < int(caLen) {
+		if len(cas) < int(caLen) {
 			return false
 		}
 
-		ca := make([]byte, caLen)
-		copy(ca, data)
-		m.certificateAuthorities[i] = ca
-		data = data[caLen:]
+		m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
+		cas = cas[caLen:]
 	}
-
 	if len(data) > 0 {
 		return false
 	}
diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go
index 89c000d..fb53767 100644
--- a/libgo/go/crypto/tls/handshake_server.go
+++ b/libgo/go/crypto/tls/handshake_server.go
@@ -150,14 +150,19 @@ FindCipherSuite:
 		c.writeRecord(recordTypeHandshake, skx.marshal())
 	}
 
-	if config.AuthenticateClient {
+	if config.ClientAuth >= RequestClientCert {
 		// Request a client certificate
 		certReq := new(certificateRequestMsg)
 		certReq.certificateTypes = []byte{certTypeRSASign}
+
 		// An empty list of certificateAuthorities signals to
 		// the client that it may send any certificate in response
-		// to our request.
-
+		// 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()
+		}
 		finishedHash.Write(certReq.marshal())
 		c.writeRecord(recordTypeHandshake, certReq.marshal())
 	}
@@ -166,52 +171,87 @@ FindCipherSuite:
 	finishedHash.Write(helloDone.marshal())
 	c.writeRecord(recordTypeHandshake, helloDone.marshal())
 
-	var pub *rsa.PublicKey
-	if config.AuthenticateClient {
-		// Get client certificate
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-		certMsg, ok = msg.(*certificateMsg)
-		if !ok {
-			return c.sendAlert(alertUnexpectedMessage)
+	var pub *rsa.PublicKey // public key for client auth, if any
+
+	msg, err = c.readHandshake()
+	if err != nil {
+		return err
+	}
+
+	// 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 {
+			return c.sendAlert(alertHandshakeFailure)
 		}
 		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")
+			}
+		}
+
 		certs := make([]*x509.Certificate, len(certMsg.certificates))
 		for i, asn1Data := range certMsg.certificates {
-			cert, err := x509.ParseCertificate(asn1Data)
-			if err != nil {
+			if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
 				c.sendAlert(alertBadCertificate)
-				return errors.New("could not parse client's certificate: " + err.Error())
+				return errors.New("tls: failed to parse client certificate: " + err.Error())
 			}
-			certs[i] = cert
 		}
 
-		// TODO(agl): do better validation of certs: max path length, name restrictions etc.
-		for i := 1; i < len(certs); i++ {
-			if err := certs[i-1].CheckSignatureFrom(certs[i]); err != nil {
+		if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
+			opts := x509.VerifyOptions{
+				Roots:         c.config.ClientCAs,
+				CurrentTime:   c.config.time(),
+				Intermediates: x509.NewCertPool(),
+			}
+
+			for i, cert := range certs {
+				if i == 0 {
+					continue
+				}
+				opts.Intermediates.AddCert(cert)
+			}
+
+			chains, err := certs[0].Verify(opts)
+			if err != nil {
 				c.sendAlert(alertBadCertificate)
-				return errors.New("could not validate certificate signature: " + err.Error())
+				return 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 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 {
-			key, ok := certs[0].PublicKey.(*rsa.PublicKey)
-			if !ok {
+			if pub, ok = certs[0].PublicKey.(*rsa.PublicKey); !ok {
 				return c.sendAlert(alertUnsupportedCertificate)
 			}
-			pub = key
 			c.peerCertificates = certs
 		}
+
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
 	}
 
 	// Get client key exchange
-	msg, err = c.readHandshake()
-	if err != nil {
-		return err
-	}
 	ckx, ok := msg.(*clientKeyExchangeMsg)
 	if !ok {
 		return c.sendAlert(alertUnexpectedMessage)
diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go
index d98e13d..4bff532 100644
--- a/libgo/go/crypto/tls/handshake_server_test.go
+++ b/libgo/go/crypto/tls/handshake_server_test.go
@@ -7,9 +7,12 @@ package tls
 import (
 	"bytes"
 	"crypto/rsa"
+	"crypto/x509"
 	"encoding/hex"
+	"encoding/pem"
 	"flag"
 	"io"
+	"log"
 	"math/big"
 	"net"
 	"strconv"
@@ -109,16 +112,18 @@ func TestClose(t *testing.T) {
 	}
 }
 
-func testServerScript(t *testing.T, name string, serverScript [][]byte, config *Config) {
+func testServerScript(t *testing.T, name string, serverScript [][]byte, config *Config, peers []*x509.Certificate) {
 	c, s := net.Pipe()
 	srv := Server(s, config)
+	pchan := make(chan []*x509.Certificate, 1)
 	go func() {
 		srv.Write([]byte("hello, world\n"))
 		srv.Close()
 		s.Close()
+		st := srv.ConnectionState()
+		pchan <- st.PeerCertificates
 	}()
 
-	defer c.Close()
 	for i, b := range serverScript {
 		if i%2 == 0 {
 			c.Write(b)
@@ -133,34 +138,66 @@ func testServerScript(t *testing.T, name string, serverScript [][]byte, config *
 			t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", name, i, bb, b)
 		}
 	}
+	c.Close()
+
+	if peers != nil {
+		gotpeers := <-pchan
+		if len(peers) == len(gotpeers) {
+			for i, _ := range peers {
+				if !peers[i].Equal(gotpeers[i]) {
+					t.Fatalf("%s: mismatch on peer cert %d", name, i)
+				}
+			}
+		} else {
+			t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", name, len(peers), len(gotpeers))
+		}
+	}
 }
 
 func TestHandshakeServerRC4(t *testing.T) {
-	testServerScript(t, "RC4", rc4ServerScript, testConfig)
+	testServerScript(t, "RC4", rc4ServerScript, testConfig, nil)
 }
 
 func TestHandshakeServer3DES(t *testing.T) {
 	des3Config := new(Config)
 	*des3Config = *testConfig
 	des3Config.CipherSuites = []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}
-	testServerScript(t, "3DES", des3ServerScript, des3Config)
+	testServerScript(t, "3DES", des3ServerScript, des3Config, nil)
 }
 
 func TestHandshakeServerAES(t *testing.T) {
 	aesConfig := new(Config)
 	*aesConfig = *testConfig
 	aesConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}
-	testServerScript(t, "AES", aesServerScript, aesConfig)
+	testServerScript(t, "AES", aesServerScript, aesConfig, nil)
 }
 
 func TestHandshakeServerSSLv3(t *testing.T) {
-	testServerScript(t, "SSLv3", sslv3ServerScript, testConfig)
+	testServerScript(t, "SSLv3", sslv3ServerScript, testConfig, nil)
+}
+
+type clientauthTest struct {
+	name       string
+	clientauth ClientAuthType
+	peers      []*x509.Certificate
+	script     [][]byte
+}
+
+func TestClientAuth(t *testing.T) {
+	for _, cat := range clientauthTests {
+		t.Log("running", cat.name)
+		cfg := new(Config)
+		*cfg = *testConfig
+		cfg.ClientAuth = cat.clientauth
+		testServerScript(t, cat.name, cat.script, cfg, cat.peers)
+	}
 }
 
 var serve = flag.Bool("serve", false, "run a TLS server on :10443")
 var testCipherSuites = flag.String("ciphersuites",
 	"0x"+strconv.FormatInt(int64(TLS_RSA_WITH_RC4_128_SHA), 16),
 	"cipher suites to accept in serving mode")
+var testClientAuth = flag.Int("clientauth", 0, "value for tls.Config.ClientAuth")
 
 func TestRunServer(t *testing.T) {
 	if !*serve {
@@ -177,6 +214,8 @@ func TestRunServer(t *testing.T) {
 		testConfig.CipherSuites[i] = uint16(suite)
 	}
 
+	testConfig.ClientAuth = ClientAuthType(*testClientAuth)
+
 	l, err := Listen("tcp", ":10443", testConfig)
 	if err != nil {
 		t.Fatal(err)
@@ -185,13 +224,23 @@ func TestRunServer(t *testing.T) {
 	for {
 		c, err := l.Accept()
 		if err != nil {
+			log.Printf("error from TLS handshake: %s", err)
 			break
 		}
+
 		_, err = c.Write([]byte("hello, world\n"))
 		if err != nil {
-			t.Errorf("error from TLS: %s", err)
-			break
+			log.Printf("error from TLS: %s", err)
+			continue
 		}
+
+		st := c.(*Conn).ConnectionState()
+		if len(st.PeerCertificates) > 0 {
+			log.Print("Handling request from client ", st.PeerCertificates[0].Subject.CommonName)
+		} else {
+			log.Print("Handling request from anon client")
+		}
+
 		c.Close()
 	}
 }
@@ -221,6 +270,18 @@ var testPrivateKey = &rsa.PrivateKey{
 	},
 }
 
+func loadPEMCert(in string) *x509.Certificate {
+	block, _ := pem.Decode([]byte(in))
+	if block.Type == "CERTIFICATE" && len(block.Headers) == 0 {
+		cert, err := x509.ParseCertificate(block.Bytes)
+		if err == nil {
+			return cert
+		}
+		panic("error parsing cert")
+	}
+	panic("error parsing PEM")
+}
+
 // Script of interaction with gnutls implementation.
 // The values for this test are obtained by building and running in server mode:
 //   % gotest -test.run "TestRunServer" -serve
@@ -229,23 +290,22 @@ var testPrivateKey = &rsa.PrivateKey{
 //   % python parse-gnutls-cli-debug-log.py < /tmp/log
 var rc4ServerScript = [][]byte{
 	{
-		0x16, 0x03, 0x02, 0x00, 0x7f, 0x01, 0x00, 0x00,
-		0x7b, 0x03, 0x02, 0x4d, 0x08, 0x1f, 0x5a, 0x7a,
-		0x0a, 0x92, 0x2f, 0xf0, 0x73, 0x16, 0x3a, 0x88,
-		0x14, 0x85, 0x4c, 0x98, 0x15, 0x7b, 0x65, 0xe0,
-		0x78, 0xd0, 0xed, 0xd0, 0xf3, 0x65, 0x20, 0xeb,
-		0x80, 0xd1, 0x0b, 0x00, 0x00, 0x34, 0x00, 0x33,
+		0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
+		0x76, 0x03, 0x02, 0x4e, 0xdd, 0xe6, 0xa5, 0xf7,
+		0x00, 0x36, 0xf7, 0x83, 0xec, 0x93, 0x7c, 0xd2,
+		0x4d, 0xe7, 0x7b, 0xf5, 0x4c, 0xf7, 0xe3, 0x86,
+		0xe8, 0xec, 0x3b, 0xbd, 0x2c, 0x9a, 0x3f, 0x57,
+		0xf0, 0xa4, 0xd4, 0x00, 0x00, 0x34, 0x00, 0x33,
 		0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
 		0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
 		0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
 		0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
 		0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
 		0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
-		0x00, 0x8a, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x09,
+		0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
 		0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
 		0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
-		0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0xff,
-		0x01, 0x00, 0x01, 0x00,
+		0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
 	},
 
 	{
@@ -349,38 +409,46 @@ var rc4ServerScript = [][]byte{
 
 	{
 		0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
-		0x82, 0x00, 0x80, 0x3c, 0x13, 0xd7, 0x12, 0xc1,
-		0x6a, 0xf0, 0x3f, 0x8c, 0xa1, 0x35, 0x5d, 0xc5,
-		0x89, 0x1e, 0x9e, 0xcd, 0x32, 0xc7, 0x9e, 0xe6,
-		0xae, 0xd5, 0xf1, 0xbf, 0x70, 0xd7, 0xa9, 0xef,
-		0x2c, 0x4c, 0xf4, 0x22, 0xbc, 0x17, 0x17, 0xaa,
-		0x05, 0xf3, 0x9f, 0x80, 0xf2, 0xe9, 0x82, 0x2f,
-		0x2a, 0x15, 0x54, 0x0d, 0x16, 0x0e, 0x77, 0x4c,
-		0x28, 0x3c, 0x03, 0x2d, 0x2d, 0xd7, 0xc8, 0x64,
-		0xd9, 0x59, 0x4b, 0x1c, 0xf4, 0xde, 0xff, 0x2f,
-		0xbc, 0x94, 0xaf, 0x18, 0x26, 0x37, 0xce, 0x4f,
-		0x84, 0x74, 0x2e, 0x45, 0x66, 0x7c, 0x0c, 0x54,
-		0x46, 0x36, 0x5f, 0x65, 0x21, 0x7b, 0x83, 0x8c,
-		0x6d, 0x76, 0xcd, 0x0d, 0x9f, 0xda, 0x1c, 0xa4,
-		0x6e, 0xfe, 0xb1, 0xf7, 0x09, 0x0d, 0xfb, 0x74,
-		0x66, 0x34, 0x99, 0x89, 0x7f, 0x5f, 0x77, 0x87,
-		0x4a, 0x66, 0x4b, 0xa9, 0x59, 0x57, 0xe3, 0x56,
-		0x0d, 0xdd, 0xd8, 0x14, 0x03, 0x01, 0x00, 0x01,
-		0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xc0, 0x4e,
-		0xd3, 0x0f, 0xb5, 0xc0, 0x57, 0xa6, 0x18, 0x80,
-		0x80, 0x6b, 0x49, 0xfe, 0xbd, 0x3a, 0x7a, 0x2c,
-		0xef, 0x70, 0xb5, 0x1c, 0xd2, 0xdf, 0x5f, 0x78,
-		0x5a, 0xd8, 0x4f, 0xa0, 0x95, 0xb4, 0xb3, 0xb5,
-		0xaa, 0x3b,
+		0x82, 0x00, 0x80, 0x39, 0xe2, 0x0f, 0x49, 0xa0,
+		0xe6, 0xe4, 0x3b, 0x0c, 0x5f, 0xce, 0x39, 0x97,
+		0x6c, 0xb6, 0x41, 0xd9, 0xe1, 0x52, 0x8f, 0x43,
+		0xb3, 0xc6, 0x4f, 0x9a, 0xe2, 0x1e, 0xb9, 0x3b,
+		0xe3, 0x72, 0x17, 0x68, 0xb2, 0x0d, 0x7b, 0x71,
+		0x33, 0x96, 0x5c, 0xf9, 0xfe, 0x18, 0x8f, 0x2f,
+		0x2b, 0x82, 0xec, 0x03, 0xf2, 0x16, 0xa8, 0xf8,
+		0x39, 0xf9, 0xbb, 0x5a, 0xd3, 0x0c, 0xc1, 0x2a,
+		0x52, 0xa1, 0x90, 0x20, 0x6b, 0x24, 0xc9, 0x55,
+		0xee, 0x05, 0xd8, 0xb3, 0x43, 0x58, 0xf6, 0x7f,
+		0x68, 0x2d, 0xb3, 0xd1, 0x1b, 0x30, 0xaa, 0xdf,
+		0xfc, 0x85, 0xf1, 0xab, 0x14, 0x51, 0x91, 0x78,
+		0x29, 0x35, 0x65, 0xe0, 0x9c, 0xf6, 0xb7, 0x35,
+		0x33, 0xdb, 0x28, 0x93, 0x4d, 0x86, 0xbc, 0xfe,
+		0xaa, 0xd1, 0xc0, 0x2e, 0x4d, 0xec, 0xa2, 0x98,
+		0xca, 0x08, 0xb2, 0x91, 0x14, 0xde, 0x97, 0x3a,
+		0xc4, 0x6b, 0x49, 0x14, 0x03, 0x01, 0x00, 0x01,
+		0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0x7a, 0xcb,
+		0x3b, 0x0e, 0xbb, 0x7a, 0x56, 0x39, 0xaf, 0x83,
+		0xae, 0xfd, 0x25, 0xfd, 0x64, 0xb4, 0x0c, 0x0c,
+		0x17, 0x46, 0x54, 0x2c, 0x6a, 0x07, 0x83, 0xc6,
+		0x46, 0x08, 0x0b, 0xcd, 0x15, 0x53, 0xef, 0x40,
+		0x4e, 0x56,
 	},
 
 	{
 		0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
-		0x01, 0x00, 0x24, 0x9d, 0xc9, 0xda, 0xdf, 0xeb,
-		0xc8, 0xdb, 0xf8, 0x94, 0xa5, 0xef, 0xd5, 0xfc,
-		0x89, 0x01, 0x64, 0x30, 0x77, 0x5a, 0x18, 0x4b,
-		0x16, 0x79, 0x9c, 0xf6, 0xf5, 0x09, 0x22, 0x12,
-		0x4c, 0x3e, 0xa8, 0x8e, 0x91, 0xa5, 0x24,
+		0x01, 0x00, 0x24, 0xd3, 0x72, 0xeb, 0x29, 0xb9,
+		0x15, 0x29, 0xb5, 0xe5, 0xb7, 0xef, 0x5c, 0xb2,
+		0x9d, 0xf6, 0xc8, 0x47, 0xd6, 0xa0, 0x84, 0xf0,
+		0x8c, 0xcb, 0xe6, 0xbe, 0xbc, 0xfb, 0x38, 0x90,
+		0x89, 0x60, 0xa2, 0xe8, 0xaa, 0xb3, 0x12, 0x17,
+		0x03, 0x01, 0x00, 0x21, 0x67, 0x4a, 0x3d, 0x31,
+		0x6c, 0x5a, 0x1c, 0xf9, 0x6e, 0xf1, 0xd8, 0x12,
+		0x0e, 0xb9, 0xfd, 0xfc, 0x66, 0x91, 0xd1, 0x1d,
+		0x6e, 0xe4, 0x55, 0xdd, 0x11, 0xb9, 0xb8, 0xa2,
+		0x65, 0xa1, 0x95, 0x64, 0x1c, 0x15, 0x03, 0x01,
+		0x00, 0x16, 0x9b, 0xa0, 0x24, 0xe3, 0xcb, 0xae,
+		0xad, 0x51, 0xb3, 0x63, 0x59, 0x78, 0x49, 0x24,
+		0x06, 0x6e, 0xee, 0x7a, 0xd7, 0x74, 0x53, 0x04,
 	},
 }
 
@@ -878,3 +946,625 @@ var sslv3ServerScript = [][]byte{
 		0xaf, 0xd3, 0xb7, 0xa3, 0xcc, 0x4a, 0x1d, 0x2e,
 	},
 }
+
+var clientauthTests = []clientauthTest{
+	// Server doesn't asks for cert
+	// gotest -test.run "TestRunServer" -serve -clientauth 0
+	// gnutls-cli --insecure --debug 100 -p 10443 localhost 2>&1 |
+	//   python parse-gnutls-cli-debug-log.py
+	{"NoClientCert", NoClientCert, nil,
+		[][]byte{{
+			0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
+			0x76, 0x03, 0x02, 0x4e, 0xe0, 0x92, 0x5d, 0xcd,
+			0xfe, 0x0c, 0x69, 0xd4, 0x7d, 0x8e, 0xa6, 0x88,
+			0xde, 0x72, 0x04, 0x29, 0x6a, 0x4a, 0x16, 0x23,
+			0xd7, 0x8f, 0xbc, 0xfa, 0x80, 0x73, 0x2e, 0x12,
+			0xb7, 0x0b, 0x39, 0x00, 0x00, 0x34, 0x00, 0x33,
+			0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
+			0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
+			0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
+			0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
+			0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
+			0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
+			0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
+			0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
+			0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
+			0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
+		},
+
+			{
+				0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
+				0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
+				0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
+				0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
+				0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
+				0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
+				0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
+				0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+				0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
+				0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+				0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
+				0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
+				0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
+				0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
+				0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
+				0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
+				0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
+				0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
+				0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
+				0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
+				0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
+				0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
+				0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+				0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
+				0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
+				0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
+				0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
+				0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
+				0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
+				0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
+				0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
+				0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+				0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
+				0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
+				0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
+				0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
+				0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
+				0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
+				0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
+				0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
+				0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
+				0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
+				0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
+				0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
+				0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
+				0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
+				0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
+				0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
+				0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
+				0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
+				0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
+				0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
+				0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
+				0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
+				0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
+				0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
+				0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
+				0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
+				0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
+				0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
+				0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+				0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
+				0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+				0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
+				0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
+				0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
+				0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
+				0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
+				0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
+				0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
+				0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
+				0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+				0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+				0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
+				0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
+				0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
+				0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
+				0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
+				0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
+				0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
+				0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
+				0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
+				0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
+				0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
+				0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
+				0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
+				0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
+				0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
+				0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
+				0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
+				0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e,
+				0x00, 0x00, 0x00,
+			},
+
+			{
+				0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
+				0x82, 0x00, 0x80, 0x10, 0xe1, 0x00, 0x3d, 0x0a,
+				0x6b, 0x02, 0x7f, 0x97, 0xde, 0xfb, 0x65, 0x46,
+				0x1a, 0x50, 0x4e, 0x34, 0x9a, 0xae, 0x14, 0x7e,
+				0xec, 0xef, 0x85, 0x15, 0x3b, 0x39, 0xc2, 0x45,
+				0x04, 0x40, 0x92, 0x71, 0xd6, 0x7e, 0xf6, 0xfd,
+				0x4d, 0x84, 0xf7, 0xc4, 0x77, 0x99, 0x3d, 0xe2,
+				0xc3, 0x8d, 0xb0, 0x4c, 0x74, 0xc8, 0x51, 0xec,
+				0xb2, 0xe8, 0x6b, 0xa1, 0xd2, 0x4d, 0xd8, 0x61,
+				0x92, 0x7a, 0x24, 0x57, 0x44, 0x4f, 0xa2, 0x1e,
+				0x74, 0x0b, 0x06, 0x4b, 0x80, 0x34, 0x8b, 0xfe,
+				0xc2, 0x0e, 0xc1, 0xcd, 0xab, 0x0c, 0x3f, 0x54,
+				0xe2, 0x44, 0xe9, 0x6c, 0x2b, 0xba, 0x7b, 0x64,
+				0xf1, 0x93, 0x65, 0x75, 0xf2, 0x35, 0xff, 0x27,
+				0x03, 0xd5, 0x64, 0xe6, 0x8e, 0xe7, 0x7b, 0x56,
+				0xb6, 0x61, 0x73, 0xeb, 0xa2, 0xdc, 0xa4, 0x6e,
+				0x52, 0xac, 0xbc, 0xba, 0x11, 0xa3, 0xd2, 0x61,
+				0x4a, 0xe0, 0xbb, 0x14, 0x03, 0x01, 0x00, 0x01,
+				0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xd2, 0x5a,
+				0x0c, 0x2a, 0x27, 0x96, 0xba, 0xa9, 0x67, 0xd2,
+				0x51, 0x68, 0x32, 0x68, 0x22, 0x1f, 0xb9, 0x27,
+				0x79, 0x59, 0x28, 0xdf, 0x38, 0x1f, 0x92, 0x21,
+				0x5d, 0x0f, 0xf4, 0xc0, 0xee, 0xb7, 0x10, 0x5a,
+				0xa9, 0x45,
+			},
+
+			{
+				0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
+				0x01, 0x00, 0x24, 0x13, 0x6f, 0x6c, 0x71, 0x83,
+				0x59, 0xcf, 0x32, 0x72, 0xe9, 0xce, 0xcc, 0x7a,
+				0x6c, 0xf0, 0x72, 0x39, 0x16, 0xae, 0x40, 0x61,
+				0xfa, 0x92, 0x4c, 0xe7, 0xf2, 0x1a, 0xd7, 0x0c,
+				0x84, 0x76, 0x6c, 0xe9, 0x11, 0x43, 0x19, 0x17,
+				0x03, 0x01, 0x00, 0x21, 0xc0, 0xa2, 0x13, 0x28,
+				0x94, 0x8c, 0x5c, 0xd6, 0x79, 0xb9, 0xfe, 0xae,
+				0x45, 0x4b, 0xc0, 0x7c, 0xae, 0x2d, 0xb4, 0x0d,
+				0x31, 0xc4, 0xad, 0x22, 0xd7, 0x1e, 0x99, 0x1c,
+				0x4c, 0x69, 0xab, 0x42, 0x61, 0x15, 0x03, 0x01,
+				0x00, 0x16, 0xe1, 0x0c, 0x67, 0xf3, 0xf4, 0xb9,
+				0x8e, 0x81, 0x8e, 0x01, 0xb8, 0xa0, 0x69, 0x8c,
+				0x03, 0x11, 0x43, 0x3e, 0xee, 0xb7, 0x4d, 0x69,
+			}}},
+	// Server asks for cert with empty CA list, client doesn't give it.
+	// gotest -test.run "TestRunServer" -serve -clientauth 1
+	// gnutls-cli --insecure --debug 100 -p 10443 localhost
+	{"RequestClientCert, none given", RequestClientCert, nil,
+		[][]byte{{
+			0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
+			0x76, 0x03, 0x02, 0x4e, 0xe0, 0x93, 0xe2, 0x47,
+			0x06, 0xa0, 0x61, 0x0c, 0x51, 0xdd, 0xf0, 0xef,
+			0xf4, 0x30, 0x72, 0xe1, 0xa6, 0x50, 0x68, 0x82,
+			0x3c, 0xfb, 0xcb, 0x72, 0x5e, 0x73, 0x9d, 0xda,
+			0x27, 0x35, 0x72, 0x00, 0x00, 0x34, 0x00, 0x33,
+			0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
+			0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
+			0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
+			0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
+			0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
+			0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
+			0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
+			0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
+			0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
+			0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
+		},
+
+			{
+				0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
+				0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
+				0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
+				0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
+				0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
+				0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
+				0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
+				0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+				0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
+				0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+				0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
+				0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
+				0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
+				0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
+				0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
+				0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
+				0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
+				0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
+				0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
+				0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
+				0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
+				0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
+				0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+				0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
+				0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
+				0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
+				0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
+				0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
+				0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
+				0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
+				0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
+				0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+				0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
+				0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
+				0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
+				0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
+				0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
+				0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
+				0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
+				0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
+				0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
+				0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
+				0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
+				0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
+				0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
+				0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
+				0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
+				0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
+				0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
+				0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
+				0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
+				0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
+				0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
+				0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
+				0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
+				0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
+				0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
+				0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
+				0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
+				0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
+				0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+				0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
+				0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+				0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
+				0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
+				0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
+				0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
+				0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
+				0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
+				0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
+				0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
+				0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+				0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+				0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
+				0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
+				0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
+				0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
+				0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
+				0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
+				0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
+				0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
+				0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
+				0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
+				0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
+				0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
+				0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
+				0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
+				0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
+				0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
+				0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
+				0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x08, 0x0d,
+				0x00, 0x00, 0x04, 0x01, 0x01, 0x00, 0x00, 0x16,
+				0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00,
+			},
+
+			{
+				0x16, 0x03, 0x01, 0x00, 0x07, 0x0b, 0x00, 0x00,
+				0x03, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, 0x00,
+				0x86, 0x10, 0x00, 0x00, 0x82, 0x00, 0x80, 0x64,
+				0x28, 0xb9, 0x3f, 0x48, 0xaf, 0x06, 0x22, 0x39,
+				0x56, 0xd8, 0x6f, 0x63, 0x5d, 0x03, 0x48, 0x63,
+				0x01, 0x13, 0xa2, 0xd6, 0x76, 0xc0, 0xab, 0xda,
+				0x25, 0x30, 0x75, 0x6c, 0xaa, 0xb4, 0xdc, 0x35,
+				0x72, 0xdc, 0xf2, 0x43, 0xe4, 0x1d, 0x82, 0xfb,
+				0x6c, 0x64, 0xe2, 0xa7, 0x8f, 0x32, 0x67, 0x6b,
+				0xcd, 0xd2, 0xb2, 0x36, 0x94, 0xbc, 0x6f, 0x46,
+				0x79, 0x29, 0x42, 0xe3, 0x1a, 0xbf, 0xfb, 0x41,
+				0xd5, 0xe3, 0xb4, 0x2a, 0xf6, 0x95, 0x6f, 0x0c,
+				0x87, 0xb9, 0x03, 0x18, 0xa1, 0xea, 0x4a, 0xe2,
+				0x2e, 0x0f, 0x50, 0x00, 0xc1, 0xe8, 0x8c, 0xc8,
+				0xa2, 0xf6, 0xa4, 0x05, 0xf4, 0x38, 0x3e, 0xd9,
+				0x6e, 0x63, 0x96, 0x0c, 0x34, 0x73, 0x90, 0x03,
+				0x55, 0xa6, 0x34, 0xb0, 0x5e, 0x8c, 0x48, 0x40,
+				0x25, 0x45, 0x84, 0xa6, 0x21, 0x3f, 0x81, 0x97,
+				0xa7, 0x11, 0x09, 0x14, 0x95, 0xa5, 0xe5, 0x14,
+				0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01,
+				0x00, 0x24, 0x16, 0xaa, 0x01, 0x2c, 0xa8, 0xc1,
+				0x28, 0xaf, 0x35, 0xc1, 0xc1, 0xf3, 0x0a, 0x25,
+				0x66, 0x6e, 0x27, 0x11, 0xa3, 0xa4, 0xd9, 0xe9,
+				0xea, 0x15, 0x09, 0x9d, 0x28, 0xe3, 0x5b, 0x2b,
+				0xa6, 0x25, 0xa7, 0x14, 0x24, 0x3a,
+			},
+
+			{
+				0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
+				0x01, 0x00, 0x24, 0x9a, 0xa8, 0xd6, 0x77, 0x46,
+				0x45, 0x68, 0x9d, 0x5d, 0xa9, 0x68, 0x03, 0xe5,
+				0xaf, 0xe8, 0xc8, 0x21, 0xc5, 0xc6, 0xc1, 0x50,
+				0xe0, 0xd8, 0x52, 0xce, 0xa3, 0x4f, 0x2d, 0xf4,
+				0xe3, 0xa7, 0x7d, 0x35, 0x80, 0x84, 0x12, 0x17,
+				0x03, 0x01, 0x00, 0x21, 0x8a, 0x82, 0x0c, 0x54,
+				0x1b, 0xeb, 0x77, 0x90, 0x2c, 0x3e, 0xbc, 0xf0,
+				0x23, 0xcc, 0xa8, 0x9f, 0x25, 0x08, 0x12, 0xed,
+				0x43, 0xf1, 0xf9, 0x06, 0xad, 0xa9, 0x4b, 0x97,
+				0x82, 0xb7, 0xc4, 0x0b, 0x4c, 0x15, 0x03, 0x01,
+				0x00, 0x16, 0x05, 0x2d, 0x9d, 0x45, 0x03, 0xb7,
+				0xc2, 0xd1, 0xb5, 0x1a, 0x43, 0xcf, 0x1a, 0x37,
+				0xf4, 0x70, 0xcc, 0xb4, 0xed, 0x07, 0x76, 0x3a,
+			}}},
+	// Server asks for cert with empty CA list, client gives one
+	// gotest -test.run "TestRunServer" -serve -clientauth 1
+	// gnutls-cli --insecure --debug 100 -p 10443 localhost
+	{"RequestClientCert, client gives it", RequestClientCert,
+		[]*x509.Certificate{clicert},
+		[][]byte{{
+			0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
+			0x76, 0x03, 0x02, 0x4e, 0xe7, 0x44, 0xda, 0x58,
+			0x7d, 0x46, 0x4a, 0x48, 0x97, 0x9f, 0xe5, 0x91,
+			0x11, 0x64, 0xa7, 0x1e, 0x4d, 0xb7, 0xfe, 0x9b,
+			0xc6, 0x63, 0xf8, 0xa4, 0xb5, 0x0b, 0x18, 0xb5,
+			0xbd, 0x19, 0xb3, 0x00, 0x00, 0x34, 0x00, 0x33,
+			0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
+			0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
+			0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
+			0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
+			0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
+			0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
+			0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
+			0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
+			0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
+			0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
+		},
+
+			{
+				0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
+				0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
+				0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
+				0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
+				0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
+				0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
+				0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
+				0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+				0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
+				0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+				0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
+				0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
+				0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
+				0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
+				0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
+				0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
+				0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
+				0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
+				0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
+				0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
+				0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
+				0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
+				0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+				0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
+				0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
+				0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
+				0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
+				0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
+				0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
+				0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
+				0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
+				0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+				0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
+				0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
+				0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
+				0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
+				0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
+				0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
+				0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
+				0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
+				0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
+				0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
+				0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
+				0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
+				0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
+				0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
+				0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
+				0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
+				0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
+				0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
+				0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
+				0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
+				0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
+				0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
+				0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
+				0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
+				0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
+				0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
+				0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
+				0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
+				0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+				0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
+				0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+				0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
+				0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
+				0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
+				0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
+				0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
+				0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
+				0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
+				0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
+				0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+				0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+				0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
+				0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
+				0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
+				0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
+				0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
+				0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
+				0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
+				0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
+				0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
+				0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
+				0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
+				0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
+				0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
+				0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
+				0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
+				0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
+				0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
+				0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x08, 0x0d,
+				0x00, 0x00, 0x04, 0x01, 0x01, 0x00, 0x00, 0x16,
+				0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00,
+			},
+
+			{
+				0x16, 0x03, 0x01, 0x01, 0xfb, 0x0b, 0x00, 0x01,
+				0xf7, 0x00, 0x01, 0xf4, 0x00, 0x01, 0xf1, 0x30,
+				0x82, 0x01, 0xed, 0x30, 0x82, 0x01, 0x58, 0xa0,
+				0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30,
+				0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+				0x0d, 0x01, 0x01, 0x05, 0x30, 0x26, 0x31, 0x10,
+				0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+				0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f,
+				0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+				0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30,
+				0x2e, 0x30, 0x2e, 0x31, 0x30, 0x1e, 0x17, 0x0d,
+				0x31, 0x31, 0x31, 0x32, 0x30, 0x38, 0x30, 0x37,
+				0x35, 0x35, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x31,
+				0x32, 0x31, 0x32, 0x30, 0x37, 0x30, 0x38, 0x30,
+				0x30, 0x31, 0x32, 0x5a, 0x30, 0x26, 0x31, 0x10,
+				0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+				0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f,
+				0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+				0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30,
+				0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9c, 0x30,
+				0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+				0x0d, 0x01, 0x01, 0x01, 0x03, 0x81, 0x8c, 0x00,
+				0x30, 0x81, 0x88, 0x02, 0x81, 0x80, 0x4e, 0xd0,
+				0x7b, 0x31, 0xe3, 0x82, 0x64, 0xd9, 0x59, 0xc0,
+				0xc2, 0x87, 0xa4, 0x5e, 0x1e, 0x8b, 0x73, 0x33,
+				0xc7, 0x63, 0x53, 0xdf, 0x66, 0x92, 0x06, 0x84,
+				0xf6, 0x64, 0xd5, 0x8f, 0xe4, 0x36, 0xa7, 0x1d,
+				0x2b, 0xe8, 0xb3, 0x20, 0x36, 0x45, 0x23, 0xb5,
+				0xe3, 0x95, 0xae, 0xed, 0xe0, 0xf5, 0x20, 0x9c,
+				0x8d, 0x95, 0xdf, 0x7f, 0x5a, 0x12, 0xef, 0x87,
+				0xe4, 0x5b, 0x68, 0xe4, 0xe9, 0x0e, 0x74, 0xec,
+				0x04, 0x8a, 0x7f, 0xde, 0x93, 0x27, 0xc4, 0x01,
+				0x19, 0x7a, 0xbd, 0xf2, 0xdc, 0x3d, 0x14, 0xab,
+				0xd0, 0x54, 0xca, 0x21, 0x0c, 0xd0, 0x4d, 0x6e,
+				0x87, 0x2e, 0x5c, 0xc5, 0xd2, 0xbb, 0x4d, 0x4b,
+				0x4f, 0xce, 0xb6, 0x2c, 0xf7, 0x7e, 0x88, 0xec,
+				0x7c, 0xd7, 0x02, 0x91, 0x74, 0xa6, 0x1e, 0x0c,
+				0x1a, 0xda, 0xe3, 0x4a, 0x5a, 0x2e, 0xde, 0x13,
+				0x9c, 0x4c, 0x40, 0x88, 0x59, 0x93, 0x02, 0x03,
+				0x01, 0x00, 0x01, 0xa3, 0x32, 0x30, 0x30, 0x30,
+				0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+				0xff, 0x04, 0x04, 0x03, 0x02, 0x00, 0xa0, 0x30,
+				0x0d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x06,
+				0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30, 0x0f,
+				0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x08, 0x30,
+				0x06, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30,
+				0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+				0x0d, 0x01, 0x01, 0x05, 0x03, 0x81, 0x81, 0x00,
+				0x36, 0x1f, 0xb3, 0x7a, 0x0c, 0x75, 0xc9, 0x6e,
+				0x37, 0x46, 0x61, 0x2b, 0xd5, 0xbd, 0xc0, 0xa7,
+				0x4b, 0xcc, 0x46, 0x9a, 0x81, 0x58, 0x7c, 0x85,
+				0x79, 0x29, 0xc8, 0xc8, 0xc6, 0x67, 0xdd, 0x32,
+				0x56, 0x45, 0x2b, 0x75, 0xb6, 0xe9, 0x24, 0xa9,
+				0x50, 0x9a, 0xbe, 0x1f, 0x5a, 0xfa, 0x1a, 0x15,
+				0xd9, 0xcc, 0x55, 0x95, 0x72, 0x16, 0x83, 0xb9,
+				0xc2, 0xb6, 0x8f, 0xfd, 0x88, 0x8c, 0x38, 0x84,
+				0x1d, 0xab, 0x5d, 0x92, 0x31, 0x13, 0x4f, 0xfd,
+				0x83, 0x3b, 0xc6, 0x9d, 0xf1, 0x11, 0x62, 0xb6,
+				0x8b, 0xec, 0xab, 0x67, 0xbe, 0xc8, 0x64, 0xb0,
+				0x11, 0x50, 0x46, 0x58, 0x17, 0x6b, 0x99, 0x1c,
+				0xd3, 0x1d, 0xfc, 0x06, 0xf1, 0x0e, 0xe5, 0x96,
+				0xa8, 0x0c, 0xf9, 0x78, 0x20, 0xb7, 0x44, 0x18,
+				0x51, 0x8d, 0x10, 0x7e, 0x4f, 0x94, 0x67, 0xdf,
+				0xa3, 0x4e, 0x70, 0x73, 0x8e, 0x90, 0x91, 0x85,
+				0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
+				0x82, 0x00, 0x80, 0xa7, 0x2f, 0xed, 0xfa, 0xc2,
+				0xbd, 0x46, 0xa1, 0xf2, 0x69, 0xc5, 0x1d, 0xa1,
+				0x34, 0xd6, 0xd0, 0x84, 0xf5, 0x5d, 0x8c, 0x82,
+				0x8d, 0x98, 0x82, 0x9c, 0xd9, 0x07, 0xe0, 0xf7,
+				0x55, 0x49, 0x4d, 0xa1, 0x48, 0x59, 0x02, 0xd3,
+				0x84, 0x37, 0xaf, 0x01, 0xb3, 0x3a, 0xf4, 0xed,
+				0x99, 0xbe, 0x67, 0x36, 0x19, 0x55, 0xf3, 0xf9,
+				0xcb, 0x94, 0xe5, 0x7b, 0x8b, 0x77, 0xf2, 0x5f,
+				0x4c, 0xfe, 0x01, 0x1f, 0x7b, 0xd7, 0x23, 0x49,
+				0x0c, 0xcb, 0x6c, 0xb0, 0xe7, 0x77, 0xd6, 0xcf,
+				0xa8, 0x7d, 0xdb, 0xa7, 0x14, 0xe2, 0xf5, 0xf3,
+				0xff, 0xba, 0x23, 0xd2, 0x9a, 0x36, 0x14, 0x60,
+				0x2a, 0x91, 0x5d, 0x2b, 0x35, 0x3b, 0xb6, 0xdd,
+				0xcb, 0x6b, 0xdc, 0x18, 0xdc, 0x33, 0xb8, 0xb3,
+				0xc7, 0x27, 0x7e, 0xfc, 0xd2, 0xf7, 0x97, 0x90,
+				0x5e, 0x17, 0xac, 0x14, 0x8e, 0x0f, 0xca, 0xb5,
+				0x6f, 0xc9, 0x2d, 0x16, 0x03, 0x01, 0x00, 0x86,
+				0x0f, 0x00, 0x00, 0x82, 0x00, 0x80, 0x44, 0x7f,
+				0xa2, 0x59, 0x60, 0x0b, 0x5a, 0xc4, 0xaf, 0x1e,
+				0x60, 0xa5, 0x24, 0xea, 0xc1, 0xc3, 0x22, 0x21,
+				0x6b, 0x22, 0x8b, 0x2a, 0x11, 0x82, 0x68, 0x7d,
+				0xb9, 0xdd, 0x9c, 0x27, 0x4c, 0xc2, 0xc8, 0xa2,
+				0x8b, 0x6b, 0x77, 0x8d, 0x3a, 0x2b, 0x8d, 0x2f,
+				0x6a, 0x2b, 0x43, 0xd2, 0xd1, 0xc6, 0x41, 0x79,
+				0xa2, 0x4f, 0x2b, 0xc2, 0xf7, 0xb2, 0x10, 0xad,
+				0xa6, 0x01, 0x51, 0x51, 0x25, 0xe7, 0x58, 0x7a,
+				0xcf, 0x3b, 0xc4, 0x29, 0xb5, 0xe5, 0xa7, 0x83,
+				0xe6, 0xcb, 0x1e, 0xf3, 0x02, 0x0f, 0x53, 0x3b,
+				0xb5, 0x39, 0xef, 0x9c, 0x42, 0xe0, 0xa6, 0x9b,
+				0x2b, 0xdd, 0x60, 0xae, 0x0a, 0x73, 0x35, 0xbe,
+				0x26, 0x10, 0x1b, 0xe9, 0xe9, 0x61, 0xab, 0x20,
+				0xa5, 0x48, 0xc6, 0x60, 0xa6, 0x50, 0x3c, 0xfb,
+				0xa7, 0xca, 0xb0, 0x80, 0x95, 0x1e, 0xce, 0xc7,
+				0xbb, 0x68, 0x44, 0xdc, 0x0e, 0x0e, 0x14, 0x03,
+				0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, 0x00,
+				0x24, 0xb6, 0xcd, 0x0c, 0x78, 0xfd, 0xd6, 0xff,
+				0xbe, 0x97, 0xd5, 0x0a, 0x7d, 0x4f, 0xa1, 0x03,
+				0x78, 0xc8, 0x61, 0x6f, 0xf2, 0x4b, 0xa8, 0x56,
+				0x4f, 0x3c, 0xa2, 0xd9, 0xd0, 0x20, 0x13, 0x1b,
+				0x8b, 0x36, 0xb7, 0x33, 0x9c,
+			},
+
+			{
+				0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
+				0x01, 0x00, 0x24, 0xa3, 0x43, 0x94, 0xe7, 0xdf,
+				0xb6, 0xc3, 0x03, 0x9f, 0xc1, 0x59, 0x0c, 0xc3,
+				0x13, 0xae, 0xed, 0xcf, 0xff, 0xf1, 0x80, 0xf3,
+				0x13, 0x63, 0x1c, 0xf0, 0xca, 0xad, 0x9e, 0x71,
+				0x46, 0x5f, 0x6b, 0xeb, 0x10, 0x3f, 0xe3, 0x17,
+				0x03, 0x01, 0x00, 0x21, 0xe9, 0x80, 0x95, 0x6e,
+				0x05, 0x55, 0x2f, 0xed, 0x4d, 0xde, 0x17, 0x3a,
+				0x32, 0x9b, 0x2a, 0x74, 0x30, 0x4f, 0xe0, 0x9f,
+				0x4e, 0xd3, 0x06, 0xbd, 0x3a, 0x43, 0x75, 0x8b,
+				0x5b, 0x9a, 0xd8, 0x2e, 0x56, 0x15, 0x03, 0x01,
+				0x00, 0x16, 0x53, 0xf5, 0xff, 0xe0, 0xa1, 0x6c,
+				0x33, 0xf4, 0x4e, 0x89, 0x68, 0xe1, 0xf7, 0x61,
+				0x13, 0xb3, 0x12, 0xa1, 0x8e, 0x5a, 0x7a, 0x02,
+			}}},
+}
+
+// cert.pem and key.pem were generated with generate_cert.go
+// Thus, they have no ExtKeyUsage fields and trigger an error
+// when verification is turned on.
+
+var clicert = loadPEMCert(`
+-----BEGIN CERTIFICATE-----
+MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD
+bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4
+MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc
+MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG
+hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE
+ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e
+E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw
+DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A
+p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4
+hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE
+GFGNEH5PlGffo05wc46QkYU=
+-----END CERTIFICATE-----
+`)
+
+/* corresponding key.pem for cert.pem is:
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgE7QezHjgmTZWcDCh6ReHotzM8djU99mkgaE9mTVj+Q2px0r6LMg
+NkUjteOVru3g9SCcjZXff1oS74fkW2jk6Q507ASKf96TJ8QBGXq98tw9FKvQVMoh
+DNBNbocuXMXSu01LT862LPd+iOx81wKRdKYeDBra40paLt4TnExAiFmTAgMBAAEC
+gYBxvXd8yNteFTns8A/2yomEMC4yeosJJSpp1CsN3BJ7g8/qTnrVPxBy+RU+qr63
+t2WquaOu/cr5P8iEsa6lk20tf8pjKLNXeX0b1RTzK8rJLbS7nGzP3tvOhL096VtQ
+dAo4ROEaro0TzYpHmpciSvxVIeEIAAdFDObDJPKqcJAxyQJBAJizfYgK8Gzx9fsx
+hxp+VteCbVPg2euASH5Yv3K5LukRdKoSzHE2grUVQgN/LafC0eZibRanxHegYSr7
+7qaswKUCQQCEIWor/X4XTMdVj3Oj+vpiw75y/S9gh682+myZL+d/02IEkwnB098P
+RkKVpenBHyrGg0oeN5La7URILWKj7CPXAkBKo6F+d+phNjwIFoN1Xb/RA32w/D1I
+saG9sF+UEhRt9AxUfW/U/tIQ9V0ZHHcSg1XaCM5Nvp934brdKdvTOKnJAkBD5h/3
+Rybatlvg/fzBEaJFyq09zhngkxlZOUtBVTqzl17RVvY2orgH02U4HbCHy4phxOn7
+qTdQRYlHRftgnWK1AkANibn9PRYJ7mJyJ9Dyj2QeNcSkSTzrt0tPvUMf4+meJymN
+1Ntu5+S1DLLzfxlaljWG6ylW6DNxujCyuXIV2rvAMAA=
+-----END RSA PRIVATE KEY-----
+*/
diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go
index 79ab502..28e93a0 100644
--- a/libgo/go/crypto/tls/tls.go
+++ b/libgo/go/crypto/tls/tls.go
@@ -120,7 +120,7 @@ func Dial(network, addr string, config *Config) (*Conn, error) {
 
 // LoadX509KeyPair reads and parses a public/private key pair from a pair of
 // files. The files must contain PEM encoded data.
-func LoadX509KeyPair(certFile string, keyFile string) (cert Certificate, err error) {
+func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) {
 	certPEMBlock, err := ioutil.ReadFile(certFile)
 	if err != nil {
 		return
diff --git a/libgo/go/crypto/x509/cert_pool.go b/libgo/go/crypto/x509/cert_pool.go
index 5a0a876..616a0b3 100644
--- a/libgo/go/crypto/x509/cert_pool.go
+++ b/libgo/go/crypto/x509/cert_pool.go
@@ -101,3 +101,13 @@ func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
 
 	return
 }
+
+// Subjects returns a list of the DER-encoded subjects of
+// all of the certificates in the pool. 
+func (s *CertPool) Subjects() (res [][]byte) {
+	res = make([][]byte, len(s.certs))
+	for i, c := range s.certs {
+		res[i] = c.RawSubject
+	}
+	return
+}
-- 
cgit v1.1