Bug 1315143 - Make OCSP use Origin Attribute framework (PSM). r=mayhemer

This commit is contained in:
Jonathan Hao
2016-11-14 18:26:15 +08:00
parent 4f67806e5f
commit c0f6a74c60
21 changed files with 196 additions and 138 deletions

View File

@@ -328,7 +328,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
/*optional*/ const Flags flags, /*optional*/ const Flags flags,
/*optional*/ const SECItem* stapledOCSPResponseSECItem, /*optional*/ const SECItem* stapledOCSPResponseSECItem,
/*optional*/ const SECItem* sctsFromTLSSECItem, /*optional*/ const SECItem* sctsFromTLSSECItem,
/*optional*/ const char* firstPartyDomain, /*optional*/ const NeckoOriginAttributes& originAttributes,
/*optional out*/ SECOidTag* evOidPolicy, /*optional out*/ SECOidTag* evOidPolicy,
/*optional out*/ OCSPStaplingStatus* ocspStaplingStatus, /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus,
/*optional out*/ KeySizeStatus* keySizeStatus, /*optional out*/ KeySizeStatus* keySizeStatus,
@@ -422,7 +422,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch, NetscapeStepUpPolicy::NeverMatch,
firstPartyDomain, originAttributes,
builtChain, nullptr, nullptr); builtChain, nullptr, nullptr);
rv = BuildCertChain(trustDomain, certDER, time, rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity, EndEntityOrCA::MustBeEndEntity,
@@ -496,7 +496,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
mCertShortLifetimeInDays, mPinningMode, MIN_RSA_BITS, mCertShortLifetimeInDays, mPinningMode, MIN_RSA_BITS,
ValidityCheckingMode::CheckForEV, ValidityCheckingMode::CheckForEV,
sha1ModeConfigurations[i], mNetscapeStepUpPolicy, sha1ModeConfigurations[i], mNetscapeStepUpPolicy,
firstPartyDomain, builtChain, pinningTelemetryInfo, originAttributes, builtChain, pinningTelemetryInfo,
hostname); hostname);
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time, rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
KeyUsage::digitalSignature,// (EC)DHE KeyUsage::digitalSignature,// (EC)DHE
@@ -584,7 +584,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
sha1ModeConfigurations[j], sha1ModeConfigurations[j],
mNetscapeStepUpPolicy, mNetscapeStepUpPolicy,
firstPartyDomain, builtChain, originAttributes, builtChain,
pinningTelemetryInfo, hostname); pinningTelemetryInfo, hostname);
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time, rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
KeyUsage::digitalSignature,//(EC)DHE KeyUsage::digitalSignature,//(EC)DHE
@@ -649,7 +649,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
pinningDisabled, MIN_RSA_BITS_WEAK, pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, mNetscapeStepUpPolicy, SHA1Mode::Allowed, mNetscapeStepUpPolicy,
firstPartyDomain, builtChain, nullptr, originAttributes, builtChain, nullptr,
nullptr); nullptr);
rv = BuildCertChain(trustDomain, certDER, time, rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeCA, KeyUsage::keyCertSign, EndEntityOrCA::MustBeCA, KeyUsage::keyCertSign,
@@ -666,7 +666,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch, NetscapeStepUpPolicy::NeverMatch,
firstPartyDomain, builtChain, nullptr, originAttributes, builtChain, nullptr,
nullptr); nullptr);
rv = BuildCertChain(trustDomain, certDER, time, rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity, EndEntityOrCA::MustBeEndEntity,
@@ -694,7 +694,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch, NetscapeStepUpPolicy::NeverMatch,
firstPartyDomain, builtChain, nullptr, originAttributes, builtChain, nullptr,
nullptr); nullptr);
rv = BuildCertChain(trustDomain, certDER, time, rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity, EndEntityOrCA::MustBeEndEntity,
@@ -719,7 +719,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch, NetscapeStepUpPolicy::NeverMatch,
firstPartyDomain, builtChain, nullptr, originAttributes, builtChain, nullptr,
nullptr); nullptr);
rv = BuildCertChain(trustDomain, certDER, time, rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity, EndEntityOrCA::MustBeEndEntity,
@@ -753,7 +753,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch, NetscapeStepUpPolicy::NeverMatch,
firstPartyDomain, builtChain, nullptr, originAttributes, builtChain, nullptr,
nullptr); nullptr);
rv = BuildCertChain(sslTrust, certDER, time, endEntityOrCA, rv = BuildCertChain(sslTrust, certDER, time, endEntityOrCA,
keyUsage, eku, CertPolicyId::anyPolicy, keyUsage, eku, CertPolicyId::anyPolicy,
@@ -766,7 +766,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch, NetscapeStepUpPolicy::NeverMatch,
firstPartyDomain, builtChain, nullptr, originAttributes, builtChain, nullptr,
nullptr); nullptr);
rv = BuildCertChain(emailTrust, certDER, time, endEntityOrCA, rv = BuildCertChain(emailTrust, certDER, time, endEntityOrCA,
keyUsage, eku, CertPolicyId::anyPolicy, keyUsage, eku, CertPolicyId::anyPolicy,
@@ -781,7 +781,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
ValidityCheckingMode::CheckingOff, ValidityCheckingMode::CheckingOff,
SHA1Mode::Allowed, SHA1Mode::Allowed,
NetscapeStepUpPolicy::NeverMatch, NetscapeStepUpPolicy::NeverMatch,
firstPartyDomain, builtChain, originAttributes, builtChain,
nullptr, nullptr); nullptr, nullptr);
rv = BuildCertChain(objectSigningTrust, certDER, time, rv = BuildCertChain(objectSigningTrust, certDER, time,
endEntityOrCA, keyUsage, eku, endEntityOrCA, keyUsage, eku,
@@ -813,7 +813,7 @@ CertVerifier::VerifySSLServerCert(const UniqueCERTCertificate& peerCert,
/*out*/ UniqueCERTCertList& builtChain, /*out*/ UniqueCERTCertList& builtChain,
/*optional*/ bool saveIntermediatesInPermanentDatabase, /*optional*/ bool saveIntermediatesInPermanentDatabase,
/*optional*/ Flags flags, /*optional*/ Flags flags,
/*optional*/ const char* firstPartyDomain, /*optional*/ const NeckoOriginAttributes& originAttributes,
/*optional out*/ SECOidTag* evOidPolicy, /*optional out*/ SECOidTag* evOidPolicy,
/*optional out*/ OCSPStaplingStatus* ocspStaplingStatus, /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus,
/*optional out*/ KeySizeStatus* keySizeStatus, /*optional out*/ KeySizeStatus* keySizeStatus,
@@ -838,7 +838,7 @@ CertVerifier::VerifySSLServerCert(const UniqueCERTCertificate& peerCert,
// if VerifyCert succeeded. // if VerifyCert succeeded.
Result rv = VerifyCert(peerCert.get(), certificateUsageSSLServer, time, Result rv = VerifyCert(peerCert.get(), certificateUsageSSLServer, time,
pinarg, hostname, builtChain, flags, pinarg, hostname, builtChain, flags,
stapledOCSPResponse, sctsFromTLS, firstPartyDomain, stapledOCSPResponse, sctsFromTLS, originAttributes,
evOidPolicy, ocspStaplingStatus, keySizeStatus, evOidPolicy, ocspStaplingStatus, keySizeStatus,
sha1ModeResult, pinningTelemetryInfo, ctInfo); sha1ModeResult, pinningTelemetryInfo, ctInfo);
if (rv != Success) { if (rv != Success) {

View File

@@ -11,6 +11,7 @@
#include "CTVerifyResult.h" #include "CTVerifyResult.h"
#include "OCSPCache.h" #include "OCSPCache.h"
#include "ScopedNSSTypes.h" #include "ScopedNSSTypes.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "pkix/pkixtypes.h" #include "pkix/pkixtypes.h"
@@ -109,7 +110,8 @@ public:
Flags flags = 0, Flags flags = 0,
/*optional in*/ const SECItem* stapledOCSPResponse = nullptr, /*optional in*/ const SECItem* stapledOCSPResponse = nullptr,
/*optional in*/ const SECItem* sctsFromTLS = nullptr, /*optional in*/ const SECItem* sctsFromTLS = nullptr,
/*optional in*/ const char* firstPartyDomain = nullptr, /*optional in*/ const NeckoOriginAttributes& originAttributes =
NeckoOriginAttributes(),
/*optional out*/ SECOidTag* evOidPolicy = nullptr, /*optional out*/ SECOidTag* evOidPolicy = nullptr,
/*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr, /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
/*optional out*/ KeySizeStatus* keySizeStatus = nullptr, /*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
@@ -127,7 +129,8 @@ public:
/*out*/ UniqueCERTCertList& builtChain, /*out*/ UniqueCERTCertList& builtChain,
/*optional*/ bool saveIntermediatesInPermanentDatabase = false, /*optional*/ bool saveIntermediatesInPermanentDatabase = false,
/*optional*/ Flags flags = 0, /*optional*/ Flags flags = 0,
/*optional*/ const char* firstPartyDomain = nullptr, /*optional*/ const NeckoOriginAttributes& originAttributes =
NeckoOriginAttributes(),
/*optional out*/ SECOidTag* evOidPolicy = nullptr, /*optional out*/ SECOidTag* evOidPolicy = nullptr,
/*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr, /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
/*optional out*/ KeySizeStatus* keySizeStatus = nullptr, /*optional out*/ KeySizeStatus* keySizeStatus = nullptr,

View File

@@ -57,7 +57,7 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
ValidityCheckingMode validityCheckingMode, ValidityCheckingMode validityCheckingMode,
CertVerifier::SHA1Mode sha1Mode, CertVerifier::SHA1Mode sha1Mode,
NetscapeStepUpPolicy netscapeStepUpPolicy, NetscapeStepUpPolicy netscapeStepUpPolicy,
const char* firstPartyDomain, const NeckoOriginAttributes& originAttributes,
UniqueCERTCertList& builtChain, UniqueCERTCertList& builtChain,
/*optional*/ PinningTelemetryInfo* pinningTelemetryInfo, /*optional*/ PinningTelemetryInfo* pinningTelemetryInfo,
/*optional*/ const char* hostname) /*optional*/ const char* hostname)
@@ -72,7 +72,7 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
, mValidityCheckingMode(validityCheckingMode) , mValidityCheckingMode(validityCheckingMode)
, mSHA1Mode(sha1Mode) , mSHA1Mode(sha1Mode)
, mNetscapeStepUpPolicy(netscapeStepUpPolicy) , mNetscapeStepUpPolicy(netscapeStepUpPolicy)
, mFirstPartyDomain(firstPartyDomain) , mOriginAttributes(originAttributes)
, mBuiltChain(builtChain) , mBuiltChain(builtChain)
, mPinningTelemetryInfo(pinningTelemetryInfo) , mPinningTelemetryInfo(pinningTelemetryInfo)
, mHostname(hostname) , mHostname(hostname)
@@ -415,7 +415,7 @@ NSSCertDBTrustDomain::CheckRevocation(EndEntityOrCA endEntityOrCA,
Result cachedResponseResult = Success; Result cachedResponseResult = Success;
Time cachedResponseValidThrough(Time::uninitialized); Time cachedResponseValidThrough(Time::uninitialized);
bool cachedResponsePresent = mOCSPCache.Get(certID, mFirstPartyDomain, bool cachedResponsePresent = mOCSPCache.Get(certID, mOriginAttributes,
cachedResponseResult, cachedResponseResult,
cachedResponseValidThrough); cachedResponseValidThrough);
if (cachedResponsePresent) { if (cachedResponsePresent) {
@@ -558,7 +558,7 @@ NSSCertDBTrustDomain::CheckRevocation(EndEntityOrCA endEntityOrCA,
// Owned by arena // Owned by arena
SECItem* responseSECItem = nullptr; SECItem* responseSECItem = nullptr;
Result tempRV = Result tempRV =
DoOCSPRequest(arena, url, mFirstPartyDomain, &ocspRequestItem, DoOCSPRequest(arena, url, mOriginAttributes, &ocspRequestItem,
OCSPFetchingTypeToTimeoutTime(mOCSPFetching), OCSPFetchingTypeToTimeoutTime(mOCSPFetching),
mOCSPGetConfig == CertVerifier::ocspGetEnabled, mOCSPGetConfig == CertVerifier::ocspGetEnabled,
responseSECItem); responseSECItem);
@@ -582,7 +582,7 @@ NSSCertDBTrustDomain::CheckRevocation(EndEntityOrCA endEntityOrCA,
if (timeout.AddSeconds(ServerFailureDelaySeconds) != Success) { if (timeout.AddSeconds(ServerFailureDelaySeconds) != Success) {
return Result::FATAL_ERROR_LIBRARY_FAILURE; // integer overflow return Result::FATAL_ERROR_LIBRARY_FAILURE; // integer overflow
} }
rv = mOCSPCache.Put(certID, mFirstPartyDomain, error, time, timeout); rv = mOCSPCache.Put(certID, mOriginAttributes, error, time, timeout);
if (rv != Success) { if (rv != Success) {
return rv; return rv;
} }
@@ -687,7 +687,7 @@ NSSCertDBTrustDomain::VerifyAndMaybeCacheEncodedOCSPResponse(
rv == Result::ERROR_OCSP_UNKNOWN_CERT) { rv == Result::ERROR_OCSP_UNKNOWN_CERT) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain: caching OCSP response")); ("NSSCertDBTrustDomain: caching OCSP response"));
Result putRV = mOCSPCache.Put(certID, mFirstPartyDomain, rv, thisUpdate, Result putRV = mOCSPCache.Put(certID, mOriginAttributes, rv, thisUpdate,
validThrough); validThrough);
if (putRV != Success) { if (putRV != Success) {
return putRV; return putRV;

View File

@@ -9,6 +9,7 @@
#include "CertVerifier.h" #include "CertVerifier.h"
#include "ScopedNSSTypes.h" #include "ScopedNSSTypes.h"
#include "mozilla/BasePrincipal.h"
#include "nsICertBlocklist.h" #include "nsICertBlocklist.h"
#include "nsString.h" #include "nsString.h"
#include "pkix/pkixtypes.h" #include "pkix/pkixtypes.h"
@@ -80,7 +81,7 @@ public:
ValidityCheckingMode validityCheckingMode, ValidityCheckingMode validityCheckingMode,
CertVerifier::SHA1Mode sha1Mode, CertVerifier::SHA1Mode sha1Mode,
NetscapeStepUpPolicy netscapeStepUpPolicy, NetscapeStepUpPolicy netscapeStepUpPolicy,
const char* firstPartyDomain, const NeckoOriginAttributes& originAttributes,
UniqueCERTCertList& builtChain, UniqueCERTCertList& builtChain,
/*optional*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr, /*optional*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
/*optional*/ const char* hostname = nullptr); /*optional*/ const char* hostname = nullptr);
@@ -184,7 +185,7 @@ private:
ValidityCheckingMode mValidityCheckingMode; ValidityCheckingMode mValidityCheckingMode;
CertVerifier::SHA1Mode mSHA1Mode; CertVerifier::SHA1Mode mSHA1Mode;
NetscapeStepUpPolicy mNetscapeStepUpPolicy; NetscapeStepUpPolicy mNetscapeStepUpPolicy;
const char* mFirstPartyDomain; const NeckoOriginAttributes& mOriginAttributes;
UniqueCERTCertList& mBuiltChain; // non-owning UniqueCERTCertList& mBuiltChain; // non-owning
PinningTelemetryInfo* mPinningTelemetryInfo; PinningTelemetryInfo* mPinningTelemetryInfo;
const char* mHostname; // non-owning - only used for pinning checks const char* mHostname; // non-owning - only used for pinning checks

View File

@@ -56,20 +56,21 @@ DigestLength(UniquePK11Context& context, uint32_t length)
return PK11_DigestOp(context.get(), array, MOZ_ARRAY_LENGTH(array)); return PK11_DigestOp(context.get(), array, MOZ_ARRAY_LENGTH(array));
} }
// Let derIssuer be the DER encoding of the issuer of aCert. // Let derIssuer be the DER encoding of the issuer of certID.
// Let derPublicKey be the DER encoding of the public key of aIssuerCert. // Let derPublicKey be the DER encoding of the public key of certID.
// Let serialNumber be the bytes of the serial number of aCert. // Let serialNumber be the bytes of the serial number of certID.
// Let serialNumberLen be the number of bytes of serialNumber. // Let serialNumberLen be the number of bytes of serialNumber.
// The first party domain is only non-empty when "privacy.firstParty.isolate" // Let firstPartyDomain be the first party domain of originAttributes.
// is enabled, in order to isolate OCSP cache by first party. // 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 firstPartyDomainLen be the number of bytes of firstPartyDomain.
// The value calculated is SHA384(derIssuer || derPublicKey || serialNumberLen // The value calculated is SHA384(derIssuer || derPublicKey || serialNumberLen
// || serialNumber || firstPartyDomainLen || firstPartyDomain). // || serialNumber || firstPartyDomainLen || firstPartyDomain).
// Because the DER encodings include the length of the data encoded, and we also // Because the DER encodings include the length of the data encoded, and we also
// include the length of serialNumber and firstPartyDomain, there do not exist // include the length of serialNumber and originAttributes, there do not exist
// A(derIssuerA, derPublicKeyA, serialNumberLenA, serialNumberA, // A(derIssuerA, derPublicKeyA, serialNumberLenA, serialNumberA,
// firstPartyDomainLenA, firstPartyDomainA) and B(derIssuerB, derPublicKeyB, // originAttributesLenA, originAttributesA) and B(derIssuerB, derPublicKeyB,
// serialNumberLenB, serialNumberB, firstPartyDomainLenB, firstPartyDomainB) // serialNumberLenB, serialNumberB, originAttributesLenB, originAttributesB)
// such that the concatenation of each tuple results in the same string of // such that the concatenation of each tuple results in the same string of
// bytes but where each part in A is not equal to its counterpart in B. This is // bytes but where each part in A is not equal to its counterpart in B. This is
// important because as a result it is computationally infeasible to find // important because as a result it is computationally infeasible to find
@@ -77,7 +78,7 @@ DigestLength(UniquePK11Context& context, uint32_t length)
// cryptographically-secure hash function). // cryptographically-secure hash function).
static SECStatus static SECStatus
CertIDHash(SHA384Buffer& buf, const CertID& certID, CertIDHash(SHA384Buffer& buf, const CertID& certID,
const char* firstPartyDomain) const NeckoOriginAttributes& originAttributes)
{ {
UniquePK11Context context(PK11_CreateDigestContext(SEC_OID_SHA384)); UniquePK11Context context(PK11_CreateDigestContext(SEC_OID_SHA384));
if (!context) { if (!context) {
@@ -110,15 +111,17 @@ CertIDHash(SHA384Buffer& buf, const CertID& certID,
if (rv != SECSuccess) { if (rv != SECSuccess) {
return rv; return rv;
} }
if (firstPartyDomain) {
uint32_t firstPartyDomainLen = strlen(firstPartyDomain); // OCSP should not be isolated by containers.
rv = DigestLength(context, firstPartyDomainLen); NS_ConvertUTF16toUTF8 firstPartyDomain(originAttributes.mFirstPartyDomain);
if (!firstPartyDomain.IsEmpty()) {
rv = DigestLength(context, firstPartyDomain.Length());
if (rv != SECSuccess) { if (rv != SECSuccess) {
return rv; return rv;
} }
rv = PK11_DigestOp(context.get(), rv = PK11_DigestOp(context.get(),
BitwiseCast<const unsigned char*>(firstPartyDomain), BitwiseCast<const unsigned char*>(firstPartyDomain.get()),
firstPartyDomainLen); firstPartyDomain.Length());
if (rv != SECSuccess) { if (rv != SECSuccess) {
return rv; return rv;
} }
@@ -132,9 +135,10 @@ CertIDHash(SHA384Buffer& buf, const CertID& certID,
} }
Result Result
OCSPCache::Entry::Init(const CertID& aCertID, const char* aFirstPartyDomain) OCSPCache::Entry::Init(const CertID& aCertID,
const NeckoOriginAttributes& aOriginAttributes)
{ {
SECStatus srv = CertIDHash(mIDHash, aCertID, aFirstPartyDomain); SECStatus srv = CertIDHash(mIDHash, aCertID, aOriginAttributes);
if (srv != SECSuccess) { if (srv != SECSuccess) {
return MapPRErrorCodeToResult(PR_GetError()); return MapPRErrorCodeToResult(PR_GetError());
} }
@@ -154,7 +158,8 @@ OCSPCache::~OCSPCache()
// Returns false with index in an undefined state if no matching entry was // Returns false with index in an undefined state if no matching entry was
// found. // found.
bool bool
OCSPCache::FindInternal(const CertID& aCertID, const char* aFirstPartyDomain, OCSPCache::FindInternal(const CertID& aCertID,
const NeckoOriginAttributes& aOriginAttributes,
/*out*/ size_t& index, /*out*/ size_t& index,
const MutexAutoLock& /* aProofOfLock */) const MutexAutoLock& /* aProofOfLock */)
{ {
@@ -163,7 +168,7 @@ OCSPCache::FindInternal(const CertID& aCertID, const char* aFirstPartyDomain,
} }
SHA384Buffer idHash; SHA384Buffer idHash;
SECStatus rv = CertIDHash(idHash, aCertID, aFirstPartyDomain); SECStatus rv = CertIDHash(idHash, aCertID, aOriginAttributes);
if (rv != SECSuccess) { if (rv != SECSuccess) {
return false; return false;
} }
@@ -182,10 +187,11 @@ OCSPCache::FindInternal(const CertID& aCertID, const char* aFirstPartyDomain,
static inline void static inline void
LogWithCertID(const char* aMessage, const CertID& aCertID, LogWithCertID(const char* aMessage, const CertID& aCertID,
const char* aFirstPartyDomain) const NeckoOriginAttributes& aOriginAttributes)
{ {
NS_ConvertUTF16toUTF8 firstPartyDomain(aOriginAttributes.mFirstPartyDomain);
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
(aMessage, &aCertID, aFirstPartyDomain)); (aMessage, &aCertID, firstPartyDomain.get()));
} }
void void
@@ -202,19 +208,20 @@ OCSPCache::MakeMostRecentlyUsed(size_t aIndex,
} }
bool bool
OCSPCache::Get(const CertID& aCertID, const char* aFirstPartyDomain, OCSPCache::Get(const CertID& aCertID,
const NeckoOriginAttributes& aOriginAttributes,
Result& aResult, Time& aValidThrough) Result& aResult, Time& aValidThrough)
{ {
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
size_t index; size_t index;
if (!FindInternal(aCertID, aFirstPartyDomain, index, lock)) { if (!FindInternal(aCertID, aOriginAttributes, index, lock)) {
LogWithCertID("OCSPCache::Get(%p,\"%s\") not in cache", aCertID, LogWithCertID("OCSPCache::Get(%p,\"%s\") not in cache", aCertID,
aFirstPartyDomain); aOriginAttributes);
return false; return false;
} }
LogWithCertID("OCSPCache::Get(%p,\"%s\") in cache", aCertID, LogWithCertID("OCSPCache::Get(%p,\"%s\") in cache", aCertID,
aFirstPartyDomain); aOriginAttributes);
aResult = mEntries[index]->mResult; aResult = mEntries[index]->mResult;
aValidThrough = mEntries[index]->mValidThrough; aValidThrough = mEntries[index]->mValidThrough;
MakeMostRecentlyUsed(index, lock); MakeMostRecentlyUsed(index, lock);
@@ -222,17 +229,18 @@ OCSPCache::Get(const CertID& aCertID, const char* aFirstPartyDomain,
} }
Result Result
OCSPCache::Put(const CertID& aCertID, const char* aFirstPartyDomain, OCSPCache::Put(const CertID& aCertID,
const NeckoOriginAttributes& aOriginAttributes,
Result aResult, Time aThisUpdate, Time aValidThrough) Result aResult, Time aThisUpdate, Time aValidThrough)
{ {
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
size_t index; size_t index;
if (FindInternal(aCertID, aFirstPartyDomain, index, lock)) { if (FindInternal(aCertID, aOriginAttributes, index, lock)) {
// Never replace an entry indicating a revoked certificate. // Never replace an entry indicating a revoked certificate.
if (mEntries[index]->mResult == Result::ERROR_REVOKED_CERTIFICATE) { if (mEntries[index]->mResult == Result::ERROR_REVOKED_CERTIFICATE) {
LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache as revoked - " LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache as revoked - "
"not replacing", aCertID, aFirstPartyDomain); "not replacing", aCertID, aOriginAttributes);
MakeMostRecentlyUsed(index, lock); MakeMostRecentlyUsed(index, lock);
return Success; return Success;
} }
@@ -243,7 +251,7 @@ OCSPCache::Put(const CertID& aCertID, const char* aFirstPartyDomain,
aResult != Result::ERROR_REVOKED_CERTIFICATE) { aResult != Result::ERROR_REVOKED_CERTIFICATE) {
LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache with more " LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache with more "
"recent validity - not replacing", aCertID, "recent validity - not replacing", aCertID,
aFirstPartyDomain); aOriginAttributes);
MakeMostRecentlyUsed(index, lock); MakeMostRecentlyUsed(index, lock);
return Success; return Success;
} }
@@ -255,13 +263,13 @@ OCSPCache::Put(const CertID& aCertID, const char* aFirstPartyDomain,
aResult != Result::ERROR_REVOKED_CERTIFICATE) { aResult != Result::ERROR_REVOKED_CERTIFICATE) {
LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache - not " LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache - not "
"replacing with less important status", aCertID, "replacing with less important status", aCertID,
aFirstPartyDomain); aOriginAttributes);
MakeMostRecentlyUsed(index, lock); MakeMostRecentlyUsed(index, lock);
return Success; return Success;
} }
LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache - replacing", LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache - replacing",
aCertID, aFirstPartyDomain); aCertID, aOriginAttributes);
mEntries[index]->mResult = aResult; mEntries[index]->mResult = aResult;
mEntries[index]->mThisUpdate = aThisUpdate; mEntries[index]->mThisUpdate = aThisUpdate;
mEntries[index]->mValidThrough = aValidThrough; mEntries[index]->mValidThrough = aValidThrough;
@@ -271,7 +279,7 @@ OCSPCache::Put(const CertID& aCertID, const char* aFirstPartyDomain,
if (mEntries.length() == MaxEntries) { if (mEntries.length() == MaxEntries) {
LogWithCertID("OCSPCache::Put(%p, \"%s\") too full - evicting an entry", LogWithCertID("OCSPCache::Put(%p, \"%s\") too full - evicting an entry",
aCertID, aFirstPartyDomain); aCertID, aOriginAttributes);
for (Entry** toEvict = mEntries.begin(); toEvict != mEntries.end(); for (Entry** toEvict = mEntries.begin(); toEvict != mEntries.end();
toEvict++) { toEvict++) {
// Never evict an entry that indicates a revoked or unknokwn certificate, // Never evict an entry that indicates a revoked or unknokwn certificate,
@@ -303,7 +311,7 @@ OCSPCache::Put(const CertID& aCertID, const char* aFirstPartyDomain,
if (!newEntry) { if (!newEntry) {
return Result::FATAL_ERROR_NO_MEMORY; return Result::FATAL_ERROR_NO_MEMORY;
} }
Result rv = newEntry->Init(aCertID, aFirstPartyDomain); Result rv = newEntry->Init(aCertID, aOriginAttributes);
if (rv != Success) { if (rv != Success) {
delete newEntry; delete newEntry;
return rv; return rv;
@@ -313,7 +321,7 @@ OCSPCache::Put(const CertID& aCertID, const char* aFirstPartyDomain,
return Result::FATAL_ERROR_NO_MEMORY; return Result::FATAL_ERROR_NO_MEMORY;
} }
LogWithCertID("OCSPCache::Put(%p, \"%s\") added to cache", aCertID, LogWithCertID("OCSPCache::Put(%p, \"%s\") added to cache", aCertID,
aFirstPartyDomain); aOriginAttributes);
return Success; return Success;
} }

View File

@@ -33,6 +33,10 @@
#include "prerror.h" #include "prerror.h"
#include "seccomon.h" #include "seccomon.h"
namespace mozilla {
class NeckoOriginAttributes;
}
namespace mozilla { namespace pkix { namespace mozilla { namespace pkix {
struct CertID; struct CertID;
} } // namespace mozilla::pkix } } // namespace mozilla::pkix
@@ -56,18 +60,17 @@ public:
// Returns true if the status of the given certificate (issued by the given // Returns true if the status of the given certificate (issued by the given
// issuer) is in the cache, and false otherwise. // issuer) is in the cache, and false otherwise.
// The first party domain is only non-empty when "privacy.firstParty.isolate"
// is enabled, in order to isolate OCSP cache by first party.
// If it is in the cache, returns by reference the error code of the cached // If it is in the cache, returns by reference the error code of the cached
// status and the time through which the status is considered trustworthy. // status and the time through which the status is considered trustworthy.
// The passed in origin attributes are used to isolate the OCSP cache.
// We currently only use the first party domain portion of the attributes, and
// it is non-empty only when "privacy.firstParty.isolate" is enabled.
bool Get(const mozilla::pkix::CertID& aCertID, bool Get(const mozilla::pkix::CertID& aCertID,
const char* aFirstPartyDomain, const NeckoOriginAttributes& aOriginAttributes,
/*out*/ mozilla::pkix::Result& aResult, /*out*/ mozilla::pkix::Result& aResult,
/*out*/ mozilla::pkix::Time& aValidThrough); /*out*/ mozilla::pkix::Time& aValidThrough);
// Caches the status of the given certificate (issued by the given issuer). // Caches the status of the given certificate (issued by the given issuer).
// The first party domain is only non-empty when "privacy.firstParty.isolate"
// is enabled, in order to isolate OCSP cache by first party.
// The status is considered trustworthy through the given time. // The status is considered trustworthy through the given time.
// A status with an error code of SEC_ERROR_REVOKED_CERTIFICATE will not // A status with an error code of SEC_ERROR_REVOKED_CERTIFICATE will not
// be replaced or evicted. // be replaced or evicted.
@@ -76,8 +79,11 @@ public:
// A status with a more recent thisUpdate will not be replaced with a // A status with a more recent thisUpdate will not be replaced with a
// status with a less recent thisUpdate unless the less recent status // status with a less recent thisUpdate unless the less recent status
// indicates the certificate is revoked. // indicates the certificate is revoked.
// The passed in origin attributes are used to isolate the OCSP cache.
// We currently only use the first party domain portion of the attributes, and
// it is non-empty only when "privacy.firstParty.isolate" is enabled.
mozilla::pkix::Result Put(const mozilla::pkix::CertID& aCertID, mozilla::pkix::Result Put(const mozilla::pkix::CertID& aCertID,
const char* aFirstPartyDomain, const NeckoOriginAttributes& aOriginAttributes,
mozilla::pkix::Result aResult, mozilla::pkix::Result aResult,
mozilla::pkix::Time aThisUpdate, mozilla::pkix::Time aThisUpdate,
mozilla::pkix::Time aValidThrough); mozilla::pkix::Time aValidThrough);
@@ -98,7 +104,7 @@ private:
{ {
} }
mozilla::pkix::Result Init(const mozilla::pkix::CertID& aCertID, mozilla::pkix::Result Init(const mozilla::pkix::CertID& aCertID,
const char* aFirstPartyDomain); const NeckoOriginAttributes& aOriginAttributes);
mozilla::pkix::Result mResult; mozilla::pkix::Result mResult;
mozilla::pkix::Time mThisUpdate; mozilla::pkix::Time mThisUpdate;
@@ -112,7 +118,7 @@ private:
}; };
bool FindInternal(const mozilla::pkix::CertID& aCertID, bool FindInternal(const mozilla::pkix::CertID& aCertID,
const char* aFirstPartyDomain, const NeckoOriginAttributes& aOriginAttributes,
/*out*/ size_t& index, /*out*/ size_t& index,
const MutexAutoLock& aProofOfLock); const MutexAutoLock& aProofOfLock);
void MakeMostRecentlyUsed(size_t aIndex, const MutexAutoLock& aProofOfLock); void MakeMostRecentlyUsed(size_t aIndex, const MutexAutoLock& aProofOfLock);

View File

@@ -74,8 +74,9 @@ AppendEscapedBase64Item(const SECItem* encodedRequest, nsACString& path)
Result Result
DoOCSPRequest(const UniquePLArenaPool& arena, const char* url, DoOCSPRequest(const UniquePLArenaPool& arena, const char* url,
const char* firstPartyDomain, const SECItem* encodedRequest, const NeckoOriginAttributes& originAttributes,
PRIntervalTime timeout, bool useGET, const SECItem* encodedRequest, PRIntervalTime timeout,
bool useGET,
/*out*/ SECItem*& encodedResponse) /*out*/ SECItem*& encodedResponse)
{ {
MOZ_ASSERT(arena.get()); MOZ_ASSERT(arena.get());
@@ -173,7 +174,7 @@ DoOCSPRequest(const UniquePLArenaPool& arena, const char* url,
nsNSSHttpRequestSession* requestSessionPtr; nsNSSHttpRequestSession* requestSessionPtr;
rv = nsNSSHttpInterface::createFcn(serverSession.get(), "http", path.get(), rv = nsNSSHttpInterface::createFcn(serverSession.get(), "http", path.get(),
method.get(), firstPartyDomain, timeout, method.get(), originAttributes, timeout,
&requestSessionPtr); &requestSessionPtr);
if (rv != Success) { if (rv != Success) {
return rv; return rv;

View File

@@ -10,11 +10,15 @@
#include "CertVerifier.h" #include "CertVerifier.h"
#include "secmodt.h" #include "secmodt.h"
namespace mozilla {
class NeckoOriginAttributes;
}
namespace mozilla { namespace psm { namespace mozilla { namespace psm {
// The memory returned via |encodedResponse| is owned by the given arena. // The memory returned via |encodedResponse| is owned by the given arena.
Result DoOCSPRequest(const UniquePLArenaPool& arena, const char* url, Result DoOCSPRequest(const UniquePLArenaPool& arena, const char* url,
const char* firstPartyDomain, const NeckoOriginAttributes& originAttributes,
const SECItem* encodedRequest, PRIntervalTime timeout, const SECItem* encodedRequest, PRIntervalTime timeout,
bool useGET, bool useGET,
/*out*/ SECItem*& encodedResponse); /*out*/ SECItem*& encodedResponse);

View File

@@ -1340,7 +1340,7 @@ AuthCertificate(CertVerifier& certVerifier,
infoObject->GetHostNameRaw(), infoObject->GetHostNameRaw(),
certList, saveIntermediates, certList, saveIntermediates,
flags, infoObject-> flags, infoObject->
GetFirstPartyDomainRaw(), GetOriginAttributes(),
&evOidPolicy, &evOidPolicy,
&ocspStaplingStatus, &ocspStaplingStatus,
&keySizeStatus, &sha1ModeResult, &keySizeStatus, &sha1ModeResult,

View File

@@ -99,9 +99,10 @@ TransportSecurityInfo::GetPort(int32_t *aPort)
} }
nsresult nsresult
TransportSecurityInfo::SetFirstPartyDomain(const nsACString& aFirstPartyDomain) TransportSecurityInfo::SetOriginAttributes(
const NeckoOriginAttributes& aOriginAttributes)
{ {
mFirstPartyDomain.Assign(aFirstPartyDomain); mOriginAttributes = aOriginAttributes;
return NS_OK; return NS_OK;
} }

View File

@@ -9,6 +9,7 @@
#include "ScopedNSSTypes.h" #include "ScopedNSSTypes.h"
#include "certt.h" #include "certt.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "nsDataHashtable.h" #include "nsDataHashtable.h"
@@ -62,8 +63,10 @@ public:
nsresult GetPort(int32_t *aPort); nsresult GetPort(int32_t *aPort);
nsresult SetPort(int32_t aPort); nsresult SetPort(int32_t aPort);
const char* GetFirstPartyDomainRaw() const { return mFirstPartyDomain.get(); } const NeckoOriginAttributes& GetOriginAttributes() const {
nsresult SetFirstPartyDomain(const nsACString& aFirstPartyDomain); return mOriginAttributes;
}
nsresult SetOriginAttributes(const NeckoOriginAttributes& aOriginAttributes);
PRErrorCode GetErrorCode() const; PRErrorCode GetErrorCode() const;
@@ -103,7 +106,7 @@ private:
int32_t mPort; int32_t mPort;
nsXPIDLCString mHostName; nsXPIDLCString mHostName;
nsCString mFirstPartyDomain; NeckoOriginAttributes mOriginAttributes;
/* SSL Status */ /* SSL Status */
RefPtr<nsSSLStatus> mSSLStatus; RefPtr<nsSSLStatus> mSSLStatus;

View File

@@ -114,10 +114,13 @@ nsHTTPDownloadEvent::Run()
chan->SetLoadFlags(nsIRequest::LOAD_ANONYMOUS | chan->SetLoadFlags(nsIRequest::LOAD_ANONYMOUS |
nsIChannel::LOAD_BYPASS_SERVICE_WORKER); nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
if (!mRequestSession->mFirstPartyDomain.IsEmpty()) { // For OCSP requests, only the first party domain aspect of origin attributes
// is used. This means that OCSP requests are shared across different
// containers.
if (mRequestSession->mOriginAttributes != NeckoOriginAttributes()) {
NeckoOriginAttributes attrs; NeckoOriginAttributes attrs;
attrs.mFirstPartyDomain = attrs.mFirstPartyDomain =
NS_ConvertUTF8toUTF16(mRequestSession->mFirstPartyDomain); mRequestSession->mOriginAttributes.mFirstPartyDomain;
nsCOMPtr<nsILoadInfo> loadInfo = chan->GetLoadInfo(); nsCOMPtr<nsILoadInfo> loadInfo = chan->GetLoadInfo();
if (loadInfo) { if (loadInfo) {
@@ -230,7 +233,7 @@ nsNSSHttpRequestSession::createFcn(const nsNSSHttpServerSession* session,
const char* http_protocol_variant, const char* http_protocol_variant,
const char* path_and_query_string, const char* path_and_query_string,
const char* http_request_method, const char* http_request_method,
const char* first_party_domain, const NeckoOriginAttributes& origin_attributes,
const PRIntervalTime timeout, const PRIntervalTime timeout,
/*out*/ nsNSSHttpRequestSession** pRequest) /*out*/ nsNSSHttpRequestSession** pRequest)
{ {
@@ -260,7 +263,7 @@ nsNSSHttpRequestSession::createFcn(const nsNSSHttpServerSession* session,
rs->mURL.AppendInt(session->mPort); rs->mURL.AppendInt(session->mPort);
rs->mURL.Append(path_and_query_string); rs->mURL.Append(path_and_query_string);
rs->mFirstPartyDomain.Assign(first_party_domain); rs->mOriginAttributes = origin_attributes;
rs->mRequestMethod = http_request_method; rs->mRequestMethod = http_request_method;
@@ -1169,7 +1172,7 @@ DetermineEVStatusAndSetNewCert(RefPtr<nsSSLStatus> sslStatus, PRFileDesc* fd,
unusedBuiltChain, unusedBuiltChain,
saveIntermediates, saveIntermediates,
flags, flags,
infoObject->GetFirstPartyDomainRaw(), infoObject->GetOriginAttributes(),
&evOidPolicy); &evOidPolicy);
RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(cert.get())); RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(cert.get()));

View File

@@ -8,6 +8,7 @@
#define nsNSSCallbacks_h #define nsNSSCallbacks_h
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/CondVar.h" #include "mozilla/CondVar.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
@@ -20,6 +21,8 @@
#include "ocspt.h" // Must be included after pk11func.h. #include "ocspt.h" // Must be included after pk11func.h.
using mozilla::NeckoOriginAttributes;
class nsILoadGroup; class nsILoadGroup;
char* char*
@@ -99,7 +102,7 @@ public:
const char* httpProtocolVariant, const char* httpProtocolVariant,
const char* pathAndQueryString, const char* pathAndQueryString,
const char* httpRequestMethod, const char* httpRequestMethod,
const char* firstPartyDomain, const NeckoOriginAttributes& originAttributes,
const PRIntervalTime timeout, const PRIntervalTime timeout,
/*out*/ nsNSSHttpRequestSession** pRequest); /*out*/ nsNSSHttpRequestSession** pRequest);
@@ -124,7 +127,7 @@ public:
nsCString mPostData; nsCString mPostData;
nsCString mPostContentType; nsCString mPostContentType;
nsCString mFirstPartyDomain; NeckoOriginAttributes mOriginAttributes;
PRIntervalTime mTimeoutInterval; PRIntervalTime mTimeoutInterval;
@@ -159,13 +162,13 @@ public:
const char* httpProtocolVariant, const char* httpProtocolVariant,
const char* pathAndQueryString, const char* pathAndQueryString,
const char* httpRequestMethod, const char* httpRequestMethod,
const char* firstPartyDomain, const NeckoOriginAttributes& originAttributes,
const PRIntervalTime timeout, const PRIntervalTime timeout,
/*out*/ nsNSSHttpRequestSession** pRequest) /*out*/ nsNSSHttpRequestSession** pRequest)
{ {
return nsNSSHttpRequestSession::createFcn(session, httpProtocolVariant, return nsNSSHttpRequestSession::createFcn(session, httpProtocolVariant,
pathAndQueryString, pathAndQueryString,
httpRequestMethod, firstPartyDomain, httpRequestMethod, originAttributes,
timeout, pRequest); timeout, pRequest);
} }

View File

@@ -1497,7 +1497,7 @@ VerifyCertAtTime(nsIX509Cert* aCert,
resultChain, resultChain,
false, // don't save intermediates false, // don't save intermediates
aFlags, aFlags,
nullptr, // firstPartyDomain NeckoOriginAttributes(),
&evOidPolicy); &evOidPolicy);
} else { } else {
result = certVerifier->VerifyCert(nssCert.get(), aUsage, aTime, result = certVerifier->VerifyCert(nssCert.get(), aUsage, aTime,
@@ -1507,7 +1507,7 @@ VerifyCertAtTime(nsIX509Cert* aCert,
aFlags, aFlags,
nullptr, // stapledOCSPResponse nullptr, // stapledOCSPResponse
nullptr, // sctsFromTLSExtension nullptr, // sctsFromTLSExtension
nullptr, // firstPartyDomain NeckoOriginAttributes(),
&evOidPolicy); &evOidPolicy);
} }

View File

@@ -1860,7 +1860,7 @@ nsSSLIOLayerNewSocket(int32_t family,
const char* host, const char* host,
int32_t port, int32_t port,
nsIProxyInfo *proxy, nsIProxyInfo *proxy,
const nsACString& firstPartyDomain, const NeckoOriginAttributes& originAttributes,
PRFileDesc** fd, PRFileDesc** fd,
nsISupports** info, nsISupports** info,
bool forSTARTTLS, bool forSTARTTLS,
@@ -1871,7 +1871,7 @@ nsSSLIOLayerNewSocket(int32_t family,
if (!sock) return NS_ERROR_OUT_OF_MEMORY; if (!sock) return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxy, nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxy,
firstPartyDomain, sock, info, originAttributes, sock, info,
forSTARTTLS, flags); forSTARTTLS, flags);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
PR_Close(sock); PR_Close(sock);
@@ -2578,7 +2578,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
const char* host, const char* host,
int32_t port, int32_t port,
nsIProxyInfo* proxy, nsIProxyInfo* proxy,
const nsACString& firstPartyDomain, const NeckoOriginAttributes& originAttributes,
PRFileDesc* fd, PRFileDesc* fd,
nsISupports** info, nsISupports** info,
bool forSTARTTLS, bool forSTARTTLS,
@@ -2599,7 +2599,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
infoObject->SetForSTARTTLS(forSTARTTLS); infoObject->SetForSTARTTLS(forSTARTTLS);
infoObject->SetHostName(host); infoObject->SetHostName(host);
infoObject->SetPort(port); infoObject->SetPort(port);
infoObject->SetFirstPartyDomain(firstPartyDomain); infoObject->SetOriginAttributes(originAttributes);
bool haveProxy = false; bool haveProxy = false;
if (proxy) { if (proxy) {

View File

@@ -19,11 +19,14 @@
#include "sslt.h" #include "sslt.h"
namespace mozilla { namespace mozilla {
class NeckoOriginAttributes;
namespace psm { namespace psm {
class SharedSSLState; class SharedSSLState;
} // namespace psm } // namespace psm
} // namespace mozilla } // namespace mozilla
using mozilla::NeckoOriginAttributes;
class nsIObserver; class nsIObserver;
class nsNSSSocketInfo final : public mozilla::psm::TransportSecurityInfo, class nsNSSSocketInfo final : public mozilla::psm::TransportSecurityInfo,
@@ -238,7 +241,7 @@ nsresult nsSSLIOLayerNewSocket(int32_t family,
const char* host, const char* host,
int32_t port, int32_t port,
nsIProxyInfo *proxy, nsIProxyInfo *proxy,
const nsACString& firstPartyDomain, const NeckoOriginAttributes& originAttributes,
PRFileDesc** fd, PRFileDesc** fd,
nsISupports** securityInfo, nsISupports** securityInfo,
bool forSTARTTLS, bool forSTARTTLS,
@@ -248,7 +251,7 @@ nsresult nsSSLIOLayerAddToSocket(int32_t family,
const char* host, const char* host,
int32_t port, int32_t port,
nsIProxyInfo *proxy, nsIProxyInfo *proxy,
const nsACString& firstPartyDomain, const NeckoOriginAttributes& originAttributes,
PRFileDesc* fd, PRFileDesc* fd,
nsISupports** securityInfo, nsISupports** securityInfo,
bool forSTARTTLS, bool forSTARTTLS,

View File

@@ -4,10 +4,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/BasePrincipal.h"
#include "nsSSLSocketProvider.h" #include "nsSSLSocketProvider.h"
#include "nsNSSIOLayer.h" #include "nsNSSIOLayer.h"
#include "nsError.h" #include "nsError.h"
using mozilla::NeckoOriginAttributes;
nsSSLSocketProvider::nsSSLSocketProvider() nsSSLSocketProvider::nsSSLSocketProvider()
{ {
} }
@@ -23,7 +26,7 @@ nsSSLSocketProvider::NewSocket(int32_t family,
const char *host, const char *host,
int32_t port, int32_t port,
nsIProxyInfo *proxy, nsIProxyInfo *proxy,
const nsACString &firstPartyDomain, const NeckoOriginAttributes &originAttributes,
uint32_t flags, uint32_t flags,
PRFileDesc **_result, PRFileDesc **_result,
nsISupports **securityInfo) nsISupports **securityInfo)
@@ -32,7 +35,7 @@ nsSSLSocketProvider::NewSocket(int32_t family,
host, host,
port, port,
proxy, proxy,
firstPartyDomain, originAttributes,
_result, _result,
securityInfo, securityInfo,
false, false,
@@ -46,7 +49,7 @@ nsSSLSocketProvider::AddToSocket(int32_t family,
const char *host, const char *host,
int32_t port, int32_t port,
nsIProxyInfo *proxy, nsIProxyInfo *proxy,
const nsACString &firstPartyDomain, const NeckoOriginAttributes &originAttributes,
uint32_t flags, uint32_t flags,
PRFileDesc *aSocket, PRFileDesc *aSocket,
nsISupports **securityInfo) nsISupports **securityInfo)
@@ -55,7 +58,7 @@ nsSSLSocketProvider::AddToSocket(int32_t family,
host, host,
port, port,
proxy, proxy,
firstPartyDomain, originAttributes,
aSocket, aSocket,
securityInfo, securityInfo,
false, false,

View File

@@ -4,10 +4,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/BasePrincipal.h"
#include "nsTLSSocketProvider.h" #include "nsTLSSocketProvider.h"
#include "nsNSSIOLayer.h" #include "nsNSSIOLayer.h"
#include "nsError.h" #include "nsError.h"
using mozilla::NeckoOriginAttributes;
nsTLSSocketProvider::nsTLSSocketProvider() nsTLSSocketProvider::nsTLSSocketProvider()
{ {
} }
@@ -23,7 +26,7 @@ nsTLSSocketProvider::NewSocket(int32_t family,
const char *host, const char *host,
int32_t port, int32_t port,
nsIProxyInfo *proxy, nsIProxyInfo *proxy,
const nsACString &firstPartyDomain, const NeckoOriginAttributes &originAttributes,
uint32_t flags, uint32_t flags,
PRFileDesc **_result, PRFileDesc **_result,
nsISupports **securityInfo) nsISupports **securityInfo)
@@ -32,7 +35,7 @@ nsTLSSocketProvider::NewSocket(int32_t family,
host, host,
port, port,
proxy, proxy,
firstPartyDomain, originAttributes,
_result, _result,
securityInfo, securityInfo,
true, true,
@@ -47,7 +50,7 @@ nsTLSSocketProvider::AddToSocket(int32_t family,
const char *host, const char *host,
int32_t port, int32_t port,
nsIProxyInfo *proxy, nsIProxyInfo *proxy,
const nsACString &firstPartyDomain, const NeckoOriginAttributes &originAttributes,
uint32_t flags, uint32_t flags,
PRFileDesc *aSocket, PRFileDesc *aSocket,
nsISupports **securityInfo) nsISupports **securityInfo)
@@ -56,7 +59,7 @@ nsTLSSocketProvider::AddToSocket(int32_t family,
host, host,
port, port,
proxy, proxy,
firstPartyDomain, originAttributes,
aSocket, aSocket,
securityInfo, securityInfo,
true, true,

View File

@@ -7,6 +7,7 @@
#include "CertVerifier.h" #include "CertVerifier.h"
#include "OCSPCache.h" #include "OCSPCache.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Casting.h" #include "mozilla/Casting.h"
#include "mozilla/Sprintf.h" #include "mozilla/Sprintf.h"
#include "nss.h" #include "nss.h"
@@ -18,6 +19,8 @@
using namespace mozilla::pkix; using namespace mozilla::pkix;
using namespace mozilla::pkix::test; using namespace mozilla::pkix::test;
using mozilla::NeckoOriginAttributes;
template <size_t N> template <size_t N>
inline Input inline Input
LiteralInput(const char(&valueString)[N]) LiteralInput(const char(&valueString)[N])
@@ -46,7 +49,8 @@ protected:
static void static void
PutAndGet(mozilla::psm::OCSPCache& cache, const CertID& certID, Result result, PutAndGet(mozilla::psm::OCSPCache& cache, const CertID& certID, Result result,
Time time, const char* firstPartyDomain = nullptr) Time time,
const NeckoOriginAttributes& originAttributes = NeckoOriginAttributes())
{ {
// The first time is thisUpdate. The second is validUntil. // The first time is thisUpdate. The second is validUntil.
// The caller is expecting the validUntil returned with Get // The caller is expecting the validUntil returned with Get
@@ -54,11 +58,11 @@ PutAndGet(mozilla::psm::OCSPCache& cache, const CertID& certID, Result result,
// be different in practice, make thisUpdate less than validUntil. // be different in practice, make thisUpdate less than validUntil.
Time thisUpdate(time); Time thisUpdate(time);
ASSERT_EQ(Success, thisUpdate.SubtractSeconds(10)); ASSERT_EQ(Success, thisUpdate.SubtractSeconds(10));
Result rv = cache.Put(certID, firstPartyDomain, result, thisUpdate, time); Result rv = cache.Put(certID, originAttributes, result, thisUpdate, time);
ASSERT_TRUE(rv == Success); ASSERT_TRUE(rv == Success);
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(certID, firstPartyDomain, resultOut, timeOut)); ASSERT_TRUE(cache.Get(certID, originAttributes, resultOut, timeOut));
ASSERT_EQ(result, resultOut); ASSERT_EQ(result, resultOut);
ASSERT_EQ(time, timeOut); ASSERT_EQ(time, timeOut);
} }
@@ -79,7 +83,7 @@ TEST_F(psm_OCSPCacheTest, TestPutAndGet)
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial000), ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial000),
nullptr, resultOut, timeOut)); NeckoOriginAttributes(), resultOut, timeOut));
} }
TEST_F(psm_OCSPCacheTest, TestVariousGets) TEST_F(psm_OCSPCacheTest, TestVariousGets)
@@ -103,11 +107,11 @@ TEST_F(psm_OCSPCacheTest, TestVariousGets)
// This will be at the end of the list in the cache // This will be at the end of the list in the cache
CertID cert0000(fakeIssuer1, fakeKey000, fakeSerial0000); CertID cert0000(fakeIssuer1, fakeKey000, fakeSerial0000);
ASSERT_TRUE(cache.Get(cert0000, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(cert0000, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Success, resultOut); ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeIn, timeOut); ASSERT_EQ(timeIn, timeOut);
// Once we access it, it goes to the front // Once we access it, it goes to the front
ASSERT_TRUE(cache.Get(cert0000, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(cert0000, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Success, resultOut); ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeIn, timeOut); ASSERT_EQ(timeIn, timeOut);
@@ -117,17 +121,17 @@ TEST_F(psm_OCSPCacheTest, TestVariousGets)
static const Input fakeSerial0512(LiteralInput("0512")); static const Input fakeSerial0512(LiteralInput("0512"));
CertID cert0512(fakeIssuer1, fakeKey000, fakeSerial0512); CertID cert0512(fakeIssuer1, fakeKey000, fakeSerial0512);
ASSERT_TRUE(cache.Get(cert0512, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(cert0512, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Success, resultOut); ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeInPlus512, timeOut); ASSERT_EQ(timeInPlus512, timeOut);
ASSERT_TRUE(cache.Get(cert0512, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(cert0512, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Success, resultOut); ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeInPlus512, timeOut); ASSERT_EQ(timeInPlus512, timeOut);
// We've never seen this certificate // We've never seen this certificate
static const Input fakeSerial1111(LiteralInput("1111")); static const Input fakeSerial1111(LiteralInput("1111"));
ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey000, fakeSerial1111), ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey000, fakeSerial1111),
nullptr, resultOut, timeOut)); NeckoOriginAttributes(), resultOut, timeOut));
} }
TEST_F(psm_OCSPCacheTest, TestEviction) TEST_F(psm_OCSPCacheTest, TestEviction)
@@ -150,7 +154,7 @@ TEST_F(psm_OCSPCacheTest, TestEviction)
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial0000), ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial0000),
nullptr, resultOut, timeOut)); NeckoOriginAttributes(), resultOut, timeOut));
} }
TEST_F(psm_OCSPCacheTest, TestNoEvictionForRevokedResponses) TEST_F(psm_OCSPCacheTest, TestNoEvictionForRevokedResponses)
@@ -174,13 +178,13 @@ TEST_F(psm_OCSPCacheTest, TestNoEvictionForRevokedResponses)
} }
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(notEvicted, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(notEvicted, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut); ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut);
ASSERT_EQ(timeIn, timeOut); ASSERT_EQ(timeIn, timeOut);
Input fakeSerial0001(LiteralInput("0001")); Input fakeSerial0001(LiteralInput("0001"));
CertID evicted(fakeIssuer1, fakeKey000, fakeSerial0001); CertID evicted(fakeIssuer1, fakeKey000, fakeSerial0001);
ASSERT_FALSE(cache.Get(evicted, nullptr, resultOut, timeOut)); ASSERT_FALSE(cache.Get(evicted, NeckoOriginAttributes(), resultOut, timeOut));
} }
TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked) TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked)
@@ -207,12 +211,12 @@ TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked)
ASSERT_EQ(Success, timeInPlus1025.AddSeconds(1025)); ASSERT_EQ(Success, timeInPlus1025.AddSeconds(1025));
Time timeInPlus1025Minus50(timeInPlus1025); Time timeInPlus1025Minus50(timeInPlus1025);
ASSERT_EQ(Success, timeInPlus1025Minus50.SubtractSeconds(50)); ASSERT_EQ(Success, timeInPlus1025Minus50.SubtractSeconds(50));
Result result = cache.Put(good, nullptr, Success, timeInPlus1025Minus50, Result result = cache.Put(good, NeckoOriginAttributes(), Success, timeInPlus1025Minus50,
timeInPlus1025); timeInPlus1025);
ASSERT_EQ(Success, result); ASSERT_EQ(Success, result);
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_FALSE(cache.Get(good, nullptr, resultOut, timeOut)); ASSERT_FALSE(cache.Get(good, NeckoOriginAttributes(), resultOut, timeOut));
static const Input fakeSerial1026(LiteralInput("1026")); static const Input fakeSerial1026(LiteralInput("1026"));
CertID revoked(fakeIssuer1, fakeKey000, fakeSerial1026); CertID revoked(fakeIssuer1, fakeKey000, fakeSerial1026);
@@ -221,7 +225,7 @@ TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked)
ASSERT_EQ(Success, timeInPlus1026.AddSeconds(1026)); ASSERT_EQ(Success, timeInPlus1026.AddSeconds(1026));
Time timeInPlus1026Minus50(timeInPlus1026); Time timeInPlus1026Minus50(timeInPlus1026);
ASSERT_EQ(Success, timeInPlus1026Minus50.SubtractSeconds(50)); ASSERT_EQ(Success, timeInPlus1026Minus50.SubtractSeconds(50));
result = cache.Put(revoked, nullptr, Result::ERROR_REVOKED_CERTIFICATE, result = cache.Put(revoked, NeckoOriginAttributes(), Result::ERROR_REVOKED_CERTIFICATE,
timeInPlus1026Minus50, timeInPlus1026); timeInPlus1026Minus50, timeInPlus1026);
ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, result); ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, result);
} }
@@ -236,15 +240,15 @@ TEST_F(psm_OCSPCacheTest, VariousIssuers)
PutAndGet(cache, subject, Success, now); PutAndGet(cache, subject, Success, now);
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(subject, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(subject, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Success, resultOut); ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeIn, timeOut); ASSERT_EQ(timeIn, timeOut);
// Test that we don't match a different issuer DN // Test that we don't match a different issuer DN
ASSERT_FALSE(cache.Get(CertID(fakeIssuer2, fakeKey000, fakeSerial001), ASSERT_FALSE(cache.Get(CertID(fakeIssuer2, fakeKey000, fakeSerial001),
nullptr, resultOut, timeOut)); NeckoOriginAttributes(), resultOut, timeOut));
// Test that we don't match a different issuer key // Test that we don't match a different issuer key
ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial001), ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial001),
nullptr, resultOut, timeOut)); NeckoOriginAttributes(), resultOut, timeOut));
} }
TEST_F(psm_OCSPCacheTest, Times) TEST_F(psm_OCSPCacheTest, Times)
@@ -256,12 +260,12 @@ TEST_F(psm_OCSPCacheTest, Times)
PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200)); PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200));
// This should not override the more recent entry. // This should not override the more recent entry.
ASSERT_EQ(Success, ASSERT_EQ(Success,
cache.Put(certID, nullptr, Result::ERROR_OCSP_UNKNOWN_CERT, cache.Put(certID, NeckoOriginAttributes(), Result::ERROR_OCSP_UNKNOWN_CERT,
TimeFromElapsedSecondsAD(100), TimeFromElapsedSecondsAD(100),
TimeFromElapsedSecondsAD(100))); TimeFromElapsedSecondsAD(100)));
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(certID, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(certID, NeckoOriginAttributes(), resultOut, timeOut));
// Here we see the more recent time. // Here we see the more recent time.
ASSERT_EQ(Success, resultOut); ASSERT_EQ(Success, resultOut);
ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut); ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut);
@@ -280,12 +284,12 @@ TEST_F(psm_OCSPCacheTest, NetworkFailure)
PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200)); PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200));
// This should not override the already present entry. // This should not override the already present entry.
ASSERT_EQ(Success, ASSERT_EQ(Success,
cache.Put(certID, nullptr, Result::ERROR_CONNECT_REFUSED, cache.Put(certID, NeckoOriginAttributes(), Result::ERROR_CONNECT_REFUSED,
TimeFromElapsedSecondsAD(300), TimeFromElapsedSecondsAD(300),
TimeFromElapsedSecondsAD(350))); TimeFromElapsedSecondsAD(350)));
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(certID, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(certID, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Success, resultOut); ASSERT_EQ(Success, resultOut);
ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut); ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut);
@@ -293,10 +297,10 @@ TEST_F(psm_OCSPCacheTest, NetworkFailure)
TimeFromElapsedSecondsAD(400)); TimeFromElapsedSecondsAD(400));
// This should not override the already present entry. // This should not override the already present entry.
ASSERT_EQ(Success, ASSERT_EQ(Success,
cache.Put(certID, nullptr, Result::ERROR_CONNECT_REFUSED, cache.Put(certID, NeckoOriginAttributes(), Result::ERROR_CONNECT_REFUSED,
TimeFromElapsedSecondsAD(500), TimeFromElapsedSecondsAD(500),
TimeFromElapsedSecondsAD(550))); TimeFromElapsedSecondsAD(550)));
ASSERT_TRUE(cache.Get(certID, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(certID, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Result::ERROR_OCSP_UNKNOWN_CERT, resultOut); ASSERT_EQ(Result::ERROR_OCSP_UNKNOWN_CERT, resultOut);
ASSERT_EQ(TimeFromElapsedSecondsAD(400), timeOut); ASSERT_EQ(TimeFromElapsedSecondsAD(400), timeOut);
@@ -304,22 +308,30 @@ TEST_F(psm_OCSPCacheTest, NetworkFailure)
TimeFromElapsedSecondsAD(600)); TimeFromElapsedSecondsAD(600));
// This should not override the already present entry. // This should not override the already present entry.
ASSERT_EQ(Success, ASSERT_EQ(Success,
cache.Put(certID, nullptr, Result::ERROR_CONNECT_REFUSED, cache.Put(certID, NeckoOriginAttributes(), Result::ERROR_CONNECT_REFUSED,
TimeFromElapsedSecondsAD(700), TimeFromElapsedSecondsAD(700),
TimeFromElapsedSecondsAD(750))); TimeFromElapsedSecondsAD(750)));
ASSERT_TRUE(cache.Get(certID, nullptr, resultOut, timeOut)); ASSERT_TRUE(cache.Get(certID, NeckoOriginAttributes(), resultOut, timeOut));
ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut); ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut);
ASSERT_EQ(TimeFromElapsedSecondsAD(600), timeOut); ASSERT_EQ(TimeFromElapsedSecondsAD(600), timeOut);
} }
TEST_F(psm_OCSPCacheTest, TestFirstPartyDomain) TEST_F(psm_OCSPCacheTest, TestOriginAttributes)
{ {
CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000); CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000);
SCOPED_TRACE(""); SCOPED_TRACE("");
PutAndGet(cache, certID, Success, now, "foo.com"); NeckoOriginAttributes attrs;
attrs.mFirstPartyDomain.AssignLiteral("foo.com");
PutAndGet(cache, certID, Success, now, attrs);
Result resultOut; Result resultOut;
Time timeOut(Time::uninitialized); Time timeOut(Time::uninitialized);
ASSERT_FALSE(cache.Get(certID, "bar.com", resultOut, timeOut)); attrs.mFirstPartyDomain.AssignLiteral("bar.com");
ASSERT_FALSE(cache.Get(certID, attrs, resultOut, timeOut));
// OCSP cache should not be isolated by containers.
attrs.mUserContextId = 1;
attrs.mFirstPartyDomain.AssignLiteral("foo.com");
ASSERT_TRUE(cache.Get(certID, attrs, resultOut, timeOut));
} }

