diff options
author | Adam Langley <agl@golang.org> | 2010-09-20 10:32:08 -0400 |
---|---|---|
committer | Adam Langley <agl@golang.org> | 2010-09-20 10:32:08 -0400 |
commit | 6989f6e312d52b9f4a200cb4691206b654669b36 (patch) | |
tree | 2823ac804643b61c80c163a658ad023c28d50b7f | |
parent | 724886b0c05f5eb5236e99d8c01b239eca9d3b91 (diff) | |
download | go-6989f6e312d52b9f4a200cb4691206b654669b36.tar.gz go-6989f6e312d52b9f4a200cb4691206b654669b36.zip |
Fix certificate validation.
asn1: add support for T61String because this is the string type which
several www.google.com certificates are now using for fields like
CommonName
tls: force a handshake in Dial so that certificates are ready
afterwards.
Fixes #1114.
R=rsc
CC=golang-dev
https://golang.org/cl/2216043
-rw-r--r-- | src/pkg/asn1/asn1.go | 12 | ||||
-rw-r--r-- | src/pkg/asn1/common.go | 1 | ||||
-rw-r--r-- | src/pkg/crypto/tls/conn.go | 10 | ||||
-rw-r--r-- | src/pkg/crypto/tls/tls.go | 8 |
4 files changed, 29 insertions, 2 deletions
diff --git a/src/pkg/asn1/asn1.go b/src/pkg/asn1/asn1.go index 3e3bb105b6..cd23fd7645 100644 --- a/src/pkg/asn1/asn1.go +++ b/src/pkg/asn1/asn1.go @@ -290,6 +290,14 @@ func parseIA5String(bytes []byte) (ret string, err os.Error) { return } +// T61String + +// parseT61String parses a ASN.1 T61String (8-bit clean string) from the given +// byte array and returns it. +func parseT61String(bytes []byte) (ret string, err os.Error) { + return string(bytes), nil +} + // A RawValue represents an undecoded ASN.1 object. type RawValue struct { Class, Tag int @@ -472,6 +480,8 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam result, err = parsePrintableString(innerBytes) case tagIA5String: result, err = parseIA5String(innerBytes) + case tagT61String: + result, err = parseT61String(innerBytes) case tagInteger: result, err = parseInt64(innerBytes) case tagBitString: @@ -689,6 +699,8 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam v, err = parsePrintableString(innerBytes) case tagIA5String: v, err = parseIA5String(innerBytes) + case tagT61String: + v, err = parseT61String(innerBytes) default: err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)} } diff --git a/src/pkg/asn1/common.go b/src/pkg/asn1/common.go index 3ea0f09b12..4a5eca1450 100644 --- a/src/pkg/asn1/common.go +++ b/src/pkg/asn1/common.go @@ -28,6 +28,7 @@ const ( tagSequence = 16 tagSet = 17 tagPrintableString = 19 + tagT61String = 20 tagIA5String = 22 tagUTCTime = 23 tagGeneralizedTime = 24 diff --git a/src/pkg/crypto/tls/conn.go b/src/pkg/crypto/tls/conn.go index 78566fa8c5..9bf9f21851 100644 --- a/src/pkg/crypto/tls/conn.go +++ b/src/pkg/crypto/tls/conn.go @@ -675,5 +675,13 @@ func (c *Conn) PeerCertificates() []*x509.Certificate { // connecting to host. If so, it returns nil; if not, it returns an os.Error // describing the problem. func (c *Conn) VerifyHostname(host string) os.Error { - return c.PeerCertificates()[0].VerifyHostname(host) + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() + if !c.isClient { + return os.ErrorString("VerifyHostname called on TLS server connection") + } + if !c.handshakeComplete { + return os.ErrorString("TLS handshake has not yet been performed") + } + return c.peerCertificates[0].VerifyHostname(host) } diff --git a/src/pkg/crypto/tls/tls.go b/src/pkg/crypto/tls/tls.go index 27e32cc2f2..2aec160a1e 100644 --- a/src/pkg/crypto/tls/tls.go +++ b/src/pkg/crypto/tls/tls.go @@ -67,7 +67,13 @@ func Dial(network, laddr, raddr string) (net.Conn, os.Error) { if err != nil { return nil, err } - return Client(c, nil), nil + conn := Client(c, nil) + err = conn.Handshake() + if err == nil { + return conn, nil + } + c.Close() + return nil, err } // LoadX509KeyPair |