Index: mozilla/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c |
=================================================================== |
--- mozilla/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c (revision 191424) |
+++ mozilla/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c (working copy) |
@@ -1,1147 +0,0 @@ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
-/* |
- * pkix_pl_httpcertstore.c |
- * |
- * HTTPCertStore Function Definitions |
- * |
- */ |
- |
-/* We can't decode the length of a message without at least this many bytes */ |
- |
-#include "pkix_pl_httpcertstore.h" |
-extern PKIX_PL_HashTable *httpSocketCache; |
-SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate) |
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) |
-SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate) |
-SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate) |
- |
-SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate) |
-SEC_ASN1_CHOOSER_DECLARE(SECOID_AlgorithmIDTemplate) |
-/* SEC_ASN1_CHOOSER_DECLARE(SEC_SetOfAnyTemplate) |
-SEC_ASN1_CHOOSER_DECLARE(CERT_SetOfSignedCrlTemplate) |
- |
-const SEC_ASN1Template CERT_IssuerAndSNTemplate[] = { |
- { SEC_ASN1_SEQUENCE, |
- 0, NULL, sizeof(CERTIssuerAndSN) }, |
- { SEC_ASN1_SAVE, |
- offsetof(CERTIssuerAndSN,derIssuer) }, |
- { SEC_ASN1_INLINE, |
- offsetof(CERTIssuerAndSN,issuer), |
- CERT_NameTemplate }, |
- { SEC_ASN1_INTEGER, |
- offsetof(CERTIssuerAndSN,serialNumber) }, |
- { 0 } |
-}; |
- |
-const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = { |
- { SEC_ASN1_SEQUENCE, |
- 0, NULL, sizeof(SECAlgorithmID) }, |
- { SEC_ASN1_OBJECT_ID, |
- offsetof(SECAlgorithmID,algorithm), }, |
- { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, |
- offsetof(SECAlgorithmID,parameters), }, |
- { 0, } |
-}; */ |
- |
-/* --Private-HttpCertStoreContext-Object Functions----------------------- */ |
- |
-/* |
- * FUNCTION: pkix_pl_HttpCertStoreContext_Destroy |
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_HttpCertStoreContext_Destroy( |
- PKIX_PL_Object *object, |
- void *plContext) |
-{ |
- const SEC_HttpClientFcnV1 *hcv1 = NULL; |
- PKIX_PL_HttpCertStoreContext *context = NULL; |
- |
- PKIX_ENTER |
- (HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStoreContext_Destroy"); |
- PKIX_NULLCHECK_ONE(object); |
- |
- PKIX_CHECK(pkix_CheckType |
- (object, PKIX_HTTPCERTSTORECONTEXT_TYPE, plContext), |
- PKIX_OBJECTNOTANHTTPCERTSTORECONTEXT); |
- |
- context = (PKIX_PL_HttpCertStoreContext *)object; |
- hcv1 = (const SEC_HttpClientFcnV1 *)(context->client); |
- if (context->requestSession != NULL) { |
- (*hcv1->freeFcn)(context->requestSession); |
- context->requestSession = NULL; |
- } |
- if (context->serverSession != NULL) { |
- (*hcv1->freeSessionFcn)(context->serverSession); |
- context->serverSession = NULL; |
- } |
- if (context->path != NULL) { |
- PORT_Free(context->path); |
- context->path = NULL; |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(HTTPCERTSTORECONTEXT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_HttpCertStoreContext_RegisterSelf |
- * |
- * DESCRIPTION: |
- * Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related |
- * functions with systemClasses[] |
- * |
- * THREAD SAFETY: |
- * Not Thread Safe - for performance and complexity reasons |
- * |
- * Since this function is only called by PKIX_PL_Initialize, which should |
- * only be called once, it is acceptable that this function is not |
- * thread-safe. |
- */ |
-PKIX_Error * |
-pkix_pl_HttpCertStoreContext_RegisterSelf(void *plContext) |
-{ |
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; |
- pkix_ClassTable_Entry *entry = &systemClasses[PKIX_HTTPCERTSTORECONTEXT_TYPE]; |
- |
- PKIX_ENTER(HTTPCERTSTORECONTEXT, |
- "pkix_pl_HttpCertStoreContext_RegisterSelf"); |
- |
- entry->description = "HttpCertStoreContext"; |
- entry->typeObjectSize = sizeof(PKIX_PL_HttpCertStoreContext); |
- entry->destructor = pkix_pl_HttpCertStoreContext_Destroy; |
- |
- PKIX_RETURN(HTTPCERTSTORECONTEXT); |
-} |
- |
- |
-/* --Private-Http-CertStore-Database-Functions----------------------- */ |
- |
-typedef struct callbackContextStruct { |
- PKIX_List *pkixCertList; |
- PKIX_Error *error; |
- void *plContext; |
-} callbackContext; |
- |
- |
-/* |
- * FUNCTION: certCallback |
- * DESCRIPTION: |
- * |
- * This function processes the null-terminated array of SECItems produced by |
- * extracting the contents of a signedData message received in response to an |
- * HTTP cert query. Its address is supplied as a callback function to |
- * CERT_DecodeCertPackage; it is not expected to be called directly. |
- * |
- * Note that it does not conform to the libpkix API standard of returning |
- * a PKIX_Error*. It returns a SECStatus. |
- * |
- * PARAMETERS: |
- * "arg" |
- * The address of the callbackContext provided as a void* argument to |
- * CERT_DecodeCertPackage. Must be non-NULL. |
- * "secitemCerts" |
- * The address of the null-terminated array of SECItems. Must be non-NULL. |
- * "numcerts" |
- * The number of SECItems found in the signedData. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns SECSuccess if the function succeeds. |
- * Returns SECFailure if the function fails. |
- */ |
-static SECStatus |
-certCallback(void *arg, SECItem **secitemCerts, int numcerts) |
-{ |
- callbackContext *cbContext; |
- PKIX_List *pkixCertList = NULL; |
- PKIX_Error *error = NULL; |
- void *plContext = NULL; |
- int itemNum = 0; |
- |
- if ((arg == NULL) || (secitemCerts == NULL)) { |
- return (SECFailure); |
- } |
- |
- cbContext = (callbackContext *)arg; |
- plContext = cbContext->plContext; |
- pkixCertList = cbContext->pkixCertList; |
- |
- for (; itemNum < numcerts; itemNum++ ) { |
- error = pkix_pl_Cert_CreateToList(secitemCerts[itemNum], |
- pkixCertList, plContext); |
- if (error != NULL) { |
- if (error->errClass == PKIX_FATAL_ERROR) { |
- cbContext->error = error; |
- return SECFailure; |
- } |
- /* reuse "error" since we could not destruct the old * |
- * value */ |
- error = PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, |
- plContext); |
- if (error) { |
- /* Treat decref failure as a fatal error. |
- * In this case will leak error, but can not do |
- * anything about it. */ |
- error->errClass = PKIX_FATAL_ERROR; |
- cbContext->error = error; |
- return SECFailure; |
- } |
- } |
- } |
- |
- return SECSuccess; |
-} |
- |
- |
-typedef SECStatus (*pkix_DecodeCertsFunc)(char *certbuf, int certlen, |
- CERTImportCertificateFunc f, void *arg); |
- |
- |
-struct pkix_DecodeFuncStr { |
- pkix_DecodeCertsFunc func; /* function pointer to the |
- * CERT_DecodeCertPackage function */ |
- PRLibrary *smimeLib; /* Pointer to the smime shared lib*/ |
- PRCallOnceType once; |
-}; |
- |
-static struct pkix_DecodeFuncStr pkix_decodeFunc; |
-static const PRCallOnceType pkix_pristine; |
- |
-#define SMIME_LIB_NAME SHLIB_PREFIX"smime3."SHLIB_SUFFIX |
- |
-/* |
- * load the smime library and look up the SEC_ReadPKCS7Certs function. |
- * we do this so we don't have a circular depenency on the smime library, |
- * and also so we don't have to load the smime library in applications that |
- * don't use it. |
- */ |
-static PRStatus PR_CALLBACK pkix_getDecodeFunction(void) |
-{ |
- pkix_decodeFunc.smimeLib = |
- PR_LoadLibrary(SHLIB_PREFIX"smime3."SHLIB_SUFFIX); |
- if (pkix_decodeFunc.smimeLib == NULL) { |
- return PR_FAILURE; |
- } |
- |
- pkix_decodeFunc.func = (pkix_DecodeCertsFunc) PR_FindFunctionSymbol( |
- pkix_decodeFunc.smimeLib, "CERT_DecodeCertPackage"); |
- if (!pkix_decodeFunc.func) { |
- return PR_FAILURE; |
- } |
- return PR_SUCCESS; |
- |
-} |
- |
-/* |
- * clears our global state on shutdown. |
- */ |
-void |
-pkix_pl_HttpCertStore_Shutdown(void *plContext) |
-{ |
- if (pkix_decodeFunc.smimeLib) { |
- PR_UnloadLibrary(pkix_decodeFunc.smimeLib); |
- pkix_decodeFunc.smimeLib = NULL; |
- } |
- /* the function pointer just need to be cleared, not freed */ |
- pkix_decodeFunc.func = NULL; |
- pkix_decodeFunc.once = pkix_pristine; |
-} |
- |
-/* |
- * This function is based on CERT_DecodeCertPackage from lib/pkcs7/certread.c |
- * read an old style ascii or binary certificate chain |
- */ |
-PKIX_Error * |
-pkix_pl_HttpCertStore_DecodeCertPackage |
- (const char *certbuf, |
- int certlen, |
- CERTImportCertificateFunc f, |
- void *arg, |
- void *plContext) |
-{ |
- |
- PRStatus status; |
- SECStatus rv; |
- |
- PKIX_ENTER |
- (HTTPCERTSTORECONTEXT, |
- "pkix_pl_HttpCertStore_DecodeCertPackage"); |
- PKIX_NULLCHECK_TWO(certbuf, f); |
- |
- status = PR_CallOnce(&pkix_decodeFunc.once, pkix_getDecodeFunction); |
- |
- if (status != PR_SUCCESS) { |
- PKIX_ERROR(PKIX_CANTLOADLIBSMIME); |
- } |
- |
- /* paranoia, shouldn't happen if status == PR_SUCCESS); */ |
- if (!pkix_decodeFunc.func) { |
- PKIX_ERROR(PKIX_CANTLOADLIBSMIME); |
- } |
- |
- rv = (*pkix_decodeFunc.func)((char*)certbuf, certlen, f, arg); |
- |
- if (rv != SECSuccess) { |
- PKIX_ERROR (PKIX_SECREADPKCS7CERTSFAILED); |
- } |
- |
- |
-cleanup: |
- |
- PKIX_RETURN(HTTPCERTSTORECONTEXT); |
-} |
- |
- |
-/* |
- * FUNCTION: pkix_pl_HttpCertStore_ProcessCertResponse |
- * 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 Certs, possibly empty, which is returned |
- * at "pCertList". |
- * |
- * 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. |
- * "pCertList" |
- * 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_ProcessCertResponse( |
- PRUint16 responseCode, |
- const char *responseContentType, |
- const char *responseData, |
- PRUint32 responseDataLen, |
- PKIX_List **pCertList, |
- void *plContext) |
-{ |
- callbackContext cbContext; |
- |
- PKIX_ENTER(HTTPCERTSTORECONTEXT, |
- "pkix_pl_HttpCertStore_ProcessCertResponse"); |
- |
- cbContext.error = NULL; |
- cbContext.plContext = plContext; |
- cbContext.pkixCertList = NULL; |
- |
- PKIX_NULLCHECK_ONE(pCertList); |
- |
- if (responseCode != 200) { |
- PKIX_ERROR(PKIX_BADHTTPRESPONSE); |
- } |
- |
- /* check that response type is application/pkcs7-mime */ |
- if (responseContentType == NULL) { |
- PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE); |
- } |
- |
- if (responseData == NULL) { |
- PKIX_ERROR(PKIX_NORESPONSEDATAINHTTPRESPONSE); |
- } |
- |
- PKIX_CHECK( |
- PKIX_List_Create(&cbContext.pkixCertList, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- PKIX_CHECK_ONLY_FATAL( |
- pkix_pl_HttpCertStore_DecodeCertPackage(responseData, |
- responseDataLen, |
- certCallback, |
- &cbContext, |
- plContext), |
- PKIX_HTTPCERTSTOREDECODECERTPACKAGEFAILED); |
- if (cbContext.error) { |
- /* Aborting on a fatal error(See certCallback fn) */ |
- pkixErrorResult = cbContext.error; |
- goto cleanup; |
- } |
- |
- *pCertList = cbContext.pkixCertList; |
- cbContext.pkixCertList = NULL; |
- |
-cleanup: |
- |
- PKIX_DECREF(cbContext.pkixCertList); |
- |
- PKIX_RETURN(HTTPCERTSTORECONTEXT); |
-} |
- |
-/* |
- * 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) |
-{ |
- SECItem encodedResponse; |
- PRInt16 compareVal = 0; |
- PKIX_List *crls = NULL; |
- SECItem *derCrlCopy = NULL; |
- CERTSignedCrl *nssCrl = NULL; |
- PKIX_PL_CRL *crl = 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); |
- } |
- |
- compareVal = PORT_Strcasecmp(responseContentType, |
- "application/pkix-crl"); |
- if (compareVal != 0) { |
- PKIX_ERROR(PKIX_CONTENTTYPENOTPKIXCRL); |
- } |
- encodedResponse.type = siBuffer; |
- encodedResponse.data = (void*)responseData; |
- encodedResponse.len = responseDataLen; |
- |
- derCrlCopy = SECITEM_DupItem(&encodedResponse); |
- if (!derCrlCopy) { |
- PKIX_ERROR(PKIX_ALLOCERROR); |
- } |
- /* crl will be based on derCrlCopy, but will not own the der. */ |
- nssCrl = |
- CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy, SEC_CRL_TYPE, |
- CRL_DECODE_DONT_COPY_DER | |
- CRL_DECODE_SKIP_ENTRIES); |
- if (!nssCrl) { |
- PKIX_ERROR(PKIX_FAILEDTODECODECRL); |
- } |
- /* pkix crls own the der. */ |
- PKIX_CHECK( |
- pkix_pl_CRL_CreateWithSignedCRL(nssCrl, derCrlCopy, NULL, |
- &crl, plContext), |
- PKIX_CRLCREATEWITHSIGNEDCRLFAILED); |
- /* Left control over memory pointed by derCrlCopy and |
- * nssCrl to pkix crl. */ |
- derCrlCopy = NULL; |
- nssCrl = NULL; |
- PKIX_CHECK(PKIX_List_Create(&crls, plContext), |
- PKIX_LISTCREATEFAILED); |
- PKIX_CHECK(PKIX_List_AppendItem |
- (crls, (PKIX_PL_Object *) crl, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- *pCrlList = crls; |
- crls = NULL; |
-cleanup: |
- if (derCrlCopy) { |
- SECITEM_FreeItem(derCrlCopy, PR_TRUE); |
- } |
- if (nssCrl) { |
- SEC_DestroyCrl(nssCrl); |
- } |
- PKIX_DECREF(crl); |
- PKIX_DECREF(crls); |
- |
- PKIX_RETURN(HTTPCERTSTORECONTEXT); |
-} |
- |
-/* |
- * 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; |
- |
- PKIX_ENTER |
- (HTTPCERTSTORECONTEXT, |
- "pkix_pl_HttpCertStore_CreateRequestSession"); |
- PKIX_NULLCHECK_TWO(context, context->serverSession); |
- |
- if (context->client->version != 1) { |
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); |
- } |
- |
- hcv1 = &(context->client->fcnTable.ftable1); |
- if (context->requestSession != NULL) { |
- (*hcv1->freeFcn)(context->requestSession); |
- context->requestSession = 0; |
- } |
- |
- rv = (*hcv1->createFcn)(context->serverSession, "http", |
- context->path, "GET", |
- PR_SecondsToInterval( |
- ((PKIX_PL_NssContext*)plContext)->timeoutSeconds), |
- &(context->requestSession)); |
- |
- if (rv != SECSuccess) { |
- PKIX_ERROR(PKIX_HTTPSERVERERROR); |
- } |
-cleanup: |
- |
- PKIX_RETURN(HTTPCERTSTORECONTEXT); |
- |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_HttpCertStore_GetCert |
- * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h) |
- */ |
-PKIX_Error * |
-pkix_pl_HttpCertStore_GetCert( |
- PKIX_CertStore *store, |
- PKIX_CertSelector *selector, |
- PKIX_VerifyNode *verifyNode, |
- 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(HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStore_GetCert"); |
- 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_CHECK(pkix_pl_HttpCertStore_CreateRequestSession |
- (context, plContext), |
- PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED); |
- |
- 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); |
-} |
- |
-/* |
- * 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, |
- PKIX_VerifyNode *verifyNode, |
- 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); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_HttpCertStore_GetCRL |
- * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h) |
- */ |
-PKIX_Error * |
-pkix_pl_HttpCertStore_GetCRL( |
- 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_GetCRL"); |
- PKIX_NULLCHECK_THREE(store, selector, pCrlList); |
- |
- 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_CHECK(pkix_pl_HttpCertStore_CreateRequestSession |
- (context, plContext), |
- PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED); |
- |
- 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_ProcessCrlResponse |
- (responseCode, |
- responseContentType, |
- responseData, |
- responseDataLen, |
- &crlList, |
- plContext), |
- PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED); |
- |
- *pCrlList = crlList; |
- |
-cleanup: |
- PKIX_DECREF(context); |
- |
- 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) { |
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); |
- } |
- hcv1 = &(context->client->fcnTable.ftable1); |
- |
- PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession |
- (context, plContext), |
- PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED); |
- |
- 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_ProcessCrlResponse |
- (responseCode, |
- responseContentType, |
- responseData, |
- responseDataLen, |
- &crlList, |
- plContext), |
- PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED); |
- |
- *pCrlList = crlList; |
- |
-cleanup: |
- PKIX_DECREF(context); |
- |
- PKIX_RETURN(CERTSTORE); |
-} |
- |
-/* --Public-HttpCertStore-Functions----------------------------------- */ |
- |
-/* |
- * 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; |
- } |
- |
- if (clientFcn->version != 1) { |
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); |
- } |
- |
- /* 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 */ |
- rv = CERT_ParseURL(locationAscii, &hostname, &port, &path); |
- if (rv == SECFailure || hostname == NULL || path == NULL) { |
- PKIX_ERROR(PKIX_URLPARSINGFAILED); |
- } |
- |
- httpCertStore->path = path; |
- path = NULL; |
- |
- hcv1 = &(clientFcn->fcnTable.ftable1); |
- rv = (*hcv1->createSessionFcn)(hostname, port, |
- &(httpCertStore->serverSession)); |
- if (rv != SECSuccess) { |
- PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED); |
- } |
- |
- 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 */ |
- NULL, /* can not store crls */ |
- NULL, /* can not do revocation check */ |
- (PKIX_PL_Object *)httpCertStore, |
- PKIX_TRUE, /* cache flag */ |
- PKIX_FALSE, /* not local */ |
- &certStore, |
- plContext), |
- PKIX_CERTSTORECREATEFAILED); |
- |
- *pCertStore = certStore; |
- certStore = NULL; |
- |
-cleanup: |
- PKIX_DECREF(httpCertStore); |
- if (hostname) { |
- PORT_Free(hostname); |
- } |
- if (path) { |
- PORT_Free(path); |
- } |
- |
- PKIX_RETURN(CERTSTORE); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_HttpCertStore_Create |
- * (see comments in pkix_samples_modules.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_HttpCertStore_Create( |
- PKIX_PL_HttpClient *client, |
- PKIX_PL_GeneralName *location, |
- PKIX_CertStore **pCertStore, |
- void *plContext) |
-{ |
- PKIX_PL_String *locationString = NULL; |
- char *locationAscii = NULL; |
- PKIX_UInt32 len = 0; |
- |
- PKIX_ENTER(CERTSTORE, "PKIX_PL_HttpCertStore_Create"); |
- PKIX_NULLCHECK_TWO(location, pCertStore); |
- |
- PKIX_TOSTRING(location, &locationString, plContext, |
- PKIX_GENERALNAMETOSTRINGFAILED); |
- |
- PKIX_CHECK(PKIX_PL_String_GetEncoded |
- (locationString, |
- PKIX_ESCASCII, |
- (void **)&locationAscii, |
- &len, |
- plContext), |
- PKIX_STRINGGETENCODEDFAILED); |
- |
- PKIX_CHECK(pkix_pl_HttpCertStore_CreateWithAsciiName |
- (client, locationAscii, pCertStore, plContext), |
- PKIX_HTTPCERTSTORECREATEWITHASCIINAMEFAILED); |
- |
-cleanup: |
- |
- PKIX_DECREF(locationString); |
- |
- PKIX_RETURN(CERTSTORE); |
-} |
- |
-/* |
- * FUNCTION: pkix_HttpCertStore_FindSocketConnection |
- * DESCRIPTION: |
- * |
- PRIntervalTime timeout, |
- char *hostname, |
- PRUint16 portnum, |
- PRErrorCode *pStatus, |
- PKIX_PL_Socket **pSocket, |
- |
- * This function checks for an existing socket, creating a new one if unable |
- * to find an existing one, for the host pointed to by "hostname" and the port |
- * pointed to by "portnum". If a new socket is created the PRIntervalTime in |
- * "timeout" will be used for the timeout value and a creation status is |
- * returned at "pStatus". The address of the socket is stored at "pSocket". |
- * |
- * PARAMETERS: |
- * "timeout" |
- * The PRIntervalTime of the timeout value. |
- * "hostname" |
- * The address of the string containing the hostname. Must be non-NULL. |
- * "portnum" |
- * The port number for the desired socket. |
- * "pStatus" |
- * The address at which the status is stored. Must be non-NULL. |
- * "pSocket" |
- * The address at which the socket 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_HttpCertStore_FindSocketConnection( |
- PRIntervalTime timeout, |
- char *hostname, |
- PRUint16 portnum, |
- PRErrorCode *pStatus, |
- PKIX_PL_Socket **pSocket, |
- void *plContext) |
-{ |
- PKIX_PL_String *formatString = NULL; |
- PKIX_PL_String *hostString = NULL; |
- PKIX_PL_String *domainString = NULL; |
- PKIX_PL_Socket *socket = NULL; |
- |
- PKIX_ENTER(CERTSTORE, "pkix_HttpCertStore_FindSocketConnection"); |
- PKIX_NULLCHECK_THREE(hostname, pStatus, pSocket); |
- |
- *pStatus = 0; |
- |
- /* create PKIX_PL_String from hostname and port */ |
- PKIX_CHECK(PKIX_PL_String_Create |
- (PKIX_ESCASCII, "%s:%d", 0, &formatString, plContext), |
- PKIX_STRINGCREATEFAILED); |
- |
-#if 0 |
-hostname = "variation.red.iplanet.com"; |
-portnum = 2001; |
-#endif |
- |
- PKIX_CHECK(PKIX_PL_String_Create |
- (PKIX_ESCASCII, hostname, 0, &hostString, plContext), |
- PKIX_STRINGCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Sprintf |
- (&domainString, plContext, formatString, hostString, portnum), |
- PKIX_STRINGCREATEFAILED); |
- |
-#ifdef PKIX_SOCKETCACHE |
- /* Is this domainName already in cache? */ |
- PKIX_CHECK(PKIX_PL_HashTable_Lookup |
- (httpSocketCache, |
- (PKIX_PL_Object *)domainString, |
- (PKIX_PL_Object **)&socket, |
- plContext), |
- PKIX_HASHTABLELOOKUPFAILED); |
-#endif |
- if (socket == NULL) { |
- |
- /* No, create a connection (and cache it) */ |
- PKIX_CHECK(pkix_pl_Socket_CreateByHostAndPort |
- (PKIX_FALSE, /* create a client, not a server */ |
- timeout, |
- hostname, |
- portnum, |
- pStatus, |
- &socket, |
- plContext), |
- PKIX_SOCKETCREATEBYHOSTANDPORTFAILED); |
- |
-#ifdef PKIX_SOCKETCACHE |
- PKIX_CHECK(PKIX_PL_HashTable_Add |
- (httpSocketCache, |
- (PKIX_PL_Object *)domainString, |
- (PKIX_PL_Object *)socket, |
- plContext), |
- PKIX_HASHTABLEADDFAILED); |
-#endif |
- } |
- |
- *pSocket = socket; |
- socket = NULL; |
- |
-cleanup: |
- |
- PKIX_DECREF(formatString); |
- PKIX_DECREF(hostString); |
- PKIX_DECREF(domainString); |
- PKIX_DECREF(socket); |
- |
- PKIX_RETURN(CERTSTORE); |
-} |
- |