commit 2822ccdb6d00b563413a285fe63488ab2ca7b460 Author: Camilo Viecco cviecco@mozilla.com Date: Thu Nov 6 10:30:37 2014 -0800
squash! Bug #11955 Backport certificate pinning
Bug #13684: Backport Mozilla's Bug 1066190 --- security/certverifier/CertVerifier.cpp | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+)
diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp index b2db9fc..1af728e 100644 --- a/security/certverifier/CertVerifier.cpp +++ b/security/certverifier/CertVerifier.cpp @@ -197,6 +197,36 @@ SECStatus chainValidationCallback(void* state, const CERTCertList* certList, return SECSuccess; }
+// This always returns secfailure but its objective is to replate +// the PR_Error +static void +tryWorsenPRErrorInCallback(CERTCertificate* cert, + ChainValidationCallbackState* callbackState) { + ScopedCERTCertificate certCopy(CERT_DupCertificate(cert)); + if (!certCopy) { + return; + } + ScopedCERTCertList certList(CERT_NewCertList()); + if (!certList) { + return; + } + SECStatus srv = CERT_AddCertToListTail(certList.get(), certCopy.get()); + if (srv != SECSuccess) { + return; + } + certCopy.release(); // now owned by certList + PRBool chainOK = false; + srv = chainValidationCallback(&callbackState, certList.get(), &chainOK); + if (srv != SECSuccess) { + return; + } + if (!chainOK) { + PR_SetError(SEC_ERROR_APPLICATION_CALLBACK_ERROR, 0); // same as libpkix + return ; + } + return; // no change in PR_error +} + static SECStatus ClassicVerifyCert(CERTCertificate* cert, const SECCertificateUsage usage, @@ -276,6 +306,12 @@ ClassicVerifyCert(CERTCertificate* cert, return SECFailure; } } + + // If there is an error we may need to worsen to error to be a pinning failure + if (rv != SECSuccess && usage == certificateUsageSSLServer) { + tryWorsenPRErrorInCallback(cert, callbackState); + } + if (rv == SECSuccess && validationChain) { *validationChain = certChain.release(); } @@ -545,6 +581,12 @@ CertVerifier::MozillaPKIXVerifyCert( return SECFailure; }
+ // If there is an error we may need to worsen to error to be a pinning failure + if (rv != SECSuccess && usage == certificateUsageSSLServer && + PR_GetError() != SEC_ERROR_APPLICATION_CALLBACK_ERROR) { + tryWorsenPRErrorInCallback(cert, callbackState); + } + if (validationChain && rv == SECSuccess) { *validationChain = builtChain.release(); } @@ -876,6 +918,12 @@ CertVerifier::VerifyCert(CERTCertificate* cert, rv = CERT_PKIXVerifyCert(cert, usage, cvin, cvout, pinArg);
pkix_done: + // If there is an error we may need to worsen to error to be a pinning failure + if (rv != SECSuccess && usage == certificateUsageSSLServer && + PR_GetError() != SEC_ERROR_APPLICATION_CALLBACK_ERROR) { + tryWorsenPRErrorInCallback(cert, &callbackState); + } + if (validationChain) { PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("VerifyCert: validation chain requested\n")); ScopedCERTCertificate trustAnchor(cvout[validationTrustAnchorLocation].value.pointer.cert);
tbb-commits@lists.torproject.org