summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaie%kuix.de <devnull@localhost>2008-02-06 17:27:55 +0000
committerkaie%kuix.de <devnull@localhost>2008-02-06 17:27:55 +0000
commit0fdf8c7d9696885adf40b49261e2158445a46c7c (patch)
treeed28eb293c980c1fc64b2ada080ca509179f62a1
parent446e193da4803c5fc14a877f0d8f4b391e36b736 (diff)
downloadnss-hg-0fdf8c7d9696885adf40b49261e2158445a46c7c.tar.gz
Bug 375019, Cache-enable pkix_OcspChecker_Check
-rw-r--r--security/nss/lib/certhigh/ocsp.c177
-rw-r--r--security/nss/lib/certhigh/ocspi.h75
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_errorstrings.h5
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_pl_pki.h2
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkixt.h4
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c57
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/pkix_tools.h11
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn3
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c279
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h87
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c108
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h8
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c24
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h1
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c1
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h1
16 files changed, 685 insertions, 158 deletions
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
index c5d5072e7..a607854bf 100644
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -95,6 +95,9 @@ struct OCSPCacheItemStr {
PRArenaPool *certStatusArena; /* NULL means: no cert status cached */
ocspCertStatus certStatus;
+ /* This may contain an error code when no OCSP response is available. */
+ SECErrorCodes missingResponseError;
+
PRPackedBool haveThisUpdate;
PRPackedBool haveNextUpdate;
PRTime thisUpdate;
@@ -592,7 +595,8 @@ ocsp_CreateCacheItemAndConsumeCertID(OCSPCacheData *cache,
arena = certID->poolp;
mark = PORT_ArenaMark(arena);
- /* ZAlloc will init all Bools to False and all Pointers to NULL */
+ /* ZAlloc will init all Bools to False and all Pointers to NULL
+ and all error codes to zero/good. */
item = (OCSPCacheItem *)PORT_ArenaZAlloc(certID->poolp,
sizeof(OCSPCacheItem));
if (!item) {
@@ -640,6 +644,7 @@ ocsp_SetCacheItemResponse(OCSPCacheItem *item,
item->certStatusArena = NULL;
return rv;
}
+ item->missingResponseError = 0;
rv = DER_GeneralizedTimeToTime(&item->thisUpdate,
&response->thisUpdate);
item->haveThisUpdate = (rv == SECSuccess);
@@ -772,6 +777,8 @@ ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache,
PR_ExitMonitor(OCSP_Global.monitor);
return rv;
}
+ } else {
+ cacheItem->missingResponseError = PORT_GetError();
}
ocsp_FreshenCacheItemNextFetchAttemptTime(cacheItem);
ocsp_CheckCacheSize(cache);
@@ -1942,13 +1949,23 @@ loser:
return NULL;
}
-static CERTOCSPRequest *
+CERTOCSPRequest *
cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
CERTCertificate *singleCert,
int64 time,
- PRBool addServiceLocator)
+ PRBool addServiceLocator,
+ CERTCertificate *signerCert)
{
CERTOCSPRequest *request;
+
+ /* XXX Support for signerCert may be implemented later,
+ * see also the comment in CERT_CreateOCSPRequest.
+ */
+ if (signerCert != NULL) {
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return NULL;
+ }
+
request = ocsp_prepareEmptyOCSPRequest();
if (!request)
return NULL;
@@ -2012,17 +2029,14 @@ CERT_CreateOCSPRequest(CERTCertList *certList, int64 time,
return NULL;
}
/*
- * XXX This should set an error, but since it is only temporary and
- * since PSM will not initially provide a way to turn on signing of
- * requests anyway, I figure we can just skip defining an error that
- * will be obsolete in the next release. When we are prepared to
- * put signing of requests back in, this entire check will go away,
- * and later in this function we will need to allocate a signature
+ * XXX When we are prepared to put signing of requests back in,
+ * we will need to allocate a signature
* structure for the request, fill in the "derCerts" field in it,
* save the signerCert there, as well as fill in the "requestorName"
* field of the tbsRequest.
*/
if (signerCert != NULL) {
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return NULL;
}
request = ocsp_prepareEmptyOCSPRequest();
@@ -3456,7 +3470,7 @@ ocsp_GetEncodedOCSPResponseForSingleCert(PRArenaPool *arena,
{
CERTOCSPRequest *request;
request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time,
- addServiceLocator);
+ addServiceLocator, NULL);
if (!request)
return NULL;
return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location,
@@ -4535,32 +4549,44 @@ ocsp_CertHasGoodStatus(ocspCertStatus *status, int64 time)
}
static SECStatus
-ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single, int64 time)
+ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single,
+ int64 time)
{
return ocsp_CertHasGoodStatus(single->certStatus, time);
}
-/* return value SECFailure means: not found or not fresh */
-static SECStatus
+/* Return value SECFailure means: not found or not fresh.
+ * On SECSuccess, the out parameters contain the OCSP status.
+ * rvOcsp contains the overall result of the OCSP operation.
+ * Depending on input parameter ignoreOcspFailureMode,
+ * a soft failure might be converted into *rvOcsp=SECSuccess.
+ * If the cached attempt to obtain OCSP information had resulted
+ * in a failure, missingResponseError shows the error code of
+ * that failure.
+ */
+SECStatus
ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
int64 time,
- SECStatus *rv_ocsp)
+ PRBool ignoreOcspFailureMode,
+ SECStatus *rvOcsp,
+ SECErrorCodes *missingResponseError)
{
OCSPCacheItem *cacheItem = NULL;
SECStatus rv = SECFailure;
- if (!certID || !rv_ocsp) {
+ if (!certID || !missingResponseError || !rvOcsp) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- *rv_ocsp = SECFailure;
+ *rvOcsp = SECFailure;
+ *missingResponseError = 0;
PR_EnterMonitor(OCSP_Global.monitor);
cacheItem = ocsp_FindCacheEntry(&OCSP_Global.cache, certID);
if (cacheItem && ocsp_IsCacheItemFresh(cacheItem)) {
/* having an arena means, we have a cached certStatus */
if (cacheItem->certStatusArena) {
- *rv_ocsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time);
+ *rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time);
rv = SECSuccess;
} else {
/*
@@ -4569,11 +4595,13 @@ ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
* However, if OCSP is optional, a recent OCSP failure is
* an allowed good state.
*/
- if (OCSP_Global.ocspFailureMode ==
+ if (!ignoreOcspFailureMode &&
+ OCSP_Global.ocspFailureMode ==
ocspMode_FailureIsNotAVerificationFailure) {
rv = SECSuccess;
- *rv_ocsp = SECSuccess;
+ *rvOcsp = SECSuccess;
}
+ *missingResponseError = cacheItem->missingResponseError;
}
}
PR_ExitMonitor(OCSP_Global.monitor);
@@ -4637,7 +4665,8 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
CERTOCSPCertID *certID;
PRBool certIDWasConsumed = PR_FALSE;
SECStatus rv = SECFailure;
- SECStatus rv_ocsp;
+ SECStatus rvOcsp;
+ SECErrorCodes dummy_error_code; /* we ignore this */
OCSP_TRACE_CERT(cert);
OCSP_TRACE_TIME("## requested validity time:", time);
@@ -4645,28 +4674,28 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
certID = CERT_CreateOCSPCertID(cert, time);
if (!certID)
return SECFailure;
- rv = ocsp_GetCachedOCSPResponseStatusIfFresh(certID, time, &rv_ocsp);
+ rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
+ certID, time, PR_FALSE, /* do not ignore global failure mode */
+ &rvOcsp, &dummy_error_code);
if (rv == SECSuccess) {
CERT_DestroyOCSPCertID(certID);
- return rv_ocsp;
+ return rvOcsp;
}
rv = ocsp_GetOCSPStatusFromNetwork(handle, certID, cert, time, pwArg,
- &certIDWasConsumed, &rv_ocsp);
+ &certIDWasConsumed,
+ &rvOcsp);
if (rv != SECSuccess) {
/* we were unable to obtain ocsp status */
PR_EnterMonitor(OCSP_Global.monitor);
- if (OCSP_Global.ocspFailureMode ==
- ocspMode_FailureIsVerificationFailure) {
- rv_ocsp = SECFailure;
- } else {
- rv_ocsp = SECSuccess;
- }
+ rvOcsp = (OCSP_Global.ocspFailureMode
+ == ocspMode_FailureIsVerificationFailure)
+ ? SECFailure : SECSuccess;
PR_ExitMonitor(OCSP_Global.monitor);
}
if (!certIDWasConsumed) {
CERT_DestroyOCSPCertID(certID);
}
- return rv_ocsp;
+ return rvOcsp;
}
/*
@@ -4878,18 +4907,90 @@ CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
CERTCertificate *signerCert,
int64 time)
{
+ /*
+ * We do not update the cache, because:
+ *
+ * CERT_GetOCSPStatusForCertID is an old exported API that was introduced
+ * before the OCSP cache got implemented.
+ *
+ * The implementation of helper function cert_ProcessOCSPResponse
+ * requires the ability to transfer ownership of the the given certID to
+ * the cache. The external API doesn't allow us to prevent the caller from
+ * destroying the certID. We don't have the original certificate available,
+ * therefore we are unable to produce another certID object (that could
+ * be stored in the cache).
+ *
+ * Should we ever implement code to produce a deep copy of certID,
+ * then this could be changed to allow updating the cache.
+ * The duplication would have to be done in
+ * cert_ProcessOCSPResponse, if the out parameter to indicate
+ * a transfer of ownership is NULL.
+ */
+ return cert_ProcessOCSPResponse(handle, response, certID,
+ signerCert, time,
+ NULL, NULL);
+}
+
+/*
+ * The first 5 parameters match the definition of CERT_GetOCSPStatusForCertID.
+ */
+SECStatus
+cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
+ CERTOCSPResponse *response,
+ CERTOCSPCertID *certID,
+ CERTCertificate *signerCert,
+ int64 time,
+ PRBool *certIDWasConsumed,
+ SECStatus *cacheUpdateStatus)
+{
SECStatus rv;
- CERTOCSPSingleResponse *single;
+ SECStatus rv_cache;
+ CERTOCSPSingleResponse *single = NULL;
rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID,
signerCert, time, &single);
- if (rv != SECSuccess)
- return rv;
- /*
- * Okay, the last step is to check whether the status says revoked,
- * and if so how that compares to the time value passed into this routine.
- */
- rv = ocsp_SingleResponseCertHasGoodStatus(single, time);
+ if (rv == SECSuccess) {
+ /*
+ * Check whether the status says revoked, and if so
+ * how that compares to the time value passed into this routine.
+ */
+ rv = ocsp_SingleResponseCertHasGoodStatus(single, time);
+ }
+
+ if (certIDWasConsumed) {
+ /*
+ * We don't have copy-of-certid implemented. In order to update
+ * the cache, the caller must supply an out variable
+ * certIDWasConsumed, allowing us to return ownership status.
+ */
+
+ PR_EnterMonitor(OCSP_Global.monitor);
+ if (OCSP_Global.maxCacheEntries >= 0) {
+ /* single == NULL means: remember response failure */
+ rv_cache =
+ ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID,
+ single, certIDWasConsumed);
+ }
+ PR_ExitMonitor(OCSP_Global.monitor);
+ if (cacheUpdateStatus) {
+ *cacheUpdateStatus = rv_cache;
+ }
+ }
+
+ return rv;
+}
+
+SECStatus
+cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
+ PRBool *certIDWasConsumed)
+{
+ SECStatus rv = SECSuccess;
+ PR_EnterMonitor(OCSP_Global.monitor);
+ if (OCSP_Global.maxCacheEntries >= 0) {
+ rv = ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, NULL,
+ certIDWasConsumed);
+ }
+ PR_ExitMonitor(OCSP_Global.monitor);
return rv;
}
diff --git a/security/nss/lib/certhigh/ocspi.h b/security/nss/lib/certhigh/ocspi.h
index 885ddde9a..4d31dd39d 100644
--- a/security/nss/lib/certhigh/ocspi.h
+++ b/security/nss/lib/certhigh/ocspi.h
@@ -63,4 +63,79 @@ ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
ocspSignature *signature,
SECItem *tbsResponseDataDER,
void *pwArg);
+
+CERTOCSPRequest *
+cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
+ CERTCertificate *singleCert,
+ int64 time,
+ PRBool addServiceLocator,
+ CERTCertificate *signerCert);
+
+SECStatus
+ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
+ int64 time,
+ PRBool ignoreOcspFailureMode,
+ SECStatus *rvOcsp,
+ SECErrorCodes *missingResponseError);
+
+/*
+ * FUNCTION: cert_ProcessOCSPResponse
+ * Same behavior and basic parameters as CERT_GetOCSPStatusForCertID.
+ * In addition it can update the OCSP cache (using information
+ * available internally to this function).
+ * INPUTS:
+ * CERTCertDBHandle *handle
+ * certificate DB of the cert that is being checked
+ * CERTOCSPResponse *response
+ * the OCSP response we want to retrieve status from.
+ * CERTOCSPCertID *certID
+ * the ID we want to look for from the response.
+ * CERTCertificate *signerCert
+ * the certificate that was used to sign the OCSP response.
+ * must be obtained via a call to CERT_VerifyOCSPResponseSignature.
+ * int64 time
+ * The time at which we're checking the status for.
+ * PRBool *certIDWasConsumed
+ * In and Out parameter.
+ * If certIDWasConsumed is NULL on input,
+ * this function might produce a deep copy of cert ID
+ * for storing it in the cache.
+ * If out value is true, ownership of parameter certID was
+ * transferred to the OCSP cache.
+ * SECStatus *cacheUpdateStatus
+ * This optional out parameter will contain the result
+ * of the cache update operation (if requested).
+ * RETURN:
+ * The return value is not influenced by the cache operation,
+ * it matches the documentation for CERT_CheckOCSPStatus
+ */
+
+SECStatus
+cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
+ CERTOCSPResponse *response,
+ CERTOCSPCertID *certID,
+ CERTCertificate *signerCert,
+ int64 time,
+ PRBool *certIDWasConsumed,
+ SECStatus *cacheUpdateStatus);
+
+/*
+ * FUNCTION: cert_RememberOCSPProcessingFailure
+ * If an application notices a failure during OCSP processing,
+ * it should finally call this function. The failure will be recorded
+ * in the OCSP cache in order to avoid repetitive failures.
+ * INPUTS:
+ * CERTOCSPCertID *certID
+ * the ID that was used for the failed OCSP processing
+ * PRBool *certIDWasConsumed
+ * Out parameter, if set to true, ownership of parameter certID was
+ * transferred to the OCSP cache.
+ * RETURN:
+ * Status of the cache update operation.
+ */
+
+SECStatus
+cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
+ PRBool *certIDWasConsumed);
+
#endif /* _OCSPI_H_ */
diff --git a/security/nss/lib/libpkix/include/pkix_errorstrings.h b/security/nss/lib/libpkix/include/pkix_errorstrings.h
index 3c949771a..2b05df990 100755
--- a/security/nss/lib/libpkix/include/pkix_errorstrings.h
+++ b/security/nss/lib/libpkix/include/pkix_errorstrings.h
@@ -20,6 +20,7 @@
*
* Contributor(s):
* Sun Microsystems, Inc.
+ * Red Hat, Inc.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -792,6 +793,7 @@ PKIX_ERRORENTRY(OBJECTNOTLOGGER,Object is not a Logger),
PKIX_ERRORENTRY(OBJECTNOTMONITORLOCK,Object is not a MonitorLock),
PKIX_ERRORENTRY(OBJECTNOTMUTEX,Object is not a Mutex),
PKIX_ERRORENTRY(OBJECTNOTNAMECONSTRAINTSCHECKERSTATE,Object is not a name constraints checker state),
+PKIX_ERRORENTRY(OBJECTNOTOCSPCERTID,Object is not an OcspCertID),
PKIX_ERRORENTRY(OBJECTNOTOCSPCHECKER,Object is not an OCSPChecker),
PKIX_ERRORENTRY(OBJECTNOTOCSPREQUEST,Object is not an OcspRequest),
PKIX_ERRORENTRY(OBJECTNOTPOLICYCHECKERSTATE,Object is not a PKIX_PolicyCheckerState),
@@ -816,6 +818,9 @@ PKIX_ERRORENTRY(OBJECTSTILLREFERENCED,Object is still referenced),
PKIX_ERRORENTRY(OBJECTTOSTRINGFAILED,PKIX_PL_Object_ToString failed),
PKIX_ERRORENTRY(OBJECTTYPESDONOTMATCH,Object types do not match),
PKIX_ERRORENTRY(OBJECTWITHNONPOSITIVEREFERENCES,Object with non-positive references),
+PKIX_ERRORENTRY(OCSPCERTIDCREATEFAILED,PKIX_PL_OcspCertID_Create failed),
+PKIX_ERRORENTRY(OCSPCERTIDGETFRESHCACHESTATUSFAILED,PKIX_PL_OcspCertID_GetFreshCacheStatus returned an error),
+PKIX_ERRORENTRY(OCSPCERTIDREMEMBEROCSPFAILUREDFAILED,PKIX_PL_OcspCertID_RememberOCSPProcessingFailure),
PKIX_ERRORENTRY(OCSPCHECKERCREATEFAILED,PKIX_OcspChecker_Create failed),
PKIX_ERRORENTRY(OCSPREQUESTCREATEFAILED,PKIX_PL_OcspRequest_Create failed),
PKIX_ERRORENTRY(OCSPREQUESTGETCERTIDFAILED,pkix_pl_OcspRequest_GetCertID failed),
diff --git a/security/nss/lib/libpkix/include/pkix_pl_pki.h b/security/nss/lib/libpkix/include/pkix_pl_pki.h
index 86ed45f75..02a4fa165 100755
--- a/security/nss/lib/libpkix/include/pkix_pl_pki.h
+++ b/security/nss/lib/libpkix/include/pkix_pl_pki.h
@@ -2572,6 +2572,7 @@ typedef PKIX_Error *
PKIX_Error *
pkix_pl_OcspRequest_Create(
PKIX_PL_Cert *cert,
+ PKIX_PL_OcspCertID *cid,
PKIX_PL_Date *validity,
PKIX_Boolean addServiceLocator,
PKIX_PL_Cert *signerCert,
@@ -2613,6 +2614,7 @@ pkix_pl_OcspResponse_VerifySignature(
PKIX_Error *
pkix_pl_OcspResponse_GetStatusForCert(
+ PKIX_PL_OcspCertID *cid,
PKIX_PL_OcspResponse *response,
PKIX_Boolean *pPassed,
SECErrorCodes *pReturnCode,
diff --git a/security/nss/lib/libpkix/include/pkixt.h b/security/nss/lib/libpkix/include/pkixt.h
index eef2861a3..54360dde8 100755
--- a/security/nss/lib/libpkix/include/pkixt.h
+++ b/security/nss/lib/libpkix/include/pkixt.h
@@ -20,6 +20,7 @@
*
* Contributor(s):
* Sun Microsystems, Inc.
+ * Red Hat, Inc.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -161,6 +162,7 @@ typedef struct PKIX_PL_LdapDefaultClientStruct PKIX_PL_LdapDefaultClient;
typedef struct PKIX_PL_SocketStruct PKIX_PL_Socket;
typedef struct PKIX_PL_InfoAccessStruct PKIX_PL_InfoAccess;
typedef struct PKIX_PL_AIAMgrStruct PKIX_PL_AIAMgr;
+typedef struct PKIX_PL_OcspCertIDStruct PKIX_PL_OcspCertID;
typedef struct PKIX_PL_OcspRequestStruct PKIX_PL_OcspRequest;
typedef struct PKIX_PL_OcspResponseStruct PKIX_PL_OcspResponse;
typedef struct PKIX_PL_HttpClientStruct PKIX_PL_HttpClient;
@@ -237,6 +239,7 @@ typedef int PKIX_Boolean;
TYPEMACRO(MONITORLOCK), \
TYPEMACRO(MUTEX), \
TYPEMACRO(OBJECT), \
+ TYPEMACRO(OCSPCERTID), \
TYPEMACRO(OCSPCHECKER), \
TYPEMACRO(OCSPREQUEST), \
TYPEMACRO(OCSPRESPONSE), \
@@ -333,6 +336,7 @@ typedef enum { /* Now invoke all those TYPEMACROs to assign the numbers */
ERRMACRO(MONITORLOCK), \
ERRMACRO(MUTEX), \
ERRMACRO(OBJECT), \
+ ERRMACRO(OCSPCERTID), \
ERRMACRO(OCSPCHECKER), \
ERRMACRO(OCSPREQUEST), \
ERRMACRO(OCSPRESPONSE), \
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
index 3b79c88dc..d968b0e5a 100644
--- a/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
+++ b/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
@@ -20,6 +20,7 @@
*
* Contributor(s):
* Sun Microsystems, Inc.
+ * Red Hat, Inc.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -42,6 +43,8 @@
*/
#include "pkix_ocspchecker.h"
+#include "pkix_pl_ocspcertid.h"
+#include "pkix_error.h"
/* --Private-Functions-------------------------------------------- */
@@ -143,11 +146,13 @@ pkix_OcspChecker_Check(
PKIX_UInt32 *pResultCode,
void *plContext)
{
- SECErrorCodes resultCode = 0;
+ SECErrorCodes resultCode = SEC_ERROR_REVOKED_CERTIFICATE_OCSP;
PKIX_Boolean uriFound = PKIX_FALSE;
PKIX_Boolean passed = PKIX_FALSE;
PKIX_OcspChecker *checker = NULL;
+ PKIX_PL_OcspCertID *cid = NULL;
PKIX_PL_OcspRequest *request = NULL;
+ PKIX_PL_Date *validity = NULL;
void *nbioContext = NULL;
PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_Check");
@@ -167,13 +172,47 @@ pkix_OcspChecker_Check(
if (nbioContext == 0) {
/* We are initiating a check, not resuming previous I/O. */
+ PKIX_Boolean hasFreshStatus = PKIX_FALSE;
+ PKIX_Boolean statusIsGood = PKIX_FALSE;
+
+ PKIX_CHECK(PKIX_PL_OcspCertID_Create
+ (cert,
+ validity,
+ &cid,
+ plContext),
+ PKIX_OCSPCERTIDCREATEFAILED);
+
+ if (!cid) {
+ goto cleanup;
+ }
+
+ PKIX_CHECK(PKIX_PL_OcspCertID_GetFreshCacheStatus
+ (cid,
+ validity,
+ &hasFreshStatus,
+ &statusIsGood,
+ &resultCode,
+ plContext),
+ PKIX_OCSPCERTIDGETFRESHCACHESTATUSFAILED);
+
+ if (hasFreshStatus) {
+ /* avoid updating the cache with a cached result... */
+ passed = PKIX_TRUE;
+
+ if (statusIsGood) {
+ resultCode = 0;
+ }
+ goto cleanup;
+ }
+
PKIX_INCREF(cert);
checker->cert = cert;
/* create request */
PKIX_CHECK(pkix_pl_OcspRequest_Create
(cert,
- NULL, /* PKIX_PL_Date *validity */
+ cid,
+ validity,
PKIX_FALSE, /* PKIX_Boolean addServiceLocator */
NULL, /* PKIX_PL_Cert *signerCert */
&uriFound,
@@ -183,6 +222,7 @@ pkix_OcspChecker_Check(
/* No uri to check is considered passing! */
if (uriFound == PKIX_FALSE) {
+ /* no caching for certs lacking URI */
passed = PKIX_TRUE;
resultCode = 0;
goto cleanup;
@@ -244,12 +284,22 @@ pkix_OcspChecker_Check(
}
PKIX_CHECK(pkix_pl_OcspResponse_GetStatusForCert
- ((checker->response), &passed, &resultCode, plContext),
+ (cid, (checker->response), &passed, &resultCode, plContext),
PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
cleanup:
+ if (!passed && cid) {
+ PKIX_Error *err;
+ err = PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
+ cid, plContext);
+ if (err) {
+ PKIX_PL_Object_DecRef((PKIX_PL_Object*)err, plContext);
+ }
+ }
+
*pResultCode = (PKIX_UInt32)resultCode;
+ PKIX_DECREF(cid);
PKIX_DECREF(request);
PKIX_DECREF(checker->response);
@@ -269,7 +319,6 @@ pkix_OcspChecker_Create(
void *plContext)
{
PKIX_OcspChecker *checkerObject = NULL;
- PKIX_RevocationChecker *revChecker = NULL;
PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_Create");
PKIX_NULLCHECK_ONE(pChecker);
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_tools.h b/security/nss/lib/libpkix/pkix/util/pkix_tools.h
index 86c2cb467..2096f2a8f 100755
--- a/security/nss/lib/libpkix/pkix/util/pkix_tools.h
+++ b/security/nss/lib/libpkix/pkix/util/pkix_tools.h
@@ -20,6 +20,7 @@
*
* Contributor(s):
* Sun Microsystems, Inc.
+ * Red Hat, Inc.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -1271,6 +1272,16 @@ extern const PKIX_StdVars zeroStdVars;
#define PKIX_OCSPCHECKER_DEBUG_ARG(expr, arg)
#endif
+#if PKIX_OCSPCERTIDDEBUG
+#define PKIX_OCSPCERTID_DEBUG(expr) \
+ PKIX_DEBUG(expr)
+#define PKIX_OCSPCERTID_DEBUG_ARG(expr, arg) \
+ PKIX_DEBUG_ARG(expr, arg)
+#else
+#define PKIX_OCSPCERTID_DEBUG(expr)
+#define PKIX_OCSPCERTID_DEBUG_ARG(expr, arg)
+#endif
+
#if PKIX_OCSPREQUESTDEBUG
#define PKIX_OCSPREQUEST_DEBUG(expr) \
PKIX_DEBUG(expr)
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn b/security/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn
index df9211c59..34941a36c 100755
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn
@@ -21,6 +21,7 @@
#
# Contributor(s):
# Sun Microsystems, Inc.
+# Red Hat, Inc.
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -56,6 +57,7 @@ PRIVATE_EXPORTS = \
pkix_pl_ocspresponse.h \
pkix_pl_publickey.h \
pkix_pl_x500name.h \
+ pkix_pl_ocspcertid.h \
$(NULL)
MODULE = nss
@@ -76,6 +78,7 @@ CSRCS = \
pkix_pl_ocspresponse.c \
pkix_pl_publickey.c \
pkix_pl_x500name.c \
+ pkix_pl_ocspcertid.c \
$(NULL)
REQUIRES = dbm
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c
new file mode 100644
index 000000000..75e0e2eab
--- /dev/null
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c
@@ -0,0 +1,279 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the PKIX-C library.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Red Hat, Inc.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * pkix_pl_ocspcertid.c
+ *
+ * Certificate ID Object for OCSP
+ *
+ */
+
+#include "pkix_pl_ocspcertid.h"
+
+/* --Private-Cert-Functions------------------------------------- */
+
+/*
+ * FUNCTION: pkix_pl_OcspCertID_Destroy
+ * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_pl_OcspCertID_Destroy(
+ PKIX_PL_Object *object,
+ void *plContext)
+{
+ PKIX_PL_OcspCertID *certID = NULL;
+
+ PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_Destroy");
+
+ PKIX_NULLCHECK_ONE(object);
+
+ PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPCERTID_TYPE, plContext),
+ PKIX_OBJECTNOTOCSPCERTID);
+
+ certID = (PKIX_PL_OcspCertID *)object;
+
+ if (!certID->certIDWasConsumed) {
+ CERT_DestroyOCSPCertID(certID->certID);
+ }
+
+cleanup:
+
+ PKIX_RETURN(OCSPCERTID);
+}
+
+/*
+ * FUNCTION: pkix_pl_OcspCertID_RegisterSelf
+ * DESCRIPTION:
+ * Registers PKIX_PUBLICKEY_TYPE and its related functions
+ * with systemClasses[]
+ * THREAD SAFETY:
+ * Not Thread Safe - for performance and complexity reasons
+ *
+ * Since this function is only called by PKIX_PL_Initialize, which should
+ * only be called once, it is acceptable that this function is not
+ * thread-safe.
+ */
+PKIX_Error *
+pkix_pl_OcspCertID_RegisterSelf(void *plContext)
+{
+ extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
+ pkix_ClassTable_Entry entry;
+
+ PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_RegisterSelf");
+
+ entry.description = "OcspCertID";
+ entry.objCounter = 0;
+ entry.typeObjectSize = sizeof(PKIX_PL_OcspCertID);
+ entry.destructor = pkix_pl_OcspCertID_Destroy;
+ entry.equalsFunction = NULL;
+ entry.hashcodeFunction = NULL;
+ entry.toStringFunction = NULL;
+ entry.comparator = NULL;
+ entry.duplicateFunction = pkix_duplicateImmutable;
+ systemClasses[PKIX_OCSPCERTID_TYPE] = entry;
+
+ PKIX_RETURN(OCSPCERTID);
+}
+
+/* --Public-Functions------------------------------------------------------- */
+
+/*
+ * FUNCTION: PKIX_PL_OcspCertID_Create
+ * DESCRIPTION:
+ *
+ * This function creates an OcspCertID for a given certificate,
+ * to be used with OCSP transactions.
+ *
+ * If a Date is provided in "validity" it may be used in the search for the
+ * issuer of "cert" but has no effect on the request itself.
+ *
+ * PARAMETERS:
+ * "cert"
+ * Address of the Cert for which an OcspCertID is to be created. Must be
+ * non-NULL.
+ * "validity"
+ * Address of the Date for which the Cert's validity is to be determined.
+ * May be NULL.
+ * "object"
+ * Address at which the result is stored. Must be non-NULL.
+ * "plContext"
+ * Platform-specific context pointer.
+ * THREAD SAFETY:
+ * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ * Returns NULL if the function succeeds.
+ * Returns an OcspCertID Error if the function fails in a non-fatal way.
+ * Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+PKIX_PL_OcspCertID_Create(
+ PKIX_PL_Cert *cert,
+ PKIX_PL_Date *validity,
+ PKIX_PL_OcspCertID **object,
+ void *plContext)
+{
+ PKIX_PL_OcspCertID *cid;
+ int64 time = 0;
+
+ PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_Create");
+ PKIX_NULLCHECK_TWO(cert, object);
+
+ PKIX_CHECK(PKIX_PL_Object_Alloc
+ (PKIX_OCSPCERTID_TYPE,
+ sizeof (PKIX_PL_OcspCertID),
+ (PKIX_PL_Object **)&cid,
+ plContext),
+ PKIX_COULDNOTCREATEOBJECT);
+
+ cid->certIDWasConsumed = PR_FALSE;
+
+ if (validity != NULL) {
+ PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
+ PKIX_DATEGETPRTIMEFAILED);
+ } else {
+ time = PR_Now();
+ }
+
+ cid->certID = CERT_CreateOCSPCertID(cert->nssCert, time);
+ *object = cid;
+ cid = NULL;
+cleanup:
+ PKIX_RETURN(OCSPCERTID);
+}
+
+/*
+ * FUNCTION: PKIX_PL_OcspCertID_GetFreshCacheStatus
+ * DESCRIPTION:
+ *
+ * This function may return cached OCSP results for the provided
+ * certificate, but only if stored information is still considered to be
+ * fresh.
+ *
+ * PARAMETERS
+ * "cid"
+ * A certificate ID as used by OCSP
+ * "validity"
+ * Optional date parameter to request validity for a specifc time.
+ * "hasFreshStatus"
+ * Output parameter, if the function successed to find fresh cached
+ * information, this will be set to true. Must be non-NULL.
+ * "statusIsGood"
+ * The good/bad result stored in the cache. Must be non-NULL.
+ * "missingResponseError"
+ * If OCSP status is "bad", this variable may indicate the exact
+ * reason why the previous OCSP request had failed.
+ * "plContext"
+ * Platform-specific context pointer.
+ * RETURNS:
+ * Returns NULL if the function succeeds.
+ * Returns an OcspCertID Error if the function fails in a non-fatal way.
+ * Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+PKIX_PL_OcspCertID_GetFreshCacheStatus(
+ PKIX_PL_OcspCertID *cid,
+ PKIX_PL_Date *validity,
+ PKIX_Boolean *hasFreshStatus,
+ PKIX_Boolean *statusIsGood,
+ SECErrorCodes *missingResponseError,
+ void *plContext)
+{
+ int64 time = 0;
+ SECStatus rv;
+ SECStatus rvOcsp;
+
+ PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_GetFreshCacheStatus");
+ PKIX_NULLCHECK_THREE(cid, hasFreshStatus, statusIsGood);
+
+ if (validity != NULL) {
+ PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
+ PKIX_DATEGETPRTIMEFAILED);
+ } else {
+ time = PR_Now();
+ }
+
+ rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
+ cid->certID, time, PR_TRUE, /* ignore OCSP failure mode */
+ &rvOcsp, missingResponseError);
+
+ /* We ignore rvBasedOnOcspFailureMode, we are interested in the
+ * real result.
+ * XXX This may change in the future, when libpkix allows the
+ * application to specify the desired failure behavior.
+ */
+
+ *hasFreshStatus = (rv == SECSuccess);
+ if (*hasFreshStatus) {
+ *statusIsGood = (rvOcsp == SECSuccess);
+ }
+cleanup:
+ PKIX_RETURN(OCSPCERTID);
+}
+
+/*
+ * FUNCTION: PKIX_PL_OcspCertID_RememberOCSPProcessingFailure
+ * DESCRIPTION:
+ *
+ * Information about the current failure associated to the given certID
+ * will be remembered in the cache, potentially allowing future calls
+ * to prevent repetitive OCSP requests.
+ * After this function got called, it may no longer be safe to
+ * use the provided cid parameter, because ownership might have been
+ * transfered to the cache. This status will be recorded inside the
+ * cid object.
+ *
+ * PARAMETERS
+ * "cid"
+ * The certificate ID associated to a failed OCSP processing.
+ * "plContext"
+ * Platform-specific context pointer.
+ * RETURNS:
+ * Returns NULL if the function succeeds.
+ * Returns an OcspCertID Error if the function fails in a non-fatal way.
+ * Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
+ PKIX_PL_OcspCertID *cid,
+ void *plContext)
+{
+ PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_RememberOCSPProcessingFailure");
+
+ cert_RememberOCSPProcessingFailure(cid->certID, &cid->certIDWasConsumed);
+
+ PKIX_RETURN(OCSPCERTID);
+}
+
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h
new file mode 100644
index 000000000..972d34406
--- /dev/null
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h
@@ -0,0 +1,87 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the PKIX-C library.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are
+ * Copyright 2008 Red Hat, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Red Hat, Inc.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * pkix_pl_ocspcertid.h
+ *
+ * Public Key Object Definitions
+ *
+ */
+
+#ifndef _PKIX_PL_OCSPCERTID_H
+#define _PKIX_PL_OCSPCERTID_H
+
+#include "pkix_pl_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct PKIX_PL_OcspCertIDStruct {
+ CERTOCSPCertID *certID;
+ PRBool certIDWasConsumed;
+};
+
+/* see source file for function documentation */
+
+PKIX_Error *pkix_pl_OcspCertID_RegisterSelf(void *plContext);
+
+PKIX_Error *
+PKIX_PL_OcspCertID_Create(
+ PKIX_PL_Cert *cert,
+ PKIX_PL_Date *validity,
+ PKIX_PL_OcspCertID **object,
+ void *plContext);
+
+PKIX_Error *
+PKIX_PL_OcspCertID_GetFreshCacheStatus(
+ PKIX_PL_OcspCertID *cid,
+ PKIX_PL_Date *validity,
+ PKIX_Boolean *hasFreshStatus,
+ PKIX_Boolean *statusIsGood,
+ SECErrorCodes *missingResponseError,
+ void *plContext);
+
+PKIX_Error *
+PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
+ PKIX_PL_OcspCertID *cid,
+ void *plContext);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PKIX_PL_OCSPCERTID_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c
index 438d364fe..f523a0a88 100644
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c
@@ -53,7 +53,6 @@ pkix_pl_OcspRequest_Destroy(
void *plContext)
{
PKIX_PL_OcspRequest *ocspReq = NULL;
- PRCList *node = NULL;
PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Destroy");
PKIX_NULLCHECK_ONE(object);
@@ -64,29 +63,15 @@ pkix_pl_OcspRequest_Destroy(
ocspReq = (PKIX_PL_OcspRequest *)object;
if (ocspReq->decoded != NULL) {
- PKIX_PL_NSSCALL(OCSPREQUEST, CERT_DestroyOCSPRequest,
- (ocspReq->decoded));
+ CERT_DestroyOCSPRequest(ocspReq->decoded);
}
if (ocspReq->encoded != NULL) {
- PKIX_PL_NSSCALL(OCSPREQUEST, SECITEM_FreeItem,
- (ocspReq->encoded, PR_TRUE));
- }
-
- if (ocspReq->certList != NULL) {
- /*
- * The CertList thinks it owns the nssCert. If it destroys it,
- * PKIX_PL_Cert_Destroy(ocspReq->cert) will crash. Let's
- * remove the nssCert first, and then destroy the CertList.
- */
- node = PR_LIST_HEAD(&ocspReq->certList->list);
- PR_REMOVE_LINK(node);
- PKIX_PL_NSSCALL(OCSPREQUEST, CERT_DestroyCertList,
- (ocspReq->certList));
+ SECITEM_FreeItem(ocspReq->encoded, PR_TRUE);
}
if (ocspReq->location != NULL) {
- PKIX_PL_NSSCALL(OCSPREQUEST, PORT_Free, (ocspReq->location));
+ PORT_Free(ocspReq->location);
}
PKIX_DECREF(ocspReq->cert);
@@ -303,6 +288,7 @@ pkix_pl_OcspRequest_RegisterSelf(void *plContext)
PKIX_Error *
pkix_pl_OcspRequest_Create(
PKIX_PL_Cert *cert,
+ PKIX_PL_OcspCertID *cid,
PKIX_PL_Date *validity,
PKIX_Boolean addServiceLocator,
PKIX_PL_Cert *signerCert,
@@ -315,7 +301,6 @@ pkix_pl_OcspRequest_Create(
SECStatus rv = SECFailure;
SECItem *encoding = NULL;
CERTOCSPRequest *certRequest = NULL;
- CERTCertList *certList = NULL;
int64 time = 0;
PRBool addServiceLocatorExtension = PR_FALSE;
CERTCertificate *nssCert = NULL;
@@ -348,7 +333,6 @@ pkix_pl_OcspRequest_Create(
ocspRequest->decoded = NULL;
ocspRequest->encoded = NULL;
- ocspRequest->certList = NULL;
ocspRequest->location = NULL;
nssCert = cert->nssCert;
@@ -357,12 +341,10 @@ pkix_pl_OcspRequest_Create(
* Does this Cert have an Authority Information Access extension with
* the URI of an OCSP responder?
*/
- PKIX_PL_NSSCALLRV
- (OCSPREQUEST, location, CERT_GetOCSPAuthorityInfoAccessLocation,
- (nssCert));
+ location = CERT_GetOCSPAuthorityInfoAccessLocation(nssCert);
if (location == NULL) {
- PKIX_PL_NSSCALLRV(OCSPREQUEST, locError, PORT_GetError, ());
+ locError = PORT_GetError();
if (locError == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) {
*pURIFound = PKIX_FALSE;
goto cleanup;
@@ -378,48 +360,26 @@ pkix_pl_OcspRequest_Create(
nssSignerCert = signerCert->nssCert;
}
- /*
- * Build a CertList with this one Cert. But be careful: apparently it
- * is customary for CertLists to "own" the Certs, and to destroy
- * them as part of CERT_DestroyCertList. We must remember to remove
- * this Cert from the List before destroying the List. Otherwise it
- * will be destroyed when the CertList is destroyed and again when
- * the PKIX_PL_Cert that owns it is destroyed.
- */
- PKIX_PL_NSSCALLRV(OCSPREQUEST, certList, CERT_NewCertList, ());
- if (certList == NULL) {
- PKIX_ERROR(PKIX_UNABLETOCREATENEWCERTLIST);
- }
-
- ocspRequest->certList = certList;
-
- PKIX_PL_NSSCALLRV(OCSPREQUEST, rv, CERT_AddCertToListTail,
- (certList, nssCert));
-
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_UNABLETOADDCERTTOCERTLIST);
- }
-
if (validity != NULL) {
PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
PKIX_DATEGETPRTIMEFAILED);
} else {
- PKIX_PL_NSSCALLRV(OCSPREQUEST, time, PR_Now, ());
+ time = PR_Now();
}
addServiceLocatorExtension =
((addServiceLocator == PKIX_TRUE)? PR_TRUE : PR_FALSE);
- PKIX_PL_NSSCALLRV(OCSPREQUEST, certRequest, CERT_CreateOCSPRequest,
- (certList, time, addServiceLocatorExtension, nssSignerCert));
+ certRequest = cert_CreateSingleCertOCSPRequest(
+ cid->certID, cert->nssCert, time,
+ addServiceLocatorExtension, nssSignerCert);
if (certRequest == NULL) {
PKIX_ERROR(PKIX_UNABLETOCREATECERTOCSPREQUEST);
}
- PKIX_PL_NSSCALLRV
- (OCSPREQUEST, rv, CERT_AddOCSPAcceptableResponses,
- (certRequest, SEC_OID_PKIX_OCSP_BASIC_RESPONSE));
+ rv = CERT_AddOCSPAcceptableResponses(
+ certRequest, SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
if (rv == SECFailure) {
PKIX_ERROR(PKIX_UNABLETOADDACCEPTABLERESPONSESTOREQUEST);
@@ -427,8 +387,7 @@ pkix_pl_OcspRequest_Create(
ocspRequest->decoded = certRequest;
- PKIX_PL_NSSCALLRV(OCSPREQUEST, encoding, CERT_EncodeOCSPRequest,
- (NULL, certRequest, NULL));
+ encoding = CERT_EncodeOCSPRequest(NULL, certRequest, NULL);
ocspRequest->encoded = encoding;
@@ -512,44 +471,3 @@ pkix_pl_OcspRequest_GetLocation(
PKIX_RETURN(OCSPREQUEST);
}
-
-/*
- * FUNCTION: pkix_pl_OcspRequest_GetCertID
- * DESCRIPTION:
- *
- * This function obtains the certID from the OcspRequest pointed to
- * by "request", storing the result at "pCertID".
- *
- * PARAMETERS
- * "request"
- * The address of the OcspRequest whose certID is to be retrieved. Must
- * be non-NULL.
- * "pCertID"
- * The address at which is stored the certID of the request. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_OcspRequest_GetCertID(
- PKIX_PL_OcspRequest *request,
- CERTOCSPCertID **pCertID,
- void *plContext)
-{
- ocspTBSRequest *tbsRequest = NULL;
-
- PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_GetCertID");
- PKIX_NULLCHECK_TWO(request, pCertID);
-
- PKIX_NULLCHECK_ONE(request->decoded);
- tbsRequest = request->decoded->tbsRequest;
- PKIX_NULLCHECK_ONE(tbsRequest);
- *pCertID = tbsRequest->requestList[0]->reqCert;
-
- PKIX_RETURN(OCSPREQUEST);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h
index d309edf0a..2012a64e3 100644
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h
@@ -55,7 +55,6 @@ struct PKIX_PL_OcspRequestStruct{
PKIX_PL_Date *validity;
PKIX_Boolean addServiceLocator;
PKIX_PL_Cert *signerCert;
- CERTCertList *certList;
CERTOCSPRequest *decoded;
SECItem *encoded;
char *location;
@@ -66,6 +65,7 @@ struct PKIX_PL_OcspRequestStruct{
PKIX_Error *
pkix_pl_OcspRequest_Create(
PKIX_PL_Cert *cert,
+ PKIX_PL_OcspCertID *cid,
PKIX_PL_Date *validity,
PKIX_Boolean addServiceLocator,
PKIX_PL_Cert *signerCert,
@@ -85,12 +85,6 @@ pkix_pl_OcspRequest_GetLocation(
char **pLocation,
void *plContext);
-PKIX_Error *
-pkix_pl_OcspRequest_GetCertID(
- PKIX_PL_OcspRequest *request,
- CERTOCSPCertID **pCertID,
- void *plContext);
-
PKIX_Error *pkix_pl_OcspRequest_RegisterSelf(void *plContext);
#ifdef __cplusplus
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
index 8cbb1f32d..4fe32ae79 100644
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
@@ -987,13 +987,14 @@ cleanup:
*/
PKIX_Error *
pkix_pl_OcspResponse_GetStatusForCert(
+ PKIX_PL_OcspCertID *cid,
PKIX_PL_OcspResponse *response,
PKIX_Boolean *pPassed,
SECErrorCodes *pReturnCode,
void *plContext)
{
- CERTOCSPCertID *certId = NULL;
SECStatus rv = SECFailure;
+ SECStatus rvCache;
PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_GetStatusForCert");
PKIX_NULLCHECK_THREE(response, pPassed, pReturnCode);
@@ -1005,25 +1006,20 @@ pkix_pl_OcspResponse_GetStatusForCert(
*/
PKIX_NULLCHECK_TWO(response->signerCert, response->request);
- PKIX_CHECK(
- pkix_pl_OcspRequest_GetCertID(
- (PKIX_PL_OcspRequest*)response->request, &certId, plContext),
- PKIX_OCSPREQUESTGETCERTIDFAILED);
-
- rv = CERT_GetOCSPStatusForCertID (response->handle,
- response->nssOCSPResponse,
- certId,
- response->signerCert,
- PR_Now());
+ rv = cert_ProcessOCSPResponse(response->handle,
+ response->nssOCSPResponse,
+ cid->certID,
+ response->signerCert,
+ PR_Now(),
+ &cid->certIDWasConsumed,
+ &rvCache);
if (rv == SECSuccess) {
*pPassed = PKIX_TRUE;
*pReturnCode = 0;
} else {
*pPassed = PKIX_FALSE;
- PKIX_PL_NSSCALLRV
- (OCSPRESPONSE, *pReturnCode, PORT_GetError, ());
+ *pReturnCode = PORT_GetError();
}
-cleanup:
PKIX_RETURN(OCSPRESPONSE);
}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
index 1e3485a5a..f42356f6c 100644
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
@@ -45,6 +45,7 @@
#define _PKIX_PL_OCSPRESPONSE_H
#include "pkix_pl_common.h"
+#include "pkix_pl_ocspcertid.h"
#include "hasht.h"
#include "cryptohi.h"
#include "ocspti.h"
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
index b71d75904..18cc43fc9 100755
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
@@ -223,6 +223,7 @@ PKIX_PL_Initialize(
pkix_pl_InfoAccess_RegisterSelf(plContext);
pkix_pl_AIAMgr_RegisterSelf(plContext);
pkix_OcspChecker_RegisterSelf(plContext);
+ pkix_pl_OcspCertID_RegisterSelf(plContext);
pkix_pl_OcspRequest_RegisterSelf(plContext);
pkix_pl_OcspResponse_RegisterSelf(plContext);
pkix_pl_HttpDefaultClient_RegisterSelf(plContext);
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
index 39054d8c1..80e1e0027 100755
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
@@ -99,6 +99,7 @@
#include "pkix_pl_nameconstraints.h"
#include "pkix_nameconstraintschecker.h"
#include "pkix_ocspchecker.h"
+#include "pkix_pl_ocspcertid.h"
#include "pkix_pl_ocsprequest.h"
#include "pkix_pl_ocspresponse.h"
#include "pkix_pl_httpdefaultclient.h"