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