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
diff --git a/src/pkg/asn1/asn1.go b/src/pkg/asn1/asn1.go
index 3e3bb10..cd23fd7 100644
--- a/src/pkg/asn1/asn1.go
+++ b/src/pkg/asn1/asn1.go
@@ -290,6 +290,14 @@
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 @@
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 @@
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 3ea0f09..4a5eca1 100644
--- a/src/pkg/asn1/common.go
+++ b/src/pkg/asn1/common.go
@@ -28,6 +28,7 @@
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 78566fa..9bf9f21 100644
--- a/src/pkg/crypto/tls/conn.go
+++ b/src/pkg/crypto/tls/conn.go
@@ -675,5 +675,13 @@
// 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 27e32cc..2aec160 100644
--- a/src/pkg/crypto/tls/tls.go
+++ b/src/pkg/crypto/tls/tls.go
@@ -67,7 +67,13 @@
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