From 0b636d21fbbfbccb136024ceab46bea76e484af4 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Fri, 15 Sep 2017 19:04:39 +0100 Subject: [PATCH] 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. --- 13.go | 33 +++++++++++++++++++++++++++++++-- auth.go | 5 +++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/13.go b/13.go index 73199a7..cc30624 100644 --- a/13.go +++ b/13.go @@ -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 { c := hs.c hash := hashForSuite(hs.suite) @@ -796,7 +820,10 @@ func (hs *clientHandshakeState) doTLS13Handshake() error { return unexpectedMessageError(certMsg, msg) } hs.keySchedule.write(certMsg.marshal()) - // TODO process Certificate + // Validate certificates. + if err := hs.processCertsFromServer13(certMsg); err != nil { + return err + } // Receive CertificateVerify message. msg, err = c.readHandshake() @@ -808,7 +835,9 @@ func (hs *clientHandshakeState) doTLS13Handshake() error { c.sendAlert(alertUnexpectedMessage) return unexpectedMessageError(certVerifyMsg, msg) } - // TODO process CertificateVerify + if err = hs.verifyPeerCertificate(certVerifyMsg); err != nil { + return err + } hs.keySchedule.write(certVerifyMsg.marshal()) // Receive Finished message. diff --git a/auth.go b/auth.go index 742013b..94de68a 100644 --- a/auth.go +++ b/auth.go @@ -45,6 +45,11 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S panic("tls: supported signature algorithm has an unknown hash function") } 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) { case *rsa.PublicKey: if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS {