crypto/tls: enable certificate validation on the client

Support validation of ECDSA and RSASSA-PSS signatures. Explicitly do not
support PKCS1-v1_5 signatures since these are not allowed for handshake
messages.
This commit is contained in:
Peter Wu 2017-09-15 19:04:39 +01:00
parent 92d04f3ebd
commit 0b636d21fb
2 changed files with 36 additions and 2 deletions

33
13.go
View File

@ -736,6 +736,30 @@ func (hs *serverHandshakeState) traceErr(err error) {
} }
} }
func (hs *clientHandshakeState) processCertsFromServer13(certMsg *certificateMsg13) error {
certs := make([][]byte, len(certMsg.certificates))
for i, cert := range certMsg.certificates {
certs[i] = cert.data
}
return hs.processCertsFromServer(certs)
}
func (hs *clientHandshakeState) verifyPeerCertificate(certVerify *certificateVerifyMsg) error {
pub := hs.c.peerCertificates[0].PublicKey
_, sigType, hashFunc, err := pickSignatureAlgorithm(pub, []SignatureScheme{certVerify.signatureAlgorithm}, hs.hello.supportedSignatureAlgorithms, hs.c.vers)
if err != nil {
hs.c.sendAlert(alertHandshakeFailure)
return err
}
digest := prepareDigitallySigned(hashFunc, "TLS 1.3, server CertificateVerify", hs.keySchedule.transcriptHash.Sum(nil))
err = verifyHandshakeSignature(sigType, pub, hashFunc, digest, certVerify.signature)
if err != nil {
hs.c.sendAlert(alertDecryptError)
return err
}
return nil
}
func (hs *clientHandshakeState) doTLS13Handshake() error { func (hs *clientHandshakeState) doTLS13Handshake() error {
c := hs.c c := hs.c
hash := hashForSuite(hs.suite) hash := hashForSuite(hs.suite)
@ -796,7 +820,10 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
return unexpectedMessageError(certMsg, msg) return unexpectedMessageError(certMsg, msg)
} }
hs.keySchedule.write(certMsg.marshal()) hs.keySchedule.write(certMsg.marshal())
// TODO process Certificate // Validate certificates.
if err := hs.processCertsFromServer13(certMsg); err != nil {
return err
}
// Receive CertificateVerify message. // Receive CertificateVerify message.
msg, err = c.readHandshake() msg, err = c.readHandshake()
@ -808,7 +835,9 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
c.sendAlert(alertUnexpectedMessage) c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(certVerifyMsg, msg) return unexpectedMessageError(certVerifyMsg, msg)
} }
// TODO process CertificateVerify if err = hs.verifyPeerCertificate(certVerifyMsg); err != nil {
return err
}
hs.keySchedule.write(certVerifyMsg.marshal()) hs.keySchedule.write(certVerifyMsg.marshal())
// Receive Finished message. // Receive Finished message.

View File

@ -45,6 +45,11 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S
panic("tls: supported signature algorithm has an unknown hash function") panic("tls: supported signature algorithm has an unknown hash function")
} }
sigType := signatureFromSignatureScheme(sigAlg) sigType := signatureFromSignatureScheme(sigAlg)
if (sigType == signaturePKCS1v15 || hashAlg == crypto.SHA1) && tlsVersion >= VersionTLS13 {
// TLS 1.3 forbids RSASSA-PKCS1-v1_5 and SHA-1 for
// handshake messages.
continue
}
switch pubkey.(type) { switch pubkey.(type) {
case *rsa.PublicKey: case *rsa.PublicKey:
if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS { if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS {