Blame nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c

Packit 40b132
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
/*
Packit 40b132
 * pkix_pl_ldapcertstore.c
Packit 40b132
 *
Packit 40b132
 * LDAPCertStore Function Definitions
Packit 40b132
 *
Packit 40b132
 */
Packit 40b132
Packit 40b132
/* We can't decode the length of a message without at least this many bytes */
Packit 40b132
#define MINIMUM_MSG_LENGTH 5
Packit 40b132
Packit 40b132
#include "pkix_pl_ldapcertstore.h"
Packit 40b132
Packit 40b132
/* --Private-Ldap-CertStore-Database-Functions----------------------- */
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_DecodeCrossCertPair
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  This function decodes a DER-encoded CrossCertPair pointed to by
Packit 40b132
 *  "responseList" and extracts and decodes the Certificates in that pair,
Packit 40b132
 *  adding the resulting Certs, if the decoding was successful, to the List
Packit 40b132
 *  (possibly empty) pointed to by "certList". If none of the objects
Packit 40b132
 *  can be decoded into a Cert, the List is returned unchanged.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "derCCPItem"
Packit 40b132
 *      The address of the SECItem containing the DER representation of the
Packit 40b132
 *      CrossCertPair. Must be non-NULL.
Packit 40b132
 *  "certList"
Packit 40b132
 *      The address of the List to which the decoded Certs are added. May be
Packit 40b132
 *      empty, but must be non-NULL.
Packit 40b132
 *  "plContext"
