Addition of httpcertstore (and http retrieval of AIA information) NSS_LIBPKIX_BRANCH
authorrichard.freedman%sun.com
Fri, 05 May 2006 21:38:45 +0000
branchNSS_LIBPKIX_BRANCH
changeset 6982 a5721cb90238d115550478611c13dfdf7988ac18
parent 6981 515aeb105e593d3e70931fcb014adc419451e865
child 6990 8c28b667bf423a667c26e3746661a5fad90076ab
push idunknown
push userunknown
push dateunknown
Addition of httpcertstore (and http retrieval of AIA information)
security/nss/cmd/libpkix/pkix_pl/module/manifest.mn
security/nss/lib/libpkix/include/pkixt.h
security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c
security/nss/lib/libpkix/pkix/util/pkix_error.c
security/nss/lib/libpkix/pkix/util/pkix_logger.c
security/nss/lib/libpkix/pkix/util/pkix_tools.h
security/nss/lib/libpkix/pkix_pl_nss/module/manifest.mn
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h
security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h
security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
security/nss/lib/nss/nss.def
--- a/security/nss/cmd/libpkix/pkix_pl/module/manifest.mn
+++ b/security/nss/cmd/libpkix/pkix_pl/module/manifest.mn
@@ -34,10 +34,11 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 PKIX_DEPTH      = ../..
 
 #
 DIRS =  colcertstore  ekuchecker  pk11certstore socket ldapcertstore \
+	httpcertstore \
 	$(NULL)
 
--- a/security/nss/lib/libpkix/include/pkixt.h
+++ b/security/nss/lib/libpkix/include/pkixt.h
@@ -111,17 +111,18 @@ typedef struct PKIX_CertSelectorStruct P
 typedef struct PKIX_CRLSelectorStruct PKIX_CRLSelector;
 typedef struct PKIX_ComCertSelParamsStruct PKIX_ComCertSelParams;
 typedef struct PKIX_ComCRLSelParamsStruct PKIX_ComCRLSelParams;
 typedef struct PKIX_TrustAnchorStruct PKIX_TrustAnchor;
 typedef struct PKIX_PolicyNodeStruct PKIX_PolicyNode;
 typedef struct PKIX_LoggerStruct PKIX_Logger;
 typedef struct PKIX_ListStruct PKIX_List;
 typedef struct PKIX_ForwardBuilderStateStruct PKIX_ForwardBuilderState;
-typedef struct PKIX_DefaultRevocationCheckerStruct PKIX_DefaultRevocationChecker;
+typedef struct PKIX_DefaultRevocationCheckerStruct
+                        PKIX_DefaultRevocationChecker;
 typedef struct PKIX_OcspCheckerStruct PKIX_OcspChecker;
 
 /* Portability Layer (PL) data types
  *
  * These types are used are used as portable data types that are defined
  * consistently across platforms
  */
 
@@ -154,17 +155,19 @@ typedef struct PKIX_PL_LdapCertStoreCont
 typedef struct PKIX_PL_LdapRequestStruct PKIX_PL_LdapRequest;
 typedef struct PKIX_PL_LdapResponseStruct PKIX_PL_LdapResponse;
 typedef struct PKIX_PL_LdapDefaultClientStruct PKIX_PL_LdapDefaultClient;
 typedef struct PKIX_PL_SocketStruct PKIX_PL_Socket;
 typedef struct PKIX_PL_InfoAccessStruct PKIX_PL_InfoAccess;
 typedef struct PKIX_PL_AIAMgrStruct PKIX_PL_AIAMgr;
 typedef struct PKIX_PL_OcspRequestStruct PKIX_PL_OcspRequest;
 typedef struct PKIX_PL_OcspResponseStruct PKIX_PL_OcspResponse;
+typedef struct PKIX_PL_HttpClientStruct PKIX_PL_HttpClient;
 typedef struct PKIX_PL_HttpDefaultClientStruct PKIX_PL_HttpDefaultClient;
+typedef struct PKIX_PL_HttpCertStoreContextStruct PKIX_PL_HttpCertStoreContext;
 
 /* Primitive types
  *
  * In order to guarantee desired behavior as well as platform-independence, we
  * typedef these types depending on the platform. XXX This needs more work!
  */
 
 /* XXX Try compiling these files (and maybe the whole libpkix-nss) on Win32.
@@ -198,27 +201,27 @@ typedef int PKIX_Boolean;
 #define PKIX_LOGGER_TYPE                ((PKIX_UInt32) 6)
 #define PKIX_MUTEX_TYPE                 ((PKIX_UInt32) 7)
 #define PKIX_OID_TYPE                   ((PKIX_UInt32) 8)
 #define PKIX_RWLOCK_TYPE                ((PKIX_UInt32) 9)
 #define PKIX_STRING_TYPE                ((PKIX_UInt32) 10)
 
 #define PKIX_CERTBASICCONSTRAINTS_TYPE  ((PKIX_UInt32) 11)
 #define PKIX_CERT_TYPE                  ((PKIX_UInt32) 12)
-/* #define PKIX_NOLONGERUSED_TYPE          ((PKIX_UInt32) 13) */
+#define PKIX_HTTPCLIENT_TYPE            ((PKIX_UInt32) 13)
 #define PKIX_CRL_TYPE                   ((PKIX_UInt32) 14)
 #define PKIX_CRLENTRY_TYPE              ((PKIX_UInt32) 15)
 #define PKIX_DATE_TYPE                  ((PKIX_UInt32) 16)
 #define PKIX_GENERALNAME_TYPE           ((PKIX_UInt32) 17)
 #define PKIX_CERTNAMECONSTRAINTS_TYPE   ((PKIX_UInt32) 18)
 #define PKIX_PUBLICKEY_TYPE             ((PKIX_UInt32) 19)
 #define PKIX_TRUSTANCHOR_TYPE           ((PKIX_UInt32) 20)
 
 #define PKIX_X500NAME_TYPE              ((PKIX_UInt32) 21)
-/* #define PKIX_NOLONGERUSED_TYPE         ((PKIX_UInt32) 22) */
+#define PKIX_HTTPCERTSTORECONTEXT_TYPE  ((PKIX_UInt32) 22)
 #define PKIX_BUILDRESULT_TYPE           ((PKIX_UInt32) 23)
 #define PKIX_PROCESSINGPARAMS_TYPE      ((PKIX_UInt32) 24)
 #define PKIX_VALIDATEPARAMS_TYPE        ((PKIX_UInt32) 25)
 #define PKIX_VALIDATERESULT_TYPE        ((PKIX_UInt32) 26)
 #define PKIX_CERTSTORE_TYPE             ((PKIX_UInt32) 27)
 #define PKIX_CERTCHAINCHECKER_TYPE      ((PKIX_UInt32) 28)
 #define PKIX_REVOCATIONCHECKER_TYPE     ((PKIX_UInt32) 29)
 #define PKIX_CERTSELECTOR_TYPE          ((PKIX_UInt32) 30)
@@ -289,17 +292,17 @@ typedef int PKIX_Boolean;
 #define PKIX_HASHTABLE_ERROR            ((PKIX_UInt32) 11)
 #define PKIX_CERT_ERROR                 ((PKIX_UInt32) 12)
 #define PKIX_X500NAME_ERROR             ((PKIX_UInt32) 13)
 #define PKIX_GENERALNAME_ERROR          ((PKIX_UInt32) 14)
 #define PKIX_PUBLICKEY_ERROR            ((PKIX_UInt32) 15)
 #define PKIX_DATE_ERROR                 ((PKIX_UInt32) 16)
 #define PKIX_TRUSTANCHOR_ERROR          ((PKIX_UInt32) 17)
 #define PKIX_PROCESSINGPARAMS_ERROR     ((PKIX_UInt32) 18)
-/* #define PKIX_NOLONGERUSED_ERROR         ((PKIX_UInt32) 19) */
+#define PKIX_HTTPCLIENT_ERROR           ((PKIX_UInt32) 19)
 #define PKIX_VALIDATEPARAMS_ERROR       ((PKIX_UInt32) 20)
 #define PKIX_VALIDATE_ERROR             ((PKIX_UInt32) 21)
 #define PKIX_VALIDATERESULT_ERROR       ((PKIX_UInt32) 22)
 #define PKIX_CERTCHAINCHECKER_ERROR     ((PKIX_UInt32) 23)
 #define PKIX_CERTSELECTOR_ERROR         ((PKIX_UInt32) 24)
 #define PKIX_COMCERTSELPARAMS_ERROR     ((PKIX_UInt32) 25)
 #define PKIX_TARGETCERTCHECKERSTATE_ERROR ((PKIX_UInt32) 26)
 #define PKIX_CERTBASICCONSTRAINTS_ERROR ((PKIX_UInt32) 27)
@@ -314,17 +317,17 @@ typedef int PKIX_Boolean;
 #define PKIX_COLLECTIONCERTSTORECONTEXT_ERROR ((PKIX_UInt32) 36)
 #define PKIX_DEFAULTCRLCHECKERSTATE_ERROR ((PKIX_UInt32) 37)
 #define PKIX_CRL_ERROR                  ((PKIX_UInt32) 38)
 #define PKIX_CRLENTRY_ERROR             ((PKIX_UInt32) 39)
 #define PKIX_CRLSELECTOR_ERROR          ((PKIX_UInt32) 40)
 #define PKIX_CERTPOLICYMAP_ERROR        ((PKIX_UInt32) 41)
 #define PKIX_BUILD_ERROR                ((PKIX_UInt32) 42)
 #define PKIX_BUILDRESULT_ERROR          ((PKIX_UInt32) 43)
-/* #define PKIX_NOLONGERUSED_ERROR         ((PKIX_UInt32) 44) */
+#define PKIX_HTTPCERTSTORECONTEXT_ERROR ((PKIX_UInt32) 44)
 #define PKIX_FORWARDBUILDERSTATE_ERROR  ((PKIX_UInt32) 45)
 #define PKIX_SIGNATURECHECKERSTATE_ERROR ((PKIX_UInt32) 46)
 #define PKIX_CERTNAMECONSTRAINTS_ERROR ((PKIX_UInt32) 47)
 #define PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_ERROR ((PKIX_UInt32) 48)
 #define PKIX_REVOCATIONCHECKER_ERROR    ((PKIX_UInt32) 49)
 #define PKIX_USERDEFINEDMODULES_ERROR   ((PKIX_UInt32) 50)
 #define PKIX_CONTEXT_ERROR              ((PKIX_UInt32) 51)
 #define PKIX_DEFAULTREVOCATIONCHECKER_ERROR ((PKIX_UInt32) 52)
--- a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c
+++ b/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c
@@ -65,16 +65,17 @@ int pkix_ceAddCount = 0;
 int pkix_ceLookupCount = 0;
 
 PKIX_PL_HashTable *cachedCrlSigTable = NULL;
 PKIX_PL_HashTable *cachedCertSigTable = NULL;
 PKIX_PL_HashTable *cachedCertChainTable = NULL;
 PKIX_PL_HashTable *cachedCertTable = NULL;
 PKIX_PL_HashTable *cachedCrlEntryTable = NULL;
 PKIX_PL_HashTable *aiaConnectionCache = NULL;
+PKIX_PL_HashTable *httpSocketCache = NULL;
 
 extern PKIX_List *pkixLoggers;
 extern PKIX_List *pkixLoggersErrors;
 extern PKIX_List *pkixLoggersDebugTrace;
 
 /* --Public-Functions--------------------------------------------- */
 
 /*
@@ -164,16 +165,20 @@ PKIX_Initialize(
         PKIX_CHECK(PKIX_PL_HashTable_Create
                     (32, 10, &cachedCrlEntryTable, plContext),
                     "PKIX_PL_HashTable_Create failed");
 
         PKIX_CHECK(PKIX_PL_HashTable_Create
                     (5, 5, &aiaConnectionCache, plContext),
                     "PKIX_PL_HashTable_Create failed");
 
+        PKIX_CHECK(PKIX_PL_HashTable_Create
+                    (5, 5, &httpSocketCache, plContext),
+                    "PKIX_PL_HashTable_Create failed");
+
         if (pkixLoggerLock == NULL) {
                 PKIX_CHECK(PKIX_PL_MonitorLock_Create
                         (&pkixLoggerLock, plContext),
                         "PKIX_PL_MonitorLock_Create failed");
         }
 
 cleanup:
 
@@ -240,16 +245,17 @@ PKIX_Shutdown(void *plContext)
 
         /* Destroy Cache Tables */
         PKIX_DECREF(cachedCertSigTable);
         PKIX_DECREF(cachedCrlSigTable);
         PKIX_DECREF(cachedCertChainTable);
         PKIX_DECREF(cachedCertTable);
         PKIX_DECREF(cachedCrlEntryTable);
         PKIX_DECREF(aiaConnectionCache);
