--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -80,25 +80,29 @@ CertificateTransparencyInfo::Reset()
enabled = false;
verifyResult.Reset();
policyCompliance = CTPolicyCompliance::Unknown;
}
CertVerifier::CertVerifier(OcspDownloadConfig odc,
OcspStrictConfig osc,
OcspGetConfig ogc,
+ mozilla::TimeDuration ocspTimeoutSoft,
+ mozilla::TimeDuration ocspTimeoutHard,
uint32_t certShortLifetimeInDays,
PinningMode pinningMode,
SHA1Mode sha1Mode,
BRNameMatchingPolicy::Mode nameMatchingMode,
NetscapeStepUpPolicy netscapeStepUpPolicy,
CertificateTransparencyMode ctMode)
: mOCSPDownloadConfig(odc)
, mOCSPStrict(osc == ocspStrict)
, mOCSPGETEnabled(ogc == ocspGetEnabled)
+ , mOCSPTimeoutSoft(ocspTimeoutSoft)
+ , mOCSPTimeoutHard(ocspTimeoutHard)
, mCertShortLifetimeInDays(certShortLifetimeInDays)
, mPinningMode(pinningMode)
, mSHA1Mode(sha1Mode)
, mNameMatchingMode(nameMatchingMode)
, mNetscapeStepUpPolicy(netscapeStepUpPolicy)
, mCTMode(ctMode)
{
LoadKnownCTLogs();
@@ -527,16 +531,17 @@ CertVerifier::VerifyCert(CERTCertificate
}
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, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
+ mOCSPTimeoutSoft, mOCSPTimeoutHard,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch,
originAttributes,
builtChain, nullptr, nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
@@ -603,16 +608,17 @@ CertVerifier::VerifyCert(CERTCertificate
// previously noted telemetry information
if (pinningTelemetryInfo) {
pinningTelemetryInfo->Reset();
}
NSSCertDBTrustDomain
trustDomain(trustSSL, evOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
+ mOCSPTimeoutSoft, mOCSPTimeoutHard,
mCertShortLifetimeInDays, mPinningMode, MIN_RSA_BITS,
ValidityCheckingMode::CheckForEV,
sha1ModeConfigurations[i], mNetscapeStepUpPolicy,
originAttributes, builtChain, pinningTelemetryInfo,
hostname);
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
KeyUsage::digitalSignature,// (EC)DHE
KeyUsage::keyEncipherment, // RSA
@@ -689,16 +695,17 @@ CertVerifier::VerifyCert(CERTCertificate
// invalidate any telemetry info relating to failed chains
if (pinningTelemetryInfo) {
pinningTelemetryInfo->Reset();
}
NSSCertDBTrustDomain trustDomain(trustSSL, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
+ mOCSPTimeoutSoft, mOCSPTimeoutHard,
mCertShortLifetimeInDays,
mPinningMode, keySizeOptions[i],
ValidityCheckingMode::CheckingOff,
sha1ModeConfigurations[j],
mNetscapeStepUpPolicy,
originAttributes, builtChain,
pinningTelemetryInfo, hostname);
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
@@ -753,32 +760,34 @@ CertVerifier::VerifyCert(CERTCertificate
}
break;
}
case certificateUsageSSLCA: {
NSSCertDBTrustDomain trustDomain(trustSSL, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
+ mOCSPTimeoutSoft, mOCSPTimeoutHard,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, mNetscapeStepUpPolicy,
originAttributes, builtChain, nullptr,
nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeCA, KeyUsage::keyCertSign,
KeyPurposeId::id_kp_serverAuth,
CertPolicyId::anyPolicy, stapledOCSPResponse);
break;
}
case certificateUsageEmailSigner: {
NSSCertDBTrustDomain trustDomain(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
+ mOCSPTimeoutSoft, mOCSPTimeoutHard,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch,
originAttributes, builtChain, nullptr,
nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
@@ -797,16 +806,17 @@ CertVerifier::VerifyCert(CERTCertificate
}
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, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
+ mOCSPTimeoutSoft, mOCSPTimeoutHard,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch,
originAttributes, builtChain, nullptr,
nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
@@ -822,16 +832,17 @@ CertVerifier::VerifyCert(CERTCertificate
CertPolicyId::anyPolicy, stapledOCSPResponse);
}
break;
}
case certificateUsageObjectSigner: {
NSSCertDBTrustDomain trustDomain(trustObjectSigning, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
+ mOCSPTimeoutSoft, mOCSPTimeoutHard,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch,
originAttributes, builtChain, nullptr,
nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
@@ -856,43 +867,48 @@ CertVerifier::VerifyCert(CERTCertificate
eku = KeyPurposeId::anyExtendedKeyUsage;
} else {
endEntityOrCA = EndEntityOrCA::MustBeEndEntity;
keyUsage = KeyUsage::digitalSignature;
eku = KeyPurposeId::id_kp_OCSPSigning;
}
NSSCertDBTrustDomain sslTrust(trustSSL, defaultOCSPFetching, mOCSPCache,
- pinArg, ocspGETConfig, mCertShortLifetimeInDays,
+ pinArg, ocspGETConfig, mOCSPTimeoutSoft,
+ mOCSPTimeoutHard, mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch,
originAttributes, builtChain, nullptr,
nullptr);
rv = BuildCertChain(sslTrust, certDER, time, endEntityOrCA,
keyUsage, eku, CertPolicyId::anyPolicy,
stapledOCSPResponse);
if (rv == Result::ERROR_UNKNOWN_ISSUER) {
NSSCertDBTrustDomain emailTrust(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
+ mOCSPTimeoutSoft, mOCSPTimeoutHard,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch,
originAttributes, builtChain, nullptr,
nullptr);
rv = BuildCertChain(emailTrust, certDER, time, endEntityOrCA,
keyUsage, eku, CertPolicyId::anyPolicy,
stapledOCSPResponse);
if (rv == Result::ERROR_UNKNOWN_ISSUER) {
NSSCertDBTrustDomain objectSigningTrust(trustObjectSigning,
- defaultOCSPFetching, mOCSPCache,
- pinArg, ocspGETConfig,
+ defaultOCSPFetching,
+ mOCSPCache, pinArg,
+ ocspGETConfig,
+ mOCSPTimeoutSoft,
+ mOCSPTimeoutHard,
mCertShortLifetimeInDays,
pinningDisabled,
MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch,
originAttributes, builtChain,
nullptr, nullptr);
--- a/security/certverifier/CertVerifier.h
+++ b/security/certverifier/CertVerifier.h
@@ -8,16 +8,17 @@
#define CertVerifier_h
#include "BRNameMatchingPolicy.h"
#include "CTPolicyEnforcer.h"
#include "CTVerifyResult.h"
#include "OCSPCache.h"
#include "ScopedNSSTypes.h"
#include "mozilla/Telemetry.h"
+#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "pkix/pkixtypes.h"
#if defined(_MSC_VER)
#pragma warning(push)
// Silence "RootingAPI.h(718): warning C4324: 'js::DispatchWrapper<T>':
// structure was padded due to alignment specifier with [ T=void * ]"
#pragma warning(disable:4324)
@@ -180,29 +181,33 @@ public:
enum OcspStrictConfig { ocspRelaxed = 0, ocspStrict };
enum OcspGetConfig { ocspGetDisabled = 0, ocspGetEnabled = 1 };
enum class CertificateTransparencyMode {
Disabled = 0,
TelemetryOnly = 1,
};
- CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
- OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
+ CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc, OcspGetConfig ogc,
+ mozilla::TimeDuration ocspTimeoutSoft,
+ mozilla::TimeDuration ocspTimeoutHard,
+ uint32_t certShortLifetimeInDays,
PinningMode pinningMode, SHA1Mode sha1Mode,
BRNameMatchingPolicy::Mode nameMatchingMode,
NetscapeStepUpPolicy netscapeStepUpPolicy,
CertificateTransparencyMode ctMode);
~CertVerifier();
void ClearOCSPCache() { mOCSPCache.Clear(); }
const OcspDownloadConfig mOCSPDownloadConfig;
const bool mOCSPStrict;
const bool mOCSPGETEnabled;
+ const mozilla::TimeDuration mOCSPTimeoutSoft;
+ const mozilla::TimeDuration mOCSPTimeoutHard;
const uint32_t mCertShortLifetimeInDays;
const PinningMode mPinningMode;
const SHA1Mode mSHA1Mode;
const BRNameMatchingPolicy::Mode mNameMatchingMode;
const NetscapeStepUpPolicy mNetscapeStepUpPolicy;
const CertificateTransparencyMode mCTMode;
private:
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -44,31 +44,35 @@ static const uint64_t ServerFailureDelay
namespace mozilla { namespace psm {
NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
OCSPFetching ocspFetching,
OCSPCache& ocspCache,
/*optional but shouldn't be*/ void* pinArg,
CertVerifier::OcspGetConfig ocspGETConfig,
+ TimeDuration ocspTimeoutSoft,
+ TimeDuration ocspTimeoutHard,
uint32_t certShortLifetimeInDays,
CertVerifier::PinningMode pinningMode,
unsigned int minRSABits,
ValidityCheckingMode validityCheckingMode,
CertVerifier::SHA1Mode sha1Mode,
NetscapeStepUpPolicy netscapeStepUpPolicy,
const OriginAttributes& originAttributes,
UniqueCERTCertList& builtChain,
/*optional*/ PinningTelemetryInfo* pinningTelemetryInfo,
/*optional*/ const char* hostname)
: mCertDBTrustType(certDBTrustType)
, mOCSPFetching(ocspFetching)
, mOCSPCache(ocspCache)
, mPinArg(pinArg)
, mOCSPGetConfig(ocspGETConfig)
+ , mOCSPTimeoutSoft(ocspTimeoutSoft)
+ , mOCSPTimeoutHard(ocspTimeoutHard)
, mCertShortLifetimeInDays(certShortLifetimeInDays)
, mPinningMode(pinningMode)
, mMinRSABits(minRSABits)
, mValidityCheckingMode(validityCheckingMode)
, mSHA1Mode(sha1Mode)
, mNetscapeStepUpPolicy(netscapeStepUpPolicy)
, mOriginAttributes(originAttributes)
, mBuiltChain(builtChain)
@@ -265,35 +269,35 @@ NSSCertDBTrustDomain::GetCertTrust(EndEn
Result
NSSCertDBTrustDomain::DigestBuf(Input item, DigestAlgorithm digestAlg,
/*out*/ uint8_t* digestBuf, size_t digestBufLen)
{
return DigestBufNSS(item, digestAlg, digestBuf, digestBufLen);
}
-static TimeDuration
-OCSPFetchingTypeToTimeoutTime(NSSCertDBTrustDomain::OCSPFetching ocspFetching)
+TimeDuration
+NSSCertDBTrustDomain::GetOCSPTimeout() const
{
- switch (ocspFetching) {
+ switch (mOCSPFetching) {
case NSSCertDBTrustDomain::FetchOCSPForDVSoftFail:
- return TimeDuration::FromSeconds(2);
+ return mOCSPTimeoutSoft;
case NSSCertDBTrustDomain::FetchOCSPForEV:
case NSSCertDBTrustDomain::FetchOCSPForDVHardFail:
- return TimeDuration::FromSeconds(10);
+ return mOCSPTimeoutHard;
// The rest of these are error cases. Assert in debug builds, but return
- // the default value corresponding to 2 seconds in release builds.
+ // the soft timeout value in release builds.
case NSSCertDBTrustDomain::NeverFetchOCSP:
case NSSCertDBTrustDomain::LocalOnlyOCSPForEV:
MOZ_ASSERT_UNREACHABLE("we should never see this OCSPFetching type here");
break;
}
MOZ_ASSERT_UNREACHABLE("we're not handling every OCSPFetching type");
- return TimeDuration::FromSeconds(2);
+ return mOCSPTimeoutSoft;
}
// Copied and modified from CERT_GetOCSPAuthorityInfoAccessLocation and
// CERT_GetGeneralNameByType. Returns a non-Result::Success result on error,
// Success with url == nullptr when an OCSP URI was not found, and Success with
// url != nullptr when an OCSP URI was found. The output url will be owned
// by the arena.
static Result
@@ -560,17 +564,17 @@ NSSCertDBTrustDomain::CheckRevocation(En
siBuffer,
ocspRequest,
static_cast<unsigned int>(ocspRequestLength)
};
// Owned by arena
SECItem* responseSECItem = nullptr;
Result tempRV =
DoOCSPRequest(arena, url, mOriginAttributes, &ocspRequestItem,
- OCSPFetchingTypeToTimeoutTime(mOCSPFetching),
+ GetOCSPTimeout(),
mOCSPGetConfig == CertVerifier::ocspGetEnabled,
responseSECItem);
MOZ_ASSERT((tempRV != Success) || responseSECItem);
if (tempRV != Success) {
rv = tempRV;
} else if (response.Init(responseSECItem->data, responseSECItem->len)
!= Success) {
rv = Result::ERROR_OCSP_MALFORMED_RESPONSE; // too big
--- a/security/certverifier/NSSCertDBTrustDomain.h
+++ b/security/certverifier/NSSCertDBTrustDomain.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef NSSCertDBTrustDomain_h
#define NSSCertDBTrustDomain_h
#include "CertVerifier.h"
#include "ScopedNSSTypes.h"
#include "mozilla/BasePrincipal.h"
+#include "mozilla/TimeStamp.h"
#include "nsICertBlocklist.h"
#include "nsString.h"
#include "pkix/pkixtypes.h"
#include "secmodt.h"
namespace mozilla { namespace psm {
enum class ValidityCheckingMode {
@@ -72,16 +73,18 @@ public:
FetchOCSPForDVHardFail = 2,
FetchOCSPForEV = 3,
LocalOnlyOCSPForEV = 4,
};
NSSCertDBTrustDomain(SECTrustType certDBTrustType, OCSPFetching ocspFetching,
OCSPCache& ocspCache, void* pinArg,
CertVerifier::OcspGetConfig ocspGETConfig,
+ mozilla::TimeDuration ocspTimeoutSoft,
+ mozilla::TimeDuration ocspTimeoutHard,
uint32_t certShortLifetimeInDays,
CertVerifier::PinningMode pinningMode,
unsigned int minRSABits,
ValidityCheckingMode validityCheckingMode,
CertVerifier::SHA1Mode sha1Mode,
NetscapeStepUpPolicy netscapeStepUpPolicy,
const OriginAttributes& originAttributes,
UniqueCERTCertList& builtChain,
@@ -172,22 +175,25 @@ private:
enum EncodedResponseSource {
ResponseIsFromNetwork = 1,
ResponseWasStapled = 2
};
Result VerifyAndMaybeCacheEncodedOCSPResponse(
const mozilla::pkix::CertID& certID, mozilla::pkix::Time time,
uint16_t maxLifetimeInDays, mozilla::pkix::Input encodedResponse,
EncodedResponseSource responseSource, /*out*/ bool& expired);
+ TimeDuration GetOCSPTimeout() const;
const SECTrustType mCertDBTrustType;
const OCSPFetching mOCSPFetching;
OCSPCache& mOCSPCache; // non-owning!
void* mPinArg; // non-owning!
const CertVerifier::OcspGetConfig mOCSPGetConfig;
+ const mozilla::TimeDuration mOCSPTimeoutSoft;
+ const mozilla::TimeDuration mOCSPTimeoutHard;
const uint32_t mCertShortLifetimeInDays;
CertVerifier::PinningMode mPinningMode;
const unsigned int mMinRSABits;
ValidityCheckingMode mValidityCheckingMode;
CertVerifier::SHA1Mode mSHA1Mode;
NetscapeStepUpPolicy mNetscapeStepUpPolicy;
const OriginAttributes& mOriginAttributes;
UniqueCERTCertList& mBuiltChain; // non-owning
--- a/security/manager/ssl/SharedCertVerifier.h
+++ b/security/manager/ssl/SharedCertVerifier.h
@@ -2,34 +2,39 @@
* 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 SharedCertVerifier_h
#define SharedCertVerifier_h
#include "CertVerifier.h"
#include "mozilla/RefPtr.h"
+#include "mozilla/TimeStamp.h"
namespace mozilla { namespace psm {
class SharedCertVerifier : public mozilla::psm::CertVerifier
{
protected:
~SharedCertVerifier();
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedCertVerifier)
SharedCertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
- OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
+ OcspGetConfig ogc,
+ mozilla::TimeDuration ocspSoftTimeout,
+ mozilla::TimeDuration ocspHardTimeout,
+ uint32_t certShortLifetimeInDays,
PinningMode pinningMode, SHA1Mode sha1Mode,
BRNameMatchingPolicy::Mode nameMatchingMode,
NetscapeStepUpPolicy netscapeStepUpPolicy,
CertificateTransparencyMode ctMode)
- : mozilla::psm::CertVerifier(odc, osc, ogc, certShortLifetimeInDays,
+ : mozilla::psm::CertVerifier(odc, osc, ogc, ocspSoftTimeout,
+ ocspHardTimeout, certShortLifetimeInDays,
pinningMode, sha1Mode, nameMatchingMode,
netscapeStepUpPolicy, ctMode)
{
}
};
} } // namespace mozilla::psm
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -17,16 +17,17 @@
#include "mozilla/Casting.h"
#include "mozilla/Preferences.h"
#include "mozilla/PodOperations.h"
#include "mozilla/PublicSSL.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/Telemetry.h"
+#include "mozilla/TimeStamp.h"
#include "mozilla/Unused.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsCRT.h"
#include "nsClientAuthRemember.h"
#include "nsComponentManagerUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsICertOverrideService.h"
#include "nsIFile.h"
@@ -125,21 +126,28 @@ bool EnsureNSSInitializedChromeOrContent
if (NS_FAILED(mozilla::psm::InitializeCipherSuite())) {
return false;
}
mozilla::psm::DisableMD5();
return true;
}
+static const uint32_t OCSP_TIMEOUT_MILLISECONDS_SOFT_DEFAULT = 2000;
+static const uint32_t OCSP_TIMEOUT_MILLISECONDS_SOFT_MAX = 5000;
+static const uint32_t OCSP_TIMEOUT_MILLISECONDS_HARD_DEFAULT = 10000;
+static const uint32_t OCSP_TIMEOUT_MILLISECONDS_HARD_MAX = 20000;
+
static void
GetRevocationBehaviorFromPrefs(/*out*/ CertVerifier::OcspDownloadConfig* odc,
/*out*/ CertVerifier::OcspStrictConfig* osc,
/*out*/ CertVerifier::OcspGetConfig* ogc,
/*out*/ uint32_t* certShortLifetimeInDays,
+ /*out*/ TimeDuration& softTimeout,
+ /*out*/ TimeDuration& hardTimeout,
const MutexAutoLock& /*proofOfLock*/)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(odc);
MOZ_ASSERT(osc);
MOZ_ASSERT(ogc);
MOZ_ASSERT(certShortLifetimeInDays);
@@ -164,16 +172,30 @@ GetRevocationBehaviorFromPrefs(/*out*/ C
// If we pass in just 0 as the second argument to Preferences::GetUint, there
// are two function signatures that match (given that 0 can be intepreted as
// a null pointer). Thus the compiler will complain without the cast.
*certShortLifetimeInDays =
Preferences::GetUint("security.pki.cert_short_lifetime_in_days",
static_cast<uint32_t>(0));
+ uint32_t softTimeoutMillis =
+ Preferences::GetUint("security.OCSP.timeoutMilliseconds.soft",
+ OCSP_TIMEOUT_MILLISECONDS_SOFT_DEFAULT);
+ softTimeoutMillis = std::min(softTimeoutMillis,
+ OCSP_TIMEOUT_MILLISECONDS_SOFT_MAX);
+ softTimeout = TimeDuration::FromMilliseconds(softTimeoutMillis);
+
+ uint32_t hardTimeoutMillis =
+ Preferences::GetUint("security.OCSP.timeoutMilliseconds.hard",
+ OCSP_TIMEOUT_MILLISECONDS_HARD_DEFAULT);
+ hardTimeoutMillis = std::min(hardTimeoutMillis,
+ OCSP_TIMEOUT_MILLISECONDS_HARD_MAX);
+ hardTimeout = TimeDuration::FromMilliseconds(hardTimeoutMillis);
+
SSL_ClearSessionCache();
}
nsNSSComponent::nsNSSComponent()
: mutex("nsNSSComponent.mutex")
, mNSSInitialized(false)
#ifndef MOZ_NO_SMART_CARDS
, mThreadList(nullptr)
@@ -1517,20 +1539,23 @@ void nsNSSComponent::setValidationOption
netscapeStepUpPolicy = NetscapeStepUpPolicy::AlwaysMatch;
break;
}
CertVerifier::OcspDownloadConfig odc;
CertVerifier::OcspStrictConfig osc;
CertVerifier::OcspGetConfig ogc;
uint32_t certShortLifetimeInDays;
+ TimeDuration softTimeout;
+ TimeDuration hardTimeout;
GetRevocationBehaviorFromPrefs(&odc, &osc, &ogc, &certShortLifetimeInDays,
- lock);
- mDefaultCertVerifier = new SharedCertVerifier(odc, osc, ogc,
+ softTimeout, hardTimeout, lock);
+ mDefaultCertVerifier = new SharedCertVerifier(odc, osc, ogc, softTimeout,
+ hardTimeout,
certShortLifetimeInDays,
pinningMode, sha1Mode,
nameMatchingMode,
netscapeStepUpPolicy,
ctMode);
}
// Enable the TLS versions given in the prefs, defaulting to TLS 1.0 (min) and
@@ -1914,17 +1939,19 @@ nsNSSComponent::Observe(nsISupports* aSu
prefName.EqualsLiteral("security.OCSP.GET.enabled") ||
prefName.EqualsLiteral("security.pki.cert_short_lifetime_in_days") ||
prefName.EqualsLiteral("security.ssl.enable_ocsp_stapling") ||
prefName.EqualsLiteral("security.ssl.enable_ocsp_must_staple") ||
prefName.EqualsLiteral("security.pki.certificate_transparency.mode") ||
prefName.EqualsLiteral("security.cert_pinning.enforcement_level") ||
prefName.EqualsLiteral("security.pki.sha1_enforcement_level") ||
prefName.EqualsLiteral("security.pki.name_matching_mode") ||
- prefName.EqualsLiteral("security.pki.netscape_step_up_policy")) {
+ prefName.EqualsLiteral("security.pki.netscape_step_up_policy") ||
+ prefName.EqualsLiteral("security.OCSP.timeoutMilliseconds.soft") ||
+ prefName.EqualsLiteral("security.OCSP.timeoutMilliseconds.hard")) {
MutexAutoLock lock(mutex);
setValidationOptions(false, lock);
#ifdef DEBUG
} else if (prefName.EqualsLiteral("security.test.built_in_root_hash")) {
MutexAutoLock lock(mutex);
mTestBuiltInRootHash = Preferences::GetString("security.test.built_in_root_hash");
#endif // DEBUG
} else if (prefName.Equals(kFamilySafetyModePref)) {
--- a/security/manager/ssl/security-prefs.js
+++ b/security/manager/ssl/security-prefs.js
@@ -45,16 +45,18 @@ pref("security.password_lifetime",
// (This is only relevant to Windows 8.1)
pref("security.family_safety.mode", 2);
pref("security.enterprise_roots.enabled", false);
pref("security.OCSP.enabled", 1);
pref("security.OCSP.require", false);
pref("security.OCSP.GET.enabled", false);
+pref("security.OCSP.timeoutMilliseconds.soft", 2000);
+pref("security.OCSP.timeoutMilliseconds.hard", 10000);
pref("security.pki.cert_short_lifetime_in_days", 10);
// NB: Changes to this pref affect CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
// See the comment in CertVerifier.cpp.
// 3 = only allow SHA-1 for certificates issued by an imported root.
pref("security.pki.sha1_enforcement_level", 3);
// security.pki.name_matching_mode controls how the platform matches hostnames
--- a/security/manager/ssl/tests/unit/test_ocsp_timeout.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_timeout.js
@@ -30,59 +30,61 @@ function run_test() {
add_tls_server_setup("OCSPStaplingServer", "ocsp_certs");
let socket = Cc["@mozilla.org/network/server-socket;1"]
.createInstance(Ci.nsIServerSocket);
socket.init(8888, true, -1);
socket.asyncListen(gSocketListener);
- add_tests_in_mode(true);
- add_tests_in_mode(false);
+ add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 1000);
+ add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 2000);
+ add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 4000);
+
+ add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 3000);
+ add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 10000);
+ add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 15000);
add_test(function() { socket.close(); run_next_test(); });
run_next_test();
}
-function add_tests_in_mode(useHardFail) {
+function add_one_test(useHardFail, timeoutPrefName, timeoutMilliseconds) {
let startTime;
add_test(function () {
Services.prefs.setBoolPref("security.OCSP.require", useHardFail);
+ Services.prefs.setIntPref(timeoutPrefName, timeoutMilliseconds);
startTime = new Date();
run_next_test();
});
add_connection_test("ocsp-stapling-none.example.com", useHardFail
? SEC_ERROR_OCSP_SERVER_ERROR
: PRErrorCodeSuccess, clearSessionCache);
- // Reset state
add_test(function() {
let endTime = new Date();
let timeDifference = endTime - startTime;
do_print(`useHardFail = ${useHardFail}`);
do_print(`startTime = ${startTime.getTime()} (${startTime})`);
do_print(`endTime = ${endTime.getTime()} (${endTime})`);
do_print(`timeDifference = ${timeDifference}ms`);
-
- // With OCSP hard-fail on, we timeout after 10 seconds.
- // With OCSP soft-fail, we timeout after 2 seconds.
// Date() is not guaranteed to be monotonic, so add extra fuzz time to
// prevent intermittent failures (this only appeared to be a problem on
// Windows XP). See Bug 1121117.
const FUZZ_MS = 300;
- if (useHardFail) {
- ok(timeDifference + FUZZ_MS > 10000,
- "Automatic OCSP timeout should be about 10s for hard-fail");
- } else {
- ok(timeDifference + FUZZ_MS > 2000,
- "Automatic OCSP timeout should be about 2s for soft-fail");
- }
+ ok(timeDifference + FUZZ_MS > timeoutMilliseconds,
+ `OCSP timeout should be ~${timeoutMilliseconds}s for ` +
+ `${useHardFail ? "hard" : "soft"}-fail`);
// Make sure we didn't wait too long.
// (Unfortunately, we probably can't have a tight upper bound on
// how long is too long for this test, because we might be running
// on slow hardware.)
ok(timeDifference < 60000,
"Automatic OCSP timeout shouldn't be more than 60s");
+
+ // Reset state
clearOCSPCache();
+ Services.prefs.clearUserPref("security.OCSP.require");
+ Services.prefs.clearUserPref(timeoutPrefName);
run_next_test();
});
}