Commit 6a1022a0 authored by Adam Langley's avatar Adam Langley

crypto/tls: fix TLS 1.2 client certificates.

With TLS 1.2, when sending client certificates the code was omitting
the new (in TLS 1.2) signature and hash fields.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/13413050
parent 5ffc0f8f
......@@ -281,17 +281,24 @@ func (c *Conn) clientHandshake() error {
if chainToSend != nil {
var signed []byte
certVerify := new(certificateVerifyMsg)
certVerify := &certificateVerifyMsg{
hasSignatureAndHash: c.vers >= VersionTLS12,
}
switch key := c.config.Certificates[0].PrivateKey.(type) {
case *ecdsa.PrivateKey:
digest, _ := finishedHash.hashForClientCertificate(signatureECDSA)
digest, _, hashId := finishedHash.hashForClientCertificate(signatureECDSA)
r, s, err := ecdsa.Sign(c.config.rand(), key, digest)
if err == nil {
signed, err = asn1.Marshal(ecdsaSignature{r, s})
}
certVerify.signatureAndHash.signature = signatureECDSA
certVerify.signatureAndHash.hash = hashId
case *rsa.PrivateKey:
digest, hashFunc := finishedHash.hashForClientCertificate(signatureRSA)
digest, hashFunc, hashId := finishedHash.hashForClientCertificate(signatureRSA)
signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest)
certVerify.signatureAndHash.signature = signatureRSA
certVerify.signatureAndHash.hash = hashId
default:
err = errors.New("unknown private key type")
}
......
This diff is collapsed.
......@@ -402,13 +402,13 @@ func (hs *serverHandshakeState) doFullHandshake() error {
err = errors.New("ECDSA signature contained zero or negative values")
break
}
digest, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA)
digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA)
if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
err = errors.New("ECDSA verification failure")
break
}
case *rsa.PublicKey:
digest, hashFunc := hs.finishedHash.hashForClientCertificate(signatureRSA)
digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA)
err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
}
if err != nil {
......
......@@ -272,20 +272,20 @@ func (h finishedHash) serverSum(masterSecret []byte) []byte {
return out
}
// hashForClientCertificate returns a digest and hash function identifier
// suitable for signing by a TLS client certificate.
func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash) {
// hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash
// id suitable for signing by a TLS client certificate.
func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash, uint8) {
if h.version >= VersionTLS12 {
digest := h.server.Sum(nil)
return digest, crypto.SHA256
return digest, crypto.SHA256, hashSHA256
}
if sigType == signatureECDSA {
digest := h.server.Sum(nil)
return digest, crypto.SHA1
return digest, crypto.SHA1, hashSHA1
}
digest := make([]byte, 0, 36)
digest = h.serverMD5.Sum(digest)
digest = h.server.Sum(digest)
return digest, crypto.MD5SHA1
return digest, crypto.MD5SHA1, 0 /* not specified in TLS 1.2. */
}
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