mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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
This commit is contained in:
parent
9fae8658ba
commit
ca986a2c81
2 changed files with 940 additions and 24 deletions
|
|
@ -165,7 +165,7 @@ func (c *Conn) clientHandshake() error {
|
|||
}
|
||||
}
|
||||
|
||||
var certToSend *Certificate
|
||||
var chainToSend *Certificate
|
||||
var certRequested bool
|
||||
certReq, ok := msg.(*certificateRequestMsg)
|
||||
if ok {
|
||||
|
|
@ -197,35 +197,39 @@ func (c *Conn) clientHandshake() error {
|
|||
// where SignatureAlgorithm is RSA and the Issuer is in
|
||||
// certReq.certificateAuthorities
|
||||
findCert:
|
||||
for i, cert := range c.config.Certificates {
|
||||
for i, chain := range c.config.Certificates {
|
||||
if !rsaAvail {
|
||||
continue
|
||||
}
|
||||
|
||||
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())
|
||||
for j, cert := range chain.Certificate {
|
||||
x509Cert := chain.Leaf
|
||||
// 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)
|
||||
return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if leaf.PublicKeyAlgorithm != x509.RSA {
|
||||
continue
|
||||
}
|
||||
if x509Cert.PublicKeyAlgorithm != x509.RSA {
|
||||
continue findCert
|
||||
}
|
||||
|
||||
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
|
||||
if len(certReq.certificateAuthorities) == 0 {
|
||||
// they gave us an empty list, so just take the
|
||||
// first RSA cert from c.config.Certificates
|
||||
chainToSend = &chain
|
||||
break findCert
|
||||
}
|
||||
|
||||
for _, ca := range certReq.certificateAuthorities {
|
||||
if bytes.Equal(x509Cert.RawIssuer, ca) {
|
||||
chainToSend = &chain
|
||||
break findCert
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,8 +250,8 @@ func (c *Conn) clientHandshake() error {
|
|||
// certificate to send.
|
||||
if certRequested {
|
||||
certMsg = new(certificateMsg)
|
||||
if certToSend != nil {
|
||||
certMsg.certificates = certToSend.Certificate
|
||||
if chainToSend != nil {
|
||||
certMsg.certificates = chainToSend.Certificate
|
||||
}
|
||||
finishedHash.Write(certMsg.marshal())
|
||||
c.writeRecord(recordTypeHandshake, certMsg.marshal())
|
||||
|
|
@ -263,7 +267,7 @@ func (c *Conn) clientHandshake() error {
|
|||
c.writeRecord(recordTypeHandshake, ckx.marshal())
|
||||
}
|
||||
|
||||
if certToSend != nil {
|
||||
if chainToSend != nil {
|
||||
certVerify := new(certificateVerifyMsg)
|
||||
digest := make([]byte, 0, 36)
|
||||
digest = finishedHash.serverMD5.Sum(digest)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue