pkix_pl_aiamgr.c (22203B)
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_aiamgr.c 6 * 7 * AIAMgr Object Definitions 8 * 9 */ 10 11 #include "pkix_pl_aiamgr.h" 12 extern PKIX_PL_HashTable *aiaConnectionCache; 13 14 #ifndef NSS_PKIX_NO_LDAP 15 /* --Virtual-LdapClient-Functions------------------------------------ */ 16 17 PKIX_Error * 18 PKIX_PL_LdapClient_InitiateRequest( 19 PKIX_PL_LdapClient *client, 20 LDAPRequestParams *requestParams, 21 void **pNBIO, 22 PKIX_List **pResponse, 23 void *plContext) 24 { 25 PKIX_ENTER(LDAPCLIENT, "PKIX_PL_LdapClient_InitiateRequest"); 26 PKIX_NULLCHECK_TWO(client, client->initiateFcn); 27 28 PKIX_CHECK(client->initiateFcn 29 (client, requestParams, pNBIO, pResponse, plContext), 30 PKIX_LDAPCLIENTINITIATEREQUESTFAILED); 31 cleanup: 32 33 PKIX_RETURN(LDAPCLIENT); 34 35 } 36 37 PKIX_Error * 38 PKIX_PL_LdapClient_ResumeRequest( 39 PKIX_PL_LdapClient *client, 40 void **pNBIO, 41 PKIX_List **pResponse, 42 void *plContext) 43 { 44 PKIX_ENTER(LDAPCLIENT, "PKIX_PL_LdapClient_ResumeRequest"); 45 PKIX_NULLCHECK_TWO(client, client->resumeFcn); 46 47 PKIX_CHECK(client->resumeFcn 48 (client, pNBIO, pResponse, plContext), 49 PKIX_LDAPCLIENTRESUMEREQUESTFAILED); 50 cleanup: 51 52 PKIX_RETURN(LDAPCLIENT); 53 54 } 55 #endif /* !NSS_PKIX_NO_LDAP */ 56 57 /* --Private-AIAMgr-Functions----------------------------------*/ 58 59 /* 60 * FUNCTION: pkix_pl_AIAMgr_Destroy 61 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_pki.h) 62 */ 63 static PKIX_Error * 64 pkix_pl_AIAMgr_Destroy( 65 PKIX_PL_Object *object, 66 void *plContext) 67 { 68 PKIX_PL_AIAMgr *aiaMgr = NULL; 69 70 PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_Destroy"); 71 PKIX_NULLCHECK_ONE(object); 72 73 PKIX_CHECK(pkix_CheckType(object, PKIX_AIAMGR_TYPE, plContext), 74 PKIX_OBJECTNOTAIAMGR); 75 76 aiaMgr = (PKIX_PL_AIAMgr *)object; 77 78 /* pointer to cert cache */ 79 /* pointer to crl cache */ 80 aiaMgr->method = 0; 81 aiaMgr->aiaIndex = 0; 82 aiaMgr->numAias = 0; 83 PKIX_DECREF(aiaMgr->aia); 84 PKIX_DECREF(aiaMgr->location); 85 PKIX_DECREF(aiaMgr->results); 86 #ifndef NSS_PKIX_NO_LDAP 87 PKIX_DECREF(aiaMgr->client.ldapClient); 88 #endif 89 90 cleanup: 91 92 PKIX_RETURN(AIAMGR); 93 } 94 95 /* 96 * FUNCTION: pkix_pl_AIAMgr_RegisterSelf 97 * DESCRIPTION: 98 * Registers PKIX_AIAMGR_TYPE and its related functions with systemClasses[] 99 * THREAD SAFETY: 100 * Not Thread Safe - for performance and complexity reasons 101 * 102 * Since this function is only called by PKIX_PL_Initialize, which should 103 * only be called once, it is acceptable that this function is not 104 * thread-safe. 105 */ 106 PKIX_Error * 107 pkix_pl_AIAMgr_RegisterSelf(void *plContext) 108 { 109 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 110 pkix_ClassTable_Entry *entry = &systemClasses[PKIX_AIAMGR_TYPE]; 111 112 PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_RegisterSelf"); 113 114 entry->description = "AIAMgr"; 115 entry->typeObjectSize = sizeof(PKIX_PL_AIAMgr); 116 entry->destructor = pkix_pl_AIAMgr_Destroy; 117 118 PKIX_RETURN(AIAMGR); 119 } 120 121 #ifndef NSS_PKIX_NO_LDAP 122 /* 123 * FUNCTION: pkix_pl_AiaMgr_FindLDAPClient 124 * DESCRIPTION: 125 * 126 * This function checks the collection of LDAPClient connections held by the 127 * AIAMgr pointed to by "aiaMgr" for one matching the domain name given by 128 * "domainName". The string may include a port number: e.g., "betty.nist.gov" 129 * or "nss.red.iplanet.com:1389". If a match is found, that LDAPClient is 130 * stored at "pClient". Otherwise, an LDAPClient is created and added to the 131 * collection, and then stored at "pClient". 132 * 133 * PARAMETERS: 134 * "aiaMgr" 135 * The AIAMgr whose LDAPClient connected are to be managed. Must be 136 * non-NULL. 137 * "domainName" 138 * Address of a string pointing to a server name. Must be non-NULL. 139 * An empty string (which means no <host> is given in the LDAP URL) is 140 * not supported. 141 * "pClient" 142 * Address at which the returned LDAPClient is stored. Must be non-NULL. 143 * "plContext" 144 * Platform-specific context pointer. 145 * THREAD SAFETY: 146 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 147 * RETURNS: 148 * Returns NULL if the function succeeds. 149 * Returns an AIAMgr Error if the function fails in a non-fatal way 150 * Returns a Fatal Error if the function fails in an unrecoverable way. 151 */ 152 static PKIX_Error * 153 pkix_pl_AiaMgr_FindLDAPClient( 154 PKIX_PL_AIAMgr *aiaMgr, 155 char *domainName, 156 PKIX_PL_LdapClient **pClient, 157 void *plContext) 158 { 159 PKIX_PL_String *domainString = NULL; 160 PKIX_PL_LdapDefaultClient *client = NULL; 161 162 PKIX_ENTER(AIAMGR, "pkix_pl_AiaMgr_FindLDAPClient"); 163 PKIX_NULLCHECK_THREE(aiaMgr, domainName, pClient); 164 165 /* 166 * An LDAP URL may not have a <host> part, for example, 167 * ldap:///o=University%20of%20Michigan,c=US 168 * PKIX_PL_LdapDefaultClient doesn't know how to discover the default 169 * LDAP server, so we don't support this kind of LDAP URL. 170 */ 171 if (*domainName == '\0') { 172 /* Simulate a PKIX_PL_LdapDefaultClient_CreateByName failure. */ 173 PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED); 174 } 175 176 /* create PKIX_PL_String from domain name */ 177 PKIX_CHECK(PKIX_PL_String_Create 178 (PKIX_ESCASCII, domainName, 0, &domainString, plContext), 179 PKIX_STRINGCREATEFAILED); 180 181 /* Is this domainName already in cache? */ 182 PKIX_CHECK(PKIX_PL_HashTable_Lookup 183 (aiaConnectionCache, 184 (PKIX_PL_Object *)domainString, 185 (PKIX_PL_Object **)&client, 186 plContext), 187 PKIX_HASHTABLELOOKUPFAILED); 188 189 if (client == NULL) { 190 191 /* No, create a connection (and cache it) */ 192 PKIX_CHECK(PKIX_PL_LdapDefaultClient_CreateByName 193 (domainName, 194 /* Do not use NBIO until we verify, that 195 * it is working. For now use 1 min timeout. */ 196 PR_SecondsToInterval( 197 ((PKIX_PL_NssContext*)plContext)->timeoutSeconds), 198 NULL, 199 &client, 200 plContext), 201 PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED); 202 203 PKIX_CHECK(PKIX_PL_HashTable_Add 204 (aiaConnectionCache, 205 (PKIX_PL_Object *)domainString, 206 (PKIX_PL_Object *)client, 207 plContext), 208 PKIX_HASHTABLEADDFAILED); 209 210 } 211 212 *pClient = (PKIX_PL_LdapClient *)client; 213 214 cleanup: 215 216 PKIX_DECREF(domainString); 217 218 PKIX_RETURN(AIAMGR); 219 } 220 #endif /* !NSS_PKIX_NO_LDAP */ 221 222 PKIX_Error * 223 pkix_pl_AIAMgr_GetHTTPCerts( 224 PKIX_PL_AIAMgr *aiaMgr, 225 PKIX_PL_InfoAccess *ia, 226 void **pNBIOContext, 227 PKIX_List **pCerts, 228 void *plContext) 229 { 230 PKIX_PL_GeneralName *location = NULL; 231 PKIX_PL_String *locationString = NULL; 232 PKIX_UInt32 len = 0; 233 PRUint16 port = 0; 234 const SEC_HttpClientFcn *httpClient = NULL; 235 const SEC_HttpClientFcnV1 *hcv1 = NULL; 236 SECStatus rv = SECFailure; 237 SEC_HTTP_SERVER_SESSION serverSession = NULL; 238 SEC_HTTP_REQUEST_SESSION requestSession = NULL; 239 char *path = NULL; 240 char *hostname = NULL; 241 char *locationAscii = NULL; 242 void *nbio = NULL; 243 PRUint16 responseCode = 0; 244 const char *responseContentType = NULL; 245 const char *responseData = NULL; 246 247 PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetHTTPCerts"); 248 PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts); 249 250 nbio = *pNBIOContext; 251 *pNBIOContext = NULL; 252 *pCerts = NULL; 253 254 if (nbio == NULL) { /* a new request */ 255 256 PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation 257 (ia, &location, plContext), 258 PKIX_INFOACCESSGETLOCATIONFAILED); 259 260 /* find or create httpClient = default client */ 261 httpClient = SEC_GetRegisteredHttpClient(); 262 aiaMgr->client.hdata.httpClient = httpClient; 263 if (!httpClient) 264 PKIX_ERROR(PKIX_OUTOFMEMORY); 265 266 if (httpClient->version == 1) { 267 268 PKIX_UInt32 timeout = 269 ((PKIX_PL_NssContext*)plContext)->timeoutSeconds; 270 271 hcv1 = &(httpClient->fcnTable.ftable1); 272 273 /* create server session */ 274 PKIX_TOSTRING(location, &locationString, plContext, 275 PKIX_GENERALNAMETOSTRINGFAILED); 276 277 PKIX_CHECK(PKIX_PL_String_GetEncoded 278 (locationString, 279 PKIX_ESCASCII, 280 (void **)&locationAscii, 281 &len, 282 plContext), 283 PKIX_STRINGGETENCODEDFAILED); 284 285 rv = CERT_ParseURL(locationAscii, &hostname, &port, 286 &path); 287 if ((rv != SECSuccess) || 288 (hostname == NULL) || 289 (path == NULL)) { 290 PKIX_ERROR(PKIX_URLPARSINGFAILED); 291 } 292 293 rv = (*hcv1->createSessionFcn)(hostname, port, 294 &serverSession); 295 if (rv != SECSuccess) { 296 PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED); 297 } 298 299 aiaMgr->client.hdata.serverSession = serverSession; 300 301 /* create request session */ 302 rv = (*hcv1->createFcn)(serverSession, "http", path, 303 "GET", PR_SecondsToInterval(timeout), 304 &requestSession); 305 if (rv != SECSuccess) { 306 PKIX_ERROR(PKIX_HTTPSERVERERROR); 307 } 308 309 aiaMgr->client.hdata.requestSession = requestSession; 310 } else { 311 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); 312 } 313 } 314 315 httpClient = aiaMgr->client.hdata.httpClient; 316 317 if (httpClient->version == 1) { 318 PRUint32 responseDataLen = 319 ((PKIX_PL_NssContext*)plContext)->maxResponseLength; 320 321 hcv1 = &(httpClient->fcnTable.ftable1); 322 requestSession = aiaMgr->client.hdata.requestSession; 323 324 /* trySendAndReceive */ 325 rv = (*hcv1->trySendAndReceiveFcn)(requestSession, 326 (PRPollDesc **)&nbio, 327 &responseCode, 328 (const char **)&responseContentType, 329 NULL, /* &responseHeaders */ 330 (const char **)&responseData, 331 &responseDataLen); 332 333 if (rv != SECSuccess) { 334 PKIX_ERROR(PKIX_HTTPSERVERERROR); 335 } 336 337 if (nbio != 0) { 338 *pNBIOContext = nbio; 339 goto cleanup; 340 } 341 342 PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse 343 (responseCode, 344 responseContentType, 345 responseData, 346 responseDataLen, 347 pCerts, 348 plContext), 349 PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED); 350 351 /* Session and request cleanup in case of success */ 352 if (aiaMgr->client.hdata.requestSession != NULL) { 353 (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession); 354 aiaMgr->client.hdata.requestSession = NULL; 355 } 356 if (aiaMgr->client.hdata.serverSession != NULL) { 357 (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession); 358 aiaMgr->client.hdata.serverSession = NULL; 359 } 360 aiaMgr->client.hdata.httpClient = 0; /* callback fn */ 361 362 } else { 363 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); 364 } 365 366 cleanup: 367 /* Session and request cleanup in case of error. Passing through without cleanup 368 * if interrupted by blocked IO. */ 369 if (PKIX_ERROR_RECEIVED) { 370 if (aiaMgr->client.hdata.requestSession != NULL) { 371 (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession); 372 aiaMgr->client.hdata.requestSession = NULL; 373 } 374 if (aiaMgr->client.hdata.serverSession != NULL) { 375 (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession); 376 aiaMgr->client.hdata.serverSession = NULL; 377 } 378 aiaMgr->client.hdata.httpClient = 0; /* callback fn */ 379 } 380 381 PKIX_DECREF(location); 382 PKIX_DECREF(locationString); 383 384 if (locationAscii) { 385 PORT_Free(locationAscii); 386 } 387 if (hostname) { 388 PORT_Free(hostname); 389 } 390 if (path) { 391 PORT_Free(path); 392 } 393 394 PKIX_RETURN(AIAMGR); 395 } 396 397 #ifndef NSS_PKIX_NO_LDAP 398 PKIX_Error * 399 pkix_pl_AIAMgr_GetLDAPCerts( 400 PKIX_PL_AIAMgr *aiaMgr, 401 PKIX_PL_InfoAccess *ia, 402 void **pNBIOContext, 403 PKIX_List **pCerts, 404 void *plContext) 405 { 406 PKIX_List *result = NULL; 407 PKIX_PL_GeneralName *location = NULL; 408 PKIX_PL_LdapClient *client = NULL; 409 LDAPRequestParams request; 410 PLArenaPool *arena = NULL; 411 char *domainName = NULL; 412 void *nbio = NULL; 413 414 PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetLDAPCerts"); 415 PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts); 416 417 nbio = *pNBIOContext; 418 *pNBIOContext = NULL; 419 *pCerts = NULL; 420 421 if (nbio == NULL) { /* a new request */ 422 423 /* Initiate an LDAP request */ 424 425 request.scope = WHOLE_SUBTREE; 426 request.derefAliases = NEVER_DEREF; 427 request.sizeLimit = 0; 428 request.timeLimit = 0; 429 430 PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation 431 (ia, &location, plContext), 432 PKIX_INFOACCESSGETLOCATIONFAILED); 433 434 /* 435 * Get a short-lived arena. We'll be done with 436 * this space once the request is encoded. 437 */ 438 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 439 if (!arena) { 440 PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY); 441 } 442 443 PKIX_CHECK(pkix_pl_InfoAccess_ParseLocation 444 (location, arena, &request, &domainName, plContext), 445 PKIX_INFOACCESSPARSELOCATIONFAILED); 446 447 PKIX_DECREF(location); 448 449 /* Find or create a connection to LDAP server */ 450 PKIX_CHECK(pkix_pl_AiaMgr_FindLDAPClient 451 (aiaMgr, domainName, &client, plContext), 452 PKIX_AIAMGRFINDLDAPCLIENTFAILED); 453 454 aiaMgr->client.ldapClient = client; 455 456 PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest 457 (aiaMgr->client.ldapClient, 458 &request, 459 &nbio, 460 &result, 461 plContext), 462 PKIX_LDAPCLIENTINITIATEREQUESTFAILED); 463 464 PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE)); 465 466 } else { 467 468 PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest 469 (aiaMgr->client.ldapClient, &nbio, &result, plContext), 470 PKIX_LDAPCLIENTRESUMEREQUESTFAILED); 471 472 } 473 474 if (nbio != NULL) { /* WOULDBLOCK */ 475 *pNBIOContext = nbio; 476 *pCerts = NULL; 477 goto cleanup; 478 } 479 480 PKIX_DECREF(aiaMgr->client.ldapClient); 481 482 if (result == NULL) { 483 *pCerts = NULL; 484 } else { 485 PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList 486 (result, pCerts, plContext), 487 PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED); 488 } 489 490 *pNBIOContext = nbio; 491 492 cleanup: 493 494 if (arena && (PKIX_ERROR_RECEIVED)) { 495 PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE)); 496 } 497 498 if (PKIX_ERROR_RECEIVED) { 499 PKIX_DECREF(aiaMgr->client.ldapClient); 500 } 501 502 PKIX_DECREF(location); 503 504 PKIX_RETURN(AIAMGR); 505 } 506 #endif /* !NSS_PKIX_NO_LDAP */ 507 508 /* 509 * FUNCTION: PKIX_PL_AIAMgr_Create 510 * DESCRIPTION: 511 * 512 * This function creates an AIAMgr, storing the result at "pAIAMgr". 513 * 514 * PARAMETERS: 515 * "pAIAMGR" 516 * Address at which the returned AIAMgr is stored. Must be non-NULL. 517 * "plContext" 518 * Platform-specific context pointer. 519 * THREAD SAFETY: 520 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 521 * RETURNS: 522 * Returns NULL if the function succeeds. 523 * Returns an AIAMgr Error if the function fails in a non-fatal way 524 * Returns a Fatal Error if the function fails in an unrecoverable way. 525 */ 526 PKIX_Error * 527 PKIX_PL_AIAMgr_Create( 528 PKIX_PL_AIAMgr **pAIAMgr, 529 void *plContext) 530 { 531 PKIX_PL_AIAMgr *aiaMgr = NULL; 532 533 PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_Create"); 534 PKIX_NULLCHECK_ONE(pAIAMgr); 535 536 PKIX_CHECK(PKIX_PL_Object_Alloc 537 (PKIX_AIAMGR_TYPE, 538 sizeof(PKIX_PL_AIAMgr), 539 (PKIX_PL_Object **)&aiaMgr, 540 plContext), 541 PKIX_COULDNOTCREATEAIAMGROBJECT); 542 /* pointer to cert cache */ 543 /* pointer to crl cache */ 544 aiaMgr->method = 0; 545 aiaMgr->aiaIndex = 0; 546 aiaMgr->numAias = 0; 547 aiaMgr->aia = NULL; 548 aiaMgr->location = NULL; 549 aiaMgr->results = NULL; 550 aiaMgr->client.hdata.httpClient = NULL; 551 aiaMgr->client.hdata.serverSession = NULL; 552 aiaMgr->client.hdata.requestSession = NULL; 553 554 *pAIAMgr = aiaMgr; 555 556 cleanup: 557 558 PKIX_RETURN(AIAMGR); 559 } 560 561 /* --Public-Functions------------------------------------------------------- */ 562 563 /* 564 * FUNCTION: PKIX_PL_AIAMgr_GetAIACerts (see description in pkix_pl_pki.h) 565 */ 566 PKIX_Error * 567 PKIX_PL_AIAMgr_GetAIACerts( 568 PKIX_PL_AIAMgr *aiaMgr, 569 PKIX_PL_Cert *prevCert, 570 void **pNBIOContext, 571 PKIX_List **pCerts, 572 void *plContext) 573 { 574 PKIX_UInt32 numAias = 0; 575 PKIX_UInt32 aiaIndex = 0; 576 PKIX_UInt32 iaType = PKIX_INFOACCESS_LOCATION_UNKNOWN; 577 PKIX_List *certs = NULL; 578 PKIX_PL_InfoAccess *ia = NULL; 579 void *nbio = NULL; 580 581 PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_GetAIACerts"); 582 PKIX_NULLCHECK_FOUR(aiaMgr, prevCert, pNBIOContext, pCerts); 583 584 nbio = *pNBIOContext; 585 *pCerts = NULL; 586 *pNBIOContext = NULL; 587 588 if (nbio == NULL) { /* a new request */ 589 590 /* Does this Cert have an AIA extension? */ 591 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess 592 (prevCert, &aiaMgr->aia, plContext), 593 PKIX_CERTGETAUTHORITYINFOACCESSFAILED); 594 595 if (aiaMgr->aia != NULL) { 596 PKIX_CHECK(PKIX_List_GetLength 597 (aiaMgr->aia, &numAias, plContext), 598 PKIX_LISTGETLENGTHFAILED); 599 } 600 601 /* And if so, does it have any entries? */ 602 if ((aiaMgr->aia == NULL) || (numAias == 0)) { 603 *pCerts = NULL; 604 goto cleanup; 605 } 606 607 aiaMgr->aiaIndex = 0; 608 aiaMgr->numAias = numAias; 609 aiaMgr->results = NULL; 610 611 } 612 613 for (aiaIndex = aiaMgr->aiaIndex; 614 aiaIndex < aiaMgr->numAias; 615 aiaIndex ++) { 616 PKIX_UInt32 method = 0; 617 618 PKIX_CHECK(PKIX_List_GetItem 619 (aiaMgr->aia, 620 aiaIndex, 621 (PKIX_PL_Object **)&ia, 622 plContext), 623 PKIX_LISTGETITEMFAILED); 624 625 PKIX_CHECK(PKIX_PL_InfoAccess_GetMethod 626 (ia, &method, plContext), 627 PKIX_INFOACCESSGETMETHODFAILED); 628 629 if (method != PKIX_INFOACCESS_CA_ISSUERS && 630 method != PKIX_INFOACCESS_CA_REPOSITORY) { 631 PKIX_DECREF(ia); 632 continue; 633 } 634 635 PKIX_CHECK(PKIX_PL_InfoAccess_GetLocationType 636 (ia, &iaType, plContext), 637 PKIX_INFOACCESSGETLOCATIONTYPEFAILED); 638 639 if (iaType == PKIX_INFOACCESS_LOCATION_HTTP) { 640 PKIX_CHECK(pkix_pl_AIAMgr_GetHTTPCerts 641 (aiaMgr, ia, &nbio, &certs, plContext), 642 PKIX_AIAMGRGETHTTPCERTSFAILED); 643 #ifndef NSS_PKIX_NO_LDAP 644 } else if (iaType == PKIX_INFOACCESS_LOCATION_LDAP) { 645 PKIX_CHECK(pkix_pl_AIAMgr_GetLDAPCerts 646 (aiaMgr, ia, &nbio, &certs, plContext), 647 PKIX_AIAMGRGETLDAPCERTSFAILED); 648 #endif 649 } else { 650 /* We only support http and ldap requests. */ 651 PKIX_DECREF(ia); 652 continue; 653 } 654 655 if (nbio != NULL) { /* WOULDBLOCK */ 656 aiaMgr->aiaIndex = aiaIndex; 657 *pNBIOContext = nbio; 658 *pCerts = NULL; 659 goto cleanup; 660 } 661 662 /* 663 * We can't just use and modify the List we received. 664 * Because it's cached, it's set immutable. 665 */ 666 if (aiaMgr->results == NULL) { 667 PKIX_CHECK(PKIX_List_Create 668 (&(aiaMgr->results), plContext), 669 PKIX_LISTCREATEFAILED); 670 } 671 PKIX_CHECK(pkix_List_AppendList 672 (aiaMgr->results, certs, plContext), 673 PKIX_APPENDLISTFAILED); 674 PKIX_DECREF(certs); 675 676 PKIX_DECREF(ia); 677 } 678 679 PKIX_DECREF(aiaMgr->aia); 680 681 *pNBIOContext = NULL; 682 *pCerts = aiaMgr->results; 683 aiaMgr->results = NULL; 684 685 cleanup: 686 687 if (PKIX_ERROR_RECEIVED) { 688 PKIX_DECREF(aiaMgr->aia); 689 PKIX_DECREF(aiaMgr->results); 690 #ifndef NSS_PKIX_NO_LDAP 691 PKIX_DECREF(aiaMgr->client.ldapClient); 692 #endif 693 } 694 695 PKIX_DECREF(certs); 696 PKIX_DECREF(ia); 697 698 PKIX_RETURN(AIAMGR); 699 }