nss: import at 3.0.1 beta 1
[mozilla-nss.git] / security / nss / lib / libpkix / pkix_pl_nss / module / pkix_pl_aiamgr.c
blob707e94c9e04b0f9fcc53e2014d7d9e2ddaccef77
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the PKIX-C library.
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
21 * Contributor(s):
22 * Sun Microsystems, Inc.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 * pkix_pl_aiamgr.c
40 * AIAMgr Object Definitions
44 #include "pkix_pl_aiamgr.h"
45 extern PKIX_PL_HashTable *aiaConnectionCache;
47 /* --Virtual-LdapClient-Functions------------------------------------ */
49 PKIX_Error *
50 PKIX_PL_LdapClient_InitiateRequest(
51 PKIX_PL_LdapClient *client,
52 LDAPRequestParams *requestParams,
53 void **pNBIO,
54 PKIX_List **pResponse,
55 void *plContext)
57 PKIX_ENTER(LDAPCLIENT, "PKIX_PL_LdapClient_InitiateRequest");
58 PKIX_NULLCHECK_TWO(client, client->initiateFcn);
60 PKIX_CHECK(client->initiateFcn
61 (client, requestParams, pNBIO, pResponse, plContext),
62 PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
63 cleanup:
65 PKIX_RETURN(LDAPCLIENT);
69 PKIX_Error *
70 PKIX_PL_LdapClient_ResumeRequest(
71 PKIX_PL_LdapClient *client,
72 void **pNBIO,
73 PKIX_List **pResponse,
74 void *plContext)
76 PKIX_ENTER(LDAPCLIENT, "PKIX_PL_LdapClient_ResumeRequest");
77 PKIX_NULLCHECK_TWO(client, client->resumeFcn);
79 PKIX_CHECK(client->resumeFcn
80 (client, pNBIO, pResponse, plContext),
81 PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
82 cleanup:
84 PKIX_RETURN(LDAPCLIENT);
88 /* --Private-AIAMgr-Functions----------------------------------*/
91 * FUNCTION: pkix_pl_AIAMgr_Destroy
92 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_pki.h)
94 static PKIX_Error *
95 pkix_pl_AIAMgr_Destroy(
96 PKIX_PL_Object *object,
97 void *plContext)
99 PKIX_PL_AIAMgr *aiaMgr = NULL;
101 PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_Destroy");
102 PKIX_NULLCHECK_ONE(object);
104 PKIX_CHECK(pkix_CheckType(object, PKIX_AIAMGR_TYPE, plContext),
105 PKIX_OBJECTNOTAIAMGR);
107 aiaMgr = (PKIX_PL_AIAMgr *)object;
109 /* pointer to cert cache */
110 /* pointer to crl cache */
111 aiaMgr->method = 0;
112 aiaMgr->aiaIndex = 0;
113 aiaMgr->numAias = 0;
114 PKIX_DECREF(aiaMgr->aia);
115 PKIX_DECREF(aiaMgr->location);
116 PKIX_DECREF(aiaMgr->results);
117 PKIX_DECREF(aiaMgr->client.ldapClient);
119 cleanup:
121 PKIX_RETURN(AIAMGR);
125 * FUNCTION: pkix_pl_AIAMgr_RegisterSelf
126 * DESCRIPTION:
127 * Registers PKIX_AIAMGR_TYPE and its related functions with systemClasses[]
128 * THREAD SAFETY:
129 * Not Thread Safe - for performance and complexity reasons
131 * Since this function is only called by PKIX_PL_Initialize, which should
132 * only be called once, it is acceptable that this function is not
133 * thread-safe.
135 PKIX_Error *
136 pkix_pl_AIAMgr_RegisterSelf(void *plContext)
138 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
139 pkix_ClassTable_Entry entry;
141 PKIX_ENTER(AIAMGR,
142 "pkix_pl_AIAMgr_RegisterSelf");
144 entry.description = "AIAMgr";
145 entry.objCounter = 0;
146 entry.typeObjectSize = sizeof(PKIX_PL_AIAMgr);
147 entry.destructor = pkix_pl_AIAMgr_Destroy;
148 entry.equalsFunction = NULL;
149 entry.hashcodeFunction = NULL;
150 entry.toStringFunction = NULL;
151 entry.comparator = NULL;
152 entry.duplicateFunction = NULL;
154 systemClasses[PKIX_AIAMGR_TYPE] = entry;
156 PKIX_RETURN(AIAMGR);
160 * FUNCTION: pkix_pl_AiaMgr_FindLDAPClient
161 * DESCRIPTION:
163 * This function checks the collection of LDAPClient connections held by the
164 * AIAMgr pointed to by "aiaMgr" for one matching the domain name given by
165 * "domainName". The string may include a port number: e.g., "betty.nist.gov"
166 * or "nss.red.iplanet.com:1389". If a match is found, that LDAPClient is
167 * stored at "pClient". Otherwise, an LDAPClient is created and added to the
168 * collection, and then stored at "pClient".
170 * PARAMETERS:
171 * "aiaMgr"
172 * The AIAMgr whose LDAPClient connected are to be managed. Must be
173 * non-NULL.
174 * "domainName"
175 * Address of a string pointing to a server name. Must be non-NULL.
176 * "pClient"
177 * Address at which the returned LDAPClient is stored. Must be non-NULL.
178 * "plContext"
179 * Platform-specific context pointer.
180 * THREAD SAFETY:
181 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
182 * RETURNS:
183 * Returns NULL if the function succeeds.
184 * Returns an AIAMgr Error if the function fails in a non-fatal way
185 * Returns a Fatal Error if the function fails in an unrecoverable way.
187 static PKIX_Error *
188 pkix_pl_AiaMgr_FindLDAPClient(
189 PKIX_PL_AIAMgr *aiaMgr,
190 char *domainName,
191 PKIX_PL_LdapClient **pClient,
192 void *plContext)
194 PKIX_PL_String *domainString = NULL;
195 PKIX_PL_LdapDefaultClient *client = NULL;
197 PKIX_ENTER(AIAMGR, "pkix_pl_AiaMgr_FindLDAPClient");
198 PKIX_NULLCHECK_THREE(aiaMgr, domainName, pClient);
200 /* create PKIX_PL_String from domain name */
201 PKIX_CHECK(PKIX_PL_String_Create
202 (PKIX_ESCASCII, domainName, 0, &domainString, plContext),
203 PKIX_STRINGCREATEFAILED);
205 /* Is this domainName already in cache? */
206 PKIX_CHECK(PKIX_PL_HashTable_Lookup
207 (aiaConnectionCache,
208 (PKIX_PL_Object *)domainString,
209 (PKIX_PL_Object **)&client,
210 plContext),
211 PKIX_HASHTABLELOOKUPFAILED);
213 if (client == NULL) {
215 /* No, create a connection (and cache it) */
216 PKIX_CHECK(PKIX_PL_LdapDefaultClient_CreateByName
217 (domainName,
218 /* Do not use NBIO until we verify, that
219 * it is working */
220 PR_INTERVAL_NO_TIMEOUT, /* PR_INTERVAL_NO_WAIT, */
221 NULL,
222 &client,
223 plContext),
224 PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED);
226 PKIX_CHECK(PKIX_PL_HashTable_Add
227 (aiaConnectionCache,
228 (PKIX_PL_Object *)domainString,
229 (PKIX_PL_Object *)client,
230 plContext),
231 PKIX_HASHTABLEADDFAILED);
235 *pClient = (PKIX_PL_LdapClient *)client;
237 cleanup:
239 PKIX_DECREF(domainString);
241 PKIX_RETURN(AIAMGR);
244 PKIX_Error *
245 pkix_pl_AIAMgr_GetHTTPCerts(
246 PKIX_PL_AIAMgr *aiaMgr,
247 PKIX_PL_InfoAccess *ia,
248 void **pNBIOContext,
249 PKIX_List **pCerts,
250 void *plContext)
252 PKIX_PL_GeneralName *location = NULL;
253 PKIX_PL_String *locationString = NULL;
254 PKIX_UInt32 len = 0;
255 PRUint16 port = 0;
256 const SEC_HttpClientFcn *httpClient = NULL;
257 const SEC_HttpClientFcnV1 *hcv1 = NULL;
258 SECStatus rv = SECFailure;
259 SEC_HTTP_SERVER_SESSION serverSession = NULL;
260 SEC_HTTP_REQUEST_SESSION requestSession = NULL;
261 char *path = NULL;
262 char *hostname = NULL;
263 char *locationAscii = NULL;
264 void *nbio = NULL;
265 PRUint16 responseCode = 0;
266 const char *responseContentType = NULL;
267 const char *responseData = NULL;
268 PRUint32 responseDataLen = 0;
270 PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetHTTPCerts");
271 PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts);
273 nbio = *pNBIOContext;
274 *pNBIOContext = NULL;
275 *pCerts = NULL;
277 if (nbio == NULL) { /* a new request */
279 PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation
280 (ia, &location, plContext),
281 PKIX_INFOACCESSGETLOCATIONFAILED);
283 /* find or create httpClient = default client */
284 httpClient = SEC_GetRegisteredHttpClient();
285 aiaMgr->client.hdata.httpClient = httpClient;
287 if (httpClient->version == 1) {
289 hcv1 = &(httpClient->fcnTable.ftable1);
291 /* create server session */
292 PKIX_TOSTRING(location, &locationString, plContext,
293 PKIX_GENERALNAMETOSTRINGFAILED);
295 PKIX_CHECK(PKIX_PL_String_GetEncoded
296 (locationString,
297 PKIX_ESCASCII,
298 (void **)&locationAscii,
299 &len,
300 plContext),
301 PKIX_STRINGGETENCODEDFAILED);
303 PKIX_PL_NSSCALLRV
304 (AIAMGR, rv, CERT_ParseURL,
305 (locationAscii, &hostname, &port, &path));
307 if ((rv != SECSuccess) ||
308 (hostname == NULL) ||
309 (path == NULL)) {
310 PKIX_ERROR(PKIX_URLPARSINGFAILED);
313 PKIX_PL_NSSCALLRV
314 (AIAMGR, rv, hcv1->createSessionFcn,
315 (hostname, port, &serverSession));
317 if (rv != SECSuccess) {
318 PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED);
321 aiaMgr->client.hdata.serverSession = serverSession;
323 /* create request session */
324 PKIX_PL_NSSCALLRV
325 (AIAMGR, rv, hcv1->createFcn,
326 (serverSession,
327 "http",
328 path,
329 "GET",
330 PR_TicksPerSecond() * 60,
331 &requestSession));
333 if (rv != SECSuccess) {
334 if (path != NULL) {
335 PORT_Free(path);
337 PKIX_ERROR(PKIX_HTTPSERVERERROR);
340 aiaMgr->client.hdata.requestSession = requestSession;
341 } else {
342 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
346 httpClient = aiaMgr->client.hdata.httpClient;
348 if (httpClient->version == 1) {
350 hcv1 = &(httpClient->fcnTable.ftable1);
351 requestSession = aiaMgr->client.hdata.requestSession;
353 /* trySendAndReceive */
354 PKIX_PL_NSSCALLRV
355 (AIAMGR, rv, hcv1->trySendAndReceiveFcn,
356 (requestSession,
357 (PRPollDesc **)&nbio,
358 &responseCode,
359 (const char **)&responseContentType,
360 NULL, /* &responseHeaders */
361 (const char **)&responseData,
362 &responseDataLen));
364 if (rv != SECSuccess) {
365 PKIX_ERROR(PKIX_HTTPSERVERERROR);
368 if (nbio != 0) {
369 *pNBIOContext = nbio;
370 goto cleanup;
373 PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
374 (responseCode,
375 responseContentType,
376 responseData,
377 responseDataLen,
378 pCerts,
379 plContext),
380 PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
382 /* Session and request cleanup in case of success */
383 if (aiaMgr->client.hdata.requestSession != NULL) {
384 (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
385 aiaMgr->client.hdata.requestSession = NULL;
387 if (aiaMgr->client.hdata.serverSession != NULL) {
388 (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession);
389 aiaMgr->client.hdata.serverSession = NULL;
391 aiaMgr->client.hdata.httpClient = 0; /* callback fn */
393 } else {
394 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
397 cleanup:
398 /* Session and request cleanup in case of error. Passing through without cleanup
399 * if interrupted by blocked IO. */
400 if (PKIX_ERROR_RECEIVED && aiaMgr) {
401 if (aiaMgr->client.hdata.requestSession != NULL) {
402 (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
403 aiaMgr->client.hdata.requestSession = NULL;
405 if (aiaMgr->client.hdata.serverSession != NULL) {
406 (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession);
407 aiaMgr->client.hdata.serverSession = NULL;
409 aiaMgr->client.hdata.httpClient = 0; /* callback fn */
412 PKIX_DECREF(location);
413 PKIX_DECREF(locationString);
415 if (locationAscii) {
416 PORT_Free(locationAscii);
419 PKIX_RETURN(AIAMGR);
422 PKIX_Error *
423 pkix_pl_AIAMgr_GetLDAPCerts(
424 PKIX_PL_AIAMgr *aiaMgr,
425 PKIX_PL_InfoAccess *ia,
426 void **pNBIOContext,
427 PKIX_List **pCerts,
428 void *plContext)
430 PKIX_List *result = NULL;
431 PKIX_PL_GeneralName *location = NULL;
432 PKIX_PL_LdapClient *client = NULL;
433 LDAPRequestParams request;
434 PRArenaPool *arena = NULL;
435 char *domainName = NULL;
436 void *nbio = NULL;
438 PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetLDAPCerts");
439 PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts);
441 nbio = *pNBIOContext;
442 *pNBIOContext = NULL;
443 *pCerts = NULL;
445 if (nbio == NULL) { /* a new request */
447 /* Initiate an LDAP request */
449 request.scope = WHOLE_SUBTREE;
450 request.derefAliases = NEVER_DEREF;
451 request.sizeLimit = 0;
452 request.timeLimit = 0;
454 PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation
455 (ia, &location, plContext),
456 PKIX_INFOACCESSGETLOCATIONFAILED);
459 * Get a short-lived arena. We'll be done with
460 * this space once the request is encoded.
462 PKIX_PL_NSSCALLRV(AIAMGR, arena, PORT_NewArena,
463 (DER_DEFAULT_CHUNKSIZE));
465 if (!arena) {
466 PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
469 PKIX_CHECK(pkix_pl_InfoAccess_ParseLocation
470 (location, arena, &request, &domainName, plContext),
471 PKIX_INFOACCESSPARSELOCATIONFAILED);
473 PKIX_DECREF(location);
475 /* Find or create a connection to LDAP server */
476 PKIX_CHECK(pkix_pl_AiaMgr_FindLDAPClient
477 (aiaMgr, domainName, &client, plContext),
478 PKIX_AIAMGRFINDLDAPCLIENTFAILED);
480 aiaMgr->client.ldapClient = client;
482 PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
483 (aiaMgr->client.ldapClient,
484 &request,
485 &nbio,
486 &result,
487 plContext),
488 PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
490 PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE));
492 } else {
494 PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
495 (aiaMgr->client.ldapClient, &nbio, &result, plContext),
496 PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
500 if (nbio != NULL) { /* WOULDBLOCK */
501 *pNBIOContext = nbio;
502 *pCerts = NULL;
503 goto cleanup;
506 PKIX_DECREF(aiaMgr->client.ldapClient);
508 if (result == NULL) {
509 *pCerts = NULL;
510 } else {
511 PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
512 (result, pCerts, plContext),
513 PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
516 *pNBIOContext = nbio;
518 cleanup:
520 if (arena && (PKIX_ERROR_RECEIVED)) {
521 PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE));
524 if (PKIX_ERROR_RECEIVED) {
525 PKIX_DECREF(aiaMgr->client.ldapClient);
528 PKIX_DECREF(location);
530 PKIX_RETURN(AIAMGR);
534 * FUNCTION: PKIX_PL_AIAMgr_Create
535 * DESCRIPTION:
537 * This function creates an AIAMgr, storing the result at "pAIAMgr".
539 * PARAMETERS:
540 * "pAIAMGR"
541 * Address at which the returned AIAMgr is stored. Must be non-NULL.
542 * "plContext"
543 * Platform-specific context pointer.
544 * THREAD SAFETY:
545 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
546 * RETURNS:
547 * Returns NULL if the function succeeds.
548 * Returns an AIAMgr Error if the function fails in a non-fatal way
549 * Returns a Fatal Error if the function fails in an unrecoverable way.
551 PKIX_Error *
552 PKIX_PL_AIAMgr_Create(
553 PKIX_PL_AIAMgr **pAIAMgr,
554 void *plContext)
556 PKIX_PL_AIAMgr *aiaMgr = NULL;
558 PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_Create");
559 PKIX_NULLCHECK_ONE(pAIAMgr);
561 PKIX_CHECK(PKIX_PL_Object_Alloc
562 (PKIX_AIAMGR_TYPE,
563 sizeof(PKIX_PL_AIAMgr),
564 (PKIX_PL_Object **)&aiaMgr,
565 plContext),
566 PKIX_COULDNOTCREATEAIAMGROBJECT);
567 /* pointer to cert cache */
568 /* pointer to crl cache */
569 aiaMgr->method = 0;
570 aiaMgr->aiaIndex = 0;
571 aiaMgr->numAias = 0;
572 aiaMgr->aia = NULL;
573 aiaMgr->location = NULL;
574 aiaMgr->results = NULL;
575 aiaMgr->client.hdata.httpClient = NULL;
576 aiaMgr->client.hdata.serverSession = NULL;
577 aiaMgr->client.hdata.requestSession = NULL;
579 *pAIAMgr = aiaMgr;
581 cleanup:
583 PKIX_RETURN(AIAMGR);
586 /* --Public-Functions------------------------------------------------------- */
589 * FUNCTION: PKIX_PL_AIAMgr_GetAIACerts (see description in pkix_pl_pki.h)
591 PKIX_Error *
592 PKIX_PL_AIAMgr_GetAIACerts(
593 PKIX_PL_AIAMgr *aiaMgr,
594 PKIX_PL_Cert *prevCert,
595 void **pNBIOContext,
596 PKIX_List **pCerts,
597 void *plContext)
599 PKIX_UInt32 numAias = 0;
600 PKIX_UInt32 aiaIndex = 0;
601 PKIX_UInt32 iaType = PKIX_INFOACCESS_LOCATION_UNKNOWN;
602 PKIX_List *certs = NULL;
603 PKIX_PL_InfoAccess *ia = NULL;
604 void *nbio = NULL;
606 PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_GetAIACerts");
607 PKIX_NULLCHECK_FOUR(aiaMgr, prevCert, pNBIOContext, pCerts);
609 nbio = *pNBIOContext;
610 *pCerts = NULL;
611 *pNBIOContext = NULL;
613 if (nbio == NULL) { /* a new request */
615 /* Does this Cert have an AIA extension? */
616 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess
617 (prevCert, &aiaMgr->aia, plContext),
618 PKIX_CERTGETAUTHORITYINFOACCESSFAILED);
620 if (aiaMgr->aia != NULL) {
621 PKIX_CHECK(PKIX_List_GetLength
622 (aiaMgr->aia, &numAias, plContext),
623 PKIX_LISTGETLENGTHFAILED);
626 /* And if so, does it have any entries? */
627 if ((aiaMgr->aia == NULL) || (numAias == 0)) {
628 *pCerts = NULL;
629 goto cleanup;
632 aiaMgr->aiaIndex = 0;
633 aiaMgr->numAias = numAias;
634 aiaMgr->results = NULL;
638 for (aiaIndex = aiaMgr->aiaIndex;
639 aiaIndex < aiaMgr->numAias;
640 aiaIndex ++) {
641 PKIX_UInt32 method = 0;
643 PKIX_CHECK(PKIX_List_GetItem
644 (aiaMgr->aia,
645 aiaIndex,
646 (PKIX_PL_Object **)&ia,
647 plContext),
648 PKIX_LISTGETITEMFAILED);
650 PKIX_CHECK(PKIX_PL_InfoAccess_GetMethod
651 (ia, &method, plContext),
652 PKIX_INFOACCESSGETMETHODFAILED);
654 if (method != PKIX_INFOACCESS_CA_ISSUERS &&
655 method != PKIX_INFOACCESS_CA_REPOSITORY) {
656 PKIX_DECREF(ia);
657 continue;
660 PKIX_CHECK(PKIX_PL_InfoAccess_GetLocationType
661 (ia, &iaType, plContext),
662 PKIX_INFOACCESSGETLOCATIONTYPEFAILED);
664 if (iaType == PKIX_INFOACCESS_LOCATION_HTTP) {
665 PKIX_CHECK(pkix_pl_AIAMgr_GetHTTPCerts
666 (aiaMgr, ia, &nbio, &certs, plContext),
667 PKIX_AIAMGRGETHTTPCERTSFAILED);
668 } else if (iaType == PKIX_INFOACCESS_LOCATION_LDAP) {
669 PKIX_CHECK(pkix_pl_AIAMgr_GetLDAPCerts
670 (aiaMgr, ia, &nbio, &certs, plContext),
671 PKIX_AIAMGRGETLDAPCERTSFAILED);
672 } else {
673 /* We only support http and ldap requests. */
674 PKIX_ERROR(PKIX_UNKNOWNINFOACCESSTYPE);
677 if (nbio != NULL) { /* WOULDBLOCK */
678 aiaMgr->aiaIndex = aiaIndex;
679 *pNBIOContext = nbio;
680 *pCerts = NULL;
681 goto cleanup;
685 * We can't just use and modify the List we received.
686 * Because it's cached, it's set immutable.
688 if (aiaMgr->results == NULL) {
689 PKIX_CHECK(PKIX_List_Create
690 (&(aiaMgr->results), plContext),
691 PKIX_LISTCREATEFAILED);
693 PKIX_CHECK(pkix_List_AppendList
694 (aiaMgr->results, certs, plContext),
695 PKIX_APPENDLISTFAILED);
696 PKIX_DECREF(certs);
698 PKIX_DECREF(ia);
701 PKIX_DECREF(aiaMgr->aia);
703 *pNBIOContext = NULL;
704 *pCerts = aiaMgr->results;
705 aiaMgr->results = NULL;
707 cleanup:
709 if (PKIX_ERROR_RECEIVED) {
710 PKIX_DECREF(aiaMgr->aia);
711 PKIX_DECREF(aiaMgr->results);
712 PKIX_DECREF(aiaMgr->client.ldapClient);
715 PKIX_DECREF(ia);
717 PKIX_RETURN(AIAMGR);