diff options
Diffstat (limited to '')
-rw-r--r-- | security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c | 251 |
1 files changed, 251 insertions, 0 deletions
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 0000000000..679811dec1 --- /dev/null +++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c @@ -0,0 +1,251 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* + * 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->certID) { + 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 = NULL; + PRTime 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); + + 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); + if (!cid->certID) { + PKIX_ERROR(PKIX_COULDNOTCREATEOBJECT); + } + + *object = cid; + cid = NULL; +cleanup: + PKIX_DECREF(cid); + 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) +{ + PRTime time = 0; + SECStatus rv; + SECStatus rvOcsp; + OCSPFreshness freshness; + + 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_GetCachedOCSPResponseStatus( + cid->certID, time, PR_TRUE, /*ignoreGlobalOcspFailureSetting*/ + &rvOcsp, missingResponseError, &freshness); + + *hasFreshStatus = (rv == SECSuccess && freshness == ocspFresh); + 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) +{ + PRBool certIDWasConsumed = PR_FALSE; + + PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_RememberOCSPProcessingFailure"); + PKIX_NULLCHECK_TWO(cid, cid->certID); + + cert_RememberOCSPProcessingFailure(cid->certID, &certIDWasConsumed); + + if (certIDWasConsumed) { + cid->certID = NULL; + } + + PKIX_RETURN(OCSPCERTID); +} + |