import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,48 @@
#! gmake
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################
include manifest.mn
#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
include config.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
export:: private_export

View file

@ -0,0 +1,35 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Override TARGETS variable so that only static libraries
# are specifed as dependencies within rules.mk.
#
TARGETS = $(LIBRARY)
SHARED_LIBRARY =
IMPORT_LIBRARY =
PROGRAM =
ifdef NSS_PKIX_NO_LDAP
LDAP_HEADERS =
LDAP_CSRCS =
else
LDAP_HEADERS = \
pkix_pl_ldapt.h \
pkix_pl_ldapcertstore.h \
pkix_pl_ldapresponse.h \
pkix_pl_ldaprequest.h \
pkix_pl_ldapdefaultclient.h \
$(NULL)
LDAP_CSRCS = \
pkix_pl_ldaptemplates.c \
pkix_pl_ldapcertstore.c \
pkix_pl_ldapresponse.c \
pkix_pl_ldaprequest.c \
pkix_pl_ldapdefaultclient.c \
$(NULL)
endif

View file

@ -0,0 +1,36 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
{
'includes': [
'../../../../coreconf/config.gypi'
],
'targets': [
{
'target_name': 'lib_libpkix_pkix_pl_nss_module_exports',
'type': 'none',
'copies': [
{
'files': [
'pkix_pl_aiamgr.h',
'pkix_pl_colcertstore.h',
'pkix_pl_httpcertstore.h',
'pkix_pl_httpdefaultclient.h',
'pkix_pl_ldapcertstore.h',
'pkix_pl_ldapdefaultclient.h',
'pkix_pl_ldaprequest.h',
'pkix_pl_ldapresponse.h',
'pkix_pl_ldapt.h',
'pkix_pl_nsscontext.h',
'pkix_pl_pk11certstore.h',
'pkix_pl_socket.h'
],
'destination': '<(nss_private_dist_dir)/<(module)'
}
]
}
],
'variables': {
'module': 'nss'
}
}

View file

@ -0,0 +1,38 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
CORE_DEPTH = ../../../..
EXPORTS = \
$(NULL)
PRIVATE_EXPORTS = \
pkix_pl_aiamgr.h \
pkix_pl_colcertstore.h \
pkix_pl_httpcertstore.h \
pkix_pl_httpdefaultclient.h \
$(LDAP_HEADERS) \
pkix_pl_nsscontext.h \
pkix_pl_pk11certstore.h \
pkix_pl_socket.h \
$(NULL)
MODULE = nss
DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\"
CSRCS = \
pkix_pl_aiamgr.c \
pkix_pl_colcertstore.c \
pkix_pl_httpcertstore.c \
pkix_pl_httpdefaultclient.c \
$(LDAP_CSRCS) \
pkix_pl_nsscontext.c \
pkix_pl_pk11certstore.c \
pkix_pl_socket.c \
$(NULL)
LIBRARY_NAME = pkixmodule

View file

@ -0,0 +1,41 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
{
'includes': [
'../../../../coreconf/config.gypi'
],
'targets': [
{
'target_name': 'pkixmodule',
'type': 'static_library',
'sources': [
'pkix_pl_aiamgr.c',
'pkix_pl_colcertstore.c',
'pkix_pl_httpcertstore.c',
'pkix_pl_httpdefaultclient.c',
'pkix_pl_ldapcertstore.c',
'pkix_pl_ldapdefaultclient.c',
'pkix_pl_ldaprequest.c',
'pkix_pl_ldapresponse.c',
'pkix_pl_ldaptemplates.c',
'pkix_pl_nsscontext.c',
'pkix_pl_pk11certstore.c',
'pkix_pl_socket.c'
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports'
]
}
],
'target_defaults': {
'defines': [
'SHLIB_SUFFIX=\"<(dll_suffix)\"',
'SHLIB_PREFIX=\"<(dll_prefix)\"',
'SHLIB_VERSION=\"\"'
]
},
'variables': {
'module': 'nss'
}
}

View file

@ -0,0 +1,699 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_aiamgr.c
*
* AIAMgr Object Definitions
*
*/
#include "pkix_pl_aiamgr.h"
extern PKIX_PL_HashTable *aiaConnectionCache;
#ifndef NSS_PKIX_NO_LDAP
/* --Virtual-LdapClient-Functions------------------------------------ */
PKIX_Error *
PKIX_PL_LdapClient_InitiateRequest(
PKIX_PL_LdapClient *client,
LDAPRequestParams *requestParams,
void **pNBIO,
PKIX_List **pResponse,
void *plContext)
{
PKIX_ENTER(LDAPCLIENT, "PKIX_PL_LdapClient_InitiateRequest");
PKIX_NULLCHECK_TWO(client, client->initiateFcn);
PKIX_CHECK(client->initiateFcn
(client, requestParams, pNBIO, pResponse, plContext),
PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
cleanup:
PKIX_RETURN(LDAPCLIENT);
}
PKIX_Error *
PKIX_PL_LdapClient_ResumeRequest(
PKIX_PL_LdapClient *client,
void **pNBIO,
PKIX_List **pResponse,
void *plContext)
{
PKIX_ENTER(LDAPCLIENT, "PKIX_PL_LdapClient_ResumeRequest");
PKIX_NULLCHECK_TWO(client, client->resumeFcn);
PKIX_CHECK(client->resumeFcn
(client, pNBIO, pResponse, plContext),
PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
cleanup:
PKIX_RETURN(LDAPCLIENT);
}
#endif /* !NSS_PKIX_NO_LDAP */
/* --Private-AIAMgr-Functions----------------------------------*/
/*
* FUNCTION: pkix_pl_AIAMgr_Destroy
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_pki.h)
*/
static PKIX_Error *
pkix_pl_AIAMgr_Destroy(
PKIX_PL_Object *object,
void *plContext)
{
PKIX_PL_AIAMgr *aiaMgr = NULL;
PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_Destroy");
PKIX_NULLCHECK_ONE(object);
PKIX_CHECK(pkix_CheckType(object, PKIX_AIAMGR_TYPE, plContext),
PKIX_OBJECTNOTAIAMGR);
aiaMgr = (PKIX_PL_AIAMgr *)object;
/* 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);
#ifndef NSS_PKIX_NO_LDAP
PKIX_DECREF(aiaMgr->client.ldapClient);
#endif
cleanup:
PKIX_RETURN(AIAMGR);
}
/*
* FUNCTION: pkix_pl_AIAMgr_RegisterSelf
* DESCRIPTION:
* Registers PKIX_AIAMGR_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_AIAMgr_RegisterSelf(void *plContext)
{
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
pkix_ClassTable_Entry *entry = &systemClasses[PKIX_AIAMGR_TYPE];
PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_RegisterSelf");
entry->description = "AIAMgr";
entry->typeObjectSize = sizeof(PKIX_PL_AIAMgr);
entry->destructor = pkix_pl_AIAMgr_Destroy;
PKIX_RETURN(AIAMGR);
}
#ifndef NSS_PKIX_NO_LDAP
/*
* 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
* collection, and then stored at "pClient".
*
* PARAMETERS:
* "aiaMgr"
* The AIAMgr whose LDAPClient connected are to be managed. Must be
* non-NULL.
* "domainName"
* Address of a string pointing to a server name. Must be non-NULL.
* An empty string (which means no <host> is given in the LDAP URL) is
* not supported.
* "pClient"
* Address at which the returned LDAPClient 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_FindLDAPClient(
PKIX_PL_AIAMgr *aiaMgr,
char *domainName,
PKIX_PL_LdapClient **pClient,
void *plContext)
{
PKIX_PL_String *domainString = NULL;
PKIX_PL_LdapDefaultClient *client = NULL;
PKIX_ENTER(AIAMGR, "pkix_pl_AiaMgr_FindLDAPClient");
PKIX_NULLCHECK_THREE(aiaMgr, domainName, pClient);
/*
* An LDAP URL may not have a <host> part, for example,
* ldap:///o=University%20of%20Michigan,c=US
* PKIX_PL_LdapDefaultClient doesn't know how to discover the default
* LDAP server, so we don't support this kind of LDAP URL.
*/
if (*domainName == '\0') {
/* Simulate a PKIX_PL_LdapDefaultClient_CreateByName failure. */
PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED);
}
/* create PKIX_PL_String from domain name */
PKIX_CHECK(PKIX_PL_String_Create
(PKIX_ESCASCII, domainName, 0, &domainString, plContext),
PKIX_STRINGCREATEFAILED);
/* Is this domainName already in cache? */
PKIX_CHECK(PKIX_PL_HashTable_Lookup
(aiaConnectionCache,
(PKIX_PL_Object *)domainString,
(PKIX_PL_Object **)&client,
plContext),
PKIX_HASHTABLELOOKUPFAILED);
if (client == NULL) {
/* No, create a connection (and cache it) */
PKIX_CHECK(PKIX_PL_LdapDefaultClient_CreateByName
(domainName,
/* Do not use NBIO until we verify, that
* it is working. For now use 1 min timeout. */
PR_SecondsToInterval(
((PKIX_PL_NssContext*)plContext)->timeoutSeconds),
NULL,
&client,
plContext),
PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED);
PKIX_CHECK(PKIX_PL_HashTable_Add
(aiaConnectionCache,
(PKIX_PL_Object *)domainString,
(PKIX_PL_Object *)client,
plContext),
PKIX_HASHTABLEADDFAILED);
}
*pClient = (PKIX_PL_LdapClient *)client;
cleanup:
PKIX_DECREF(domainString);
PKIX_RETURN(AIAMGR);
}
#endif /* !NSS_PKIX_NO_LDAP */
PKIX_Error *
pkix_pl_AIAMgr_GetHTTPCerts(
PKIX_PL_AIAMgr *aiaMgr,
PKIX_PL_InfoAccess *ia,
void **pNBIOContext,
PKIX_List **pCerts,
void *plContext)
{
PKIX_PL_GeneralName *location = NULL;
PKIX_PL_String *locationString = NULL;
PKIX_UInt32 len = 0;
PRUint16 port = 0;
const SEC_HttpClientFcn *httpClient = NULL;
const SEC_HttpClientFcnV1 *hcv1 = NULL;
SECStatus rv = SECFailure;
SEC_HTTP_SERVER_SESSION serverSession = NULL;
SEC_HTTP_REQUEST_SESSION requestSession = NULL;
char *path = NULL;
char *hostname = NULL;
char *locationAscii = NULL;
void *nbio = NULL;
PRUint16 responseCode = 0;
const char *responseContentType = NULL;
const char *responseData = NULL;
PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetHTTPCerts");
PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts);
nbio = *pNBIOContext;
*pNBIOContext = NULL;
*pCerts = NULL;
if (nbio == NULL) { /* a new request */
PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation
(ia, &location, plContext),
PKIX_INFOACCESSGETLOCATIONFAILED);
/* find or create httpClient = default client */
httpClient = SEC_GetRegisteredHttpClient();
aiaMgr->client.hdata.httpClient = httpClient;
if (!httpClient)
PKIX_ERROR(PKIX_OUTOFMEMORY);
if (httpClient->version == 1) {
PKIX_UInt32 timeout =
((PKIX_PL_NssContext*)plContext)->timeoutSeconds;
hcv1 = &(httpClient->fcnTable.ftable1);
/* create server session */
PKIX_TOSTRING(location, &locationString, plContext,
PKIX_GENERALNAMETOSTRINGFAILED);
PKIX_CHECK(PKIX_PL_String_GetEncoded
(locationString,
PKIX_ESCASCII,
(void **)&locationAscii,
&len,
plContext),
PKIX_STRINGGETENCODEDFAILED);
rv = CERT_ParseURL(locationAscii, &hostname, &port,
&path);
if ((rv != SECSuccess) ||
(hostname == NULL) ||
(path == NULL)) {
PKIX_ERROR(PKIX_URLPARSINGFAILED);
}
rv = (*hcv1->createSessionFcn)(hostname, port,
&serverSession);
if (rv != SECSuccess) {
PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED);
}
aiaMgr->client.hdata.serverSession = serverSession;
/* create request session */
rv = (*hcv1->createFcn)(serverSession, "http", path,
"GET", PR_SecondsToInterval(timeout),
&requestSession);
if (rv != SECSuccess) {
PKIX_ERROR(PKIX_HTTPSERVERERROR);
}
aiaMgr->client.hdata.requestSession = requestSession;
} else {
PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
}
}
httpClient = aiaMgr->client.hdata.httpClient;
if (httpClient->version == 1) {
PRUint32 responseDataLen =
((PKIX_PL_NssContext*)plContext)->maxResponseLength;
hcv1 = &(httpClient->fcnTable.ftable1);
requestSession = aiaMgr->client.hdata.requestSession;
/* trySendAndReceive */
rv = (*hcv1->trySendAndReceiveFcn)(requestSession,
(PRPollDesc **)&nbio,
&responseCode,
(const char **)&responseContentType,
NULL, /* &responseHeaders */
(const char **)&responseData,
&responseDataLen);
if (rv != SECSuccess) {
PKIX_ERROR(PKIX_HTTPSERVERERROR);
}
if (nbio != 0) {
*pNBIOContext = nbio;
goto cleanup;
}
PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
(responseCode,
responseContentType,
responseData,
responseDataLen,
pCerts,
plContext),
PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
/* Session and request cleanup in case of success */
if (aiaMgr->client.hdata.requestSession != NULL) {
(*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
aiaMgr->client.hdata.requestSession = NULL;
}
if (aiaMgr->client.hdata.serverSession != NULL) {
(*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession);
aiaMgr->client.hdata.serverSession = NULL;
}
aiaMgr->client.hdata.httpClient = 0; /* callback fn */
} else {
PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
}
cleanup:
/* Session and request cleanup in case of error. Passing through without cleanup
* if interrupted by blocked IO. */
if (PKIX_ERROR_RECEIVED) {
if (aiaMgr->client.hdata.requestSession != NULL) {
(*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
aiaMgr->client.hdata.requestSession = NULL;
}
if (aiaMgr->client.hdata.serverSession != NULL) {
(*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession);
aiaMgr->client.hdata.serverSession = NULL;
}
aiaMgr->client.hdata.httpClient = 0; /* callback fn */
}
PKIX_DECREF(location);
PKIX_DECREF(locationString);
if (locationAscii) {
PORT_Free(locationAscii);
}
if (hostname) {
PORT_Free(hostname);
}
if (path) {
PORT_Free(path);
}
PKIX_RETURN(AIAMGR);
}
#ifndef NSS_PKIX_NO_LDAP
PKIX_Error *
pkix_pl_AIAMgr_GetLDAPCerts(
PKIX_PL_AIAMgr *aiaMgr,
PKIX_PL_InfoAccess *ia,
void **pNBIOContext,
PKIX_List **pCerts,
void *plContext)
{
PKIX_List *result = NULL;
PKIX_PL_GeneralName *location = NULL;
PKIX_PL_LdapClient *client = NULL;
LDAPRequestParams request;
PLArenaPool *arena = NULL;
char *domainName = NULL;
void *nbio = NULL;
PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetLDAPCerts");
PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts);
nbio = *pNBIOContext;
*pNBIOContext = NULL;
*pCerts = NULL;
if (nbio == NULL) { /* a new request */
/* Initiate an LDAP request */
request.scope = WHOLE_SUBTREE;
request.derefAliases = NEVER_DEREF;
request.sizeLimit = 0;
request.timeLimit = 0;
PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation
(ia, &location, plContext),
PKIX_INFOACCESSGETLOCATIONFAILED);
/*
* Get a short-lived arena. We'll be done with
* this space once the request is encoded.
*/
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
}
PKIX_CHECK(pkix_pl_InfoAccess_ParseLocation
(location, arena, &request, &domainName, plContext),
PKIX_INFOACCESSPARSELOCATIONFAILED);
PKIX_DECREF(location);
/* Find or create a connection to LDAP server */
PKIX_CHECK(pkix_pl_AiaMgr_FindLDAPClient
(aiaMgr, domainName, &client, plContext),
PKIX_AIAMGRFINDLDAPCLIENTFAILED);
aiaMgr->client.ldapClient = client;
PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
(aiaMgr->client.ldapClient,
&request,
&nbio,
&result,
plContext),
PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE));
} else {
PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
(aiaMgr->client.ldapClient, &nbio, &result, plContext),
PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
}
if (nbio != NULL) { /* WOULDBLOCK */
*pNBIOContext = nbio;
*pCerts = NULL;
goto cleanup;
}
PKIX_DECREF(aiaMgr->client.ldapClient);
if (result == NULL) {
*pCerts = NULL;
} else {
PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
(result, pCerts, plContext),
PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
}
*pNBIOContext = nbio;
cleanup:
if (arena && (PKIX_ERROR_RECEIVED)) {
PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE));
}
if (PKIX_ERROR_RECEIVED) {
PKIX_DECREF(aiaMgr->client.ldapClient);
}
PKIX_DECREF(location);
PKIX_RETURN(AIAMGR);
}
#endif /* !NSS_PKIX_NO_LDAP */
/*
* FUNCTION: PKIX_PL_AIAMgr_Create
* DESCRIPTION:
*
* This function creates an AIAMgr, storing the result at "pAIAMgr".
*
* PARAMETERS:
* "pAIAMGR"
* Address at which the returned AIAMgr 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.
*/
PKIX_Error *
PKIX_PL_AIAMgr_Create(
PKIX_PL_AIAMgr **pAIAMgr,
void *plContext)
{
PKIX_PL_AIAMgr *aiaMgr = NULL;
PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_Create");
PKIX_NULLCHECK_ONE(pAIAMgr);
PKIX_CHECK(PKIX_PL_Object_Alloc
(PKIX_AIAMGR_TYPE,
sizeof(PKIX_PL_AIAMgr),
(PKIX_PL_Object **)&aiaMgr,
plContext),
PKIX_COULDNOTCREATEAIAMGROBJECT);
/* 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.hdata.httpClient = NULL;
aiaMgr->client.hdata.serverSession = NULL;
aiaMgr->client.hdata.requestSession = NULL;
*pAIAMgr = aiaMgr;
cleanup:
PKIX_RETURN(AIAMGR);
}
/* --Public-Functions------------------------------------------------------- */
/*
* FUNCTION: PKIX_PL_AIAMgr_GetAIACerts (see description in pkix_pl_pki.h)
*/
PKIX_Error *
PKIX_PL_AIAMgr_GetAIACerts(
PKIX_PL_AIAMgr *aiaMgr,
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 *certs = NULL;
PKIX_PL_InfoAccess *ia = NULL;
void *nbio = NULL;
PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_GetAIACerts");
PKIX_NULLCHECK_FOUR(aiaMgr, prevCert, pNBIOContext, pCerts);
nbio = *pNBIOContext;
*pCerts = NULL;
*pNBIOContext = NULL;
if (nbio == NULL) { /* a new request */
/* Does this Cert have an AIA extension? */
PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess
(prevCert, &aiaMgr->aia, plContext),
PKIX_CERTGETAUTHORITYINFOACCESSFAILED);
if (aiaMgr->aia != NULL) {
PKIX_CHECK(PKIX_List_GetLength
(aiaMgr->aia, &numAias, plContext),
PKIX_LISTGETLENGTHFAILED);
}
/* And if so, does it have any entries? */
if ((aiaMgr->aia == NULL) || (numAias == 0)) {
*pCerts = NULL;
goto cleanup;
}
aiaMgr->aiaIndex = 0;
aiaMgr->numAias = numAias;
aiaMgr->results = NULL;
}
for (aiaIndex = aiaMgr->aiaIndex;
aiaIndex < aiaMgr->numAias;
aiaIndex ++) {
PKIX_UInt32 method = 0;
PKIX_CHECK(PKIX_List_GetItem
(aiaMgr->aia,
aiaIndex,
(PKIX_PL_Object **)&ia,
plContext),
PKIX_LISTGETITEMFAILED);
PKIX_CHECK(PKIX_PL_InfoAccess_GetMethod
(ia, &method, plContext),
PKIX_INFOACCESSGETMETHODFAILED);
if (method != PKIX_INFOACCESS_CA_ISSUERS &&
method != PKIX_INFOACCESS_CA_REPOSITORY) {
PKIX_DECREF(ia);
continue;
}
PKIX_CHECK(PKIX_PL_InfoAccess_GetLocationType
(ia, &iaType, plContext),
PKIX_INFOACCESSGETLOCATIONTYPEFAILED);
if (iaType == PKIX_INFOACCESS_LOCATION_HTTP) {
PKIX_CHECK(pkix_pl_AIAMgr_GetHTTPCerts
(aiaMgr, ia, &nbio, &certs, plContext),
PKIX_AIAMGRGETHTTPCERTSFAILED);
#ifndef NSS_PKIX_NO_LDAP
} else if (iaType == PKIX_INFOACCESS_LOCATION_LDAP) {
PKIX_CHECK(pkix_pl_AIAMgr_GetLDAPCerts
(aiaMgr, ia, &nbio, &certs, plContext),
PKIX_AIAMGRGETLDAPCERTSFAILED);
#endif
} else {
/* We only support http and ldap requests. */
PKIX_DECREF(ia);
continue;
}
if (nbio != NULL) { /* WOULDBLOCK */
aiaMgr->aiaIndex = aiaIndex;
*pNBIOContext = nbio;
*pCerts = NULL;
goto cleanup;
}
/*
* We can't just use and modify the List we received.
* Because it's cached, it's set immutable.
*/
if (aiaMgr->results == NULL) {
PKIX_CHECK(PKIX_List_Create
(&(aiaMgr->results), plContext),
PKIX_LISTCREATEFAILED);
}
PKIX_CHECK(pkix_List_AppendList
(aiaMgr->results, certs, plContext),
PKIX_APPENDLISTFAILED);
PKIX_DECREF(certs);
PKIX_DECREF(ia);
}
PKIX_DECREF(aiaMgr->aia);
*pNBIOContext = NULL;
*pCerts = aiaMgr->results;
aiaMgr->results = NULL;
cleanup:
if (PKIX_ERROR_RECEIVED) {
PKIX_DECREF(aiaMgr->aia);
PKIX_DECREF(aiaMgr->results);
#ifndef NSS_PKIX_NO_LDAP
PKIX_DECREF(aiaMgr->client.ldapClient);
#endif
}
PKIX_DECREF(certs);
PKIX_DECREF(ia);
PKIX_RETURN(AIAMGR);
}