+        PKIX_DECREF(httpSocketCache);
 
         PKIX_CHECK(PKIX_PL_Shutdown(pkixPlatformInit, plContext),
                 "PKIX_PL_Shutdown failed");
 
         pkixIsInitialized = PKIX_FALSE;
 
 cleanup:
 
--- a/security/nss/lib/libpkix/pkix/util/pkix_error.c
+++ b/security/nss/lib/libpkix/pkix/util/pkix_error.c
@@ -387,17 +387,17 @@ PKIX_ERRORNAMES[PKIX_NUMERRORS] =
         "HashTable Error",
         "Cert Error",
         "X500Name Error",
         "GeneralName Error",
         "PublicKey Error",
         "Date Error",
         "TrustAnchor Error",
         "ProcessingParams Error",
-        "NoLongerUsed Error",
+        "HttpClient Error",
         "ValidateParams Error",
         "Validate Error",
         "ValidateResult Error",
         "CertChainChecker Error",
         "CertSelector Error",
         "ComCertSelParams Error",
         "TargetCertCheckerState Error",
         "CertBasicConstraints Error",
@@ -412,17 +412,17 @@ PKIX_ERRORNAMES[PKIX_NUMERRORS] =
         "CollectionCertStoreContext Error",
         "DefaultCRLCheckerState Error",
         "CRL Error",
         "CRLEntry Error",
         "CRLSelector Error",
         "CertPolicyMap Error",
         "Build Error",
         "BuildResult Error",
-        "NoLongerUsed Error",
+        "HttpCertStoreContext Error",
         "ForwardBuilderState Error",
         "SignatureCheckerState Error",
         "CertNameConstraints Error",
         "CertNameConstraintsCheckerState Error",
         "RevocationChecker Error",
         "User Defined Modules Error",
         "Context Error",
         "DefaultRevocationChecker Error",
@@ -434,17 +434,17 @@ PKIX_ERRORNAMES[PKIX_NUMERRORS] =
         "Resource Limits Error",
         "Logger Error",
         "MonitorLock Error",
         "InfoAccess Error",
         "AIAMgr Error",
         "OcspChecker Error",
         "OcspRequest Error",
         "OcspResponse Error",
-        "HttpClient Error"
+        "HttpDefaultClient Error"
 };
 
 /*
  * FUNCTION: pkix_Error_RegisterSelf
  * DESCRIPTION:
  *  Registers PKIX_ERROR_TYPE and its related functions with systemClasses[]
  * THREAD SAFETY:
  *  Not Thread Safe - for performance and complexity reasons
--- a/security/nss/lib/libpkix/pkix/util/pkix_logger.c
+++ b/security/nss/lib/libpkix/pkix/util/pkix_logger.c
@@ -96,17 +96,17 @@ PKIX_COMPONENTNAMES[PKIX_NUMERRORS] =
         "HashTable",
         "Cert",
         "X500Name",
         "GeneralName",
         "PublicKey",
         "Date",
         "TrustAnchor",
         "ProcessingParams",
-        "NoLongerUsed",
+        "HttpClient",
         "ValidateParams",
         "Validate",
         "ValidateResult",
         "CertChainChecker",
         "CertSelector",
         "ComCertSelParams",
         "TargetCertCheckerState",
         "CertBasicConstraints",
@@ -121,17 +121,17 @@ PKIX_COMPONENTNAMES[PKIX_NUMERRORS] =
         "CollectionCertStoreContext",
         "DefaultCRLCheckerState",
         "CRL",
         "CRLEntry",
         "CRLSelector",
         "CertPolicyMap",
         "Build",
         "BuildResult",
-        "NoLongerUsed",
+        "HttpCertStoreContext",
         "ForwardBuilderState",
         "SignatureCheckerState",
         "CertNameConstraints",
         "CertNameConstraintsCheckerState",
         "RevocationChecker",
         "User Defined Modules",
         "Context",
         "DefaultRevocationChecker",
@@ -143,17 +143,17 @@ PKIX_COMPONENTNAMES[PKIX_NUMERRORS] =
         "ResourceLimits",
         "Logger",
         "MonitorLock",
         "InfoAccess",
         "AIAMgr",
         "OcspChecker",
         "OcspRequest"
         "OcspResponse",
-        "HttpClient"
+        "HttpDefaultClient"
 };
 
 /* --Private-Functions-------------------------------------------- */
 
 /*
  * FUNCTION: pkix_Logger_CheckErrors
  * DESCRIPTION:
  *
--- a/security/nss/lib/libpkix/pkix/util/pkix_tools.h
+++ b/security/nss/lib/libpkix/pkix/util/pkix_tools.h
@@ -446,16 +446,17 @@ extern "C" {
 #define PKIX_BYTEARRAYDEBUG                       1
 #define PKIX_RWLOCKDEBUG                          1
 #define PKIX_BIGINTDEBUG                          1
 #define PKIX_HASHTABLEDEBUG                       1
 #define PKIX_X500NAMEDEBUG                        1
 #define PKIX_GENERALNAMEDEBUG                     1
 #define PKIX_PUBLICKEYDEBUG                       1
 #define PKIX_CERTDEBUG                            1
+#define PKIX_HTTPCLIENTDEBUG                      1
 #define PKIX_DATEDEBUG                            1
 #define PKIX_TRUSTANCHORDEBUG                     1
 #define PKIX_PROCESSINGPARAMSDEBUG                1
 #define PKIX_VALIDATEPARAMSDEBUG                  1
 #define PKIX_VALIDATERESULTDEBUG                  1
 #define PKIX_VALIDATEDEBUG                        1
 #define PKIX_CERTCHAINCHECKERDEBUG                1
 #define PKIX_REVOCATIONCHECKERDEBUG               1
@@ -498,16 +499,17 @@ extern "C" {
 #define PKIX_LOGGERDEBUG                          1
 #define PKIX_MONITORLOCKDEBUG                     1
 #define PKIX_INFOACCESSDEBUG                      1
 #define PKIX_AIAMGRDEBUG                          1
 #define PKIX_OCSPCHECKERDEBUG                     1
 #define PKIX_OCSPREQUESTDEBUG                     1
 #define PKIX_OCSPRESPONSEDEBUG                    1
 #define PKIX_HTTPDEFAULTCLIENTDEBUG               1
+#define PKIX_HTTPCERTSTORECONTEXTDEBUG            1
 #endif
 
 /*
  * XXX Both PKIX_DEBUG and PKIX_DEBUG_ARG currently use printf.
  * This needs to be replaced with Loggers.
  */
 
 #define PKIX_DEBUG(expr) \
