Bug 1264562 - Part 5: Double key OCSP cache with firstPartyDomain (adapted from Tor Browser patch #13670) r=keeler

--HG--
extra : rebase_source : cfca6f16dcd315c03704e75ed63181466a8eb5c4
This commit is contained in:
Jonathan Hao 2016-10-18 17:08:39 +08:00
Родитель d9e14ecf6a
Коммит 8c7b033b68
4 изменённых файлов: 141 добавлений и 64 удалений

Просмотреть файл

@ -421,7 +421,7 @@ NSSCertDBTrustDomain::CheckRevocation(EndEntityOrCA endEntityOrCA,
Result cachedResponseResult = Success;
Time cachedResponseValidThrough(Time::uninitialized);
bool cachedResponsePresent = mOCSPCache.Get(certID,
bool cachedResponsePresent = mOCSPCache.Get(certID, mFirstPartyDomain,
cachedResponseResult,
cachedResponseValidThrough);
if (cachedResponsePresent) {
@ -588,7 +588,7 @@ NSSCertDBTrustDomain::CheckRevocation(EndEntityOrCA endEntityOrCA,
if (timeout.AddSeconds(ServerFailureDelaySeconds) != Success) {
return Result::FATAL_ERROR_LIBRARY_FAILURE; // integer overflow
}
rv = mOCSPCache.Put(certID, error, time, timeout);
rv = mOCSPCache.Put(certID, mFirstPartyDomain, error, time, timeout);
if (rv != Success) {
return rv;
}
@ -693,7 +693,8 @@ NSSCertDBTrustDomain::VerifyAndMaybeCacheEncodedOCSPResponse(
rv == Result::ERROR_OCSP_UNKNOWN_CERT) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain: caching OCSP response"));
Result putRV = mOCSPCache.Put(certID, rv, thisUpdate, validThrough);
Result putRV = mOCSPCache.Put(certID, mFirstPartyDomain, rv, thisUpdate,
validThrough);
if (putRV != Success) {
return putRV;
}

Просмотреть файл

@ -38,19 +38,44 @@ using namespace mozilla::pkix;
namespace mozilla { namespace psm {
static SECStatus
DigestLength(UniquePK11Context& context, uint32_t length)
{
// Restrict length to 2 bytes because it should be big enough for all
// inputs this code will actually see and that it is well-defined and
// type-size-independent.
if (length >= 65536) {
return SECFailure;
}
unsigned char array[2];
array[0] = length & 255;
array[1] = (length >> 8) & 255;
return PK11_DigestOp(context.get(), array, MOZ_ARRAY_LENGTH(array));
}
// Let derIssuer be the DER encoding of the issuer of aCert.
// Let derPublicKey be the DER encoding of the public key of aIssuerCert.
// Let serialNumber be the bytes of the serial number of aCert.
// The value calculated is SHA384(derIssuer || derPublicKey || serialNumber).
// Because the DER encodings include the length of the data encoded,
// there do not exist A(derIssuerA, derPublicKeyA, serialNumberA) and
// B(derIssuerB, derPublicKeyB, serialNumberB) such that the concatenation of
// each triplet results in the same string of 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 collisions that would subvert this
// cache (given that SHA384 is a cryptographically-secure hash function).
// Let serialNumberLen be the number of bytes of serialNumber.
// The first party domain 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.
// The value calculated is SHA384(derIssuer || derPublicKey || serialNumberLen
// || serialNumber || firstPartyDomainLen || firstPartyDomain).
// 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
// A(derIssuerA, derPublicKeyA, serialNumberLenA, serialNumberA,
// firstPartyDomainLenA, firstPartyDomainA) and B(derIssuerB, derPublicKeyB,
// serialNumberLenB, serialNumberB, firstPartyDomainLenB, firstPartyDomainB)
// 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
// important because as a result it is computationally infeasible to find
// collisions that would subvert this cache (given that SHA384 is a
// cryptographically-secure hash function).
static SECStatus
CertIDHash(SHA384Buffer& buf, const CertID& certID)
CertIDHash(SHA384Buffer& buf, const CertID& certID,
const char* firstPartyDomain)
{
UniquePK11Context context(PK11_CreateDigestContext(SEC_OID_SHA384));
if (!context) {
@ -74,11 +99,28 @@ CertIDHash(SHA384Buffer& buf, const CertID& certID)
}
SECItem certIDSerialNumber =
UnsafeMapInputToSECItem(certID.serialNumber);
rv = DigestLength(context, certIDSerialNumber.len);
if (rv != SECSuccess) {
return rv;
}
rv = PK11_DigestOp(context.get(), certIDSerialNumber.data,
certIDSerialNumber.len);
if (rv != SECSuccess) {
return rv;
}
if (firstPartyDomain) {
uint32_t firstPartyDomainLen = strlen(firstPartyDomain);
rv = DigestLength(context, firstPartyDomainLen);
if (rv != SECSuccess) {
return rv;
}
rv = PK11_DigestOp(context.get(),
BitwiseCast<const unsigned char*>(firstPartyDomain),
firstPartyDomainLen);
if (rv != SECSuccess) {
return rv;
}
}
uint32_t outLen = 0;
rv = PK11_DigestFinal(context.get(), buf, &outLen, SHA384_LENGTH);
if (outLen != SHA384_LENGTH) {
@ -88,9 +130,9 @@ CertIDHash(SHA384Buffer& buf, const CertID& certID)
}
Result
OCSPCache::Entry::Init(const CertID& aCertID)
OCSPCache::Entry::Init(const CertID& aCertID, const char* aFirstPartyDomain)
{
SECStatus srv = CertIDHash(mIDHash, aCertID);
SECStatus srv = CertIDHash(mIDHash, aCertID, aFirstPartyDomain);
if (srv != SECSuccess) {
return MapPRErrorCodeToResult(PR_GetError());
}
@ -110,7 +152,8 @@ OCSPCache::~OCSPCache()
// Returns false with index in an undefined state if no matching entry was
// found.
bool
OCSPCache::FindInternal(const CertID& aCertID, /*out*/ size_t& index,
OCSPCache::FindInternal(const CertID& aCertID, const char* aFirstPartyDomain,
/*out*/ size_t& index,
const MutexAutoLock& /* aProofOfLock */)
{
if (mEntries.length() == 0) {
@ -118,7 +161,7 @@ OCSPCache::FindInternal(const CertID& aCertID, /*out*/ size_t& index,
}
SHA384Buffer idHash;
SECStatus rv = CertIDHash(idHash, aCertID);
SECStatus rv = CertIDHash(idHash, aCertID, aFirstPartyDomain);
if (rv != SECSuccess) {
return false;
}
@ -136,9 +179,11 @@ OCSPCache::FindInternal(const CertID& aCertID, /*out*/ size_t& index,
}
static inline void
LogWithCertID(const char* aMessage, const CertID& aCertID)
LogWithCertID(const char* aMessage, const CertID& aCertID,
const char* aFirstPartyDomain)
{
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, (aMessage, &aCertID));
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
(aMessage, &aCertID, aFirstPartyDomain));
}
void
@ -155,16 +200,19 @@ OCSPCache::MakeMostRecentlyUsed(size_t aIndex,
}
bool
OCSPCache::Get(const CertID& aCertID, Result& aResult, Time& aValidThrough)
OCSPCache::Get(const CertID& aCertID, const char* aFirstPartyDomain,
Result& aResult, Time& aValidThrough)
{
MutexAutoLock lock(mMutex);
size_t index;
if (!FindInternal(aCertID, index, lock)) {
LogWithCertID("OCSPCache::Get(%p) not in cache", aCertID);
if (!FindInternal(aCertID, aFirstPartyDomain, index, lock)) {
LogWithCertID("OCSPCache::Get(%p,\"%s\") not in cache", aCertID,
aFirstPartyDomain);
return false;
}
LogWithCertID("OCSPCache::Get(%p) in cache", aCertID);
LogWithCertID("OCSPCache::Get(%p,\"%s\") in cache", aCertID,
aFirstPartyDomain);
aResult = mEntries[index]->mResult;
aValidThrough = mEntries[index]->mValidThrough;
MakeMostRecentlyUsed(index, lock);
@ -172,17 +220,17 @@ OCSPCache::Get(const CertID& aCertID, Result& aResult, Time& aValidThrough)
}
Result
OCSPCache::Put(const CertID& aCertID, Result aResult,
Time aThisUpdate, Time aValidThrough)
OCSPCache::Put(const CertID& aCertID, const char* aFirstPartyDomain,
Result aResult, Time aThisUpdate, Time aValidThrough)
{
MutexAutoLock lock(mMutex);
size_t index;
if (FindInternal(aCertID, index, lock)) {
if (FindInternal(aCertID, aFirstPartyDomain, index, lock)) {
// Never replace an entry indicating a revoked certificate.
if (mEntries[index]->mResult == Result::ERROR_REVOKED_CERTIFICATE) {
LogWithCertID("OCSPCache::Put(%p) already in cache as revoked - "
"not replacing", aCertID);
LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache as revoked - "
"not replacing", aCertID, aFirstPartyDomain);
MakeMostRecentlyUsed(index, lock);
return Success;
}
@ -191,8 +239,9 @@ OCSPCache::Put(const CertID& aCertID, Result aResult,
// indicates a revoked certificate, which we want to remember.
if (mEntries[index]->mThisUpdate > aThisUpdate &&
aResult != Result::ERROR_REVOKED_CERTIFICATE) {
LogWithCertID("OCSPCache::Put(%p) already in cache with more recent "
"validity - not replacing", aCertID);
LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache with more "
"recent validity - not replacing", aCertID,
aFirstPartyDomain);
MakeMostRecentlyUsed(index, lock);
return Success;
}
@ -202,13 +251,15 @@ OCSPCache::Put(const CertID& aCertID, Result aResult,
if (aResult != Success &&
aResult != Result::ERROR_OCSP_UNKNOWN_CERT &&
aResult != Result::ERROR_REVOKED_CERTIFICATE) {
LogWithCertID("OCSPCache::Put(%p) already in cache - not replacing "
"with less important status", aCertID);
LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache - not "
"replacing with less important status", aCertID,
aFirstPartyDomain);
MakeMostRecentlyUsed(index, lock);
return Success;
}
LogWithCertID("OCSPCache::Put(%p) already in cache - replacing", aCertID);
LogWithCertID("OCSPCache::Put(%p, \"%s\") already in cache - replacing",
aCertID, aFirstPartyDomain);
mEntries[index]->mResult = aResult;
mEntries[index]->mThisUpdate = aThisUpdate;
mEntries[index]->mValidThrough = aValidThrough;
@ -217,7 +268,8 @@ OCSPCache::Put(const CertID& aCertID, Result aResult,
}
if (mEntries.length() == MaxEntries) {
LogWithCertID("OCSPCache::Put(%p) too full - evicting an entry", aCertID);
LogWithCertID("OCSPCache::Put(%p, \"%s\") too full - evicting an entry",
aCertID, aFirstPartyDomain);
for (Entry** toEvict = mEntries.begin(); toEvict != mEntries.end();
toEvict++) {
// Never evict an entry that indicates a revoked or unknokwn certificate,
@ -249,7 +301,7 @@ OCSPCache::Put(const CertID& aCertID, Result aResult,
if (!newEntry) {
return Result::FATAL_ERROR_NO_MEMORY;
}
Result rv = newEntry->Init(aCertID);
Result rv = newEntry->Init(aCertID, aFirstPartyDomain);
if (rv != Success) {
delete newEntry;
return rv;
@ -258,7 +310,8 @@ OCSPCache::Put(const CertID& aCertID, Result aResult,
delete newEntry;
return Result::FATAL_ERROR_NO_MEMORY;
}
LogWithCertID("OCSPCache::Put(%p) added to cache", aCertID);
LogWithCertID("OCSPCache::Put(%p, \"%s\") added to cache", aCertID,
aFirstPartyDomain);
return Success;
}

Просмотреть файл

@ -56,13 +56,18 @@ public:
// Returns true if the status of the given certificate (issued by the given
// 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
// status and the time through which the status is considered trustworthy.
bool Get(const mozilla::pkix::CertID& aCertID,
const char* aFirstPartyDomain,
/*out*/ mozilla::pkix::Result& aResult,
/*out*/ mozilla::pkix::Time& aValidThrough);
// 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.
// A status with an error code of SEC_ERROR_REVOKED_CERTIFICATE will not
// be replaced or evicted.
@ -72,6 +77,7 @@ public:
// status with a less recent thisUpdate unless the less recent status
// indicates the certificate is revoked.
mozilla::pkix::Result Put(const mozilla::pkix::CertID& aCertID,
const char* aFirstPartyDomain,
mozilla::pkix::Result aResult,
mozilla::pkix::Time aThisUpdate,
mozilla::pkix::Time aValidThrough);
@ -91,18 +97,23 @@ private:
, mValidThrough(aValidThrough)
{
}
mozilla::pkix::Result Init(const mozilla::pkix::CertID& aCertID);
mozilla::pkix::Result Init(const mozilla::pkix::CertID& aCertID,
const char* aFirstPartyDomain);
mozilla::pkix::Result mResult;
mozilla::pkix::Time mThisUpdate;
mozilla::pkix::Time mValidThrough;
// The SHA-384 hash of the concatenation of the DER encodings of the
// issuer name and issuer key, followed by the serial number.
// issuer name and issuer key, followed by the length of the serial number,
// the serial number, the length of the first party domain, and the first
// party domain (if "privacy.firstparty.isolate" is enabled).
// See the documentation for CertIDHash in OCSPCache.cpp.
SHA384Buffer mIDHash;
};
bool FindInternal(const mozilla::pkix::CertID& aCertID, /*out*/ size_t& index,
bool FindInternal(const mozilla::pkix::CertID& aCertID,
const char* aFirstPartyDomain,
/*out*/ size_t& index,
const MutexAutoLock& aProofOfLock);
void MakeMostRecentlyUsed(size_t aIndex, const MutexAutoLock& aProofOfLock);

Просмотреть файл

@ -47,7 +47,7 @@ protected:
static void
PutAndGet(OCSPCache& cache, const CertID& certID, Result result,
Time time)
Time time, const char* firstPartyDomain = nullptr)
{
// The first time is thisUpdate. The second is validUntil.
// The caller is expecting the validUntil returned with Get
@ -55,11 +55,11 @@ PutAndGet(OCSPCache& cache, const CertID& certID, Result result,
// be different in practice, make thisUpdate less than validUntil.
Time thisUpdate(time);
ASSERT_EQ(Success, thisUpdate.SubtractSeconds(10));
Result rv = cache.Put(certID, result, thisUpdate, time);
Result rv = cache.Put(certID, firstPartyDomain, result, thisUpdate, time);
ASSERT_TRUE(rv == Success);
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(certID, resultOut, timeOut));
ASSERT_TRUE(cache.Get(certID, firstPartyDomain, resultOut, timeOut));
ASSERT_EQ(result, resultOut);
ASSERT_EQ(time, timeOut);
}
@ -80,7 +80,7 @@ TEST_F(psm_OCSPCacheTest, TestPutAndGet)
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial000),
resultOut, timeOut));
nullptr, resultOut, timeOut));
}
TEST_F(psm_OCSPCacheTest, TestVariousGets)
@ -104,11 +104,11 @@ TEST_F(psm_OCSPCacheTest, TestVariousGets)
// This will be at the end of the list in the cache
CertID cert0000(fakeIssuer1, fakeKey000, fakeSerial0000);
ASSERT_TRUE(cache.Get(cert0000, resultOut, timeOut));
ASSERT_TRUE(cache.Get(cert0000, nullptr, resultOut, timeOut));
ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeIn, timeOut);
// Once we access it, it goes to the front
ASSERT_TRUE(cache.Get(cert0000, resultOut, timeOut));
ASSERT_TRUE(cache.Get(cert0000, nullptr, resultOut, timeOut));
ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeIn, timeOut);
@ -118,17 +118,17 @@ TEST_F(psm_OCSPCacheTest, TestVariousGets)
static const Input fakeSerial0512(LiteralInput("0512"));
CertID cert0512(fakeIssuer1, fakeKey000, fakeSerial0512);
ASSERT_TRUE(cache.Get(cert0512, resultOut, timeOut));
ASSERT_TRUE(cache.Get(cert0512, nullptr, resultOut, timeOut));
ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeInPlus512, timeOut);
ASSERT_TRUE(cache.Get(cert0512, resultOut, timeOut));
ASSERT_TRUE(cache.Get(cert0512, nullptr, resultOut, timeOut));
ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeInPlus512, timeOut);
// We've never seen this certificate
static const Input fakeSerial1111(LiteralInput("1111"));
ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey000, fakeSerial1111),
resultOut, timeOut));
nullptr, resultOut, timeOut));
}
TEST_F(psm_OCSPCacheTest, TestEviction)
@ -151,7 +151,7 @@ TEST_F(psm_OCSPCacheTest, TestEviction)
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial0000),
resultOut, timeOut));
nullptr, resultOut, timeOut));
}
TEST_F(psm_OCSPCacheTest, TestNoEvictionForRevokedResponses)
@ -175,13 +175,13 @@ TEST_F(psm_OCSPCacheTest, TestNoEvictionForRevokedResponses)
}
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(notEvicted, resultOut, timeOut));
ASSERT_TRUE(cache.Get(notEvicted, nullptr, resultOut, timeOut));
ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut);
ASSERT_EQ(timeIn, timeOut);
Input fakeSerial0001(LiteralInput("0001"));
CertID evicted(fakeIssuer1, fakeKey000, fakeSerial0001);
ASSERT_FALSE(cache.Get(evicted, resultOut, timeOut));
ASSERT_FALSE(cache.Get(evicted, nullptr, resultOut, timeOut));
}
TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked)
@ -208,12 +208,12 @@ TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked)
ASSERT_EQ(Success, timeInPlus1025.AddSeconds(1025));
Time timeInPlus1025Minus50(timeInPlus1025);
ASSERT_EQ(Success, timeInPlus1025Minus50.SubtractSeconds(50));
Result result = cache.Put(good, Success, timeInPlus1025Minus50,
Result result = cache.Put(good, nullptr, Success, timeInPlus1025Minus50,
timeInPlus1025);
ASSERT_EQ(Success, result);
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_FALSE(cache.Get(good, resultOut, timeOut));
ASSERT_FALSE(cache.Get(good, nullptr, resultOut, timeOut));
static const Input fakeSerial1026(LiteralInput("1026"));
CertID revoked(fakeIssuer1, fakeKey000, fakeSerial1026);
@ -222,7 +222,7 @@ TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked)
ASSERT_EQ(Success, timeInPlus1026.AddSeconds(1026));
Time timeInPlus1026Minus50(timeInPlus1026);
ASSERT_EQ(Success, timeInPlus1026Minus50.SubtractSeconds(50));
result = cache.Put(revoked, Result::ERROR_REVOKED_CERTIFICATE,
result = cache.Put(revoked, nullptr, Result::ERROR_REVOKED_CERTIFICATE,
timeInPlus1026Minus50, timeInPlus1026);
ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, result);
}
@ -237,15 +237,15 @@ TEST_F(psm_OCSPCacheTest, VariousIssuers)
PutAndGet(cache, subject, Success, now);
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(subject, resultOut, timeOut));
ASSERT_TRUE(cache.Get(subject, nullptr, resultOut, timeOut));
ASSERT_EQ(Success, resultOut);
ASSERT_EQ(timeIn, timeOut);
// Test that we don't match a different issuer DN
ASSERT_FALSE(cache.Get(CertID(fakeIssuer2, fakeKey000, fakeSerial001),
resultOut, timeOut));
nullptr, resultOut, timeOut));
// Test that we don't match a different issuer key
ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial001),
resultOut, timeOut));
nullptr, resultOut, timeOut));
}
TEST_F(psm_OCSPCacheTest, Times)
@ -257,12 +257,12 @@ TEST_F(psm_OCSPCacheTest, Times)
PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200));
// This should not override the more recent entry.
ASSERT_EQ(Success,
cache.Put(certID, Result::ERROR_OCSP_UNKNOWN_CERT,
cache.Put(certID, nullptr, Result::ERROR_OCSP_UNKNOWN_CERT,
TimeFromElapsedSecondsAD(100),
TimeFromElapsedSecondsAD(100)));
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(certID, resultOut, timeOut));
ASSERT_TRUE(cache.Get(certID, nullptr, resultOut, timeOut));
// Here we see the more recent time.
ASSERT_EQ(Success, resultOut);
ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut);
@ -281,12 +281,12 @@ TEST_F(psm_OCSPCacheTest, NetworkFailure)
PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200));
// This should not override the already present entry.
ASSERT_EQ(Success,
cache.Put(certID, Result::ERROR_CONNECT_REFUSED,
cache.Put(certID, nullptr, Result::ERROR_CONNECT_REFUSED,
TimeFromElapsedSecondsAD(300),
TimeFromElapsedSecondsAD(350)));
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_TRUE(cache.Get(certID, resultOut, timeOut));
ASSERT_TRUE(cache.Get(certID, nullptr, resultOut, timeOut));
ASSERT_EQ(Success, resultOut);
ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut);
@ -294,10 +294,10 @@ TEST_F(psm_OCSPCacheTest, NetworkFailure)
TimeFromElapsedSecondsAD(400));
// This should not override the already present entry.
ASSERT_EQ(Success,
cache.Put(certID, Result::ERROR_CONNECT_REFUSED,
cache.Put(certID, nullptr, Result::ERROR_CONNECT_REFUSED,
TimeFromElapsedSecondsAD(500),
TimeFromElapsedSecondsAD(550)));
ASSERT_TRUE(cache.Get(certID, resultOut, timeOut));
ASSERT_TRUE(cache.Get(certID, nullptr, resultOut, timeOut));
ASSERT_EQ(Result::ERROR_OCSP_UNKNOWN_CERT, resultOut);
ASSERT_EQ(TimeFromElapsedSecondsAD(400), timeOut);
@ -305,10 +305,22 @@ TEST_F(psm_OCSPCacheTest, NetworkFailure)
TimeFromElapsedSecondsAD(600));
// This should not override the already present entry.
ASSERT_EQ(Success,
cache.Put(certID, Result::ERROR_CONNECT_REFUSED,
cache.Put(certID, nullptr, Result::ERROR_CONNECT_REFUSED,
TimeFromElapsedSecondsAD(700),
TimeFromElapsedSecondsAD(750)));
ASSERT_TRUE(cache.Get(certID, resultOut, timeOut));
ASSERT_TRUE(cache.Get(certID, nullptr, resultOut, timeOut));
ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut);
ASSERT_EQ(TimeFromElapsedSecondsAD(600), timeOut);
}
TEST_F(psm_OCSPCacheTest, TestFirstPartyDomain)
{
CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000);
SCOPED_TRACE("");
PutAndGet(cache, certID, Success, now, "foo.com");
Result resultOut;
Time timeOut(Time::uninitialized);
ASSERT_FALSE(cache.Get(certID, "bar.com", resultOut, timeOut));
}