Bug 921684 - SQL backend does not reload certificates, a=rrelyea,r=rsleevi
--- a/lib/certdb/certi.h
+++ b/lib/certdb/certi.h
@@ -111,21 +111,26 @@ struct CachedCrlStr {
*/
struct CRLDPCacheStr {
#ifdef DPC_RWLOCK
NSSRWLock* lock;
#else
PRLock* lock;
#endif
- CERTCertificate* issuer; /* issuer cert
- XXX there may be multiple issuer certs,
- with different validity dates. Also
- need to deal with SKID/AKID . See
- bugzilla 217387, 233118 */
+ SECItem *issuerDERCert; /* issuer DER cert. Don't hold a reference
+ to the actual cert so the trust can be
+ updated on the cert automatically.
+ XXX there may be multiple issuer certs,
+ with different validity dates. Also
+ need to deal with SKID/AKID . See
+ bugzilla 217387, 233118 */
+
+ CERTCertDBHandle *dbHandle;
+
SECItem* subject; /* DER of issuer subject */
SECItem* distributionPoint; /* DER of distribution point. This may be
NULL when distribution points aren't
in use (ie. the CA has a single CRL).
Currently not used. */
/* array of full CRLs matching this distribution point */
PRUint32 ncrls; /* total number of CRLs in crls */
@@ -160,25 +165,16 @@ struct CRLDPCacheStr {
XCRL once we support multiple issuing distribution points, this object
will be a hash table. For now, it just holds the single CRL distribution
point cache structure.
*/
struct CRLIssuerCacheStr {
SECItem* subject; /* DER of issuer subject */
CRLDPCache* dpp;
-#if 0
- /* XCRL for future use.
- We don't need to lock at the moment because we only have one DP,
- which gets created at the same time as this object */
- NSSRWLock* lock;
- CRLDPCache** dps;
- PLHashTable* distributionpoints;
- CERTCertificate* issuer;
-#endif
};
/* CRL revocation cache object
This object tracks all the issuer caches
*/
struct CRLCacheStr {
#ifdef GLOBAL_RWLOCK
--- a/lib/certdb/crl.c
+++ b/lib/certdb/crl.c
@@ -1118,19 +1118,19 @@ static SECStatus DPCache_Destroy(CRLDPCa
}
}
/* free the array of CRLs */
if (cache->crls)
{
PORT_Free(cache->crls);
}
/* destroy the cert */
- if (cache->issuer)
+ if (cache->issuerDERCert)
{
- CERT_DestroyCertificate(cache->issuer);
+ SECITEM_FreeItem(cache->issuerDERCert, PR_TRUE);
}
/* free the subject */
if (cache->subject)
{
SECITEM_FreeItem(cache->subject, PR_TRUE);
}
/* free the distribution points */
if (cache->distributionPoint)
@@ -1566,24 +1566,30 @@ static SECStatus CachedCrl_Verify(CRLDPC
crlobject->sigChecked = PR_TRUE; /* we can never verify a CRL
with bogus DER. Mark it checked so we won't try again */
PORT_SetError(SEC_ERROR_BAD_DER);
return SECSuccess;
}
else
{
SECStatus signstatus = SECFailure;
- if (cache->issuer)
+ if (cache->issuerDERCert)
{
- signstatus = CERT_VerifyCRL(crlobject->crl, cache->issuer, vfdate,
+ CERTCertificate *issuer = CERT_NewTempCertificate(cache->dbHandle,
+ cache->issuerDERCert, NULL, PR_FALSE, PR_TRUE);
+
+ if (issuer) {
+ signstatus = CERT_VerifyCRL(crlobject->crl, issuer, vfdate,
wincx);
+ CERT_DestroyCertificate(issuer);
+ }
}
if (SECSuccess != signstatus)
{
- if (!cache->issuer)
+ if (!cache->issuerDERCert)
{
/* we tried to verify without an issuer cert . This is
because this CRL came through a call to SEC_FindCrlByName.
So, we don't cache this verification failure. We'll try
to verify the CRL again when a certificate from that issuer
becomes available */
} else
{
@@ -1920,36 +1926,37 @@ static SECStatus DPCache_GetUpToDate(CRL
{
cache->lastcheck = PR_Now();
DPCache_UnlockWrite();
mustunlock = PR_FALSE;
}
}
/* add issuer certificate if it was previously unavailable */
- if (issuer && (NULL == cache->issuer) &&
+ if (issuer && (NULL == cache->issuerDERCert) &&
(SECSuccess == CERT_CheckCertUsage(issuer, KU_CRL_SIGN)))
{
/* if we didn't have a valid issuer cert yet, but we do now. add it */
DPCache_LockWrite();
- if (!cache->issuer)
+ if (!cache->issuerDERCert)
{
dirty = PR_TRUE;
- cache->issuer = CERT_DupCertificate(issuer);
+ cache->dbHandle = issuer->dbhandle;
+ cache->issuerDERCert = SECITEM_DupItem(&issuer->derCert);
}
DPCache_UnlockWrite();
}
/* verify CRLs that couldn't be checked when inserted into the cache
because the issuer cert or a verification date was unavailable.
These are CRLs that were inserted into the cache through
SEC_FindCrlByName, or through manual insertion, rather than through a
certificate verification (CERT_CheckCRL) */
- if (cache->issuer && vfdate )
+ if (cache->issuerDERCert && vfdate )
{
mustunlock = PR_FALSE;
/* re-process all unverified CRLs */
for (i = 0; i < cache->ncrls ; i++)
{
CachedCrl* savcrl = cache->crls[i];
if (!savcrl)
{
@@ -2196,17 +2203,18 @@ static SECStatus DPCache_Create(CRLDPCac
#endif
if (!cache->lock)
{
PORT_Free(cache);
return SECFailure;
}
if (issuer)
{
- cache->issuer = CERT_DupCertificate(issuer);
+ cache->dbHandle = issuer->dbhandle;
+ cache->issuerDERCert = SECITEM_DupItem(&issuer->derCert);
}
cache->distributionPoint = SECITEM_DupItem(dp);
cache->subject = SECITEM_DupItem(subject);
cache->lastfetch = 0;
cache->lastcheck = 0;
*returned = cache;
return SECSuccess;
}