@@ -683,16 +685,26 @@ extern "C" {
         PKIX_DEBUG(expr)
 #define PKIX_CERT_DEBUG_ARG(expr, arg) \
         PKIX_DEBUG_ARG(expr, arg)
 #else
 #define PKIX_CERT_DEBUG(expr)
 #define PKIX_CERT_DEBUG_ARG(expr, arg)
 #endif
 
+#if PKIX_HTTPCLIENTDEBUG
+#define PKIX_HTTPCLIENT_DEBUG(expr) \
+        PKIX_DEBUG(expr)
+#define PKIX_HTTPCLIENT_DEBUG_ARG(expr, arg) \
+        PKIX_DEBUG_ARG(expr, arg)
+#else
+#define PKIX_HTTPCLIENT_DEBUG(expr)
+#define PKIX_HTTPCLIENT_DEBUG_ARG(expr, arg)
+#endif
+
 #if PKIX_BIGINTDEBUG
 #define PKIX_BIGINT_DEBUG(expr) \
         PKIX_DEBUG(expr)
 #define PKIX_BIGINT_DEBUG_ARG(expr, arg) \
         PKIX_DEBUG_ARG(expr, arg)
 #else
 #define PKIX_BIGINT_DEBUG(expr)
 #define PKIX_BIGINT_DEBUG_ARG(expr, arg)
@@ -1213,16 +1225,26 @@ extern "C" {
         PKIX_DEBUG(expr)
 #define PKIX_HTTPDEFAULTCLIENT_DEBUG_ARG(expr, arg) \
         PKIX_DEBUG_ARG(expr, arg)
 #else
 #define PKIX_HTTPDEFAULTCLIENT_DEBUG(expr)
 #define PKIX_HTTPDEFAULTCLIENT_DEBUG_ARG(expr, arg)
 #endif
 
+#if PKIX_HTTPCERTSTORECONTEXTDEBUG
+#define PKIX_HTTPCERTSTORECONTEXT_DEBUG(expr) \
+        PKIX_DEBUG(expr)
+#define PKIX_HTTPCERTSTORECONTEXT_DEBUG_ARG(expr, arg) \
+        PKIX_DEBUG_ARG(expr, arg)
+#else
+#define PKIX_HTTPCERTSTORECONTEXT_DEBUG(expr)
+#define PKIX_HTTPCERTSTORECONTEXT_DEBUG_ARG(expr, arg)
+#endif
+
 /*
  * All object types register themselves with the system using a
  * pkix_ClassTable_Entry, which consists of a set of functions for that
  * type and an ASCII string (char *) which is used by the default
  * ToStringCallback (if necessary). System types register themselves directly
  * when their respective PKIX_"type"_RegisterSelf functions are called.
  * User-defined types can be registered using PKIX_PL_Object_RegisterType.
  * (see comments in pkix_pl_system.h)
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/manifest.mn
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/manifest.mn
@@ -38,16 +38,17 @@ CORE_DEPTH = ../../../../..
 
 EXPORTS = \
 	$(NULL)
 
 PRIVATE_EXPORTS = \
 	pkix_pl_aiamgr.h \
 	pkix_pl_colcertstore.h \
 	pkix_pl_ekuchecker.h \
+	pkix_pl_httpcertstore.h \
 	pkix_pl_httpdefaultclient.h \
 	pkix_pl_ldapt.h \
 	pkix_pl_ldapcertstore.h \
 	pkix_pl_ldapresponse.h \
 	pkix_pl_ldaprequest.h \
 	pkix_pl_ldapdefaultclient.h \
 	pkix_pl_nsscontext.h \
 	pkix_pl_pk11certstore.h \
@@ -55,16 +56,17 @@ PRIVATE_EXPORTS = \
 	$(NULL)
 
 MODULE = nss
 
 CSRCS = \
 	pkix_pl_aiamgr.c \
 	pkix_pl_ekuchecker.c \
 	pkix_pl_colcertstore.c \
+	pkix_pl_httpcertstore.c \
 	pkix_pl_httpdefaultclient.c \
 	pkix_pl_ldaptemplates.c \
 	pkix_pl_ldapcertstore.c \
 	pkix_pl_ldapresponse.c \
 	pkix_pl_ldaprequest.c \
 	pkix_pl_ldapdefaultclient.c \
 	pkix_pl_nsscontext.c \
 	pkix_pl_pk11certstore.c \
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
@@ -109,17 +109,17 @@ pkix_pl_AIAMgr_Destroy(
         /* pointer to cert cache */
         /* pointer to crl cache */
         aiaMgr->method = 0;
         aiaMgr->aiaIndex = 0;
         aiaMgr->numAias = 0;
         PKIX_DECREF(aiaMgr->aia);
         PKIX_DECREF(aiaMgr->location);
         PKIX_DECREF(aiaMgr->results);
-        PKIX_DECREF(aiaMgr->client);
+        PKIX_DECREF(aiaMgr->client.ldapClient);
 
 cleanup:
 
         PKIX_RETURN(AIAMGR);
 }
 
 /*
  * FUNCTION: pkix_pl_AIAMgr_RegisterSelf
@@ -150,66 +150,16 @@ pkix_pl_AIAMgr_RegisterSelf(void *plCont
         entry.duplicateFunction = NULL;
 
         systemClasses[PKIX_AIAMGR_TYPE] = entry;
 
         PKIX_RETURN(AIAMGR);
 }
 
 /*
- * FUNCTION: pkix_pl_AIAMgr_ConvertResponses
- * DESCRIPTION:
- *
- *  This function processes the List of LDAPResponses pointed to by "responses"
- *  into a List of resulting Certs, storing the result at "pCerts". If there
- *  are no responses converted successfully, a NULL may be stored.
- *
- * PARAMETERS:
- *  "responses"
- *      The LDAPResponses whose contents are to be converted. Must be non-NULL.
- *  "pCerts"
- *      Address at which the returned List 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 AIAMgr 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_AIAMgr_ConvertResponses(
-        PKIX_List *responses,
-        PKIX_List **pCerts,
-        void *plContext)
-{
-        PKIX_List *certs = NULL;
-
-        PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_ConvertResponses");
-        PKIX_NULLCHECK_TWO(responses, pCerts);
-
-        *pCerts = NULL;
-
-         if (responses != NULL) {
-                PKIX_CHECK(pkix_pl_LdapCertStore_ConvertCertResponses
-                        (responses,
-                        &certs,
-                        plContext),
-                        "pkix_pl_LdapCertStore_ConvertCertResponses failed");
-                *pCerts = certs;
-        }
-
-cleanup:
-
-        PKIX_RETURN(AIAMGR);
-
-}
-
-/*
  * FUNCTION: pkix_pl_AiaMgr_FindLDAPClient
  * DESCRIPTION:
  *
  *  This function checks the collection of LDAPClient connections held by the
  *  AIAMgr pointed to by "aiaMgr" for one matching the domain name given by
  *  "domainName". The string may include a port number: e.g., "betty.nist.gov"
  *  or "nss.red.iplanet.com:1389". If a match is found, that LDAPClient is
  *  stored at "pClient". Otherwise, an LDAPClient is created and added to the
@@ -258,17 +208,17 @@ pkix_pl_AiaMgr_FindLDAPClient(
                 plContext),
                 "PKIX_PL_HashTable_Lookup failed");
 
         if (client == NULL) {
 
                 /* No, create a connection (and cache it) */
                 PKIX_CHECK(PKIX_PL_LdapDefaultClient_CreateByName
                         (domainName,
-                        PR_INTERVAL_NO_TIMEOUT,
+                        PR_INTERVAL_NO_WAIT, /* PR_INTERVAL_NO_TIMEOUT, */
                         NULL,
                         &client,
                         plContext),
                         "PKIX_PL_LdapDefaultClient_CreateByName failed");
 
                 PKIX_CHECK(PKIX_PL_HashTable_Add
                         (aiaConnectionCache,
                         (PKIX_PL_Object *)domainString,
@@ -282,16 +232,283 @@ pkix_pl_AiaMgr_FindLDAPClient(
 
 cleanup:
 
         PKIX_DECREF(domainString);
 
         PKIX_RETURN(AIAMGR);
 }
 
+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;
+	PRUint32 responseDataLen = 0;
+
+        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_PL_InfoAccess_GetLocation failed");
+
+                /* find or create httpClient = default client */
+		httpClient = GetRegisteredHttpClient();
+		aiaMgr->client.hdata.httpClient = httpClient;
+
+		if (httpClient->version == 1) {
+
+			hcv1 = &(httpClient->fcnTable.ftable1);
+
+			/* create server session */
+			PKIX_TOSTRING(location, &locationString, plContext,
+				"PKIX_PL_GeneralName_ToString failed");
+
+			PKIX_CHECK(PKIX_PL_String_GetEncoded
+				(locationString,
+				PKIX_ESCASCII,
+				(void **)&locationAscii,
+				&len,
+				plContext),
+				"PKIX_PL_String_GetEncoded failed");
+
+			PKIX_PL_NSSCALLRV
+				(AIAMGR, rv, CERT_ParseURL,
+				(locationAscii, &hostname, &port, &path));
+
+			if ((rv != SECSuccess) ||
+			    (hostname == NULL) ||
+			    (path == NULL)) {
+				PKIX_ERROR("URL Parsing failed");
+			}
+
+			PKIX_PL_NSSCALLRV
+                        	(AIAMGR, rv, hcv1->createSessionFcn,
+                        	(hostname, port, &serverSession));
+
+	                if (rv != SECSuccess) {
+				PKIX_ERROR("HttpClient->CreateSession failed");
+			}
+
+			aiaMgr->client.hdata.serverSession = serverSession;
+
+			/* create request session */
+			PKIX_PL_NSSCALLRV
+                        	(AIAMGR, rv, hcv1->createFcn,
+                        	(serverSession,
+                        	"http",
+                        	path,
+                        	"GET",
+                        	PR_TicksPerSecond() * 60,
+                        	&requestSession));
+
+                	if (rv != SECSuccess) {
+                        	if (path != NULL) {
+                                	PORT_Free(path);
+                        	}
+                        	PKIX_ERROR("HTTP Server Error");
+                	}
+
+			aiaMgr->client.hdata.requestSession = requestSession;
+		} else {
+			PKIX_ERROR("Unsupported version of Http Client");
+		}
+	}
+
+	httpClient = aiaMgr->client.hdata.httpClient;
+
+	if (httpClient->version == 1) {
+
+		hcv1 = &(httpClient->fcnTable.ftable1);
+		requestSession = aiaMgr->client.hdata.requestSession;
+
+		/* trySendAndReceive */
+		PKIX_PL_NSSCALLRV
+                        (AIAMGR, rv, hcv1->trySendAndReceiveFcn,
+                        (requestSession,
+                        (PRPollDesc **)&nbio,
+                        &responseCode,
+                        (const char **)&responseContentType,
+                        NULL, /* &responseHeaders */
+                        (const char **)&responseData,
+                        &responseDataLen));
+
+                if (rv != SECSuccess) {
+                        PKIX_ERROR("HTTP Server Error");
+                }
+
+                if (nbio != 0) {
+                        *pNBIOContext = nbio;
+                        goto cleanup;
+                }
+
+		PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
+	                (responseCode,
+	                responseContentType,
+	                responseData,
+	                responseDataLen,
+	                pCerts,
+	                plContext),
+	                "pkix_pl_HttpCertStore_ProcessCertResponse failed");
+
+		PKIX_DECREF(aiaMgr->client.hdata.requestSession);
+		PKIX_DECREF(aiaMgr->client.hdata.serverSession);
+		aiaMgr->client.hdata.httpClient = 0; /* not an object */
+
+        } else  {
+		PKIX_ERROR("Unsupported version of Http Client");
+	}
+
+cleanup:
+	if (PKIX_ERROR_RECEIVED) {
+		PKIX_DECREF(aiaMgr->client.hdata.requestSession);
+		PKIX_DECREF(aiaMgr->client.hdata.serverSession);
+		aiaMgr->client.hdata.httpClient = 0; /* not an object */
+	}
+
+        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;
+        PRArenaPool *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_PL_InfoAccess_GetLocation failed");
+
+                /*
+                 * Get a short-lived arena. We'll be done with
+                 * this space once the request is encoded.
+                 */
+                PKIX_PL_NSSCALLRV(AIAMGR, arena, PORT_NewArena,
+                        (DER_DEFAULT_CHUNKSIZE));
+
+                if (!arena) {
+                        PKIX_ERROR_FATAL("Out of memory");
+                }
+
+                PKIX_CHECK(pkix_pl_InfoAccess_ParseLocation
+                        (location, arena, &request, &domainName, plContext),
+                        "pkix_pl_InfoAccess_ParseLocation failed");
+
+                PKIX_DECREF(location);
+
+                /* Find or create a connection to LDAP server */
+                PKIX_CHECK(pkix_pl_AiaMgr_FindLDAPClient
+                        (aiaMgr, domainName, &client, plContext),
+                        "pkix_pl_AiaMgr_FindLDAPClient failed");
+
+                aiaMgr->client.ldapClient = client;
+
+                PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
+                        (aiaMgr->client.ldapClient,
+			&request,
+			&nbio,
+			&result,
+			plContext),
+                        "PKIX_PL_LdapClient_InitiateRequest failed");
+
+                PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE));
+
+        } else {
+
+                PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
+                        (aiaMgr->client.ldapClient, &nbio, &result, plContext),
+                        "PKIX_PL_LdapClient_ResumeRequest failed");
+
+        }
+
+        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_pl_LdapCertStore_BuildCertList failed");
+	}
+
+	*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);
+}
+
 /*
  * FUNCTION: PKIX_PL_AIAMgr_Create
  * DESCRIPTION:
  *
  *  This function creates an AIAMgr, storing the result at "pAIAMgr".
  *
  * PARAMETERS:
  *  "pAIAMGR"
@@ -324,17 +541,19 @@ PKIX_PL_AIAMgr_Create(
         /* pointer to cert cache */
         /* pointer to crl cache */
         aiaMgr->method = 0;
         aiaMgr->aiaIndex = 0;
         aiaMgr->numAias = 0;
         aiaMgr->aia = NULL;
         aiaMgr->location = NULL;
         aiaMgr->results = NULL;
-        aiaMgr->client = NULL;
+        aiaMgr->client.hdata.httpClient = NULL;
+	aiaMgr->client.hdata.serverSession = NULL;
+	aiaMgr->client.hdata.requestSession = NULL;
 
         *pAIAMgr = aiaMgr;
 
 cleanup:
 
         PKIX_RETURN(AIAMGR);
 }
 
@@ -349,25 +568,19 @@ PKIX_PL_AIAMgr_GetAIACerts(
         PKIX_PL_Cert *prevCert,
         void **pNBIOContext,
         PKIX_List **pCerts,
         void *plContext)
 {
         PKIX_UInt32 numAias = 0;
         PKIX_UInt32 aiaIndex = 0;
         PKIX_UInt32 iaType = PKIX_INFOACCESS_LOCATION_UNKNOWN;
-        PKIX_List *result = NULL;
         PKIX_List *certs = NULL;
         PKIX_PL_InfoAccess *ia = NULL;
-        PKIX_PL_GeneralName *location = NULL;
-        PKIX_PL_LdapClient *client = NULL;
         void *nbio = NULL;
-        PRArenaPool *arena = NULL;
-        char *domainName = NULL;
-        LDAPRequestParams request;
 
         PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_GetAIACerts");
         PKIX_NULLCHECK_FOUR(aiaMgr, prevCert, pNBIOContext, pCerts);
 
         nbio = *pNBIOContext;
         *pCerts = NULL;
         *pNBIOContext = NULL;
 
@@ -406,87 +619,27 @@ PKIX_PL_AIAMgr_GetAIACerts(
                         (PKIX_PL_Object **)&ia,
                         plContext),
                         "PKIX_List_GetItem failed");
 
                 PKIX_CHECK(PKIX_PL_InfoAccess_GetLocationType
                         (ia, &iaType, plContext),
                         "PKIX_PL_InfoAccess_GetLocationType failed");
 
