Bug 1664995 - Part 1: Make OCSP cache to be aware of the partitionKey in the originAttributes. r=keeler

The patch add partitionKey into the certIDHash to isolate OCSP by the
partitionKey.

Differential Revision: https://phabricator.services.mozilla.com/D123957
This commit is contained in:
Tim Huang 2021-09-16 09:20:39 +00:00
parent 72c414923b
commit 374fb44e84
2 changed files with 48 additions and 11 deletions

View File

@ -10506,6 +10506,18 @@
value: true
mirror: always
# Partition the OCSP cache by the partitionKey.
- name: privacy.partition.network_state.ocsp_cache
type: RelaxedAtomicBool
value: @IS_NIGHTLY_BUILD@
mirror: always
# Partition the OCSP cache by the partitionKey for private browsing mode.
- name: privacy.partition.network_state.ocsp_cache.pbmode
type: RelaxedAtomicBool
value: true
mirror: always
- name: privacy.partition.bloburl_per_agent_cluster
type: RelaxedAtomicBool
value: false

View File

@ -28,6 +28,7 @@
#include "NSSCertDBTrustDomain.h"
#include "pk11pub.h"
#include "mozilla/StaticPrefs_privacy.h"
#include "mozpkix/pkixnss.h"
#include "ScopedNSSTypes.h"
#include "secerr.h"
@ -63,8 +64,11 @@ static SECStatus DigestLength(UniquePK11Context& context, uint32_t length) {
// It is only non-empty when "privacy.firstParty.isolate" is enabled, in order
// to isolate OCSP cache by first party.
// Let firstPartyDomainLen be the number of bytes of firstPartyDomain.
// Let partitionKey be the partition key of originAttributes.
// Let partitionKeyLen be the number of bytes of partitionKey.
// The value calculated is SHA384(derIssuer || derPublicKey || serialNumberLen
// || serialNumber || firstPartyDomainLen || firstPartyDomain).
// || serialNumber || firstPartyDomainLen || firstPartyDomain || partitionKeyLen
// || partitionKey).
// Because the DER encodings include the length of the data encoded, and we also
// include the length of serialNumber and originAttributes, there do not exist
// A(derIssuerA, derPublicKeyA, serialNumberLenA, serialNumberA,
@ -108,17 +112,36 @@ static SECStatus CertIDHash(SHA384Buffer& buf, const CertID& certID,
return rv;
}
// OCSP should not be isolated by containers.
NS_ConvertUTF16toUTF8 firstPartyDomain(originAttributes.mFirstPartyDomain);
if (!firstPartyDomain.IsEmpty()) {
rv = DigestLength(context, firstPartyDomain.Length());
auto populateOriginAttributesKey = [&context](const nsString& aKey) {
NS_ConvertUTF16toUTF8 key(aKey);
if (key.IsEmpty()) {
return SECSuccess;
}
SECStatus rv = DigestLength(context, key.Length());
if (rv != SECSuccess) {
return rv;
}
rv =
PK11_DigestOp(context.get(),
BitwiseCast<const unsigned char*>(firstPartyDomain.get()),
firstPartyDomain.Length());
return PK11_DigestOp(context.get(),
BitwiseCast<const unsigned char*>(key.get()),
key.Length());
};
// OCSP should be isolated by firstPartyDomain and partitionKey, but not
// by containers.
rv = populateOriginAttributesKey(originAttributes.mFirstPartyDomain);
if (rv != SECSuccess) {
return rv;
}
bool isolateByPartitionKey =
originAttributes.mPrivateBrowsingId > 0
? StaticPrefs::privacy_partition_network_state_ocsp_cache_pbmode()
: StaticPrefs::privacy_partition_network_state_ocsp_cache();
if (isolateByPartitionKey) {
rv = populateOriginAttributesKey(originAttributes.mPartitionKey);
if (rv != SECSuccess) {
return rv;
}
@ -174,9 +197,11 @@ bool OCSPCache::FindInternal(const CertID& aCertID,
static inline void LogWithCertID(const char* aMessage, const CertID& aCertID,
const OriginAttributes& aOriginAttributes) {
NS_ConvertUTF16toUTF8 firstPartyDomain(aOriginAttributes.mFirstPartyDomain);
nsAutoString info = u"firstPartyDomain: "_ns +
aOriginAttributes.mFirstPartyDomain +
u", partitionKey: "_ns + aOriginAttributes.mPartitionKey;
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
(aMessage, &aCertID, firstPartyDomain.get()));
(aMessage, &aCertID, NS_ConvertUTF16toUTF8(info).get()));
}
void OCSPCache::MakeMostRecentlyUsed(size_t aIndex,