Packit 40b132
 *      Platform-specific context pointer.
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CertStore Error if the function fails in a non-fatal way.
Packit 40b132
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_DecodeCrossCertPair(
Packit 40b132
        SECItem *derCCPItem,
Packit 40b132
        PKIX_List *certList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        LDAPCertPair certPair = {{ siBuffer, NULL, 0 }, { siBuffer, NULL, 0 }};
Packit 40b132
        SECStatus rv = SECFailure;
Packit 40b132
Packit 40b132
        PLArenaPool *tempArena = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_DecodeCrossCertPair");
Packit 40b132
        PKIX_NULLCHECK_TWO(derCCPItem, certList);
Packit 40b132
Packit 40b132
        tempArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
Packit 40b132
        if (!tempArena) {
Packit 40b132
            PKIX_ERROR(PKIX_OUTOFMEMORY);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        rv = SEC_ASN1DecodeItem(tempArena, &certPair, PKIX_PL_LDAPCrossCertPairTemplate,
Packit 40b132
                                derCCPItem);
Packit 40b132
        if (rv != SECSuccess) {
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if (certPair.forward.data != NULL) {
Packit 40b132
Packit 40b132
            PKIX_CHECK(
Packit 40b132
                pkix_pl_Cert_CreateToList(&certPair.forward, certList,
Packit 40b132
                                          plContext),
Packit 40b132
                PKIX_CERTCREATETOLISTFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if (certPair.reverse.data != NULL) {
Packit 40b132
Packit 40b132
            PKIX_CHECK(
Packit 40b132
                pkix_pl_Cert_CreateToList(&certPair.reverse, certList,
Packit 40b132
                                          plContext),
Packit 40b132
                PKIX_CERTCREATETOLISTFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        if (tempArena) {
Packit 40b132
            PORT_FreeArena(tempArena, PR_FALSE);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_BuildCertList
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  This function takes a List of LdapResponse objects pointed to by
Packit 40b132
 *  "responseList" and extracts and decodes the Certificates in those responses,
Packit 40b132
 *  storing the List of those Certificates at "pCerts". If none of the objects
Packit 40b132
 *  can be decoded into a Cert, the returned List is empty.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "responseList"
Packit 40b132
 *      The address of the List of LdapResponses. Must be non-NULL.
Packit 40b132
 *  "pCerts"
Packit 40b132
 *      The address at which the result is stored. Must be non-NULL.
Packit 40b132
 *  "plContext"
Packit 40b132
 *      Platform-specific context pointer.
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CertStore Error if the function fails in a non-fatal way.
Packit 40b132
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_BuildCertList(
Packit 40b132
        PKIX_List *responseList,
Packit 40b132
        PKIX_List **pCerts,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_UInt32 numResponses = 0;
Packit 40b132
        PKIX_UInt32 respIx = 0;
Packit 40b132
        LdapAttrMask attrBits = 0;
Packit 40b132
        PKIX_PL_LdapResponse *response = NULL;
Packit 40b132
        PKIX_List *certList = NULL;
Packit 40b132
        LDAPMessage *message = NULL;
Packit 40b132
        LDAPSearchResponseEntry *sre = NULL;
Packit 40b132
        LDAPSearchResponseAttr **sreAttrArray = NULL;
Packit 40b132
        LDAPSearchResponseAttr *sreAttr = NULL;
Packit 40b132
        SECItem *attrType = NULL;
Packit 40b132
        SECItem **attrVal = NULL;
Packit 40b132
        SECItem *derCertItem = NULL;
Packit 40b132
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_BuildCertList");
Packit 40b132
        PKIX_NULLCHECK_TWO(responseList, pCerts);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_List_Create(&certList, plContext),
Packit 40b132
                PKIX_LISTCREATEFAILED);
Packit 40b132
Packit 40b132
        /* extract certs from response */
Packit 40b132
        PKIX_CHECK(PKIX_List_GetLength
Packit 40b132
                (responseList, &numResponses, plContext),
Packit 40b132
                PKIX_LISTGETLENGTHFAILED);
Packit 40b132
Packit 40b132
        for (respIx = 0; respIx < numResponses; respIx++) {
Packit 40b132
                PKIX_CHECK(PKIX_List_GetItem
Packit 40b132
                        (responseList,
Packit 40b132
                        respIx,
Packit 40b132
                        (PKIX_PL_Object **)&response,
Packit 40b132
                        plContext),
Packit 40b132
                        PKIX_LISTGETITEMFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(pkix_pl_LdapResponse_GetMessage
Packit 40b132
                        (response, &message, plContext),
Packit 40b132
                        PKIX_LDAPRESPONSEGETMESSAGEFAILED);
Packit 40b132
Packit 40b132
                sre = &(message->protocolOp.op.searchResponseEntryMsg);
Packit 40b132
                sreAttrArray = sre->attributes;
Packit 40b132
Packit 40b132
                /* Get next element of null-terminated array */
Packit 40b132
                sreAttr = *sreAttrArray++;
Packit 40b132
                while (sreAttr != NULL) {
Packit 40b132
                    attrType = &(sreAttr->attrType);
Packit 40b132
                    PKIX_CHECK(pkix_pl_LdapRequest_AttrTypeToBit
Packit 40b132
                        (attrType, &attrBits, plContext),
Packit 40b132
                        PKIX_LDAPREQUESTATTRTYPETOBITFAILED);
Packit 40b132
                    /* Is this attrVal a Certificate? */
Packit 40b132
                    if (((LDAPATTR_CACERT | LDAPATTR_USERCERT) &
Packit 40b132
                            attrBits) == attrBits) {
Packit 40b132
                        attrVal = sreAttr->val;
Packit 40b132
                        derCertItem = *attrVal++;
Packit 40b132
                        while (derCertItem != 0) {
Packit 40b132
                            /* create a PKIX_PL_Cert from derCert */
Packit 40b132
                            PKIX_CHECK(pkix_pl_Cert_CreateToList
Packit 40b132
                                (derCertItem, certList, plContext),
Packit 40b132
                                PKIX_CERTCREATETOLISTFAILED);
Packit 40b132
                            derCertItem = *attrVal++;
Packit 40b132
                        }
Packit 40b132
                    } else if ((LDAPATTR_CROSSPAIRCERT & attrBits) == attrBits){
Packit 40b132
                        /* Is this attrVal a CrossPairCertificate? */
Packit 40b132
                        attrVal = sreAttr->val;
Packit 40b132
                        derCertItem = *attrVal++;
Packit 40b132
                        while (derCertItem != 0) {
Packit 40b132
                            /* create PKIX_PL_Certs from derCert */
Packit 40b132
                            PKIX_CHECK(pkix_pl_LdapCertStore_DecodeCrossCertPair
Packit 40b132
                                (derCertItem, certList, plContext),
Packit 40b132
                                PKIX_LDAPCERTSTOREDECODECROSSCERTPAIRFAILED);
Packit 40b132
                            derCertItem = *attrVal++;
Packit 40b132
                        }
Packit 40b132
                    }
Packit 40b132
                    sreAttr = *sreAttrArray++;
Packit 40b132
                }
Packit 40b132
                PKIX_DECREF(response);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pCerts = certList;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        if (PKIX_ERROR_RECEIVED) {
Packit 40b132
                PKIX_DECREF(certList);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_DECREF(response);
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_BuildCrlList
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  This function takes a List of LdapResponse objects pointed to by
Packit 40b132
 *  "responseList" and extracts and decodes the CRLs in those responses, storing
Packit 40b132
 *  the List of those CRLs at "pCrls". If none of the objects can be decoded
Packit 40b132
 *  into a CRL, the returned List is empty.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "responseList"
Packit 40b132
 *      The address of the List of LdapResponses. Must be non-NULL.
Packit 40b132
 *  "pCrls"
Packit 40b132
 *      The address at which the result is stored. Must be non-NULL.
Packit 40b132
 *  "plContext"
Packit 40b132
 *      Platform-specific context pointer.
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CertStore Error if the function fails in a non-fatal way.
Packit 40b132
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_BuildCrlList(
Packit 40b132
        PKIX_List *responseList,
Packit 40b132
        PKIX_List **pCrls,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_UInt32 numResponses = 0;
Packit 40b132
        PKIX_UInt32 respIx = 0;
Packit 40b132
        LdapAttrMask attrBits = 0;
Packit 40b132
        CERTSignedCrl *nssCrl = NULL;
Packit 40b132
        PKIX_PL_LdapResponse *response = NULL;
Packit 40b132
        PKIX_List *crlList = NULL;
Packit 40b132
        PKIX_PL_CRL *crl = NULL;
Packit 40b132
        LDAPMessage *message = NULL;
Packit 40b132
        LDAPSearchResponseEntry *sre = NULL;
Packit 40b132
        LDAPSearchResponseAttr **sreAttrArray = NULL;
Packit 40b132
        LDAPSearchResponseAttr *sreAttr = NULL;
Packit 40b132
        SECItem *attrType = NULL;
Packit 40b132
        SECItem **attrVal = NULL;
Packit 40b132
        SECItem *derCrlCopy = NULL;
Packit 40b132
        SECItem *derCrlItem = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_BuildCrlList");
Packit 40b132
        PKIX_NULLCHECK_TWO(responseList, pCrls);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_List_Create(&crlList, plContext),
Packit 40b132
                PKIX_LISTCREATEFAILED);
Packit 40b132
Packit 40b132
        /* extract crls from response */
Packit 40b132
        PKIX_CHECK(PKIX_List_GetLength
Packit 40b132
                (responseList, &numResponses, plContext),
Packit 40b132
                PKIX_LISTGETLENGTHFAILED);
Packit 40b132
Packit 40b132
        for (respIx = 0; respIx < numResponses; respIx++) {
Packit 40b132
                PKIX_CHECK(PKIX_List_GetItem
Packit 40b132
                        (responseList,
Packit 40b132
                        respIx,
Packit 40b132
                        (PKIX_PL_Object **)&response,
Packit 40b132
                        plContext),
Packit 40b132
                        PKIX_LISTGETITEMFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(pkix_pl_LdapResponse_GetMessage
Packit 40b132
                        (response, &message, plContext),
Packit 40b132
                        PKIX_LDAPRESPONSEGETMESSAGEFAILED);
Packit 40b132
Packit 40b132
                sre = &(message->protocolOp.op.searchResponseEntryMsg);
Packit 40b132
                sreAttrArray = sre->attributes;
Packit 40b132
Packit 40b132
                /* Get next element of null-terminated array */
Packit 40b132
                sreAttr = *sreAttrArray++;
Packit 40b132
                while (sreAttr != NULL) {
Packit 40b132
                    attrType = &(sreAttr->attrType);
Packit 40b132
                    PKIX_CHECK(pkix_pl_LdapRequest_AttrTypeToBit
Packit 40b132
                        (attrType, &attrBits, plContext),
Packit 40b132
                        PKIX_LDAPREQUESTATTRTYPETOBITFAILED);
Packit 40b132
                    /* Is this attrVal a Revocation List? */
Packit 40b132
                    if (((LDAPATTR_CERTREVLIST | LDAPATTR_AUTHREVLIST) &
Packit 40b132
                            attrBits) == attrBits) {
Packit 40b132
                        attrVal = sreAttr->val;
Packit 40b132
                        derCrlItem = *attrVal++;
Packit 40b132
                        while (derCrlItem != 0) {
Packit 40b132
                            /* create a PKIX_PL_Crl from derCrl */
Packit 40b132
                            derCrlCopy = SECITEM_DupItem(derCrlItem);
Packit 40b132
                            if (!derCrlCopy) {
Packit 40b132
                                PKIX_ERROR(PKIX_ALLOCERROR);
Packit 40b132
                            }
Packit 40b132
                            /* crl will be based on derCrlCopy, but wont
Packit 40b132
                             * own the der. */
Packit 40b132
                            nssCrl =
Packit 40b132
                                CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy,
Packit 40b132
                                                       SEC_CRL_TYPE,
Packit 40b132
                                                       CRL_DECODE_DONT_COPY_DER |
Packit 40b132
                                                       CRL_DECODE_SKIP_ENTRIES);
Packit 40b132
                            if (!nssCrl) {
Packit 40b132
                                SECITEM_FreeItem(derCrlCopy, PKIX_TRUE);
Packit 40b132
                                continue;
Packit 40b132
                            }
Packit 40b132
                            /* pkix crl own the der. */
Packit 40b132
                            PKIX_CHECK(
Packit 40b132
                                pkix_pl_CRL_CreateWithSignedCRL(nssCrl, 
Packit 40b132
                                       derCrlCopy, NULL, &crl, plContext),
Packit 40b132
                                PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
Packit 40b132
                            /* Left control over memory pointed by derCrlCopy and
Packit 40b132
                             * nssCrl to pkix crl. */
Packit 40b132
                            derCrlCopy = NULL;
Packit 40b132
                            nssCrl = NULL;
Packit 40b132
                            PKIX_CHECK(PKIX_List_AppendItem
Packit 40b132
                                       (crlList, (PKIX_PL_Object *) crl, plContext),
Packit 40b132
                                       PKIX_LISTAPPENDITEMFAILED);
Packit 40b132
                            PKIX_DECREF(crl);
Packit 40b132
                            derCrlItem = *attrVal++;
Packit 40b132
                        }
Packit 40b132
                        /* Clean up after PKIX_CHECK_ONLY_FATAL */
Packit 40b132
                        pkixTempErrorReceived = PKIX_FALSE;
Packit 40b132
                    }
Packit 40b132
                    sreAttr = *sreAttrArray++;
Packit 40b132
                }
Packit 40b132
                PKIX_DECREF(response);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pCrls = crlList;
Packit 40b132
        crlList = NULL;
Packit 40b132
cleanup:
Packit 40b132
        if (derCrlCopy) {
Packit 40b132
            SECITEM_FreeItem(derCrlCopy, PKIX_TRUE);
Packit 40b132
        }
Packit 40b132
        if (nssCrl) {
Packit 40b132
            SEC_DestroyCrl(nssCrl);
Packit 40b132
        }
Packit 40b132
        PKIX_DECREF(crl);
Packit 40b132
        PKIX_DECREF(crlList);
Packit 40b132
        PKIX_DECREF(response);
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_DestroyAVAList
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  This function frees the space allocated for the components of the
Packit 40b132
 *  equalFilters that make up the andFilter pointed to by "filter".
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "requestParams"
Packit 40b132
 *      The address of the andFilter whose components are to be freed. Must be
Packit 40b132
 *      non-NULL.
Packit 40b132
 *  "plContext"
Packit 40b132
 *      Platform-specific context pointer
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CertStore Error if the function fails in a non-fatal way.
Packit 40b132
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_DestroyAVAList(
Packit 40b132
        LDAPNameComponent **nameComponents,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        LDAPNameComponent **currentNC = NULL;
Packit 40b132
        unsigned char *component = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_DestroyAVAList");
Packit 40b132
        PKIX_NULLCHECK_ONE(nameComponents);
Packit 40b132
Packit 40b132
        /* Set currentNC to point to first AVA pointer */
Packit 40b132
        currentNC = nameComponents;
Packit 40b132
Packit 40b132
        while ((*currentNC) != NULL) {
Packit 40b132
                component = (*currentNC)->attrValue;
Packit 40b132
                if (component != NULL) {
Packit 40b132
                        PORT_Free(component);
Packit 40b132
                }
Packit 40b132
                currentNC++;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_MakeNameAVAList
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  This function allocates space from the arena pointed to by "arena" to
Packit 40b132
 *  construct a filter that will match components of the X500Name pointed to
Packit 40b132
 *  by "name", and stores the resulting filter at "pFilter".
Packit 40b132
 *
Packit 40b132
 *  "name" is checked for commonName and organizationName components (cn=,
Packit 40b132
 *  and o=). The component strings are extracted using the family of
Packit 40b132
 *  CERT_Get* functions, and each must be freed with PORT_Free.
Packit 40b132
 *
Packit 40b132
 *  It is not clear which components should be in a request, so, for now,
Packit 40b132
 *  we stop adding components after we have found one.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "arena"
Packit 40b132
 *      The address of the PLArenaPool used in creating the filter. Must be
Packit 40b132
 *       non-NULL.
Packit 40b132
 *  "name"
Packit 40b132
 *      The address of the X500Name whose components define the desired
Packit 40b132
 *      matches. Must be non-NULL.
Packit 40b132
 *  "pList"
Packit 40b132
 *      The address at which the result is stored.
Packit 40b132
 *  "plContext"
Packit 40b132
 *      Platform-specific context pointer
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CertStore Error if the function fails in a non-fatal way.
Packit 40b132
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_MakeNameAVAList(
Packit 40b132
        PLArenaPool *arena,
Packit 40b132
        PKIX_PL_X500Name *subjectName, 
Packit 40b132
        LDAPNameComponent ***pList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        LDAPNameComponent **setOfNameComponents;
Packit 40b132
        LDAPNameComponent *currentNameComponent = NULL;
Packit 40b132
        PKIX_UInt32 componentsPresent = 0;
Packit 40b132
        void *v = NULL;
Packit 40b132
        unsigned char *component = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_MakeNameAVAList");
Packit 40b132
        PKIX_NULLCHECK_THREE(arena, subjectName, pList);
Packit 40b132
Packit 40b132
        /* Increase this if additional components may be extracted */
Packit 40b132
#define MAX_NUM_COMPONENTS 3
Packit 40b132
Packit 40b132
        /* Space for (MAX_NUM_COMPONENTS + 1) pointers to LDAPNameComponents */
Packit 40b132
        PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZAlloc,
Packit 40b132
                (arena, (MAX_NUM_COMPONENTS + 1)*sizeof(LDAPNameComponent *)));
Packit 40b132
        setOfNameComponents = (LDAPNameComponent **)v;
Packit 40b132
Packit 40b132
        /* Space for MAX_NUM_COMPONENTS LDAPNameComponents */
Packit 40b132
        PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZNewArray,
Packit 40b132
                (arena, LDAPNameComponent, MAX_NUM_COMPONENTS));
Packit 40b132
Packit 40b132
        currentNameComponent = (LDAPNameComponent *)v;
Packit 40b132
Packit 40b132
        /* Try for commonName */
Packit 40b132
        PKIX_CHECK(pkix_pl_X500Name_GetCommonName
Packit 40b132
                (subjectName, &component, plContext),
Packit 40b132
                PKIX_X500NAMEGETCOMMONNAMEFAILED);
Packit 40b132
        if (component) {
Packit 40b132
                setOfNameComponents[componentsPresent] = currentNameComponent;
Packit 40b132
                currentNameComponent->attrType = (unsigned char *)"cn";
Packit 40b132
                currentNameComponent->attrValue = component;
Packit 40b132
                componentsPresent++;
Packit 40b132
                currentNameComponent++;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * The LDAP specification says we can send multiple name components
Packit 40b132
         * in an "AND" filter, but the LDAP Servers don't seem to be able to
Packit 40b132
         * handle such requests. So we'll quit after the cn component.
Packit 40b132
         */
Packit 40b132
#if 0
Packit 40b132
        /* Try for orgName */
Packit 40b132
        PKIX_CHECK(pkix_pl_X500Name_GetOrgName
Packit 40b132
                (subjectName, &component, plContext),
Packit 40b132
                PKIX_X500NAMEGETORGNAMEFAILED);
Packit 40b132
        if (component) {
Packit 40b132
                setOfNameComponents[componentsPresent] = currentNameComponent;
Packit 40b132
                currentNameComponent->attrType = (unsigned char *)"o";
Packit 40b132
                currentNameComponent->attrValue = component;
Packit 40b132
                componentsPresent++;
Packit 40b132
                currentNameComponent++;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /* Try for countryName */
Packit 40b132
        PKIX_CHECK(pkix_pl_X500Name_GetCountryName
Packit 40b132
                (subjectName, &component, plContext),
Packit 40b132
                PKIX_X500NAMEGETCOUNTRYNAMEFAILED);
Packit 40b132
        if (component) {
Packit 40b132
                setOfNameComponents[componentsPresent] = currentNameComponent;
Packit 40b132
                currentNameComponent->attrType = (unsigned char *)"c";
Packit 40b132
                currentNameComponent->attrValue = component;
Packit 40b132
                componentsPresent++;
Packit 40b132
                currentNameComponent++;
Packit 40b132
        }
Packit 40b132
#endif
Packit 40b132
Packit 40b132
        setOfNameComponents[componentsPresent] = NULL;
Packit 40b132
Packit 40b132
        *pList = setOfNameComponents;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
Packit 40b132
}
Packit 40b132
Packit 40b132
#if 0
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertstore_ConvertCertResponses
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  This function processes the List of LDAPResponses pointed to by "responses"
Packit 40b132
 *  into a List of resulting Certs, storing the result at "pCerts". If there
Packit 40b132
 *  are no responses converted successfully, a NULL may be stored.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "responses"
Packit 40b132
 *      The LDAPResponses whose contents are to be converted. Must be non-NULL.
Packit 40b132
 *  "pCerts"
Packit 40b132
 *      Address at which the returned List is stored. Must be non-NULL.
Packit 40b132
 *  "plContext"
Packit 40b132
 *      Platform-specific context pointer.
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CertStore Error if the function fails in a non-fatal way
Packit 40b132
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_ConvertCertResponses(
Packit 40b132
        PKIX_List *responses,
Packit 40b132
        PKIX_List **pCerts,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_List *unfiltered = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_ConvertCertResponses");
Packit 40b132
        PKIX_NULLCHECK_TWO(responses, pCerts);
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * We have a List of LdapResponse objects that have to be
Packit 40b132
         * turned into Certs.
Packit 40b132
         */
Packit 40b132
        PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
Packit 40b132
                (responses, &unfiltered, plContext),
Packit 40b132
                PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
Packit 40b132
Packit 40b132
        *pCerts = unfiltered;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
#endif
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_GetCert
Packit 40b132
 *  (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_GetCert(
Packit 40b132
        PKIX_CertStore *store,
Packit 40b132
        PKIX_CertSelector *selector,
Packit 40b132
        PKIX_VerifyNode *verifyNode,
Packit 40b132
        void **pNBIOContext,
Packit 40b132
        PKIX_List **pCertList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PLArenaPool *requestArena = NULL;
Packit 40b132
        LDAPRequestParams requestParams;
Packit 40b132
        void *pollDesc = NULL;
Packit 40b132
        PKIX_Int32 minPathLen = 0;
Packit 40b132
        PKIX_Boolean cacheFlag = PKIX_FALSE;
Packit 40b132
        PKIX_ComCertSelParams *params = NULL;
Packit 40b132
        PKIX_PL_LdapCertStoreContext *lcs = NULL;
Packit 40b132
        PKIX_List *responses = NULL;
Packit 40b132
        PKIX_List *unfilteredCerts = NULL;
Packit 40b132
        PKIX_List *filteredCerts = NULL;
Packit 40b132
        PKIX_PL_X500Name *subjectName = 0;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCert");
Packit 40b132
        PKIX_NULLCHECK_THREE(store, selector, pCertList);
Packit 40b132
Packit 40b132
        requestParams.baseObject = "c=US";
Packit 40b132
        requestParams.scope = WHOLE_SUBTREE;
Packit 40b132
        requestParams.derefAliases = NEVER_DEREF;
Packit 40b132
        requestParams.sizeLimit = 0;
Packit 40b132
        requestParams.timeLimit = 0;
Packit 40b132
Packit 40b132
        /* Prepare elements for request filter */
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * Get a short-lived arena. We'll be done with this space once
Packit 40b132
         * the request is encoded.
Packit 40b132
         */
Packit 40b132
        requestArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
Packit 40b132
        if (!requestArena) {
Packit 40b132
                PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
Packit 40b132
                (selector, &params, plContext),
Packit 40b132
                PKIX_CERTSELECTORGETCOMCERTSELPARAMSFAILED);
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * If we have the subject name for the desired subject,
Packit 40b132
         * ask the server for Certs with that subject.
Packit 40b132
         */
Packit 40b132
        PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
Packit 40b132
                (params, &subjectName, plContext),
Packit 40b132
                PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints
Packit 40b132
                (params, &minPathLen, plContext),
Packit 40b132
                PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED);
Packit 40b132
Packit 40b132
        if (subjectName) {
Packit 40b132
                PKIX_CHECK(pkix_pl_LdapCertStore_MakeNameAVAList
Packit 40b132
                        (requestArena,
Packit 40b132
                        subjectName,
Packit 40b132
                        &(requestParams.nc),
Packit 40b132
                        plContext),
Packit 40b132
                        PKIX_LDAPCERTSTOREMAKENAMEAVALISTFAILED);
Packit 40b132
Packit 40b132
                if (*requestParams.nc == NULL) {
Packit 40b132
                        /*
Packit 40b132
                         * The subjectName may not include any components
Packit 40b132
                         * that we know how to encode. We do not return
Packit 40b132
                         * an error, because the caller did not necessarily
Packit 40b132
                         * do anything wrong, but we return an empty List.
Packit 40b132
                         */
Packit 40b132
                        PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
Packit 40b132
                                (requestArena, PR_FALSE));
Packit 40b132
Packit 40b132
                        PKIX_CHECK(PKIX_List_Create(&filteredCerts, plContext),
Packit 40b132
                                PKIX_LISTCREATEFAILED);
Packit 40b132
Packit 40b132
                        PKIX_CHECK(PKIX_List_SetImmutable
Packit 40b132
                                (filteredCerts, plContext),
Packit 40b132
                                PKIX_LISTSETIMMUTABLEFAILED);
Packit 40b132
Packit 40b132
                        *pNBIOContext = NULL;
Packit 40b132
                        *pCertList = filteredCerts;
Packit 40b132
                        filteredCerts = NULL;
Packit 40b132
                        goto cleanup;
Packit 40b132
                }
Packit 40b132
        } else {
Packit 40b132
                PKIX_ERROR(PKIX_INSUFFICIENTCRITERIAFORCERTQUERY);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /* Prepare attribute field of request */
Packit 40b132
Packit 40b132
        requestParams.attributes = 0;
Packit 40b132
Packit 40b132
        if (minPathLen < 0) {
Packit 40b132
                requestParams.attributes |= LDAPATTR_USERCERT;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if (minPathLen > -2) {
Packit 40b132
                requestParams.attributes |=
Packit 40b132
                        LDAPATTR_CACERT | LDAPATTR_CROSSPAIRCERT;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /* All request fields are done */
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
Packit 40b132
                (store, (PKIX_PL_Object **)&lcs, plContext),
Packit 40b132
                PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
Packit 40b132
                ((PKIX_PL_LdapClient *)lcs,
Packit 40b132
                &requestParams,
Packit 40b132
                &pollDesc,
Packit 40b132
                &responses,
Packit 40b132
                plContext),
Packit 40b132
                PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_pl_LdapCertStore_DestroyAVAList
Packit 40b132
                (requestParams.nc, plContext),
Packit 40b132
                PKIX_LDAPCERTSTOREDESTROYAVALISTFAILED);
Packit 40b132
Packit 40b132
        if (requestArena) {
Packit 40b132
                PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
Packit 40b132
                        (requestArena, PR_FALSE));
Packit 40b132
                requestArena = NULL;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if (pollDesc != NULL) {
Packit 40b132
                /* client is waiting for non-blocking I/O to complete */
Packit 40b132
                *pNBIOContext = (void *)pollDesc;
Packit 40b132
                *pCertList = NULL;
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
        /* LdapClient has given us a response! */
Packit 40b132
Packit 40b132
        if (responses) {
Packit 40b132
                PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
Packit 40b132
                        (store, &cacheFlag, plContext),
Packit 40b132
                        PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
Packit 40b132
                        (responses, &unfilteredCerts, plContext),
Packit 40b132
                        PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(pkix_CertSelector_Select
Packit 40b132
                        (selector, unfilteredCerts, &filteredCerts, plContext),
Packit 40b132
                        PKIX_CERTSELECTORSELECTFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pNBIOContext = NULL;
Packit 40b132
        *pCertList = filteredCerts;
Packit 40b132
        filteredCerts = NULL;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_DECREF(params);
Packit 40b132
        PKIX_DECREF(subjectName);
Packit 40b132
        PKIX_DECREF(responses);
Packit 40b132
        PKIX_DECREF(unfilteredCerts);
Packit 40b132
        PKIX_DECREF(filteredCerts);
Packit 40b132
        PKIX_DECREF(lcs);
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_GetCertContinue
Packit 40b132
 *  (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_GetCertContinue(
Packit 40b132
        PKIX_CertStore *store,
Packit 40b132
        PKIX_CertSelector *selector,
Packit 40b132
        PKIX_VerifyNode *verifyNode,
Packit 40b132
        void **pNBIOContext,
Packit 40b132
        PKIX_List **pCertList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_Boolean cacheFlag = PKIX_FALSE;
Packit 40b132
        PKIX_PL_LdapCertStoreContext *lcs = NULL;
Packit 40b132
        void *pollDesc = NULL;
Packit 40b132
        PKIX_List *responses = NULL;
Packit 40b132
        PKIX_List *unfilteredCerts = NULL;
Packit 40b132
        PKIX_List *filteredCerts = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCertContinue");
Packit 40b132
        PKIX_NULLCHECK_THREE(store, selector, pCertList);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
Packit 40b132
                (store, (PKIX_PL_Object **)&lcs, plContext),
Packit 40b132
                PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
Packit 40b132
                ((PKIX_PL_LdapClient *)lcs, &pollDesc, &responses, plContext),
Packit 40b132
                PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
Packit 40b132
Packit 40b132
        if (pollDesc != NULL) {
Packit 40b132
                /* client is waiting for non-blocking I/O to complete */
Packit 40b132
                *pNBIOContext = (void *)pollDesc;
Packit 40b132
                *pCertList = NULL;
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
        /* LdapClient has given us a response! */
Packit 40b132
Packit 40b132
        if (responses) {
Packit 40b132
                PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
Packit 40b132
                        (store, &cacheFlag, plContext),
Packit 40b132
                        PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
Packit 40b132
                        (responses, &unfilteredCerts, plContext),
Packit 40b132
                        PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(pkix_CertSelector_Select
Packit 40b132
                        (selector, unfilteredCerts, &filteredCerts, plContext),
Packit 40b132
                        PKIX_CERTSELECTORSELECTFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pNBIOContext = NULL;
Packit 40b132
        *pCertList = filteredCerts;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_DECREF(responses);
Packit 40b132
        PKIX_DECREF(unfilteredCerts);
Packit 40b132
        PKIX_DECREF(lcs);
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_GetCRL
Packit 40b132
 *  (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_GetCRL(
Packit 40b132
        PKIX_CertStore *store,
Packit 40b132
        PKIX_CRLSelector *selector,
Packit 40b132
        void **pNBIOContext,
Packit 40b132
        PKIX_List **pCrlList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        LDAPRequestParams requestParams;
Packit 40b132
        void *pollDesc = NULL;
Packit 40b132
        PLArenaPool *requestArena = NULL;
Packit 40b132
        PKIX_UInt32 numNames = 0;
Packit 40b132
        PKIX_UInt32 thisName = 0;
Packit 40b132
        PKIX_PL_CRL *candidate = NULL;
Packit 40b132
        PKIX_List *responses = NULL;
Packit 40b132
        PKIX_List *issuerNames = NULL;
Packit 40b132
        PKIX_List *filteredCRLs = NULL;
Packit 40b132
        PKIX_List *unfilteredCRLs = NULL;
Packit 40b132
        PKIX_PL_X500Name *issuer = NULL;
Packit 40b132
        PKIX_PL_LdapCertStoreContext *lcs = NULL;
Packit 40b132
        PKIX_ComCRLSelParams *params = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCRL");
Packit 40b132
        PKIX_NULLCHECK_THREE(store, selector, pCrlList);
Packit 40b132
Packit 40b132
        requestParams.baseObject = "c=US";
Packit 40b132
        requestParams.scope = WHOLE_SUBTREE;
Packit 40b132
        requestParams.derefAliases = NEVER_DEREF;
Packit 40b132
        requestParams.sizeLimit = 0;
Packit 40b132
        requestParams.timeLimit = 0;
Packit 40b132
        requestParams.attributes = LDAPATTR_CERTREVLIST | LDAPATTR_AUTHREVLIST;
Packit 40b132
        /* Prepare elements for request filter */
Packit 40b132
Packit 40b132
        /* XXX Place CRLDP code here. Handle the case when */
Packit 40b132
        /* RFC 5280. Paragraph: 4.2.1.13: */
Packit 40b132
        /* If the distributionPoint field contains a directoryName, the entry */
Packit 40b132
        /* for that directoryName contains the current CRL for the associated */
Packit 40b132
        /* reasons and the CRL is issued by the associated cRLIssuer.  The CRL */
Packit 40b132
        /* may be stored in either the certificateRevocationList or */
Packit 40b132
        /* authorityRevocationList attribute.  The CRL is to be obtained by the */
Packit 40b132
        /* application from whatever directory server is locally configured. */
Packit 40b132
        /* The protocol the application uses to access the directory (e.g., DAP */
Packit 40b132
        /* or LDAP) is a local matter. */
Packit 40b132
Packit 40b132
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * Get a short-lived arena. We'll be done with this space once
Packit 40b132
         * the request is encoded.
Packit 40b132
         */
Packit 40b132
        PKIX_PL_NSSCALLRV
Packit 40b132
            (CERTSTORE, requestArena, PORT_NewArena, (DER_DEFAULT_CHUNKSIZE));
Packit 40b132
Packit 40b132
        if (!requestArena) {
Packit 40b132
                PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CRLSelector_GetCommonCRLSelectorParams
Packit 40b132
                (selector, &params, plContext),
Packit 40b132
                PKIX_CRLSELECTORGETCOMCERTSELPARAMSFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_ComCRLSelParams_GetIssuerNames
Packit 40b132
                (params, &issuerNames, plContext),
Packit 40b132
                PKIX_COMCRLSELPARAMSGETISSUERNAMESFAILED);
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * The specification for PKIX_ComCRLSelParams_GetIssuerNames in
Packit 40b132
         * pkix_crlsel.h says that if the criterion is not set we get a null
Packit 40b132
         * pointer. If we get an empty List the criterion is impossible to
Packit 40b132
         * meet ("must match at least one of the names in the List").
Packit 40b132
         */
Packit 40b132
        if (issuerNames) {
Packit 40b132
Packit 40b132
                PKIX_CHECK(PKIX_List_GetLength
Packit 40b132
                        (issuerNames, &numNames, plContext),
Packit 40b132
                        PKIX_LISTGETLENGTHFAILED);
Packit 40b132
Packit 40b132
                if (numNames > 0) {
Packit 40b132
                        for (thisName = 0; thisName < numNames; thisName++) {
Packit 40b132
                                PKIX_CHECK(PKIX_List_GetItem
Packit 40b132
                                (issuerNames,
Packit 40b132
                                thisName,
Packit 40b132
                                (PKIX_PL_Object **)&issuer,
Packit 40b132
                                plContext),
Packit 40b132
                                PKIX_LISTGETITEMFAILED);
Packit 40b132
Packit 40b132
                                PKIX_CHECK
Packit 40b132
                                        (pkix_pl_LdapCertStore_MakeNameAVAList
Packit 40b132
                                        (requestArena,
Packit 40b132
                                        issuer,
Packit 40b132
                                        &(requestParams.nc),
Packit 40b132
                                        plContext),
Packit 40b132
                                        PKIX_LDAPCERTSTOREMAKENAMEAVALISTFAILED);
Packit 40b132
Packit 40b132
                                PKIX_DECREF(issuer);
Packit 40b132
Packit 40b132
                                if (*requestParams.nc == NULL) {
Packit 40b132
                                        /*
Packit 40b132
                                         * The issuer may not include any
Packit 40b132
                                         * components that we know how to
Packit 40b132
                                         * encode. We do not return an error,
Packit 40b132
                                         * because the caller did not
Packit 40b132
                                         * necessarily do anything wrong, but
Packit 40b132
                                         * we return an empty List.
Packit 40b132
                                         */
Packit 40b132
                                        PKIX_PL_NSSCALL
Packit 40b132
                                                (CERTSTORE, PORT_FreeArena,
Packit 40b132
                                                (requestArena, PR_FALSE));
Packit 40b132
Packit 40b132
                                        PKIX_CHECK(PKIX_List_Create
Packit 40b132
                                                (&filteredCRLs, plContext),
Packit 40b132
                                                PKIX_LISTCREATEFAILED);
Packit 40b132
Packit 40b132
                                        PKIX_CHECK(PKIX_List_SetImmutable
Packit 40b132
                                                (filteredCRLs, plContext),
Packit 40b132
                                               PKIX_LISTSETIMMUTABLEFAILED);
Packit 40b132
Packit 40b132
                                        *pNBIOContext = NULL;
Packit 40b132
                                        *pCrlList = filteredCRLs;
Packit 40b132
                                        goto cleanup;
Packit 40b132
                                }
Packit 40b132
Packit 40b132
                                /*
Packit 40b132
                                 * LDAP Servers don't seem to be able to handle
Packit 40b132
                                 * requests with more than more than one name.
Packit 40b132
                                 */
Packit 40b132
                                break;
Packit 40b132
                        }
Packit 40b132
                } else {
Packit 40b132
                        PKIX_ERROR(PKIX_IMPOSSIBLECRITERIONFORCRLQUERY);
Packit 40b132
                }
Packit 40b132
        } else {
Packit 40b132
                PKIX_ERROR(PKIX_IMPOSSIBLECRITERIONFORCRLQUERY);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /* All request fields are done */
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
Packit 40b132
                (store, (PKIX_PL_Object **)&lcs, plContext),
Packit 40b132
                PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
Packit 40b132
                ((PKIX_PL_LdapClient *)lcs,
Packit 40b132
                &requestParams,
Packit 40b132
                &pollDesc,
Packit 40b132
                &responses,
Packit 40b132
                plContext),
Packit 40b132
                PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_pl_LdapCertStore_DestroyAVAList
Packit 40b132
                (requestParams.nc, plContext),
Packit 40b132
                PKIX_LDAPCERTSTOREDESTROYAVALISTFAILED);
Packit 40b132
Packit 40b132
        if (requestArena) {
Packit 40b132
                PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
Packit 40b132
                        (requestArena, PR_FALSE));
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if (pollDesc != NULL) {
Packit 40b132
                /* client is waiting for non-blocking I/O to complete */
Packit 40b132
                *pNBIOContext = (void *)pollDesc;
Packit 40b132
                *pCrlList = NULL;
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
        /* client has finished! */
Packit 40b132
Packit 40b132
        if (responses) {
Packit 40b132
Packit 40b132
                /*
Packit 40b132
                 * We have a List of LdapResponse objects that still have to be
Packit 40b132
                 * turned into Crls.
Packit 40b132
                 */
Packit 40b132
                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCrlList
Packit 40b132
                        (responses, &unfilteredCRLs, plContext),
Packit 40b132
                        PKIX_LDAPCERTSTOREBUILDCRLLISTFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(pkix_CRLSelector_Select
Packit 40b132
                        (selector, unfilteredCRLs, &filteredCRLs, plContext),
Packit 40b132
                        PKIX_CRLSELECTORSELECTFAILED);
Packit 40b132
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /* Don't throw away the list if one CRL was bad! */
Packit 40b132
        pkixTempErrorReceived = PKIX_FALSE;
Packit 40b132
Packit 40b132
        *pNBIOContext = NULL;
Packit 40b132
        *pCrlList = filteredCRLs;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        if (PKIX_ERROR_RECEIVED) {
Packit 40b132
                PKIX_DECREF(filteredCRLs);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_DECREF(params);
Packit 40b132
        PKIX_DECREF(issuerNames);
Packit 40b132
        PKIX_DECREF(issuer);
Packit 40b132
        PKIX_DECREF(candidate);
Packit 40b132
        PKIX_DECREF(responses);
Packit 40b132
        PKIX_DECREF(unfilteredCRLs);
Packit 40b132
        PKIX_DECREF(lcs);
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_LdapCertStore_GetCRLContinue
Packit 40b132
 *  (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_LdapCertStore_GetCRLContinue(
Packit 40b132
        PKIX_CertStore *store,
Packit 40b132
        PKIX_CRLSelector *selector,
Packit 40b132
        void **pNBIOContext,
Packit 40b132
        PKIX_List **pCrlList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        void *nbio = NULL;
Packit 40b132
        PKIX_PL_CRL *candidate = NULL;
Packit 40b132
        PKIX_List *responses = NULL;
Packit 40b132
        PKIX_PL_LdapCertStoreContext *lcs = NULL;
Packit 40b132
        PKIX_List *filteredCRLs = NULL;
Packit 40b132
        PKIX_List *unfilteredCRLs = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCRLContinue");
Packit 40b132
        PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCrlList);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
Packit 40b132
                (store, (PKIX_PL_Object **)&lcs, plContext),
Packit 40b132
                PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
Packit 40b132
                ((PKIX_PL_LdapClient *)lcs, &nbio, &responses, plContext),
Packit 40b132
                PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
Packit 40b132
Packit 40b132
        if (nbio != NULL) {
Packit 40b132
                /* client is waiting for non-blocking I/O to complete */
Packit 40b132
                *pNBIOContext = (void *)nbio;
Packit 40b132
                *pCrlList = NULL;
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
        /* client has finished! */
Packit 40b132
Packit 40b132
        if (responses) {
Packit 40b132
Packit 40b132
                /*
Packit 40b132
                 * We have a List of LdapResponse objects that still have to be
Packit 40b132
                 * turned into Crls.
Packit 40b132
                 */
Packit 40b132
                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCrlList
Packit 40b132
                        (responses, &unfilteredCRLs, plContext),
Packit 40b132
                        PKIX_LDAPCERTSTOREBUILDCRLLISTFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(pkix_CRLSelector_Select
Packit 40b132
                        (selector, unfilteredCRLs, &filteredCRLs, plContext),
Packit 40b132
                        PKIX_CRLSELECTORSELECTFAILED);
Packit 40b132
Packit 40b132
                PKIX_CHECK(PKIX_List_SetImmutable(filteredCRLs, plContext),
Packit 40b132
                        PKIX_LISTSETIMMUTABLEFAILED);
Packit 40b132
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /* Don't throw away the list if one CRL was bad! */
Packit 40b132
        pkixTempErrorReceived = PKIX_FALSE;
Packit 40b132
Packit 40b132
        *pCrlList = filteredCRLs;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        if (PKIX_ERROR_RECEIVED) {
Packit 40b132
                PKIX_DECREF(filteredCRLs);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_DECREF(candidate);
Packit 40b132
        PKIX_DECREF(responses);
Packit 40b132
        PKIX_DECREF(unfilteredCRLs);
Packit 40b132
        PKIX_DECREF(lcs);
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/* --Public-LdapCertStore-Functions----------------------------------- */
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: PKIX_PL_LdapCertStore_Create
Packit 40b132
 * (see comments in pkix_samples_modules.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
PKIX_PL_LdapCertStore_Create(
Packit 40b132
        PKIX_PL_LdapClient *client,
Packit 40b132
        PKIX_CertStore **pCertStore,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_CertStore *certStore = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "PKIX_PL_LdapCertStore_Create");
Packit 40b132
        PKIX_NULLCHECK_TWO(client, pCertStore);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertStore_Create
Packit 40b132
                (pkix_pl_LdapCertStore_GetCert,
Packit 40b132
                pkix_pl_LdapCertStore_GetCRL,
Packit 40b132
                pkix_pl_LdapCertStore_GetCertContinue,
Packit 40b132
                pkix_pl_LdapCertStore_GetCRLContinue,
Packit 40b132
                NULL,       /* don't support trust */
Packit 40b132
                NULL,      /* can not store crls */
Packit 40b132
                NULL,      /* can not do revocation check */
Packit 40b132
                (PKIX_PL_Object *)client,
Packit 40b132
                PKIX_TRUE,  /* cache flag */
Packit 40b132
                PKIX_FALSE, /* not local */
Packit 40b132
                &certStore,
Packit 40b132
                plContext),
Packit 40b132
                PKIX_CERTSTORECREATEFAILED);
Packit 40b132
Packit 40b132
        *pCertStore = certStore;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}