-                if (iaType == PKIX_INFOACCESS_LOCATION_LDAP) {
-
-                        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_PL_InfoAccess_GetLocation failed");
-
-                                /*
-                                 * Get a short-lived arena. We'll be done with
-                                 * this space once the request is encoded.
-                                 */
-                                PKIX_PL_NSSCALLRV(AIAMGR, arena, PORT_NewArena,
-                                        (DER_DEFAULT_CHUNKSIZE));
-
-                                if (!arena) {
-                                        PKIX_ERROR_FATAL("Out of memory");
-                                }
-
-                                PKIX_CHECK(pkix_pl_InfoAccess_ParseLocation
-                                        (location,
-                                        arena,
-                                        &request,
-                                        &domainName,
-                                        plContext),
-                                        "pkix_pl_InfoAccess_ParseLocation"
-                                        " failed");
-
-                                PKIX_DECREF(location);
-
-                                /* Find or create a connection to LDAP server */
-                                PKIX_CHECK(pkix_pl_AiaMgr_FindLDAPClient
-                                        (aiaMgr,
-                                        domainName,
-                                        &client,
-                                        plContext),
-                                        "pkix_pl_AiaMgr_FindLDAPClient failed");
-
-                                aiaMgr->client = client;
-
-                                PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
-                                        (aiaMgr->client,
-                                        &request,
-                                        &nbio,
-                                        &result,
-                                        plContext),
-                                        "PKIX_PL_LdapClient_InitiateRequest"
-                                        " failed");
-
-                                PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena,
-                                        (arena, PR_FALSE));
-
-                        } else {
-
-                                PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
-                                        (aiaMgr->client,
-                                        &nbio,
-                                        &result,
-                                        plContext),
-                                        "PKIX_PL_LdapClient_ResumeRequest failed");
-                        }
-
+                if (iaType == PKIX_INFOACCESS_LOCATION_HTTP) {
+			PKIX_CHECK(pkix_pl_AIAMgr_GetHTTPCerts
+				(aiaMgr, ia, &nbio, &certs, plContext),
+				"pkix_pl_AIAMgr_GetHTTPCerts failed");
+                } else if (iaType == PKIX_INFOACCESS_LOCATION_LDAP) {
+			PKIX_CHECK(pkix_pl_AIAMgr_GetLDAPCerts
+				(aiaMgr, ia, &nbio, &certs, plContext),
+				"pkix_pl_AIAMgr_GetLDAPCerts failed");
                 } else {
-                        /* We only support ldap requests at this time. */
+                        /* We only support http and ldap requests. */
+			PKIX_ERROR("Unknown InfoAccess type");
                 }
 
                 if (nbio != NULL) { /* WOULDBLOCK */
                         aiaMgr->aiaIndex = aiaIndex;
                         *pNBIOContext = nbio;
                         *pCerts = NULL;
                         goto cleanup;
                 }
@@ -496,45 +649,33 @@ PKIX_PL_AIAMgr_GetAIACerts(
                  * Because it's cached, it's set immutable.
                  */
                 if (aiaMgr->results == NULL) {
                         PKIX_CHECK(PKIX_List_Create
                                 (&(aiaMgr->results), plContext),
                                 "PKIX_List_Create failed");
                 }
                 PKIX_CHECK(pkix_List_AppendList
-                        (aiaMgr->results, result, plContext),
+                        (aiaMgr->results, certs, plContext),
                         "pkix_pl_AppendList failed");
-                PKIX_DECREF(result);
+                PKIX_DECREF(certs);
 
                 PKIX_DECREF(ia);
-                PKIX_DECREF(aiaMgr->client);
         }
 
         PKIX_DECREF(aiaMgr->aia);
 
-        if (aiaMgr->results != NULL) {
-                PKIX_CHECK(pkix_pl_AIAMgr_ConvertResponses
-                        (aiaMgr->results, &certs, plContext),
-                        "pkix_pl_AIAMgr_ConvertResponses failed");
-        }
-
         *pNBIOContext = NULL;
-        *pCerts = certs;
-        PKIX_DECREF(aiaMgr->results);
+        *pCerts = aiaMgr->results;
+        aiaMgr->results = NULL;
 
 cleanup:
 
-        if (arena && (PKIX_ERROR_RECEIVED)) {
-                PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE));
-        }
-
         if (PKIX_ERROR_RECEIVED) {
                 PKIX_DECREF(aiaMgr->aia);
                 PKIX_DECREF(aiaMgr->results);
-                PKIX_DECREF(aiaMgr->client);
+                PKIX_DECREF(aiaMgr->client.ldapClient);
         }
 
         PKIX_DECREF(ia);
