Bug 813418 - Backout 2f47fcb0a648 due to bustage CLOSED TREE

This commit is contained in:
Camilo Viecco 2013-04-15 16:45:11 -07:00
parent 181f3b3cb5
commit 915e0525f7
15 changed files with 623 additions and 311 deletions

View File

@ -1,65 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_psm__CertVerifier_h
#define mozilla_psm__CertVerifier_h
#include "mozilla/RefPtr.h"
#include "CryptoUtil.h"
#include "nsISupportsImpl.h"
#include "certt.h"
class nsIInterfaceRequestor;
class nsNSSComponent;
namespace mozilla { namespace psm {
class CertVerifier
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CertVerifier)
typedef unsigned int Flags;
static const Flags FLAG_LOCAL_ONLY;
// XXX: The localonly flag is ignored in the classic verification case
// *evOidPolicy == SEC_OID_UNKNOWN means the cert is NOT EV
SECStatus VerifyCert(CERTCertificate * cert,
const SECCertificateUsage usage,
const PRTime time,
nsIInterfaceRequestor * pinArg,
const Flags flags = 0,
/*optional out*/ CERTCertList **validationChain = nullptr,
/*optional out*/ SECOidTag *evOidPolicy = nullptr ,
/*optional out*/ CERTVerifyLog *verifyLog = nullptr);
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 };
bool IsOCSPDownloadEnabled() const { return mOCSPDownloadEnabled; }
private:
CertVerifier(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);
~CertVerifier();
const bool mMissingCertDownloadEnabled;
const bool mCRLDownloadEnabled;
const bool mOCSPDownloadEnabled;
const bool mOCSPStrict;
const bool mRequireRevocationInfo;
const bool mCRLFirst;
friend class ::nsNSSComponent;
};
MOZ_WARN_UNUSED_RESULT TemporaryRef<CertVerifier> GetDefaultCertVerifier();
} } // namespace mozilla::psm
#endif // mozilla_psm__CertVerifier_h

View File

@ -1,13 +0,0 @@
#ifndef mozilla_psm__CryptoUtil_h
#define mozilla_psm__CryptoUtil_h
#include <mozilla/RefPtr.h>
#include "mozilla/Types.h"
#ifdef MOZILLA_INTERNAL_API
#define MOZ_CRYPTO_API(x) MOZ_EXPORT_API(x)
#else
#define MOZ_CRYPTO_API(x) MOZ_IMPORT_API(x)
#endif
#endif // mozilla_psm__CryptoUtil_h

View File

@ -20,7 +20,7 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \
CryptoTask.cpp \
JARSignatureVerification.cpp \
CertVerifier.cpp \
nsCERTValInParamWrapper.cpp \
nsNSSCleaner.cpp \
nsCertOverrideService.cpp \
nsRecentBadCerts.cpp \

View File

