]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: better error messages for certificate issues.
authorAdam Langley <agl@golang.org>
Mon, 11 Oct 2010 14:39:56 +0000 (10:39 -0400)
committerAdam Langley <agl@golang.org>
Mon, 11 Oct 2010 14:39:56 +0000 (10:39 -0400)
        Fixes #1146.

R=rsc, agl1
CC=golang-dev
https://golang.org/cl/2380042

src/pkg/crypto/tls/handshake_client.go
src/pkg/crypto/tls/handshake_server.go
src/pkg/crypto/tls/tls.go

index a37fc78ccaf1620fba1da93c56903967906f8431..bef6d20de897ef128fa617f113732e401fa8d962 100644 (file)
@@ -37,7 +37,8 @@ func (c *Conn) clientHandshake() os.Error {
        hello.random[3] = byte(t)
        _, err := io.ReadFull(c.config.Rand, hello.random[4:])
        if err != nil {
-               return c.sendAlert(alertInternalError)
+               c.sendAlert(alertInternalError)
+               return os.ErrorString("short read from Rand")
        }
 
        finishedHash.Write(hello.marshal())
@@ -79,14 +80,16 @@ func (c *Conn) clientHandshake() os.Error {
        for i, asn1Data := range certMsg.certificates {
                cert, err := x509.ParseCertificate(asn1Data)
                if err != nil {
-                       return c.sendAlert(alertBadCertificate)
+                       c.sendAlert(alertBadCertificate)
+                       return os.ErrorString("failed to parse certificate from server: " + err.String())
                }
                certs[i] = cert
        }
 
        for i := 1; i < len(certs); i++ {
                if !certs[i].BasicConstraintsValid || !certs[i].IsCA {
-                       return c.sendAlert(alertBadCertificate)
+                       c.sendAlert(alertBadCertificate)
+                       return os.ErrorString("intermediate certificate does not have CA bit set")
                }
                // KeyUsage status flags are ignored. From Engineering
                // Security, Peter Gutmann:
@@ -109,7 +112,8 @@ func (c *Conn) clientHandshake() os.Error {
                // could only be used for Diffie-Hellman key agreement.
 
                if err := certs[i-1].CheckSignatureFrom(certs[i]); err != nil {
-                       return c.sendAlert(alertBadCertificate)
+                       c.sendAlert(alertBadCertificate)
+                       return os.ErrorString("could not validate certificate signature: " + err.String())
                }
        }
 
@@ -117,10 +121,12 @@ func (c *Conn) clientHandshake() os.Error {
        if c.config.RootCAs != nil {
                root := c.config.RootCAs.FindParent(certs[len(certs)-1])
                if root == nil {
-                       return c.sendAlert(alertBadCertificate)
+                       c.sendAlert(alertBadCertificate)
+                       return os.ErrorString("could not find root certificate for chain")
                }
-               if certs[len(certs)-1].CheckSignatureFrom(root) != nil {
-                       return c.sendAlert(alertBadCertificate)
+               if err := certs[len(certs)-1].CheckSignatureFrom(root); err != nil {
+                       c.sendAlert(alertBadCertificate)
+                       return os.ErrorString("could not validate signature from expected root: " + err.String())
                }
        }
 
index 118dd4352f31a16d706de986f1a4e9a3e2dab250..71cbe6a4dd021e5e7deb3ce3ef7562bfc69f9221 100644 (file)
@@ -145,7 +145,8 @@ func (c *Conn) serverHandshake() os.Error {
                for i, asn1Data := range certMsg.certificates {
                        cert, err := x509.ParseCertificate(asn1Data)
                        if err != nil {
-                               return c.sendAlert(alertBadCertificate)
+                               c.sendAlert(alertBadCertificate)
+                               return os.ErrorString("could not parse client's certificate: " + err.String())
                        }
                        certs[i] = cert
                }
@@ -153,7 +154,8 @@ func (c *Conn) serverHandshake() os.Error {
                // 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 {
-                               return c.sendAlert(alertBadCertificate)
+                               c.sendAlert(alertBadCertificate)
+                               return os.ErrorString("could not validate certificate signature: " + err.String())
                        }
                }
 
@@ -199,7 +201,8 @@ func (c *Conn) serverHandshake() os.Error {
                copy(digest[16:36], finishedHash.serverSHA1.Sum())
                err = rsa.VerifyPKCS1v15(pub, rsa.HashMD5SHA1, digest, certVerify.signature)
                if err != nil {
-                       return c.sendAlert(alertBadCertificate)
+                       c.sendAlert(alertBadCertificate)
+                       return os.ErrorString("could not validate signature of connection nonces: " + err.String())
                }
 
                finishedHash.Write(certVerify.marshal())
index 2aec160a1e35761249d8cde62b96d0d4a4ee2a7a..052212f0bbe50cd7fe4916c8211e6616cfc8725d 100644 (file)
@@ -76,7 +76,8 @@ func Dial(network, laddr, raddr string) (net.Conn, os.Error) {
        return nil, err
 }
 
-// LoadX509KeyPair
+// 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 os.Error) {
        certPEMBlock, err := ioutil.ReadFile(certFile)
        if err != nil {