-        PKIX_DECREF(location);
 
         PKIX_RETURN(AIAMGR);
 }
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h
@@ -54,17 +54,25 @@ struct PKIX_PL_AIAMgrStruct {
         /* pointer to cert cache */
         /* pointer to crl cache */
         PKIX_UInt32 method;
         PKIX_UInt32 aiaIndex;
         PKIX_UInt32 numAias;
         PKIX_List *aia;
         PKIX_PL_GeneralName *location;
         PKIX_List *results;
-        PKIX_PL_LdapClient *client;
+	union {
+	        PKIX_PL_LdapClient *ldapClient;
+		struct {
+		        const SEC_HttpClientFcn *httpClient;
+			SEC_HTTP_SERVER_SESSION serverSession;
+			SEC_HTTP_REQUEST_SESSION requestSession;
+			char *path;
+		} hdata;
+	} client;
 };
 
 /* see source file for function documentation */
 
 PKIX_Error *pkix_pl_AIAMgr_RegisterSelf(void *plContext);
 
 PKIX_Error *PKIX_PL_LdapClient_InitiateRequest(
         PKIX_PL_LdapClient *client,
new file mode 100755
--- /dev/null
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
@@ -0,0 +1,1080 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sun Microsystems
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * 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;
+
+/* --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),
+                    "Object is not an HttpCertStoreContext");
+
+        context = (PKIX_PL_HttpCertStoreContext *)object;
+
+        hcv1 = (const SEC_HttpClientFcnV1 *)(context->client);
+
+        if (context->requestSession != NULL) {
+                PKIX_PL_NSSCALL(HTTPCERTSTORECONTEXT, hcv1->freeFcn,
+                        (context->requestSession));
+                context->requestSession = NULL;
+        }
+
+        if (context->serverSession != NULL) {
+                PKIX_PL_NSSCALL(HTTPCERTSTORECONTEXT, hcv1->freeSessionFcn,
+                        (context->serverSession));
+                context->serverSession = NULL;
+        }
+
+        if (context->path != NULL) {
+                PKIX_PL_NSSCALL
+                        (HTTPCERTSTORECONTEXT, 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;
+
+        PKIX_ENTER
+                (HTTPCERTSTORECONTEXT,
+                "pkix_pl_HttpCertStoreContext_RegisterSelf");
+
+        entry.description = "HttpCertStoreContext";
+        entry.destructor = pkix_pl_HttpCertStoreContext_Destroy;
+        entry.equalsFunction = NULL;
+        entry.hashcodeFunction = NULL;
+        entry.toStringFunction = NULL;
+        entry.comparator = NULL;
+        entry.duplicateFunction = NULL;
+
+        systemClasses[PKIX_HTTPCERTSTORECONTEXT_TYPE] = entry;
+
+        PKIX_RETURN(HTTPCERTSTORECONTEXT);
+}
+
+/* --Private-Http-CertStore-Database-Functions----------------------- */
+
+typedef struct callbackContextStruct  {
+        PKIX_List *pkixCertList;
+        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)
+{
+        SECStatus rv;
+        callbackContext *cbContext;
+        SECItem **certs = NULL;
+        SECItem *cert = NULL;
+        PKIX_List *pkixCertList = NULL;
+        PKIX_Error *error = NULL;
+        void *plContext = NULL;
+        int certsFound = 0;
+
+        if ((arg == NULL) || (secitemCerts == NULL)) {
+                return (SECFailure);
+        }
+
+        cbContext = (callbackContext *)arg;
+        plContext = cbContext->plContext;
+        pkixCertList = cbContext->pkixCertList;
+        certs = secitemCerts;
+
+        while ( *certs ) {
+                cert = *certs;
+                error = pkix_pl_Cert_CreateToList
+                        (cert, pkixCertList, plContext);
+                certsFound++;
+                certs++;
+                if (error != NULL) {
+                        PKIX_PL_Object_DecRef
+                                ((PKIX_PL_Object *)error, plContext);
+                }
+        }
+
+        rv = (certsFound == numcerts)?SECSuccess:SECFailure;
+
+cleanup:
+
+        return(rv);
+}
+
+/*
+ * 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)
+{
+        PRArenaPool *arena = NULL;
+        char *encodedResponse = NULL;
+        PRIntn compareVal = 0;
+        PKIX_List *certs = NULL;
+        SECStatus rv = SECFailure;
+        callbackContext cbContext;
+
+        PKIX_ENTER
+                (HTTPCERTSTORECONTEXT,
+                "pkix_pl_HttpCertStore_ProcessCertResponse");
+        PKIX_NULLCHECK_ONE(pCertList);
+
+        if (responseCode != 200) {
+                PKIX_ERROR("Bad Http Response");
+        }
+
+        /* check that response type is application/pkcs7-mime */
+        if (responseContentType == NULL) {
+                PKIX_ERROR("No content type in Http Response");
+        }
+
+        PKIX_PL_NSSCALLRV(HTTPCERTSTORECONTEXT, compareVal, PORT_Strcasecmp,
+                (responseContentType, "application/pkcs7-mime"));
+
+        if (compareVal != 0) {
+                PKIX_ERROR("Content type is not application/pkcs7-mime");
+        }
+
+        PKIX_PL_NSSCALLRV(HTTPCERTSTORECONTEXT, arena, PORT_NewArena,
+                (DER_DEFAULT_CHUNKSIZE));
+
+        if (arena == NULL) {
+                PKIX_ERROR("Out of Memory");
+        }
+
+        if (responseData == NULL) {
+                PKIX_ERROR("No responseData in Http Response");
+        }
+
+        PKIX_CHECK(PKIX_List_Create(&certs, plContext),
+                "PKIX_List_Create failed");
+
+        cbContext.pkixCertList = certs;
+        cbContext.plContext = plContext;
+        encodedResponse = (char *)responseData;
+
+        PKIX_PL_NSSCALLRV(HTTPCERTSTORECONTEXT, rv, CERT_DecodeCertPackage,
+                (encodedResponse, responseDataLen, certCallback, &cbContext));
+
+        if (rv != SECSuccess) {
+                PKIX_ERROR("Error decoding pkcs7-mime data");
+        }
+
+        *pCertList = cbContext.pkixCertList;
+
+cleanup:
+        if (PKIX_ERROR_RECEIVED) {
+                PKIX_DECREF(cbContext.pkixCertList);
+        }
+
+        if (arena != NULL) {
+                PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena, (arena, PR_FALSE));
+        }
+
+        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)
+{
+        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("Bad Http Response");
+        }
+
+        /* check that response type is application/pkix-crl */
+        if (responseContentType == NULL) {
+                PKIX_ERROR("No content type in Http Response");
+        }
+
+        PKIX_PL_NSSCALLRV
+                (HTTPCERTSTORECONTEXT, compareVal, PORT_Strcasecmp,
+                (responseContentType, "application/pkix-crl"));
+
+        if (compareVal != 0) {
+                PKIX_ERROR("Content type is not application/pkix-crl");
+        }
+
+        /* Make a SECItem of the response data */
+        PKIX_PL_NSSCALLRV(HTTPCERTSTORECONTEXT, arena, PORT_NewArena,
+                (DER_DEFAULT_CHUNKSIZE));
+
+        if (arena == NULL) {
+                PKIX_ERROR("Out of Memory");
+        }
+
+        if (responseData == NULL) {
+                PKIX_ERROR("No responseData in Http Response");
+        }
+
+        PKIX_PL_NSSCALLRV
+                (HTTPCERTSTORECONTEXT, encodedResponse, SECITEM_AllocItem,
+                (arena, NULL, responseDataLen));
+
+        if (encodedResponse == NULL) {
+                PKIX_ERROR("Out of Memory");
+        }
+
+        PKIX_PL_NSSCALL(HTTPCERTSTORECONTEXT, PORT_Memcpy,
+                (encodedResponse->data, responseData, responseDataLen));
+
+        PKIX_CHECK(PKIX_List_Create(&crls, plContext),
+                "PKIX_List_Create failed");
+
+        PKIX_CHECK(pkix_pl_CRL_CreateToList
+                (encodedResponse, crls, plContext),
+                "pkix_pl_CRL_CreateToList failed");
+
+        *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);
+}
+
+/*
+ * 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("HTTP Server Error");
+                }
+        } else {
+                PKIX_ERROR("Unsupported version of Http Client");
+        }
+
+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,
+        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_CertStore_GetCertStoreContext failed");
+
+        if (context->client->version == 1) {
+                hcv1 = &(context->client->fcnTable.ftable1);
+
+                PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
+                        (context, plContext),
+                        "pkix_pl_HttpCertStore_CreateRequestSession failed");
+
+                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("HTTP Server Error");
+                }
+
+                if (nbioContext != 0) {
+                        *pNBIOContext = nbioContext;
+                        goto cleanup;
+                }
+
+        } else {
+                PKIX_ERROR("Unsupported version of Http Client");
+        }
+
+        PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
+                (responseCode,
+                responseContentType,
+                responseData,
+                responseDataLen,
+                &certList,
+                plContext),
+                "pkix_pl_HttpCertStore_ProcessCertResponse failed");
+
+        *pCertList = certList;
+
+cleanup:
+
+        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,
+        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_CertStore_GetCertStoreContext failed");
+
+        if (context->client->version == 1) {
+                hcv1 = &(context->client->fcnTable.ftable1);
+
+                PKIX_NULLCHECK_ONE(context->requestSession);
+
+                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("HTTP Server Error");
+                }
+
+                if (nbioContext != 0) {
+                        *pNBIOContext = nbioContext;
+                        goto cleanup;
+                }
+
+        } else {
+                PKIX_ERROR("Unsupported version of Http Client");
+        }
+
+        PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
+                (responseCode,
+                responseContentType,
+                responseData,
+                responseDataLen,
+                &certList,
+                plContext),
+                "pkix_pl_HttpCertStore_ProcessCertResponse failed");
+
+        *pCertList = certList;
+
+cleanup:
+
+        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_CertStore_GetCertStoreContext failed");
+
+        if (context->client->version == 1) {
+                hcv1 = &(context->client->fcnTable.ftable1);
+
+                PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
+                        (context, plContext),
+                        "pkix_pl_HttpCertStore_CreateRequestSession failed");
+
+                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("HTTP Server Error");
+                }
+
+                if (nbioContext != 0) {
+                        *pNBIOContext = nbioContext;
+                        goto cleanup;
+                }
+
+        } else {
+                PKIX_ERROR("Unsupported version of Http Client");
+        }
+
+        PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse
+                (responseCode,
+                responseContentType,
+                responseData,
+                responseDataLen,
+                &crlList,
+                plContext),
+                "pkix_pl_HttpCertStore_ProcessCrlResponse failed");
+
+        *pCrlList = crlList;
+
+cleanup:
+
+        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_CertStore_GetCertStoreContext failed");
+
+        if (context->client->version == 1) {
+                hcv1 = &(context->client->fcnTable.ftable1);
+
+                PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
+                        (context, plContext),
+                        "pkix_pl_HttpCertStore_CreateRequestSession failed");
+
+                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("HTTP Server Error");
+                }
+
+                if (nbioContext != 0) {
+                        *pNBIOContext = nbioContext;
+                        goto cleanup;
+                }
+
+        } else {
+                PKIX_ERROR("Unsupported version of Http Client");
+        }
+
+        PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse
+                (responseCode,
+                responseContentType,
+                responseData,
+                responseDataLen,
+                &crlList,
+                plContext),
+                "pkix_pl_HttpCertStore_ProcessCrlResponse failed");
+
+        *pCrlList = crlList;
+
+cleanup:
+
+        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;
+        PKIX_PL_String *locationString = NULL;
+        char *hostname = NULL;
+        char *path = NULL;
+        PKIX_UInt32 len = 0;
+        PRUint16 port = 0;
+        SECStatus rv = SECFailure;
+
+        PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_CreateWithAsciiName");
+        PKIX_NULLCHECK_TWO(locationAscii, pCertStore);
+
+        if (client == NULL) {
+                clientFcn = GetRegisteredHttpClient();
+                if (clientFcn == NULL) {
+                        PKIX_ERROR("No registered Http Client");
+                }
+        } 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),
+                  "Could not create object");
+
+        /* 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("URL Parsing failed");
+        }
+
+        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("HttpClient->CreateSession failed");
+                }
+        } else {
+                PKIX_ERROR("Unsupported version of Http Client");
+        }
+
+        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_CertStore_Create failed");
+
+        *pCertStore = certStore;
+
+cleanup:
+
+        if (PKIX_ERROR_RECEIVED) {
+                PKIX_DECREF(httpCertStore);
+        }
+
+        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_PL_GeneralName_ToString failed");
+
+        PKIX_CHECK(PKIX_PL_String_GetEncoded
+                (locationString,
+                PKIX_ESCASCII,
+                (void **)&locationAscii,
+                &len,
+                plContext),
+                "PKIX_PL_String_GetEncoded failed");
+
+        PKIX_CHECK(pkix_pl_HttpCertStore_CreateWithAsciiName
+                (client, locationAscii, pCertStore, plContext),
+                "PKIX_PL_HttpCertStore_CreateWithAsciiName failed");
+
+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_PL_String_Create failed");
+
+hostname = "variation.red.iplanet.com";
+portnum = 2001;
+
+        PKIX_CHECK(PKIX_PL_String_Create
+                (PKIX_ESCASCII, hostname, 0, &hostString, plContext),
+                "PKIX_PL_String_Create failed");
+
+        PKIX_CHECK(PKIX_PL_Sprintf
+                (&domainString, plContext, formatString, hostString, portnum),
+                "PKIX_PL_String_Create failed");
+
+        /* Is this domainName already in cache? */
+        PKIX_CHECK(PKIX_PL_HashTable_Lookup
+                (httpSocketCache,
+                (PKIX_PL_Object *)domainString,
+                (PKIX_PL_Object **)&socket,
+                plContext),
+                "PKIX_PL_HashTable_Lookup failed");
+
+        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_pl_Socket_CreateByHostAndPort failed");
+
+                PKIX_CHECK(PKIX_PL_HashTable_Add
+                        (httpSocketCache,
+                        (PKIX_PL_Object *)domainString,
+                        (PKIX_PL_Object *)socket,
+                        plContext),
+                        "PKIX_PL_HashTable_Add failed");
+
+        }
+
+        *pSocket = socket;
+
+cleanup:
+
+        PKIX_DECREF(formatString);
+        PKIX_DECREF(hostString);
+        PKIX_DECREF(domainString);
+
+        PKIX_RETURN(CERTSTORE);
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h
@@ -0,0 +1,103 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sun Microsystems
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * pkix_pl_httpcertstore.h
+ *
+ * HTTPCertstore Object Type Definition
+ *
+ */
+
+#ifndef _PKIX_PL_HTTPCERTSTORE_H
+#define _PKIX_PL_HTTPCERTSTORE_H
+
+#include "pkix_pl_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RCVBUFSIZE              512
+
+#if 0
+struct PKIX_PL_HttpClientStruct {
+	const SEC_HttpClientFcn *httpClient;
+};
+ 
+typedef const SEC_HttpClientFcn *PKIX_PL_HttpClient;
+#endif
+
+struct PKIX_PL_HttpCertStoreContextStruct {
+        const SEC_HttpClientFcn *client;
+        SEC_HTTP_SERVER_SESSION serverSession;
+        SEC_HTTP_REQUEST_SESSION requestSession;
+	char *path;
+};
+
+/* see source file for function documentation */
+
+PKIX_Error *pkix_pl_HttpCertStoreContext_RegisterSelf(void *plContext);
+
+PKIX_Error *
+pkix_pl_HttpCertStore_CreateWithAsciiName(
+        PKIX_PL_HttpClient *client,
+	char *locationAscii,
+        PKIX_CertStore **pCertStore,
+        void *plContext);
+
+PKIX_Error *
+pkix_HttpCertStore_FindSocketConnection(
+        PRIntervalTime timeout,
+        char *hostname,
+        PRUint16 portnum,
+        PRErrorCode *pStatus,
+        PKIX_PL_Socket **pSocket,
+        void *plContext);
+
+PKIX_Error *
+pkix_pl_HttpCertStore_ProcessCertResponse(
+	PRUint16 responseCode,
+	const char *responseContentType,
+	const char *responseData,
+        PRUint32 responseDataLen,
+	PKIX_List **pCertList,
+        void *plContext);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PKIX_PL_HTTPCERTSTORE_H */
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
@@ -125,33 +125,34 @@ pkix_pl_HttpDefaultClient_HdrCheckComple
         char *eoh = NULL;
         char *statusLineEnd = NULL;
         char *space = NULL;
         char *nextHeader = NULL;
         const char *httpcode = NULL;
         char *thisHeaderEnd = NULL;
         char *value = NULL;
         char *colon = NULL;
-        void *body = NULL;
+	char *copy = NULL;
+        char *body = NULL;
 
         PKIX_ENTER
                 (HTTPDEFAULTCLIENT,
                 "pkix_pl_HttpDefaultClient_HdrCheckComplete");
         PKIX_NULLCHECK_TWO(client, pKeepGoing);
 
         *pKeepGoing = PKIX_FALSE;
 
         /* Does buffer contain end-of-header marker? */
         alreadyScanned = client->alreadyScanned;
         /*
          * If this is the initial buffer, we have to scan from the beginning.
          * If we scanned, failed to find eohMarker, and read some more, we
          * only have to scan from where we left off.
          */
