Commit ca986a2c authored by John Shahid's avatar John Shahid Committed by Adam Langley

crypto/tls: Check all certificates in the path.

Currently we only check the leaf node's issuer against the list of
distinguished names in the server's CertificateRequest message. This
will fail if the client certiciate has more than one certificate in
the path and the leaf node issuer isn't in the list of distinguished
names, but the issuer's issuer was in the distinguished names.

R=agl, agl
CC=gobot, golang-dev
https://golang.org/cl/9795043
parent 9fae8658
...@@ -165,7 +165,7 @@ func (c *Conn) clientHandshake() error { ...@@ -165,7 +165,7 @@ func (c *Conn) clientHandshake() error {
} }
} }
var certToSend *Certificate var chainToSend *Certificate
var certRequested bool var certRequested bool
certReq, ok := msg.(*certificateRequestMsg) certReq, ok := msg.(*certificateRequestMsg)
if ok { if ok {
...@@ -197,37 +197,41 @@ func (c *Conn) clientHandshake() error { ...@@ -197,37 +197,41 @@ func (c *Conn) clientHandshake() error {
// where SignatureAlgorithm is RSA and the Issuer is in // where SignatureAlgorithm is RSA and the Issuer is in
// certReq.certificateAuthorities // certReq.certificateAuthorities
findCert: findCert:
for i, cert := range c.config.Certificates { for i, chain := range c.config.Certificates {
if !rsaAvail { if !rsaAvail {
continue continue
} }
leaf := cert.Leaf for j, cert := range chain.Certificate {
if leaf == nil { x509Cert := chain.Leaf
if leaf, err = x509.ParseCertificate(cert.Certificate[0]); err != nil { // parse the certificate if this isn't the leaf
// node, or if chain.Leaf was nil
if j != 0 || x509Cert == nil {
if x509Cert, err = x509.ParseCertificate(cert); err != nil {
c.sendAlert(alertInternalError) c.sendAlert(alertInternalError)
return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
} }
} }
if leaf.PublicKeyAlgorithm != x509.RSA { if x509Cert.PublicKeyAlgorithm != x509.RSA {
continue continue findCert
} }
if len(certReq.certificateAuthorities) == 0 { if len(certReq.certificateAuthorities) == 0 {
// they gave us an empty list, so just take the // they gave us an empty list, so just take the
// first RSA cert from c.config.Certificates // first RSA cert from c.config.Certificates
certToSend = &cert chainToSend = &chain
break break findCert
} }
for _, ca := range certReq.certificateAuthorities { for _, ca := range certReq.certificateAuthorities {
if bytes.Equal(leaf.RawIssuer, ca) { if bytes.Equal(x509Cert.RawIssuer, ca) {
certToSend = &cert chainToSend = &chain
break findCert break findCert
} }
} }
} }
}
msg, err = c.readHandshake() msg, err = c.readHandshake()
if err != nil { if err != nil {
...@@ -246,8 +250,8 @@ func (c *Conn) clientHandshake() error { ...@@ -246,8 +250,8 @@ func (c *Conn) clientHandshake() error {
// certificate to send. // certificate to send.
if certRequested { if certRequested {
certMsg = new(certificateMsg) certMsg = new(certificateMsg)
if certToSend != nil { if chainToSend != nil {
certMsg.certificates = certToSend.Certificate certMsg.certificates = chainToSend.Certificate
} }
finishedHash.Write(certMsg.marshal()) finishedHash.Write(certMsg.marshal())
c.writeRecord(recordTypeHandshake, certMsg.marshal()) c.writeRecord(recordTypeHandshake, certMsg.marshal())
...@@ -263,7 +267,7 @@ func (c *Conn) clientHandshake() error { ...@@ -263,7 +267,7 @@ func (c *Conn) clientHandshake() error {
c.writeRecord(recordTypeHandshake, ckx.marshal()) c.writeRecord(recordTypeHandshake, ckx.marshal())
} }
if certToSend != nil { if chainToSend != nil {
certVerify := new(certificateVerifyMsg) certVerify := new(certificateVerifyMsg)
digest := make([]byte, 0, 36) digest := make([]byte, 0, 36)
digest = finishedHash.serverMD5.Sum(digest) digest = finishedHash.serverMD5.Sum(digest)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment