--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -3,17 +3,17 @@
/* 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 "CertVerifier.h"
#include <stdint.h>
-#include "insanity/pkixtypes.h"
+#include "insanity/pkix.h"
#include "ExtendedValidation.h"
#include "NSSCertDBTrustDomain.h"
#include "cert.h"
#include "ocsp.h"
#include "secerr.h"
#include "prerror.h"
#include "sslerr.h"
@@ -27,24 +27,28 @@ static PRLogModuleInfo* gCertVerifierLog
#endif
namespace mozilla { namespace psm {
const CertVerifier::Flags CertVerifier::FLAG_LOCAL_ONLY = 1;
const CertVerifier::Flags CertVerifier::FLAG_MUST_BE_EV = 2;
CertVerifier::CertVerifier(implementation_config ic,
+#ifndef NSS_NO_LIBPKIX
missing_cert_download_config mcdc,
crl_download_config cdc,
+#endif
ocsp_download_config odc,
ocsp_strict_config osc,
ocsp_get_config ogc)
: mImplementation(ic)
+#ifndef NSS_NO_LIBPKIX
, mMissingCertDownloadEnabled(mcdc == missing_cert_download_on)
, mCRLDownloadEnabled(cdc == crl_download_allowed)
+#endif
, mOCSPDownloadEnabled(odc == ocsp_on)
, mOCSPStrict(osc == ocsp_strict)
, mOCSPGETEnabled(ogc == ocsp_get_enabled)
{
}
CertVerifier::~CertVerifier()
{
@@ -104,47 +108,34 @@ ClassicVerifyCert(CERTCertificate* cert,
if (validationChain) {
switch(usage){
case certificateUsageSSLClient:
enumUsage = certUsageSSLClient;
break;
case certificateUsageSSLServer:
enumUsage = certUsageSSLServer;
break;
- case certificateUsageSSLServerWithStepUp:
- enumUsage = certUsageSSLServerWithStepUp;
- break;
case certificateUsageSSLCA:
enumUsage = certUsageSSLCA;
break;
case certificateUsageEmailSigner:
enumUsage = certUsageEmailSigner;
break;
case certificateUsageEmailRecipient:
enumUsage = certUsageEmailRecipient;
break;
case certificateUsageObjectSigner:
enumUsage = certUsageObjectSigner;
break;
- case certificateUsageUserCertImport:
- enumUsage = certUsageUserCertImport;
- break;
- case certificateUsageVerifyCA:
- enumUsage = certUsageVerifyCA;
- break;
- case certificateUsageProtectedObjectSigner:
- enumUsage = certUsageProtectedObjectSigner;
- break;
case certificateUsageStatusResponder:
enumUsage = certUsageStatusResponder;
break;
- case certificateUsageAnyCA:
- enumUsage = certUsageAnyCA;
- break;
- default:
+ default:
+ PR_NOT_REACHED("unexpected usage");
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
}
if (usage == certificateUsageSSLServer) {
// SSL server cert verification has always used CERT_VerifyCert, so we
// continue to use it for SSL cert verification to minimize the risk of
// there being any differnce in results between CERT_VerifyCert and
// CERT_VerifyCertificate.
@@ -174,16 +165,191 @@ destroyCertListThatShouldNotExist(CERTCe
// There SHOULD not be a validation chain on failure, asserion here for
// the debug builds AND a fallback for production builds
CERT_DestroyCertList(*certChain);
*certChain = nullptr;
}
}
#endif
+static SECStatus
+BuildCertChainForOneKeyUsage(TrustDomain& trustDomain, CERTCertificate* cert,
+ PRTime time, KeyUsages ku1, KeyUsages ku2,
+ KeyUsages ku3, SECOidTag eku,
+ ScopedCERTCertList& builtChain)
+{
+ PR_ASSERT(ku1);
+ PR_ASSERT(ku2);
+
+ SECStatus rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
+ ku1, eku, builtChain);
+ if (rv != SECSuccess && ku2 &&
+ PR_GetError() == SEC_ERROR_INADEQUATE_KEY_USAGE) {
+ rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
+ ku2, eku, builtChain);
+ if (rv != SECSuccess && ku3 &&
+ PR_GetError() == SEC_ERROR_INADEQUATE_KEY_USAGE) {
+ rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
+ ku3, eku, builtChain);
+ if (rv != SECSuccess) {
+ PR_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE, 0);
+ }
+ }
+ }
+ return rv;
+}
+
+SECStatus
+CertVerifier::InsanityVerifyCert(
+ CERTCertificate* cert,
+ /*optional*/ const SECItem* /*TODO: stapledOCSPResponse*/,
+ const SECCertificateUsage usage,
+ const PRTime time,
+ void* pinArg,
+ const Flags flags,
+ /*optional out*/ insanity::pkix::ScopedCERTCertList* validationChain)
+{
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("Top of InsanityVerifyCert\n"));
+ SECStatus rv;
+
+ // TODO(bug 970750): anyExtendedKeyUsage
+ // TODO: encipherOnly/decipherOnly
+ // S/MIME Key Usage: http://tools.ietf.org/html/rfc3850#section-4.4.2
+ // S/MIME EKU: http://tools.ietf.org/html/rfc3850#section-4.4.4
+
+ // TODO(bug 915931): Pass in stapled OCSP response in all calls to
+ // BuildCertChain.
+
+ insanity::pkix::ScopedCERTCertList builtChain;
+ switch (usage) {
+ case certificateUsageSSLClient: {
+ // XXX: We don't really have a trust bit for SSL client authentication so
+ // just use trustEmail as it is the closest alternative.
+ NSSCertDBTrustDomain trustDomain(trustEmail, mOCSPDownloadEnabled,
+ mOCSPStrict, pinArg);
+ rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
+ KU_DIGITAL_SIGNATURE,
+ SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH,
+ builtChain);
+ break;
+ }
+
+ case certificateUsageSSLServer: {
+ // TODO: When verifying a certificate in an SSL handshake, we should
+ // restrict the acceptable key usage based on the key exchange method
+ // chosen by the server.
+ NSSCertDBTrustDomain trustDomain(trustSSL, mOCSPDownloadEnabled,
+ mOCSPStrict, pinArg);
+ rv = BuildCertChainForOneKeyUsage(trustDomain, cert, time,
+ KU_DIGITAL_SIGNATURE, // ECDHE/DHE
+ KU_KEY_ENCIPHERMENT, // RSA
+ KU_KEY_AGREEMENT, // ECDH/DH
+ SEC_OID_EXT_KEY_USAGE_SERVER_AUTH,
+ builtChain);
+ break;
+ }
+
+ case certificateUsageSSLCA: {
+ NSSCertDBTrustDomain trustDomain(trustSSL, mOCSPDownloadEnabled,
+ mOCSPStrict, pinArg);
+ rv = BuildCertChain(trustDomain, cert, time, MustBeCA,
+ KU_KEY_CERT_SIGN,
+ SEC_OID_EXT_KEY_USAGE_SERVER_AUTH,
+ builtChain);
+ break;
+ }
+
+ case certificateUsageEmailSigner: {
+ NSSCertDBTrustDomain trustDomain(trustEmail, mOCSPDownloadEnabled,
+ mOCSPStrict, pinArg);
+ rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
+ KU_DIGITAL_SIGNATURE,
+ SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT,
+ builtChain);
+ break;
+ }
+
+ case certificateUsageEmailRecipient: {
+ // TODO: The higher level S/MIME processing should pass in which key
+ // usage it is trying to verify for, and base its algorithm choices
+ // based on the result of the verification(s).
+ NSSCertDBTrustDomain trustDomain(trustEmail, mOCSPDownloadEnabled,
+ mOCSPStrict, pinArg);
+ rv = BuildCertChainForOneKeyUsage(trustDomain, cert, time,
+ KU_KEY_ENCIPHERMENT, // RSA
+ KU_KEY_AGREEMENT, // ECDH/DH
+ 0,
+ SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT,
+ builtChain);
+ break;
+ }
+
+ case certificateUsageObjectSigner: {
+ NSSCertDBTrustDomain trustDomain(trustObjectSigning,
+ mOCSPDownloadEnabled, mOCSPStrict,
+ pinArg);
+ rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
+ KU_DIGITAL_SIGNATURE,
+ SEC_OID_EXT_KEY_USAGE_CODE_SIGN,
+ builtChain);
+ break;
+ }
+
+ case certificateUsageVerifyCA:
+ case certificateUsageStatusResponder: {
+ // XXX This is a pretty useless way to verify a certificate. It is used
+ // by the implementation of window.crypto.importCertificates and in the
+ // certificate viewer UI. Because we don't know what trust bit is
+ // interesting, we just try them all.
+ insanity::pkix::EndEntityOrCA endEntityOrCA;
+ insanity::pkix::KeyUsages keyUsage;
+ SECOidTag eku;
+ if (usage == certificateUsageVerifyCA) {
+ endEntityOrCA = MustBeCA;
+ keyUsage = KU_KEY_CERT_SIGN;
+ eku = SEC_OID_UNKNOWN;
+ } else {
+ endEntityOrCA = MustBeEndEntity;
+ keyUsage = KU_DIGITAL_SIGNATURE;
+ eku = SEC_OID_OCSP_RESPONDER;
+ }
+
+ NSSCertDBTrustDomain sslTrust(trustSSL,
+ mOCSPDownloadEnabled, mOCSPStrict, pinArg);
+ rv = BuildCertChain(sslTrust, cert, time, endEntityOrCA,
+ keyUsage, eku, builtChain);
+ if (rv == SECFailure && PR_GetError() == SEC_ERROR_UNKNOWN_ISSUER) {
+ NSSCertDBTrustDomain emailTrust(trustEmail, mOCSPDownloadEnabled,
+ mOCSPStrict, pinArg);
+ rv = BuildCertChain(emailTrust, cert, time, endEntityOrCA, keyUsage,
+ eku, builtChain);
+ if (rv == SECFailure && SEC_ERROR_UNKNOWN_ISSUER) {
+ NSSCertDBTrustDomain objectSigningTrust(trustObjectSigning,
+ mOCSPDownloadEnabled,
+ mOCSPStrict, pinArg);
+ rv = BuildCertChain(objectSigningTrust, cert, time, endEntityOrCA,
+ keyUsage, eku, builtChain);
+ }
+ }
+
+ break;
+ }
+
+ default:
+ PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
+ return SECFailure;
+ }
+
+ if (validationChain && rv == SECSuccess) {
+ *validationChain = builtChain.release();
+ }
+
+ return rv;
+}
+
SECStatus
CertVerifier::VerifyCert(CERTCertificate* cert,
/*optional*/ const SECItem* stapledOCSPResponse,
const SECCertificateUsage usage,
const PRTime time,
void* pinArg,
const Flags flags,
/*optional out*/ ScopedCERTCertList* validationChain,
@@ -398,16 +564,21 @@ CertVerifier::VerifyCert(CERTCertificate
#ifdef NSS_NO_LIBPKIX
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
#else
PR_SetError(PR_INVALID_STATE_ERROR, 0);
#endif
return SECFailure;
}
+ if (mImplementation == insanity) {
+ return InsanityVerifyCert(cert, stapledOCSPResponse, usage, time,
+ pinArg, flags, validationChain);
+ }
+
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
--- a/security/certverifier/CertVerifier.h
+++ b/security/certverifier/CertVerifier.h
@@ -2,17 +2,16 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "certt.h"
#include "insanity/pkixtypes.h"
namespace mozilla { namespace psm {
class CertVerifier
{
public:
typedef unsigned int Flags;
@@ -44,36 +43,50 @@ public:
/*optional out*/ SECOidTag* evOidPolicy = nullptr);
enum implementation_config {
classic = 0,
#ifndef NSS_NO_LIBPKIX
libpkix = 1,
#endif
+ insanity = 2
};
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 ocsp_get_config { ocsp_get_disabled = 0, ocsp_get_enabled = 1 };
bool IsOCSPDownloadEnabled() const { return mOCSPDownloadEnabled; }
- 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(implementation_config ic,
+#ifndef NSS_NO_LIBPKIX
+ missing_cert_download_config ac, crl_download_config cdc,
+#endif
+ ocsp_download_config odc, ocsp_strict_config osc,
+ ocsp_get_config ogc);
~CertVerifier();
-public:
const implementation_config mImplementation;
+#ifndef NSS_NO_LIBPKIX
const bool mMissingCertDownloadEnabled;
const bool mCRLDownloadEnabled;
+#endif
const bool mOCSPDownloadEnabled;
const bool mOCSPStrict;
const bool mOCSPGETEnabled;
+
+private:
+ SECStatus InsanityVerifyCert(CERTCertificate* cert,
+ /*optional*/ const SECItem* stapledOCSPResponse,
+ const SECCertificateUsage usage,
+ const PRTime time,
+ void* pinArg,
+ const Flags flags,
+ /*optional out*/ insanity::pkix::ScopedCERTCertList* validationChain);
};
void InitCertVerifierLog();
} } // namespace mozilla::psm
#endif // mozilla_psm__CertVerifier_h
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -3,39 +3,129 @@
/* 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 "NSSCertDBTrustDomain.h"
#include <stdint.h>
-#include "insanity/ScopedPtr.h"
+#include "insanity/pkix.h"
#include "certdb.h"
#include "nss.h"
#include "ocsp.h"
#include "pk11pub.h"
#include "prerror.h"
#include "prmem.h"
#include "prprf.h"
#include "secerr.h"
#include "secmod.h"
using namespace insanity::pkix;
+#ifdef PR_LOGGING
+extern PRLogModuleInfo* gCertVerifierLog;
+#endif
+
namespace mozilla { namespace psm {
const char BUILTIN_ROOTS_MODULE_DEFAULT_NAME[] = "Builtin Roots Module";
namespace {
inline void PORT_Free_string(char* str) { PORT_Free(str); }
typedef ScopedPtr<SECMODModule, SECMOD_DestroyModule> ScopedSECMODModule;
+} // unnamed namespace
+
+NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
+ bool /*ocspDownloadEnabled*/,
+ bool /*ocspStrict*/,
+ void* pinArg)
+ : mCertDBTrustType(certDBTrustType)
+// , mOCSPDownloadEnabled(ocspDownloadEnabled)
+// , mOCSPStrict(ocspStrict)
+ , mPinArg(pinArg)
+{
+}
+
+SECStatus
+NSSCertDBTrustDomain::FindPotentialIssuers(
+ const SECItem* encodedIssuerName, PRTime time,
+ /*out*/ insanity::pkix::ScopedCERTCertList& results)
+{
+ // TODO: normalize encodedIssuerName
+ // TODO: NSS seems to be ambiguous between "no potential issuers found" and
+ // "there was an error trying to retrieve the potential issuers."
+ results = CERT_CreateSubjectCertList(nullptr, CERT_GetDefaultCertDB(),
+ encodedIssuerName, time, true);
+ if (!results) {
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
+ const CERTCertificate* candidateCert,
+ /*out*/ TrustLevel* trustLevel)
+{
+ PORT_Assert(candidateCert);
+ PORT_Assert(trustLevel);
+ if (!candidateCert || !trustLevel) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ // XXX: CERT_GetCertTrust seems to be abusing SECStatus as a boolean, where
+ // SECSuccess means that there is a trust record and SECFailure means there
+ // is not a trust record. I looked at NSS's internal uses of
+ // CERT_GetCertTrust, and all that code uses the result as a boolean meaning
+ // "We have a trust record."
+ CERTCertTrust trust;
+ if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
+ PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, mCertDBTrustType);
+
+ // For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
+ // because we can have active distrust for either type of cert. Note that
+ // CERTDB_TERMINAL_RECORD means "stop trying to inherit trust" so if the
+ // relevant trust bit isn't set then that means the cert must be considered
+ // distrusted.
+ PRUint32 relevantTrustBit = endEntityOrCA == MustBeCA ? CERTDB_TRUSTED_CA
+ : CERTDB_TRUSTED;
+ if (((flags & (relevantTrustBit|CERTDB_TERMINAL_RECORD)))
+ == CERTDB_TERMINAL_RECORD) {
+ *trustLevel = ActivelyDistrusted;
+ return SECSuccess;
+ }
+
+ // For TRUST, we only use the CERTDB_TRUSTED_CA bit, because Gecko hasn't
+ // needed to consider end-entity certs to be their own trust anchors since
+ // Gecko implemented nsICertOverrideService.
+ if (flags & CERTDB_TRUSTED_CA) {
+ *trustLevel = TrustAnchor;
+ return SECSuccess;
+ }
+ }
+
+ *trustLevel = InheritsTrust;
+ return SECSuccess;
+}
+
+SECStatus
+NSSCertDBTrustDomain::VerifySignedData(const CERTSignedData* signedData,
+ const CERTCertificate* cert)
+{
+ return ::insanity::pkix::VerifySignedData(signedData, cert, mPinArg);
+}
+
+namespace {
+
static char*
nss_addEscape(const char* string, char quote)
{
char* newString = 0;
int escapes = 0, size = 0;
const char* src;
char* dest;
--- a/security/certverifier/NSSCertDBTrustDomain.h
+++ b/security/certverifier/NSSCertDBTrustDomain.h
@@ -38,11 +38,38 @@ SetClassicOCSPBehavior(CertVerifier::ocs
CertVerifier::ocsp_strict_config strict,
CertVerifier::ocsp_get_config get);
// Caller must free the result with PR_Free
char* DefaultServerNicknameForCert(CERTCertificate* cert);
void SaveIntermediateCerts(const insanity::pkix::ScopedCERTCertList& certList);
+class NSSCertDBTrustDomain : public insanity::pkix::TrustDomain
+{
+
+public:
+ NSSCertDBTrustDomain(SECTrustType certDBTrustType,
+ bool ocspDownloadEnabled, bool ocspStrict,
+ void* pinArg);
+
+ virtual SECStatus FindPotentialIssuers(
+ const SECItem* encodedIssuerName,
+ PRTime time,
+ /*out*/ insanity::pkix::ScopedCERTCertList& results);
+
+ virtual SECStatus GetCertTrust(insanity::pkix::EndEntityOrCA endEntityOrCA,
+ const CERTCertificate* candidateCert,
+ /*out*/ TrustLevel* trustLevel);
+
+ virtual SECStatus VerifySignedData(const CERTSignedData* signedData,
+ const CERTCertificate* cert);
+
+private:
+ const SECTrustType mCertDBTrustType;
+// const bool mOCSPDownloadEnabled;
+// const bool mOCSPStrict;
+ void* mPinArg; // non-owning!
+};
+
} } // namespace mozilla::psm
#endif // mozilla_psm__NSSCertDBTrustDomain_h
--- a/security/manager/ssl/src/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/src/SSLServerCertVerification.cpp
@@ -737,16 +737,18 @@ AuthCertificate(CertVerifier& certVerifi
CERTCertificate* cert, SECItem* stapledOCSPResponse,
uint32_t providerFlags, PRTime time)
{
MOZ_ASSERT(infoObject);
MOZ_ASSERT(cert);
SECStatus rv;
+ // TODO: Remove this after we switch to insanity::pkix as the
+ // only option
if (stapledOCSPResponse) {
CERTCertDBHandle* handle = CERT_GetDefaultCertDB();
rv = CERT_CacheOCSPResponseFromSideChannel(handle, cert, PR_Now(),
stapledOCSPResponse,
infoObject);
if (rv != SECSuccess) {
// Due to buggy servers that will staple expired OCSP responses
// (see for example http://trac.nginx.org/nginx/ticket/425),
@@ -914,16 +916,22 @@ SSLServerCertVerificationJob::Run()
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;
+ case CertVerifier::insanity:
+ successTelemetry
+ = Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_INSANITY;
+ failureTelemetry
+ = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_INSANITY;
+ 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
--- a/security/manager/ssl/src/SharedCertVerifier.h
+++ b/security/manager/ssl/src/SharedCertVerifier.h
@@ -10,20 +10,27 @@
#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(implementation_config ic,
+#ifndef NSS_NO_LIBPKIX
+ missing_cert_download_config ac, crl_download_config cdc,
+#endif
+ ocsp_download_config odc, ocsp_strict_config osc,
+ ocsp_get_config ogc)
+ : mozilla::psm::CertVerifier(ic,
+#ifndef NSS_NO_LIBPKIX
+ ac, cdc,
+#endif
+ odc, osc, ogc)
{
}
~SharedCertVerifier();
};
} } // namespace mozilla::psm
#endif // mozilla_psm__SharedCertVerifier_h
--- a/security/manager/ssl/src/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp
@@ -1733,18 +1733,17 @@ nsNSSCertificateDB::VerifyCertNow(nsIX50
SECOidTag evOidPolicy;
SECStatus srv;
srv = certVerifier->VerifyCert(nssCert, nullptr,
aUsage, PR_Now(),
nullptr, // Assume no context
aFlags,
&resultChain,
- &evOidPolicy,
- nullptr);
+ &evOidPolicy);
PRErrorCode error = PR_GetError();
nsCOMPtr<nsIX509CertList> nssCertList;
// This adopts the list
nssCertList = new nsNSSCertList(resultChain, locker);
NS_ENSURE_TRUE(nssCertList, NS_ERROR_FAILURE);
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -935,63 +935,71 @@ CipherSuiteChangeObserver::Observe(nsISu
}
} // anonymous namespace
// Caller must hold a lock on nsNSSComponent::mutex when calling this function
void nsNSSComponent::setValidationOptions(bool isInitialSetting,
const MutexAutoLock& lock)
{
- bool crlDownloading = Preferences::GetBool("security.CRL_download.enabled",
- false);
-
// This preference controls whether we do OCSP fetching and does not affect
// OCSP stapling.
// 0 = disabled, 1 = enabled
int32_t ocspEnabled = Preferences::GetInt("security.OCSP.enabled",
OCSP_ENABLED_DEFAULT);
bool ocspRequired = ocspEnabled &&
Preferences::GetBool("security.OCSP.require", false);
// We measure the setting of the pref at startup only to minimize noise by
// addons that may muck with the settings, though it probably doesn't matter.
if (isInitialSetting) {
Telemetry::Accumulate(Telemetry::CERT_OCSP_ENABLED, ocspEnabled);
Telemetry::Accumulate(Telemetry::CERT_OCSP_REQUIRED, ocspRequired);
}
- bool aiaDownloadEnabled = Preferences::GetBool("security.missing_cert_download.enabled",
- false);
+#ifndef NSS_NO_LIBPKIX
+ bool crlDownloading = Preferences::GetBool("security.CRL_download.enabled",
+ false);
+ bool aiaDownloadEnabled =
+ Preferences::GetBool("security.missing_cert_download.enabled", false);
+#endif
bool ocspStaplingEnabled = Preferences::GetBool("security.ssl.enable_ocsp_stapling",
true);
PublicSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
PrivateSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
CertVerifier::implementation_config certVerifierImplementation
= CertVerifier::classic;
+ // The insanity::pkix pref overrides the libpkix pref
+ if (Preferences::GetBool("security.use_insanity_verification", false)) {
+ certVerifierImplementation = CertVerifier::insanity;
+ } else {
#ifndef NSS_NO_LIBPKIX
if (Preferences::GetBool("security.use_libpkix_verification", false)) {
certVerifierImplementation = CertVerifier::libpkix;
}
#endif
+ }
CertVerifier::ocsp_download_config odc;
CertVerifier::ocsp_strict_config osc;
CertVerifier::ocsp_get_config ogc;
SetClassicOCSPBehaviorFromPrefs(&odc, &osc, &ogc, lock);
mDefaultCertVerifier = new SharedCertVerifier(
certVerifierImplementation,
+#ifndef NSS_NO_LIBPKIX
aiaDownloadEnabled ?
CertVerifier::missing_cert_download_on : CertVerifier::missing_cert_download_off,
crlDownloading ?
CertVerifier::crl_download_allowed : CertVerifier::crl_local_only,
+#endif
odc, osc, ogc);
}
// Enable the TLS versions given in the prefs, defaulting to SSL 3.0 (min
// version) and TLS 1.2 (max version) when the prefs aren't set or set to
// invalid values.
nsresult
nsNSSComponent::setEnabledTLSVersions()
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -4213,32 +4213,48 @@
"SSL_SUCCESFUL_CERT_VALIDATION_TIME_CLASSIC": {
"expires_in_version": "never",
"kind": "exponential",
"high": "60000",
"n_buckets": 50,
"extended_statistics_ok": true,
"description": "Time spent on a successful cert verification in classic mode (ms)"
},
- "SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_LIBPKIX": {
+ "SSL_SUCCESFUL_CERT_VALIDATION_TIME_INSANITY" : {
+ "expires_in_version": "never",
+ "kind": "exponential",
+ "high": "60000",
+ "n_buckets": 50,
+ "extended_statistics_ok": true,
+ "description": "Time spent on a successful cert verification in insanity mode (ms)"
+ },
+ "SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_LIBPKIX" : {
"expires_in_version": "never",
"kind": "exponential",
"high": "60000",
"n_buckets": 50,
"extended_statistics_ok": true,
"description": "Time spent on an initially failed cert verification in libpix mode (ms)"
},
"SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_CLASSIC": {
"expires_in_version": "never",
"kind": "exponential",
"high": "60000",
"n_buckets": 50,
"extended_statistics_ok": true,
"description": "Time spent on an initially failed cert verification in classic mode (ms)"
},
+ "SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_INSANITY" : {
+ "expires_in_version": "never",
+ "kind": "exponential",
+ "high": "60000",
+ "n_buckets": 50,
+ "extended_statistics_ok": true,
+ "description": "Time spent on an initially failed cert verification in insanity mode (ms)"
+ },
"HEALTHREPORT_DB_OPEN_FIRSTRUN_MS": {
"expires_in_version": "never",
"kind": "exponential",
"high": "20000",
"n_buckets": 15,
"description": "Time (ms) spent to open Firefox Health Report's database the first time, including schema setup."
},
"HEALTHREPORT_DB_OPEN_MS": {