-        if ((alreadyScanned - eohMarkLen) > 0) {
+        if (alreadyScanned > eohMarkLen) {
                 searchOffset = alreadyScanned - eohMarkLen;
                 PKIX_PL_NSSCALLRV(HTTPDEFAULTCLIENT, eoh, PL_strnstr,
                         (&(client->rcvBuf[searchOffset]),
                         eohMarker,
                         client->capacity - searchOffset));
         } else {
                 PKIX_PL_NSSCALLRV(HTTPDEFAULTCLIENT, eoh, PL_strnstr,
                         (client->rcvBuf, eohMarker, bytesRead));
@@ -167,34 +168,35 @@ pkix_pl_HttpDefaultClient_HdrCheckComple
                 *pKeepGoing = PKIX_TRUE;
                 goto cleanup;
 
         }
 
         /* Yes. Calculate how many bytes in header (not counting eohMarker) */
         headerLength = (eoh - client->rcvBuf);
 
+        /* allocate space to copy header (and for the NULL terminator) */
+        PKIX_CHECK(PKIX_PL_Malloc(headerLength + 1, (void **)&copy, plContext),
+                "PKIX_PL_Malloc failed");
+
+        /* copy header data before we corrupt it (by storing NULLs) */
+        PKIX_CHECK(PKIX_PL_Memcpy
+                (client->rcvBuf, headerLength, (void **)&copy, plContext),
+                "PKIX_PL_Memcpy failed");
+
+	/* Store the NULL terminator */
+	copy[headerLength] = '\0';
+
+	client->rcvHeaders = copy;
+
         /* Did caller want a pointer to header? */
         if (client->rcv_http_headers != NULL) {
 
-                /* allocate space */
-                PKIX_CHECK(PKIX_PL_Malloc
-                        (headerLength, &client->rcvHeaders, plContext),
-                        "PKIX_PL_Malloc failed");
-
-                /* copy header data before we corrupt it (by storing NULLs) */
-                PKIX_CHECK(PKIX_PL_Memcpy
-                        (client->rcvBuf,
-                        headerLength,
-                        &client->rcvHeaders,
-                        plContext),
-                        "PKIX_PL_Memcpy failed");
-
                 /* store pointer for caller */
-                *(client->rcv_http_headers) = client->rcvHeaders;
+                *(client->rcv_http_headers) = copy;
         }
 
         /* Check that message status is okay. */
 
         PKIX_PL_NSSCALLRV(HTTPDEFAULTCLIENT, statusLineEnd, PL_strnstr,
                 (client->rcvBuf, crlf, client->capacity));
 
         if (statusLineEnd == NULL) {
@@ -296,70 +298,75 @@ pkix_pl_HttpDefaultClient_HdrCheckComple
         /* Did caller provide a pointer to return content-type? */
         if (client->rcv_http_content_type != NULL) {
                 *(client->rcv_http_content_type) = client->rcvContentType;
         }
 
         if (client->rcvContentType == NULL) {
                 client->connectStatus = HTTP_ERROR;
                 goto cleanup;
-        } else {
+        }
+#if 0
+/* XXX move this code into ocsp checker */
+ else {
                 PKIX_PL_NSSCALLRV
                         (HTTPDEFAULTCLIENT,
                         comp,
                         PORT_Strcasecmp,
                         (client->rcvContentType, "application/ocsp-response"));
                 if (comp != 0) {
                         client->connectStatus = HTTP_ERROR;
                         goto cleanup;
                 }
         }
+#endif
 
         /*
          * The headers have passed validation. Now figure out whether the
          * message is within the caller's size limit (if one was specified).
          */
 
         client->rcv_http_data_len = contentLength;
         if (client->maxResponseLen > 0) {
                 if (client->maxResponseLen < contentLength) {
                         client->connectStatus = HTTP_ERROR;
                         goto cleanup;
                 }
         }
 
         /* allocate a buffer of size contentLength  for the content */
-        PKIX_CHECK(PKIX_PL_Malloc(contentLength, &body, plContext),
+        PKIX_CHECK(PKIX_PL_Malloc(contentLength, (void **)&body, plContext),
                 "PKIX_PL_Malloc failed");
 
-        /* How many bytes remain in this buffer, beyond the header? */
+        /* How many bytes remain in current buffer, beyond the header? */
         headerLength += eohMarkLen;
         client->currentBytesAvailable -= headerLength;
 
-        /* copy into it any remaining bytes in current buffer */
+        /* copy any remaining bytes in current buffer into new buffer */
         if (client->currentBytesAvailable > 0) {
                 PKIX_CHECK(PKIX_PL_Memcpy
                         (&(client->rcvBuf[headerLength]),
                         client->currentBytesAvailable,
-                        &body,
+                        (void **)&body,
                         plContext),
                         "PKIX_PL_Memcpy failed");
         }
 
         PKIX_CHECK(PKIX_PL_Free(client->rcvBuf, plContext),
                 "PKIX_PL_Free failed");
-        client->rcvBuf = (char *)body;
+        client->rcvBuf = body;
 
         /*
          * Do we have all of the message body, or do we need to read some more?
          */
 
         if (client->currentBytesAvailable < contentLength) {
                 client->bytesToRead =
                         contentLength - client->currentBytesAvailable;
+		client->alreadyScanned = 0;
                 client->connectStatus = HTTP_RECV_BODY;
         } else {
                 client->connectStatus = HTTP_COMPLETE;
                 *pKeepGoing = PKIX_FALSE;
                 goto cleanup;
         }
 
         *pKeepGoing = PKIX_TRUE;
@@ -416,17 +423,17 @@ pkix_pl_HttpDefaultClient_Create(
                 (PKIX_HTTPDEFAULTCLIENT_TYPE,
                 sizeof (PKIX_PL_HttpDefaultClient),
                 (PKIX_PL_Object **)&client,
                 plContext),
                 "Could not create HttpDefaultClient object");
 
         client->connectStatus = HTTP_NOT_CONNECTED;
         client->portnum = portnum;
-        client->timeout = PR_INTERVAL_NO_TIMEOUT;
+        client->timeout = PR_INTERVAL_NO_WAIT; /* PR_INTERVAL_NO_TIMEOUT; */
         client->bytesToWrite = 0;
         client->bytesToRead = 0;
         client->send_http_data_len = 0;
         client->rcv_http_data_len = 0;
         client->capacity = 0;
         client->alreadyScanned = 0;
         client->currentBytesAvailable = 0;
         client->responseCode = 0;
@@ -496,20 +503,22 @@ pkix_pl_HttpDefaultClient_Destroy(
                 client->GETBuf = NULL;
         }
 
         if (client->POSTBuf != NULL) {
                 PKIX_PL_Free(client->POSTBuf, plContext);
                 client->POSTBuf = NULL;
         }
 
+#if 0
         if (client->rcvBuf != NULL) {
                 PKIX_PL_Free(client->rcvBuf, plContext);
                 client->rcvBuf = NULL;
         }
+#endif
 
         PKIX_DECREF(client->socket);
 
 cleanup:
 
         PKIX_RETURN(HTTPDEFAULTCLIENT);
 }
 
@@ -690,17 +699,17 @@ pkix_pl_HttpDefaultClient_Send(
                 client->currentBytesAvailable = 0;
 
                 /*
                  * If the send completed we can proceed to try for the
                  * response. If the send did not complete we will have
                  * to poll for completion later.
                  */
                 if (bytesWritten >= 0) {
-                          client->connectStatus = HTTP_RECV_HDR;
+                        client->connectStatus = HTTP_RECV_HDR;
                         *pKeepGoing = PKIX_TRUE;
                 } else {
                         client->connectStatus = HTTP_SEND_PENDING;
                         *pKeepGoing = PKIX_FALSE;
                 }
 
         }
 
@@ -963,31 +972,38 @@ pkix_pl_HttpDefaultClient_RecvBody(
 
         PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_RecvBody");
         PKIX_NULLCHECK_TWO(client, pKeepGoing);
 
         callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
 
         PKIX_CHECK(callbackList->recvCallback
                 (client->socket,
-                client->rcvBuf,
+                (void *)&(client->rcvBuf[client->currentBytesAvailable]),
                 client->bytesToRead,
                 &bytesRead,
                 plContext),
                 "pkix_pl_Socket_Recv failed");
 
         if (bytesRead > 0) {
 
+		/* We got something. Did we get it all? */
                 client->currentBytesAvailable += bytesRead;
-                client->connectStatus = HTTP_COMPLETE;
-                *pKeepGoing = PKIX_FALSE;
+
+		if (client->bytesToRead > bytesRead) {
+                	client->bytesToRead -= bytesRead;
+			*pKeepGoing = PKIX_TRUE;
+		} else {
+	                client->connectStatus = HTTP_COMPLETE;
+	                *pKeepGoing = PKIX_FALSE;
+		}
 
         } else {
 
-                client->connectStatus = HTTP_RECV_HDR_PENDING;
+                client->connectStatus = HTTP_RECV_BODY_PENDING;
                 *pKeepGoing = PKIX_TRUE;
         }
 
 cleanup:
 
         PKIX_RETURN(HTTPDEFAULTCLIENT);
 }
 
@@ -1034,19 +1050,27 @@ pkix_pl_HttpDefaultClient_RecvBodyContin
 
         PKIX_CHECK(callbackList->pollCallback
                 (client->socket, NULL, &bytesRead, plContext),
                 "pkix_pl_Socket_Poll failed");
 
 
         if (bytesRead > 0) {
 
+		/* We got something. Did we get it all? */
                 client->currentBytesAvailable += bytesRead;
-                client->connectStatus = HTTP_COMPLETE;
+                client->bytesToRead -= bytesRead;
 
+		if (client->bytesToRead > 0) {
+                	client->connectStatus = HTTP_RECV_BODY;
+			*pKeepGoing = PKIX_TRUE;
+		} else {
+	                client->connectStatus = HTTP_COMPLETE;
+	                *pKeepGoing = PKIX_FALSE;
+		}
         }
 
         *pKeepGoing = PKIX_FALSE;
 
 cleanup:
 
         PKIX_RETURN(HTTPDEFAULTCLIENT);
 }
@@ -1249,26 +1273,24 @@ pkix_pl_HttpDefaultClient_RequestCreate(
                 /* We only know how to do POST and GET */
                 PKIX_ERROR("Unrecognized request method");
         }
 
         client->path = path_and_query_string;
 
         client->timeout = timeout;
 
-        /* create socket */
-        PKIX_CHECK(pkix_pl_Socket_CreateByHostAndPort
-                (PKIX_FALSE,       /* create a client, not a server */
-                timeout,
-                (char *)client->host,
-                client->portnum,
+	PKIX_CHECK(pkix_HttpCertStore_FindSocketConnection
+                (timeout,
+                "variation.red.iplanet.com", /* (char *)client->host, */
+                2001,   /* client->portnum, */
                 &status,
                 &socket,
                 plContext),
-                "pkix_pl_Socket_CreateByHostAndPort failed");
+		"pkix_HttpCertStore_FindSocketConnection failed");
 
         client->socket = socket;
 
         PKIX_CHECK(pkix_pl_Socket_GetCallbackList
                 (socket, &callbackList, plContext),
                 "pkix_pl_Socket_GetCallbackList failed");
 
         client->callbackList = (void *)callbackList;
@@ -1425,17 +1447,17 @@ pkix_pl_HttpDefaultClient_TrySendAndRece
                             "Content-Type: %s\r\nContent-Length: %u\r\n\r\n",
                             client->path,
                             client->host,
                             client->portnum,
                             client->send_http_content_type,
                             client->send_http_data_len));
 
                         PKIX_PL_NSSCALLRV
