PKIX_Error * pkix_pl_AIAMgr_GetHTTPCerts( PKIX_PL_AIAMgr *aiaMgr, PKIX_PL_InfoAccess *ia, void **pNBIOContext, PKIX_List **pCerts, void *plContext) { PKIX_PL_GeneralName *location = NULL; PKIX_PL_String *locationString = NULL; PKIX_UInt32 len = 0; PRUint16 port = 0; const SEC_HttpClientFcn *httpClient = NULL; const SEC_HttpClientFcnV1 *hcv1 = NULL; SECStatus rv = SECFailure; SEC_HTTP_SERVER_SESSION serverSession = NULL; SEC_HTTP_REQUEST_SESSION requestSession = NULL; char *path = NULL; char *hostname = NULL; char *locationAscii = NULL; void *nbio = NULL; PRUint16 responseCode = 0; const char *responseContentType = NULL; const char *responseData = NULL; PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetHTTPCerts"); PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts); nbio = *pNBIOContext; *pNBIOContext = NULL; *pCerts = NULL; if (nbio == NULL) { /* a new request */ PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation (ia, &location, plContext), PKIX_INFOACCESSGETLOCATIONFAILED); /* find or create httpClient = default client */ httpClient = SEC_GetRegisteredHttpClient(); aiaMgr->client.hdata.httpClient = httpClient; if (!httpClient) PKIX_ERROR(PKIX_OUTOFMEMORY); if (httpClient->version == 1) { PKIX_UInt32 timeout = ((PKIX_PL_NssContext*)plContext)->timeoutSeconds; hcv1 = &(httpClient->fcnTable.ftable1); /* create server session */ PKIX_TOSTRING(location, &locationString, plContext, PKIX_GENERALNAMETOSTRINGFAILED); PKIX_CHECK(PKIX_PL_String_GetEncoded (locationString, PKIX_ESCASCII, (void **)&locationAscii, &len, plContext), PKIX_STRINGGETENCODEDFAILED); rv = CERT_ParseURL(locationAscii, &hostname, &port, &path); if ((rv != SECSuccess) || (hostname == NULL) || (path == NULL)) { PKIX_ERROR(PKIX_URLPARSINGFAILED); } rv = (*hcv1->createSessionFcn)(hostname, port, &serverSession); if (rv != SECSuccess) { PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED); } aiaMgr->client.hdata.serverSession = serverSession; /* create request session */ rv = (*hcv1->createFcn)(serverSession, "http", path, "GET", PR_SecondsToInterval(timeout), &requestSession); if (rv != SECSuccess) { PKIX_ERROR(PKIX_HTTPSERVERERROR); } aiaMgr->client.hdata.requestSession = requestSession; } else { PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); } } httpClient = aiaMgr->client.hdata.httpClient; if (httpClient->version == 1) { PRUint32 responseDataLen = ((PKIX_PL_NssContext*)plContext)->maxResponseLength; hcv1 = &(httpClient->fcnTable.ftable1); requestSession = aiaMgr->client.hdata.requestSession; /* trySendAndReceive */ rv = (*hcv1->trySendAndReceiveFcn)(requestSession, (PRPollDesc **)&nbio, &responseCode, (const char **)&responseContentType, NULL, /* &responseHeaders */ (const char **)&responseData, &responseDataLen); if (rv != SECSuccess) { PKIX_ERROR(PKIX_HTTPSERVERERROR); } if (nbio != 0) { *pNBIOContext = nbio; goto cleanup; } PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse (responseCode, responseContentType, responseData, responseDataLen, pCerts, plContext), PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED); /* Session and request cleanup in case of success */ if (aiaMgr->client.hdata.requestSession != NULL) { (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession); aiaMgr->client.hdata.requestSession = NULL; } if (aiaMgr->client.hdata.serverSession != NULL) { (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession); aiaMgr->client.hdata.serverSession = NULL; } aiaMgr->client.hdata.httpClient = 0; /* callback fn */ } else { PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); } cleanup: /* Session and request cleanup in case of error. Passing through without cleanup * if interrupted by blocked IO. */ if (PKIX_ERROR_RECEIVED && aiaMgr) { if (aiaMgr->client.hdata.requestSession != NULL) { (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession); aiaMgr->client.hdata.requestSession = NULL; } if (aiaMgr->client.hdata.serverSession != NULL) { (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession); aiaMgr->client.hdata.serverSession = NULL; } aiaMgr->client.hdata.httpClient = 0; /* callback fn */ } PKIX_DECREF(location); PKIX_DECREF(locationString); if (locationAscii) { PORT_Free(locationAscii); } if (hostname) { PORT_Free(hostname); } if (path) { PORT_Free(path); } PKIX_RETURN(AIAMGR); }
/* * FUNCTION: pkix_pl_HttpCertStore_GetCertContinue * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h) */ PKIX_Error * pkix_pl_HttpCertStore_GetCertContinue( PKIX_CertStore *store, PKIX_CertSelector *selector, void **pNBIOContext, PKIX_List **pCertList, void *plContext) { const SEC_HttpClientFcnV1 *hcv1 = NULL; PKIX_PL_HttpCertStoreContext *context = NULL; void *nbioContext = NULL; SECStatus rv = SECFailure; PRUint16 responseCode = 0; const char *responseContentType = NULL; const char *responseData = NULL; PRUint32 responseDataLen = 0; PKIX_List *certList = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCertContinue"); PKIX_NULLCHECK_THREE(store, selector, pCertList); nbioContext = *pNBIOContext; *pNBIOContext = NULL; PKIX_CHECK(PKIX_CertStore_GetCertStoreContext (store, (PKIX_PL_Object **)&context, plContext), PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED); if (context->client->version != 1) { PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); } hcv1 = &(context->client->fcnTable.ftable1); PKIX_NULLCHECK_ONE(context->requestSession); responseDataLen = ((PKIX_PL_NssContext*)plContext)->maxResponseLength; rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession, (PRPollDesc **)&nbioContext, &responseCode, (const char **)&responseContentType, NULL, /* &responseHeaders */ (const char **)&responseData, &responseDataLen); if (rv != SECSuccess) { PKIX_ERROR(PKIX_HTTPSERVERERROR); } if (nbioContext != 0) { *pNBIOContext = nbioContext; goto cleanup; } PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse (responseCode, responseContentType, responseData, responseDataLen, &certList, plContext), PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED); *pCertList = certList; cleanup: PKIX_DECREF(context); PKIX_RETURN(CERTSTORE); }