@ -95,7 +95,6 @@
*/
#include "SSLServerCertVerification.h"
#include "CertVerifier.h"
#include "nsIBadCertListener2.h"
#include "nsICertOverrideService.h"
#include "nsIStrictTransportSecurityService.h"
@ -114,6 +113,7 @@
#include "nsServiceManagerUtils.h"
#include "nsIConsoleService.h"
#include "PSMRunnable.h"
#include "ScopedNSSTypes.h"
#include "SharedSSLState.h"
#include "ssl.h"
@ -131,7 +131,6 @@ namespace {
NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate)
NSSCleanupAutoPtrClass_WithParam(PLArenaPool, PORT_FreeArena, FalseParam, false)
// do not use a nsCOMPtr to avoid static initializer/destructor
@ -468,26 +467,31 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
}
SECStatus srv;
nsresult nsrv;
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
if (!certVerifier) {
NS_ERROR("GetDefaultCerVerifier failed");
nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
if (!inss) {
NS_ERROR("do_GetService(kNSSComponentCID) failed");
PR_SetError(defaultErrorCodeToReport, 0);
return nullptr;
}
RefPtr<nsCERTValInParamWrapper> survivingParams;
nsrv = inss->GetDefaultCERTValInParam(survivingParams);
if (NS_FAILED(nsrv)) {
NS_ERROR("GetDefaultCERTValInParam failed");
PR_SetError(defaultErrorCodeToReport, 0);
return nullptr;
}
PRTime now = PR_Now();
PLArenaPool *log_arena = nullptr;
PLArenaPool *log_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
PLArenaPoolCleanerFalseParam log_arena_cleaner(log_arena);
CERTVerifyLog * verify_log = nullptr;
log_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!log_arena) {
NS_ERROR("PORT_NewArena failed");
return nullptr; // PORT_NewArena set error code
}
verify_log = PORT_ArenaZNew(log_arena, CERTVerifyLog);
CERTVerifyLog *verify_log = PORT_ArenaZNew(log_arena, CERTVerifyLog);
if (!verify_log) {
NS_ERROR("PORT_ArenaZNew failed");
return nullptr; // PORT_ArenaZNew set error code
@ -495,8 +499,22 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
CERTVerifyLogContentsCleaner verify_log_cleaner(verify_log);
verify_log->arena = log_arena;
srv = certVerifier->VerifyCert(cert, certificateUsageSSLServer, now,
infoObject, 0, nullptr, nullptr, verify_log);
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
srv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), cert,
true, certificateUsageSSLServer,
PR_Now(), static_cast<void*>(infoObject),
verify_log, nullptr);
}
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(cert, certificateUsageSSLServer,
survivingParams->GetRawPointerForNSS(),
cvout, static_cast<void*>(infoObject));
}
// We ignore the result code of the cert verification.
// Either it is a failure, which is expected, and we'll process the
@ -521,44 +539,40 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
}
if (verify_log) {
CERTVerifyLogNode *i_node;
for (i_node = verify_log->head; i_node; i_node = i_node->next)
CERTVerifyLogNode *i_node;
for (i_node = verify_log->head; i_node; i_node = i_node->next)
{
switch (i_node->error)
{
switch (i_node->error)
{
case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_CA_CERT_INVALID:
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
case SEC_ERROR_UNTRUSTED_CERT:
case SEC_ERROR_INADEQUATE_KEY_USAGE:
case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
// We group all these errors as "cert not trusted"
collected_errors |= nsICertOverrideService::ERROR_UNTRUSTED;
if (errorCodeTrust == SECSuccess) {
errorCodeTrust = i_node->error;
}
break;
case SSL_ERROR_BAD_CERT_DOMAIN:
collected_errors |= nsICertOverrideService::ERROR_MISMATCH;
if (errorCodeMismatch == SECSuccess) {
errorCodeMismatch = i_node->error;
}
break;
case SEC_ERROR_EXPIRED_CERTIFICATE:
collected_errors |= nsICertOverrideService::ERROR_TIME;
if (errorCodeExpired == SECSuccess) {
errorCodeExpired = i_node->error;
}
break;
default:
PR_SetError(i_node->error, 0);
return nullptr;
}
case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_CA_CERT_INVALID:
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
case SEC_ERROR_UNTRUSTED_CERT:
case SEC_ERROR_INADEQUATE_KEY_USAGE:
case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
// We group all these errors as "cert not trusted"
collected_errors |= nsICertOverrideService::ERROR_UNTRUSTED;
if (errorCodeTrust == SECSuccess) {
errorCodeTrust = i_node->error;
}
break;
case SSL_ERROR_BAD_CERT_DOMAIN:
collected_errors |= nsICertOverrideService::ERROR_MISMATCH;
if (errorCodeMismatch == SECSuccess) {
errorCodeMismatch = i_node->error;
}
break;
case SEC_ERROR_EXPIRED_CERTIFICATE:
collected_errors |= nsICertOverrideService::ERROR_TIME;
if (errorCodeExpired == SECSuccess) {
errorCodeExpired = i_node->error;
}
break;
default:
PR_SetError(i_node->error, 0);
return nullptr;
}
} else {
// XXX set errorCodeTrust, errorCodeMismatch, errorCodeExpired, collected_errors
}
if (!collected_errors)
@ -647,21 +661,31 @@ SSLServerCertVerificationJob::SSLServerCertVerificationJob(
}
SECStatus
PSM_SSL_PKIX_AuthCertificate(CERTCertificate *peerCert,
nsIInterfaceRequestor * pinarg,
const char * hostname,
CERTCertList **validationChain,
SECOidTag *evOidPolicy)
PSM_SSL_PKIX_AuthCertificate(CERTCertificate *peerCert, void * pinarg,
const char * hostname)
{
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
if (!certVerifier) {
PR_SetError(PR_INVALID_STATE_ERROR, 0);
return SECFailure;
SECStatus rv;
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
rv = CERT_VerifyCertNow(CERT_GetDefaultCertDB(), peerCert, true,
certUsageSSLServer, pinarg);
}
else {
nsresult nsrv;
nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
if (!inss)
return SECFailure;
RefPtr<nsCERTValInParamWrapper> survivingParams;
if (NS_FAILED(inss->GetDefaultCERTValInParam(survivingParams)))
return SECFailure;
SECStatus rv = certVerifier->VerifyCert(peerCert,
certificateUsageSSLServer, PR_Now(),
pinarg, 0, validationChain , evOidPolicy);
CERTValOutParam cvout[1];
cvout[0].type = cert_po_end;
rv = CERT_PKIXVerifyCert(peerCert, certificateUsageSSLServer,
survivingParams->GetRawPointerForNSS(),
cvout, pinarg);
}
if (rv == SECSuccess) {
/* cert is OK. This is the client side of an SSL connection.
@ -873,12 +897,8 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert,
}
}
CERTCertList *verifyCertChain = nullptr;
SECOidTag evOidPolicy;
SECStatus rv = PSM_SSL_PKIX_AuthCertificate(cert, infoObject,
infoObject->GetHostName(),
&verifyCertChain,
&evOidPolicy);
infoObject->GetHostName());
// 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.
@ -888,12 +908,7 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert,
RefPtr<nsNSSCertificate> nsc;
if (!status || !status->mServerCert) {
if( rv == SECSuccess ){
nsc = nsNSSCertificate::Create(cert, &evOidPolicy);
}
else {
nsc = nsNSSCertificate::Create(cert);
}
nsc = nsNSSCertificate::Create(cert);
}
ScopedCERTCertList certList(CERT_GetCertChainFromCert(cert, PR_Now(),
@ -922,6 +937,13 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert,
}
if (rv == SECSuccess) {
if (nsc) {
bool dummyIsEV;
nsc->GetIsExtendedValidation(&dummyIsEV); // the nsc object will cache the status
}
nsCOMPtr<nsINSSComponent> nssComponent;
// We want to avoid storing any intermediate cert information when browsing
// in private, transient contexts.
if (!(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE)) {

View File

@ -0,0 +1,126 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCERTValInParamWrapper.h"
NS_IMPL_THREADSAFE_ADDREF(nsCERTValInParamWrapper)
NS_IMPL_THREADSAFE_RELEASE(nsCERTValInParamWrapper)
nsCERTValInParamWrapper::nsCERTValInParamWrapper()
:mAlreadyConstructed(false)
,mCVIN(nullptr)
,mRev(nullptr)
{
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;
mOCSPDownloadEnabled = odc == ocsp_on;
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
;
bool wantsCrlFirst = (firstNetworkRevocationMethod != nullptr)
&& (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 = true;
mCVIN = p;
mRev = rev;
return NS_OK;
}

View File

@ -0,0 +1,71 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#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 RefPtr<nsCERTValInParamWrapper> = 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();
bool IsOCSPDownloadEnabled() const { return mOCSPDownloadEnabled; }
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
bool mAlreadyConstructed;
CERTValInParam *mCVIN;
CERTRevocationFlags *mRev;
bool mOCSPDownloadEnabled;
public:
CERTValInParam *GetRawPointerForNSS() { return mCVIN; }
};
#endif

View File

@ -3,9 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCMS.h"
#include "CertVerifier.h"
#include "nsISupports.h"
#include "nsCMS.h"
#include "nsNSSHelper.h"
#include "nsNSSCertificate.h"
#include "smime.h"
@ -14,17 +13,19 @@
#include "nsIArray.h"
#include "nsArrayUtils.h"
#include "nsCertVerificationThread.h"
#include "nsCERTValInParamWrapper.h"
#include "ScopedNSSTypes.h"
#include "prlog.h"
using namespace mozilla;
using namespace mozilla::psm;
#include "nsNSSComponent.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
#endif
using namespace mozilla;
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
NS_IMPL_THREADSAFE_ISUPPORTS2(nsCMSMessage, nsICMSMessage,
@ -217,8 +218,9 @@ nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, uint32_
NSSCMSSignedData *sigd = nullptr;
NSSCMSSignerInfo *si;
int32_t nsigners;
RefPtr<CertVerifier> certVerifier;
nsresult rv = NS_ERROR_FAILURE;
RefPtr<nsCERTValInParamWrapper> survivingParams;
nsCOMPtr<nsINSSComponent> inss;
if (!NSS_CMSMessage_IsSigned(m_cmsMsg)) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - not signed\n"));
@ -262,16 +264,32 @@ nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, uint32_
// See bug 324474. We want to make sure the signing cert is
// still valid at the current time.
certVerifier = GetDefaultCertVerifier();
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
if (CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), si->cert, true,
certificateUsageEmailSigner,
si->cmsg->pwfn_arg, nullptr) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - signing cert not trusted now\n"));
rv = NS_ERROR_CMS_VERIFY_UNTRUSTED;
goto loser;
}
}
else {
CERTValOutParam cvout[1];
cvout[0].type = cert_po_end;
{
SECStatus srv = certVerifier->VerifyCert(si->cert,
certificateUsageEmailSigner,
PR_Now(), nullptr /*XXX pinarg*/);
if (srv != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("nsCMSMessage::CommonVerifySignature - signing cert not trusted now\n"));
inss = do_GetService(kNSSComponentCID, &rv);
if (!inss) {
goto loser;
}
if (NS_FAILED(inss->GetDefaultCERTValInParam(survivingParams))) {
goto loser;
}
SECStatus stat = CERT_PKIXVerifyCert(si->cert, certificateUsageEmailSigner,
survivingParams->GetRawPointerForNSS(),
cvout, si->cmsg->pwfn_arg);
if (stat != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - signing cert not trusted now\n"));
rv = NS_ERROR_CMS_VERIFY_UNTRUSTED;
goto loser;
}

View File

@ -4,7 +4,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CertVerifier.h"
#include "mozilla/RefPtr.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsStreamUtils.h"
@ -21,7 +20,6 @@
#include "ScopedNSSTypes.h"
using namespace mozilla;
using namespace mozilla::psm;
#ifdef DEBUG
#ifndef PSM_ENABLE_TEST_EV_ROOTS
@ -1015,9 +1013,7 @@ isEVPolicy(SECOidTag policyOIDTag)
return false;
}
namespace mozilla { namespace psm {
CERTCertList*
static CERTCertList*
getRootsForOid(SECOidTag oid_tag)
{
CERTCertList *certList = CERT_NewCertList();
@ -1038,8 +1034,6 @@ getRootsForOid(SECOidTag oid_tag)
return certList;
}
}}
static bool
isApprovedForEV(SECOidTag policyOIDTag, CERTCertificate *rootCert)
{
@ -1133,10 +1127,8 @@ nsNSSComponent::IdentityInfoInit()
return PR_SUCCESS;
}
namespace mozilla { namespace psm {
// Find the first policy OID that is known to be an EV policy OID.
SECStatus getFirstEVPolicy(CERTCertificate *cert, SECOidTag &outOidTag)
static SECStatus getFirstEVPolicy(CERTCertificate *cert, SECOidTag &outOidTag)
{
if (!cert)
return SECFailure;
@ -1181,8 +1173,6 @@ SECStatus getFirstEVPolicy(CERTCertificate *cert, SECOidTag &outOidTag)
return SECFailure;
}
}}
NS_IMETHODIMP
nsSSLStatus::GetIsExtendedValidation(bool* aIsEV)
{
@ -1225,23 +1215,101 @@ nsNSSCertificate::hasValidEVOidTag(SECOidTag &resultOidTag, bool &validEV)
return nrv;
nssComponent->EnsureIdentityInfoLoaded();
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
RefPtr<nsCERTValInParamWrapper> certVal;
nrv = nssComponent->GetDefaultCERTValInParam(certVal);
NS_ENSURE_SUCCESS(nrv, nrv);
validEV = false;
resultOidTag = SEC_OID_UNKNOWN;
SECStatus rv = certVerifier->VerifyCert(mCert,
certificateUsageSSLServer, PR_Now(),
nullptr /* XXX pinarg*/,
0, nullptr, &resultOidTag);
SECOidTag oid_tag;
SECStatus rv = getFirstEVPolicy(mCert, oid_tag);
if (rv != SECSuccess)
return NS_OK;
if (rv != SECSuccess) {
resultOidTag = SEC_OID_UNKNOWN;
}
if (resultOidTag != SEC_OID_UNKNOWN) {
validEV = true;
if (oid_tag == SEC_OID_UNKNOWN) // not in our list of OIDs accepted for EV
return NS_OK;
ScopedCERTCertList rootList(getRootsForOid(oid_tag));
CERTRevocationMethodIndex preferedRevMethods[1] = {
cert_revocation_method_ocsp
};
uint64_t revMethodFlags =
CERT_REV_M_TEST_USING_THIS_METHOD
| (certVal->IsOCSPDownloadEnabled() ? CERT_REV_M_ALLOW_NETWORK_FETCHING
: CERT_REV_M_FORBID_NETWORK_FETCHING)
| CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE
| CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE
| CERT_REV_M_IGNORE_MISSING_FRESH_INFO
| CERT_REV_M_STOP_TESTING_ON_FRESH_INFO;
uint64_t revMethodIndependentFlags =
CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST
| CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE;
uint64_t methodFlags[2];
methodFlags[cert_revocation_method_crl] = revMethodFlags;
methodFlags[cert_revocation_method_ocsp] = revMethodFlags;
CERTRevocationFlags rev;
rev.leafTests.number_of_defined_methods = cert_revocation_method_ocsp +1;
rev.leafTests.cert_rev_flags_per_method = methodFlags;
rev.leafTests.number_of_preferred_methods = 1;
rev.leafTests.preferred_methods = preferedRevMethods;
rev.leafTests.cert_rev_method_independent_flags =
revMethodIndependentFlags;
rev.chainTests.number_of_defined_methods = cert_revocation_method_ocsp +1;
rev.chainTests.cert_rev_flags_per_method = methodFlags;
rev.chainTests.number_of_preferred_methods = 1;
rev.chainTests.preferred_methods = preferedRevMethods;
rev.chainTests.cert_rev_method_independent_flags =
revMethodIndependentFlags;
CERTValInParam cvin[4];
cvin[0].type = cert_pi_policyOID;
cvin[0].value.arraySize = 1;
cvin[0].value.array.oids = &oid_tag;
cvin[1].type = cert_pi_revocationFlags;
cvin[1].value.pointer.revocation = &rev;
cvin[2].type = cert_pi_trustAnchors;
cvin[2].value.pointer.chain = rootList;
cvin[3].type = cert_pi_end;
CERTValOutParam cvout[2];
cvout[0].type = cert_po_trustAnchor;
cvout[0].value.pointer.cert = nullptr;
cvout[1].type = cert_po_end;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("calling CERT_PKIXVerifyCert nss cert %p\n", mCert.get()));
rv = CERT_PKIXVerifyCert(mCert, certificateUsageSSLServer,
cvin, cvout, nullptr);
if (rv != SECSuccess)
return NS_OK;
ScopedCERTCertificate issuerCert(cvout[0].value.pointer.cert);
#ifdef PR_LOGGING
if (PR_LOG_TEST(gPIPNSSLog, PR_LOG_DEBUG)) {
nsNSSCertificate ic(issuerCert);
nsAutoString fingerprint;
ic.GetSha1Fingerprint(fingerprint);
NS_LossyConvertUTF16toASCII fpa(fingerprint);
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CERT_PKIXVerifyCert returned success, issuer: %s, SHA1: %s\n",
issuerCert->subjectName, fpa.get()));
}
#endif
validEV = isApprovedForEV(oid_tag, issuerCert);
if (validEV)
resultOidTag = oid_tag;
return NS_OK;
}
@ -1277,10 +1345,8 @@ nsNSSCertificate::GetIsExtendedValidation(bool* aIsEV)
if (mCachedEVStatus != ev_status_unknown) {
*aIsEV = (mCachedEVStatus == ev_status_valid);
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSSCertificate::GetIsExtendedValidation value IS cached! \n"));
return NS_OK;
}
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSSCertificate::GetIsExtendedValidation value is NOT cached! \n"));
SECOidTag oid_tag;
return getValidEVOidTag(oid_tag, *aIsEV);

