mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1128607 - Add freshness check for OneCRL (r=keeler)
This commit is contained in:
parent
726e9673d3
commit
9e5913dddb
@ -1740,6 +1740,10 @@ pref("security.mixed_content.block_active_content", true);
|
||||
// 1 = allow MITM for certificate pinning checks.
|
||||
pref("security.cert_pinning.enforcement_level", 1);
|
||||
|
||||
// Required blocklist freshness for OneCRL OCSP bypass
|
||||
// (default should be at least as large as extensions.blocklist.interval)
|
||||
pref("security.onecrl.maximum_staleness_in_seconds", 0);
|
||||
|
||||
// Override the Gecko-default value of false for Firefox.
|
||||
pref("plain_text.wrap_long_lines", true);
|
||||
|
||||
|
@ -444,6 +444,13 @@ NSSCertDBTrustDomain::CheckRevocation(EndEntityOrCA endEntityOrCA,
|
||||
PR_ASSERT((!cachedResponsePresent && cachedResponseResult == Success) ||
|
||||
(cachedResponsePresent && cachedResponseResult != Success));
|
||||
|
||||
// If we have a fresh OneCRL Blocklist we can skip OCSP for CA certs
|
||||
bool blocklistIsFresh;
|
||||
nsresult nsrv = mCertBlocklist->IsBlocklistFresh(&blocklistIsFresh);
|
||||
if (NS_FAILED(nsrv)) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
||||
// TODO: We still need to handle the fallback for expired responses. But,
|
||||
// if/when we disable OCSP fetching by default, it would be ambiguous whether
|
||||
// security.OCSP.enable==0 means "I want the default" or "I really never want
|
||||
@ -452,7 +459,8 @@ NSSCertDBTrustDomain::CheckRevocation(EndEntityOrCA endEntityOrCA,
|
||||
if ((mOCSPFetching == NeverFetchOCSP) ||
|
||||
(endEntityOrCA == EndEntityOrCA::MustBeCA &&
|
||||
(mOCSPFetching == FetchOCSPForDVHardFail ||
|
||||
mOCSPFetching == FetchOCSPForDVSoftFail))) {
|
||||
mOCSPFetching == FetchOCSPForDVSoftFail ||
|
||||
blocklistIsFresh))) {
|
||||
// We're not going to be doing any fetching, so if there was a cached
|
||||
// "unknown" response, say so.
|
||||
if (cachedResponseResult == Result::ERROR_OCSP_UNKNOWN_CERT) {
|
||||
|
@ -14,7 +14,7 @@ interface nsIX509Cert;
|
||||
/**
|
||||
* Represents a service to add certificates as explicitly blocked/distrusted.
|
||||
*/
|
||||
[scriptable, uuid(fed30090-c190-11e4-8830-0800200c9a66)]
|
||||
[scriptable, uuid(e0654480-f433-11e4-b939-0800200c9a66)]
|
||||
interface nsICertBlocklist : nsISupports {
|
||||
/**
|
||||
* Add details of a revoked certificate :
|
||||
@ -50,4 +50,12 @@ interface nsICertBlocklist : nsISupports {
|
||||
in unsigned long subject_length,
|
||||
[const, array, size_is(pubkey_length)] in octet pubkey,
|
||||
in unsigned long pubkey_length);
|
||||
|
||||
/**
|
||||
* Check that the blocklist data is current. Specifically, that the current
|
||||
* time is no more than security.onecrl.maximum_staleness_in_seconds seconds
|
||||
* after the last blocklist update (as stored in the
|
||||
* app.update.lastUpdateTime.blocklist-background-update-timer pref)
|
||||
*/
|
||||
boolean isBlocklistFresh();
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "CertBlocklist.h"
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsCRTGlue.h"
|
||||
@ -22,8 +23,17 @@
|
||||
|
||||
NS_IMPL_ISUPPORTS(CertBlocklist, nsICertBlocklist)
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::pkix;
|
||||
|
||||
#define PREF_BACKGROUND_UPDATE_TIMER "app.update.lastUpdateTime.blocklist-background-update-timer"
|
||||
#define PREF_MAX_STALENESS_IN_SECONDS "security.onecrl.maximum_staleness_in_seconds"
|
||||
|
||||
static PRLogModuleInfo* gCertBlockPRLog;
|
||||
|
||||
uint32_t CertBlocklist::sLastBlocklistUpdate = 0U;
|
||||
uint32_t CertBlocklist::sMaxStaleness = 0U;
|
||||
|
||||
CertBlocklistItem::CertBlocklistItem(const uint8_t* DNData,
|
||||
size_t DNLength,
|
||||
const uint8_t* otherData,
|
||||
@ -69,11 +79,11 @@ CertBlocklistItem::ToBase64(nsACString& b64DNOut, nsACString& b64OtherOut)
|
||||
mDNLength);
|
||||
nsDependentCSubstring otherString(reinterpret_cast<char*>(mOtherData),
|
||||
mOtherLength);
|
||||
nsresult rv = mozilla::Base64Encode(DNString, b64DNOut);
|
||||
nsresult rv = Base64Encode(DNString, b64DNOut);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = mozilla::Base64Encode(otherString, b64OtherOut);
|
||||
rv = Base64Encode(otherString, b64OtherOut);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -120,6 +130,12 @@ CertBlocklist::CertBlocklist()
|
||||
|
||||
CertBlocklist::~CertBlocklist()
|
||||
{
|
||||
Preferences::UnregisterCallback(CertBlocklist::PreferenceChanged,
|
||||
PREF_BACKGROUND_UPDATE_TIMER,
|
||||
this);
|
||||
Preferences::UnregisterCallback(CertBlocklist::PreferenceChanged,
|
||||
PREF_MAX_STALENESS_IN_SECONDS,
|
||||
this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -134,9 +150,24 @@ CertBlocklist::Init()
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
}
|
||||
|
||||
// Register preference callbacks
|
||||
nsresult rv =
|
||||
Preferences::RegisterCallbackAndCall(CertBlocklist::PreferenceChanged,
|
||||
PREF_BACKGROUND_UPDATE_TIMER,
|
||||
this);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = Preferences::RegisterCallbackAndCall(CertBlocklist::PreferenceChanged,
|
||||
PREF_MAX_STALENESS_IN_SECONDS,
|
||||
this);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the profile directory
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(mBackingFile));
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(mBackingFile));
|
||||
if (NS_FAILED(rv) || !mBackingFile) {
|
||||
PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
|
||||
("CertBlocklist::Init - couldn't get profile dir"));
|
||||
@ -162,7 +193,7 @@ CertBlocklist::Init()
|
||||
}
|
||||
|
||||
nsresult
|
||||
CertBlocklist::EnsureBackingFileInitialized(mozilla::MutexAutoLock& lock)
|
||||
CertBlocklist::EnsureBackingFileInitialized(MutexAutoLock& lock)
|
||||
{
|
||||
PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
|
||||
("CertBlocklist::EnsureBackingFileInitialized"));
|
||||
@ -262,7 +293,7 @@ CertBlocklist::RevokeCertBySubjectAndPubKey(const char* aSubject,
|
||||
PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
|
||||
("CertBlocklist::RevokeCertBySubjectAndPubKey - subject is: %s and pubKeyHash: %s",
|
||||
aSubject, aPubKeyHash));
|
||||
mozilla::MutexAutoLock lock(mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
return AddRevokedCertInternal(nsDependentCString(aSubject),
|
||||
nsDependentCString(aPubKeyHash),
|
||||
@ -278,7 +309,7 @@ CertBlocklist::RevokeCertByIssuerAndSerial(const char* aIssuer,
|
||||
PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
|
||||
("CertBlocklist::RevokeCertByIssuerAndSerial - issuer is: %s and serial: %s",
|
||||
aIssuer, aSerialNumber));
|
||||
mozilla::MutexAutoLock lock(mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
return AddRevokedCertInternal(nsDependentCString(aIssuer),
|
||||
nsDependentCString(aSerialNumber),
|
||||
@ -291,16 +322,16 @@ CertBlocklist::AddRevokedCertInternal(const nsACString& aEncodedDN,
|
||||
const nsACString& aEncodedOther,
|
||||
CertBlocklistItemMechanism aMechanism,
|
||||
CertBlocklistItemState aItemState,
|
||||
mozilla::MutexAutoLock& /*proofOfLock*/)
|
||||
MutexAutoLock& /*proofOfLock*/)
|
||||
{
|
||||
nsCString decodedDN;
|
||||
nsCString decodedOther;
|
||||
|
||||
nsresult rv = mozilla::Base64Decode(aEncodedDN, decodedDN);
|
||||
nsresult rv = Base64Decode(aEncodedDN, decodedDN);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = mozilla::Base64Decode(aEncodedOther, decodedOther);
|
||||
rv = Base64Decode(aEncodedOther, decodedOther);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -452,7 +483,7 @@ CertBlocklist::SaveEntries()
|
||||
{
|
||||
PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
|
||||
("CertBlocklist::SaveEntries - not initialized"));
|
||||
mozilla::MutexAutoLock lock(mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mModified) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -532,19 +563,19 @@ CertBlocklist::IsCertRevoked(const uint8_t* aIssuer,
|
||||
uint32_t aPubKeyLength,
|
||||
bool* _retval)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
nsresult rv = EnsureBackingFileInitialized(lock);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mozilla::pkix::Input issuer;
|
||||
mozilla::pkix::Input serial;
|
||||
if (issuer.Init(aIssuer, aIssuerLength) != mozilla::pkix::Success) {
|
||||
Input issuer;
|
||||
Input serial;
|
||||
if (issuer.Init(aIssuer, aIssuerLength) != Success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (serial.Init(aSerial, aSerialLength) != mozilla::pkix::Success) {
|
||||
if (serial.Init(aSerial, aSerialLength) != Success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -585,3 +616,43 @@ CertBlocklist::IsCertRevoked(const uint8_t* aIssuer,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CertBlocklist::IsBlocklistFresh(bool* _retval)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
*_retval = false;
|
||||
|
||||
uint32_t now = uint32_t(PR_Now() / PR_USEC_PER_SEC);
|
||||
|
||||
if (now > sLastBlocklistUpdate) {
|
||||
int64_t interval = now - sLastBlocklistUpdate;
|
||||
PR_LOG(gCertBlockPRLog, PR_LOG_WARN,
|
||||
("CertBlocklist::IsBlocklistFresh we're after the last BlocklistUpdate "
|
||||
"interval is %i, staleness %u", interval, sMaxStaleness));
|
||||
*_retval = sMaxStaleness > interval;
|
||||
}
|
||||
PR_LOG(gCertBlockPRLog, PR_LOG_WARN,
|
||||
("CertBlocklist::IsBlocklistFresh ? %s", *_retval ? "true" : "false"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* static */
|
||||
void
|
||||
CertBlocklist::PreferenceChanged(const char* aPref, void* aClosure)
|
||||
|
||||
{
|
||||
CertBlocklist* blocklist = reinterpret_cast<CertBlocklist*>(aClosure);
|
||||
MutexAutoLock lock(blocklist->mMutex);
|
||||
|
||||
PR_LOG(gCertBlockPRLog, PR_LOG_WARN,
|
||||
("CertBlocklist::PreferenceChanged %s changed", aPref));
|
||||
if (strcmp(aPref, PREF_BACKGROUND_UPDATE_TIMER) == 0) {
|
||||
sLastBlocklistUpdate = Preferences::GetUint(PREF_BACKGROUND_UPDATE_TIMER,
|
||||
uint32_t(0));
|
||||
} else if (strcmp(aPref, PREF_MAX_STALENESS_IN_SECONDS) == 0) {
|
||||
sMaxStaleness = Preferences::GetUint(PREF_MAX_STALENESS_IN_SECONDS,
|
||||
uint32_t(0));
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,9 @@ private:
|
||||
nsCOMPtr<nsIFile> mBackingFile;
|
||||
|
||||
protected:
|
||||
static void PreferenceChanged(const char* aPref, void* aClosure);
|
||||
static uint32_t sLastBlocklistUpdate;
|
||||
static uint32_t sMaxStaleness;
|
||||
virtual ~CertBlocklist();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user