From 97271fa8e444efec333d0be31142de677d7c3fe0 Mon Sep 17 00:00:00 2001 From: Kai Engert Date: Thu, 5 May 2011 22:41:40 +0200 Subject: [PATCH] Bug 479393, Add libpkix-based certificate validation to PSM (off by default), r=rrelyea, r=bsmith --- security/manager/ssl/public/nsIX509Cert.idl | 10 +- security/manager/ssl/src/Makefile.in | 1 + .../ssl/src/nsCERTValInParamWrapper.cpp | 157 +++++++++++++++++ .../manager/ssl/src/nsCERTValInParamWrapper.h | 102 +++++++++++ security/manager/ssl/src/nsCMS.cpp | 30 +++- security/manager/ssl/src/nsNSSCallbacks.cpp | 58 ++++++- security/manager/ssl/src/nsNSSCertificate.cpp | 34 +++- .../manager/ssl/src/nsNSSCertificateDB.cpp | 49 +++++- .../ssl/src/nsNSSCertificateFakeTransport.cpp | 4 +- security/manager/ssl/src/nsNSSComponent.cpp | 159 +++++++++++++++--- security/manager/ssl/src/nsNSSComponent.h | 14 ++ security/manager/ssl/src/nsNSSIOLayer.cpp | 22 +++ .../manager/ssl/src/nsUsageArrayHelper.cpp | 57 +++++-- security/manager/ssl/src/nsUsageArrayHelper.h | 2 +- 14 files changed, 645 insertions(+), 54 deletions(-) create mode 100644 security/manager/ssl/src/nsCERTValInParamWrapper.cpp create mode 100644 security/manager/ssl/src/nsCERTValInParamWrapper.h diff --git a/security/manager/ssl/public/nsIX509Cert.idl b/security/manager/ssl/public/nsIX509Cert.idl index 94e54a5a1271..88d31e9cb779 100644 --- a/security/manager/ssl/public/nsIX509Cert.idl +++ b/security/manager/ssl/public/nsIX509Cert.idl @@ -214,12 +214,13 @@ interface nsIX509Cert : nsISupports { * Obtain an array of human readable strings describing * the certificate's certified usages. * - * @param ignoreOcsp Do not use OCSP even if it is currently activated. + * @param localOnly Do not hit the network, even if revocation information + * downloading is currently activated. * @param verified The certificate verification result, see constants. * @param count The number of human readable usages returned. * @param usages The array of human readable usages. */ - void getUsagesArray(in boolean ignoreOcsp, + void getUsagesArray(in boolean localOnly, out PRUint32 verified, out PRUint32 count, [array, size_is(count)] out wstring usages); @@ -228,11 +229,12 @@ interface nsIX509Cert : nsISupports { * Obtain a single comma separated human readable string describing * the certificate's certified usages. * - * @param ignoreOcsp Do not use OCSP even if it is currently activated. + * @param localOnly Do not hit the network, even if revocation information + * downloading is currently activated. * @param verified The certificate verification result, see constants. * @param purposes The string listing the usages. */ - void getUsagesString(in boolean ignoreOcsp, out PRUint32 verified, out AString usages); + void getUsagesString(in boolean localOnly, out PRUint32 verified, out AString usages); /** * Verify the certificate for a particular usage. diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 4e301a5e11d4..2aca078247d1 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -54,6 +54,7 @@ GRE_MODULE = 1 LIBXUL_LIBRARY = 1 CPPSRCS = \ + nsCERTValInParamWrapper.cpp \ nsNSSCleaner.cpp \ nsCertOverrideService.cpp \ nsRecentBadCerts.cpp \ diff --git a/security/manager/ssl/src/nsCERTValInParamWrapper.cpp b/security/manager/ssl/src/nsCERTValInParamWrapper.cpp new file mode 100644 index 000000000000..717883fd216c --- /dev/null +++ b/security/manager/ssl/src/nsCERTValInParamWrapper.cpp @@ -0,0 +1,157 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Red Hat, Inc. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kai Engert + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsCERTValInParamWrapper.h" + +NS_IMPL_THREADSAFE_ADDREF(nsCERTValInParamWrapper) +NS_IMPL_THREADSAFE_RELEASE(nsCERTValInParamWrapper) + +nsCERTValInParamWrapper::nsCERTValInParamWrapper() +:mAlreadyConstructed(PR_FALSE) +,mCVIN(nsnull) +,mRev(nsnull) +{ + MOZ_COUNT_CTOR(nsCERTValInParamWrapper); +} + +nsCERTValInParamWrapper::~nsCERTValInParamWrapper() +{ + MOZ_COUNT_DTOR(nsCERTValInParamWrapper); + if (mRev) { + CERT_DestroyCERTRevocationFlags(mRev); + } + if (mCVIN) + PORT_Free(mCVIN); +} + +nsresult nsCERTValInParamWrapper::Construct(missing_cert_download_config mcdc, + crl_download_config cdc, + ocsp_download_config odc, + ocsp_strict_config osc, + any_revo_fresh_config arfc, + const char *firstNetworkRevocationMethod) +{ + if (mAlreadyConstructed) + return NS_ERROR_FAILURE; + + CERTValInParam *p = (CERTValInParam*)PORT_Alloc(3 * sizeof(CERTValInParam)); + if (!p) + return NS_ERROR_OUT_OF_MEMORY; + + CERTRevocationFlags *rev = CERT_AllocCERTRevocationFlags( + cert_revocation_method_ocsp +1, 1, + cert_revocation_method_ocsp +1, 1); + + if (!rev) { + PORT_Free(p); + return NS_ERROR_OUT_OF_MEMORY; + } + + p[0].type = cert_pi_useAIACertFetch; + p[0].value.scalar.b = (mcdc == missing_cert_download_on); + p[1].type = cert_pi_revocationFlags; + p[1].value.pointer.revocation = rev; + p[2].type = cert_pi_end; + + rev->leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] = + rev->chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] = + // implicit default source - makes no sense for CRLs + CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE + + // let's not stop on fresh CRL. If OCSP is enabled, too, let's check it + | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO + + // no fresh CRL? well, let other flag decide whether to fail or not + | CERT_REV_M_IGNORE_MISSING_FRESH_INFO + + // testing using local CRLs is always allowed + | CERT_REV_M_TEST_USING_THIS_METHOD + + // no local crl and don't know where to get it from? ignore + | CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE + + // crl download based on parameter + | ((cdc == crl_download_allowed) ? + CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING) + ; + + rev->leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = + rev->chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = + // is ocsp enabled at all? + ((odc == ocsp_on) ? + CERT_REV_M_TEST_USING_THIS_METHOD : CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD) + + // ocsp enabled controls network fetching, too + | ((odc == ocsp_on) ? + CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING) + + // ocsp set to strict==required? + | ((osc == ocsp_strict) ? + CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO : CERT_REV_M_IGNORE_MISSING_FRESH_INFO) + + // if app has a default OCSP responder configured, let's use it + | CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE + + // of course OCSP doesn't work without a source. let's accept such certs + | CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE + + // ocsp success is sufficient + | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO + ; + + PRBool wantsCrlFirst = (firstNetworkRevocationMethod != nsnull) + && (strcmp("crl", firstNetworkRevocationMethod) == 0); + + rev->leafTests.preferred_methods[0] = + rev->chainTests.preferred_methods[0] = + wantsCrlFirst ? cert_revocation_method_crl : cert_revocation_method_ocsp; + + rev->leafTests.cert_rev_method_independent_flags = + rev->chainTests.cert_rev_method_independent_flags = + // avoiding the network is good, let's try local first + CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST + + // is overall revocation requirement strict or relaxed? + | ((arfc == any_revo_strict) ? + CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE : CERT_REV_MI_NO_OVERALL_INFO_REQUIREMENT) + ; + + mAlreadyConstructed = PR_TRUE; + mCVIN = p; + mRev = rev; + return NS_OK; +} diff --git a/security/manager/ssl/src/nsCERTValInParamWrapper.h b/security/manager/ssl/src/nsCERTValInParamWrapper.h new file mode 100644 index 000000000000..6a7cdff30ad2 --- /dev/null +++ b/security/manager/ssl/src/nsCERTValInParamWrapper.h @@ -0,0 +1,102 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Red Hat, Inc. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kai Engert + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _nsCERTValInParamWrapper_H +#define _nsCERTValInParamWrapper_H + +#include "nsISupports.h" +#include "cert.h" + +/* + * This is a wrapper around type + * CERTValInParam is a nested input parameter type for CERT_PKIXVerifyCert. + * The values inside this type depend on application preferences, + * as a consequence it's expensive to construct this object. + * (and we shall avoid to access prefs from secondary threads anyway). + * We want to create an instance of that input type once, and use as long as possible. + * Every time the preferences change, we will create a new default object. + * + * A race is possible between "verification function is active and object in use" + * and "must switch to new defaults". + * + * The global default object may be replaced at any time with a new object. + * The contents of inner CERTValInParam are supposed to be stable (const). + * + * In order to protect against the race, we use a reference counted wrapper. + * Each user of a foreign nsCERTValInParamWrapper object + * (e.g. the current global default object) + * must use nsRefPtr = other-object + * prior to calling CERT_PKIXVerifyCert. + * + * This guarantees the object will still be alive after the call, + * and if the default object has been replaced in the meantime, + * the reference counter will go to zero, and the old default + * object will get destroyed automatically. + */ +class nsCERTValInParamWrapper +{ + public: + NS_IMETHOD_(nsrefcnt) AddRef(); + NS_IMETHOD_(nsrefcnt) Release(); + +public: + nsCERTValInParamWrapper(); + virtual ~nsCERTValInParamWrapper(); + + enum missing_cert_download_config { missing_cert_download_off = 0, missing_cert_download_on }; + enum crl_download_config { crl_local_only = 0, crl_download_allowed }; + enum ocsp_download_config { ocsp_off = 0, ocsp_on }; + enum ocsp_strict_config { ocsp_relaxed = 0, ocsp_strict }; + enum any_revo_fresh_config { any_revo_relaxed = 0, any_revo_strict }; + + nsresult Construct(missing_cert_download_config ac, crl_download_config cdc, + ocsp_download_config odc, ocsp_strict_config osc, + any_revo_fresh_config arfc, + const char *firstNetworkRevocationMethod); + +private: + nsAutoRefCnt mRefCnt; + NS_DECL_OWNINGTHREAD + PRBool mAlreadyConstructed; + CERTValInParam *mCVIN; + CERTRevocationFlags *mRev; + +public: + CERTValInParam *GetRawPointerForNSS() { return mCVIN; } +}; + +#endif diff --git a/security/manager/ssl/src/nsCMS.cpp b/security/manager/ssl/src/nsCMS.cpp index fd02751c0a82..70f2141ade89 100644 --- a/security/manager/ssl/src/nsCMS.cpp +++ b/security/manager/ssl/src/nsCMS.cpp @@ -46,6 +46,7 @@ #include "nsIArray.h" #include "nsArrayUtils.h" #include "nsCertVerificationThread.h" +#include "nsCERTValInParamWrapper.h" #include "prlog.h" #ifdef PR_LOGGING @@ -53,6 +54,8 @@ extern PRLogModuleInfo* gPIPNSSLog; #endif #include "nsNSSCleaner.h" +#include "nsNSSComponent.h" +static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate) @@ -247,6 +250,8 @@ nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, PRUint3 NSSCMSSignerInfo *si; PRInt32 nsigners; nsresult rv = NS_ERROR_FAILURE; + nsRefPtr survivingParams; + nsCOMPtr inss; if (!NSS_CMSMessage_IsSigned(m_cmsMsg)) { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - not signed\n")); @@ -287,9 +292,10 @@ nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, PRUint3 PR_ASSERT(nsigners > 0); si = NSS_CMSSignedData_GetSignerInfo(sigd, 0); - // See bug 324474. We want to make sure the signing cert is // still valid at the current time. + +if (!nsNSSComponent::globalConstFlagUsePKIXVerification) { if (CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), si->cert, PR_TRUE, certificateUsageEmailSigner, si->cmsg->pwfn_arg, NULL) != SECSuccess) { @@ -297,6 +303,28 @@ nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, PRUint3 rv = NS_ERROR_CMS_VERIFY_UNTRUSTED; goto loser; } +} +else { + CERTValOutParam cvout[1]; + cvout[0].type = cert_po_end; + + inss = do_GetService(kNSSComponentCID, &rv); + if (!inss) { + goto loser; + } + + if (NS_FAILED(inss->GetDefaultCERTValInParam(survivingParams))) { + goto loser; + } + rv = CERT_PKIXVerifyCert(si->cert, certificateUsageEmailSigner, + survivingParams->GetRawPointerForNSS(), + cvout, si->cmsg->pwfn_arg); + if (rv != SECSuccess) { + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - signing cert not trusted now\n")); + rv = NS_ERROR_CMS_VERIFY_UNTRUSTED; + goto loser; + } +} // We verify the first signer info, only // if (NSS_CMSSignedData_VerifySignerInfo(sigd, 0, CERT_GetDefaultCertDB(), certUsageEmailSigner) != SECSuccess) { diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index cdfbcce2705f..ea51a05a9609 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -75,6 +75,7 @@ #include "ocsp.h" #include "nssb64.h" #include "secerr.h" +#include "sslerr.h" using namespace mozilla; @@ -958,6 +959,60 @@ void PR_CALLBACK HandshakeCallback(PRFileDesc* fd, void* client_data) { PR_Free(signer); } +SECStatus +PSM_SSL_PKIX_AuthCertificate(PRFileDesc *fd, CERTCertificate *peerCert, PRBool checksig, PRBool isServer) +{ + SECStatus rv; + SECCertUsage certUsage; + SECCertificateUsage certificateusage; + void * pinarg; + char * hostname; + + pinarg = SSL_RevealPinArg(fd); + hostname = SSL_RevealURL(fd); + + /* this may seem backwards, but isn't. */ + certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; + certificateusage = isServer ? certificateUsageSSLClient : certificateUsageSSLServer; + +if (!nsNSSComponent::globalConstFlagUsePKIXVerification) { + rv = CERT_VerifyCertNow(CERT_GetDefaultCertDB(), peerCert, checksig, certUsage, + pinarg); +} +else { + nsresult nsrv; + nsCOMPtr inss = do_GetService(kNSSComponentCID, &nsrv); + if (!inss) + return SECFailure; + nsRefPtr survivingParams; + if (NS_FAILED(inss->GetDefaultCERTValInParam(survivingParams))) + return SECFailure; + + CERTValOutParam cvout[1]; + cvout[0].type = cert_po_end; + + rv = CERT_PKIXVerifyCert(peerCert, certificateusage, + survivingParams->GetRawPointerForNSS(), + cvout, pinarg); +} + + if ( rv == SECSuccess && isServer ) { + /* cert is OK. This is the client side of an SSL connection. + * Now check the name field in the cert against the desired hostname. + * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! + */ + if (hostname && hostname[0]) + rv = CERT_VerifyCertName(peerCert, hostname); + else + rv = SECFailure; + if (rv != SECSuccess) + PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); + } + + PORT_Free(hostname); + return rv; +} + struct nsSerialBinaryBlacklistEntry { unsigned int len; @@ -1025,8 +1080,7 @@ SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd, } } - // first the default action - SECStatus rv = SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer); + SECStatus rv = PSM_SSL_PKIX_AuthCertificate(fd, serverCert, checksig, isServer); // We want to remember the CA certs in the temp db, so that the application can find the // complete chain at any time it might need it. diff --git a/security/manager/ssl/src/nsNSSCertificate.cpp b/security/manager/ssl/src/nsNSSCertificate.cpp index 491015fb524b..e7b22a7d9537 100644 --- a/security/manager/ssl/src/nsNSSCertificate.cpp +++ b/security/manager/ssl/src/nsNSSCertificate.cpp @@ -1289,6 +1289,15 @@ nsNSSCertificate::VerifyForUsage(PRUint32 usage, PRUint32 *verificationResult) NS_ENSURE_ARG(verificationResult); + nsresult nsrv; + nsCOMPtr inss = do_GetService(kNSSComponentCID, &nsrv); + if (!inss) + return nsrv; + nsRefPtr survivingParams; + nsrv = inss->GetDefaultCERTValInParam(survivingParams); + if (NS_FAILED(nsrv)) + return nsrv; + SECCertificateUsage nss_usage; switch (usage) @@ -1345,10 +1354,21 @@ nsNSSCertificate::VerifyForUsage(PRUint32 usage, PRUint32 *verificationResult) return NS_ERROR_FAILURE; } + SECStatus verify_result; +if (!nsNSSComponent::globalConstFlagUsePKIXVerification) { CERTCertDBHandle *defaultcertdb = CERT_GetDefaultCertDB(); - - if (CERT_VerifyCertificateNow(defaultcertdb, mCert, PR_TRUE, - nss_usage, NULL, NULL) == SECSuccess) + verify_result = CERT_VerifyCertificateNow(defaultcertdb, mCert, PR_TRUE, + nss_usage, NULL, NULL); +} +else { + CERTValOutParam cvout[1]; + cvout[0].type = cert_po_end; + verify_result = CERT_PKIXVerifyCert(mCert, nss_usage, + survivingParams->GetRawPointerForNSS(), + cvout, NULL); +} + + if (verify_result == SECSuccess) { *verificationResult = VERIFIED_OK; } @@ -1401,7 +1421,7 @@ nsNSSCertificate::VerifyForUsage(PRUint32 usage, PRUint32 *verificationResult) NS_IMETHODIMP -nsNSSCertificate::GetUsagesArray(PRBool ignoreOcsp, +nsNSSCertificate::GetUsagesArray(PRBool localOnly, PRUint32 *_verified, PRUint32 *_count, PRUnichar ***_usages) @@ -1416,7 +1436,7 @@ nsNSSCertificate::GetUsagesArray(PRBool ignoreOcsp, const char *suffix = ""; PRUint32 tmpCount; nsUsageArrayHelper uah(mCert); - rv = uah.GetUsagesArray(suffix, ignoreOcsp, max_usages, _verified, &tmpCount, tmpUsages); + rv = uah.GetUsagesArray(suffix, localOnly, max_usages, _verified, &tmpCount, tmpUsages); NS_ENSURE_SUCCESS(rv,rv); if (tmpCount > 0) { *_usages = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * tmpCount); @@ -1456,7 +1476,7 @@ nsNSSCertificate::RequestUsagesArrayAsync(nsICertVerificationListener *aResultLi } NS_IMETHODIMP -nsNSSCertificate::GetUsagesString(PRBool ignoreOcsp, +nsNSSCertificate::GetUsagesString(PRBool localOnly, PRUint32 *_verified, nsAString &_usages) { @@ -1470,7 +1490,7 @@ nsNSSCertificate::GetUsagesString(PRBool ignoreOcsp, const char *suffix = "_p"; PRUint32 tmpCount; nsUsageArrayHelper uah(mCert); - rv = uah.GetUsagesArray(suffix, ignoreOcsp, max_usages, _verified, &tmpCount, tmpUsages); + rv = uah.GetUsagesArray(suffix, localOnly, max_usages, _verified, &tmpCount, tmpUsages); NS_ENSURE_SUCCESS(rv,rv); _usages.Truncate(); for (PRUint32 i=0; i inss = do_GetService(kNSSComponentCID, &nsrv); + if (!inss) + return nsrv; + nsRefPtr survivingParams; + nsrv = inss->GetDefaultCERTValInParam(survivingParams); + if (NS_FAILED(nsrv)) + return nsrv; PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) @@ -549,6 +558,7 @@ nsNSSCertificateDB::ImportEmailCertificate(PRUint8 * data, PRUint32 length, certdb = CERT_GetDefaultCertDB(); certusage = certUsageEmailRecipient; + certificateusage = certificateUsageEmailRecipient; numcerts = certCollection->numcerts; @@ -591,6 +601,9 @@ nsNSSCertificateDB::ImportEmailCertificate(PRUint8 * data, PRUint32 length, * valid chains, then import them. */ now = PR_Now(); + CERTValOutParam cvout[1]; + cvout[0].type = cert_po_end; + for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node,certList); node = CERT_LIST_NEXT(node)) { @@ -601,10 +614,20 @@ nsNSSCertificateDB::ImportEmailCertificate(PRUint8 * data, PRUint32 length, continue; } - if (CERT_VerifyCert(certdb, node->cert, +if (!nsNSSComponent::globalConstFlagUsePKIXVerification) { + if (CERT_VerifyCert(certdb, node->cert, PR_TRUE, certusage, now, ctx, NULL) != SECSuccess) { alert_and_skip = true; } +} +else { + if (CERT_PKIXVerifyCert(node->cert, certificateusage, + survivingParams->GetRawPointerForNSS(), + cvout, ctx) + != SECSuccess) { + alert_and_skip = true; + } +} CERTCertificateList *certChain = nsnull; CERTCertificateListCleaner chainCleaner(certChain); @@ -774,6 +797,14 @@ nsresult nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfaceRequestor *ctx) { SECItem **rawArray; + nsresult nsrv; + nsCOMPtr inss = do_GetService(kNSSComponentCID, &nsrv); + if (!inss) + return nsrv; + nsRefPtr survivingParams; + nsrv = inss->GetDefaultCERTValInParam(survivingParams); + if (NS_FAILED(nsrv)) + return nsrv; /* filter out the certs we don't want */ SECStatus srv = CERT_FilterCertListByUsage(certList, certUsageAnyCA, PR_TRUE); @@ -784,18 +815,30 @@ nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfac /* go down the remaining list of certs and verify that they have * valid chains, if yes, then import. */ - PRTime now = PR_Now(); CERTCertListNode *node; + CERTValOutParam cvout[1]; + cvout[0].type = cert_po_end; + for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node,certList); node = CERT_LIST_NEXT(node)) { bool alert_and_skip = false; +if (!nsNSSComponent::globalConstFlagUsePKIXVerification) { if (CERT_VerifyCert(CERT_GetDefaultCertDB(), node->cert, - PR_TRUE, certUsageVerifyCA, now, ctx, NULL) != SECSuccess) { + PR_TRUE, certUsageVerifyCA, PR_Now(), ctx, NULL) != SECSuccess) { alert_and_skip = true; } +} +else { + if (CERT_PKIXVerifyCert(node->cert, certificateUsageVerifyCA, + survivingParams->GetRawPointerForNSS(), + cvout, ctx) + != SECSuccess) { + alert_and_skip = true; + } +} CERTCertificateList *certChain = nsnull; CERTCertificateListCleaner chainCleaner(certChain); diff --git a/security/manager/ssl/src/nsNSSCertificateFakeTransport.cpp b/security/manager/ssl/src/nsNSSCertificateFakeTransport.cpp index 6f25a14438da..f731e1c18335 100644 --- a/security/manager/ssl/src/nsNSSCertificateFakeTransport.cpp +++ b/security/manager/ssl/src/nsNSSCertificateFakeTransport.cpp @@ -284,7 +284,7 @@ nsNSSCertificateFakeTransport::VerifyForUsage(PRUint32 usage, PRUint32 *verifica } NS_IMETHODIMP -nsNSSCertificateFakeTransport::GetUsagesArray(PRBool ignoreOcsp, +nsNSSCertificateFakeTransport::GetUsagesArray(PRBool localOnly, PRUint32 *_verified, PRUint32 *_count, PRUnichar ***_usages) @@ -301,7 +301,7 @@ nsNSSCertificateFakeTransport::RequestUsagesArrayAsync(nsICertVerificationListen } NS_IMETHODIMP -nsNSSCertificateFakeTransport::GetUsagesString(PRBool ignoreOcsp, +nsNSSCertificateFakeTransport::GetUsagesString(PRBool localOnly, PRUint32 *_verified, nsAString &_usages) { diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index d0b55cf8846b..a9462ccf12f4 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -117,6 +117,7 @@ #include "base64.h" #include "secerr.h" #include "sslerr.h" +#include "cert.h" #include "nsXULAppAPI.h" @@ -139,6 +140,7 @@ PRLogModuleInfo* gPIPNSSLog = nsnull; static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); int nsNSSComponent::mInstanceCount = 0; +PRBool nsNSSComponent::globalConstFlagUsePKIXVerification = PR_FALSE; // XXX tmp callback for slot password extern char * PR_CALLBACK @@ -147,7 +149,6 @@ pk11PasswordPrompt(PK11SlotInfo *slot, PRBool retry, void *arg); #define PIPNSS_STRBUNDLE_URL "chrome://pipnss/locale/pipnss.properties" #define NSSERR_STRBUNDLE_URL "chrome://pipnss/locale/nsserrors.properties" - static PLHashNumber PR_CALLBACK certHashtable_keyHash(const void *key) { if (!key) @@ -589,8 +590,6 @@ nsNSSComponent::DispatchEventToWindow(nsIDOMWindow *domWin, } -static void setOCSPOptions(nsIPrefBranch * pref); - NS_IMETHODIMP nsNSSComponent::PIPBundleFormatStringFromName(const char *name, const PRUnichar **params, @@ -671,7 +670,6 @@ nsNSSComponent::GetNSSBundleString(const char *name, return rv; } - NS_IMETHODIMP nsNSSComponent::SkipOcsp() { @@ -685,7 +683,18 @@ nsNSSComponent::SkipOcsp() NS_IMETHODIMP nsNSSComponent::SkipOcspOff() { - setOCSPOptions(mPrefBranch); + nsNSSShutDownPreventionLock locker; + PRInt32 ocspEnabled; + if (NS_FAILED(mPrefBranch->GetIntPref("security.OCSP.enabled", &ocspEnabled))) + ocspEnabled = OCSP_ENABLED_DEFAULT; + // 0 = disabled, 1 = enabled, + // 2 = enabled with given default responder + + setNonPkixOcspEnabled(ocspEnabled, mPrefBranch); + + if (ocspEnabled) + SSL_ClearSessionCache(); + return NS_OK; } @@ -1111,12 +1120,9 @@ nsresult nsNSSComponent::GetNSSCipherIDFromPrefString(const nsACString &aPrefStr return NS_ERROR_NOT_AVAILABLE; } -static void setOCSPOptions(nsIPrefBranch * pref) +static void +setNonPkixOcspEnabled(PRInt32 ocspEnabled, nsIPrefBranch * pref) { - nsNSSShutDownPreventionLock locker; - // Set up OCSP // - PRInt32 ocspEnabled; - pref->GetIntPref("security.OCSP.enabled", &ocspEnabled); switch (ocspEnabled) { case 0: CERT_DisableOCSPChecking(CERT_GetDefaultCertDB()); @@ -1125,7 +1131,6 @@ static void setOCSPOptions(nsIPrefBranch * pref) case 1: CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB()); - SSL_ClearSessionCache(); break; case 2: { @@ -1140,21 +1145,89 @@ static void setOCSPOptions(nsIPrefBranch * pref) CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); CERT_SetOCSPDefaultResponder(CERT_GetDefaultCertDB(), url, signingCA); CERT_EnableOCSPDefaultResponder(CERT_GetDefaultCertDB()); - SSL_ClearSessionCache(); nsMemory::Free(signingCA); nsMemory::Free(url); } break; } +} + +#define CRL_DOWNLOAD_DEFAULT PR_FALSE +#define OCSP_ENABLED_DEFAULT 1 +#define OCSP_REQUIRED_DEFAULT 0 +#define FRESH_REVOCATION_REQUIRED_DEFAULT PR_FALSE +#define MISSING_CERT_DOWNLOAD_DEFAULT PR_FALSE +#define FIRST_REVO_METHOD_DEFAULT "ocsp" +#define USE_NSS_LIBPKIX_DEFAULT PR_FALSE + +// Caller must hold a lock on nsNSSComponent::mutex when calling this function +void nsNSSComponent::setValidationOptions(nsIPrefBranch * pref) +{ + nsNSSShutDownPreventionLock locker; + nsresult rv; + + PRBool crlDownloading; + rv = pref->GetBoolPref("security.CRL_download.enabled", &crlDownloading); + if (NS_FAILED(rv)) + crlDownloading = CRL_DOWNLOAD_DEFAULT; + + PRInt32 ocspEnabled; + rv = pref->GetIntPref("security.OCSP.enabled", &ocspEnabled); + // 0 = disabled, 1 = enabled, + // 2 = enabled with given default responder + if (NS_FAILED(rv)) + ocspEnabled = OCSP_ENABLED_DEFAULT; + PRBool ocspRequired; - pref->GetBoolPref("security.OCSP.require", &ocspRequired); - if (ocspRequired) { - CERT_SetOCSPFailureMode(ocspMode_FailureIsVerificationFailure); - } - else { - CERT_SetOCSPFailureMode(ocspMode_FailureIsNotAVerificationFailure); + rv = pref->GetBoolPref("security.OCSP.require", &ocspRequired); + if (NS_FAILED(rv)) + ocspRequired = OCSP_REQUIRED_DEFAULT; + + PRBool anyFreshRequired; + rv = pref->GetBoolPref("security.fresh_revocation_info.require", &anyFreshRequired); + if (NS_FAILED(rv)) + anyFreshRequired = FRESH_REVOCATION_REQUIRED_DEFAULT; + + PRBool aiaDownloadEnabled; + rv = pref->GetBoolPref("security.missing_cert_download.enabled", &aiaDownloadEnabled); + if (NS_FAILED(rv)) + aiaDownloadEnabled = MISSING_CERT_DOWNLOAD_DEFAULT; + + nsCString firstNetworkRevo; + rv = pref->GetCharPref("security.first_network_revocation_method", getter_Copies(firstNetworkRevo)); + if (NS_FAILED(rv)) + firstNetworkRevo = FIRST_REVO_METHOD_DEFAULT; + + setNonPkixOcspEnabled(ocspEnabled, pref); + + CERT_SetOCSPFailureMode( ocspRequired ? + ocspMode_FailureIsVerificationFailure + : ocspMode_FailureIsNotAVerificationFailure); + + nsRefPtr newCVIN = new nsCERTValInParamWrapper; + if (NS_SUCCEEDED(newCVIN->Construct( + aiaDownloadEnabled ? + nsCERTValInParamWrapper::missing_cert_download_on : nsCERTValInParamWrapper::missing_cert_download_off, + crlDownloading ? + nsCERTValInParamWrapper::crl_download_allowed : nsCERTValInParamWrapper::crl_local_only, + ocspEnabled ? + nsCERTValInParamWrapper::ocsp_on : nsCERTValInParamWrapper::ocsp_off, + ocspRequired ? + nsCERTValInParamWrapper::ocsp_strict : nsCERTValInParamWrapper::ocsp_relaxed, + anyFreshRequired ? + nsCERTValInParamWrapper::any_revo_strict : nsCERTValInParamWrapper::any_revo_relaxed, + firstNetworkRevo.get()))) { + // Swap to new defaults, and will cause the old defaults to be released, + // as soon as any concurrent use of the old default objects has finished. + mDefaultCERTValInParam = newCVIN; } + + /* + * The new defaults might change the validity of already established SSL sessions, + * let's not reuse them. + */ + SSL_ClearSessionCache(); } nsresult @@ -1642,6 +1715,10 @@ nsNSSComponent::InitializeNSS(PRBool showWarningBox) TryCFM2MachOMigration(cfmSecurityPath, profilePath); #endif + rv = mPrefBranch->GetBoolPref("security.use_libpkix_verification", &globalConstFlagUsePKIXVerification); + if (NS_FAILED(rv)) + globalConstFlagUsePKIXVerification = USE_NSS_LIBPKIX_DEFAULT; + PRBool supress_warning_preference = PR_FALSE; rv = mPrefBranch->GetBoolPref("security.suppress_nss_rw_impossible_warning", &supress_warning_preference); @@ -1767,8 +1844,23 @@ nsNSSComponent::InitializeNSS(PRBool showWarningBox) SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1); PORT_SetUCS2_ASCIIConversionFunction(pip_ucs2_ascii_conversion_fn); - // Set up OCSP // - setOCSPOptions(mPrefBranch); + // dynamic options from prefs + setValidationOptions(mPrefBranch); + + // static validation options for usagesarray - do not hit the network + mDefaultCERTValInParamLocalOnly = new nsCERTValInParamWrapper; + rv = mDefaultCERTValInParamLocalOnly->Construct( + nsCERTValInParamWrapper::missing_cert_download_off, + nsCERTValInParamWrapper::crl_local_only, + nsCERTValInParamWrapper::ocsp_off, + nsCERTValInParamWrapper::ocsp_relaxed, + nsCERTValInParamWrapper::any_revo_relaxed, + "ocsp"); + if (NS_FAILED(rv)) { + nsPSMInitPanic::SetPanic(); + return rv; + } + RegisterMyOCSPAIAInfoCallback(); mHttpForNSS.initTable(); @@ -2273,8 +2365,13 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, SSL_OptionSetDefault(SSL_ENABLE_FALSE_START, enabled); #endif } else if (prefName.Equals("security.OCSP.enabled") + || prefName.Equals("security.CRL_download.enabled") + || prefName.Equals("security.fresh_revocation_info.require") + || prefName.Equals("security.missing_cert_download.enabled") + || prefName.Equals("security.first_network_revocation_method") || prefName.Equals("security.OCSP.require")) { - setOCSPOptions(mPrefBranch); + MutexAutoLock lock(mutex); + setValidationOptions(mPrefBranch); } else { /* Look through the cipher table and set according to pref setting */ for (CipherPref* cp = CipherPrefs; cp->pref; ++cp) { @@ -2561,6 +2658,26 @@ nsNSSComponent::IsNSSInitialized(PRBool *initialized) return NS_OK; } +NS_IMETHODIMP +nsNSSComponent::GetDefaultCERTValInParam(nsRefPtr &out) +{ + MutexAutoLock lock(mutex); + if (!mNSSInitialized) + return NS_ERROR_NOT_INITIALIZED; + out = mDefaultCERTValInParam; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSComponent::GetDefaultCERTValInParamLocalOnly(nsRefPtr &out) +{ + MutexAutoLock lock(mutex); + if (!mNSSInitialized) + return NS_ERROR_NOT_INITIALIZED; + out = mDefaultCERTValInParamLocalOnly; + return NS_OK; +} + //--------------------------------------------- // Implementing nsICryptoHash //--------------------------------------------- diff --git a/security/manager/ssl/src/nsNSSComponent.h b/security/manager/ssl/src/nsNSSComponent.h index 1bf3955a0ca9..17d0b9cc350e 100644 --- a/security/manager/ssl/src/nsNSSComponent.h +++ b/security/manager/ssl/src/nsNSSComponent.h @@ -71,6 +71,7 @@ #include "nsNSSHelper.h" #include "nsClientAuthRemember.h" +#include "nsCERTValInParamWrapper.h" #define NS_NSSCOMPONENT_CID \ {0xa277189c, 0x1dd1, 0x11b2, {0xa8, 0xc9, 0xe4, 0xe8, 0xbf, 0xb1, 0x33, 0x8e}} @@ -141,6 +142,8 @@ protected: nsresult handleContentDownloadError(nsresult errCode); }; +class nsNSSComponent; + class NS_NO_VTABLE nsINSSComponent : public nsISupports { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_INSSCOMPONENT_IID) @@ -190,6 +193,9 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports { NS_IMETHOD EnsureIdentityInfoLoaded() = 0; NS_IMETHOD IsNSSInitialized(PRBool *initialized) = 0; + + NS_IMETHOD GetDefaultCERTValInParam(nsRefPtr &out) = 0; + NS_IMETHOD GetDefaultCERTValInParamLocalOnly(nsRefPtr &out) = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsINSSComponent, NS_INSSCOMPONENT_IID) @@ -287,6 +293,8 @@ public: NS_IMETHOD EnsureIdentityInfoLoaded(); NS_IMETHOD IsNSSInitialized(PRBool *initialized); + NS_IMETHOD GetDefaultCERTValInParam(nsRefPtr &out); + NS_IMETHOD GetDefaultCERTValInParamLocalOnly(nsRefPtr &out); private: nsresult InitializeNSS(PRBool showWarningBox); @@ -309,6 +317,7 @@ private: void LaunchSmartCardThreads(); void ShutdownSmartCardThreads(); void CleanupIdentityInfo(); + void setValidationOptions(nsIPrefBranch * pref); nsresult InitializePIPNSSBundle(); nsresult ConfigureInternalPKCS11Token(); nsresult RegisterPSMContentListener(); @@ -352,9 +361,14 @@ private: nsCertVerificationThread *mCertVerificationThread; nsNSSHttpInterface mHttpForNSS; nsRefPtr mClientAuthRememberService; + nsRefPtr mDefaultCERTValInParam; + nsRefPtr mDefaultCERTValInParamLocalOnly; static PRStatus PR_CALLBACK IdentityInfoInit(void); PRCallOnceType mIdentityInfoCallOnce; + +public: + static PRBool globalConstFlagUsePKIXVerification; }; class PSMContentListener : public nsIURIContentListener, diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 6f7615523a1d..5bc7ca1693fd 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -116,6 +116,8 @@ NSSCleanupAutoPtrClass(char, PL_strfree) NSSCleanupAutoPtrClass(void, PR_FREEIF) NSSCleanupAutoPtrClass_WithParam(PRArenaPool, PORT_FreeArena, FalseParam, PR_FALSE) +static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); + /* SSM_UserCertChoice: enum for cert choice info */ typedef enum {ASK, AUTO} SSM_UserCertChoice; @@ -3377,6 +3379,14 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket) PRErrorCode errorCodeMismatch = SECSuccess; PRErrorCode errorCodeExpired = SECSuccess; + nsCOMPtr inss = do_GetService(kNSSComponentCID, &nsrv); + if (!inss) + return cancel_and_failure(infoObject); + nsRefPtr survivingParams; + nsrv = inss->GetDefaultCERTValInParam(survivingParams); + if (NS_FAILED(nsrv)) + return cancel_and_failure(infoObject); + char *hostname = SSL_RevealURL(sslSocket); if (!hostname) return cancel_and_failure(infoObject); @@ -3415,10 +3425,22 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket) verify_log->arena = log_arena; +if (!nsNSSComponent::globalConstFlagUsePKIXVerification) { srv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), peerCert, PR_TRUE, certificateUsageSSLServer, PR_Now(), (void*)infoObject, verify_log, NULL); +} +else { + CERTValOutParam cvout[2]; + cvout[0].type = cert_po_errorLog; + cvout[0].value.pointer.log = verify_log; + cvout[1].type = cert_po_end; + + srv = CERT_PKIXVerifyCert(peerCert, certificateUsageSSLServer, + survivingParams->GetRawPointerForNSS(), + cvout, (void*)infoObject); +} // We ignore the result code of the cert verification. // Either it is a failure, which is expected, and we'll process the diff --git a/security/manager/ssl/src/nsUsageArrayHelper.cpp b/security/manager/ssl/src/nsUsageArrayHelper.cpp index 968cab5bedd9..3f93dadc2e2c 100644 --- a/security/manager/ssl/src/nsUsageArrayHelper.cpp +++ b/security/manager/ssl/src/nsUsageArrayHelper.cpp @@ -152,7 +152,7 @@ nsUsageArrayHelper::verifyFailed(PRUint32 *_verified, int err) nsresult nsUsageArrayHelper::GetUsagesArray(const char *suffix, - PRBool ignoreOcsp, + PRBool localOnly, PRUint32 outArraySize, PRUint32 *_verified, PRUint32 *_count, @@ -167,7 +167,7 @@ nsUsageArrayHelper::GetUsagesArray(const char *suffix, nsCOMPtr nssComponent; - if (ignoreOcsp) { + if (!nsNSSComponent::globalConstFlagUsePKIXVerification && localOnly) { nsresult rv; nssComponent = do_GetService(kNSSComponentCID, &rv); if (NS_FAILED(rv)) @@ -177,12 +177,15 @@ nsUsageArrayHelper::GetUsagesArray(const char *suffix, nssComponent->SkipOcsp(); } } - + PRUint32 &count = *_count; count = 0; - SECCertificateUsage usages; - - CERT_VerifyCertificateNow(defaultcertdb, mCert, PR_TRUE, + SECCertificateUsage usages = 0; + SECStatus verifyResult; + +if (!nsNSSComponent::globalConstFlagUsePKIXVerification) { + verifyResult = + CERT_VerifyCertificateNow(defaultcertdb, mCert, PR_TRUE, certificateUsageSSLClient | certificateUsageSSLServer | certificateUsageSSLServerWithStepUp | @@ -192,7 +195,39 @@ nsUsageArrayHelper::GetUsagesArray(const char *suffix, certificateUsageSSLCA | certificateUsageStatusResponder, NULL, &usages); - int err = PR_GetError(); +} +else { + nsresult nsrv; + nsCOMPtr inss = do_GetService(kNSSComponentCID, &nsrv); + if (!inss) + return nsrv; + nsRefPtr survivingParams; + if (localOnly) + nsrv = inss->GetDefaultCERTValInParamLocalOnly(survivingParams); + else + nsrv = inss->GetDefaultCERTValInParam(survivingParams); + + if (NS_FAILED(nsrv)) + return nsrv; + + CERTValOutParam cvout[2]; + cvout[0].type = cert_po_usages; + cvout[0].value.scalar.usages = 0; + cvout[1].type = cert_po_end; + + verifyResult = + CERT_PKIXVerifyCert(mCert, certificateUsageCheckAllUsages, + survivingParams->GetRawPointerForNSS(), + cvout, NULL); + + usages = cvout[0].value.scalar.usages; +} + + if (verifyResult != SECSuccess) { + int err = PR_GetError(); + verifyFailed(_verified, err); + return NS_OK; + } // The following list of checks must be < max_returned_out_array_size @@ -215,14 +250,10 @@ nsUsageArrayHelper::GetUsagesArray(const char *suffix, check(suffix, usages & certificateUsageAnyCA, count, outUsages); #endif - if (ignoreOcsp && nssComponent) { + if (!nsNSSComponent::globalConstFlagUsePKIXVerification && localOnly && nssComponent) { nssComponent->SkipOcspOff(); } - if (count == 0) { - verifyFailed(_verified, err); - } else { - *_verified = nsNSSCertificate::VERIFIED_OK; - } + *_verified = nsNSSCertificate::VERIFIED_OK; return NS_OK; } diff --git a/security/manager/ssl/src/nsUsageArrayHelper.h b/security/manager/ssl/src/nsUsageArrayHelper.h index dce44f10fd99..d6df85ecd914 100644 --- a/security/manager/ssl/src/nsUsageArrayHelper.h +++ b/security/manager/ssl/src/nsUsageArrayHelper.h @@ -48,7 +48,7 @@ public: nsUsageArrayHelper(CERTCertificate *aCert); nsresult GetUsagesArray(const char *suffix, - PRBool ignoreOcsp, + PRBool localOnly, PRUint32 outArraySize, PRUint32 *_verified, PRUint32 *_count,