/* * FUNCTION: pkix_pl_Date_ToString_Helper * DESCRIPTION: * * Helper function that creates a string representation of the SECItem pointed * to by "nssTime" (which represents a date) and stores it at "pString". * * PARAMETERS * "nssTime" * Address of SECItem whose string representation is desired. * Must be non-NULL. * "pString" * Address where object pointer will be stored. Must be non-NULL. * "plContext" - Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a Date Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_Date_ToString_Helper( SECItem *nssTime, PKIX_PL_String **pString, void *plContext) { char *asciiDate = NULL; PKIX_ENTER(DATE, "pkix_pl_Date_ToString_Helper"); PKIX_NULLCHECK_TWO(nssTime, pString); switch (nssTime->type) { case siUTCTime: PKIX_PL_NSSCALLRV (DATE, asciiDate, DER_UTCDayToAscii, (nssTime)); if (!asciiDate){ PKIX_ERROR(PKIX_DERUTCTIMETOASCIIFAILED); } break; case siGeneralizedTime: /* * we don't currently have any way to create GeneralizedTime. * this code is only here so that it will be in place when * we do have the capability to create GeneralizedTime. */ PKIX_PL_NSSCALLRV (DATE, asciiDate, DER_GeneralizedDayToAscii, (nssTime)); if (!asciiDate){ PKIX_ERROR(PKIX_DERGENERALIZEDDAYTOASCIIFAILED); } break; default: PKIX_ERROR(PKIX_UNRECOGNIZEDTIMETYPE); } PKIX_CHECK(PKIX_PL_String_Create (PKIX_ESCASCII, asciiDate, 0, pString, plContext), PKIX_STRINGCREATEFAILED); cleanup: PR_Free(asciiDate); PKIX_RETURN(DATE); }
/* * FUNCTION: pkix_pl_HttpCertStore_CreateRequestSession * DESCRIPTION: * * This function takes elements from the HttpCertStoreContext pointed to by * "context" (path, client, and serverSession) and creates a RequestSession. * See the HTTPClient API described in ocspt.h for further details. * * PARAMETERS: * "context" * The address of the HttpCertStoreContext. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a HttpCertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_HttpCertStore_CreateRequestSession( PKIX_PL_HttpCertStoreContext *context, void *plContext) { const SEC_HttpClientFcnV1 *hcv1 = NULL; SECStatus rv = SECFailure; char *pathString = NULL; PKIX_ENTER (HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStore_CreateRequestSession"); PKIX_NULLCHECK_TWO(context, context->serverSession); pathString = PR_smprintf("%s", context->path); if (context->client->version == 1) { hcv1 = &(context->client->fcnTable.ftable1); if (context->requestSession != NULL) { PKIX_PL_NSSCALL(HTTPCERTSTORECONTEXT, hcv1->freeFcn, (context->requestSession)); context->requestSession = 0; } PKIX_PL_NSSCALLRV (HTTPCERTSTORECONTEXT, rv, hcv1->createFcn, (context->serverSession, "http", pathString, "GET", PR_TicksPerSecond() * 60, &(context->requestSession))); if (rv != SECSuccess) { if (pathString != NULL) { PORT_Free(pathString); } PKIX_ERROR(PKIX_HTTPSERVERERROR); } } else { PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); } cleanup: PKIX_RETURN(HTTPCERTSTORECONTEXT); }
/* * FUNCTION: pkix_pl_LdapCertStore_GetCRL * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h) */ PKIX_Error * pkix_pl_LdapCertStore_GetCRL( PKIX_CertStore *store, PKIX_CRLSelector *selector, void **pNBIOContext, PKIX_List **pCrlList, void *plContext) { LDAPRequestParams requestParams; void *pollDesc = NULL; PRArenaPool *requestArena = NULL; PKIX_UInt32 numNames = 0; PKIX_UInt32 thisName = 0; PKIX_PL_CRL *candidate = NULL; PKIX_List *responses = NULL; PKIX_List *issuerNames = NULL; PKIX_List *filteredCRLs = NULL; PKIX_List *unfilteredCRLs = NULL; PKIX_PL_X500Name *issuer = NULL; PKIX_PL_LdapCertStoreContext *lcs = NULL; PKIX_ComCRLSelParams *params = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCRL"); PKIX_NULLCHECK_THREE(store, selector, pCrlList); requestParams.baseObject = "c=US"; requestParams.scope = WHOLE_SUBTREE; requestParams.derefAliases = NEVER_DEREF; requestParams.sizeLimit = 0; requestParams.timeLimit = 0; requestParams.attributes = LDAPATTR_CERTREVLIST | LDAPATTR_AUTHREVLIST; /* Prepare elements for request filter */ /* XXX Place CRLDP code here. Handle the case when */ /* RFC 5280. Paragraph: 4.2.1.13: */ /* If the distributionPoint field contains a directoryName, the entry */ /* for that directoryName contains the current CRL for the associated */ /* reasons and the CRL is issued by the associated cRLIssuer. The CRL */ /* may be stored in either the certificateRevocationList or */ /* authorityRevocationList attribute. The CRL is to be obtained by the */ /* application from whatever directory server is locally configured. */ /* The protocol the application uses to access the directory (e.g., DAP */ /* or LDAP) is a local matter. */ /* * Get a short-lived arena. We'll be done with this space once * the request is encoded. */ PKIX_PL_NSSCALLRV (CERTSTORE, requestArena, PORT_NewArena, (DER_DEFAULT_CHUNKSIZE)); if (!requestArena) { PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY); } PKIX_CHECK(PKIX_CRLSelector_GetCommonCRLSelectorParams (selector, ¶ms, plContext), PKIX_CRLSELECTORGETCOMCERTSELPARAMSFAILED); PKIX_CHECK(PKIX_ComCRLSelParams_GetIssuerNames (params, &issuerNames, plContext), PKIX_COMCRLSELPARAMSGETISSUERNAMESFAILED); /* * The specification for PKIX_ComCRLSelParams_GetIssuerNames in * pkix_crlsel.h says that if the criterion is not set we get a null * pointer. If we get an empty List the criterion is impossible to * meet ("must match at least one of the names in the List"). */ if (issuerNames) { PKIX_CHECK(PKIX_List_GetLength (issuerNames, &numNames, plContext), PKIX_LISTGETLENGTHFAILED); if (numNames > 0) { for (thisName = 0; thisName < numNames; thisName++) { PKIX_CHECK(PKIX_List_GetItem (issuerNames, thisName, (PKIX_PL_Object **)&issuer, plContext), PKIX_LISTGETITEMFAILED); PKIX_CHECK (pkix_pl_LdapCertStore_MakeNameAVAList (requestArena, issuer, &(requestParams.nc), plContext), PKIX_LDAPCERTSTOREMAKENAMEAVALISTFAILED); PKIX_DECREF(issuer); if (*requestParams.nc == NULL) { /* * The issuer may not include any * components that we know how to * encode. We do not return an error, * because the caller did not * necessarily do anything wrong, but * we return an empty List. */ PKIX_PL_NSSCALL (CERTSTORE, PORT_FreeArena, (requestArena, PR_FALSE)); PKIX_CHECK(PKIX_List_Create (&filteredCRLs, plContext), PKIX_LISTCREATEFAILED); PKIX_CHECK(PKIX_List_SetImmutable (filteredCRLs, plContext), PKIX_LISTSETIMMUTABLEFAILED); *pNBIOContext = NULL; *pCrlList = filteredCRLs; goto cleanup; } /* * LDAP Servers don't seem to be able to handle * requests with more than more than one name. */ break; } } else { PKIX_ERROR(PKIX_IMPOSSIBLECRITERIONFORCRLQUERY); } } else { PKIX_ERROR(PKIX_IMPOSSIBLECRITERIONFORCRLQUERY); } /* All request fields are done */ PKIX_CHECK(PKIX_CertStore_GetCertStoreContext (store, (PKIX_PL_Object **)&lcs, plContext), PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED); PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest ((PKIX_PL_LdapClient *)lcs, &requestParams, &pollDesc, &responses, plContext), PKIX_LDAPCLIENTINITIATEREQUESTFAILED); PKIX_CHECK(pkix_pl_LdapCertStore_DestroyAVAList (requestParams.nc, plContext), PKIX_LDAPCERTSTOREDESTROYAVALISTFAILED); if (requestArena) { PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena, (requestArena, PR_FALSE)); } if (pollDesc != NULL) { /* client is waiting for non-blocking I/O to complete */ *pNBIOContext = (void *)pollDesc; *pCrlList = NULL; goto cleanup; } /* client has finished! */ if (responses) { /* * We have a List of LdapResponse objects that still have to be * turned into Crls. */ PKIX_CHECK(pkix_pl_LdapCertStore_BuildCrlList (responses, &unfilteredCRLs, plContext), PKIX_LDAPCERTSTOREBUILDCRLLISTFAILED); PKIX_CHECK(pkix_CRLSelector_Select (selector, unfilteredCRLs, &filteredCRLs, plContext), PKIX_CRLSELECTORSELECTFAILED); } /* Don't throw away the list if one CRL was bad! */ pkixTempErrorReceived = PKIX_FALSE; *pNBIOContext = NULL; *pCrlList = filteredCRLs; cleanup: if (PKIX_ERROR_RECEIVED) { PKIX_DECREF(filteredCRLs); } PKIX_DECREF(params); PKIX_DECREF(issuerNames); PKIX_DECREF(issuer); PKIX_DECREF(candidate); PKIX_DECREF(responses); PKIX_DECREF(unfilteredCRLs); PKIX_DECREF(lcs); PKIX_RETURN(CERTSTORE); }
/* * FUNCTION: pkix_pl_LdapCertStore_MakeNameAVAList * DESCRIPTION: * * This function allocates space from the arena pointed to by "arena" to * construct a filter that will match components of the X500Name pointed to * by "name", and stores the resulting filter at "pFilter". * * "name" is checked for commonName and organizationName components (cn=, * and o=). The component strings are extracted using the family of * CERT_Get* functions, and each must be freed with PORT_Free. * * It is not clear which components should be in a request, so, for now, * we stop adding components after we have found one. * * PARAMETERS: * "arena" * The address of the PRArenaPool used in creating the filter. Must be * non-NULL. * "name" * The address of the X500Name whose components define the desired * matches. Must be non-NULL. * "pList" * The address at which the result is stored. * "plContext" * Platform-specific context pointer * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a CertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ static PKIX_Error * pkix_pl_LdapCertStore_MakeNameAVAList( PRArenaPool *arena, PKIX_PL_X500Name *subjectName, LDAPNameComponent ***pList, void *plContext) { LDAPNameComponent **setOfNameComponents; LDAPNameComponent *currentNameComponent = NULL; PKIX_UInt32 componentsPresent = 0; void *v = NULL; unsigned char *component = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_MakeNameAVAList"); PKIX_NULLCHECK_THREE(arena, subjectName, pList); /* Increase this if additional components may be extracted */ #define MAX_NUM_COMPONENTS 3 /* Space for (MAX_NUM_COMPONENTS + 1) pointers to LDAPNameComponents */ PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZAlloc, (arena, (MAX_NUM_COMPONENTS + 1)*sizeof(LDAPNameComponent *))); setOfNameComponents = (LDAPNameComponent **)v; /* Space for MAX_NUM_COMPONENTS LDAPNameComponents */ PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZNewArray, (arena, LDAPNameComponent, MAX_NUM_COMPONENTS)); currentNameComponent = (LDAPNameComponent *)v; /* Try for commonName */ PKIX_CHECK(pkix_pl_X500Name_GetCommonName (subjectName, &component, plContext), PKIX_X500NAMEGETCOMMONNAMEFAILED); if (component) { setOfNameComponents[componentsPresent] = currentNameComponent; currentNameComponent->attrType = (unsigned char *)"cn"; currentNameComponent->attrValue = component; componentsPresent++; currentNameComponent++; } /* * The LDAP specification says we can send multiple name components * in an "AND" filter, but the LDAP Servers don't seem to be able to * handle such requests. So we'll quit after the cn component. */ #if 0 /* Try for orgName */ PKIX_CHECK(pkix_pl_X500Name_GetOrgName (subjectName, &component, plContext), PKIX_X500NAMEGETORGNAMEFAILED); if (component) { setOfNameComponents[componentsPresent] = currentNameComponent; currentNameComponent->attrType = (unsigned char *)"o"; currentNameComponent->attrValue = component; componentsPresent++; currentNameComponent++; } /* Try for countryName */ PKIX_CHECK(pkix_pl_X500Name_GetCountryName (subjectName, &component, plContext), PKIX_X500NAMEGETCOUNTRYNAMEFAILED); if (component) { setOfNameComponents[componentsPresent] = currentNameComponent; currentNameComponent->attrType = (unsigned char *)"c"; currentNameComponent->attrValue = component; componentsPresent++; currentNameComponent++; } #endif setOfNameComponents[componentsPresent] = NULL; *pList = setOfNameComponents; cleanup: PKIX_RETURN(CERTSTORE); }
/* * FUNCTION: pkix_pl_OcspResponse_Create * DESCRIPTION: * * This function transmits the OcspRequest pointed to by "request" and obtains * an OcspResponse, which it stores at "pOcspResponse". If the HTTPClient * supports non-blocking I/O this function may store a non-NULL value at * "pNBIOContext" (the WOULDBLOCK condition). In that case the caller should * make a subsequent call with the same value in "pNBIOContext" and * "pOcspResponse" to resume the operation. Additional WOULDBLOCK returns may * occur; the caller should persist until a return occurs with NULL stored at * "pNBIOContext". * * If a SEC_HttpClientFcn "responder" is supplied, it is used as the client * to which the OCSP query is sent. If none is supplied, the default responder * is used. * * If an OcspResponse_VerifyCallback "verifyFcn" is supplied, it is used to * verify the Cert received from the responder as the signer. If none is * supplied, the default verification function is used. * * The contents of "request" are ignored on calls subsequent to a WOULDBLOCK * return, and the caller is permitted to supply NULL. * * PARAMETERS * "request" * Address of the OcspRequest for which a response is desired. * "responder" * Address, if non-NULL, of the SEC_HttpClientFcn to be sent the OCSP * query. * "verifyFcn" * Address, if non-NULL, of the OcspResponse_VerifyCallback function to be * used to verify the Cert of the OCSP responder. * "pNBIOContext" * Address at which platform-dependent information is stored for handling * of non-blocking I/O. Must be non-NULL. * "pOcspResponse" * The address where the created OcspResponse is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns an OcspResponse Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_OcspResponse_Create( PKIX_PL_OcspRequest *request, void *responder, PKIX_PL_OcspResponse_VerifyCallback verifyFcn, void **pNBIOContext, PKIX_PL_OcspResponse **pResponse, void *plContext) { void *nbioContext = NULL; PKIX_PL_OcspResponse *ocspResponse = NULL; const SEC_HttpClientFcn *httpClient = NULL; const SEC_HttpClientFcnV1 *hcv1 = NULL; SECStatus rv = SECFailure; char *location = NULL; char *hostname = NULL; char *path = NULL; PRUint16 port = 0; SEC_HTTP_SERVER_SESSION serverSession = NULL; SEC_HTTP_REQUEST_SESSION requestSession = NULL; SECItem *encodedRequest = NULL; PRUint16 responseCode = 0; char *responseData = NULL; PRUint32 responseDataLen = 0; PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Create"); PKIX_NULLCHECK_TWO(pNBIOContext, pResponse); nbioContext = *pNBIOContext; *pNBIOContext = NULL; if (nbioContext != NULL) { ocspResponse = *pResponse; PKIX_NULLCHECK_ONE(ocspResponse); httpClient = ocspResponse->httpClient; serverSession = ocspResponse->serverSession; requestSession = ocspResponse->requestSession; PKIX_NULLCHECK_THREE(httpClient, serverSession, requestSession); } else { PKIX_NULLCHECK_ONE(request); PKIX_CHECK(pkix_pl_OcspRequest_GetEncoded (request, &encodedRequest, plContext), PKIX_OCSPREQUESTGETENCODEDFAILED); /* prepare initial message to HTTPClient */ /* Is there a default responder and is it enabled? */ if (!responder) { PKIX_PL_NSSCALLRV (OCSPRESPONSE, responder, (void *)SEC_GetRegisteredHttpClient, ()); } httpClient = (const SEC_HttpClientFcn *)responder; if (httpClient && (httpClient->version == 1)) { hcv1 = &(httpClient->fcnTable.ftable1); PKIX_CHECK(pkix_pl_OcspRequest_GetLocation (request, &location, plContext), PKIX_OCSPREQUESTGETLOCATIONFAILED); /* parse location -> hostname, port, path */ PKIX_PL_NSSCALLRV(OCSPRESPONSE, rv, CERT_ParseURL, (location, &hostname, &port, &path)); if ((hostname == NULL) || (path == NULL)) { PKIX_ERROR(PKIX_URLPARSINGFAILED); } PKIX_PL_NSSCALLRV (OCSPRESPONSE, rv, hcv1->createSessionFcn, (hostname, port, &serverSession)); if (rv != SECSuccess) { PKIX_ERROR(PKIX_OCSPSERVERERROR); } PKIX_PL_NSSCALLRV (OCSPRESPONSE, rv, hcv1->createFcn, (serverSession, "http", path, "POST", PR_TicksPerSecond() * 60, &requestSession)); if (rv != SECSuccess) { PKIX_ERROR(PKIX_OCSPSERVERERROR); } PKIX_PL_NSSCALLRV (OCSPRESPONSE, rv, hcv1->setPostDataFcn, (requestSession, (char *)encodedRequest->data, encodedRequest->len, "application/ocsp-request")); if (rv != SECSuccess) { PKIX_ERROR(PKIX_OCSPSERVERERROR); } /* create a PKIX_PL_OcspResponse object */ PKIX_CHECK(PKIX_PL_Object_Alloc (PKIX_OCSPRESPONSE_TYPE, sizeof (PKIX_PL_OcspResponse), (PKIX_PL_Object **)&ocspResponse, plContext), PKIX_COULDNOTCREATEOBJECT); PKIX_INCREF(request); ocspResponse->request = request; ocspResponse->httpClient = httpClient; ocspResponse->serverSession = serverSession; ocspResponse->requestSession = requestSession; ocspResponse->verifyFcn = verifyFcn; ocspResponse->handle = CERT_GetDefaultCertDB(); ocspResponse->encodedResponse = NULL; ocspResponse->arena = NULL; ocspResponse->producedAt = 0; ocspResponse->producedAtDate = NULL; ocspResponse->pkixSignerCert = NULL; ocspResponse->nssOCSPResponse = NULL; ocspResponse->signerCert = NULL; } }
/* * FUNCTION: pkix_pl_HttpCertStore_CreateWithAsciiName * DESCRIPTION: * * This function uses the HttpClient pointed to by "client" and the string * (hostname:portnum/path, with portnum optional) pointed to by "locationAscii" * to create an HttpCertStore connected to the desired location, storing the * created CertStore at "pCertStore". * * PARAMETERS: * "client" * The address of the HttpClient. Must be non-NULL. * "locationAscii" * The address of the character string indicating the hostname, port, and * path to be queried for Certs or Crls. Must be non-NULL. * "pCertStore" * The address in which the object is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a HttpCertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_HttpCertStore_CreateWithAsciiName( PKIX_PL_HttpClient *client, char *locationAscii, PKIX_CertStore **pCertStore, void *plContext) { const SEC_HttpClientFcn *clientFcn = NULL; const SEC_HttpClientFcnV1 *hcv1 = NULL; PKIX_PL_HttpCertStoreContext *httpCertStore = NULL; PKIX_CertStore *certStore = NULL; char *hostname = NULL; char *path = NULL; PRUint16 port = 0; SECStatus rv = SECFailure; PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_CreateWithAsciiName"); PKIX_NULLCHECK_TWO(locationAscii, pCertStore); if (client == NULL) { clientFcn = SEC_GetRegisteredHttpClient(); if (clientFcn == NULL) { PKIX_ERROR(PKIX_NOREGISTEREDHTTPCLIENT); } } else { clientFcn = (const SEC_HttpClientFcn *)client; } /* create a PKIX_PL_HttpCertStore object */ PKIX_CHECK(PKIX_PL_Object_Alloc (PKIX_HTTPCERTSTORECONTEXT_TYPE, sizeof (PKIX_PL_HttpCertStoreContext), (PKIX_PL_Object **)&httpCertStore, plContext), PKIX_COULDNOTCREATEOBJECT); /* Initialize fields */ httpCertStore->client = clientFcn; /* not a PKIX object! */ /* parse location -> hostname, port, path */ PKIX_PL_NSSCALLRV(CERTSTORE, rv, CERT_ParseURL, (locationAscii, &hostname, &port, &path)); if ((hostname == NULL) || (path == NULL)) { PKIX_ERROR(PKIX_URLPARSINGFAILED); } httpCertStore->path = path; if (clientFcn->version == 1) { hcv1 = &(clientFcn->fcnTable.ftable1); PKIX_PL_NSSCALLRV (HTTPCERTSTORECONTEXT, rv, hcv1->createSessionFcn, (hostname, port, &(httpCertStore->serverSession))); if (rv != SECSuccess) { PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED); } } else { PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); } httpCertStore->requestSession = NULL; PKIX_CHECK(PKIX_CertStore_Create (pkix_pl_HttpCertStore_GetCert, pkix_pl_HttpCertStore_GetCRL, pkix_pl_HttpCertStore_GetCertContinue, pkix_pl_HttpCertStore_GetCRLContinue, NULL, /* don't support trust */ (PKIX_PL_Object *)httpCertStore, PKIX_TRUE, /* cache flag */ PKIX_FALSE, /* not local */ &certStore, plContext), PKIX_CERTSTORECREATEFAILED); *pCertStore = certStore; cleanup: if (PKIX_ERROR_RECEIVED) { PKIX_DECREF(httpCertStore); } PKIX_RETURN(CERTSTORE); }
/* * FUNCTION: pkix_pl_HttpCertStore_GetCRLContinue * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h) */ PKIX_Error * pkix_pl_HttpCertStore_GetCRLContinue( PKIX_CertStore *store, PKIX_CRLSelector *selector, void **pNBIOContext, PKIX_List **pCrlList, 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 *crlList = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCRLContinue"); PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCrlList); nbioContext = *pNBIOContext; *pNBIOContext = NULL; PKIX_CHECK(PKIX_CertStore_GetCertStoreContext (store, (PKIX_PL_Object **)&context, plContext), PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED); if (context->client->version == 1) { hcv1 = &(context->client->fcnTable.ftable1); PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession (context, plContext), PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED); PKIX_PL_NSSCALLRV (HTTPCERTSTORECONTEXT, 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; } } else { PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); } PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse (responseCode, responseContentType, responseData, responseDataLen, &crlList, plContext), PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED); *pCrlList = crlList; cleanup: PKIX_RETURN(CERTSTORE); }
/* * FUNCTION: pkix_pl_HttpCertStore_ProcessCrlResponse * DESCRIPTION: * * This function verifies that the response code pointed to by "responseCode" * and the content type pointed to by "responseContentType" are as expected, * and then decodes the data pointed to by "responseData", of length * "responseDataLen", into a List of Crls, possibly empty, which is returned * at "pCrlList". * * PARAMETERS: * "responseCode" * The value of the HTTP response code. * "responseContentType" * The address of the Content-type string. Must be non-NULL. * "responseData" * The address of the message data. Must be non-NULL. * "responseDataLen" * The length of the message data. * "pCrlList" * The address of the List that is created. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a HttpCertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_HttpCertStore_ProcessCrlResponse( PRUint16 responseCode, const char *responseContentType, const char *responseData, PRUint32 responseDataLen, PKIX_List **pCrlList, void *plContext) { PRArenaPool *arena = NULL; SECItem *encodedResponse = NULL; PRInt16 compareVal = 0; PKIX_List *crls = NULL; PKIX_ENTER (HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStore_ProcessCrlResponse"); PKIX_NULLCHECK_ONE(pCrlList); if (responseCode != 200) { PKIX_ERROR(PKIX_BADHTTPRESPONSE); } /* check that response type is application/pkix-crl */ if (responseContentType == NULL) { PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE); } PKIX_PL_NSSCALLRV (HTTPCERTSTORECONTEXT, compareVal, PORT_Strcasecmp, (responseContentType, "application/pkix-crl")); if (compareVal != 0) { PKIX_ERROR(PKIX_CONTENTTYPENOTPKIXCRL); } /* Make a SECItem of the response data */ PKIX_PL_NSSCALLRV(HTTPCERTSTORECONTEXT, arena, PORT_NewArena, (DER_DEFAULT_CHUNKSIZE)); if (arena == NULL) { PKIX_ERROR(PKIX_OUTOFMEMORY); } if (responseData == NULL) { PKIX_ERROR(PKIX_NORESPONSEDATAINHTTPRESPONSE); } PKIX_PL_NSSCALLRV (HTTPCERTSTORECONTEXT, encodedResponse, SECITEM_AllocItem, (arena, NULL, responseDataLen)); if (encodedResponse == NULL) { PKIX_ERROR(PKIX_OUTOFMEMORY); } PKIX_PL_NSSCALL(HTTPCERTSTORECONTEXT, PORT_Memcpy, (encodedResponse->data, responseData, responseDataLen)); PKIX_CHECK(PKIX_List_Create(&crls, plContext), PKIX_LISTCREATEFAILED); PKIX_CHECK(pkix_pl_CRL_CreateToList (encodedResponse, crls, plContext), PKIX_CRLCREATETOLISTFAILED); *pCrlList = crls; cleanup: if (PKIX_ERROR_RECEIVED) { PKIX_DECREF(crls); } if (arena != NULL) { PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena, (arena, PR_FALSE)); } PKIX_RETURN(HTTPCERTSTORECONTEXT); }