-                                       (HTTPDEFAULTCLIENT, postLen, PORT_Strlen,
+                                (HTTPDEFAULTCLIENT, postLen, PORT_Strlen,
                                 (sendbuf));
 
                         client->POSTLen = postLen + client->send_http_data_len;
 
                         /* allocate postBuffer big enough for header + data */
                         PKIX_CHECK(PKIX_PL_Malloc
                                 (client->POSTLen,
                                 (void **)&(client->POSTBuf),
@@ -1462,17 +1484,17 @@ pkix_pl_HttpDefaultClient_TrySendAndRece
                         /* PR_smprintf_free original header buffer */
                         PKIX_PL_NSSCALL
                                 (HTTPDEFAULTCLIENT, PR_smprintf_free,
                                 (sendbuf));
                         
                 } else if (client->send_http_method == HTTP_GET_METHOD) {
                         PKIX_PL_NSSCALLRV
                             (HTTPDEFAULTCLIENT, sendbuf, PR_smprintf,
-                            ("GET %s HTTP/1.0\r\nHost: %s:%d\r\n\r\n",
+                            ("GET %s HTTP/1.1\r\nHost: %s:%d\r\n\r\n",
                             client->path,
                             client->host,
                             client->portnum));
 
                         client->GETBuf = sendbuf;
 
                         PKIX_PL_NSSCALLRV
                                 (HTTPDEFAULTCLIENT, client->GETLen, PORT_Strlen,
@@ -1509,17 +1531,17 @@ pkix_pl_HttpDefaultClient_TrySendAndRece
                         }
 
                         *pPollDesc = NULL;
                         *pSECReturn = SECFailure;
                         break;
                 case HTTP_COMPLETE:
                         *(client->rcv_http_response_code) =
                                 client->responseCode;
-                        if (client->maxResponseLen != 0) {
+                        if (client->pRcv_http_data_len != NULL) {
                                 *http_response_data_len =
                                          client->rcv_http_data_len;
                         }
                         if (client->rcv_http_data != NULL) {
                                 *(client->rcv_http_data) = client->rcvBuf;
                         }
                         *pPollDesc = NULL;
                         *pSECReturn = SECSuccess;
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c
@@ -44,137 +44,42 @@
 /* We can't decode the length of a message without at least this many bytes */
 #define MINIMUM_MSG_LENGTH 5
 
 #include "pkix_pl_ldapcertstore.h"
 
 /* --Private-Ldap-CertStore-Database-Functions----------------------- */
 
 /*
- * FUNCTION: pkix_pl_ASN1CertStore_DecodeCert
+ * FUNCTION: pkix_pl_LdapCertStore_DecodeCrossCertPair
  * DESCRIPTION:
  *
- *  This function decodes a DER-encoded Certificate pointed to by "derCertItem",
- *  adding the resulting PKIX_PL_Cert, if the decoding was successful, to the
- *  List (possibly empty) pointed to by "certList".
+ *  This function decodes a DER-encoded CrossCertPair pointed to by
+ *  "responseList" and extracts and decodes the Certificates in that pair,
+ *  adding the resulting Certs, if the decoding was successful, to the List
+ *  (possibly empty) pointed to by "certList". If none of the objects
+ *  can be decoded into a Cert, the List is returned unchanged.
  *
  * PARAMETERS:
- *  "derCertItem"
- *      The address of the SECItem containing the DER-encoded Certificate. Must
- *      be non-NULL.
+ *  "derCCPItem"
+ *      The address of the SECItem containing the DER representation of the
+ *      CrossCertPair. Must be non-NULL.
  *  "certList"
- *      The address of the List to which the decoded Certificate is added. Must
- *      be non-NULL.
+ *      The address of the List to which the decoded Certs are added. May be
+ *      empty, but 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 CertStore 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_ASN1CertStore_DecodeCert(
-        SECItem *derCertItem,
-        PKIX_List *certList,
-        void *plContext)
-{
-        CERTCertificate *nssCert = NULL;
-        PKIX_PL_Cert *cert = NULL;
-
-        PKIX_ENTER(CERTSTORE, "pkix_pl_ASN1CertStore_DecodeCert");
-        PKIX_NULLCHECK_TWO(derCertItem, certList);
-
-        PKIX_PL_NSSCALLRV(CERTSTORE, nssCert, CERT_DecodeDERCertificate,
-                (derCertItem, PR_TRUE, NULL));
-
-        if (nssCert) {
-                PKIX_CHECK_ONLY_FATAL(pkix_pl_Cert_CreateWithNSSCert
-                        (nssCert, &cert, plContext),
-                        "pkix_pl_Cert_CreateWithNSSCert failed");
-
-                /* skip bad certs and append good ones */
-                if (!PKIX_ERROR_RECEIVED) {
-                        PKIX_CHECK(PKIX_List_AppendItem
-                                (certList, (PKIX_PL_Object *) cert, plContext),
-                                "PKIX_List_AppendItem failed");
-                }
-
-                PKIX_DECREF(cert);
-        }
-cleanup:
-
-        PKIX_DECREF(cert);
-
-        PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_ASN1CertStore_DecodeCrl
- * DESCRIPTION:
- *
- *  This function decodes a DER-encoded Certificate Revocation List pointed to
- *  by "derCrlItem", adding the resulting PKIX_PL_CRL, if the decoding was
- *  successful, to the List (possibly empty) pointed to by "crlList".
- *
- * PARAMETERS:
- *  "derCrlItem"
- *      The address of the SECItem containing the DER-encoded Certificate
- *      Revocation List. Must be non-NULL.
- *  "crlList"
- *      The address of the List to which the decoded CRL is added. 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 CertStore 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_ASN1CertStore_DecodeCrl(
-        SECItem *derCrlItem,
-        PKIX_List *crlList,
-        void *plContext)
-{
-        CERTSignedCrl *nssCrl = NULL;
-        PKIX_PL_CRL *crl = NULL;
-
-        PKIX_ENTER(CERTSTORE, "pkix_pl_ASN1CertStore_DecodeCrl");
-        PKIX_NULLCHECK_TWO(derCrlItem, crlList);
-
-        PKIX_PL_NSSCALLRV(CERTSTORE, nssCrl, CERT_DecodeDERCrl,
-                (NULL, derCrlItem, SEC_CRL_TYPE));
-
-        if (nssCrl) {
-                PKIX_CHECK_ONLY_FATAL(pkix_pl_CRL_CreateWithSignedCRL
-                        (nssCrl, &crl, plContext),
-                        "pkix_pl_CRL_CreateWithSignedCRL failed");
-    
-                /* skip bad crls and append good ones */
-                if (!PKIX_ERROR_RECEIVED) {
-                        PKIX_CHECK(PKIX_List_AppendItem
-                                (crlList, (PKIX_PL_Object *) crl, plContext),
-                                "PKIX_List_AppendItem failed");
-                }
-
-                PKIX_DECREF(crl);
-
-        }
-cleanup:
-
-        PKIX_DECREF(crl);
-
-        PKIX_RETURN(CERTSTORE);
-}
-
-PKIX_Error *
 pkix_pl_LdapCertStore_DecodeCrossCertPair(
         SECItem *derCCPItem,
         PKIX_List *certList,
         void *plContext)
 {
         LDAPCertPair certPair = {{ siBuffer, NULL, 0 }, { siBuffer, NULL, 0 }};
         CERTCertificate *nssCert = NULL;
         PKIX_PL_Cert *cert = NULL;
@@ -249,16 +154,17 @@ pkix_pl_LdapCertStore_DecodeCrossCertPai
 cleanup:
 
         PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena, (tempArena, PR_FALSE));
 
         PKIX_DECREF(cert);
 
         PKIX_RETURN(CERTSTORE);
 }
+
 /*
  * FUNCTION: pkix_pl_LdapCertStore_BuildCertList
  * DESCRIPTION:
  *
  *  This function takes a List of LdapResponse objects pointed to by
  *  "responseList" and extracts and decodes the Certificates in those responses,
  *  storing the List of those Certificates at "pCerts". If none of the objects
  *  can be decoded into a Cert, the returned List is empty.
@@ -332,19 +238,19 @@ pkix_pl_LdapCertStore_BuildCertList(
                         "pkix_pl_LdapRequest_AttrTypeToBit failed");
                     /* Is this attrVal a Certificate? */
                     if (((LDAPATTR_CACERT | LDAPATTR_USERCERT) &
                             attrBits) == attrBits) {
                         attrVal = sreAttr->val;
                         derCertItem = *attrVal++;
                         while (derCertItem != 0) {
                             /* create a PKIX_PL_Cert from derCert */
-                            PKIX_CHECK(pkix_pl_ASN1CertStore_DecodeCert
+                            PKIX_CHECK(pkix_pl_Cert_CreateToList
                                 (derCertItem, certList, plContext),
-                                "pkix_pl_ASN1CertStore_DecodeCert failed");
+                                "pkix_pl_Cert_CreateToList failed");
                             derCertItem = *attrVal++;
                         }
                     } else if ((LDAPATTR_CROSSPAIRCERT & attrBits) == attrBits){
                         /* Is this attrVal a CrossPairCertificate? */
                         attrVal = sreAttr->val;
                         derCertItem = *attrVal++;
                         while (derCertItem != 0) {
                             /* create PKIX_PL_Certs from derCert */
@@ -450,19 +356,19 @@ pkix_pl_LdapCertStore_BuildCrlList(
                         "pkix_pl_LdapRequest_AttrTypeToBit failed");
                     /* Is this attrVal a Revocation List? */
                     if (((LDAPATTR_CERTREVLIST | LDAPATTR_AUTHREVLIST) &
                             attrBits) == attrBits) {
                         attrVal = sreAttr->val;
                         derCrlItem = *attrVal++;
                         while (derCrlItem != 0) {
                             /* create a PKIX_PL_Crl from derCrl */
-                            PKIX_CHECK(pkix_pl_ASN1CertStore_DecodeCrl
+                            PKIX_CHECK(pkix_pl_CRL_CreateToList
                                 (derCrlItem, crlList, plContext),
-                                "pkix_pl_ASN1CertStore_DecodeCrl failed");
+                                "pkix_pl_CRL_CreateToList failed");
                             derCrlItem = *attrVal++;
                         }
                     }
                     sreAttr = *sreAttrArray++;
                 }
                 PKIX_DECREF(response);
         }
 
@@ -637,16 +543,17 @@ pkix_pl_LdapCertStore_MakeNameAVAList(
         *pList = setOfNameComponents;
 
 cleanup:
 
         PKIX_RETURN(CERTSTORE);
 
 }
 
+#if 0
 /*
  * FUNCTION: pkix_pl_LdapCertstore_ConvertCertResponses
  * DESCRIPTION:
  *
  *  This function processes the List of LDAPResponses pointed to by "responses"
  *  into a List of resulting Certs, storing the result at "pCerts". If there
  *  are no responses converted successfully, a NULL may be stored.
  *
@@ -684,16 +591,17 @@ pkix_pl_LdapCertStore_ConvertCertRespons
                 "pkix_pl_LdapCertStore_BuildCertList failed");
 
         *pCerts = unfiltered;
 
 cleanup:
 
         PKIX_RETURN(CERTSTORE);
 }
+#endif
 
 /*
  * FUNCTION: pkix_pl_LdapCertStore_GetCert
  *  (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
  */
 PKIX_Error *
 pkix_pl_LdapCertStore_GetCert(
         PKIX_CertStore *store,
@@ -830,19 +738,19 @@ pkix_pl_LdapCertStore_GetCert(
         }
         /* LdapClient has given us a response! */
 
         if (responses) {
                 PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
                         (store, &cacheFlag, plContext),
                         "PKIX_CertStore_GetCertStoreCacheFlag failed");
 
-                PKIX_CHECK(pkix_pl_LdapCertStore_ConvertCertResponses
+                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
                         (responses, &unfilteredCerts, plContext),
-                        "pkix_pl_LdapCertStore_ConvertCertResponses failed");
+                        "pkix_pl_LdapCertStore_BuildCertList failed");
 
                 PKIX_CHECK(pkix_CertSelector_Select
                         (selector, unfilteredCerts, &filteredCerts, plContext),
                         "pkix_CertSelector_Select failed");
         }
 
         *pNBIOContext = NULL;
         *pCertList = filteredCerts;
@@ -896,19 +804,19 @@ pkix_pl_LdapCertStore_GetCertContinue(
         }
         /* LdapClient has given us a response! */
 
         if (responses) {
                 PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
                         (store, &cacheFlag, plContext),
                         "PKIX_CertStore_GetCertStoreCacheFlag failed");
 
-                PKIX_CHECK(pkix_pl_LdapCertStore_ConvertCertResponses
+                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
                         (responses, &unfilteredCerts, plContext),
-                        "pkix_pl_LdapCertStore_ConvertCertResponses failed");
+                        "pkix_pl_LdapCertStore_BuildCertList failed");
 
                 PKIX_CHECK(pkix_CertSelector_Select
                         (selector, unfilteredCerts, &filteredCerts, plContext),
                         "pkix_CertSelector_Select failed");
         }
 
         *pNBIOContext = NULL;
         *pCertList = filteredCerts;
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h
@@ -90,30 +90,19 @@ typedef enum {
 struct PKIX_PL_LdapCertStoreContext {
         PKIX_PL_LdapClient *client;
 };
 
 /* see source file for function documentation */
 
 PKIX_Error *pkix_pl_LdapCertStoreContext_RegisterSelf(void *plContext);
 
-PKIX_Error *pkix_pl_LdapCertStore_ConvertCertResponses(
-        PKIX_List *responses,
-        PKIX_List **pCertList,
-        void *plContext);
-
 PKIX_Error *
-pkix_pl_ASN1CertStore_DecodeCert(
-        SECItem *derCertItem,
-        PKIX_List *certList,
-        void *plContext);
-
-PKIX_Error *
-pkix_pl_ASN1CertStore_DecodeCrl(
-        SECItem *derCrlItem,
-        PKIX_List *crlList,
+pkix_pl_LdapCertStore_BuildCertList(
+        PKIX_List *responseList,
+        PKIX_List **pCerts,
         void *plContext);
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* _PKIX_PL_LDAPCERTSTORE_H */
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c
@@ -2460,19 +2460,35 @@ cleanup:
         PKIX_RETURN(LDAPDEFAULTCLIENT);
 
 }
 
 /* --Public-LdapDefaultClient-Functions----------------------------------- */
 
 /*
  * FUNCTION: PKIX_PL_LdapDefaultClient_AbandonRequest
+ * DESCRIPTION:
+ *
+ *  This function creates and sends an LDAP-protocol "Abandon" message to the 
+ *  server connected to the LdapDefaultClient pointed to by "client".
+ *
+ * PARAMETERS:
+ *  "client"
+ *      The LdapDefaultClient whose connection is to be abandoned. 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 Fatal Error if the function fails in an unrecoverable way.
  */
 PKIX_Error *
-PKIX_PL_LdapCertStore_AbandonRequest(
+PKIX_PL_LdapDefaultClient_AbandonRequest(
         PKIX_PL_LdapDefaultClient *client,
         void *plContext)
 {
         PKIX_Int32 bytesWritten = 0;
         PKIX_PL_Socket_Callback *callbackList = NULL;
         SECItem *encoded = NULL;
 
         PKIX_ENTER(CERTSTORE, "PKIX_PL_LdapDefaultClient_AbandonRequest");
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
@@ -1509,16 +1509,78 @@ pkix_pl_Cert_CreateWithNSSCert(
 
         *pCert = cert;
 
 cleanup:
 
         PKIX_RETURN(CERT);
 }
 
+/*
+ * FUNCTION: pkix_pl_Cert_CreateToList
+ * DESCRIPTION:
+ *
+ *  Creates a new certificate using the DER-encoding pointed to by "derCertItem"
+ *  and appends it to the list pointed to by "certList". If Cert creation fails,
+ *  the function returns with certList unchanged, but any decoding Error is
+ *  discarded.
+ *
+ * PARAMETERS:
+ *  "derCertItem"
+ *      Address of SECItem containing the DER representation of a certificate.
+ *      Must be non-NULL.
+ *  "certList"
+ *      Address of List to which the Cert will be appended, if successfully
+ *      created. May be empty, but 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 Cert 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_Cert_CreateToList(
+        SECItem *derCertItem,
+        PKIX_List *certList,
+        void *plContext)
+{
+        CERTCertificate *nssCert = NULL;
+        PKIX_PL_Cert *cert = NULL;
+
+        PKIX_ENTER(CERT, "pkix_pl_Cert_CreateToList");
+        PKIX_NULLCHECK_TWO(derCertItem, certList);
+
+        PKIX_PL_NSSCALLRV(CERT, nssCert, CERT_DecodeDERCertificate,
+                (derCertItem, PR_TRUE, NULL));
+
+        if (nssCert) {
+                PKIX_CHECK_ONLY_FATAL(pkix_pl_Cert_CreateWithNSSCert
+                        (nssCert, &cert, plContext),
+                        "pkix_pl_Cert_CreateWithNSSCert failed");
+
+                /* skip bad certs and append good ones */
+                if (!PKIX_ERROR_RECEIVED) {
+                        PKIX_CHECK(PKIX_List_AppendItem
+                                (certList, (PKIX_PL_Object *) cert, plContext),
+                                "PKIX_List_AppendItem failed");
+                }
+
+                PKIX_DECREF(cert);
+        }
+
+cleanup:
+
+        PKIX_DECREF(cert);
+
+        PKIX_RETURN(CERT);
+}
+
 /* --Public-Functions------------------------------------------------------- */
 
 /*
  * FUNCTION: PKIX_PL_Cert_Create (see comments in pkix_pl_pki.h)
  * XXX We may want to cache the cert after parsing it, so it can be reused
  * XXX Are the NSS/NSPR functions thread safe
  */
 PKIX_Error *
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h
@@ -94,16 +94,22 @@ pkix_pl_Cert_RegisterSelf(void *plContex
 
 PKIX_Error *
 pkix_pl_Cert_CreateWithNSSCert(
         CERTCertificate *nssCert,
         PKIX_PL_Cert **pCert,
         void *plContext);
 
 PKIX_Error *
+pkix_pl_Cert_CreateToList(
+        SECItem *derCertItem,
+        PKIX_List *certList,
+        void *plContext);
+
+PKIX_Error *
 pkix_pl_Cert_CheckSubjectAltNameConstraints(
         PKIX_PL_Cert *cert,
         PKIX_PL_CertNameConstraints *nameConstraints,
         PKIX_Boolean matchAll,
         void *plContext);
 
 PKIX_Error *
 pkix_pl_Cert_ToString_Helper(
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
@@ -812,16 +812,77 @@ cleanup:
 
         if (PKIX_ERROR_RECEIVED){
                 PKIX_DECREF(crl);
         }
 
         PKIX_RETURN(CRL);
 }
 
+/*
+ * FUNCTION: pkix_pl_CRL_CreateToList
+ * DESCRIPTION:
+ *
+ *  This function decodes a DER-encoded Certificate Revocation List pointed to
+ *  by "derCrlItem", adding the resulting PKIX_PL_CRL, if the decoding was
+ *  successful, to the List (possibly empty) pointed to by "crlList".
+ *
+ * PARAMETERS:
+ *  "derCrlItem"
+ *      The address of the SECItem containing the DER-encoded Certificate
+ *      Revocation List. Must be non-NULL.
+ *  "crlList"
+ *      The address of the List to which the decoded CRL is added. May be
+ *      empty, but 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 CertStore 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_CRL_CreateToList(
+        SECItem *derCrlItem,
+        PKIX_List *crlList,
+        void *plContext)
+{
+        CERTSignedCrl *nssCrl = NULL;
+        PKIX_PL_CRL *crl = NULL;
+
+        PKIX_ENTER(CRL, "pkix_pl_CRL_CreateToList");
+        PKIX_NULLCHECK_TWO(derCrlItem, crlList);
+
+        PKIX_PL_NSSCALLRV(CRL, nssCrl, CERT_DecodeDERCrl,
+                (NULL, derCrlItem, SEC_CRL_TYPE));
+
+        if (nssCrl) {
+                PKIX_CHECK_ONLY_FATAL(pkix_pl_CRL_CreateWithSignedCRL
+                        (nssCrl, &crl, plContext),
+                        "pkix_pl_CRL_CreateWithSignedCRL failed");
+
+                /* skip bad crls and append good ones */
+                if (!PKIX_ERROR_RECEIVED) {
+                        PKIX_CHECK(PKIX_List_AppendItem
+                                (crlList, (PKIX_PL_Object *) crl, plContext),
+                                "PKIX_List_AppendItem failed");
+                }
+
+                PKIX_DECREF(crl);
+
+        }
+cleanup:
+
+        PKIX_DECREF(crl);
+
+        PKIX_RETURN(CRL);
+}
+
 /* --Public-CRL-Functions------------------------------------- */
 
 /*
  * FUNCTION: PKIX_PL_CRL_Create (see comments in pkix_pl_pki.h)
  */
 PKIX_Error *
 PKIX_PL_CRL_Create(
         PKIX_PL_ByteArray *byteArray,
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h
@@ -65,13 +65,19 @@ struct PKIX_PL_CRLStruct {
 PKIX_Error *pkix_pl_CRL_RegisterSelf(void *plContext);
 
 PKIX_Error *
 pkix_pl_CRL_CreateWithSignedCRL(
         CERTSignedCrl *nssSignedCrl,
         PKIX_PL_CRL **pCrl,
         void *plContext);
 
+PKIX_Error *
+pkix_pl_CRL_CreateToList(
+        SECItem *derCrlItem,
+        PKIX_List *crlList,
+        void *plContext);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* _PKIX_PL_CRL_H */
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h
@@ -94,16 +94,18 @@
 #include "pkix_pl_ocsprequest.h"
 #include "pkix_pl_ocspresponse.h"
 #include "pkix_pl_pk11certstore.h"
 #include "pkix_pl_socket.h"
 #include "pkix_pl_ldapcertstore.h"
 #include "pkix_pl_ldaprequest.h"
 #include "pkix_pl_ldapresponse.h"
 #include "pkix_pl_nsscontext.h"
+#include "pkix_pl_httpcertstore.h"
+#include "pkix_pl_httpdefaultclient.h"
 #include "pkix_pl_infoaccess.h"
 #include "pkix_sample_modules.h"
 
 #define MAX_DIGITS_32 (PKIX_UInt32) 10
 
 #define PKIX_PL_NSSCALL(type, func, args)  \
         PKIX_ ## type ## _DEBUG_ARG("( Calling %s).\n", #func); \
         (func args)
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
@@ -180,27 +180,27 @@ PKIX_PL_Initialize(
         pkix_Logger_RegisterSelf(plContext);
         (void) pkix_pl_Mutex_RegisterSelf(plContext);
         (void) pkix_pl_OID_RegisterSelf(plContext);
         (void) pkix_pl_RWLock_RegisterSelf(plContext);
         /* already registered! pkix_pl_String_RegisterSelf(plContext); */
 
         pkix_pl_CertBasicConstraints_RegisterSelf(plContext); /* 11-20 */
         pkix_pl_Cert_RegisterSelf(plContext);
-        /* pkix_NoLongerUsed_RegisterSelf(plContext); */
+        /* pkix_HttpClient_RegisterSelf(plContext); */
         pkix_pl_CRL_RegisterSelf(plContext);
         pkix_pl_CRLEntry_RegisterSelf(plContext);
         pkix_pl_Date_RegisterSelf(plContext);
         pkix_pl_GeneralName_RegisterSelf(plContext);
         pkix_pl_CertNameConstraints_RegisterSelf(plContext);
         pkix_pl_PublicKey_RegisterSelf(plContext);
         pkix_TrustAnchor_RegisterSelf(plContext);
 
         pkix_pl_X500Name_RegisterSelf(plContext);   /* 21-30 */
-        /* pkix_NoLongerUsed_RegisterSelf(plContext); */
+        pkix_pl_HttpCertStoreContext_RegisterSelf(plContext);
         pkix_BuildResult_RegisterSelf(plContext);
         pkix_ProcessingParams_RegisterSelf(plContext);
         pkix_ValidateParams_RegisterSelf(plContext);
         pkix_ValidateResult_RegisterSelf(plContext);
         pkix_CertStore_RegisterSelf(plContext);
         pkix_CertChainChecker_RegisterSelf(plContext);
         pkix_RevocationChecker_RegisterSelf(plContext);
         pkix_CertSelector_RegisterSelf(plContext);
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
@@ -96,16 +96,17 @@
 #include "pkix_buildresult.h"
 #include "pkix_build.h"
 #include "pkix_pl_nameconstraints.h"
 #include "pkix_nameconstraintschecker.h"
 #include "pkix_ocspchecker.h"
 #include "pkix_pl_ocsprequest.h"
 #include "pkix_pl_ocspresponse.h"
 #include "pkix_pl_httpdefaultclient.h"
+#include "pkix_pl_httpcertstore.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct PKIX_PL_InitializeParamsStruct {
         PKIX_List *loggers;
         PKIX_UInt32 majorVersion;
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -92,16 +92,17 @@ CERT_ImportCAChain;
 CERT_NameToAscii;
 CERT_RFC1485_EscapeAndQuote;
 CERT_SetSlopTime;
 CERT_VerifyCertName;
 CERT_VerifyCertNow;
 DER_UTCDayToAscii;
 DER_UTCTimeToAscii;
 DER_GeneralizedTimeToTime;
+GetRegisteredHttpClient;
 NSS_Init;
 NSS_Initialize;
 NSS_InitReadWrite;
 NSS_NoDB_Init;
 NSS_Shutdown;
 NSS_VersionCheck;
 PK11_Authenticate;
 PK11_ChangePW;
@@ -1033,16 +1034,18 @@ pkix_pl_Date_GetPRTime;
 PKIX_PL_EkuChecker_Initialize;
 PKIX_PL_Free;
 PKIX_PL_GeneralName_Create;
 PKIX_PL_GetString;
 PKIX_PL_HashTable_Add;
 PKIX_PL_HashTable_Create;
 PKIX_PL_HashTable_Lookup;
 PKIX_PL_HashTable_Remove;
+PKIX_PL_HttpCertStore_Create;
+pkix_pl_HttpCertStore_CreateWithAsciiName;
 PKIX_PL_Initialize;
 PKIX_PL_InfoAccess_GetMethod;
 PKIX_PL_InfoAccess_GetLocation;
 PKIX_PL_InfoAccess_GetLocationType;
 PKIX_PL_LdapCertStore_AbandonRequest;
 PKIX_PL_LdapCertStore_Create;
 PKIX_PL_LdapClient_InitiateRequest;
 PKIX_PL_LdapClient_ResumeRequest;