View file

@ -0,0 +1,65 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_aiamgr.h
*
* AIAMgr Object Definitions
*
*/
#ifndef _PKIX_PL_AIAMGR_H
#define _PKIX_PL_AIAMGR_H
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
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;
union {
#ifndef NSS_PKIX_NO_LDAP
PKIX_PL_LdapClient *ldapClient;
#endif
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);
#ifndef NSS_PKIX_NO_LDAP
PKIX_Error *PKIX_PL_LdapClient_InitiateRequest(
PKIX_PL_LdapClient *client,
LDAPRequestParams *requestParams,
void **pPollDesc,
PKIX_List **pResponse,
void *plContext);
PKIX_Error *PKIX_PL_LdapClient_ResumeRequest(
PKIX_PL_LdapClient *client,
void **pPollDesc,
PKIX_List **pResponse,
void *plContext);
#endif /* !NSS_PKIX_NO_LDAP */
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_AIAMGR_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_colcertstore.h
*
* CollectionCertstore Object Type Definition
*
*/
#ifndef _PKIX_PL_COLCERTSTORE_H
#define _PKIX_PL_COLCERTSTORE_H
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
struct PKIX_PL_CollectionCertStoreContext {
PKIX_PL_String *storeDir;
PKIX_List *crlList;
PKIX_List *certList;
};
/* see source file for function documentation */
PKIX_Error *pkix_pl_CollectionCertStoreContext_RegisterSelf(void *plContext);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_COLCERTSTORE_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,62 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_httpcertstore.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
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);
void pkix_pl_HttpCertStore_Shutdown(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 */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,139 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_httpdefaultclient.h
*
* HTTPDefaultClient Object Type Definition
*
*/
#ifndef _PKIX_PL_HTTPDEFAULTCLIENT_H
#define _PKIX_PL_HTTPDEFAULTCLIENT_H
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#define HTTP_DATA_BUFSIZE 4096
#define HTTP_HEADER_BUFSIZE 1024
#define HTTP_MIN_AVAILABLE_BUFFER_SIZE 512
typedef enum {
HTTP_NOT_CONNECTED,
HTTP_CONNECT_PENDING,
HTTP_CONNECTED,
HTTP_SEND_PENDING,
HTTP_RECV_HDR,
HTTP_RECV_HDR_PENDING,
HTTP_RECV_BODY,
HTTP_RECV_BODY_PENDING,
HTTP_COMPLETE,
HTTP_ERROR
} HttpConnectStatus;
typedef enum {
HTTP_POST_METHOD,
HTTP_GET_METHOD
} HttpMethod;
struct PKIX_PL_HttpDefaultClientStruct {
HttpConnectStatus connectStatus;
PRUint16 portnum;
PRIntervalTime timeout;
PKIX_UInt32 bytesToWrite;
PKIX_UInt32 send_http_data_len;
PKIX_UInt32 rcv_http_data_len;
PKIX_UInt32 capacity;
PKIX_UInt32 filledupBytes;
PKIX_UInt32 responseCode;
PKIX_UInt32 maxResponseLen;
PKIX_UInt32 GETLen;
PKIX_UInt32 POSTLen;
PRUint32 *pRcv_http_data_len;
PRPollDesc pollDesc;
void *callbackList; /* cast this to (PKIX_PL_Socket_Callback *) */
char *GETBuf;
char *POSTBuf;
char *rcvBuf;
char *host;
char *path;
char *rcvContentType;
void *rcvHeaders;
HttpMethod send_http_method;
const char *send_http_content_type;
const char *send_http_data;
PRUint16 *rcv_http_response_code;
const char **rcv_http_content_type;
const char **rcv_http_headers;
const char **rcv_http_data;
PKIX_PL_Socket *socket;
void *plContext;
};
/* see source file for function documentation */
PKIX_Error *pkix_pl_HttpDefaultClient_RegisterSelf(void *plContext);
SECStatus
pkix_pl_HttpDefaultClient_CreateSessionFcn(
const char *host,
PRUint16 portnum,
SEC_HTTP_SERVER_SESSION *pSession);
SECStatus
pkix_pl_HttpDefaultClient_KeepAliveSessionFcn(
SEC_HTTP_SERVER_SESSION session,
PRPollDesc **pPollDesc);
SECStatus
pkix_pl_HttpDefaultClient_FreeSessionFcn(
SEC_HTTP_SERVER_SESSION session);
SECStatus
pkix_pl_HttpDefaultClient_RequestCreateFcn(
SEC_HTTP_SERVER_SESSION session,
const char *http_protocol_variant, /* usually "http" */
const char *path_and_query_string,
const char *http_request_method,
const PRIntervalTime timeout,
SEC_HTTP_REQUEST_SESSION *pRequest);
SECStatus
pkix_pl_HttpDefaultClient_SetPostDataFcn(
SEC_HTTP_REQUEST_SESSION request,
const char *http_data,
const PRUint32 http_data_len,
const char *http_content_type);
SECStatus
pkix_pl_HttpDefaultClient_AddHeaderFcn(
SEC_HTTP_REQUEST_SESSION request,
const char *http_header_name,
const char *http_header_value);
SECStatus
pkix_pl_HttpDefaultClient_TrySendAndReceiveFcn(
SEC_HTTP_REQUEST_SESSION request,
PRPollDesc **pPollDesc,
PRUint16 *http_response_code,
const char **http_response_content_type,
const char **http_response_headers,
const char **http_response_data,
PRUint32 *http_response_data_len);
SECStatus
pkix_pl_HttpDefaultClient_CancelFcn(
SEC_HTTP_REQUEST_SESSION request);
SECStatus
pkix_pl_HttpDefaultClient_FreeFcn(
SEC_HTTP_REQUEST_SESSION request);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_HTTPDEFAULTCLIENT_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,75 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_ldapcertstore.h
*
* LDAPCertstore Object Type Definition
*
*/
#ifndef _PKIX_PL_LDAPCERTSTORE_H
#define _PKIX_PL_LDAPCERTSTORE_H
#include "pkix_pl_ldapt.h"
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* At the time of this version, there are unresolved questions about the LDAP
* protocol. Although RFC1777 describes a BIND and UNBIND message, it is not
* clear whether they are appropriate to this application. We have tested only
* using servers that do not expect authentication, and that reject BIND
* messages. It is not clear what values might be appropriate for the bindname
* and authentication fields, which are currently implemented as char strings
* supplied by the caller. (If this changes, the API and possibly the templates
* will have to change.) Therefore the CertStore_Create API contains a BindAPI
* structure, a union, which will have to be revised and extended when this
* area of the protocol is better understood.
*
* It is further assumed that a given LdapCertStore will connect only to a
* single server, and that the creation of the socket will initiate the
* CONNECT. Therefore the LdapCertStore handles only the case of continuing
* the connection, if nonblocking I/O is being used.
*/
typedef enum {
LDAP_CONNECT_PENDING,
LDAP_CONNECTED,
LDAP_BIND_PENDING,
LDAP_BIND_RESPONSE,
LDAP_BIND_RESPONSE_PENDING,
LDAP_BOUND,
LDAP_SEND_PENDING,
LDAP_RECV,
LDAP_RECV_PENDING,
LDAP_RECV_INITIAL,
LDAP_RECV_NONINITIAL,
LDAP_ABANDON_PENDING
} LDAPConnectStatus;
#define LDAP_CACHEBUCKETS 128
#define RCVBUFSIZE 512
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_BuildCertList(
PKIX_List *responseList,
PKIX_List **pCerts,
void *plContext);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_LDAPCERTSTORE_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,82 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_ldapdefaultclient.h
*
* LDAPDefaultClient Object Type Definition
*
*/
#ifndef _PKIX_PL_LDAPDEFAULTCLIENT_H
#define _PKIX_PL_LDAPDEFAULTCLIENT_H
#include "pkix_pl_ldapt.h"
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* At the time of this version, there are unresolved questions about the LDAP
* protocol. Although RFC1777 describes a BIND and UNBIND message, it is not
* clear whether they are appropriate to this application. We have tested only
* using servers that do not expect authentication, and that reject BIND
* messages. It is not clear what values might be appropriate for the bindname
* and authentication fields, which are currently implemented as char strings
* supplied by the caller. (If this changes, the API and possibly the templates
* will have to change.) Therefore the LDAPClient_Create API contains a
* BindAPI structure, a union, which will have to be revised and extended when
* this area of the protocol is better understood.
*
*/
typedef enum {
CONNECT_PENDING,
CONNECTED,
BIND_PENDING,
BIND_RESPONSE,
BIND_RESPONSE_PENDING,
BOUND,
SEND_PENDING,
RECV,
RECV_PENDING,
RECV_INITIAL,
RECV_NONINITIAL,
ABANDON_PENDING
} LdapClientConnectStatus;
struct PKIX_PL_LdapDefaultClientStruct {
PKIX_PL_LdapClient vtable;
LdapClientConnectStatus connectStatus;
PKIX_UInt32 messageID;
PKIX_PL_HashTable *cachePtr;
PKIX_PL_Socket *clientSocket;
PRPollDesc pollDesc;
void *callbackList; /* cast this to (PKIX_PL_Socket_Callback *) */
LDAPBindAPI *bindAPI;
PLArenaPool *arena;
PRTime lastIO;
void *sendBuf;
PKIX_UInt32 bytesToWrite;
void *rcvBuf;
PKIX_UInt32 capacity;
void *currentInPtr;
PKIX_UInt32 currentBytesAvailable;
void *bindMsg;
PKIX_UInt32 bindMsgLen;
PKIX_List *entriesFound;
PKIX_PL_LdapRequest *currentRequest;
PKIX_PL_LdapResponse *currentResponse;
};
/* see source file for function documentation */
PKIX_Error *pkix_pl_LdapDefaultClient_RegisterSelf(void *plContext);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_LDAPDEFAULTCLIENT_H */

View file

@ -0,0 +1,757 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_ldaprequest.c
*
*/
#include "pkix_pl_ldaprequest.h"
/* --Private-LdapRequest-Functions------------------------------------- */
/* Note: lengths do not include the NULL terminator */
static const char caAttr[] = "caCertificate;binary";
static unsigned int caAttrLen = sizeof(caAttr) - 1;
static const char uAttr[] = "userCertificate;binary";
static unsigned int uAttrLen = sizeof(uAttr) - 1;
static const char ccpAttr[] = "crossCertificatePair;binary";
static unsigned int ccpAttrLen = sizeof(ccpAttr) - 1;
static const char crlAttr[] = "certificateRevocationList;binary";
static unsigned int crlAttrLen = sizeof(crlAttr) - 1;
static const char arlAttr[] = "authorityRevocationList;binary";
static unsigned int arlAttrLen = sizeof(arlAttr) - 1;
/*
* XXX If this function were moved into pkix_pl_ldapcertstore.c then all of
* LdapRequest and LdapResponse could be considered part of the LDAP client.
* But the constants, above, would have to be copied as well, and they are
* also needed in pkix_pl_LdapRequest_EncodeAttrs. So there would have to be
* two copies.
*/
/*
* FUNCTION: pkix_pl_LdapRequest_AttrTypeToBit
* DESCRIPTION:
*
* This function creates an attribute mask bit corresponding to the SECItem
* pointed to by "attrType", storing the result at "pAttrBit". The comparison
* is case-insensitive. If "attrType" does not match any of the known types,
* zero is stored at "pAttrBit".
*
* PARAMETERS
* "attrType"
* The address of the SECItem whose string contents are to be compared to
* the various known attribute types. Must be non-NULL.
* "pAttrBit"
* The address where the result 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 LdapRequest 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_LdapRequest_AttrTypeToBit(
SECItem *attrType,
LdapAttrMask *pAttrBit,
void *plContext)
{
LdapAttrMask attrBit = 0;
unsigned int attrLen = 0;
const char *s = NULL;
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrTypeToBit");
PKIX_NULLCHECK_TWO(attrType, pAttrBit);
s = (const char *)attrType->data;
attrLen = attrType->len;
/*
* Taking note of the fact that all of the comparand strings are
* different lengths, we do a slight optimization. If a string
* length matches but the string does not match, we skip comparing
* to the other strings. If new strings are added to the comparand
* list, and any are of equal length, be careful to change the
* grouping of tests accordingly.
*/
if (attrLen == caAttrLen) {
if (PORT_Strncasecmp(caAttr, s, attrLen) == 0) {
attrBit = LDAPATTR_CACERT;
}
} else if (attrLen == uAttrLen) {
if (PORT_Strncasecmp(uAttr, s, attrLen) == 0) {
attrBit = LDAPATTR_USERCERT;
}
} else if (attrLen == ccpAttrLen) {
if (PORT_Strncasecmp(ccpAttr, s, attrLen) == 0) {
attrBit = LDAPATTR_CROSSPAIRCERT;
}
} else if (attrLen == crlAttrLen) {
if (PORT_Strncasecmp(crlAttr, s, attrLen) == 0) {
attrBit = LDAPATTR_CERTREVLIST;
}
} else if (attrLen == arlAttrLen) {
if (PORT_Strncasecmp(arlAttr, s, attrLen) == 0) {
attrBit = LDAPATTR_AUTHREVLIST;
}
}
*pAttrBit = attrBit;
PKIX_RETURN(LDAPREQUEST);
}
/*
* FUNCTION: pkix_pl_LdapRequest_AttrStringToBit
* DESCRIPTION:
*
* This function creates an attribute mask bit corresponding to the null-
* terminated string pointed to by "attrString", storing the result at
* "pAttrBit". The comparison is case-insensitive. If "attrString" does not
* match any of the known types, zero is stored at "pAttrBit".
*
* PARAMETERS
* "attrString"
* The address of the null-terminated string whose contents are to be compared to
* the various known attribute types. Must be non-NULL.
* "pAttrBit"
* The address where the result 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 LdapRequest 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_LdapRequest_AttrStringToBit(
char *attrString,
LdapAttrMask *pAttrBit,
void *plContext)
{
LdapAttrMask attrBit = 0;
unsigned int attrLen = 0;
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrStringToBit");
PKIX_NULLCHECK_TWO(attrString, pAttrBit);
attrLen = PL_strlen(attrString);
/*
* Taking note of the fact that all of the comparand strings are
* different lengths, we do a slight optimization. If a string
* length matches but the string does not match, we skip comparing
* to the other strings. If new strings are added to the comparand
* list, and any are of equal length, be careful to change the
* grouping of tests accordingly.
*/
if (attrLen == caAttrLen) {
if (PORT_Strncasecmp(caAttr, attrString, attrLen) == 0) {
attrBit = LDAPATTR_CACERT;
}
} else if (attrLen == uAttrLen) {
if (PORT_Strncasecmp(uAttr, attrString, attrLen) == 0) {
attrBit = LDAPATTR_USERCERT;
}
} else if (attrLen == ccpAttrLen) {
if (PORT_Strncasecmp(ccpAttr, attrString, attrLen) == 0) {
attrBit = LDAPATTR_CROSSPAIRCERT;
}
} else if (attrLen == crlAttrLen) {
if (PORT_Strncasecmp(crlAttr, attrString, attrLen) == 0) {
attrBit = LDAPATTR_CERTREVLIST;
}
} else if (attrLen == arlAttrLen) {
if (PORT_Strncasecmp(arlAttr, attrString, attrLen) == 0) {
attrBit = LDAPATTR_AUTHREVLIST;
}
}
*pAttrBit = attrBit;
PKIX_RETURN(LDAPREQUEST);
}
/*
* FUNCTION: pkix_pl_LdapRequest_EncodeAttrs
* DESCRIPTION:
*
* This function obtains the attribute mask bits from the LdapRequest pointed
* to by "request", creates the corresponding array of AttributeTypes for the
* encoding of the SearchRequest message.
*
* PARAMETERS
* "request"
* The address of the LdapRequest whose attributes are to be encoded. 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 LdapRequest 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_LdapRequest_EncodeAttrs(
PKIX_PL_LdapRequest *request,
void *plContext)
{
SECItem **attrArray = NULL;
PKIX_UInt32 attrIndex = 0;
LdapAttrMask attrBits;
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_EncodeAttrs");
PKIX_NULLCHECK_ONE(request);
/* construct "attrs" according to bits in request->attrBits */
attrBits = request->attrBits;
attrArray = request->attrArray;
if ((attrBits & LDAPATTR_CACERT) == LDAPATTR_CACERT) {
attrArray[attrIndex] = &(request->attributes[attrIndex]);
request->attributes[attrIndex].type = siAsciiString;
request->attributes[attrIndex].data = (unsigned char *)caAttr;
request->attributes[attrIndex].len = caAttrLen;
attrIndex++;
}
if ((attrBits & LDAPATTR_USERCERT) == LDAPATTR_USERCERT) {
attrArray[attrIndex] = &(request->attributes[attrIndex]);
request->attributes[attrIndex].type = siAsciiString;
request->attributes[attrIndex].data = (unsigned char *)uAttr;
request->attributes[attrIndex].len = uAttrLen;
attrIndex++;
}
if ((attrBits & LDAPATTR_CROSSPAIRCERT) == LDAPATTR_CROSSPAIRCERT) {
attrArray[attrIndex] = &(request->attributes[attrIndex]);
request->attributes[attrIndex].type = siAsciiString;
request->attributes[attrIndex].data = (unsigned char *)ccpAttr;
request->attributes[attrIndex].len = ccpAttrLen;
attrIndex++;
}
if ((attrBits & LDAPATTR_CERTREVLIST) == LDAPATTR_CERTREVLIST) {
attrArray[attrIndex] = &(request->attributes[attrIndex]);
request->attributes[attrIndex].type = siAsciiString;
request->attributes[attrIndex].data = (unsigned char *)crlAttr;
request->attributes[attrIndex].len = crlAttrLen;
attrIndex++;
}
if ((attrBits & LDAPATTR_AUTHREVLIST) == LDAPATTR_AUTHREVLIST) {
attrArray[attrIndex] = &(request->attributes[attrIndex]);
request->attributes[attrIndex].type = siAsciiString;
request->attributes[attrIndex].data = (unsigned char *)arlAttr;
request->attributes[attrIndex].len = arlAttrLen;
attrIndex++;
}
attrArray[attrIndex] = (SECItem *)NULL;
PKIX_RETURN(LDAPREQUEST);
}
/*
* FUNCTION: pkix_pl_LdapRequest_Destroy
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
*/
static PKIX_Error *
pkix_pl_LdapRequest_Destroy(
PKIX_PL_Object *object,
void *plContext)
{
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Destroy");
PKIX_NULLCHECK_ONE(object);
PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext),
PKIX_OBJECTNOTLDAPREQUEST);
/*
* All dynamic fields in an LDAPRequest are allocated
* in an arena, and will be freed when the arena is destroyed.
*/
cleanup:
PKIX_RETURN(LDAPREQUEST);
}
/*
* FUNCTION: pkix_pl_LdapRequest_Hashcode
* (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
*/
static PKIX_Error *
pkix_pl_LdapRequest_Hashcode(
PKIX_PL_Object *object,
PKIX_UInt32 *pHashcode,
void *plContext)
{
PKIX_UInt32 dataLen = 0;
PKIX_UInt32 dindex = 0;
PKIX_UInt32 sizeOfLength = 0;
PKIX_UInt32 idLen = 0;
const unsigned char *msgBuf = NULL;
PKIX_PL_LdapRequest *ldapRq = NULL;
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Hashcode");
PKIX_NULLCHECK_TWO(object, pHashcode);
PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext),
PKIX_OBJECTNOTLDAPREQUEST);
ldapRq = (PKIX_PL_LdapRequest *)object;
*pHashcode = 0;
/*
* Two requests that differ only in msgnum are a match! Therefore,
* start hashcoding beyond the encoded messageID field.
*/
if (ldapRq->encoded) {
msgBuf = (const unsigned char *)ldapRq->encoded->data;
/* Is message length short form (one octet) or long form? */
if ((msgBuf[1] & 0x80) != 0) {
sizeOfLength = msgBuf[1] & 0x7F;
for (dindex = 0; dindex < sizeOfLength; dindex++) {
dataLen = (dataLen << 8) + msgBuf[dindex + 2];
}
} else {
dataLen = msgBuf[1];
}
/* How many bytes for the messageID? (Assume short form) */
idLen = msgBuf[dindex + 3] + 2;
dindex += idLen;
dataLen -= idLen;
msgBuf = &msgBuf[dindex + 2];
PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext),
PKIX_HASHFAILED);
}
cleanup:
PKIX_RETURN(LDAPREQUEST);
}
/*
* FUNCTION: pkix_pl_LdapRequest_Equals
* (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
*/
static PKIX_Error *
pkix_pl_LdapRequest_Equals(
PKIX_PL_Object *firstObj,
PKIX_PL_Object *secondObj,
PKIX_Boolean *pResult,
void *plContext)
{
PKIX_PL_LdapRequest *firstReq = NULL;
PKIX_PL_LdapRequest *secondReq = NULL;
PKIX_UInt32 secondType = 0;
PKIX_UInt32 firstLen = 0;
const unsigned char *firstData = NULL;
const unsigned char *secondData = NULL;
PKIX_UInt32 sizeOfLength = 0;
PKIX_UInt32 dindex = 0;
PKIX_UInt32 i = 0;
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Equals");
PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
/* test that firstObj is a LdapRequest */
PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPREQUEST_TYPE, plContext),
PKIX_FIRSTOBJARGUMENTNOTLDAPREQUEST);
/*
* Since we know firstObj is a LdapRequest, if both references are
* identical, they must be equal
*/
if (firstObj == secondObj){
*pResult = PKIX_TRUE;
goto cleanup;
}
/*
* If secondObj isn't a LdapRequest, we don't throw an error.
* We simply return a Boolean result of FALSE
*/
*pResult = PKIX_FALSE;
PKIX_CHECK(PKIX_PL_Object_GetType
(secondObj, &secondType, plContext),
PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
if (secondType != PKIX_LDAPREQUEST_TYPE) {
goto cleanup;
}
firstReq = (PKIX_PL_LdapRequest *)firstObj;
secondReq = (PKIX_PL_LdapRequest *)secondObj;
/* If either lacks an encoded string, they cannot be compared */
if (!(firstReq->encoded) || !(secondReq->encoded)) {
goto cleanup;
}
if (firstReq->encoded->len != secondReq->encoded->len) {
goto cleanup;
}
firstData = (const unsigned char *)firstReq->encoded->data;
secondData = (const unsigned char *)secondReq->encoded->data;
/*
* Two requests that differ only in msgnum are equal! Therefore,
* start the byte comparison beyond the encoded messageID field.
*/
/* Is message length short form (one octet) or long form? */
if ((firstData[1] & 0x80) != 0) {
sizeOfLength = firstData[1] & 0x7F;
for (dindex = 0; dindex < sizeOfLength; dindex++) {
firstLen = (firstLen << 8) + firstData[dindex + 2];
}
} else {
firstLen = firstData[1];
}
/* How many bytes for the messageID? (Assume short form) */
i = firstData[dindex + 3] + 2;
dindex += i;
firstLen -= i;
firstData = &firstData[dindex + 2];
/*
* In theory, we have to calculate where the second message data
* begins by checking its length encodings. But if these messages
* are equal, we can re-use the calculation we already did. If they
* are not equal, the byte comparisons will surely fail.
*/
secondData = &secondData[dindex + 2];
for (i = 0; i < firstLen; i++) {
if (firstData[i] != secondData[i]) {
goto cleanup;
}
}
*pResult = PKIX_TRUE;
cleanup:
PKIX_RETURN(LDAPREQUEST);
}
/*
* FUNCTION: pkix_pl_LdapRequest_RegisterSelf
* DESCRIPTION:
* Registers PKIX_LDAPREQUEST_TYPE and its related functions with
* systemClasses[]
* PARAMETERS:
* "plContext"
* Platform-specific context pointer.
* 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_LdapRequest_RegisterSelf(void *plContext)
{
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
pkix_ClassTable_Entry entry;
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_RegisterSelf");
entry.description = "LdapRequest";
entry.objCounter = 0;
entry.typeObjectSize = sizeof(PKIX_PL_LdapRequest);
entry.destructor = pkix_pl_LdapRequest_Destroy;
entry.equalsFunction = pkix_pl_LdapRequest_Equals;
entry.hashcodeFunction = pkix_pl_LdapRequest_Hashcode;
entry.toStringFunction = NULL;
entry.comparator = NULL;
entry.duplicateFunction = pkix_duplicateImmutable;
systemClasses[PKIX_LDAPREQUEST_TYPE] = entry;
PKIX_RETURN(LDAPREQUEST);
}
/* --Public-Functions------------------------------------------------------- */
/*
* FUNCTION: pkix_pl_LdapRequest_Create
* DESCRIPTION:
*
* This function creates an LdapRequest using the PLArenaPool pointed to by
* "arena", a message number whose value is "msgnum", a base object pointed to
* by "issuerDN", a scope whose value is "scope", a derefAliases flag whose
* value is "derefAliases", a sizeLimit whose value is "sizeLimit", a timeLimit
* whose value is "timeLimit", an attrsOnly flag whose value is "attrsOnly", a
* filter whose value is "filter", and attribute bits whose value is
* "attrBits"; storing the result at "pRequestMsg".
*
* See pkix_pl_ldaptemplates.c (and below) for the ASN.1 representation of
* message components, and see pkix_pl_ldapt.h for data types.
*
* PARAMETERS
* "arena"
* The address of the PLArenaPool to be used in the encoding. Must be
* non-NULL.
* "msgnum"
* The UInt32 message number to be used for the messageID component of the
* LDAP message exchange.
* "issuerDN"
* The address of the string to be used for the baseObject component of the
* LDAP SearchRequest message. Must be non-NULL.
* "scope"
* The (enumerated) ScopeType to be used for the scope component of the
* LDAP SearchRequest message
* "derefAliases"
* The (enumerated) DerefType to be used for the derefAliases component of
* the LDAP SearchRequest message
* "sizeLimit"
* The UInt32 value to be used for the sizeLimit component of the LDAP
* SearchRequest message
* "timeLimit"
* The UInt32 value to be used for the timeLimit component of the LDAP
* SearchRequest message
* "attrsOnly"
* The Boolean value to be used for the attrsOnly component of the LDAP
* SearchRequest message
* "filter"
* The filter to be used for the filter component of the LDAP
* SearchRequest message
* "attrBits"
* The LdapAttrMask bits indicating the attributes to be included in the
* attributes sequence of the LDAP SearchRequest message
* "pRequestMsg"
* The address at which the address of the LdapRequest 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 LdapRequest Error if the function fails in a non-fatal way.
* Returns a Fatal Error if the function fails in an unrecoverable way.
*/
/*
* SearchRequest ::=
* [APPLICATION 3] SEQUENCE {
* baseObject LDAPDN,
* scope ENUMERATED {
* baseObject (0),
* singleLevel (1),
* wholeSubtree (2)
* },
* derefAliases ENUMERATED {
* neverDerefAliases (0),
* derefInSearching (1),
* derefFindingBaseObj (2),
* alwaysDerefAliases (3)
* },
* sizeLimit INTEGER (0 .. MAXINT),
* -- value of 0 implies no sizeLimit
* timeLimit INTEGER (0 .. MAXINT),
* -- value of 0 implies no timeLimit
* attrsOnly BOOLEAN,
* -- TRUE, if only attributes (without values)
* -- to be returned
* filter Filter,
* attributes SEQUENCE OF AttributeType
* }
*
* Filter ::=
* CHOICE {
* and [0] SET OF Filter,
* or [1] SET OF Filter,
* not [2] Filter,
* equalityMatch [3] AttributeValueAssertion,
* substrings [4] SubstringFilter,
* greaterOrEqual [5] AttributeValueAssertion,
* lessOrEqual [6] AttributeValueAssertion,
* present [7] AttributeType,
* approxMatch [8] AttributeValueAssertion
* }
*
* SubstringFilter ::=
* SEQUENCE {
* type AttributeType,
* SEQUENCE OF CHOICE {
* initial [0] LDAPString,
* any [1] LDAPString,
* final [2] LDAPString,
* }
* }
*
* AttributeValueAssertion ::=
* SEQUENCE {
* attributeType AttributeType,
* attributeValue AttributeValue,
* }
*
* AttributeValue ::= OCTET STRING
*
* AttributeType ::= LDAPString
* -- text name of the attribute, or dotted
* -- OID representation
*
* LDAPDN ::= LDAPString
*
* LDAPString ::= OCTET STRING
*
*/
PKIX_Error *
pkix_pl_LdapRequest_Create(
PLArenaPool *arena,
PKIX_UInt32 msgnum,
char *issuerDN,
ScopeType scope,
DerefType derefAliases,
PKIX_UInt32 sizeLimit,
PKIX_UInt32 timeLimit,
char attrsOnly,
LDAPFilter *filter,
LdapAttrMask attrBits,
PKIX_PL_LdapRequest **pRequestMsg,
void *plContext)
{
LDAPMessage msg;
LDAPSearch *search;
PKIX_PL_LdapRequest *ldapRequest = NULL;
char scopeTypeAsChar;
char derefAliasesTypeAsChar;
SECItem *attrArray[MAX_LDAPATTRS + 1];
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Create");
PKIX_NULLCHECK_THREE(arena, issuerDN, pRequestMsg);
/* create a PKIX_PL_LdapRequest object */
PKIX_CHECK(PKIX_PL_Object_Alloc
(PKIX_LDAPREQUEST_TYPE,
sizeof (PKIX_PL_LdapRequest),
(PKIX_PL_Object **)&ldapRequest,
plContext),
PKIX_COULDNOTCREATEOBJECT);
ldapRequest->arena = arena;
ldapRequest->msgnum = msgnum;
ldapRequest->issuerDN = issuerDN;
ldapRequest->scope = scope;
ldapRequest->derefAliases = derefAliases;
ldapRequest->sizeLimit = sizeLimit;
ldapRequest->timeLimit = timeLimit;
ldapRequest->attrsOnly = attrsOnly;
ldapRequest->filter = filter;
ldapRequest->attrBits = attrBits;
ldapRequest->attrArray = attrArray;
PKIX_CHECK(pkix_pl_LdapRequest_EncodeAttrs
(ldapRequest, plContext),
PKIX_LDAPREQUESTENCODEATTRSFAILED);
PKIX_PL_NSSCALL
(LDAPREQUEST, PORT_Memset, (&msg, 0, sizeof (LDAPMessage)));
msg.messageID.type = siUnsignedInteger;
msg.messageID.data = (void*)&msgnum;
msg.messageID.len = sizeof (msgnum);
msg.protocolOp.selector = LDAP_SEARCH_TYPE;
search = &(msg.protocolOp.op.searchMsg);
search->baseObject.type = siAsciiString;
search->baseObject.data = (void *)issuerDN;
search->baseObject.len = PL_strlen(issuerDN);
scopeTypeAsChar = (char)scope;
search->scope.type = siUnsignedInteger;
search->scope.data = (void *)&scopeTypeAsChar;
search->scope.len = sizeof (scopeTypeAsChar);
derefAliasesTypeAsChar = (char)derefAliases;
search->derefAliases.type = siUnsignedInteger;
search->derefAliases.data =
(void *)&derefAliasesTypeAsChar;
search->derefAliases.len =
sizeof (derefAliasesTypeAsChar);
search->sizeLimit.type = siUnsignedInteger;
search->sizeLimit.data = (void *)&sizeLimit;
search->sizeLimit.len = sizeof (PKIX_UInt32);
search->timeLimit.type = siUnsignedInteger;
search->timeLimit.data = (void *)&timeLimit;
search->timeLimit.len = sizeof (PKIX_UInt32);
search->attrsOnly.type = siBuffer;
search->attrsOnly.data = (void *)&attrsOnly;
search->attrsOnly.len = sizeof (attrsOnly);
PKIX_PL_NSSCALL
(LDAPREQUEST,
PORT_Memcpy,
(&search->filter, filter, sizeof (LDAPFilter)));
search->attributes = attrArray;
PKIX_PL_NSSCALLRV
(LDAPREQUEST, ldapRequest->encoded, SEC_ASN1EncodeItem,
(arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
if (!(ldapRequest->encoded)) {
PKIX_ERROR(PKIX_FAILEDINENCODINGSEARCHREQUEST);
}
*pRequestMsg = ldapRequest;
cleanup:
if (PKIX_ERROR_RECEIVED) {
PKIX_DECREF(ldapRequest);
}
PKIX_RETURN(LDAPREQUEST);
}
/*
* FUNCTION: pkix_pl_LdapRequest_GetEncoded
* DESCRIPTION:
*
* This function obtains the encoded message from the LdapRequest pointed to
* by "request", storing the result at "pRequestBuf".
*
* PARAMETERS
* "request"
* The address of the LdapRequest whose encoded message is to be
* retrieved. Must be non-NULL.
* "pRequestBuf"
* The address at which is stored the address of the encoded message. 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 LdapRequest 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_LdapRequest_GetEncoded(
PKIX_PL_LdapRequest *request,
SECItem **pRequestBuf,
void *plContext)
{
PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_GetEncoded");
PKIX_NULLCHECK_TWO(request, pRequestBuf);
*pRequestBuf = request->encoded;
PKIX_RETURN(LDAPREQUEST);
}

View file

@ -0,0 +1,86 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_ldaprequest.h
*
* LdapRequest Object Definitions
*
*/
#ifndef _PKIX_PL_LDAPREQUEST_H
#define _PKIX_PL_LDAPREQUEST_H
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
USER_CERT,
CA_CERT,
CROSS_CERT,
CRL,
ARL,
DELTA_CRL
} PKIX_PL_LdapAttr;
struct PKIX_PL_LdapRequestStruct{
PLArenaPool *arena;
PKIX_UInt32 msgnum;
char *issuerDN;
ScopeType scope;
DerefType derefAliases;
PKIX_UInt32 sizeLimit;
PKIX_UInt32 timeLimit;
char attrsOnly;
LDAPFilter *filter;
LdapAttrMask attrBits;
SECItem attributes[MAX_LDAPATTRS];
SECItem **attrArray;
SECItem *encoded;
};
/* see source file for function documentation */
PKIX_Error *
pkix_pl_LdapRequest_Create(
PLArenaPool *arena,
PKIX_UInt32 msgnum,
char *issuerDN,
ScopeType scope,
DerefType derefAliases,
PKIX_UInt32 sizeLimit,
PKIX_UInt32 timeLimit,
char attrsOnly,
LDAPFilter *filter,
LdapAttrMask attrBits,
PKIX_PL_LdapRequest **pRequestMsg,
void *plContext);
PKIX_Error *
pkix_pl_LdapRequest_AttrTypeToBit(
SECItem *attrType,
LdapAttrMask *pAttrBit,
void *plContext);
PKIX_Error *
pkix_pl_LdapRequest_AttrStringToBit(
char *attrString,
LdapAttrMask *pAttrBit,
void *plContext);
PKIX_Error *
pkix_pl_LdapRequest_GetEncoded(
PKIX_PL_LdapRequest *request,
SECItem **pRequestBuf,
void *plContext);
PKIX_Error *pkix_pl_LdapRequest_RegisterSelf(void *plContext);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_LDAPREQUEST_H */

View file

@ -0,0 +1,786 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_ldapresponse.c
*
*/
#include <fcntl.h>
#include "pkix_pl_ldapresponse.h"
/* --Private-LdapResponse-Functions------------------------------------- */
/*
* FUNCTION: pkix_pl_LdapResponse_Destroy
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
*/
static PKIX_Error *
pkix_pl_LdapResponse_Destroy(
PKIX_PL_Object *object,
void *plContext)
{
PKIX_PL_LdapResponse *ldapRsp = NULL;
LDAPMessage *m = NULL;
LDAPSearchResponseEntry *entry = NULL;
LDAPSearchResponseResult *result = NULL;
LDAPSearchResponseAttr **attributes = NULL;
LDAPSearchResponseAttr *attr = NULL;
SECItem **valp = NULL;
SECItem *val = NULL;
PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Destroy");
PKIX_NULLCHECK_ONE(object);
PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPRESPONSE_TYPE, plContext),
PKIX_OBJECTNOTLDAPRESPONSE);
ldapRsp = (PKIX_PL_LdapResponse *)object;
m = &ldapRsp->decoded;
if (m->messageID.data != NULL) {
PR_Free(m->messageID.data);
}
if (m->protocolOp.selector ==
LDAP_SEARCHRESPONSEENTRY_TYPE) {
entry = &m->protocolOp.op.searchResponseEntryMsg;
if (entry->objectName.data != NULL) {
PR_Free(entry->objectName.data);
}
if (entry->attributes != NULL) {
for (attributes = entry->attributes;
*attributes != NULL;
attributes++) {
attr = *attributes;
PR_Free(attr->attrType.data);
for (valp = attr->val; *valp != NULL; valp++) {
val = *valp;
if (val->data != NULL) {
PR_Free(val->data);
}
PR_Free(val);
}
PR_Free(attr->val);
PR_Free(attr);
}
PR_Free(entry->attributes);
}
} else if (m->protocolOp.selector ==
LDAP_SEARCHRESPONSERESULT_TYPE) {
result = &m->protocolOp.op.searchResponseResultMsg;
if (result->resultCode.data != NULL) {
PR_Free(result->resultCode.data);
}
}
PKIX_FREE(ldapRsp->derEncoded.data);
cleanup:
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_Hashcode
* (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
*/
static PKIX_Error *
pkix_pl_LdapResponse_Hashcode(
PKIX_PL_Object *object,
PKIX_UInt32 *pHashcode,
void *plContext)
{
PKIX_UInt32 dataLen = 0;
PKIX_UInt32 dindex = 0;
PKIX_UInt32 sizeOfLength = 0;
PKIX_UInt32 idLen = 0;
const unsigned char *msgBuf = NULL;
PKIX_PL_LdapResponse *ldapRsp = NULL;
PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Hashcode");
PKIX_NULLCHECK_TWO(object, pHashcode);
PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPRESPONSE_TYPE, plContext),
PKIX_OBJECTNOTLDAPRESPONSE);
ldapRsp = (PKIX_PL_LdapResponse *)object;
*pHashcode = 0;
/*
* Two responses that differ only in msgnum are a match! Therefore,
* start hashcoding beyond the encoded messageID field.
*/
if (ldapRsp->derEncoded.data) {
msgBuf = (const unsigned char *)ldapRsp->derEncoded.data;
/* Is message length short form (one octet) or long form? */
if ((msgBuf[1] & 0x80) != 0) {
sizeOfLength = msgBuf[1] & 0x7F;
for (dindex = 0; dindex < sizeOfLength; dindex++) {
dataLen = (dataLen << 8) + msgBuf[dindex + 2];
}
} else {
dataLen = msgBuf[1];
}
/* How many bytes for the messageID? (Assume short form) */
idLen = msgBuf[dindex + 3] + 2;
dindex += idLen;
dataLen -= idLen;
msgBuf = &msgBuf[dindex + 2];
PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext),
PKIX_HASHFAILED);
}
cleanup:
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_Equals
* (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
*/
static PKIX_Error *
pkix_pl_LdapResponse_Equals(
PKIX_PL_Object *firstObj,
PKIX_PL_Object *secondObj,
PKIX_Boolean *pResult,
void *plContext)
{
PKIX_PL_LdapResponse *rsp1 = NULL;
PKIX_PL_LdapResponse *rsp2 = NULL;
PKIX_UInt32 secondType = 0;
PKIX_UInt32 firstLen = 0;
const unsigned char *firstData = NULL;
const unsigned char *secondData = NULL;
PKIX_UInt32 sizeOfLength = 0;
PKIX_UInt32 dindex = 0;
PKIX_UInt32 i = 0;
PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Equals");
PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
/* test that firstObj is a LdapResponse */
PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPRESPONSE_TYPE, plContext),
PKIX_FIRSTOBJARGUMENTNOTLDAPRESPONSE);
/*
* Since we know firstObj is a LdapResponse, if both references are
* identical, they must be equal
*/
if (firstObj == secondObj){
*pResult = PKIX_TRUE;
goto cleanup;
}
/*
* If secondObj isn't a LdapResponse, we don't throw an error.
* We simply return a Boolean result of FALSE
*/
*pResult = PKIX_FALSE;
PKIX_CHECK(PKIX_PL_Object_GetType(secondObj, &secondType, plContext),
PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
if (secondType != PKIX_LDAPRESPONSE_TYPE) {
goto cleanup;
}
rsp1 = (PKIX_PL_LdapResponse *)firstObj;
rsp2 = (PKIX_PL_LdapResponse *)secondObj;
/* If either lacks an encoded string, they cannot be compared */
if (!(rsp1->derEncoded.data) || !(rsp2->derEncoded.data)) {
goto cleanup;
}
if (rsp1->derEncoded.len != rsp2->derEncoded.len) {
goto cleanup;
}
firstData = (const unsigned char *)rsp1->derEncoded.data;
secondData = (const unsigned char *)rsp2->derEncoded.data;
/*
* Two responses that differ only in msgnum are equal! Therefore,
* start the byte comparison beyond the encoded messageID field.
*/
/* Is message length short form (one octet) or long form? */
if ((firstData[1] & 0x80) != 0) {
sizeOfLength = firstData[1] & 0x7F;
for (dindex = 0; dindex < sizeOfLength; dindex++) {
firstLen = (firstLen << 8) + firstData[dindex + 2];
}
} else {
firstLen = firstData[1];
}
/* How many bytes for the messageID? (Assume short form) */
i = firstData[dindex + 3] + 2;
dindex += i;
firstLen -= i;
firstData = &firstData[dindex + 2];
/*
* In theory, we have to calculate where the second message data
* begins by checking its length encodings. But if these messages
* are equal, we can re-use the calculation we already did. If they
* are not equal, the byte comparisons will surely fail.
*/
secondData = &secondData[dindex + 2];
for (i = 0; i < firstLen; i++) {
if (firstData[i] != secondData[i]) {
goto cleanup;
}
}
*pResult = PKIX_TRUE;
cleanup:
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_RegisterSelf
* DESCRIPTION:
* Registers PKIX_LDAPRESPONSE_TYPE and its related functions with
* systemClasses[]
* PARAMETERS:
* "plContext"
* Platform-specific context pointer.
* 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_LdapResponse_RegisterSelf(void *plContext)
{
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
pkix_ClassTable_Entry entry;
PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_RegisterSelf");
entry.description = "LdapResponse";
entry.objCounter = 0;
entry.typeObjectSize = sizeof(PKIX_PL_LdapResponse);
entry.destructor = pkix_pl_LdapResponse_Destroy;
entry.equalsFunction = pkix_pl_LdapResponse_Equals;
entry.hashcodeFunction = pkix_pl_LdapResponse_Hashcode;
entry.toStringFunction = NULL;
entry.comparator = NULL;
entry.duplicateFunction = pkix_duplicateImmutable;
systemClasses[PKIX_LDAPRESPONSE_TYPE] = entry;
PKIX_RETURN(LDAPRESPONSE);
}
/* --Public-Functions------------------------------------------------------- */
/*
* FUNCTION: pkix_pl_LdapResponse_Create
* DESCRIPTION:
*
* This function creates an LdapResponse for the LDAPMessageType provided in
* "responseType" and a buffer capacity provided by "totalLength". It copies
* into its buffer either "totalLength" or "bytesAvailable" bytes, whichever
* is less, from the buffer pointed to by "partialData", storing the number of
* bytes copied at "pBytesConsumed" and storing the address of the LdapResponse
* at "pLdapResponse".
*
* If a message is complete in a single I/O buffer, the LdapResponse will be
* complete when this function returns. If the message carries over into
* additional buffers, their contents will be added to the LdapResponse by
* susequent calls to pkix_pl_LdapResponse_Append.
*
* PARAMETERS
* "responseType"
* The value of the message type (LDAP_SEARCHRESPONSEENTRY_TYPE or
* LDAP_SEARCHRESPONSERESULT_TYPE) for the LdapResponse being created
* "totalLength"
* The UInt32 value for the total length of the encoded message to be
* stored in the LdapResponse
* "bytesAvailable"
* The UInt32 value for the number of bytes of data available in the
* current buffer.
* "partialData"
* The address from which data is to be copied.
* "pBytesConsumed"
* The address at which is stored the UInt32 number of bytes taken from the
* current buffer. If this number is less than "bytesAvailable", then bytes
* remain in the buffer for the next LdapResponse. Must be non-NULL.
* "pLdapResponse"
* The address where the created LdapResponse 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 LdapResponse 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_LdapResponse_Create(
LDAPMessageType responseType,
PKIX_UInt32 totalLength,
PKIX_UInt32 bytesAvailable,
void *partialData,
PKIX_UInt32 *pBytesConsumed,
PKIX_PL_LdapResponse **pLdapResponse,
void *plContext)
{
PKIX_UInt32 bytesConsumed = 0;
PKIX_PL_LdapResponse *ldapResponse = NULL;
void *data = NULL;
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Create");
PKIX_NULLCHECK_ONE(pLdapResponse);
if (bytesAvailable <= totalLength) {
bytesConsumed = bytesAvailable;
} else {
bytesConsumed = totalLength;
}
/* create a PKIX_PL_LdapResponse object */
PKIX_CHECK(PKIX_PL_Object_Alloc
(PKIX_LDAPRESPONSE_TYPE,
sizeof (PKIX_PL_LdapResponse),
(PKIX_PL_Object **)&ldapResponse,
plContext),
PKIX_COULDNOTCREATEOBJECT);
ldapResponse->decoded.protocolOp.selector = responseType;
ldapResponse->totalLength = totalLength;
ldapResponse->partialLength = bytesConsumed;
if (totalLength != 0){
/* Alloc space for array */
PKIX_NULLCHECK_ONE(partialData);
PKIX_CHECK(PKIX_PL_Malloc
(totalLength,
&data,
plContext),
PKIX_MALLOCFAILED);
PKIX_PL_NSSCALL
(LDAPRESPONSE,
PORT_Memcpy,
(data, partialData, bytesConsumed));
}
ldapResponse->derEncoded.type = siBuffer;
ldapResponse->derEncoded.data = data;
ldapResponse->derEncoded.len = totalLength;
*pBytesConsumed = bytesConsumed;
*pLdapResponse = ldapResponse;
cleanup:
if (PKIX_ERROR_RECEIVED){
PKIX_DECREF(ldapResponse);
}
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_Append
* DESCRIPTION:
*
* This function updates the LdapResponse pointed to by "response" with up to
* "incrLength" from the buffer pointer to by "incrData", storing the number of
* bytes copied at "pBytesConsumed".
*
* PARAMETERS
* "response"
* The address of the LdapResponse being updated. Must be non-zero.
* "incrLength"
* The UInt32 value for the number of bytes of data available in the
* current buffer.
* "incrData"
* The address from which data is to be copied.
* "pBytesConsumed"
* The address at which is stored the UInt32 number of bytes taken from the
* current buffer. If this number is less than "incrLength", then bytes
* remain in the buffer for the next LdapResponse. 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 LdapResponse 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_LdapResponse_Append(
PKIX_PL_LdapResponse *response,
PKIX_UInt32 incrLength,
void *incrData,
PKIX_UInt32 *pBytesConsumed,
void *plContext)
{
PKIX_UInt32 newPartialLength = 0;
PKIX_UInt32 bytesConsumed = 0;
void *dest = NULL;
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Append");
PKIX_NULLCHECK_TWO(response, pBytesConsumed);
if (incrLength > 0) {
/* Calculate how many bytes we have room for. */
bytesConsumed =
response->totalLength - response->partialLength;
if (bytesConsumed > incrLength) {
bytesConsumed = incrLength;
}
newPartialLength = response->partialLength + bytesConsumed;
PKIX_NULLCHECK_ONE(incrData);
dest = &(((char *)response->derEncoded.data)[
response->partialLength]);
PKIX_PL_NSSCALL
(LDAPRESPONSE,
PORT_Memcpy,
(dest, incrData, bytesConsumed));
response->partialLength = newPartialLength;
}
*pBytesConsumed = bytesConsumed;
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_IsComplete
* DESCRIPTION:
*
* This function determines whether the LdapResponse pointed to by "response"
* contains all the data called for by the "totalLength" parameter provided
* when it was created, storing PKIX_TRUE at "pIsComplete" if so, and
* PKIX_FALSE otherwise.
*
* PARAMETERS
* "response"
* The address of the LdapResponse being evaluaTED. Must be non-zero.
* "incrLength"
* The UInt32 value for the number of bytes of data available in the
* current buffer.
* "incrData"
* The address from which data is to be copied.
* "pIsComplete"
* The address at which is stored the Boolean indication of whether the
* LdapResponse is complete. 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 LdapResponse 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_LdapResponse_IsComplete(
PKIX_PL_LdapResponse *response,
PKIX_Boolean *pIsComplete,
void *plContext)
{
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_IsComplete");
PKIX_NULLCHECK_TWO(response, pIsComplete);
if (response->totalLength == response->partialLength) {
*pIsComplete = PKIX_TRUE;
} else {
*pIsComplete = PKIX_FALSE;
}
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_Decode
* DESCRIPTION:
*
* This function decodes the DER data contained in the LdapResponse pointed to
* by "response", using the arena pointed to by "arena", and storing at
* "pStatus" SECSuccess if the decoding was successful and SECFailure
* otherwise. The decoded message is stored in an element of "response".
*
* PARAMETERS
* "arena"
* The address of the PLArenaPool to be used in the decoding. Must be
* non-NULL.
* "response"
* The address of the LdapResponse whose DER data is to be decoded. Must
* be non-NULL.
* "pStatus"
* The address at which is stored the status from the decoding, SECSuccess
* if successful, SECFailure otherwise. 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 LdapResponse 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_LdapResponse_Decode(
PLArenaPool *arena,
PKIX_PL_LdapResponse *response,
SECStatus *pStatus,
void *plContext)
{
LDAPMessage *msg;
SECStatus rv = SECFailure;
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Decode");
PKIX_NULLCHECK_THREE(arena, response, pStatus);
if (response->totalLength != response->partialLength) {
PKIX_ERROR(PKIX_ATTEMPTTODECODEANINCOMPLETERESPONSE);
}
msg = &(response->decoded);
PKIX_PL_NSSCALL
(LDAPRESPONSE, PORT_Memset, (msg, 0, sizeof (LDAPMessage)));
PKIX_PL_NSSCALLRV(LDAPRESPONSE, rv, SEC_ASN1DecodeItem,
(NULL, msg, PKIX_PL_LDAPMessageTemplate, &(response->derEncoded)));
*pStatus = rv;
cleanup:
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_GetMessage
* DESCRIPTION:
*
* This function obtains the decoded message from the LdapResponse pointed to
* by "response", storing the result at "pMessage".
*
* PARAMETERS
* "response"
* The address of the LdapResponse whose decoded message is to be
* retrieved. Must be non-NULL.
* "pMessage"
* The address at which is stored the address of the decoded message. 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_LdapResponse_GetMessage(
PKIX_PL_LdapResponse *response,
LDAPMessage **pMessage,
void *plContext)
{
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessage");
PKIX_NULLCHECK_TWO(response, pMessage);
*pMessage = &response->decoded;
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_GetCapacity
* DESCRIPTION:
*
* This function obtains from the LdapResponse pointed to by "response" the
* number of bytes remaining to be read, based on the totalLength that was
* provided to LdapResponse_Create and the data subsequently provided to
* LdapResponse_Append, storing the result at "pMessage".
*
* PARAMETERS
* "response"
* The address of the LdapResponse whose remaining capacity is to be
* retrieved. Must be non-NULL.
* "pCapacity"
* The address at which is stored the address of the decoded message. 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 LdapResponse 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_LdapResponse_GetCapacity(
PKIX_PL_LdapResponse *response,
PKIX_UInt32 *pCapacity,
void *plContext)
{
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetCapacity");
PKIX_NULLCHECK_TWO(response, pCapacity);
*pCapacity = response->totalLength - response->partialLength;
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_GetMessageType
* DESCRIPTION:
*
* This function obtains the message type from the LdapResponse pointed to
* by "response", storing the result at "pMessageType".
*
* PARAMETERS
* "response"
* The address of the LdapResponse whose message type is to be
* retrieved. Must be non-NULL.
* "pMessageType"
* The address at which is stored the type of the response message. 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_LdapResponse_GetMessageType(
PKIX_PL_LdapResponse *response,
LDAPMessageType *pMessageType,
void *plContext)
{
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessageType");
PKIX_NULLCHECK_TWO(response, pMessageType);
*pMessageType = response->decoded.protocolOp.selector;
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_GetResultCode
* DESCRIPTION:
*
* This function obtains the result code from the LdapResponse pointed to
* by "response", storing the result at "pResultCode".
*
* PARAMETERS
* "response"
* The address of the LdapResponse whose result code is to be
* retrieved. Must be non-NULL.
* "pResultCode"
* The address at which is stored the address of the decoded message. 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 LdapResponse 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_LdapResponse_GetResultCode(
PKIX_PL_LdapResponse *response,
LDAPResultCode *pResultCode,
void *plContext)
{
LDAPMessageType messageType = 0;
LDAPSearchResponseResult *resultMsg = NULL;
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode");
PKIX_NULLCHECK_TWO(response, pResultCode);
messageType = response->decoded.protocolOp.selector;
if (messageType != LDAP_SEARCHRESPONSERESULT_TYPE) {
PKIX_ERROR(PKIX_GETRESULTCODECALLEDFORNONRESULTMESSAGE);
}
resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg;
*pResultCode = *(resultMsg->resultCode.data);
cleanup:
PKIX_RETURN(LDAPRESPONSE);
}
/*
* FUNCTION: pkix_pl_LdapResponse_GetAttributes
* DESCRIPTION:
*
* This function obtains the attributes from the LdapResponse pointed to
* by "response", storing the result at "pAttributes".
*
* PARAMETERS
* "response"
* The address of the LdapResponse whose decoded message is to be
* retrieved. Must be non-NULL.
* "pAttributes"
* The address at which is stored the attributes of the message. 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 LdapResponse 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_LdapResponse_GetAttributes(
PKIX_PL_LdapResponse *response,
LDAPSearchResponseAttr ***pAttributes,
void *plContext)
{
LDAPMessageType messageType = 0;
PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode");
PKIX_NULLCHECK_TWO(response, pAttributes);
messageType = response->decoded.protocolOp.selector;
if (messageType != LDAP_SEARCHRESPONSEENTRY_TYPE) {
PKIX_ERROR(PKIX_GETATTRIBUTESCALLEDFORNONENTRYMESSAGE);
}
*pAttributes = response->
decoded.protocolOp.op.searchResponseEntryMsg.attributes;
cleanup:
PKIX_RETURN(LDAPRESPONSE);
}

View file

@ -0,0 +1,96 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_ldapresponse.h
*
* LdapResponse Object Definitions
*
*/
#ifndef _PKIX_PL_LDAPRESPONSE_H
#define _PKIX_PL_LDAPRESPONSE_H
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
struct PKIX_PL_LdapResponseStruct{
LDAPMessage decoded;
PKIX_UInt32 partialLength;
PKIX_UInt32 totalLength;
SECItem derEncoded;
};
/* see source file for function documentation */
PKIX_Error *
pkix_pl_LdapResponse_Create(
LDAPMessageType responseType,
PKIX_UInt32 totalLength,
PKIX_UInt32 bytesAvailable,
void *partialData,
PKIX_UInt32 *pBytesConsumed,
PKIX_PL_LdapResponse **pResponse,
void *plContext);
PKIX_Error *
pkix_pl_LdapResponse_Append(
PKIX_PL_LdapResponse *response,
PKIX_UInt32 partialLength,
void *partialData,
PKIX_UInt32 *bytesConsumed,
void *plContext);
PKIX_Error *
pkix_pl_LdapResponse_IsComplete(
PKIX_PL_LdapResponse *response,
PKIX_Boolean *pIsComplete,
void *plContext);
PKIX_Error *
pkix_pl_LdapResponse_Decode(
PLArenaPool *arena,
PKIX_PL_LdapResponse *response,
SECStatus *pStatus,
void *plContext);
PKIX_Error *
pkix_pl_LdapResponse_GetMessage(
PKIX_PL_LdapResponse *response,
LDAPMessage **pMessage,
void *plContext);
PKIX_Error *
pkix_pl_LdapResponse_GetMessageType(
PKIX_PL_LdapResponse *response,
LDAPMessageType *pMessageType,
void *plContext);
PKIX_Error *
pkix_pl_LdapResponse_GetCapacity(
PKIX_PL_LdapResponse *response,
PKIX_UInt32 *pCapacity,
void *plContext);
PKIX_Error *
pkix_pl_LdapResponse_GetResultCode(
PKIX_PL_LdapResponse *response,
LDAPResultCode *pResultCode,
void *plContext);
PKIX_Error *
pkix_pl_LdapResponse_GetAttributes(
PKIX_PL_LdapResponse *response,
LDAPSearchResponseAttr ***pAttributes,
void *plContext);
PKIX_Error *pkix_pl_LdapResponse_RegisterSelf(void *plContext);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_LDAPRESPONSE_H */

View file

@ -0,0 +1,314 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _LDAP_H_
#define _LDAP_H_
#include "certt.h"
#include "pkixt.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const SEC_ASN1Template PKIX_PL_LDAPCrossCertPairTemplate[];
SEC_ASN1_CHOOSER_DECLARE(PKIX_PL_LDAPCrossCertPairTemplate)
extern const SEC_ASN1Template PKIX_PL_LDAPMessageTemplate[];
SEC_ASN1_CHOOSER_DECLARE(PKIX_PL_LDAPMessageTemplate)
extern const SEC_ASN1Template LDAPFilterTemplate[];
SEC_ASN1_CHOOSER_DECLARE(LDAPFilterTemplate)
/* ********************************************************************** */
#define SEC_ASN1_LDAP_STRING SEC_ASN1_OCTET_STRING
#define LDAPATTR_CACERT (1<<0)
#define LDAPATTR_USERCERT (1<<1)
#define LDAPATTR_CROSSPAIRCERT (1<<2)
#define LDAPATTR_CERTREVLIST (1<<3)
#define LDAPATTR_AUTHREVLIST (1<<4)
#define MAX_LDAPATTRS 5
typedef PKIX_UInt32 LdapAttrMask;
typedef enum {
SIMPLE_AUTH = 0,
KRBV42LDAP_AUTH = 1,
KRBV42DSA_AUTH = 2
} AuthType;
typedef enum {
BASE_OBJECT = 0,
SINGLE_LEVEL = 1,
WHOLE_SUBTREE = 2
} ScopeType;
typedef enum {
NEVER_DEREF = 0,
DEREF_IN_SEARCHING = 1,
DEREF_FINDING_BASEOBJ = 2,
ALWAYS_DEREF = 3
} DerefType;
typedef enum {
LDAP_INITIALSUBSTRING_TYPE = 0,
LDAP_ANYSUBSTRING_TYPE = 1,
LDAP_FINALSUBSTRING_TYPE = 2
} LDAPSubstringFilterType;
typedef enum {
LDAP_ANDFILTER_TYPE = 0,
LDAP_ORFILTER_TYPE = 1,
LDAP_NOTFILTER_TYPE = 2,
LDAP_EQUALFILTER_TYPE = 3,
LDAP_SUBSTRINGFILTER_TYPE = 4,
LDAP_GREATEROREQUALFILTER_TYPE = 5,
LDAP_LESSOREQUALFILTER_TYPE = 6,
LDAP_PRESENTFILTER_TYPE = 7,
LDAP_APPROXMATCHFILTER_TYPE = 8
} LDAPFilterType;
typedef enum {
LDAP_BIND_TYPE = 0,
LDAP_BINDRESPONSE_TYPE = 1,
LDAP_UNBIND_TYPE = 2,
LDAP_SEARCH_TYPE = 3,
LDAP_SEARCHRESPONSEENTRY_TYPE = 4,
LDAP_SEARCHRESPONSERESULT_TYPE = 5,
LDAP_ABANDONREQUEST_TYPE = 16
} LDAPMessageType;
typedef enum {
SUCCESS = 0,
OPERATIONSERROR = 1,
PROTOCOLERROR = 2,
TIMELIMITEXCEEDED = 3,
SIZELIMITEXCEEDED = 4,
COMPAREFALSE = 5,
COMPARETRUE = 6,
AUTHMETHODNOTSUPPORTED = 7,
STRONGAUTHREQUIRED = 8,
NOSUCHATTRIBUTE = 16,
UNDEFINEDATTRIBUTETYPE = 17,
INAPPROPRIATEMATCHING = 18,
CONSTRAINTVIOLATION = 19,
ATTRIBUTEORVALUEEXISTS = 20,
INVALIDATTRIBUTESYNTAX = 21,
NOSUCHOBJECT = 32,
ALIASPROBLEM = 33,
INVALIDDNSYNTAX = 34,
ISLEAF = 35,
ALIASDEREFERENCINGPROBLEM = 36,
INAPPROPRIATEAUTHENTICATION = 48,
INVALIDCREDENTIALS = 49,
INSUFFICIENTACCESSRIGHTS = 50,
BUSY = 51,
UNAVAILABLE = 52,
UNWILLINGTOPERFORM = 53,
LOOPDETECT = 54,
NAMINGVIOLATION = 64,
OBJECTCLASSVIOLATION = 65,
NOTALLOWEDONNONLEAF = 66,
NOTALLOWEDONRDN = 67,
ENTRYALREADYEXISTS = 68,
OBJECTCLASSMODSPROHIBITED = 69,
OTHER = 80
} LDAPResultCode;
typedef struct LDAPLocationStruct LDAPLocation;
typedef struct LDAPCertPairStruct LDAPCertPair;
typedef struct LDAPSimpleBindStruct LDAPSimpleBind;
typedef struct LDAPBindAPIStruct LDAPBindAPI;
typedef struct LDAPBindStruct LDAPBind;
typedef struct LDAPResultStruct LDAPBindResponse;
typedef struct LDAPResultStruct LDAPResult;
typedef struct LDAPSearchResponseAttrStruct LDAPSearchResponseAttr;
typedef struct LDAPSearchResponseEntryStruct LDAPSearchResponseEntry;
typedef struct LDAPResultStruct LDAPSearchResponseResult;
typedef struct LDAPUnbindStruct LDAPUnbind;
typedef struct LDAPFilterStruct LDAPFilter;
typedef struct LDAPAndFilterStruct LDAPAndFilter;
typedef struct LDAPNotFilterStruct LDAPNotFilter;
typedef struct LDAPSubstringStruct LDAPSubstring;
typedef struct LDAPSubstringFilterStruct LDAPSubstringFilter;
typedef struct LDAPPresentFilterStruct LDAPPresentFilter;
typedef struct LDAPAttributeValueAssertionStruct LDAPAttributeValueAssertion;
typedef struct LDAPNameComponentStruct LDAPNameComponent;
typedef struct LDAPRequestParamsStruct LDAPRequestParams;
typedef struct LDAPSearchStruct LDAPSearch;
typedef struct LDAPAbandonRequestStruct LDAPAbandonRequest;
typedef struct protocolOpStruct LDAPProtocolOp;
typedef struct LDAPMessageStruct LDAPMessage;
typedef LDAPAndFilter LDAPOrFilter;
typedef LDAPAttributeValueAssertion LDAPEqualFilter;
typedef LDAPAttributeValueAssertion LDAPGreaterOrEqualFilter;
typedef LDAPAttributeValueAssertion LDAPLessOrEqualFilter;
typedef LDAPAttributeValueAssertion LDAPApproxMatchFilter;
struct LDAPLocationStruct {
PLArenaPool *arena;
void *serverSite;
void **filterString;
void **attrBitString;
};
struct LDAPCertPairStruct {
SECItem forward;
SECItem reverse;
};
struct LDAPSimpleBindStruct {
char *bindName;
char *authentication;
};
struct LDAPBindAPIStruct {
AuthType selector;
union {
LDAPSimpleBind simple;
} chooser;
};
struct LDAPBindStruct {
SECItem version;
SECItem bindName;
SECItem authentication;
};
struct LDAPResultStruct {
SECItem resultCode;
SECItem matchedDN;
SECItem errorMessage;
};
struct LDAPSearchResponseAttrStruct {
SECItem attrType;
SECItem **val;
};
struct LDAPSearchResponseEntryStruct {
SECItem objectName;
LDAPSearchResponseAttr **attributes;
};
struct LDAPUnbindStruct {
SECItem dummy;
};
struct LDAPAndFilterStruct {
LDAPFilter **filters;
};
struct LDAPNotFilterStruct {
LDAPFilter *filter;
};
struct LDAPSubstringStruct {
LDAPSubstringFilterType selector;
SECItem item;
};
struct LDAPSubstringFilterStruct {
SECItem attrType;
LDAPSubstring *strings;
};
struct LDAPPresentFilterStruct {
SECItem attrType;
};
struct LDAPAttributeValueAssertionStruct {
SECItem attrType;
SECItem attrValue;
};
struct LDAPFilterStruct {
LDAPFilterType selector;
union {
LDAPAndFilter andFilter;
LDAPOrFilter orFilter;
LDAPNotFilter notFilter;
LDAPEqualFilter equalFilter;
LDAPSubstringFilter substringFilter;
LDAPGreaterOrEqualFilter greaterOrEqualFilter;
LDAPLessOrEqualFilter lessOrEqualFilter;
LDAPPresentFilter presentFilter;
LDAPApproxMatchFilter approxMatchFilter;
} filter;
};
struct LDAPNameComponentStruct {
unsigned char *attrType;
unsigned char *attrValue;
};
struct LDAPRequestParamsStruct {
char *baseObject; /* e.g. "c=US" */
ScopeType scope;
DerefType derefAliases;
PKIX_UInt32 sizeLimit; /* 0 = no limit */
PRIntervalTime timeLimit; /* 0 = no limit */
LDAPNameComponent **nc; /* e.g. {{"cn","xxx"},{"o","yyy"},NULL} */
LdapAttrMask attributes;
};
struct LDAPSearchStruct {
SECItem baseObject;
SECItem scope;
SECItem derefAliases;
SECItem sizeLimit;
SECItem timeLimit;
SECItem attrsOnly;
LDAPFilter filter;
SECItem **attributes;
};
struct LDAPAbandonRequestStruct {
SECItem messageID;
};
struct protocolOpStruct {
LDAPMessageType selector;
union {
LDAPBind bindMsg;
LDAPBindResponse bindResponseMsg;
LDAPUnbind unbindMsg;
LDAPSearch searchMsg;
LDAPSearchResponseEntry searchResponseEntryMsg;
LDAPSearchResponseResult searchResponseResultMsg;
LDAPAbandonRequest abandonRequestMsg;
} op;
};
struct LDAPMessageStruct {
SECItem messageID;
LDAPProtocolOp protocolOp;
};
typedef struct PKIX_PL_LdapClientStruct PKIX_PL_LdapClient;
typedef PKIX_Error *
(*PKIX_PL_LdapClient_InitiateFcn)(
PKIX_PL_LdapClient *client,
LDAPRequestParams *requestParams,
void **pNBIO,
PKIX_List **pResponse,
void *plContext);
typedef PKIX_Error *
(*PKIX_PL_LdapClient_ResumeFcn)(
PKIX_PL_LdapClient *client,
void **pNBIO,
PKIX_List **pResponse,
void *plContext);
struct PKIX_PL_LdapClientStruct {
PKIX_PL_LdapClient_InitiateFcn initiateFcn;
PKIX_PL_LdapClient_ResumeFcn resumeFcn;
};
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,417 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "pkix_pl_ldapt.h"
SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SEC_NullTemplate)
SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
/*
* CertificatePair ::= SEQUENCE {
* forward [0] Certificate OPTIONAL,
* reverse [1] Certificate OPTIONAL
* -- at least one of the pair shall be present --
* }
*/
const SEC_ASN1Template PKIX_PL_LDAPCrossCertPairTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(LDAPCertPair) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0,
offsetof(LDAPCertPair, forward), SEC_ASN1_SUB(SEC_AnyTemplate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 1,
offsetof(LDAPCertPair, reverse), SEC_ASN1_SUB(SEC_AnyTemplate) },
{ 0 }
};
/*
* BindRequest ::=
* [APPLICATION 0] SEQUENCE {
* version INTEGER (1..127),
* name LDAPDN,
* authentication CHOICE {
* simple [0] OCTET STRING,
* krbv42LDAP [1] OCTET STRING,
* krbv42DSA [2] OCTET STRING
* }
* }
*
* LDAPDN ::= LDAPString
*
* LDAPString ::= OCTET STRING
*/
#define LDAPStringTemplate SEC_ASN1_SUB(SEC_OctetStringTemplate)
static const SEC_ASN1Template LDAPBindApplTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL },
{ SEC_ASN1_INTEGER, offsetof(LDAPBind, version) },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPBind, bindName) },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPBind, authentication) },
{ 0 }
};
static const SEC_ASN1Template LDAPBindTemplate[] = {
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_BIND_TYPE, 0,
LDAPBindApplTemplate, sizeof (LDAPBind) }
};
/*
* BindResponse ::= [APPLICATION 1] LDAPResult
*
* LDAPResult ::=
* SEQUENCE {
* resultCode ENUMERATED {
* success (0),
* operationsError (1),
* protocolError (2),
* timeLimitExceeded (3),
* sizeLimitExceeded (4),
* compareFalse (5),
* compareTrue (6),
* authMethodNotSupported (7),
* strongAuthRequired (8),
* noSuchAttribute (16),
* undefinedAttributeType (17),
* inappropriateMatching (18),
* constraintViolation (19),
* attributeOrValueExists (20),
* invalidAttributeSyntax (21),
* noSuchObject (32),
* aliasProblem (33),
* invalidDNSyntax (34),
* isLeaf (35),
* aliasDereferencingProblem (36),
* inappropriateAuthentication (48),
* invalidCredentials (49),
* insufficientAccessRights (50),
* busy (51),
* unavailable (52),
* unwillingToPerform (53),
* loopDetect (54),
* namingViolation (64),
* objectClassViolation (65),
* notAllowedOnNonLeaf (66),
* notAllowedOnRDN (67),
* entryAlreadyExists (68),
* objectClassModsProhibited (69),
* other (80)
* },
* matchedDN LDAPDN,
* errorMessage LDAPString
* }
*/
static const SEC_ASN1Template LDAPResultTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL },
{ SEC_ASN1_ENUMERATED, offsetof(LDAPResult, resultCode) },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPResult, matchedDN) },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPResult, errorMessage) },
{ 0 }
};
static const SEC_ASN1Template LDAPBindResponseTemplate[] = {
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_BINDRESPONSE_TYPE, 0,
LDAPResultTemplate, sizeof (LDAPBindResponse) }
};
/*
* UnbindRequest ::= [APPLICATION 2] NULL
*/
static const SEC_ASN1Template LDAPUnbindTemplate[] = {
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | SEC_ASN1_XTRN |
LDAP_UNBIND_TYPE , 0, SEC_ASN1_SUB(SEC_NullTemplate) }
};
/*
* AttributeValueAssertion ::=
* SEQUENCE {
* attributeType AttributeType,
* attributeValue AttributeValue,
* }
*
* AttributeType ::= LDAPString
* -- text name of the attribute, or dotted
* -- OID representation
*
* AttributeValue ::= OCTET STRING
*/
#define LDAPAttributeTypeTemplate LDAPStringTemplate
/*
* SubstringFilter ::=
* SEQUENCE {
* type AttributeType,
* SEQUENCE OF CHOICE {
* initial [0] LDAPString,
* any [1] LDAPString,
* final [2] LDAPString,
* }
* }
*/
#define LDAPSubstringFilterInitialTemplate LDAPStringTemplate
#define LDAPSubstringFilterAnyTemplate LDAPStringTemplate
#define LDAPSubstringFilterFinalTemplate LDAPStringTemplate
static const SEC_ASN1Template LDAPSubstringFilterChoiceTemplate[] = {
{ SEC_ASN1_CHOICE, offsetof(LDAPSubstring, selector), 0,
sizeof (LDAPFilter) },
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
offsetof(LDAPSubstring, item),
LDAPSubstringFilterInitialTemplate,
LDAP_INITIALSUBSTRING_TYPE },
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
offsetof(LDAPSubstring, item),
LDAPSubstringFilterAnyTemplate,
LDAP_ANYSUBSTRING_TYPE },
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
offsetof(LDAPSubstring, item),
LDAPSubstringFilterFinalTemplate,
LDAP_FINALSUBSTRING_TYPE },
{ 0 }
};
/*
* Filter ::=
* CHOICE {
* and [0] SET OF Filter,
* or [1] SET OF Filter,
* not [2] Filter,
* equalityMatch [3] AttributeValueAssertion,
* substrings [4] SubstringFilter,
* greaterOrEqual [5] AttributeValueAssertion,
* lessOrEqual [6] AttributeValueAssertion,
* present [7] AttributeType,
* approxMatch [8] AttributeValueAssertion
}
*/
static const SEC_ASN1Template LDAPSubstringFilterTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof (LDAPSubstringFilter) },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPSubstringFilter, attrType) },
{ SEC_ASN1_SEQUENCE_OF, offsetof(LDAPSubstringFilter, strings),
LDAPSubstringFilterChoiceTemplate },
{ 0 }
};
const SEC_ASN1Template LDAPFilterTemplate[]; /* forward reference */
static const SEC_ASN1Template LDAPSetOfFiltersTemplate[] = {
{ SEC_ASN1_SET_OF, 0, LDAPFilterTemplate }
};
static const SEC_ASN1Template LDAPAVAFilterTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof (LDAPAttributeValueAssertion) },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPAttributeValueAssertion, attrType) },
{ SEC_ASN1_OCTET_STRING, offsetof(LDAPAttributeValueAssertion, attrValue) },
{ 0 }
};
static const SEC_ASN1Template LDAPPresentFilterTemplate[] = {
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPPresentFilter, attrType) }
};
#define LDAPEqualFilterTemplate LDAPAVAFilterTemplate
#define LDAPGreaterOrEqualFilterTemplate LDAPAVAFilterTemplate
#define LDAPLessOrEqualFilterTemplate LDAPAVAFilterTemplate
#define LDAPApproxMatchFilterTemplate LDAPAVAFilterTemplate
const SEC_ASN1Template LDAPFilterTemplate[] = {
{ SEC_ASN1_CHOICE, offsetof(LDAPFilter, selector), 0, sizeof(LDAPFilter) },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_ANDFILTER_TYPE,
offsetof(LDAPFilter, filter.andFilter.filters),
LDAPSetOfFiltersTemplate, LDAP_ANDFILTER_TYPE },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_ORFILTER_TYPE,
offsetof(LDAPFilter, filter.orFilter.filters),
LDAPSetOfFiltersTemplate, LDAP_ORFILTER_TYPE },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_NOTFILTER_TYPE | SEC_ASN1_POINTER,
offsetof(LDAPFilter, filter.notFilter),
LDAPFilterTemplate, LDAP_NOTFILTER_TYPE },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_EQUALFILTER_TYPE,
offsetof(LDAPFilter, filter.equalFilter),
LDAPEqualFilterTemplate, LDAP_EQUALFILTER_TYPE },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_SUBSTRINGFILTER_TYPE, offsetof(LDAPFilter, filter.substringFilter),
LDAPSubstringFilterTemplate, LDAP_SUBSTRINGFILTER_TYPE },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_GREATEROREQUALFILTER_TYPE,
offsetof(LDAPFilter, filter.greaterOrEqualFilter),
LDAPGreaterOrEqualFilterTemplate, LDAP_GREATEROREQUALFILTER_TYPE },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_LESSOREQUALFILTER_TYPE,
offsetof(LDAPFilter, filter.lessOrEqualFilter),
LDAPLessOrEqualFilterTemplate, LDAP_LESSOREQUALFILTER_TYPE },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_PRESENTFILTER_TYPE,
offsetof(LDAPFilter, filter.presentFilter),
LDAPPresentFilterTemplate, LDAP_PRESENTFILTER_TYPE },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
LDAP_APPROXMATCHFILTER_TYPE,
offsetof(LDAPFilter, filter.approxMatchFilter),
LDAPApproxMatchFilterTemplate, LDAP_APPROXMATCHFILTER_TYPE },
{ 0 }
};
/*
* SearchRequest ::=
* [APPLICATION 3] SEQUENCE {
* baseObject LDAPDN,
* scope ENUMERATED {
* baseObject (0),
* singleLevel (1),
* wholeSubtree (2)
* },
* derefAliases ENUMERATED {
* neverDerefAliases (0),
* derefInSearching (1),
* derefFindingBaseObj (2),
* alwaysDerefAliases (3)
* },
* sizeLimit INTEGER (0 .. MAXINT),
* -- value of 0 implies no sizeLimit
* timeLimit INTEGER (0 .. MAXINT),
* -- value of 0 implies no timeLimit
* attrsOnly BOOLEAN,
* -- TRUE, if only attributes (without values)
* -- to be returned
* filter Filter,
* attributes SEQUENCE OF AttributeType
* }
*/
static const SEC_ASN1Template LDAPAttributeTemplate[] = {
{ SEC_ASN1_LDAP_STRING, 0, NULL, sizeof (SECItem) }
};
static const SEC_ASN1Template LDAPSearchApplTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPSearch, baseObject) },
{ SEC_ASN1_ENUMERATED, offsetof(LDAPSearch, scope) },
{ SEC_ASN1_ENUMERATED, offsetof(LDAPSearch, derefAliases) },
{ SEC_ASN1_INTEGER, offsetof(LDAPSearch, sizeLimit) },
{ SEC_ASN1_INTEGER, offsetof(LDAPSearch, timeLimit) },
{ SEC_ASN1_BOOLEAN, offsetof(LDAPSearch, attrsOnly) },
{ SEC_ASN1_INLINE, offsetof(LDAPSearch, filter), LDAPFilterTemplate },
{ SEC_ASN1_SEQUENCE_OF, offsetof(LDAPSearch, attributes), LDAPAttributeTemplate },
{ 0 }
};
static const SEC_ASN1Template LDAPSearchTemplate[] = {
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_SEARCH_TYPE, 0,
LDAPSearchApplTemplate, sizeof (LDAPSearch) }
};
/*
* SearchResponse ::=
* CHOICE {
* entry [APPLICATION 4] SEQUENCE {
* objectName LDAPDN,
* attributes SEQUENCE OF SEQUENCE {
* AttributeType,
* SET OF AttributeValue
* }
* }
* resultCode [APPLICATION 5] LDAPResult
* }
*/
static const SEC_ASN1Template LDAPSearchResponseAttrTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(LDAPSearchResponseAttr) },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPSearchResponseAttr, attrType) },
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(LDAPSearchResponseAttr, val),
LDAPStringTemplate },
{ 0 }
};
static const SEC_ASN1Template LDAPEntryTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL },
{ SEC_ASN1_LDAP_STRING, offsetof(LDAPSearchResponseEntry, objectName) },
{ SEC_ASN1_SEQUENCE_OF, offsetof(LDAPSearchResponseEntry, attributes),
LDAPSearchResponseAttrTemplate },
{ 0 }
};
static const SEC_ASN1Template LDAPSearchResponseEntryTemplate[] = {
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_SEARCHRESPONSEENTRY_TYPE, 0,
LDAPEntryTemplate, sizeof (LDAPSearchResponseEntry) }
};
static const SEC_ASN1Template LDAPSearchResponseResultTemplate[] = {
{ SEC_ASN1_APPLICATION | LDAP_SEARCHRESPONSERESULT_TYPE, 0,
LDAPResultTemplate, sizeof (LDAPSearchResponseResult) }
};
/*
* AbandonRequest ::=
* [APPLICATION 16] MessageID
*/
static const SEC_ASN1Template LDAPAbandonTemplate[] = {
{ SEC_ASN1_INTEGER, offsetof(LDAPAbandonRequest, messageID) }
};
static const SEC_ASN1Template LDAPAbandonRequestTemplate[] = {
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_ABANDONREQUEST_TYPE, 0,
LDAPAbandonTemplate, sizeof (LDAPAbandonRequest) }
};
/*
* LDAPMessage ::=
* SEQUENCE {
* messageID MessageID,
* protocolOp CHOICE {
* bindRequest BindRequest,
* bindResponse BindResponse,
* unbindRequest UnbindRequest,
* searchRequest SearchRequest,
* searchResponse SearchResponse,
* abandonRequest AbandonRequest
* }
* }
*
* (other choices exist, not shown)
*
* MessageID ::= INTEGER (0 .. maxInt)
*/
static const SEC_ASN1Template LDAPMessageProtocolOpTemplate[] = {
{ SEC_ASN1_CHOICE, offsetof(LDAPProtocolOp, selector), 0, sizeof (LDAPProtocolOp) },
{ SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.bindMsg),
LDAPBindTemplate, LDAP_BIND_TYPE },
{ SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.bindResponseMsg),
LDAPBindResponseTemplate, LDAP_BINDRESPONSE_TYPE },
{ SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.unbindMsg),
LDAPUnbindTemplate, LDAP_UNBIND_TYPE },
{ SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.searchMsg),
LDAPSearchTemplate, LDAP_SEARCH_TYPE },
{ SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.searchResponseEntryMsg),
LDAPSearchResponseEntryTemplate, LDAP_SEARCHRESPONSEENTRY_TYPE },
{ SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.searchResponseResultMsg),
LDAPSearchResponseResultTemplate, LDAP_SEARCHRESPONSERESULT_TYPE },
{ SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.abandonRequestMsg),
LDAPAbandonRequestTemplate, LDAP_ABANDONREQUEST_TYPE },
{ 0 }
};
const SEC_ASN1Template PKIX_PL_LDAPMessageTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL },
{ SEC_ASN1_INTEGER, offsetof(LDAPMessage, messageID) },
{ SEC_ASN1_INLINE, offsetof(LDAPMessage, protocolOp),
LDAPMessageProtocolOpTemplate },
{ 0 }
};
/* This function simply returns the address of the message template.
* This is necessary for Windows DLLs.
*/
SEC_ASN1_CHOOSER_IMPLEMENT(PKIX_PL_LDAPMessageTemplate)

