mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 891066, Part 1: Remove CertVerifier's dependency on nsNSSComponent, r=keeler, r=cviecco
--HG-- extra : rebase_source : 3242f78d6d4d68080997dd56dae1fd0675750d5e extra : source : 965c9f30e9b87e418bbf6ab43657257e94992223
This commit is contained in:
parent
66b7c5ca69
commit
5a83bd1831
@ -3,10 +3,10 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CertVerifier.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "cert.h"
|
||||
#include "secerr.h"
|
||||
#include "prerror.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
extern PRLogModuleInfo* gPIPNSSLog;
|
||||
@ -20,31 +20,30 @@ extern CERTCertList* getRootsForOid(SECOidTag oid_tag);
|
||||
const CertVerifier::Flags CertVerifier::FLAG_LOCAL_ONLY = 1;
|
||||
const CertVerifier::Flags CertVerifier::FLAG_NO_DV_FALLBACK_FOR_EV = 2;
|
||||
|
||||
CertVerifier::CertVerifier(missing_cert_download_config mcdc,
|
||||
CertVerifier::CertVerifier(implementation_config ic,
|
||||
missing_cert_download_config mcdc,
|
||||
crl_download_config cdc,
|
||||
ocsp_download_config odc,
|
||||
ocsp_strict_config osc,
|
||||
ocsp_get_config ogc)
|
||||
: mMissingCertDownloadEnabled(mcdc == missing_cert_download_on)
|
||||
: mImplementation(ic)
|
||||
, mMissingCertDownloadEnabled(mcdc == missing_cert_download_on)
|
||||
, mCRLDownloadEnabled(cdc == crl_download_allowed)
|
||||
, mOCSPDownloadEnabled(odc == ocsp_on)
|
||||
, mOCSPStrict(osc == ocsp_strict)
|
||||
, mOCSPGETEnabled(ogc == ocsp_get_enabled)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CertVerifier);
|
||||
}
|
||||
|
||||
CertVerifier::~CertVerifier()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CertVerifier);
|
||||
}
|
||||
|
||||
|
||||
static SECStatus
|
||||
ClassicVerifyCert(CERTCertificate* cert,
|
||||
const SECCertificateUsage usage,
|
||||
const PRTime time,
|
||||
nsIInterfaceRequestor* pinArg,
|
||||
void* pinArg,
|
||||
/*optional out*/ CERTCertList** validationChain,
|
||||
/*optional out*/ CERTVerifyLog* verifyLog)
|
||||
{
|
||||
@ -117,13 +116,17 @@ SECStatus
|
||||
CertVerifier::VerifyCert(CERTCertificate* cert,
|
||||
const SECCertificateUsage usage,
|
||||
const PRTime time,
|
||||
nsIInterfaceRequestor* pinArg,
|
||||
void* pinArg,
|
||||
const Flags flags,
|
||||
/*optional out*/ CERTCertList** validationChain,
|
||||
/*optional out*/ SECOidTag* evOidPolicy,
|
||||
/*optional out*/ CERTVerifyLog* verifyLog)
|
||||
{
|
||||
if (!cert) {
|
||||
if (!cert ||
|
||||
((flags & FLAG_NO_DV_FALLBACK_FOR_EV) &&
|
||||
(usage != certificateUsageSSLServer || !evOidPolicy)))
|
||||
{
|
||||
PR_NOT_REACHED("Invalid arguments to CertVerifier::VerifyCert");
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
@ -149,17 +152,11 @@ CertVerifier::VerifyCert(CERTCertificate* cert,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
ScopedCERTCertList trustAnchors;
|
||||
SECStatus rv;
|
||||
SECOidTag evPolicy = SEC_OID_UNKNOWN;
|
||||
|
||||
#ifdef NSS_NO_LIBPKIX
|
||||
if (flags & FLAG_NO_DV_FALLBACK_FOR_EV) {
|
||||
return SECSuccess;
|
||||
}
|
||||
return ClassicVerifyCert(cert, usage, time, pinArg, validationChain,
|
||||
verifyLog);
|
||||
#else
|
||||
// Do EV checking only for sslserver usage
|
||||
if (usage == certificateUsageSSLServer) {
|
||||
SECStatus srv = getFirstEVPolicy(cert, evPolicy);
|
||||
@ -315,20 +312,29 @@ CertVerifier::VerifyCert(CERTCertificate* cert,
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we're here, PKIX EV verification failed.
|
||||
// If requested, don't do DV fallback.
|
||||
if (flags & FLAG_NO_DV_FALLBACK_FOR_EV) {
|
||||
PR_ASSERT(*evOidPolicy == SEC_OID_UNKNOWN);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
if (!nsNSSComponent::globalConstFlagUsePKIXVerification){
|
||||
if (mImplementation == classic) {
|
||||
// XXX: we do not care about the localOnly flag (currently) as the
|
||||
// caller that wants localOnly should disable and reenable the fetching.
|
||||
return ClassicVerifyCert(cert, usage, time, pinArg, validationChain,
|
||||
verifyLog);
|
||||
}
|
||||
|
||||
#ifdef NSS_NO_LIBPKIX
|
||||
PR_NOT_REACHED("libpkix implementation chosen but not even compiled in");
|
||||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
return SECFailure;
|
||||
#else
|
||||
PR_ASSERT(mImplementation == libpkix);
|
||||
|
||||
// The current flags check the chain the same way as the leafs
|
||||
rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] =
|
||||
rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] =
|
||||
@ -432,17 +438,4 @@ pkix_done:
|
||||
#endif
|
||||
}
|
||||
|
||||
TemporaryRef<CertVerifier>
|
||||
GetDefaultCertVerifier()
|
||||
{
|
||||
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
|
||||
|
||||
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID));
|
||||
RefPtr<CertVerifier> certVerifier;
|
||||
if (nssComponent) {
|
||||
(void) nssComponent->GetDefaultCertVerifier(certVerifier);
|
||||
}
|
||||
return certVerifier;
|
||||
}
|
||||
|
||||
} } // namespace mozilla::psm
|
||||
|
@ -5,21 +5,14 @@
|
||||
#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;
|
||||
#include "insanity/ScopedPtr.h"
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
class CertVerifier
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CertVerifier)
|
||||
|
||||
typedef unsigned int Flags;
|
||||
// XXX: FLAG_LOCAL_ONLY is ignored in the classic verification case
|
||||
static const Flags FLAG_LOCAL_ONLY;
|
||||
@ -31,12 +24,19 @@ public:
|
||||
SECStatus VerifyCert(CERTCertificate* cert,
|
||||
const SECCertificateUsage usage,
|
||||
const PRTime time,
|
||||
nsIInterfaceRequestor* pinArg,
|
||||
void* pinArg,
|
||||
const Flags flags = 0,
|
||||
/*optional out*/ CERTCertList** validationChain = nullptr,
|
||||
/*optional out*/ SECOidTag* evOidPolicy = nullptr ,
|
||||
/*optional out*/ CERTVerifyLog* verifyLog = nullptr);
|
||||
|
||||
enum implementation_config {
|
||||
classic = 0,
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
libpkix = 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
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 };
|
||||
@ -45,22 +45,20 @@ public:
|
||||
|
||||
bool IsOCSPDownloadEnabled() const { return mOCSPDownloadEnabled; }
|
||||
|
||||
private:
|
||||
CertVerifier(missing_cert_download_config ac, crl_download_config cdc,
|
||||
ocsp_download_config odc, ocsp_strict_config osc,
|
||||
ocsp_get_config ogc);
|
||||
CertVerifier(implementation_config ic, missing_cert_download_config ac,
|
||||
crl_download_config cdc, ocsp_download_config odc,
|
||||
ocsp_strict_config osc, ocsp_get_config ogc);
|
||||
~CertVerifier();
|
||||
|
||||
public:
|
||||
const implementation_config mImplementation;
|
||||
const bool mMissingCertDownloadEnabled;
|
||||
const bool mCRLDownloadEnabled;
|
||||
const bool mOCSPDownloadEnabled;
|
||||
const bool mOCSPStrict;
|
||||
const bool mOCSPGETEnabled;
|
||||
friend class ::nsNSSComponent;
|
||||
};
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT TemporaryRef<CertVerifier> GetDefaultCertVerifier();
|
||||
|
||||
} } // namespace mozilla::psm
|
||||
|
||||
#endif // mozilla_psm__CertVerifier_h
|
||||
|
@ -465,7 +465,8 @@ PRErrorCodeToOverrideType(PRErrorCode errorCode)
|
||||
// Returns null with the error code (PR_GetError()) set if it does not create
|
||||
// the CertErrorRunnable.
|
||||
CertErrorRunnable*
|
||||
CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
|
||||
CreateCertErrorRunnable(CertVerifier& certVerifier,
|
||||
PRErrorCode defaultErrorCodeToReport,
|
||||
TransportSecurityInfo* infoObject,
|
||||
CERTCertificate* cert,
|
||||
const void* fdForLogging,
|
||||
@ -498,13 +499,6 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
|
||||
|
||||
SECStatus srv;
|
||||
|
||||
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
if (!certVerifier) {
|
||||
NS_ERROR("GetDefaultCerVerifier failed");
|
||||
PR_SetError(defaultErrorCodeToReport, 0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PLArenaPool* log_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
PLArenaPoolCleanerFalseParam log_arena_cleaner(log_arena);
|
||||
if (!log_arena) {
|
||||
@ -520,8 +514,8 @@ 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);
|
||||
srv = certVerifier.VerifyCert(cert, certificateUsageSSLServer, now,
|
||||
infoObject, 0, nullptr, nullptr, verify_log);
|
||||
|
||||
// We ignore the result code of the cert verification.
|
||||
// Either it is a failure, which is expected, and we'll process the
|
||||
@ -624,8 +618,9 @@ class SSLServerCertVerificationJob : public nsRunnable
|
||||
{
|
||||
public:
|
||||
// Must be called only on the socket transport thread
|
||||
static SECStatus Dispatch(const void* fdForLogging,
|
||||
nsNSSSocketInfo* infoObject,
|
||||
static SECStatus Dispatch(const RefPtr<SharedCertVerifier>& certVerifier,
|
||||
const void* fdForLogging,
|
||||
TransportSecurityInfo* infoObject,
|
||||
CERTCertificate* serverCert,
|
||||
SECItem* stapledOCSPResponse,
|
||||
uint32_t providerFlags);
|
||||
@ -633,13 +628,15 @@ private:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
// Must be called only on the socket transport thread
|
||||
SSLServerCertVerificationJob(const void* fdForLogging,
|
||||
nsNSSSocketInfo* infoObject,
|
||||
SSLServerCertVerificationJob(const RefPtr<SharedCertVerifier>& certVerifier,
|
||||
const void* fdForLogging,
|
||||
TransportSecurityInfo* infoObject,
|
||||
CERTCertificate* cert,
|
||||
SECItem* stapledOCSPResponse,
|
||||
uint32_t providerFlags);
|
||||
const RefPtr<SharedCertVerifier> mCertVerifier;
|
||||
const void* const mFdForLogging;
|
||||
const RefPtr<nsNSSSocketInfo> mInfoObject;
|
||||
const RefPtr<TransportSecurityInfo> mInfoObject;
|
||||
const ScopedCERTCertificate mCert;
|
||||
const uint32_t mProviderFlags;
|
||||
const TimeStamp mJobStartTime;
|
||||
@ -647,10 +644,11 @@ private:
|
||||
};
|
||||
|
||||
SSLServerCertVerificationJob::SSLServerCertVerificationJob(
|
||||
const void* fdForLogging, nsNSSSocketInfo* infoObject,
|
||||
CERTCertificate* cert, SECItem* stapledOCSPResponse,
|
||||
uint32_t providerFlags)
|
||||
: mFdForLogging(fdForLogging)
|
||||
const RefPtr<SharedCertVerifier>& certVerifier, const void* fdForLogging,
|
||||
TransportSecurityInfo* infoObject, CERTCertificate* cert,
|
||||
SECItem* stapledOCSPResponse, uint32_t providerFlags)
|
||||
: mCertVerifier(certVerifier)
|
||||
, mFdForLogging(fdForLogging)
|
||||
, mInfoObject(infoObject)
|
||||
, mCert(CERT_DupCertificate(cert))
|
||||
, mProviderFlags(providerFlags)
|
||||
@ -660,21 +658,16 @@ SSLServerCertVerificationJob::SSLServerCertVerificationJob(
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PSM_SSL_PKIX_AuthCertificate(CERTCertificate* peerCert,
|
||||
PSM_SSL_PKIX_AuthCertificate(CertVerifier& certVerifier,
|
||||
CERTCertificate* peerCert,
|
||||
nsIInterfaceRequestor* pinarg,
|
||||
const char* hostname,
|
||||
CERTCertList** validationChain,
|
||||
SECOidTag* evOidPolicy)
|
||||
{
|
||||
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
if (!certVerifier) {
|
||||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus rv = certVerifier->VerifyCert(peerCert,
|
||||
certificateUsageSSLServer, PR_Now(),
|
||||
pinarg, 0, validationChain , evOidPolicy);
|
||||
SECStatus rv = certVerifier.VerifyCert(peerCert, certificateUsageSSLServer,
|
||||
PR_Now(), pinarg, 0,
|
||||
validationChain, evOidPolicy);
|
||||
|
||||
if (rv == SECSuccess) {
|
||||
// cert is OK. This is the client side of an SSL connection.
|
||||
@ -845,8 +838,9 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo* infoObject,
|
||||
}
|
||||
|
||||
SECStatus
|
||||
AuthCertificate(nsNSSSocketInfo* infoObject, CERTCertificate* cert,
|
||||
SECItem* stapledOCSPResponse, uint32_t providerFlags)
|
||||
AuthCertificate(CertVerifier& certVerifier, TransportSecurityInfo* infoObject,
|
||||
CERTCertificate* cert, SECItem* stapledOCSPResponse,
|
||||
uint32_t providerFlags)
|
||||
{
|
||||
if (cert->serialNumber.data &&
|
||||
cert->issuerName &&
|
||||
@ -926,7 +920,7 @@ AuthCertificate(nsNSSSocketInfo* infoObject, CERTCertificate* cert,
|
||||
PORT_Free(ocspURI);
|
||||
}
|
||||
|
||||
if (!infoObject->SharedState().IsOCSPFetchingEnabled()) {
|
||||
if (!certVerifier.mOCSPDownloadEnabled) {
|
||||
reasonsForNotFetching |= 2;
|
||||
}
|
||||
|
||||
@ -936,7 +930,8 @@ AuthCertificate(nsNSSSocketInfo* infoObject, CERTCertificate* cert,
|
||||
|
||||
CERTCertList* verifyCertChain = nullptr;
|
||||
SECOidTag evOidPolicy;
|
||||
rv = PSM_SSL_PKIX_AuthCertificate(cert, infoObject, infoObject->GetHostNameRaw(),
|
||||
rv = PSM_SSL_PKIX_AuthCertificate(certVerifier, cert, infoObject,
|
||||
infoObject->GetHostNameRaw(),
|
||||
&verifyCertChain, &evOidPolicy);
|
||||
|
||||
// We want to remember the CA certs in the temp db, so that the application can find the
|
||||
@ -1052,22 +1047,25 @@ AuthCertificate(nsNSSSocketInfo* infoObject, CERTCertificate* cert,
|
||||
}
|
||||
|
||||
/*static*/ SECStatus
|
||||
SSLServerCertVerificationJob::Dispatch(const void* fdForLogging,
|
||||
nsNSSSocketInfo* infoObject,
|
||||
CERTCertificate* serverCert,
|
||||
SECItem* stapledOCSPResponse,
|
||||
uint32_t providerFlags)
|
||||
SSLServerCertVerificationJob::Dispatch(
|
||||
const RefPtr<SharedCertVerifier>& certVerifier,
|
||||
const void* fdForLogging,
|
||||
TransportSecurityInfo* infoObject,
|
||||
CERTCertificate* serverCert,
|
||||
SECItem* stapledOCSPResponse,
|
||||
uint32_t providerFlags)
|
||||
{
|
||||
// Runs on the socket transport thread
|
||||
if (!infoObject || !serverCert) {
|
||||
if (!certVerifier || !infoObject || !serverCert) {
|
||||
NS_ERROR("Invalid parameters for SSL server cert validation");
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
RefPtr<SSLServerCertVerificationJob> job(
|
||||
new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert,
|
||||
stapledOCSPResponse, providerFlags));
|
||||
new SSLServerCertVerificationJob(certVerifier, fdForLogging, infoObject,
|
||||
serverCert, stapledOCSPResponse,
|
||||
providerFlags));
|
||||
|
||||
nsresult nrv;
|
||||
if (!gCertVerificationThreadPool) {
|
||||
@ -1108,27 +1106,37 @@ SSLServerCertVerificationJob::Run()
|
||||
if (mInfoObject->isAlreadyShutDown()) {
|
||||
error = SEC_ERROR_USER_CANCELLED;
|
||||
} else {
|
||||
Telemetry::ID successTelemetry;
|
||||
Telemetry::ID failureTelemetry;
|
||||
switch (mCertVerifier->mImplementation) {
|
||||
case CertVerifier::classic:
|
||||
successTelemetry
|
||||
= Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_CLASSIC;
|
||||
failureTelemetry
|
||||
= Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_CLASSIC;
|
||||
break;
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
case CertVerifier::libpkix:
|
||||
successTelemetry
|
||||
= Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_LIBPKIX;
|
||||
failureTelemetry
|
||||
= Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_LIBPKIX;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
MOZ_CRASH("Unknown CertVerifier mode");
|
||||
}
|
||||
|
||||
// Reset the error code here so we can detect if AuthCertificate fails to
|
||||
// set the error code if/when it fails.
|
||||
PR_SetError(0, 0);
|
||||
SECStatus rv = AuthCertificate(mInfoObject, mCert, mStapledOCSPResponse,
|
||||
mProviderFlags);
|
||||
SECStatus rv = AuthCertificate(*mCertVerifier, mInfoObject, mCert,
|
||||
mStapledOCSPResponse, mProviderFlags);
|
||||
if (rv == SECSuccess) {
|
||||
uint32_t interval = (uint32_t) ((TimeStamp::Now() - mJobStartTime).ToMilliseconds());
|
||||
Telemetry::ID telemetryID;
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
if(nsNSSComponent::globalConstFlagUsePKIXVerification){
|
||||
telemetryID = Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_LIBPKIX;
|
||||
}
|
||||
else{
|
||||
#endif
|
||||
telemetryID = Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_CLASSIC;
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
}
|
||||
#endif
|
||||
RefPtr<SSLServerCertVerificationResult> restart(
|
||||
new SSLServerCertVerificationResult(mInfoObject, 0,
|
||||
telemetryID, interval));
|
||||
successTelemetry, interval));
|
||||
restart->Dispatch();
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1138,25 +1146,13 @@ SSLServerCertVerificationJob::Run()
|
||||
error = PR_GetError();
|
||||
{
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
Telemetry::ID telemetryID;
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
if(nsNSSComponent::globalConstFlagUsePKIXVerification) {
|
||||
telemetryID = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_LIBPKIX;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
telemetryID = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_CLASSIC;
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
}
|
||||
#endif
|
||||
MutexAutoLock telemetryMutex(*gSSLVerificationTelemetryMutex);
|
||||
Telemetry::AccumulateTimeDelta(telemetryID,
|
||||
mJobStartTime,
|
||||
now);
|
||||
Telemetry::AccumulateTimeDelta(failureTelemetry, mJobStartTime, now);
|
||||
}
|
||||
if (error != 0) {
|
||||
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
|
||||
error, mInfoObject, mCert, mFdForLogging, mProviderFlags, PR_Now()));
|
||||
RefPtr<CertErrorRunnable> runnable(
|
||||
CreateCertErrorRunnable(*mCertVerifier, error, mInfoObject, mCert,
|
||||
mFdForLogging, mProviderFlags, PR_Now()));
|
||||
if (!runnable) {
|
||||
// CreateCertErrorRunnable set a new error code
|
||||
error = PR_GetError();
|
||||
@ -1206,6 +1202,12 @@ SSLServerCertVerificationJob::Run()
|
||||
SECStatus
|
||||
AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer)
|
||||
{
|
||||
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
if (!certVerifier) {
|
||||
PR_SetError(SEC_ERROR_NOT_INITIALIZED, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
// Runs on the socket transport thread
|
||||
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
|
||||
@ -1230,6 +1232,10 @@ AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer)
|
||||
|
||||
socketInfo->SetFullHandshake();
|
||||
|
||||
// This value of "now" is used both here for OCSP stapling and later
|
||||
// when calling CreateCertErrorRunnable.
|
||||
PRTime now = PR_Now();
|
||||
|
||||
if (BlockServerCertChangeForSpdy(socketInfo, serverCert) != SECSuccess)
|
||||
return SECFailure;
|
||||
|
||||
@ -1269,8 +1275,8 @@ AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer)
|
||||
// because of the performance benefits of doing so.
|
||||
socketInfo->SetCertVerificationWaiting();
|
||||
SECStatus rv = SSLServerCertVerificationJob::Dispatch(
|
||||
static_cast<const void*>(fd), socketInfo, serverCert,
|
||||
stapledOCSPResponse, providerFlags);
|
||||
certVerifier, static_cast<const void*>(fd), socketInfo,
|
||||
serverCert, stapledOCSPResponse, providerFlags);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1279,17 +1285,18 @@ AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer)
|
||||
// of our SSLServerCertVerificationResult event, and/or it might not even be
|
||||
// a non-blocking socket.
|
||||
|
||||
SECStatus rv = AuthCertificate(socketInfo, serverCert, stapledOCSPResponse,
|
||||
providerFlags);
|
||||
SECStatus rv = AuthCertificate(*certVerifier, socketInfo, serverCert,
|
||||
stapledOCSPResponse, providerFlags);
|
||||
if (rv == SECSuccess) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
PRErrorCode error = PR_GetError();
|
||||
if (error != 0) {
|
||||
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
|
||||
error, socketInfo, serverCert,
|
||||
static_cast<const void*>(fd), providerFlags, PR_Now()));
|
||||
RefPtr<CertErrorRunnable> runnable(
|
||||
CreateCertErrorRunnable(*certVerifier, error, socketInfo, serverCert,
|
||||
static_cast<const void*>(fd), providerFlags,
|
||||
now));
|
||||
if (!runnable) {
|
||||
// CreateCertErrorRunnable sets a new error code when it fails
|
||||
error = PR_GetError();
|
||||
|
29
security/manager/ssl/src/SharedCertVerifier.h
Normal file
29
security/manager/ssl/src/SharedCertVerifier.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* 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__SharedCertVerifier_h
|
||||
#define mozilla_psm__SharedCertVerifier_h
|
||||
|
||||
#include "certt.h"
|
||||
#include "CertVerifier.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
class SharedCertVerifier : public mozilla::psm::CertVerifier,
|
||||
public mozilla::AtomicRefCounted<SharedCertVerifier>
|
||||
{
|
||||
public:
|
||||
SharedCertVerifier(implementation_config ic, missing_cert_download_config ac,
|
||||
crl_download_config cdc, ocsp_download_config odc,
|
||||
ocsp_strict_config osc, ocsp_get_config ogc)
|
||||
: mozilla::psm::CertVerifier(ic, ac, cdc, odc, osc, ogc)
|
||||
{
|
||||
}
|
||||
~SharedCertVerifier();
|
||||
};
|
||||
|
||||
} } // namespace mozilla::psm
|
||||
|
||||
#endif // mozilla_psm__SharedCertVerifier_h
|
@ -136,7 +136,6 @@ SharedSSLState::SharedSSLState()
|
||||
, mMutex("SharedSSLState::mMutex")
|
||||
, mSocketCreated(false)
|
||||
, mOCSPStaplingEnabled(false)
|
||||
, mOCSPFetchingEnabled(false)
|
||||
{
|
||||
mIOLayerHelpers.Init();
|
||||
mClientAuthRemember->Init();
|
||||
|
@ -36,9 +36,8 @@ public:
|
||||
// Main-thread only
|
||||
void ResetStoredData();
|
||||
void NotePrivateBrowsingStatus();
|
||||
void SetOCSPOptions(bool fetchingEnabled, bool staplingEnabled)
|
||||
void SetOCSPStaplingEnabled(bool staplingEnabled)
|
||||
{
|
||||
mOCSPFetchingEnabled = fetchingEnabled;
|
||||
mOCSPStaplingEnabled = staplingEnabled;
|
||||
}
|
||||
|
||||
@ -48,7 +47,6 @@ public:
|
||||
static void NoteCertOverrideServiceInstantiated();
|
||||
static void NoteCertDBServiceInstantiated();
|
||||
bool IsOCSPStaplingEnabled() const { return mOCSPStaplingEnabled; }
|
||||
bool IsOCSPFetchingEnabled() const { return mOCSPFetchingEnabled; }
|
||||
|
||||
private:
|
||||
void Cleanup();
|
||||
@ -63,7 +61,6 @@ private:
|
||||
Mutex mMutex;
|
||||
bool mSocketCreated;
|
||||
bool mOCSPStaplingEnabled;
|
||||
bool mOCSPFetchingEnabled;
|
||||
};
|
||||
|
||||
SharedSSLState* PublicSSLState();
|
||||
|
@ -93,6 +93,11 @@ UNIFIED_SOURCES += [
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../../../insanity/include',
|
||||
]
|
||||
|
||||
|
||||
DEFINES['NSS_ENABLE_ECC'] = 'True'
|
||||
for var in ('DLL_PREFIX', 'DLL_SUFFIX'):
|
||||
DEFINES[var] = '"%s"' % CONFIG[var]
|
||||
|
@ -213,7 +213,7 @@ nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, uint32_
|
||||
NSSCMSSignedData *sigd = nullptr;
|
||||
NSSCMSSignerInfo *si;
|
||||
int32_t nsigners;
|
||||
RefPtr<CertVerifier> certVerifier;
|
||||
RefPtr<SharedCertVerifier> certVerifier;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (!NSS_CMSMessage_IsSigned(m_cmsMsg)) {
|
||||
|
@ -1280,7 +1280,8 @@ nsNSSCertificate::hasValidEVOidTag(SECOidTag& resultOidTag, bool& validEV)
|
||||
return nrv;
|
||||
nssComponent->EnsureIdentityInfoLoaded();
|
||||
|
||||
RefPtr<mozilla::psm::CertVerifier> certVerifier(mozilla::psm::GetDefaultCertVerifier());
|
||||
RefPtr<mozilla::psm::SharedCertVerifier>
|
||||
certVerifier(mozilla::psm::GetDefaultCertVerifier());
|
||||
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
|
||||
|
||||
validEV = false;
|
||||
|
@ -824,7 +824,7 @@ nsNSSCertificate::GetChain(nsIArray** _rvChain)
|
||||
ScopedCERTCertList nssChain;
|
||||
SECStatus srv;
|
||||
nssChain = nullptr;
|
||||
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
|
||||
CERTCertList* pkixNssChain = nullptr;
|
||||
|
||||
|
@ -565,7 +565,7 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
|
||||
|
||||
certdb = CERT_GetDefaultCertDB();
|
||||
@ -770,7 +770,7 @@ nsresult
|
||||
nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfaceRequestor *ctx,
|
||||
const nsNSSShutDownPreventionLock &proofOfLock)
|
||||
{
|
||||
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
if (!certVerifier)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
@ -1347,7 +1347,7 @@ nsNSSCertificateDB::FindCertByEmailAddress(nsISupports *aToken, const char *aEma
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
|
||||
|
||||
ScopedCERTCertList certlist(
|
||||
@ -1713,7 +1713,7 @@ nsNSSCertificateDB::VerifyCertNow(nsIX509Cert* aCert,
|
||||
}
|
||||
ScopedCERTCertificate nssCert(x509Cert->GetCert());
|
||||
|
||||
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
NS_ENSURE_TRUE(certVerifier, NS_ERROR_FAILURE);
|
||||
|
||||
CERTCertList* resultChain = nullptr;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "nsNSSComponent.h"
|
||||
|
||||
#include "CertVerifier.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsCertVerificationThread.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
@ -78,10 +77,6 @@ PRLogModuleInfo* gPIPNSSLog = nullptr;
|
||||
|
||||
int nsNSSComponent::mInstanceCount = 0;
|
||||
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
bool nsNSSComponent::globalConstFlagUsePKIXVerification = false;
|
||||
#endif
|
||||
|
||||
// XXX tmp callback for slot password
|
||||
extern char* pk11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg);
|
||||
|
||||
@ -1032,8 +1027,8 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting)
|
||||
|
||||
bool ocspStaplingEnabled = Preferences::GetBool("security.ssl.enable_ocsp_stapling",
|
||||
true);
|
||||
PublicSSLState()->SetOCSPOptions(ocspEnabled, ocspStaplingEnabled);
|
||||
PrivateSSLState()->SetOCSPOptions(ocspEnabled, ocspStaplingEnabled);
|
||||
PublicSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
|
||||
PrivateSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
|
||||
|
||||
setNonPkixOcspEnabled(ocspEnabled);
|
||||
|
||||
@ -1051,7 +1046,17 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting)
|
||||
bool ocspGetEnabled = Preferences::GetBool("security.OCSP.GET.enabled", false);
|
||||
CERT_ForcePostMethodForOCSP(!ocspGetEnabled);
|
||||
|
||||
mDefaultCertVerifier = new CertVerifier(
|
||||
CertVerifier::implementation_config certVerifierImplementation
|
||||
= CertVerifier::classic;
|
||||
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
if (Preferences::GetBool("security.use_libpkix_verification", false)) {
|
||||
certVerifierImplementation = CertVerifier::libpkix;
|
||||
}
|
||||
#endif
|
||||
|
||||
mDefaultCertVerifier = new SharedCertVerifier(
|
||||
certVerifierImplementation,
|
||||
aiaDownloadEnabled ?
|
||||
CertVerifier::missing_cert_download_on : CertVerifier::missing_cert_download_off,
|
||||
crlDownloading ?
|
||||
@ -1188,10 +1193,6 @@ nsNSSComponent::InitializeNSS()
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
globalConstFlagUsePKIXVerification =
|
||||
Preferences::GetBool("security.use_libpkix_verification", false);
|
||||
#endif
|
||||
|
||||
// init phase 2, init calls to NSS library
|
||||
|
||||
@ -1897,17 +1898,35 @@ nsNSSComponent::IsNSSInitialized(bool* initialized)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SharedCertVerifier::~SharedCertVerifier() { }
|
||||
|
||||
//#ifndef NSS_NO_LIBPKIX
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::GetDefaultCertVerifier(RefPtr<CertVerifier>& out)
|
||||
TemporaryRef<SharedCertVerifier>
|
||||
nsNSSComponent::GetDefaultCertVerifier()
|
||||
{
|
||||
MutexAutoLock lock(mutex);
|
||||
if (!mNSSInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
out = mDefaultCertVerifier;
|
||||
return NS_OK;
|
||||
MOZ_ASSERT(mNSSInitialized);
|
||||
return mDefaultCertVerifier;
|
||||
}
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
TemporaryRef<SharedCertVerifier>
|
||||
GetDefaultCertVerifier()
|
||||
{
|
||||
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
|
||||
|
||||
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID));
|
||||
RefPtr<SharedCertVerifier> certVerifier;
|
||||
if (nssComponent) {
|
||||
return nssComponent->GetDefaultCertVerifier();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} } // namespace mozilla::psm
|
||||
|
||||
NS_IMPL_ISUPPORTS1(PipUIContext, nsIInterfaceRequestor)
|
||||
|
||||
PipUIContext::PipUIContext()
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "nsINSSErrorsService.h"
|
||||
#include "nsNSSCallbacks.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "SharedCertVerifier.h"
|
||||
#include "nsNSSHelper.h"
|
||||
#include "nsClientAuthRemember.h"
|
||||
#include "prerror.h"
|
||||
@ -30,7 +31,9 @@ class SmartCardThreadList;
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
class CertVerifier;
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
::mozilla::TemporaryRef<mozilla::psm::SharedCertVerifier>
|
||||
GetDefaultCertVerifier();
|
||||
|
||||
} } // namespace mozilla::psm
|
||||
|
||||
@ -110,8 +113,8 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports {
|
||||
|
||||
NS_IMETHOD IsNSSInitialized(bool* initialized) = 0;
|
||||
|
||||
NS_IMETHOD GetDefaultCertVerifier(
|
||||
mozilla::RefPtr<mozilla::psm::CertVerifier>& out) = 0;
|
||||
virtual ::mozilla::TemporaryRef<mozilla::psm::SharedCertVerifier>
|
||||
GetDefaultCertVerifier() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsINSSComponent, NS_INSSCOMPONENT_IID)
|
||||
@ -177,10 +180,10 @@ public:
|
||||
#endif
|
||||
NS_IMETHOD IsNSSInitialized(bool* initialized);
|
||||
|
||||
NS_IMETHOD GetDefaultCertVerifier(
|
||||
mozilla::RefPtr<mozilla::psm::CertVerifier>& out);
|
||||
private:
|
||||
::mozilla::TemporaryRef<mozilla::psm::SharedCertVerifier>
|
||||
GetDefaultCertVerifier() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsresult InitializeNSS();
|
||||
void ShutdownNSS();
|
||||
|
||||
@ -219,14 +222,11 @@ private:
|
||||
nsCertVerificationThread* mCertVerificationThread;
|
||||
|
||||
nsNSSHttpInterface mHttpForNSS;
|
||||
mozilla::RefPtr<mozilla::psm::CertVerifier> mDefaultCertVerifier;
|
||||
mozilla::RefPtr<mozilla::psm::SharedCertVerifier> mDefaultCertVerifier;
|
||||
|
||||
|
||||
static PRStatus IdentityInfoInit(void);
|
||||
PRCallOnceType mIdentityInfoCallOnce;
|
||||
|
||||
public:
|
||||
static bool globalConstFlagUsePKIXVerification;
|
||||
};
|
||||
|
||||
class nsNSSErrors
|
||||
|
@ -199,12 +199,12 @@ nsUsageArrayHelper::GetUsagesArray(const char *suffix,
|
||||
if (outArraySize < max_returned_out_array_size)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Bug 860076, this disabling ocsp for all NSS is incorrect.
|
||||
#ifndef NSS_NO_LIBPKIX
|
||||
const bool localOSCPDisable = !nsNSSComponent::globalConstFlagUsePKIXVerification && localOnly;
|
||||
#else
|
||||
const bool localOSCPDisable = localOnly;
|
||||
#endif
|
||||
const bool localOSCPDisable
|
||||
= certVerifier->mImplementation == CertVerifier::classic;
|
||||
if (localOSCPDisable) {
|
||||
nsresult rv;
|
||||
nssComponent = do_GetService(kNSSComponentCID, &rv);
|
||||
@ -219,9 +219,6 @@ nsUsageArrayHelper::GetUsagesArray(const char *suffix,
|
||||
uint32_t &count = *_count;
|
||||
count = 0;
|
||||
|
||||
RefPtr<CertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
|
||||
|
||||
PRTime now = PR_Now();
|
||||
CertVerifier::Flags flags = localOnly ? CertVerifier::FLAG_LOCAL_ONLY : 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user