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); }
PKIX_Error * pkix_pl_AIAMgr_GetLDAPCerts( PKIX_PL_AIAMgr *aiaMgr, PKIX_PL_InfoAccess *ia, void **pNBIOContext, PKIX_List **pCerts, void *plContext) { PKIX_List *result = NULL; PKIX_PL_GeneralName *location = NULL; PKIX_PL_LdapClient *client = NULL; LDAPRequestParams request; PLArenaPool *arena = NULL; char *domainName = NULL; void *nbio = NULL; PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetLDAPCerts"); PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts); nbio = *pNBIOContext; *pNBIOContext = NULL; *pCerts = NULL; if (nbio == NULL) { /* a new request */ /* Initiate an LDAP request */ request.scope = WHOLE_SUBTREE; request.derefAliases = NEVER_DEREF; request.sizeLimit = 0; request.timeLimit = 0; PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation (ia, &location, plContext), PKIX_INFOACCESSGETLOCATIONFAILED); /* * Get a short-lived arena. We'll be done with * this space once the request is encoded. */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY); } PKIX_CHECK(pkix_pl_InfoAccess_ParseLocation (location, arena, &request, &domainName, plContext), PKIX_INFOACCESSPARSELOCATIONFAILED); PKIX_DECREF(location); /* Find or create a connection to LDAP server */ PKIX_CHECK(pkix_pl_AiaMgr_FindLDAPClient (aiaMgr, domainName, &client, plContext), PKIX_AIAMGRFINDLDAPCLIENTFAILED); aiaMgr->client.ldapClient = client; PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest (aiaMgr->client.ldapClient, &request, &nbio, &result, plContext), PKIX_LDAPCLIENTINITIATEREQUESTFAILED); PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE)); } else { PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest (aiaMgr->client.ldapClient, &nbio, &result, plContext), PKIX_LDAPCLIENTRESUMEREQUESTFAILED); } if (nbio != NULL) { /* WOULDBLOCK */ *pNBIOContext = nbio; *pCerts = NULL; goto cleanup; } PKIX_DECREF(aiaMgr->client.ldapClient); if (result == NULL) { *pCerts = NULL; } else { PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList (result, pCerts, plContext), PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED); } *pNBIOContext = nbio; cleanup: if (arena && (PKIX_ERROR_RECEIVED)) { PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE)); } if (PKIX_ERROR_RECEIVED) { PKIX_DECREF(aiaMgr->client.ldapClient); } PKIX_DECREF(location); PKIX_RETURN(AIAMGR); }
int test_subjectinfoaccess(int argc, char *argv[]) { PKIX_PL_Cert *cert = NULL; PKIX_PL_Cert *certDiff = NULL; PKIX_List *aiaList = NULL; PKIX_List *siaList = NULL; PKIX_PL_InfoAccess *sia = NULL; PKIX_PL_InfoAccess *siaDup = NULL; PKIX_PL_InfoAccess *siaDiff = NULL; PKIX_PL_GeneralName *location = NULL; char *certPathName = NULL; char *dirName = NULL; PKIX_UInt32 method = 0; PKIX_UInt32 actualMinorVersion; PKIX_UInt32 size, i; PKIX_UInt32 j = 0; char *expectedAscii = "[method:caRepository, " "location:http://betty.nist.gov/pathdiscoverytestsuite/" "p7cfiles/IssuedByTrustAnchor1.p7c]"; PKIX_TEST_STD_VARS(); startTests("SubjectInfoAccess"); PKIX_TEST_EXPECT_NO_ERROR( PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext)); if (argc < 5+j) { printf("Usage: %s <test-purpose> <cert> <diff-cert>\n", argv[0]); } dirName = argv[2+j]; certPathName = argv[3+j]; subTest("Creating Cert with Subject Info Access"); cert = createCert(dirName, certPathName, plContext); certPathName = argv[4+j]; subTest("Creating Cert with Subject Info Access"); certDiff = createCert(dirName, certPathName, plContext); subTest("Getting Subject Info Access"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectInfoAccess (cert, &siaList, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength (siaList, &size, plContext)); if (size != 1) { pkixTestErrorMsg = "unexpected number of AIA"; goto cleanup; } PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem (siaList, 0, (PKIX_PL_Object **) &sia, plContext)); subTest("PKIX_PL_InfoAccess_GetMethod"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_InfoAccess_GetMethod (sia, &method, plContext)); if (method != PKIX_INFOACCESS_CA_REPOSITORY) { pkixTestErrorMsg = "unexpected method of AIA"; goto cleanup; } subTest("PKIX_PL_InfoAccess_GetLocation"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_InfoAccess_GetLocation (sia, &location, plContext)); if (!location) { pkixTestErrorMsg = "Cannot get AIA location"; goto cleanup; } PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem (siaList, 0, (PKIX_PL_Object **) &siaDup, plContext)); subTest("Getting Authority Info Access as difference comparison"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetAuthorityInfoAccess (certDiff, &aiaList, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength (aiaList, &size, plContext)); if (size != 1) { pkixTestErrorMsg = "unexpected number of AIA"; goto cleanup; } PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem (aiaList, 0, (PKIX_PL_Object **) &siaDiff, plContext)); subTest("Checking: Equal, Hash and ToString"); PKIX_TEST_EQ_HASH_TOSTR_DUP (sia, siaDup, siaDiff, expectedAscii, InfoAccess, PKIX_FALSE); cleanup: PKIX_TEST_DECREF_AC(location); PKIX_TEST_DECREF_AC(sia); PKIX_TEST_DECREF_AC(siaDup); PKIX_TEST_DECREF_AC(siaDiff); PKIX_TEST_DECREF_AC(aiaList); PKIX_TEST_DECREF_AC(siaList); PKIX_TEST_DECREF_AC(cert); PKIX_TEST_DECREF_AC(certDiff); PKIX_Shutdown(plContext); PKIX_TEST_RETURN(); endTests("Subjectinfoaccess"); return (0); }