View file

@ -0,0 +1,319 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_nsscontext.c
*
* NSSContext Function Definitions
*
*/
#include "pkix_pl_nsscontext.h"
#define PKIX_DEFAULT_MAX_RESPONSE_LENGTH 64 * 1024
#define PKIX_DEFAULT_COMM_TIMEOUT_SECONDS 60
#define PKIX_DEFAULT_CRL_RELOAD_DELAY_SECONDS 6 * 24 * 60 * 60
#define PKIX_DEFAULT_BAD_CRL_RELOAD_DELAY_SECONDS 60 * 60
/* --Public-NSSContext-Functions--------------------------- */
/*
* FUNCTION: PKIX_PL_NssContext_Create
* (see comments in pkix_samples_modules.h)
*/
PKIX_Error *
PKIX_PL_NssContext_Create(
PKIX_UInt32 certificateUsage,
PKIX_Boolean useNssArena,
void *wincx,
void **pNssContext)
{
PKIX_PL_NssContext *context = NULL;
PLArenaPool *arena = NULL;
void *plContext = NULL;
PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_Create");
PKIX_NULLCHECK_ONE(pNssContext);
PKIX_CHECK(PKIX_PL_Malloc
(sizeof(PKIX_PL_NssContext), (void **)&context, NULL),
PKIX_MALLOCFAILED);
if (useNssArena == PKIX_TRUE) {
PKIX_CONTEXT_DEBUG("\t\tCalling PORT_NewArena\n");
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
}
context->arena = arena;
context->certificateUsage = (SECCertificateUsage)certificateUsage;
context->wincx = wincx;
context->timeoutSeconds = PKIX_DEFAULT_COMM_TIMEOUT_SECONDS;
context->maxResponseLength = PKIX_DEFAULT_MAX_RESPONSE_LENGTH;
context->crlReloadDelay = PKIX_DEFAULT_CRL_RELOAD_DELAY_SECONDS;
context->badDerCrlReloadDelay =
PKIX_DEFAULT_BAD_CRL_RELOAD_DELAY_SECONDS;
context->chainVerifyCallback.isChainValid = NULL;
context->chainVerifyCallback.isChainValidArg = NULL;
*pNssContext = context;
cleanup:
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: PKIX_PL_NssContext_Destroy
* (see comments in pkix_samples_modules.h)
*/
PKIX_Error *
PKIX_PL_NssContext_Destroy(
void *nssContext)
{
void *plContext = NULL;
PKIX_PL_NssContext *context = NULL;
PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_Destroy");
PKIX_NULLCHECK_ONE(nssContext);
context = (PKIX_PL_NssContext*)nssContext;
if (context->arena != NULL) {
PKIX_CONTEXT_DEBUG("\t\tCalling PORT_FreeArena\n");
PORT_FreeArena(context->arena, PKIX_FALSE);
}
PKIX_PL_Free(nssContext, NULL);
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: pkix_pl_NssContext_GetCertUsage
* DESCRIPTION:
*
* This function obtains the platform-dependent SECCertificateUsage parameter
* from the context object pointed to by "nssContext", storing the result at
* "pCertUsage".
*
* PARAMETERS:
* "nssContext"
* The address of the context object whose wincx parameter is to be
* obtained. Must be non-NULL.
* "pCertUsage"
* The address where the result is stored. Must be non-NULL.
* 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_NssContext_GetCertUsage(
PKIX_PL_NssContext *nssContext,
SECCertificateUsage *pCertUsage)
{
void *plContext = NULL;
PKIX_ENTER(CONTEXT, "pkix_pl_NssContext_GetCertUsage");
PKIX_NULLCHECK_TWO(nssContext, pCertUsage);
*pCertUsage = nssContext->certificateUsage;
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: pkix_pl_NssContext_SetCertUsage
* DESCRIPTION:
*
* This function sets the platform-dependent SECCertificateUsage parameter in
* the context object pointed to by "nssContext" to the value provided in
* "certUsage".
*
* PARAMETERS:
* "certUsage"
* Platform-dependent value to be stored.
* "nssContext"
* The address of the context object whose wincx parameter is to be
* obtained. Must be non-NULL.
* 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_NssContext_SetCertUsage(
SECCertificateUsage certUsage,
PKIX_PL_NssContext *nssContext)
{
void *plContext = NULL;
PKIX_ENTER(CONTEXT, "pkix_pl_NssContext_SetCertUsage");
PKIX_NULLCHECK_ONE(nssContext);
nssContext->certificateUsage = certUsage;
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: pkix_pl_NssContext_GetWincx
* DESCRIPTION:
*
* This function obtains the platform-dependent wincx parameter from the
* context object pointed to by "nssContext", storing the result at "pWincx".
*
* PARAMETERS:
* "nssContext"
* The address of the context object whose wincx parameter is to be
* obtained. Must be non-NULL.
* "pWincx"
* The address where the result is stored. Must be non-NULL.
* 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_NssContext_GetWincx(
PKIX_PL_NssContext *nssContext,
void **pWincx)
{
void *plContext = NULL;
PKIX_PL_NssContext *context = NULL;
PKIX_ENTER(CONTEXT, "pkix_pl_NssContext_GetWincx");
PKIX_NULLCHECK_TWO(nssContext, pWincx);
context = (PKIX_PL_NssContext *)nssContext;
*pWincx = context->wincx;
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: pkix_pl_NssContext_SetWincx
* DESCRIPTION:
*
* This function sets the platform-dependent wincx parameter in the context
* object pointed to by "nssContext" to the value provided in "wincx".
*
* PARAMETERS:
* "wincx"
* Platform-dependent value to be stored.
* "nssContext"
* The address of the context object whose wincx parameter is to be
* obtained. Must be non-NULL.
* 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_NssContext_SetWincx(
void *wincx,
PKIX_PL_NssContext *nssContext)
{
void *plContext = NULL;
PKIX_ENTER(CONTEXT, "pkix_pl_NssContext_SetWincx");
PKIX_NULLCHECK_ONE(nssContext);
nssContext->wincx = wincx;
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: PKIX_PL_NssContext_SetTimeout
* DESCRIPTION:
*
* Sets user defined socket timeout for the validation
* session. Default is 60 seconds.
*
*/
PKIX_Error *
PKIX_PL_NssContext_SetTimeout(PKIX_UInt32 timeout,
PKIX_PL_NssContext *nssContext)
{
void *plContext = NULL;
PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_SetTimeout");
PKIX_NULLCHECK_ONE(nssContext);
nssContext->timeoutSeconds = timeout;
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: PKIX_PL_NssContext_SetMaxResponseLen
* DESCRIPTION:
*
* Sets user defined maximum transmission length of a message.
*
*/
PKIX_Error *
PKIX_PL_NssContext_SetMaxResponseLen(PKIX_UInt32 len,
PKIX_PL_NssContext *nssContext)
{
void *plContext = NULL;
PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_SetMaxResponseLen");
PKIX_NULLCHECK_ONE(nssContext);
nssContext->maxResponseLength = len;
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: PKIX_PL_NssContext_SetCrlReloadDelay
* DESCRIPTION:
*
* Sets user defined delay between attempts to load crl using
* CRLDP.
*
*/
PKIX_Error *
PKIX_PL_NssContext_SetCrlReloadDelay(PKIX_UInt32 delay,
PKIX_PL_NssContext *nssContext)
{
void *plContext = NULL;
PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_SetCrlReloadDelay");
PKIX_NULLCHECK_ONE(nssContext);
nssContext->crlReloadDelay = delay;
PKIX_RETURN(CONTEXT);
}
/*
* FUNCTION: PKIX_PL_NssContext_SetBadDerCrlReloadDelay
* DESCRIPTION:
*
* Sets user defined delay between attempts to load crl that
* failed to decode.
*
*/
PKIX_Error *
PKIX_PL_NssContext_SetBadDerCrlReloadDelay(PKIX_UInt32 delay,
PKIX_PL_NssContext *nssContext)
{
void *plContext = NULL;
PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_SetBadDerCrlReloadDelay");
PKIX_NULLCHECK_ONE(nssContext);
nssContext->badDerCrlReloadDelay = delay;
PKIX_RETURN(CONTEXT);
}

View file

@ -0,0 +1,52 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_nsscontext.h
*
* NSSContext Object Type Definition
*
*/
#ifndef _PKIX_PL_NSSCONTEXT_H
#define _PKIX_PL_NSSCONTEXT_H
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
struct PKIX_PL_NssContextStruct {
SECCertificateUsage certificateUsage;
PLArenaPool *arena;
void *wincx;
PKIX_UInt32 timeoutSeconds;
PKIX_UInt32 maxResponseLength;
PRTime crlReloadDelay;
PRTime badDerCrlReloadDelay;
CERTChainVerifyCallback chainVerifyCallback;
};
PKIX_Error *
pkix_pl_NssContext_GetCertUsage
(PKIX_PL_NssContext *nssContext, SECCertificateUsage *pCertUsage);
/* XXX move the setter into the public header. */
PKIX_Error *
pkix_pl_NssContext_SetCertUsage
(SECCertificateUsage certUsage, PKIX_PL_NssContext *nssContext);
PKIX_Error *
pkix_pl_NssContext_GetWincx(PKIX_PL_NssContext *nssContext, void **pWincx);
/* XXX move the setter into the public header. */
PKIX_Error *
pkix_pl_NssContext_SetWincx(void *wincx, PKIX_PL_NssContext *nssContext);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_NSSCONTEXT_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_pk11certstore.h
*
* PK11Certstore Object Type Definition
*
*/
#ifndef _PKIX_PL_PK11CERTSTORE_H
#define _PKIX_PL_PK11CERTSTORE_H
#include "pkix_pl_common.h"
#include "certi.h"
#ifdef __cplusplus
extern "C" {
#endif
/* see source file for function documentation */
PKIX_Error *
PKIX_PL_Pk11CertStore_Create(
PKIX_CertStore **pCertStore,
void *plContext);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_PK11CERTSTORE_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,209 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* pkix_pl_socket.h
*
* Socket Object Type Definition
*
*/
#ifndef _PKIX_PL_SOCKET_H
#define _PKIX_PL_SOCKET_H
#include <errno.h>
#include "pkix_pl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
SOCKET_BOUND,
SOCKET_LISTENING,
SOCKET_ACCEPTPENDING,
SOCKET_UNCONNECTED,
SOCKET_CONNECTPENDING,
SOCKET_CONNECTED,
SOCKET_SENDPENDING,
SOCKET_RCVPENDING,
SOCKET_SENDRCVPENDING,
SOCKET_SHUTDOWN
} SockStatus;
/* This is the default port number, if none is supplied to CreateByName. */
#define LDAP_PORT 389
/*
* These callbacks allow a user to substitute a counterfeit socket in places
* where a PKIX_PL_Socket is expected. A conforming usage will use the
* ListenCallback function instead of Listen, AcceptCallback instead of Accept,
* etc. The counterfeit socket may have special capabilites such as the
* ability to do proxy authentication, etc.
*/
typedef PKIX_Error *
(*pkix_pl_Socket_ListenCallback)(
PKIX_PL_Socket *socket,
PKIX_UInt32 backlog,
void *plContext);
typedef PKIX_Error *
(*pkix_pl_Socket_AcceptCallback)(
PKIX_PL_Socket *socket,
PKIX_PL_Socket **pRendezvousSock,
void *plContext);
typedef PKIX_Error *
(*pkix_pl_Socket_ConnectContinueCallback)(
PKIX_PL_Socket *socket,
PRErrorCode *pStatus,
void *plContext);
typedef PKIX_Error *
(*pkix_pl_Socket_SendCallback)(
PKIX_PL_Socket *sendSock,
void *buf,
PKIX_UInt32 bytesToWrite,
PKIX_Int32 *pBytesWritten,
void *plContext);
typedef PKIX_Error *
(*pkix_pl_Socket_RecvCallback)(
PKIX_PL_Socket *rcvSock,
void *buf,
PKIX_UInt32 capacity,
PKIX_Int32 *pBytesRead,
void *plContext);
typedef PKIX_Error *
(*pkix_pl_Socket_PollCallback)(
PKIX_PL_Socket *sock,
PKIX_Int32 *pBytesWritten,
PKIX_Int32 *pBytesRead,
void *plContext);
typedef PKIX_Error *
(*pkix_pl_Socket_ShutdownCallback)(
PKIX_PL_Socket *socket, void *plContext);
typedef struct PKIX_PL_Socket_CallbackStruct {
pkix_pl_Socket_ListenCallback listenCallback;
pkix_pl_Socket_AcceptCallback acceptCallback;
pkix_pl_Socket_ConnectContinueCallback connectcontinueCallback;
pkix_pl_Socket_SendCallback sendCallback;
pkix_pl_Socket_RecvCallback recvCallback;
pkix_pl_Socket_PollCallback pollCallback;
pkix_pl_Socket_ShutdownCallback shutdownCallback;
} PKIX_PL_Socket_Callback;
struct PKIX_PL_SocketStruct {
PKIX_Boolean isServer;
PRIntervalTime timeout; /* zero for non-blocking I/O */
SockStatus status;
PRFileDesc *clientSock;
PRFileDesc *serverSock;
void *readBuf;
void *writeBuf;
PKIX_UInt32 readBufSize;
PKIX_UInt32 writeBufSize;
PRNetAddr *netAddr;
PKIX_PL_Socket_Callback callbackList;
};
/* see source file for function documentation */
PKIX_Error *pkix_pl_Socket_RegisterSelf(void *plContext);
PKIX_Error *
pkix_pl_Socket_Create(
PKIX_Boolean isServer,
PRIntervalTime timeout, /* zero for non-blocking I/O */
PRNetAddr *netAddr,
PRErrorCode *status,
PKIX_PL_Socket **pSocket,
void *plContext);
PKIX_Error *
pkix_pl_Socket_CreateByName(
PKIX_Boolean isServer,
PRIntervalTime timeout,
char *serverName,
PRErrorCode *pStatus,
PKIX_PL_Socket **pSocket,
void *plContext);
PKIX_Error *
pkix_pl_Socket_CreateByHostAndPort(
PKIX_Boolean isServer,
PRIntervalTime timeout,
char *hostname,
PRUint16 portnum,
PRErrorCode *pStatus,
PKIX_PL_Socket **pSocket,
void *plContext);
/* Do not use these functions directly; use their callback variants instead
* static PKIX_Error *
* pkix_pl_Socket_Listen(
* PKIX_PL_Socket *socket,
* PKIX_UInt32 backlog,
* void *plContext);
*
* static PKIX_Error *
* pkix_pl_Socket_Accept(
* PKIX_PL_Socket *socket,
* PKIX_PL_Socket **pRendezvousSock,
* void *plContext);
*
* static PKIX_Error *
* pkix_pl_Socket_ConnectContinue(
* PKIX_PL_Socket *socket,
* PRErrorCode *pStatus,
* void *plContext);
*
* static PKIX_Error *
* pkix_pl_Socket_Send(
* PKIX_PL_Socket *sendSock,
* void *buf,
* PKIX_UInt32 bytesToWrite,
* PKIX_Int32 *pBytesWritten,
* void *plContext);
*
* static PKIX_Error *
* pkix_pl_Socket_Recv(
* PKIX_PL_Socket *rcvSock,
* void *buf,
* PKIX_UInt32 capacity,
* PKIX_Int32 *pBytesRead,
* void *plContext);
*
* static PKIX_Error *
* pkix_pl_Socket_Poll(
* PKIX_PL_Socket *sock,
* PKIX_Int32 *pBytesWritten,
* PKIX_Int32 *pBytesRead,
* void *plContext);
*
* static PKIX_Error *
* pkix_pl_Socket_Shutdown(
* PKIX_PL_Socket *socket, void *plContext);
*/
PKIX_Error *
pkix_pl_Socket_GetCallbackList(
PKIX_PL_Socket *socket,
PKIX_PL_Socket_Callback **pCallbackList,
void *plContext);
PKIX_Error *
pkix_pl_Socket_GetPRFileDesc(
PKIX_PL_Socket *socket,
PRFileDesc **pDesc,
void *plContext);
#ifdef __cplusplus
}
#endif
#endif /* _PKIX_PL_SOCKET_H */