View File

@@ -324,12 +324,15 @@ function add_tls_server_setup(serverBinName, certsPath) {
* @param {Function} aAfterStreamOpen * @param {Function} aAfterStreamOpen
* A callback function that is called with the nsISocketTransport once the * A callback function that is called with the nsISocketTransport once the
* output stream is ready. * output stream is ready.
* @param {String} aFirstPartyDomain * @param {OriginAttributes} aOriginAttributes (optional)
* The first party domain which will be used to double-key the OCSP cache. * The origin attributes that the socket transport will have. This parameter
* affects OCSP because OCSP cache is double-keyed by origin attributes' first
* party domain.
*/ */
function add_connection_test(aHost, aExpectedResult, function add_connection_test(aHost, aExpectedResult,
aBeforeConnect, aWithSecurityInfo, aBeforeConnect, aWithSecurityInfo,
aAfterStreamOpen, aFirstPartyDomain) { aAfterStreamOpen,
/*optional*/ aOriginAttributes) {
const REMOTE_PORT = 8443; const REMOTE_PORT = 8443;
function Connection(host) { function Connection(host) {
@@ -345,8 +348,8 @@ function add_connection_test(aHost, aExpectedResult,
// listening on 127.0.0.1 causes frequent failures on OS X 10.10. // listening on 127.0.0.1 causes frequent failures on OS X 10.10.
this.transport.connectionFlags |= Ci.nsISocketTransport.DISABLE_IPV6; this.transport.connectionFlags |= Ci.nsISocketTransport.DISABLE_IPV6;
this.transport.setEventSink(this, this.thread); this.transport.setEventSink(this, this.thread);
if (aFirstPartyDomain) { if (aOriginAttributes) {
this.transport.firstPartyDomain = aFirstPartyDomain; this.transport.originAttributes = aOriginAttributes;
} }
this.inputStream = null; this.inputStream = null;
this.outputStream = null; this.outputStream = null;

View File

@@ -43,7 +43,7 @@ function generateGoodOCSPResponse() {
} }
function add_ocsp_test(aHost, aExpectedResult, aResponses, aMessage, function add_ocsp_test(aHost, aExpectedResult, aResponses, aMessage,
aFirstPartyDomain) { aOriginAttributes) {
add_connection_test(aHost, aExpectedResult, add_connection_test(aHost, aExpectedResult,
function() { function() {
clearSessionCache(); clearSessionCache();
@@ -56,7 +56,7 @@ function add_ocsp_test(aHost, aExpectedResult, aResponses, aMessage,
equal(gFetchCount, aResponses.length, equal(gFetchCount, aResponses.length,
"should have made " + aResponses.length + "should have made " + aResponses.length +
" OCSP request" + (aResponses.length == 1 ? "" : "s")); " OCSP request" + (aResponses.length == 1 ? "" : "s"));
}, null, aFirstPartyDomain); }, null, aOriginAttributes);
} }
function run_test() { function run_test() {
@@ -259,12 +259,13 @@ function add_tests() {
add_ocsp_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess, add_ocsp_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess,
[respondWithGoodOCSP], [respondWithGoodOCSP],
"No stapled response (firstPartyDomain = foo.com) -> a fetch " + "No stapled response (firstPartyDomain = foo.com) -> a fetch " +
"should have been attempted", "foo.com"); "should have been attempted", { firstPartyDomain: "foo.com" });
// The cache will prevent a fetch from happening. // The cache will prevent a fetch from happening.
add_ocsp_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess, [], add_ocsp_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess, [],
"Noted OCSP server failure (firstPartyDomain = foo.com) -> a " + "Noted OCSP server failure (firstPartyDomain = foo.com) -> a " +
"fetch should not have been attempted", "foo.com"); "fetch should not have been attempted",
{ firstPartyDomain: "foo.com" });
add_test(function() { add_test(function() {
stopObservingChannels(); stopObservingChannels();
@@ -282,7 +283,7 @@ function add_tests() {
add_ocsp_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess, add_ocsp_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess,
[respondWithGoodOCSP], [respondWithGoodOCSP],
"No stapled response (firstPartyDomain = bar.com) -> a fetch " + "No stapled response (firstPartyDomain = bar.com) -> a fetch " +
"should have been attempted", "bar.com"); "should have been attempted", { firstPartyDomain: "bar.com" });
add_test(function() { add_test(function() {
stopObservingChannels(); stopObservingChannels();