View File

@ -7,12 +7,11 @@
#include "prerror.h"
#include "prprf.h"
#include "nsNSSCertificate.h"
#include "CertVerifier.h"
#include "nsNSSComponent.h" // for PIPNSS string bundle calls.
#include "nsNSSCleaner.h"
#include "nsCOMPtr.h"
#include "nsIMutableArray.h"
#include "nsNSSCertificate.h"
#include "nsNSSCertValidity.h"
#include "nsPKCS12Blob.h"
#include "nsPK11TokenDB.h"
@ -49,7 +48,6 @@
#include "plbase64.h"
using namespace mozilla;
using namespace mozilla::psm;
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
@ -77,14 +75,14 @@ NS_IMPL_THREADSAFE_ISUPPORTS7(nsNSSCertificate, nsIX509Cert,
/* static */
nsNSSCertificate*
nsNSSCertificate::Create(CERTCertificate *cert, SECOidTag *evOidPolicy)
nsNSSCertificate::Create(CERTCertificate *cert)
{
if (GeckoProcessType_Default != XRE_GetProcessType()) {
NS_ERROR("Trying to initialize nsNSSCertificate in a non-chrome process!");
return nullptr;
}
if (cert)
return new nsNSSCertificate(cert, evOidPolicy);
return new nsNSSCertificate(cert);
else
return new nsNSSCertificate();
}
@ -129,8 +127,7 @@ nsNSSCertificate::InitFromDER(char *certDER, int derLen)
return true;
}
nsNSSCertificate::nsNSSCertificate(CERTCertificate *cert,
SECOidTag *evOidPolicy) :
nsNSSCertificate::nsNSSCertificate(CERTCertificate *cert) :
mCert(nullptr),
mPermDelete(false),
mCertType(CERT_TYPE_NOT_YET_INITIALIZED),
@ -145,18 +142,8 @@ nsNSSCertificate::nsNSSCertificate(CERTCertificate *cert,
if (isAlreadyShutDown())
return;
if (cert) {
if (cert)
mCert = CERT_DupCertificate(cert);
if (evOidPolicy) {
if ( *evOidPolicy == SEC_OID_UNKNOWN) {
mCachedEVStatus = ev_status_invalid;
}
else {
mCachedEVStatus = ev_status_valid;
}
mCachedEVOidTag = *evOidPolicy;
}
}
}
nsNSSCertificate::nsNSSCertificate() :
@ -1214,9 +1201,15 @@ nsNSSCertificate::VerifyForUsage(uint32_t usage, uint32_t *verificationResult)
NS_ENSURE_ARG(verificationResult);
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
nsresult nsrv;
nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
if (!inss)
return nsrv;
RefPtr<nsCERTValInParamWrapper> survivingParams;
nsrv = inss->GetDefaultCERTValInParam(survivingParams);
if (NS_FAILED(nsrv))
return nsrv;
SECCertificateUsage nss_usage;
switch (usage)
@ -1273,8 +1266,19 @@ nsNSSCertificate::VerifyForUsage(uint32_t usage, uint32_t *verificationResult)
return NS_ERROR_FAILURE;
}
SECStatus verify_result = certVerifier->VerifyCert(mCert, nss_usage, PR_Now(),
nullptr /*XXX pinarg*/);
SECStatus verify_result;
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
CERTCertDBHandle *defaultcertdb = CERT_GetDefaultCertDB();
verify_result = CERT_VerifyCertificateNow(defaultcertdb, mCert, true,
nss_usage, nullptr, nullptr);
}
else {
CERTValOutParam cvout[1];
cvout[0].type = cert_po_end;
verify_result = CERT_PKIXVerifyCert(mCert, nss_usage,
survivingParams->GetRawPointerForNSS(),
cvout, nullptr);
}
if (verify_result == SECSuccess)
{

View File

@ -44,12 +44,12 @@ public:
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO
nsNSSCertificate(CERTCertificate *cert,SECOidTag *evOidPolicy = nullptr);
nsNSSCertificate(CERTCertificate *cert);
nsNSSCertificate();
/* from a request? */
virtual ~nsNSSCertificate();
nsresult FormatUIStrings(const nsAutoString &nickname, nsAutoString &nickWithSerial, nsAutoString &details);
static nsNSSCertificate* Create(CERTCertificate *cert = nullptr, SECOidTag *evOidPolicy = nullptr);
static nsNSSCertificate* Create(CERTCertificate *cert = nullptr);
static nsNSSCertificate* ConstructFromDER(char *certDER, int derLen);
// It is the responsibility of the caller of this method to free the returned

View File

@ -7,10 +7,8 @@
// only exported so PSM can use it for this specific purpose.
#define CERT_AddTempCertToPerm __CERT_AddTempCertToPerm
#include "nsNSSCertificateDB.h"
#include "CertVerifier.h"
#include "nsNSSComponent.h"
#include "nsNSSCertificateDB.h"
#include "mozilla/Base64.h"
#include "nsCOMPtr.h"
#include "nsNSSCertificate.h"
@ -48,7 +46,6 @@
#include "plbase64.h"
using namespace mozilla;
using namespace mozilla::psm;
using mozilla::psm::SharedSSLState;
#ifdef PR_LOGGING
@ -497,9 +494,22 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
CERTCertificate **certArray = nullptr;
ScopedCERTCertList certList;
CERTCertListNode *node;
PRTime now;
SECCertUsage certusage;
SECCertificateUsage certificateusage;
SECItem **rawArray;
int numcerts;
int i;
CERTValOutParam cvout[1];
cvout[0].type = cert_po_end;
nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
if (!inss)
return nsrv;
RefPtr<nsCERTValInParamWrapper> survivingParams;
nsrv = inss->GetDefaultCERTValInParam(survivingParams);
if (NS_FAILED(nsrv))
return nsrv;
PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena)
@ -511,11 +521,9 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
return NS_ERROR_FAILURE;
}
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
certdb = CERT_GetDefaultCertDB();
const PRTime now = PR_Now();
certusage = certUsageEmailRecipient;
certificateusage = certificateUsageEmailRecipient;
numcerts = certCollection->numcerts;
@ -529,7 +537,7 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
rawArray[i] = &certCollection->rawCerts[i];
}
srv = CERT_ImportCerts(certdb, certUsageEmailRecipient, numcerts, rawArray,
srv = CERT_ImportCerts(certdb, certusage, numcerts, rawArray,
&certArray, false, false, nullptr);
PORT_Free(rawArray);
@ -557,6 +565,7 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
/* go down the remaining list of certs and verify that they have
* valid chains, then import them.
*/
now = PR_Now();
for (node = CERT_LIST_HEAD(certList);
!CERT_LIST_END(node,certList);
@ -568,18 +577,25 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
continue;
}
SECStatus rv = certVerifier->VerifyCert(node->cert,
certificateUsageEmailRecipient,
now, ctx);
if (rv != SECSuccess) {
alert_and_skip = true;
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
if (CERT_VerifyCert(certdb, node->cert,
true, certusage, now, ctx, nullptr) != SECSuccess) {
alert_and_skip = true;
}
}
else {
if (CERT_PKIXVerifyCert(node->cert, certificateusage,
survivingParams->GetRawPointerForNSS(),
cvout, ctx)
!= SECSuccess) {
alert_and_skip = true;
}
}
ScopedCERTCertificateList certChain;
if (!alert_and_skip) {
certChain = CERT_CertChainFromCert(node->cert, certUsageEmailRecipient,
false);
certChain = CERT_CertChainFromCert(node->cert, certusage, false);
if (!certChain) {
alert_and_skip = true;
}
@ -603,7 +619,7 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
for (i=0; i < certChain->len; i++) {
rawArray[i] = &certChain->certs[i];
}
CERT_ImportCerts(certdb, certUsageEmailRecipient, certChain->len,
CERT_ImportCerts(certdb, certusage, certChain->len,
rawArray, nullptr, true, false, nullptr);
CERT_SaveSMimeProfile(node->cert, nullptr, nullptr);
@ -736,9 +752,14 @@ nsresult
nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfaceRequestor *ctx)
{
SECItem **rawArray;
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
if (!certVerifier)
return NS_ERROR_UNEXPECTED;
nsresult nsrv;
nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
if (!inss)
return nsrv;
RefPtr<nsCERTValInParamWrapper> 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, true);
@ -759,10 +780,19 @@ nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfac
bool alert_and_skip = false;
SECStatus rv = certVerifier->VerifyCert(node->cert, certificateUsageVerifyCA,
PR_Now(), ctx);
if (rv != SECSuccess) {
alert_and_skip = true;
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
if (CERT_VerifyCert(CERT_GetDefaultCertDB(), node->cert,
true, certUsageVerifyCA, PR_Now(), ctx, nullptr) != SECSuccess) {
alert_and_skip = true;
}
}
else {
if (CERT_PKIXVerifyCert(node->cert, certificateUsageVerifyCA,
survivingParams->GetRawPointerForNSS(),
cvout, ctx)
!= SECSuccess) {
alert_and_skip = true;
}
}
ScopedCERTCertificateList certChain;
@ -1294,8 +1324,18 @@ nsNSSCertificateDB::FindCertByEmailAddress(nsISupports *aToken, const char *aEma
{
nsNSSShutDownPreventionLock locker;
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsINSSComponent> inss;
RefPtr<nsCERTValInParamWrapper> survivingParams;
nsresult nsrv;
if (nsNSSComponent::globalConstFlagUsePKIXVerification) {
inss = do_GetService(kNSSComponentCID, &nsrv);
if (!inss)
return nsrv;
nsrv = inss->GetDefaultCERTValInParam(survivingParams);
if (NS_FAILED(nsrv))
return nsrv;
}
ScopedCERTCertList certlist(
PK11_FindCertsFromEmailAddress(aEmailAddress, nullptr));
@ -1314,11 +1354,23 @@ nsNSSCertificateDB::FindCertByEmailAddress(nsISupports *aToken, const char *aEma
!CERT_LIST_END(node, certlist);
node = CERT_LIST_NEXT(node)) {
SECStatus srv = certVerifier->VerifyCert(node->cert,
certificateUsageEmailRecipient,
PR_Now(), nullptr /*XXX pinarg*/);
if (srv == SECSuccess) {
break;
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
if (CERT_VerifyCert(CERT_GetDefaultCertDB(), node->cert,
true, certUsageEmailRecipient, PR_Now(), nullptr, nullptr) == SECSuccess) {
// found a valid certificate
break;
}
}
else {
CERTValOutParam cvout[1];
cvout[0].type = cert_po_end;
if (CERT_PKIXVerifyCert(node->cert, certificateUsageEmailRecipient,
survivingParams->GetRawPointerForNSS(),
cvout, nullptr)
== SECSuccess) {
// found a valid certificate
break;
}
}
}

View File

@ -9,8 +9,6 @@
#endif
#include "nsNSSComponent.h"
#include "CertVerifier.h"
#include "nsNSSCallbacks.h"
#include "nsNSSIOLayer.h"
#include "nsCertVerificationThread.h"
@ -69,6 +67,7 @@
#include "nsNSSShutDown.h"
#include "GeneratedEvents.h"
#include "nsIKeyModule.h"
#include "ScopedNSSTypes.h"
#include "SharedSSLState.h"
#include "nss.h"
@ -1099,18 +1098,23 @@ void nsNSSComponent::setValidationOptions(nsIPrefBranch * pref)
ocspMode_FailureIsVerificationFailure
: ocspMode_FailureIsNotAVerificationFailure);
mDefaultCertVerifier = new CertVerifier(
RefPtr<nsCERTValInParamWrapper> newCVIN(new nsCERTValInParamWrapper);
if (NS_SUCCEEDED(newCVIN->Construct(
aiaDownloadEnabled ?
CertVerifier::missing_cert_download_on : CertVerifier::missing_cert_download_off,
nsCERTValInParamWrapper::missing_cert_download_on : nsCERTValInParamWrapper::missing_cert_download_off,
crlDownloading ?
CertVerifier::crl_download_allowed : CertVerifier::crl_local_only,
nsCERTValInParamWrapper::crl_download_allowed : nsCERTValInParamWrapper::crl_local_only,
ocspEnabled ?
CertVerifier::ocsp_on : CertVerifier::ocsp_off,
nsCERTValInParamWrapper::ocsp_on : nsCERTValInParamWrapper::ocsp_off,
ocspRequired ?
CertVerifier::ocsp_strict : CertVerifier::ocsp_relaxed,
nsCERTValInParamWrapper::ocsp_strict : nsCERTValInParamWrapper::ocsp_relaxed,
anyFreshRequired ?
CertVerifier::any_revo_strict : CertVerifier::any_revo_relaxed,
firstNetworkRevo.get());
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,
@ -1822,6 +1826,20 @@ nsNSSComponent::InitializeNSS(bool showWarningBox)
// 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,
FIRST_REVO_METHOD_DEFAULT);
if (NS_FAILED(rv)) {
nsPSMInitPanic::SetPanic();
return rv;
}
RegisterMyOCSPAIAInfoCallback();
mHttpForNSS.initTable();
@ -2035,7 +2053,7 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen,
*aPrincipal = nullptr;
nsNSSShutDownPreventionLock locker;
ScopedSEC_PKCS7ContentInfo p7_info;
ScopedSEC_PKCS7ContentInfo p7_info;
unsigned char hash[SHA1_LENGTH];
SECItem item;
@ -2048,6 +2066,10 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen,
GetDecryptKeyCallback, nullptr,
DecryptionAllowedCallback);
if (!p7_info) {
return NS_ERROR_FAILURE;
}
// Make sure we call SEC_PKCS7DestroyContentInfo after this point;
// otherwise we leak data in p7_info
@ -2504,12 +2526,22 @@ nsNSSComponent::IsNSSInitialized(bool *initialized)
}
NS_IMETHODIMP
nsNSSComponent::GetDefaultCertVerifier(RefPtr<CertVerifier> &out)
nsNSSComponent::GetDefaultCERTValInParam(RefPtr<nsCERTValInParamWrapper> &out)
{
MutexAutoLock lock(mutex);
if (!mNSSInitialized)
return NS_ERROR_NOT_INITIALIZED;
out = mDefaultCertVerifier;
out = mDefaultCERTValInParam;
return NS_OK;
}
NS_IMETHODIMP
nsNSSComponent::GetDefaultCERTValInParamLocalOnly(RefPtr<nsCERTValInParamWrapper> &out)
{
MutexAutoLock lock(mutex);
if (!mNSSInitialized)
return NS_ERROR_NOT_INITIALIZED;
out = mDefaultCERTValInParamLocalOnly;
return NS_OK;
}

View File

@ -37,13 +37,7 @@
#include "nsNSSHelper.h"
#include "nsClientAuthRemember.h"
namespace mozilla { namespace psm {
class CertVerifier;
} } // namespace mozilla::psm
#include "nsCERTValInParamWrapper.h"
#define NS_NSSCOMPONENT_CID \
{0xa277189c, 0x1dd1, 0x11b2, {0xa8, 0xc9, 0xe4, 0xe8, 0xbf, 0xb1, 0x33, 0x8e}}
@ -163,8 +157,10 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports {
NS_IMETHOD IsNSSInitialized(bool *initialized) = 0;
NS_IMETHOD GetDefaultCertVerifier(
mozilla::RefPtr<mozilla::psm::CertVerifier> &out) = 0;
NS_IMETHOD GetDefaultCERTValInParam(
mozilla::RefPtr<nsCERTValInParamWrapper> &out) = 0;
NS_IMETHOD GetDefaultCERTValInParamLocalOnly(
mozilla::RefPtr<nsCERTValInParamWrapper> &out) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsINSSComponent, NS_INSSCOMPONENT_IID)
@ -268,8 +264,10 @@ public:
NS_IMETHOD EnsureIdentityInfoLoaded();
NS_IMETHOD IsNSSInitialized(bool *initialized);
NS_IMETHOD GetDefaultCertVerifier(
mozilla::RefPtr<mozilla::psm::CertVerifier> &out);
NS_IMETHOD GetDefaultCERTValInParam(
mozilla::RefPtr<nsCERTValInParamWrapper> &out);
NS_IMETHOD GetDefaultCERTValInParamLocalOnly(
mozilla::RefPtr<nsCERTValInParamWrapper> &out);
private:
nsresult InitializeNSS(bool showWarningBox);
@ -329,8 +327,8 @@ private:
nsCertVerificationThread *mCertVerificationThread;
nsNSSHttpInterface mHttpForNSS;
mozilla::RefPtr<mozilla::psm::CertVerifier> mDefaultCertVerifier;
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParam;
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParamLocalOnly;
static PRStatus IdentityInfoInit(void);
PRCallOnceType mIdentityInfoCallOnce;

View File

@ -16,7 +16,6 @@
#include "secerr.h"
using namespace mozilla;
using namespace mozilla::psm;
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
@ -119,10 +118,8 @@ isFatalError(uint32_t checkResult)
uint32_t
nsUsageArrayHelper::check(uint32_t previousCheckResult,
const char *suffix,
CertVerifier * certVerifier,
SECCertificateUsage aCertUsage,
PRTime time,
CertVerifier::Flags flags,
nsCERTValInParamWrapper * aValInParams,
uint32_t &aCounter,
PRUnichar **outUsages)
{
@ -178,8 +175,13 @@ nsUsageArrayHelper::check(uint32_t previousCheckResult,
return nsIX509Cert::NOT_VERIFIED_UNKNOWN;
}
SECStatus rv = certVerifier->VerifyCert(mCert, aCertUsage,
time, nullptr /*XXX:wincx*/, flags);
SECStatus rv;
CERTValOutParam cvout[1];
cvout[0].type = cert_po_end;
rv = CERT_PKIXVerifyCert(mCert, aCertUsage,
aValInParams->GetRawPointerForNSS(),
cvout, nullptr);
if (rv == SECSuccess) {
typestr.Append(suffix);
@ -296,6 +298,7 @@ if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
check(suffix, usages & certificateUsageSSLClient, count, outUsages);
check(suffix, usages & certificateUsageSSLServer, count, outUsages);
check(suffix, usages & certificateUsageSSLServerWithStepUp, count, outUsages);
check(suffix, usages & certificateUsageEmailSigner, count, outUsages);
check(suffix, usages & certificateUsageEmailRecipient, count, outUsages);
check(suffix, usages & certificateUsageObjectSigner, count, outUsages);
@ -320,43 +323,43 @@ if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
return NS_OK;
}
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
PRTime now = PR_Now();
CertVerifier::Flags flags = localOnly ? CertVerifier::FLAG_LOCAL_ONLY : 0;
RefPtr<nsCERTValInParamWrapper> params;
nsresult rv = localOnly ? nssComponent->GetDefaultCERTValInParamLocalOnly(params)
: nssComponent->GetDefaultCERTValInParam(params);
NS_ENSURE_SUCCESS(rv, rv);
// The following list of checks must be < max_returned_out_array_size
uint32_t result;
result = check(nsIX509Cert::VERIFIED_OK, suffix, certVerifier,
certificateUsageSSLClient, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageSSLServer, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageEmailSigner, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageEmailRecipient, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageObjectSigner, now, flags, count, outUsages);
result = check(nsIX509Cert::VERIFIED_OK, suffix, certificateUsageSSLClient,
params, count, outUsages);
result = check(result, suffix, certificateUsageSSLServer,
params, count, outUsages);
result = check(result, suffix, certificateUsageSSLServerWithStepUp,
params, count, outUsages);
result = check(result, suffix, certificateUsageEmailSigner,
params, count, outUsages);
result = check(result, suffix, certificateUsageEmailRecipient,
params, count, outUsages);
result = check(result, suffix, certificateUsageObjectSigner,
params, count, outUsages);
#if 0
result = check(result, suffix, certVerifier,
certificateUsageProtectedObjectSigner, now, flags, count,
outUsages);
result = check(result, suffix, certVerifier,
certificateUsageUserCertImport, now, flags, count, outUsages);
result = check(result, suffix, certificateUsageProtectedObjectSigner,
params, count, outUsages);
result = check(result, suffix, certificateUsageUserCertImport,
params, count, outUsages);
#endif
result = check(result, suffix, certVerifier,
certificateUsageSSLCA, now, flags, count, outUsages);
result = check(result, suffix, certificateUsageSSLCA,
params, count, outUsages);
#if 0
result = check(result, suffix, certVerifier,
certificateUsageVerifyCA, now, flags, count, outUsages);
result = check(result, suffix, certificateUsageVerifyCA,
params, count, outUsages);
#endif
result = check(result, suffix, certVerifier,
certificateUsageStatusResponder, now, flags, count, outUsages);
result = check(result, suffix, certificateUsageStatusResponder,
params, count, outUsages);
#if 0
result = check(result, suffix, certVerifier,
certificateUsageAnyCA, now, flags, count, outUsages);
result = checkPKIX(result, check(suffix, certificateUsageAnyCA,
params, count, outUsages);
#endif
if (isFatalError(result) || count == 0) {

View File

@ -5,10 +5,10 @@
#ifndef _NSUSAGEARRAYHELPER_H_
#define _NSUSAGEARRAYHELPER_H_
#include "CertVerifier.h"
#include "nsNSSComponent.h"
#include "certt.h"
#include "nsNSSComponent.h"
class nsUsageArrayHelper
{
public:
@ -38,10 +38,8 @@ private:
uint32_t check(uint32_t previousCheckResult,
const char *suffix,
mozilla::psm::CertVerifier * certVerifier,
SECCertificateUsage aCertUsage,
PRTime time,
mozilla::psm::CertVerifier::Flags flags,
nsCERTValInParamWrapper * aValInParams,
uint32_t &aCounter,
PRUnichar **outUsages);