pkix_pl_ocspcertid.c (7828B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* 5 * pkix_pl_ocspcertid.c 6 * 7 * Certificate ID Object for OCSP 8 * 9 */ 10 11 #include "pkix_pl_ocspcertid.h" 12 13 /* --Private-Cert-Functions------------------------------------- */ 14 15 /* 16 * FUNCTION: pkix_pl_OcspCertID_Destroy 17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 18 */ 19 static PKIX_Error * 20 pkix_pl_OcspCertID_Destroy( 21 PKIX_PL_Object *object, 22 void *plContext) 23 { 24 PKIX_PL_OcspCertID *certID = NULL; 25 26 PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_Destroy"); 27 28 PKIX_NULLCHECK_ONE(object); 29 30 PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPCERTID_TYPE, plContext), 31 PKIX_OBJECTNOTOCSPCERTID); 32 33 certID = (PKIX_PL_OcspCertID *)object; 34 35 if (certID->certID) { 36 CERT_DestroyOCSPCertID(certID->certID); 37 } 38 39 cleanup: 40 41 PKIX_RETURN(OCSPCERTID); 42 } 43 44 /* 45 * FUNCTION: pkix_pl_OcspCertID_RegisterSelf 46 * DESCRIPTION: 47 * Registers PKIX_PUBLICKEY_TYPE and its related functions 48 * with systemClasses[] 49 * THREAD SAFETY: 50 * Not Thread Safe - for performance and complexity reasons 51 * 52 * Since this function is only called by PKIX_PL_Initialize, which should 53 * only be called once, it is acceptable that this function is not 54 * thread-safe. 55 */ 56 PKIX_Error * 57 pkix_pl_OcspCertID_RegisterSelf(void *plContext) 58 { 59 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 60 pkix_ClassTable_Entry entry; 61 62 PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_RegisterSelf"); 63 64 entry.description = "OcspCertID"; 65 entry.objCounter = 0; 66 entry.typeObjectSize = sizeof(PKIX_PL_OcspCertID); 67 entry.destructor = pkix_pl_OcspCertID_Destroy; 68 entry.equalsFunction = NULL; 69 entry.hashcodeFunction = NULL; 70 entry.toStringFunction = NULL; 71 entry.comparator = NULL; 72 entry.duplicateFunction = pkix_duplicateImmutable; 73 systemClasses[PKIX_OCSPCERTID_TYPE] = entry; 74 75 PKIX_RETURN(OCSPCERTID); 76 } 77 78 /* --Public-Functions------------------------------------------------------- */ 79 80 /* 81 * FUNCTION: PKIX_PL_OcspCertID_Create 82 * DESCRIPTION: 83 * 84 * This function creates an OcspCertID for a given certificate, 85 * to be used with OCSP transactions. 86 * 87 * If a Date is provided in "validity" it may be used in the search for the 88 * issuer of "cert" but has no effect on the request itself. 89 * 90 * PARAMETERS: 91 * "cert" 92 * Address of the Cert for which an OcspCertID is to be created. Must be 93 * non-NULL. 94 * "validity" 95 * Address of the Date for which the Cert's validity is to be determined. 96 * May be NULL. 97 * "object" 98 * Address at which the result is stored. Must be non-NULL. 99 * "plContext" 100 * Platform-specific context pointer. 101 * THREAD SAFETY: 102 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 103 * RETURNS: 104 * Returns NULL if the function succeeds. 105 * Returns an OcspCertID Error if the function fails in a non-fatal way. 106 * Returns a Fatal Error if the function fails in an unrecoverable way. 107 */ 108 PKIX_Error * 109 PKIX_PL_OcspCertID_Create( 110 PKIX_PL_Cert *cert, 111 PKIX_PL_Date *validity, 112 PKIX_PL_OcspCertID **object, 113 void *plContext) 114 { 115 PKIX_PL_OcspCertID *cid = NULL; 116 PRTime time = 0; 117 118 PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_Create"); 119 PKIX_NULLCHECK_TWO(cert, object); 120 121 PKIX_CHECK(PKIX_PL_Object_Alloc 122 (PKIX_OCSPCERTID_TYPE, 123 sizeof (PKIX_PL_OcspCertID), 124 (PKIX_PL_Object **)&cid, 125 plContext), 126 PKIX_COULDNOTCREATEOBJECT); 127 128 if (validity != NULL) { 129 PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext), 130 PKIX_DATEGETPRTIMEFAILED); 131 } else { 132 time = PR_Now(); 133 } 134 135 cid->certID = CERT_CreateOCSPCertID(cert->nssCert, time); 136 if (!cid->certID) { 137 PKIX_ERROR(PKIX_COULDNOTCREATEOBJECT); 138 } 139 140 *object = cid; 141 cid = NULL; 142 cleanup: 143 PKIX_DECREF(cid); 144 PKIX_RETURN(OCSPCERTID); 145 } 146 147 /* 148 * FUNCTION: PKIX_PL_OcspCertID_GetFreshCacheStatus 149 * DESCRIPTION: 150 * 151 * This function may return cached OCSP results for the provided 152 * certificate, but only if stored information is still considered to be 153 * fresh. 154 * 155 * PARAMETERS 156 * "cid" 157 * A certificate ID as used by OCSP 158 * "validity" 159 * Optional date parameter to request validity for a specifc time. 160 * "hasFreshStatus" 161 * Output parameter, if the function successed to find fresh cached 162 * information, this will be set to true. Must be non-NULL. 163 * "statusIsGood" 164 * The good/bad result stored in the cache. Must be non-NULL. 165 * "missingResponseError" 166 * If OCSP status is "bad", this variable may indicate the exact 167 * reason why the previous OCSP request had failed. 168 * "plContext" 169 * Platform-specific context pointer. 170 * RETURNS: 171 * Returns NULL if the function succeeds. 172 * Returns an OcspCertID Error if the function fails in a non-fatal way. 173 * Returns a Fatal Error if the function fails in an unrecoverable way. 174 */ 175 PKIX_Error * 176 PKIX_PL_OcspCertID_GetFreshCacheStatus( 177 PKIX_PL_OcspCertID *cid, 178 PKIX_PL_Date *validity, 179 PKIX_Boolean *hasFreshStatus, 180 PKIX_Boolean *statusIsGood, 181 SECErrorCodes *missingResponseError, 182 void *plContext) 183 { 184 PRTime time = 0; 185 SECStatus rv; 186 SECStatus rvOcsp; 187 OCSPFreshness freshness; 188 189 PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_GetFreshCacheStatus"); 190 PKIX_NULLCHECK_THREE(cid, hasFreshStatus, statusIsGood); 191 192 if (validity != NULL) { 193 PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext), 194 PKIX_DATEGETPRTIMEFAILED); 195 } else { 196 time = PR_Now(); 197 } 198 199 rv = ocsp_GetCachedOCSPResponseStatus( 200 cid->certID, time, PR_TRUE, /*ignoreGlobalOcspFailureSetting*/ 201 &rvOcsp, missingResponseError, &freshness); 202 203 *hasFreshStatus = (rv == SECSuccess && freshness == ocspFresh); 204 if (*hasFreshStatus) { 205 *statusIsGood = (rvOcsp == SECSuccess); 206 } 207 cleanup: 208 PKIX_RETURN(OCSPCERTID); 209 } 210 211 /* 212 * FUNCTION: PKIX_PL_OcspCertID_RememberOCSPProcessingFailure 213 * DESCRIPTION: 214 * 215 * Information about the current failure associated to the given certID 216 * will be remembered in the cache, potentially allowing future calls 217 * to prevent repetitive OCSP requests. 218 * After this function got called, it may no longer be safe to 219 * use the provided cid parameter, because ownership might have been 220 * transfered to the cache. This status will be recorded inside the 221 * cid object. 222 * 223 * PARAMETERS 224 * "cid" 225 * The certificate ID associated to a failed OCSP processing. 226 * "plContext" 227 * Platform-specific context pointer. 228 * RETURNS: 229 * Returns NULL if the function succeeds. 230 * Returns an OcspCertID Error if the function fails in a non-fatal way. 231 * Returns a Fatal Error if the function fails in an unrecoverable way. 232 */ 233 PKIX_Error * 234 PKIX_PL_OcspCertID_RememberOCSPProcessingFailure( 235 PKIX_PL_OcspCertID *cid, 236 void *plContext) 237 { 238 PRBool certIDWasConsumed = PR_FALSE; 239 240 PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_RememberOCSPProcessingFailure"); 241 PKIX_NULLCHECK_TWO(cid, cid->certID); 242 243 cert_RememberOCSPProcessingFailure(cid->certID, &certIDWasConsumed); 244 245 if (certIDWasConsumed) { 246 cid->certID = NULL; 247 } 248 249 PKIX_RETURN(OCSPCERTID); 250 }