| OLD | NEW |
| (Empty) |
| 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_pk11certstore.c | |
| 6 * | |
| 7 * PKCS11CertStore Function Definitions | |
| 8 * | |
| 9 */ | |
| 10 | |
| 11 #include "pkix_pl_pk11certstore.h" | |
| 12 | |
| 13 /* | |
| 14 * PKIX_DEFAULT_MAX_RESPONSE_LENGTH (64 * 1024) is too small for downloading | |
| 15 * CRLs. We observed CRLs of sizes 338759 and 439035 in practice. So we | |
| 16 * need to use a higher max response length for CRLs. | |
| 17 */ | |
| 18 #define PKIX_DEFAULT_MAX_CRL_RESPONSE_LENGTH (512 * 1024) | |
| 19 | |
| 20 /* --Private-Pk11CertStore-Functions---------------------------------- */ | |
| 21 | |
| 22 /* | |
| 23 * FUNCTION: pkix_pl_Pk11CertStore_CheckTrust | |
| 24 * DESCRIPTION: | |
| 25 * This function checks the trust status of this "cert" that was retrieved | |
| 26 * from the CertStore "store" and returns its trust status at "pTrusted". | |
| 27 * | |
| 28 * PARAMETERS: | |
| 29 * "store" | |
| 30 * Address of the CertStore. Must be non-NULL. | |
| 31 * "cert" | |
| 32 * Address of the Cert. Must be non-NULL. | |
| 33 * "pTrusted" | |
| 34 * Address of PKIX_Boolean where the "cert" trust status is returned. | |
| 35 * Must be non-NULL. | |
| 36 * "plContext" | |
| 37 * Platform-specific context pointer | |
| 38 * THREAD SAFETY: | |
| 39 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 40 * RETURNS: | |
| 41 * Returns NULL if the function succeeds. | |
| 42 * Returns a CertStore Error if the function fails in a non-fatal way. | |
| 43 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 44 */ | |
| 45 static PKIX_Error * | |
| 46 pkix_pl_Pk11CertStore_CheckTrust( | |
| 47 PKIX_CertStore *store, | |
| 48 PKIX_PL_Cert *cert, | |
| 49 PKIX_Boolean *pTrusted, | |
| 50 void *plContext) | |
| 51 { | |
| 52 SECStatus rv = SECFailure; | |
| 53 PKIX_Boolean trusted = PKIX_FALSE; | |
| 54 SECCertUsage certUsage = 0; | |
| 55 SECCertificateUsage certificateUsage; | |
| 56 unsigned int requiredFlags; | |
| 57 SECTrustType trustType; | |
| 58 CERTCertTrust trust; | |
| 59 | |
| 60 PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_CheckTrust"); | |
| 61 PKIX_NULLCHECK_THREE(store, cert, pTrusted); | |
| 62 PKIX_NULLCHECK_ONE(cert->nssCert); | |
| 63 | |
| 64 certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage; | |
| 65 | |
| 66 /* ensure we obtained a single usage bit only */ | |
| 67 PORT_Assert(!(certificateUsage & (certificateUsage - 1))); | |
| 68 | |
| 69 /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */ | |
| 70 while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; } | |
| 71 | |
| 72 rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, &trustType
); | |
| 73 if (rv == SECSuccess) { | |
| 74 rv = CERT_GetCertTrust(cert->nssCert, &trust); | |
| 75 } | |
| 76 | |
| 77 if (rv == SECSuccess) { | |
| 78 unsigned int certFlags; | |
| 79 | |
| 80 if (certUsage != certUsageAnyCA && | |
| 81 certUsage != certUsageStatusResponder) { | |
| 82 CERTCertificate *nssCert = cert->nssCert; | |
| 83 | |
| 84 if (certUsage == certUsageVerifyCA) { | |
| 85 if (nssCert->nsCertType & NS_CERT_TYPE_EMAIL_CA) { | |
| 86 trustType = trustEmail; | |
| 87 } else if (nssCert->nsCertType & NS_CERT_TYPE_SSL_CA) { | |
| 88 trustType = trustSSL; | |
| 89 } else { | |
| 90 trustType = trustObjectSigning; | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 certFlags = SEC_GET_TRUST_FLAGS((&trust), trustType); | |
| 95 if ((certFlags & requiredFlags) == requiredFlags) { | |
| 96 trusted = PKIX_TRUE; | |
| 97 } | |
| 98 } else { | |
| 99 for (trustType = trustSSL; trustType < trustTypeNone; | |
| 100 trustType++) { | |
| 101 certFlags = | |
| 102 SEC_GET_TRUST_FLAGS((&trust), trustType); | |
| 103 if ((certFlags & requiredFlags) == requiredFlags) { | |
| 104 trusted = PKIX_TRUE; | |
| 105 break; | |
| 106 } | |
| 107 } | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 *pTrusted = trusted; | |
| 112 | |
| 113 PKIX_RETURN(CERTSTORE); | |
| 114 } | |
| 115 | |
| 116 /* | |
| 117 * FUNCTION: pkix_pl_Pk11CertStore_CertQuery | |
| 118 * DESCRIPTION: | |
| 119 * | |
| 120 * This function obtains from the database the Certs specified by the | |
| 121 * ComCertSelParams pointed to by "params" and stores the resulting | |
| 122 * List at "pSelected". If no matching Certs are found, a NULL pointer | |
| 123 * will be stored. | |
| 124 * | |
| 125 * This function uses a "smart" database query if the Subject has been set | |
| 126 * in ComCertSelParams. Otherwise, it uses a very inefficient call to | |
| 127 * retrieve all Certs in the database (and run them through the selector). | |
| 128 * | |
| 129 * PARAMETERS: | |
| 130 * "params" | |
| 131 * Address of the ComCertSelParams. Must be non-NULL. | |
| 132 * "pSelected" | |
| 133 * Address at which List will be stored. Must be non-NULL. | |
| 134 * "plContext" | |
| 135 * Platform-specific context pointer | |
| 136 * THREAD SAFETY: | |
| 137 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 138 * RETURNS: | |
| 139 * Returns NULL if the function succeeds. | |
| 140 * Returns a CertStore Error if the function fails in a non-fatal way. | |
| 141 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 142 */ | |
| 143 static PKIX_Error * | |
| 144 pkix_pl_Pk11CertStore_CertQuery( | |
| 145 PKIX_ComCertSelParams *params, | |
| 146 PKIX_List **pSelected, | |
| 147 void *plContext) | |
| 148 { | |
| 149 PRBool validOnly = PR_FALSE; | |
| 150 PRTime prtime = 0; | |
| 151 PKIX_PL_X500Name *subjectName = NULL; | |
| 152 PKIX_PL_Date *certValid = NULL; | |
| 153 PKIX_List *certList = NULL; | |
| 154 PKIX_PL_Cert *cert = NULL; | |
| 155 CERTCertList *pk11CertList = NULL; | |
| 156 CERTCertListNode *node = NULL; | |
| 157 CERTCertificate *nssCert = NULL; | |
| 158 CERTCertDBHandle *dbHandle = NULL; | |
| 159 | |
| 160 PLArenaPool *arena = NULL; | |
| 161 SECItem *nameItem = NULL; | |
| 162 void *wincx = NULL; | |
| 163 | |
| 164 PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_CertQuery"); | |
| 165 PKIX_NULLCHECK_TWO(params, pSelected); | |
| 166 | |
| 167 /* avoid multiple calls to retrieve a constant */ | |
| 168 PKIX_PL_NSSCALLRV(CERTSTORE, dbHandle, CERT_GetDefaultCertDB, ()); | |
| 169 | |
| 170 /* | |
| 171 * Any of the ComCertSelParams may be obtained and used to constrain | |
| 172 * the database query, to allow the use of a "smart" query. See | |
| 173 * pkix_certsel.h for a list of the PKIX_ComCertSelParams_Get* | |
| 174 * calls available. No corresponding "smart" queries exist at present, | |
| 175 * except for CERT_CreateSubjectCertList based on Subject. When others | |
| 176 * are added, corresponding code should be added to | |
| 177 * pkix_pl_Pk11CertStore_CertQuery to use them when appropriate | |
| 178 * selector parameters have been set. | |
| 179 */ | |
| 180 | |
| 181 PKIX_CHECK(PKIX_ComCertSelParams_GetSubject | |
| 182 (params, &subjectName, plContext), | |
| 183 PKIX_COMCERTSELPARAMSGETSUBJECTFAILED); | |
| 184 | |
| 185 PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid | |
| 186 (params, &certValid, plContext), | |
| 187 PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED); | |
| 188 | |
| 189 /* If caller specified a Date, convert it to PRTime */ | |
| 190 if (certValid) { | |
| 191 PKIX_CHECK(pkix_pl_Date_GetPRTime | |
| 192 (certValid, &prtime, plContext), | |
| 193 PKIX_DATEGETPRTIMEFAILED); | |
| 194 validOnly = PR_TRUE; | |
| 195 } | |
| 196 | |
| 197 /* | |
| 198 * If we have the subject name for the desired subject, | |
| 199 * ask the database for Certs with that subject. Otherwise | |
| 200 * ask the database for all Certs. | |
| 201 */ | |
| 202 if (subjectName) { | |
| 203 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
| 204 if (arena) { | |
| 205 | |
| 206 PKIX_CHECK(pkix_pl_X500Name_GetDERName | |
| 207 (subjectName, arena, &nameItem, plContext), | |
| 208 PKIX_X500NAMEGETSECNAMEFAILED); | |
| 209 | |
| 210 if (nameItem) { | |
| 211 | |
| 212 PKIX_PL_NSSCALLRV | |
| 213 (CERTSTORE, | |
| 214 pk11CertList, | |
| 215 CERT_CreateSubjectCertList, | |
| 216 (NULL, dbHandle, nameItem, prtime, validOnly)); | |
| 217 } | |
| 218 PKIX_PL_NSSCALL | |
| 219 (CERTSTORE, PORT_FreeArena, (arena, PR_FALSE)); | |
| 220 arena = NULL; | |
| 221 } | |
| 222 | |
| 223 } else { | |
| 224 | |
| 225 PKIX_CHECK(pkix_pl_NssContext_GetWincx | |
| 226 ((PKIX_PL_NssContext *)plContext, &wincx), | |
| 227 PKIX_NSSCONTEXTGETWINCXFAILED); | |
| 228 | |
| 229 PKIX_PL_NSSCALLRV | |
| 230 (CERTSTORE, | |
| 231 pk11CertList, | |
| 232 PK11_ListCerts, | |
| 233 (PK11CertListAll, wincx)); | |
| 234 } | |
| 235 | |
| 236 if (pk11CertList) { | |
| 237 | |
| 238 PKIX_CHECK(PKIX_List_Create(&certList, plContext), | |
| 239 PKIX_LISTCREATEFAILED); | |
| 240 | |
| 241 for (node = CERT_LIST_HEAD(pk11CertList); | |
| 242 !(CERT_LIST_END(node, pk11CertList)); | |
| 243 node = CERT_LIST_NEXT(node)) { | |
| 244 | |
| 245 PKIX_PL_NSSCALLRV | |
| 246 (CERTSTORE, | |
| 247 nssCert, | |
| 248 CERT_DupCertificate, | |
| 249 (node->cert)); | |
| 250 | |
| 251 if (!nssCert) { | |
| 252 continue; /* just skip bad certs */ | |
| 253 } | |
| 254 | |
| 255 PKIX_CHECK_ONLY_FATAL(pkix_pl_Cert_CreateWithNSSCert | |
| 256 (nssCert, &cert, plContext), | |
| 257 PKIX_CERTCREATEWITHNSSCERTFAILED); | |
| 258 | |
| 259 if (PKIX_ERROR_RECEIVED) { | |
| 260 CERT_DestroyCertificate(nssCert); | |
| 261 nssCert = NULL; | |
| 262 continue; /* just skip bad certs */ | |
| 263 } | |
| 264 | |
| 265 PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem | |
| 266 (certList, (PKIX_PL_Object *)cert, plContext), | |
| 267 PKIX_LISTAPPENDITEMFAILED); | |
| 268 | |
| 269 PKIX_DECREF(cert); | |
| 270 | |
| 271 } | |
| 272 | |
| 273 /* Don't throw away the list if one cert was bad! */ | |
| 274 pkixTempErrorReceived = PKIX_FALSE; | |
| 275 } | |
| 276 | |
| 277 *pSelected = certList; | |
| 278 certList = NULL; | |
| 279 | |
| 280 cleanup: | |
| 281 | |
| 282 if (pk11CertList) { | |
| 283 CERT_DestroyCertList(pk11CertList); | |
| 284 } | |
| 285 if (arena) { | |
| 286 PORT_FreeArena(arena, PR_FALSE); | |
| 287 } | |
| 288 | |
| 289 PKIX_DECREF(subjectName); | |
| 290 PKIX_DECREF(certValid); | |
| 291 PKIX_DECREF(cert); | |
| 292 PKIX_DECREF(certList); | |
| 293 | |
| 294 PKIX_RETURN(CERTSTORE); | |
| 295 } | |
| 296 | |
| 297 /* | |
| 298 * FUNCTION: pkix_pl_Pk11CertStore_ImportCrl | |
| 299 * DESCRIPTION: | |
| 300 * | |
| 301 * PARAMETERS: | |
| 302 * "params" | |
| 303 * Address of the ComCRLSelParams. Must be non-NULL. | |
| 304 * "pSelected" | |
| 305 * Address at which List will be stored. Must be non-NULL. | |
| 306 * "plContext" | |
| 307 * Platform-specific context pointer | |
| 308 * THREAD SAFETY: | |
| 309 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 310 * RETURNS: | |
| 311 * Returns NULL if the function succeeds. | |
| 312 * Returns a CertStore Error if the function fails in a non-fatal way. | |
| 313 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 314 */ | |
| 315 static PKIX_Error * | |
| 316 pkix_pl_Pk11CertStore_ImportCrl( | |
| 317 PKIX_CertStore *store, | |
| 318 PKIX_PL_X500Name *issuerName, | |
| 319 PKIX_List *crlList, | |
| 320 void *plContext) | |
| 321 { | |
| 322 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); | |
| 323 PKIX_PL_CRL *crl = NULL; | |
| 324 SECItem *derCrl = NULL; | |
| 325 | |
| 326 PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_ImportCrl"); | |
| 327 PKIX_NULLCHECK_TWO(store, plContext); | |
| 328 | |
| 329 if (!crlList) { | |
| 330 goto cleanup; | |
| 331 } | |
| 332 while (crlList->length > 0) { | |
| 333 PKIX_CHECK( | |
| 334 PKIX_List_GetItem(crlList, 0, (PKIX_PL_Object**)&crl, | |
| 335 plContext), | |
| 336 PKIX_LISTGETITEMFAILED); | |
| 337 | |
| 338 /* Delete crl from the list to keep controll of the | |
| 339 * last reference. crl need to be destroyed right after | |
| 340 * it released the ownership of the crl der. */ | |
| 341 PKIX_CHECK( | |
| 342 PKIX_List_DeleteItem(crlList, 0, plContext), | |
| 343 PKIX_LISTDELETEITEMFAILED); | |
| 344 | |
| 345 /* acquire the crlder ownership */ | |
| 346 pkixErrorResult = | |
| 347 PKIX_PL_CRL_ReleaseDerCrl(crl, &derCrl, plContext); | |
| 348 PORT_Assert(!pkixErrorResult && derCrl); | |
| 349 if (pkixErrorResult || !derCrl) { | |
| 350 /* All pkix delivered crls should be able to | |
| 351 * release their ders. */ | |
| 352 PKIX_DECREF(pkixErrorResult); | |
| 353 PKIX_DECREF(crl); | |
| 354 continue; | |
| 355 } | |
| 356 cert_CacheCRLByGeneralName(certHandle, derCrl, | |
| 357 crl->derGenName); | |
| 358 /* Do not check the status. If it is a SECFailure, | |
| 359 * derCrl is already destroyed. */ | |
| 360 derCrl = NULL; | |
| 361 PKIX_DECREF(crl); | |
| 362 } | |
| 363 | |
| 364 cleanup: | |
| 365 PKIX_DECREF(crl); | |
| 366 | |
| 367 PKIX_RETURN(CERTSTORE); | |
| 368 } | |
| 369 | |
| 370 static PKIX_Error * | |
| 371 NameCacheHasFetchedCrlInfo(PKIX_PL_Cert *pkixCert, | |
| 372 PRTime time, | |
| 373 PKIX_Boolean *pHasFetchedCrlInCache, | |
| 374 void *plContext) | |
| 375 { | |
| 376 /* Returning true result in this case will mean, that case info | |
| 377 * is currect and should used as is. */ | |
| 378 NamedCRLCache* nameCrlCache = NULL; | |
| 379 PKIX_Boolean hasFetchedCrlInCache = PKIX_TRUE; | |
| 380 PKIX_List *dpList = NULL; | |
| 381 pkix_pl_CrlDp *dp = NULL; | |
| 382 PKIX_UInt32 dpIndex = 0; | |
| 383 SECStatus rv = SECSuccess; | |
| 384 PRTime reloadDelay = 0, badCrlInvalDelay = 0; | |
| 385 | |
| 386 PKIX_ENTER(CERTSTORE, "ChechCacheHasFetchedCrl"); | |
| 387 | |
| 388 reloadDelay = | |
| 389 ((PKIX_PL_NssContext*)plContext)->crlReloadDelay * | |
| 390 PR_USEC_PER_SEC; | |
| 391 badCrlInvalDelay = | |
| 392 ((PKIX_PL_NssContext*)plContext)->badDerCrlReloadDelay * | |
| 393 PR_USEC_PER_SEC; | |
| 394 if (!time) { | |
| 395 time = PR_Now(); | |
| 396 } | |
| 397 /* If we already download the crl and inserted into the cache, then | |
| 398 * there is no need to check for fetched crl. We have what we have. */ | |
| 399 PKIX_CHECK( | |
| 400 PKIX_PL_Cert_GetCrlDp(pkixCert, &dpList, plContext), | |
| 401 PKIX_CERTGETCRLDPFAILED); | |
| 402 if (dpList && dpList->length) { | |
| 403 hasFetchedCrlInCache = PKIX_FALSE; | |
| 404 rv = cert_AcquireNamedCRLCache(&nameCrlCache); | |
| 405 if (rv != SECSuccess) { | |
| 406 PKIX_DECREF(dpList); | |
| 407 } | |
| 408 } else { | |
| 409 /* If no dp then treat it as if we already have | |
| 410 * a fetched crl. */ | |
| 411 PKIX_DECREF(dpList); | |
| 412 } | |
| 413 for (;!hasFetchedCrlInCache && | |
| 414 dpList && dpIndex < dpList->length;dpIndex++) { | |
| 415 SECItem **derDpNames = NULL; | |
| 416 pkixErrorResult = | |
| 417 PKIX_List_GetItem(dpList, dpIndex, (PKIX_PL_Object **)&dp, | |
| 418 plContext); | |
| 419 if (pkixErrorResult) { | |
| 420 PKIX_DECREF(pkixErrorResult); | |
| 421 continue; | |
| 422 } | |
| 423 if (dp->nssdp->distPointType == generalName) { | |
| 424 /* dp can only be created from nssdp. */ | |
| 425 derDpNames = dp->nssdp->derFullName; | |
| 426 } | |
| 427 while (derDpNames && *derDpNames != NULL) { | |
| 428 NamedCRLCacheEntry* cacheEntry = NULL; | |
| 429 const SECItem *derDpName = *derDpNames++; | |
| 430 rv = cert_FindCRLByGeneralName(nameCrlCache, derDpName, | |
| 431 &cacheEntry); | |
| 432 if (rv == SECSuccess && cacheEntry) { | |
| 433 if ((cacheEntry->inCRLCache && | |
| 434 (cacheEntry->successfulInsertionTime + reloadDelay > time || | |
| 435 (cacheEntry->dupe && | |
| 436 cacheEntry->lastAttemptTime + reloadDelay > time))) || | |
| 437 (cacheEntry->badDER && | |
| 438 cacheEntry->lastAttemptTime + badCrlInvalDelay > time)) { | |
| 439 hasFetchedCrlInCache = PKIX_TRUE; | |
| 440 break; | |
| 441 } | |
| 442 } | |
| 443 } | |
| 444 PKIX_DECREF(dp); | |
| 445 } | |
| 446 cleanup: | |
| 447 *pHasFetchedCrlInCache = hasFetchedCrlInCache; | |
| 448 if (nameCrlCache) { | |
| 449 cert_ReleaseNamedCRLCache(nameCrlCache); | |
| 450 } | |
| 451 PKIX_DECREF(dpList); | |
| 452 | |
| 453 PKIX_RETURN(CERTSTORE); | |
| 454 } | |
| 455 | |
| 456 /* | |
| 457 * FUNCTION: pkix_pl_Pk11CertStore_CheckCrl | |
| 458 * DESCRIPTION: | |
| 459 * | |
| 460 * PARAMETERS: | |
| 461 * "params" | |
| 462 * Address of the ComCRLSelParams. Must be non-NULL. | |
| 463 * "pSelected" | |
| 464 * Address at which List will be stored. Must be non-NULL. | |
| 465 * "plContext" | |
| 466 * Platform-specific context pointer | |
| 467 * THREAD SAFETY: | |
| 468 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 469 * RETURNS: | |
| 470 * Returns NULL if the function succeeds. | |
| 471 * Returns a CertStore Error if the function fails in a non-fatal way. | |
| 472 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 473 */ | |
| 474 static PKIX_Error * | |
| 475 pkix_pl_Pk11CertStore_CheckRevByCrl( | |
| 476 PKIX_CertStore *store, | |
| 477 PKIX_PL_Cert *pkixCert, | |
| 478 PKIX_PL_Cert *pkixIssuer, | |
| 479 PKIX_PL_Date *date, | |
| 480 PKIX_Boolean crlDownloadDone, | |
| 481 CERTCRLEntryReasonCode *pReasonCode, | |
| 482 PKIX_RevocationStatus *pStatus, | |
| 483 void *plContext) | |
| 484 { | |
| 485 PKIX_RevocationStatus pkixRevStatus = PKIX_RevStatus_NoInfo; | |
| 486 CERTRevocationStatus revStatus = certRevocationStatusUnknown; | |
| 487 PKIX_Boolean hasFetchedCrlInCache = PKIX_TRUE; | |
| 488 CERTCertificate *cert = NULL, *issuer = NULL; | |
| 489 SECStatus rv = SECSuccess; | |
| 490 void *wincx = NULL; | |
| 491 PRTime time = 0; | |
| 492 | |
| 493 PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_CheckRevByCrl"); | |
| 494 PKIX_NULLCHECK_FOUR(store, pkixCert, pkixIssuer, plContext); | |
| 495 | |
| 496 cert = pkixCert->nssCert; | |
| 497 issuer = pkixIssuer->nssCert; | |
| 498 if (date) { | |
| 499 PKIX_CHECK( | |
| 500 pkix_pl_Date_GetPRTime(date, &time, plContext), | |
| 501 PKIX_DATEGETPRTIMEFAILED); | |
| 502 } | |
| 503 PKIX_CHECK( | |
| 504 pkix_pl_NssContext_GetWincx((PKIX_PL_NssContext*)plContext, | |
| 505 &wincx), | |
| 506 PKIX_NSSCONTEXTGETWINCXFAILED); | |
| 507 /* No need to check any cDPs, since partitioned crls are not | |
| 508 * supported. If a ds does not point to partitioned crl, then | |
| 509 * the crl should be in issuer cache that is unrelated to any | |
| 510 * dp. Using NULL as a dp pointer to check it.*/ | |
| 511 rv = cert_CheckCertRevocationStatus(cert, issuer, NULL, | |
| 512 /* Will not validate the signature | |
| 513 * on the crl if time is not specified.*
/ | |
| 514 time, wincx, &revStatus, pReasonCode); | |
| 515 if (rv == SECFailure) { | |
| 516 pkixRevStatus = PKIX_RevStatus_Revoked; | |
| 517 goto cleanup; | |
| 518 } | |
| 519 if (crlDownloadDone) { | |
| 520 if (revStatus == certRevocationStatusRevoked) { | |
| 521 pkixRevStatus = PKIX_RevStatus_Revoked; | |
| 522 } else if (revStatus == certRevocationStatusValid) { | |
| 523 pkixRevStatus = PKIX_RevStatus_Success; | |
| 524 } | |
| 525 } else { | |
| 526 pkixErrorResult = | |
| 527 NameCacheHasFetchedCrlInfo(pkixCert, time, &hasFetchedCrlInCache, | |
| 528 plContext); | |
| 529 if (pkixErrorResult) { | |
| 530 goto cleanup; | |
| 531 } | |
| 532 if (revStatus == certRevocationStatusRevoked && | |
| 533 (hasFetchedCrlInCache || | |
| 534 *pReasonCode != crlEntryReasoncertificatedHold)) { | |
| 535 pkixRevStatus = PKIX_RevStatus_Revoked; | |
| 536 } else if (revStatus == certRevocationStatusValid && | |
| 537 hasFetchedCrlInCache) { | |
| 538 pkixRevStatus = PKIX_RevStatus_Success; | |
| 539 } | |
| 540 } | |
| 541 cleanup: | |
| 542 *pStatus = pkixRevStatus; | |
| 543 | |
| 544 PKIX_RETURN(CERTSTORE); | |
| 545 } | |
| 546 | |
| 547 | |
| 548 /* | |
| 549 * FUNCTION: pkix_pl_Pk11CertStore_GetCert | |
| 550 * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h) | |
| 551 */ | |
| 552 PKIX_Error * | |
| 553 pkix_pl_Pk11CertStore_GetCert( | |
| 554 PKIX_CertStore *store, | |
| 555 PKIX_CertSelector *selector, | |
| 556 PKIX_VerifyNode *parentVerifyNode, | |
| 557 void **pNBIOContext, | |
| 558 PKIX_List **pCertList, | |
| 559 void *plContext) | |
| 560 { | |
| 561 PKIX_UInt32 i = 0; | |
| 562 PKIX_UInt32 numFound = 0; | |
| 563 PKIX_PL_Cert *candidate = NULL; | |
| 564 PKIX_List *selected = NULL; | |
| 565 PKIX_List *filtered = NULL; | |
| 566 PKIX_CertSelector_MatchCallback selectorCallback = NULL; | |
| 567 PKIX_CertStore_CheckTrustCallback trustCallback = NULL; | |
| 568 PKIX_ComCertSelParams *params = NULL; | |
| 569 PKIX_Boolean cacheFlag = PKIX_FALSE; | |
| 570 PKIX_VerifyNode *verifyNode = NULL; | |
| 571 PKIX_Error *selectorError = NULL; | |
| 572 | |
| 573 PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_GetCert"); | |
| 574 PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCertList); | |
| 575 | |
| 576 *pNBIOContext = NULL; /* We don't use non-blocking I/O */ | |
| 577 | |
| 578 PKIX_CHECK(PKIX_CertSelector_GetMatchCallback | |
| 579 (selector, &selectorCallback, plContext), | |
| 580 PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); | |
| 581 | |
| 582 PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams | |
| 583 (selector, ¶ms, plContext), | |
| 584 PKIX_CERTSELECTORGETCOMCERTSELPARAMSFAILED); | |
| 585 | |
| 586 PKIX_CHECK(pkix_pl_Pk11CertStore_CertQuery | |
| 587 (params, &selected, plContext), | |
| 588 PKIX_PK11CERTSTORECERTQUERYFAILED); | |
| 589 | |
| 590 if (selected) { | |
| 591 PKIX_CHECK(PKIX_List_GetLength(selected, &numFound, plContext), | |
| 592 PKIX_LISTGETLENGTHFAILED); | |
| 593 } | |
| 594 | |
| 595 PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag | |
| 596 (store, &cacheFlag, plContext), | |
| 597 PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED); | |
| 598 | |
| 599 PKIX_CHECK(PKIX_CertStore_GetTrustCallback | |
| 600 (store, &trustCallback, plContext), | |
| 601 PKIX_CERTSTOREGETTRUSTCALLBACKFAILED); | |
| 602 | |
| 603 PKIX_CHECK(PKIX_List_Create(&filtered, plContext), | |
| 604 PKIX_LISTCREATEFAILED); | |
| 605 | |
| 606 for (i = 0; i < numFound; i++) { | |
| 607 PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem | |
| 608 (selected, | |
| 609 i, | |
| 610 (PKIX_PL_Object **)&candidate, | |
| 611 plContext), | |
| 612 PKIX_LISTGETITEMFAILED); | |
| 613 | |
| 614 if (PKIX_ERROR_RECEIVED) { | |
| 615 continue; /* just skip bad certs */ | |
| 616 } | |
| 617 | |
| 618 selectorError = | |
| 619 selectorCallback(selector, candidate, plContext); | |
| 620 if (!selectorError) { | |
| 621 PKIX_CHECK(PKIX_PL_Cert_SetCacheFlag | |
| 622 (candidate, cacheFlag, plContext), | |
| 623 PKIX_CERTSETCACHEFLAGFAILED); | |
| 624 | |
| 625 if (trustCallback) { | |
| 626 PKIX_CHECK(PKIX_PL_Cert_SetTrustCertStore | |
| 627 (candidate, store, plContext), | |
| 628 PKIX_CERTSETTRUSTCERTSTOREFAILED); | |
| 629 } | |
| 630 | |
| 631 PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem | |
| 632 (filtered, | |
| 633 (PKIX_PL_Object *)candidate, | |
| 634 plContext), | |
| 635 PKIX_LISTAPPENDITEMFAILED); | |
| 636 } else if (parentVerifyNode) { | |
| 637 PKIX_CHECK_FATAL( | |
| 638 pkix_VerifyNode_Create(candidate, 0, selectorError, | |
| 639 &verifyNode, plContext), | |
| 640 PKIX_VERIFYNODECREATEFAILED); | |
| 641 PKIX_CHECK_FATAL( | |
| 642 pkix_VerifyNode_AddToTree(parentVerifyNode, | |
| 643 verifyNode, | |
| 644 plContext), | |
| 645 PKIX_VERIFYNODEADDTOTREEFAILED); | |
| 646 PKIX_DECREF(verifyNode); | |
| 647 } | |
| 648 PKIX_DECREF(selectorError); | |
| 649 PKIX_DECREF(candidate); | |
| 650 } | |
| 651 | |
| 652 /* Don't throw away the list if one cert was bad! */ | |
| 653 pkixTempErrorReceived = PKIX_FALSE; | |
| 654 | |
| 655 *pCertList = filtered; | |
| 656 filtered = NULL; | |
| 657 | |
| 658 cleanup: | |
| 659 fatal: | |
| 660 PKIX_DECREF(filtered); | |
| 661 PKIX_DECREF(candidate); | |
| 662 PKIX_DECREF(selected); | |
| 663 PKIX_DECREF(params); | |
| 664 PKIX_DECREF(verifyNode); | |
| 665 PKIX_DECREF(selectorError); | |
| 666 | |
| 667 PKIX_RETURN(CERTSTORE); | |
| 668 } | |
| 669 | |
| 670 static PKIX_Error * | |
| 671 RemovePartitionedDpsFromList(PKIX_List *dpList, PKIX_PL_Date *date, | |
| 672 void *plContext) | |
| 673 { | |
| 674 NamedCRLCache* nameCrlCache = NULL; | |
| 675 pkix_pl_CrlDp *dp = NULL; | |
| 676 unsigned int dpIndex = 0; | |
| 677 PRTime time; | |
| 678 PRTime reloadDelay = 0, badCrlInvalDelay = 0; | |
| 679 SECStatus rv; | |
| 680 | |
| 681 PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_ListRemovePrtDp"); | |
| 682 | |
| 683 if (!dpList || !dpList->length) { | |
| 684 PKIX_RETURN(CERTSTORE); | |
| 685 } | |
| 686 reloadDelay = | |
| 687 ((PKIX_PL_NssContext*)plContext)->crlReloadDelay * | |
| 688 PR_USEC_PER_SEC; | |
| 689 badCrlInvalDelay = | |
| 690 ((PKIX_PL_NssContext*)plContext)->badDerCrlReloadDelay * | |
| 691 PR_USEC_PER_SEC; | |
| 692 PKIX_CHECK(pkix_pl_Date_GetPRTime(date, &time, plContext), | |
| 693 PKIX_DATEGETPRTIMEFAILED); | |
| 694 rv = cert_AcquireNamedCRLCache(&nameCrlCache); | |
| 695 if (rv == SECFailure) { | |
| 696 /* Baling out. Wont find out any thing useful. */ | |
| 697 PKIX_RETURN(CERTSTORE); | |
| 698 } | |
| 699 while (dpIndex < dpList->length) { | |
| 700 SECItem **derDpNames = NULL; | |
| 701 PKIX_Boolean removeDp = PKIX_FALSE; | |
| 702 | |
| 703 PKIX_CHECK( | |
| 704 PKIX_List_GetItem(dpList, dpIndex, (PKIX_PL_Object **)&dp, | |
| 705 plContext), | |
| 706 PKIX_LISTGETITEMFAILED); | |
| 707 if (!dp->isPartitionedByReasonCode) { | |
| 708 /* See if we know about this dp anything why we should | |
| 709 * not use it to download a crl. */ | |
| 710 if (dp->nssdp->distPointType == generalName) { | |
| 711 /* dp can only be created from nssdp. */ | |
| 712 derDpNames = dp->nssdp->derFullName; | |
| 713 } else { | |
| 714 removeDp = PKIX_TRUE; | |
| 715 } | |
| 716 while (derDpNames && *derDpNames != NULL) { | |
| 717 NamedCRLCacheEntry* cacheEntry = NULL; | |
| 718 const SECItem *derDpName = *derDpNames++; | |
| 719 /* Removing from the list all dps that we know about. */ | |
| 720 rv = cert_FindCRLByGeneralName(nameCrlCache, derDpName, | |
| 721 &cacheEntry); | |
| 722 if (rv && cacheEntry) { | |
| 723 if (cacheEntry->unsupported || | |
| 724 (cacheEntry->inCRLCache && | |
| 725 (cacheEntry->successfulInsertionTime + reloadDelay > ti
me || | |
| 726 (cacheEntry->dupe && | |
| 727 cacheEntry->lastAttemptTime + reloadDelay > time))) |
| | |
| 728 (cacheEntry->badDER && | |
| 729 cacheEntry->lastAttemptTime + badCrlInvalDelay > time
)) { | |
| 730 removeDp = PKIX_TRUE; | |
| 731 } | |
| 732 } | |
| 733 } | |
| 734 } else { | |
| 735 /* Remove dp that point to a partitioned crl . RFC 5280 | |
| 736 * recommends against crl partitioned by reason code. | |
| 737 * Will skip such crls */ | |
| 738 removeDp = PKIX_TRUE; | |
| 739 } | |
| 740 if (removeDp) { | |
| 741 PKIX_CHECK_ONLY_FATAL( | |
| 742 pkix_List_Remove(dpList,(PKIX_PL_Object*)dp, | |
| 743 plContext), | |
| 744 PKIX_LISTGETITEMFAILED); | |
| 745 } else { | |
| 746 dpIndex += 1; | |
| 747 } | |
| 748 PKIX_DECREF(dp); | |
| 749 } | |
| 750 | |
| 751 cleanup: | |
| 752 if (nameCrlCache) { | |
| 753 cert_ReleaseNamedCRLCache(nameCrlCache); | |
| 754 } | |
| 755 PKIX_DECREF(dp); | |
| 756 | |
| 757 PKIX_RETURN(CERTSTORE); | |
| 758 } | |
| 759 | |
| 760 /* | |
| 761 * FUNCTION: pkix_pl_Pk11CertStore_DownloadCrl | |
| 762 */ | |
| 763 static PKIX_Error * | |
| 764 DownloadCrl(pkix_pl_CrlDp *dp, PKIX_PL_CRL **crl, | |
| 765 const SEC_HttpClientFcnV1 *hcv1, void *plContext) | |
| 766 { | |
| 767 char *location = NULL; | |
| 768 char *hostname = NULL; | |
| 769 char *path = NULL; | |
| 770 PRUint16 port; | |
| 771 SEC_HTTP_SERVER_SESSION pServerSession = NULL; | |
| 772 SEC_HTTP_REQUEST_SESSION pRequestSession = NULL; | |
| 773 PRUint16 myHttpResponseCode; | |
| 774 const char *myHttpResponseData = NULL; | |
| 775 PRUint32 myHttpResponseDataLen; | |
| 776 SECItem *uri = NULL; | |
| 777 SECItem *derCrlCopy = NULL; | |
| 778 CERTSignedCrl *nssCrl = NULL; | |
| 779 CERTGeneralName *genName = NULL; | |
| 780 SECItem **derGenNames = NULL; | |
| 781 SECItem *derGenName = NULL; | |
| 782 | |
| 783 PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_DownloadCrl"); | |
| 784 | |
| 785 /* Do not support dps others than a one with GeneralName | |
| 786 * name type. */ | |
| 787 if (dp->distPointType != generalName || | |
| 788 !dp->nssdp->derFullName) { | |
| 789 PKIX_ERROR(PKIX_UNSUPPORTEDCRLDPTYPE); | |
| 790 } | |
| 791 genName = dp->name.fullName; | |
| 792 derGenNames = dp->nssdp->derFullName; | |
| 793 do { | |
| 794 derGenName = *derGenNames; | |
| 795 do { | |
| 796 if (!derGenName || | |
| 797 !genName->name.other.data) { | |
| 798 /* get to next name if no data. */ | |
| 799 break; | |
| 800 } | |
| 801 uri = &genName->name.other; | |
| 802 location = (char*)PR_Malloc(1 + uri->len); | |
| 803 if (!location) { | |
| 804 break; | |
| 805 } | |
| 806 PORT_Memcpy(location, uri->data, uri->len); | |
| 807 location[uri->len] = 0; | |
| 808 if (CERT_ParseURL(location, &hostname, | |
| 809 &port, &path) != SECSuccess) { | |
| 810 PORT_SetError(SEC_ERROR_BAD_CRL_DP_URL); | |
| 811 break; | |
| 812 } | |
| 813 | |
| 814 PORT_Assert(hostname != NULL); | |
| 815 PORT_Assert(path != NULL); | |
| 816 | |
| 817 if ((*hcv1->createSessionFcn)(hostname, port, | |
| 818 &pServerSession) != SECSuccess) { | |
| 819 PORT_SetError(SEC_ERROR_BAD_CRL_DP_URL); | |
| 820 break; | |
| 821 } | |
| 822 | |
| 823 if ((*hcv1->createFcn)(pServerSession, "http", path, "GET", | |
| 824 /* Users with slow connections might not get CRL revocation | |
| 825 checking for certs that use big CRLs because of the timeout | |
| 826 We absolutely need code that limits our retry attempts. | |
| 827 */ | |
| 828 PR_SecondsToInterval( | |
| 829 ((PKIX_PL_NssContext*)plContext)->timeoutSeconds), | |
| 830 &pRequestSession) != SECSuccess) { | |
| 831 break; | |
| 832 } | |
| 833 | |
| 834 myHttpResponseDataLen = | |
| 835 ((PKIX_PL_NssContext*)plContext)->maxResponseLength; | |
| 836 if (myHttpResponseDataLen < PKIX_DEFAULT_MAX_CRL_RESPONSE_LENGTH) | |
| 837 myHttpResponseDataLen = PKIX_DEFAULT_MAX_CRL_RESPONSE_LENGTH; | |
| 838 | |
| 839 /* We use a non-zero timeout, which means: | |
| 840 - the client will use blocking I/O | |
| 841 - TryFcn will not return WOULD_BLOCK nor a poll descriptor | |
| 842 - it's sufficient to call TryFcn once | |
| 843 */ | |
| 844 /* we don't want result objects larger than this: */ | |
| 845 if ((*hcv1->trySendAndReceiveFcn)( | |
| 846 pRequestSession, | |
| 847 NULL, | |
| 848 &myHttpResponseCode, | |
| 849 NULL, | |
| 850 NULL, | |
| 851 &myHttpResponseData, | |
| 852 &myHttpResponseDataLen) != SECSuccess) { | |
| 853 break; | |
| 854 } | |
| 855 | |
| 856 if (myHttpResponseCode != 200) { | |
| 857 break; | |
| 858 } | |
| 859 } while(0); | |
| 860 if (!myHttpResponseData) { | |
| 861 /* Going to the next one. */ | |
| 862 genName = CERT_GetNextGeneralName(genName); | |
| 863 derGenNames++; | |
| 864 } | |
| 865 /* Staing in the loop through all the names until | |
| 866 * we have a successful download. */ | |
| 867 } while (!myHttpResponseData && *derGenNames && | |
| 868 genName != dp->name.fullName); | |
| 869 /* Need this name to track the crl source location. */ | |
| 870 PORT_Assert(derGenName); | |
| 871 | |
| 872 if (!myHttpResponseData) { | |
| 873 /* Generating fake bad CRL to keep track of this dp */ | |
| 874 SECItem derCrl = {siBuffer, (void*)"BadCrl", 6 }; | |
| 875 | |
| 876 derCrlCopy = SECITEM_DupItem(&derCrl); | |
| 877 if (!derCrlCopy) { | |
| 878 PKIX_ERROR(PKIX_ALLOCERROR); | |
| 879 } | |
| 880 derGenName = *dp->nssdp->derFullName; | |
| 881 } else { | |
| 882 SECItem derCrl = { siBuffer, | |
| 883 (void*)myHttpResponseData, | |
| 884 myHttpResponseDataLen }; | |
| 885 derCrlCopy = SECITEM_DupItem(&derCrl); | |
| 886 if (!derCrlCopy) { | |
| 887 PKIX_ERROR(PKIX_ALLOCERROR); | |
| 888 } | |
| 889 /* crl will be based on derCrlCopy, but will not own the der. */ | |
| 890 nssCrl = | |
| 891 CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy, SEC_CRL_TYPE, | |
| 892 CRL_DECODE_DONT_COPY_DER | | |
| 893 CRL_DECODE_SKIP_ENTRIES); | |
| 894 } | |
| 895 /* pkix crl owns the der. */ | |
| 896 PKIX_CHECK( | |
| 897 pkix_pl_CRL_CreateWithSignedCRL(nssCrl, derCrlCopy, | |
| 898 derGenName, | |
| 899 crl, plContext), | |
| 900 PKIX_CRLCREATEWITHSIGNEDCRLFAILED); | |
| 901 /* pkix crl now own both objects. */ | |
| 902 derCrlCopy = NULL; | |
| 903 nssCrl = NULL; | |
| 904 | |
| 905 cleanup: | |
| 906 if (derCrlCopy) | |
| 907 PORT_Free(derCrlCopy); | |
| 908 if (nssCrl) | |
| 909 SEC_DestroyCrl(nssCrl); | |
| 910 if (pRequestSession != NULL) | |
| 911 (*hcv1->freeFcn)(pRequestSession); | |
| 912 if (pServerSession != NULL) | |
| 913 (*hcv1->freeSessionFcn)(pServerSession); | |
| 914 if (path != NULL) | |
| 915 PORT_Free(path); | |
| 916 if (hostname != NULL) | |
| 917 PORT_Free(hostname); | |
| 918 if (location) { | |
| 919 PORT_Free(location); | |
| 920 } | |
| 921 | |
| 922 PKIX_RETURN(CERTSTORE); | |
| 923 } | |
| 924 | |
| 925 /* | |
| 926 * FUNCTION: pkix_pl_Pk11CertStore_GetCRL | |
| 927 * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h) | |
| 928 */ | |
| 929 static PKIX_Error * | |
| 930 pkix_pl_Pk11CertStore_GetCRL( | |
| 931 PKIX_CertStore *store, | |
| 932 PKIX_CRLSelector *selector, | |
| 933 void **pNBIOContext, | |
| 934 PKIX_List **pCrlList, | |
| 935 void *plContext) | |
| 936 { | |
| 937 PKIX_UInt32 dpIndex = 0; | |
| 938 PKIX_PL_CRL *crl = NULL; | |
| 939 PKIX_List *crlList = NULL; | |
| 940 PKIX_List *dpList = NULL; | |
| 941 pkix_pl_CrlDp *dp = NULL; | |
| 942 PKIX_PL_Date *date = NULL; | |
| 943 const SEC_HttpClientFcn *registeredHttpClient = NULL; | |
| 944 | |
| 945 PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_GetCRL"); | |
| 946 PKIX_NULLCHECK_THREE(store, pNBIOContext, pCrlList); | |
| 947 PKIX_NULLCHECK_TWO(selector, selector->params); | |
| 948 | |
| 949 registeredHttpClient = SEC_GetRegisteredHttpClient(); | |
| 950 if (!registeredHttpClient || registeredHttpClient->version != 1) { | |
| 951 goto cleanup; | |
| 952 } | |
| 953 dpList = selector->params->crldpList; | |
| 954 date = selector->params->date; | |
| 955 PKIX_CHECK( | |
| 956 RemovePartitionedDpsFromList(dpList, date, | |
| 957 plContext), | |
| 958 PKIX_FAILTOREMOVEDPFROMLIST); | |
| 959 for (;dpIndex < dpList->length;dpIndex++) { | |
| 960 PKIX_DECREF(dp); | |
| 961 pkixErrorResult = | |
| 962 PKIX_List_GetItem(dpList, dpIndex, | |
| 963 (PKIX_PL_Object **)&dp, | |
| 964 plContext); | |
| 965 if (pkixErrorResult) { | |
| 966 PKIX_DECREF(pkixErrorResult); | |
| 967 continue; | |
| 968 } | |
| 969 pkixErrorResult = | |
| 970 DownloadCrl(dp, &crl, | |
| 971 ®isteredHttpClient->fcnTable.ftable1, | |
| 972 plContext); | |
| 973 if (pkixErrorResult || !crl) { | |
| 974 /* continue to next dp in case of unsuccesfull | |
| 975 * download attempt. */ | |
| 976 PKIX_DECREF(pkixErrorResult); | |
| 977 continue; | |
| 978 } | |
| 979 if (!crlList) { | |
| 980 PKIX_CHECK(PKIX_List_Create(&crlList, plContext), | |
| 981 PKIX_LISTCREATEFAILED); | |
| 982 } | |
| 983 pkixErrorResult = | |
| 984 PKIX_List_AppendItem(crlList, (PKIX_PL_Object *)crl, | |
| 985 plContext); | |
| 986 if (pkixErrorResult) { | |
| 987 PKIX_DECREF(pkixErrorResult); | |
| 988 } | |
| 989 PKIX_DECREF(crl); | |
| 990 } | |
| 991 *pCrlList = crlList; | |
| 992 crlList = NULL; | |
| 993 | |
| 994 cleanup: | |
| 995 PKIX_DECREF(dp); | |
| 996 PKIX_DECREF(crl); | |
| 997 PKIX_DECREF(crlList); | |
| 998 | |
| 999 PKIX_RETURN(CERTSTORE); | |
| 1000 } | |
| 1001 | |
| 1002 | |
| 1003 /* --Public-Pk11CertStore-Functions----------------------------------- */ | |
| 1004 | |
| 1005 /* | |
| 1006 * FUNCTION: PKIX_PL_Pk11CertStore_Create | |
| 1007 * (see comments in pkix_samples_modules.h) | |
| 1008 */ | |
| 1009 PKIX_Error * | |
| 1010 PKIX_PL_Pk11CertStore_Create( | |
| 1011 PKIX_CertStore **pCertStore, | |
| 1012 void *plContext) | |
| 1013 { | |
| 1014 PKIX_CertStore *certStore = NULL; | |
| 1015 | |
| 1016 PKIX_ENTER(CERTSTORE, "PKIX_PL_Pk11CertStore_Create"); | |
| 1017 PKIX_NULLCHECK_ONE(pCertStore); | |
| 1018 | |
| 1019 PKIX_CHECK(PKIX_CertStore_Create | |
| 1020 (pkix_pl_Pk11CertStore_GetCert, | |
| 1021 pkix_pl_Pk11CertStore_GetCRL, | |
| 1022 NULL, /* getCertContinue */ | |
| 1023 NULL, /* getCrlContinue */ | |
| 1024 pkix_pl_Pk11CertStore_CheckTrust, | |
| 1025 pkix_pl_Pk11CertStore_ImportCrl, | |
| 1026 pkix_pl_Pk11CertStore_CheckRevByCrl, | |
| 1027 NULL, | |
| 1028 PKIX_TRUE, /* cache flag */ | |
| 1029 PKIX_TRUE, /* local - no network I/O */ | |
| 1030 &certStore, | |
| 1031 plContext), | |
| 1032 PKIX_CERTSTORECREATEFAILED); | |
| 1033 | |
| 1034 *pCertStore = certStore; | |
| 1035 | |
| 1036 cleanup: | |
| 1037 | |
| 1038 PKIX_RETURN(CERTSTORE); | |
| 1039 } | |
| OLD | NEW |