diff options
author | kaie%kuix.de <devnull@localhost> | 2008-02-06 17:27:55 +0000 |
---|---|---|
committer | kaie%kuix.de <devnull@localhost> | 2008-02-06 17:27:55 +0000 |
commit | 0fdf8c7d9696885adf40b49261e2158445a46c7c (patch) | |
tree | ed28eb293c980c1fc64b2ada080ca509179f62a1 | |
parent | 446e193da4803c5fc14a877f0d8f4b391e36b736 (diff) | |
download | nss-hg-0fdf8c7d9696885adf40b49261e2158445a46c7c.tar.gz |
Bug 375019, Cache-enable pkix_OcspChecker_Check
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" |