Blame nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.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_colcertstore.c
Packit 40b132
 *
Packit 40b132
 * CollectionCertStore Function Definitions
Packit 40b132
 *
Packit 40b132
 */
Packit 40b132
Packit 40b132
#include "pkix_pl_colcertstore.h"
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * This Object is going to be taken out from libpkix SOON. The following
Packit 40b132
 * function is copied from nss/cmd library, but not supported by NSS as
Packit 40b132
 * public API. We use it since ColCertStore are read in Cert/Crl from
Packit 40b132
 * files and need this support.
Packit 40b132
 */
Packit 40b132
Packit 40b132
static SECStatus
Packit 40b132
SECU_FileToItem(SECItem *dst, PRFileDesc *src)
Packit 40b132
{
Packit 40b132
    PRFileInfo info;
Packit 40b132
    PRInt32 numBytes;
Packit 40b132
    PRStatus prStatus;
Packit 40b132
Packit 40b132
    prStatus = PR_GetOpenFileInfo(src, &info;;
Packit 40b132
Packit 40b132
    if (prStatus != PR_SUCCESS) {
Packit 40b132
        PORT_SetError(SEC_ERROR_IO);
Packit 40b132
        return SECFailure;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* XXX workaround for 3.1, not all utils zero dst before sending */
Packit 40b132
    dst->data = 0;
Packit 40b132
    if (!SECITEM_AllocItem(NULL, dst, info.size))
Packit 40b132
        goto loser;
Packit 40b132
Packit 40b132
    numBytes = PR_Read(src, dst->data, info.size);
Packit 40b132
    if (numBytes != info.size) {
Packit 40b132
        PORT_SetError(SEC_ERROR_IO);
Packit 40b132
        goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return SECSuccess;
Packit 40b132
loser:
Packit 40b132
    SECITEM_FreeItem(dst, PR_FALSE);
Packit 40b132
    return SECFailure;
Packit 40b132
}
Packit 40b132
Packit 40b132
static SECStatus
Packit 40b132
SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii)
Packit 40b132
{
Packit 40b132
    SECStatus rv;
Packit 40b132
    if (ascii) {
Packit 40b132
        /* First convert ascii to binary */
Packit 40b132
        SECItem filedata;
Packit 40b132
        char *asc, *body;
Packit 40b132
Packit 40b132
        /* Read in ascii data */
Packit 40b132
        rv = SECU_FileToItem(&filedata, inFile);
Packit 40b132
        asc = (char *)filedata.data;
Packit 40b132
        if (!asc) {
Packit 40b132
            fprintf(stderr, "unable to read data from input file\n");
Packit 40b132
            return SECFailure;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /* check for headers and trailers and remove them */
Packit 40b132
        if ((body = strstr(asc, "-----BEGIN")) != NULL) {
Packit 40b132
            char *trailer = NULL;
Packit 40b132
            asc = body;
Packit 40b132
            body = PORT_Strchr(body, '\n');
Packit 40b132
            if (!body)
Packit 40b132
                body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */
Packit 40b132
            if (body)
Packit 40b132
                trailer = strstr(++body, "-----END");
Packit 40b132
            if (trailer != NULL) {
Packit 40b132
                *trailer = '\0';
Packit 40b132
            } else {
Packit 40b132
                fprintf(stderr, "input has header but no trailer\n");
Packit 40b132
                PORT_Free(filedata.data);
Packit 40b132
                return SECFailure;
Packit 40b132
            }
Packit 40b132
        } else {
Packit 40b132
            body = asc;
Packit 40b132
        }
Packit 40b132
     
Packit 40b132
        /* Convert to binary */
Packit 40b132
        rv = ATOB_ConvertAsciiToItem(der, body);
Packit 40b132
        if (rv) {
Packit 40b132
            return SECFailure;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PORT_Free(filedata.data);
Packit 40b132
    } else {
Packit 40b132
        /* Read in binary der */
Packit 40b132
        rv = SECU_FileToItem(der, inFile);
Packit 40b132
        if (rv) {
Packit 40b132
            return SECFailure;
Packit 40b132
        }
Packit 40b132
    }
Packit 40b132
    return SECSuccess;
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: PKIX_PL_CollectionCertStoreContext_Create
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Creates a new CollectionCertStoreContext using the String pointed to
Packit 40b132
 *  by "storeDir" and stores it at "pColCertStoreContext".
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "storeDir"
Packit 40b132
 *      The absolute path where *.crl and *.crt files are located.
Packit 40b132
 *  "pColCertStoreContext"
Packit 40b132
 *      Address where object pointer will be 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 CollectionCertStoreContext Error if the function fails in
Packit 40b132
 *      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_CollectionCertStoreContext_Create(
Packit 40b132
        PKIX_PL_String *storeDir,
Packit 40b132
        PKIX_PL_CollectionCertStoreContext **pColCertStoreContext,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_Create");
Packit 40b132
        PKIX_NULLCHECK_TWO(storeDir, pColCertStoreContext);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_Object_Alloc
Packit 40b132
                    (PKIX_COLLECTIONCERTSTORECONTEXT_TYPE,
Packit 40b132
                    sizeof (PKIX_PL_CollectionCertStoreContext),
Packit 40b132
                    (PKIX_PL_Object **)&colCertStoreContext,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_COULDNOTCREATECOLLECTIONCERTSTORECONTEXTOBJECT);
Packit 40b132
Packit 40b132
        PKIX_INCREF(storeDir);
Packit 40b132
        colCertStoreContext->storeDir = storeDir;
Packit 40b132
Packit 40b132
        colCertStoreContext->crlList = NULL;
Packit 40b132
        colCertStoreContext->certList = NULL;
Packit 40b132
Packit 40b132
        *pColCertStoreContext = colCertStoreContext;
Packit 40b132
        colCertStoreContext = NULL;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_DECREF(colCertStoreContext);
Packit 40b132
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_Destroy
Packit 40b132
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_CollectionCertStoreContext_Destroy(
Packit 40b132
        PKIX_PL_Object *object,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_Destroy");
Packit 40b132
        PKIX_NULLCHECK_ONE(object);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_CheckType
Packit 40b132
                    (object, PKIX_COLLECTIONCERTSTORECONTEXT_TYPE, plContext),
Packit 40b132
                    PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT);
Packit 40b132
Packit 40b132
        colCertStoreContext = (PKIX_PL_CollectionCertStoreContext *)object;
Packit 40b132
Packit 40b132
        PKIX_DECREF(colCertStoreContext->storeDir);
Packit 40b132
        PKIX_DECREF(colCertStoreContext->crlList);
Packit 40b132
        PKIX_DECREF(colCertStoreContext->certList);
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_Hashcode
Packit 40b132
 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_CollectionCertStoreContext_Hashcode(
Packit 40b132
        PKIX_PL_Object *object,
Packit 40b132
        PKIX_UInt32 *pHashcode,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *collectionCSContext = NULL;
Packit 40b132
        PKIX_UInt32 tempHash = 0;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_Hashcode");
Packit 40b132
        PKIX_NULLCHECK_TWO(object, pHashcode);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_CheckType
Packit 40b132
                    (object,
Packit 40b132
                    PKIX_COLLECTIONCERTSTORECONTEXT_TYPE,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT);
Packit 40b132
Packit 40b132
        collectionCSContext = (PKIX_PL_CollectionCertStoreContext *)object;
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_Object_Hashcode
Packit 40b132
                    ((PKIX_PL_Object *) collectionCSContext->storeDir,
Packit 40b132
                    &tempHash,
Packit 40b132
                    plContext),
Packit 40b132
                   PKIX_STRINGHASHCODEFAILED);
Packit 40b132
Packit 40b132
        *pHashcode = tempHash << 7;
Packit 40b132
Packit 40b132
        /* should not hash on crlList and certList, values are dynamic */
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_Equals
Packit 40b132
 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_CollectionCertStoreContext_Equals(
Packit 40b132
        PKIX_PL_Object *firstObject,
Packit 40b132
        PKIX_PL_Object *secondObject,
Packit 40b132
        PKIX_Int32 *pResult,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *firstCCSContext = NULL;
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *secondCCSContext = NULL;
Packit 40b132
        PKIX_Boolean cmpResult = 0;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_Equals");
Packit 40b132
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_CheckTypes
Packit 40b132
                    (firstObject,
Packit 40b132
                    secondObject,
Packit 40b132
                    PKIX_COLLECTIONCERTSTORECONTEXT_TYPE,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT);
Packit 40b132
Packit 40b132
        firstCCSContext = (PKIX_PL_CollectionCertStoreContext *)firstObject;
Packit 40b132
        secondCCSContext = (PKIX_PL_CollectionCertStoreContext *)secondObject;
Packit 40b132
Packit 40b132
        if (firstCCSContext->storeDir == secondCCSContext->storeDir) {
Packit 40b132
Packit 40b132
                cmpResult = PKIX_TRUE;
Packit 40b132
Packit 40b132
        } else {
Packit 40b132
Packit 40b132
                PKIX_CHECK(PKIX_PL_Object_Equals
Packit 40b132
                    ((PKIX_PL_Object *) firstCCSContext->storeDir,
Packit 40b132
                    (PKIX_PL_Object *) secondCCSContext->storeDir,
Packit 40b132
                    &cmpResult,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_STRINGEQUALSFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pResult = cmpResult;
Packit 40b132
Packit 40b132
        /* should not check equal on crlList and certList, data are dynamic */
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStore_CheckTrust
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 * This function checks the trust status of this "cert" that was retrieved
Packit 40b132
 * from the CertStore "store" and returns its trust status at "pTrusted".
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 * "store"
Packit 40b132
 *      Address of the CertStore. Must be non-NULL.
Packit 40b132
 * "cert"
Packit 40b132
 *      Address of the Cert. Must be non-NULL.
Packit 40b132
 * "pTrusted"
Packit 40b132
 *      Address of PKIX_Boolean where the "cert" trust status is returned.
Packit 40b132
 *      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
static PKIX_Error *
Packit 40b132
pkix_pl_CollectionCertStore_CheckTrust(
Packit 40b132
        PKIX_CertStore *store,
Packit 40b132
        PKIX_PL_Cert *cert,
Packit 40b132
        PKIX_Boolean *pTrusted,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_CheckTrust");
Packit 40b132
        PKIX_NULLCHECK_THREE(store, cert, pTrusted);
Packit 40b132
Packit 40b132
        *pTrusted = PKIX_TRUE;
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_CreateCert
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Creates Cert using data file path name pointed to by "certFileName" and
Packit 40b132
 *  stores it at "pCert". If the Cert can not be decoded, NULL is stored
Packit 40b132
 *  at "pCert".
Packit 40b132
 *
Packit 40b132
 * PARAMETERS
Packit 40b132
 *  "certFileName" - Address of Cert data file path name. Must be non-NULL.
Packit 40b132
 *  "pCert" - Address where object pointer will be stored. Must be non-NULL.
Packit 40b132
 *  "plContext" - 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 CollectionCertStoreContext Error if the function fails in
Packit 40b132
 *              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_CollectionCertStoreContext_CreateCert(
Packit 40b132
        const char *certFileName,
Packit 40b132
        PKIX_PL_Cert **pCert,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_ByteArray *byteArray = NULL;
Packit 40b132
        PKIX_PL_Cert *cert = NULL;
Packit 40b132
        PRFileDesc *inFile = NULL;
Packit 40b132
        SECItem certDER;
Packit 40b132
        void *buf = NULL;
Packit 40b132
        PKIX_UInt32 len;
Packit 40b132
        SECStatus rv;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_CreateCert");
Packit 40b132
        PKIX_NULLCHECK_TWO(certFileName, pCert);
Packit 40b132
Packit 40b132
        *pCert = NULL;
Packit 40b132
        certDER.data = NULL;
Packit 40b132
Packit 40b132
        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_Open.\n");
Packit 40b132
        inFile = PR_Open(certFileName, PR_RDONLY, 0);
Packit 40b132
Packit 40b132
        if (!inFile){
Packit 40b132
                PKIX_ERROR(PKIX_UNABLETOOPENCERTFILE);
Packit 40b132
        } else {
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling SECU_ReadDerFromFile.\n");
Packit 40b132
                rv = SECU_ReadDERFromFile(&certDER, inFile, PR_FALSE);
Packit 40b132
                if (!rv){
Packit 40b132
                        buf = (void *)certDER.data;
Packit 40b132
                        len = certDER.len;
Packit 40b132
Packit 40b132
                        PKIX_CHECK(PKIX_PL_ByteArray_Create
Packit 40b132
                                    (buf, len, &byteArray, plContext),
Packit 40b132
                                    PKIX_BYTEARRAYCREATEFAILED);
Packit 40b132
Packit 40b132
                        PKIX_CHECK(PKIX_PL_Cert_Create
Packit 40b132
                                    (byteArray, &cert, plContext),
Packit 40b132
                                    PKIX_CERTCREATEFAILED);
Packit 40b132
Packit 40b132
                        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                                ("\t\t Calling SECITEM_FreeItem.\n");
Packit 40b132
                        SECITEM_FreeItem(&certDER, PR_FALSE);
Packit 40b132
Packit 40b132
                } else {
Packit 40b132
                        PKIX_ERROR(PKIX_UNABLETOREADDERFROMCERTFILE);
Packit 40b132
                }
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pCert = cert;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        if (inFile){
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_CloseDir.\n");
Packit 40b132
                PR_Close(inFile);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if (PKIX_ERROR_RECEIVED){
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling SECITEM_FreeItem).\n");
Packit 40b132
                SECITEM_FreeItem(&certDER, PR_FALSE);
Packit 40b132
Packit 40b132
                PKIX_DECREF(cert);
Packit 40b132
        }
Packit 40b132
        PKIX_DECREF(byteArray);
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_CreateCRL
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Creates CRL using data file path name pointed to by "crlFileName" and
Packit 40b132
 *  stores it at "pCrl". If the CRL can not be decoded, NULL is stored
Packit 40b132
 *  at "pCrl".
Packit 40b132
 *
Packit 40b132
 * PARAMETERS
Packit 40b132
 *  "crlFileName" - Address of CRL data file path name. Must be non-NULL.
Packit 40b132
 *  "pCrl" - Address where object pointer will be stored. Must be non-NULL.
Packit 40b132
 *  "plContext" - 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 CollectionCertStoreContext Error if the function fails in
Packit 40b132
 *              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_CollectionCertStoreContext_CreateCRL(
Packit 40b132
        const char *crlFileName,
Packit 40b132
        PKIX_PL_CRL **pCrl,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_ByteArray *byteArray = NULL;
Packit 40b132
        PKIX_PL_CRL *crl = NULL;
Packit 40b132
        PRFileDesc *inFile = NULL;
Packit 40b132
        SECItem crlDER;
Packit 40b132
        void *buf = NULL;
Packit 40b132
        PKIX_UInt32 len;
Packit 40b132
        SECStatus rv;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_CreateCRL");
Packit 40b132
        PKIX_NULLCHECK_TWO(crlFileName, pCrl);
Packit 40b132
Packit 40b132
        *pCrl = NULL;
Packit 40b132
        crlDER.data = NULL;
Packit 40b132
Packit 40b132
        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_Open.\n");
Packit 40b132
        inFile = PR_Open(crlFileName, PR_RDONLY, 0);
Packit 40b132
Packit 40b132
        if (!inFile){
Packit 40b132
                PKIX_ERROR(PKIX_UNABLETOOPENCRLFILE);
Packit 40b132
        } else {
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling SECU_ReadDerFromFile.\n");
Packit 40b132
                rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE);
Packit 40b132
                if (!rv){
Packit 40b132
                        buf = (void *)crlDER.data;
Packit 40b132
                        len = crlDER.len;
Packit 40b132
Packit 40b132
                        PKIX_CHECK(PKIX_PL_ByteArray_Create
Packit 40b132
                                (buf, len, &byteArray, plContext),
Packit 40b132
                                PKIX_BYTEARRAYCREATEFAILED);
Packit 40b132
Packit 40b132
                        PKIX_CHECK(PKIX_PL_CRL_Create
Packit 40b132
                                (byteArray, &crl, plContext),
Packit 40b132
                                PKIX_CRLCREATEFAILED);
Packit 40b132
Packit 40b132
                        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                                ("\t\t Calling SECITEM_FreeItem.\n");
Packit 40b132
                        SECITEM_FreeItem(&crlDER, PR_FALSE);
Packit 40b132
Packit 40b132
                } else {
Packit 40b132
                        PKIX_ERROR(PKIX_UNABLETOREADDERFROMCRLFILE);
Packit 40b132
                }
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pCrl = crl;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        if (inFile){
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_CloseDir.\n");
Packit 40b132
                PR_Close(inFile);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if (PKIX_ERROR_RECEIVED){
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling SECITEM_FreeItem).\n");
Packit 40b132
                SECITEM_FreeItem(&crlDER, PR_FALSE);
Packit 40b132
Packit 40b132
                PKIX_DECREF(crl);
Packit 40b132
                if (crlDER.data != NULL) {
Packit 40b132
                        SECITEM_FreeItem(&crlDER, PR_FALSE);
Packit 40b132
                }
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_DECREF(byteArray);
Packit 40b132
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCert
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Create list of Certs from *.crt files at directory specified in dirName,
Packit 40b132
 *  Not recursive to sub-directory. Also assume the directory contents are
Packit 40b132
 *  not changed dynamically.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS
Packit 40b132
 *  "colCertStoreContext" - Address of CollectionCertStoreContext
Packit 40b132
 *              where the dirName is specified and where the return
Packit 40b132
 *              Certs are stored as a list. Must be non-NULL.
Packit 40b132
 *  "plContext" - Platform-specific context pointer.
Packit 40b132
 *
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Not Thread Safe - A lock at top level is required.
Packit 40b132
 *
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CollectionCertStoreContext Error if the function fails in
Packit 40b132
 *              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_CollectionCertStoreContext_PopulateCert(
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_List *certList = NULL;
Packit 40b132
        PKIX_PL_Cert *certItem = NULL;
Packit 40b132
        char *dirName = NULL;
Packit 40b132
        char *pathName = NULL;
Packit 40b132
        PKIX_UInt32 dirNameLen = 0;
Packit 40b132
        PRErrorCode prError = 0;
Packit 40b132
        PRDir *dir = NULL;
Packit 40b132
        PRDirEntry *dirEntry = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_PopulateCert");
Packit 40b132
        PKIX_NULLCHECK_ONE(colCertStoreContext);
Packit 40b132
Packit 40b132
        /* convert directory to ascii */
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_String_GetEncoded
Packit 40b132
                    (colCertStoreContext->storeDir,
Packit 40b132
                    PKIX_ESCASCII,
Packit 40b132
                    (void **)&dirName,
Packit 40b132
                    &dirNameLen,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_STRINGGETENCODEDFAILED);
Packit 40b132
Packit 40b132
        /* create cert list, if no cert file, should return an empty list */
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_List_Create(&certList, plContext),
Packit 40b132
                    PKIX_LISTCREATEFAILED);
Packit 40b132
Packit 40b132
        /* open directory and read in .crt files */
Packit 40b132
Packit 40b132
        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n");
Packit 40b132
        dir = PR_OpenDir(dirName);
Packit 40b132
Packit 40b132
        if (!dir) {
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG
Packit 40b132
                        ("\t\t Directory Name:%s\n", dirName);
Packit 40b132
                PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n");
Packit 40b132
        dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);
Packit 40b132
Packit 40b132
        if (!dirEntry) {
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Empty directory.\n");
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_GetError.\n");
Packit 40b132
                prError = PR_GetError();
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n");
Packit 40b132
        PR_SetError(0, 0);
Packit 40b132
Packit 40b132
        while (dirEntry != NULL && prError == 0) {
Packit 40b132
                if (PL_strrstr(dirEntry->name, ".crt") ==
Packit 40b132
                    dirEntry->name + PL_strlen(dirEntry->name) - 4) {
Packit 40b132
Packit 40b132
                        PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                (PKIX_PL_Malloc
Packit 40b132
                                (dirNameLen + PL_strlen(dirEntry->name) + 2,
Packit 40b132
                                (void **)&pathName,
Packit 40b132
                                plContext),
Packit 40b132
                                PKIX_MALLOCFAILED);
Packit 40b132
Packit 40b132
                        if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){
Packit 40b132
Packit 40b132
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                                    ("\t\t Calling PL_strcpy for dirName.\n");
Packit 40b132
                                PL_strcpy(pathName, dirName);
Packit 40b132
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                                    ("\t\t Calling PL_strcat for dirName.\n");
Packit 40b132
                                PL_strcat(pathName, "/");
Packit 40b132
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                                        ("\t\t Calling PL_strcat for /.\n");
Packit 40b132
                                PL_strcat(pathName, dirEntry->name);
Packit 40b132
Packit 40b132
                                PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                (pkix_pl_CollectionCertStoreContext_CreateCert
Packit 40b132
                                    (pathName, &certItem, plContext),
Packit 40b132
                              PKIX_COLLECTIONCERTSTORECONTEXTCREATECERTFAILED);
Packit 40b132
Packit 40b132
                                if (!PKIX_ERROR_RECEIVED){
Packit 40b132
                                        PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                                (PKIX_List_AppendItem
Packit 40b132
                                                (certList,
Packit 40b132
                                                (PKIX_PL_Object *)certItem,
Packit 40b132
                                                plContext),
Packit 40b132
                                                PKIX_LISTAPPENDITEMFAILED);
Packit 40b132
                                }
Packit 40b132
                        }
Packit 40b132
Packit 40b132
                        PKIX_DECREF(certItem);
Packit 40b132
                        PKIX_FREE(pathName);
Packit 40b132
                }
Packit 40b132
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_SetError.\n");
Packit 40b132
                PR_SetError(0, 0);
Packit 40b132
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_ReadDir.\n");
Packit 40b132
                dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);
Packit 40b132
Packit 40b132
                if (!dirEntry) {
Packit 40b132
                    PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_GetError.\n");
Packit 40b132
                    prError = PR_GetError();
Packit 40b132
                }
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) {
Packit 40b132
                PKIX_ERROR(PKIX_COLLECTIONCERTSTOREPOPULATECERTFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_List_SetImmutable(certList, plContext),
Packit 40b132
                    PKIX_LISTSETIMMUTABLEFAILED);
Packit 40b132
Packit 40b132
        PKIX_INCREF(certList);
Packit 40b132
        colCertStoreContext->certList = certList;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        if (dir) {
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_CloseDir.\n");
Packit 40b132
                PR_CloseDir(dir);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_FREE(pathName);
Packit 40b132
        PKIX_FREE(dirName);
Packit 40b132
Packit 40b132
        if (PKIX_ERROR_RECEIVED){
Packit 40b132
                PKIX_DECREF(certList);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_DECREF(certItem);
Packit 40b132
        PKIX_DECREF(certList);
Packit 40b132
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCRL
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Create list of CRLs from *.crl files at directory specified in dirName,
Packit 40b132
 *  Not recursive to sub-dirctory. Also assume the directory contents are
Packit 40b132
 *  not changed dynamically.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS
Packit 40b132
 *  "colCertStoreContext" - Address of CollectionCertStoreContext
Packit 40b132
 *              where the dirName is specified and where the return
Packit 40b132
 *              CRLs are stored as a list. Must be non-NULL.
Packit 40b132
 *  "plContext" - Platform-specific context pointer.
Packit 40b132
 *
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Not Thread Safe - A lock at top level is required.
Packit 40b132
 *
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CollectionCertStoreContext Error if the function fails in
Packit 40b132
 *              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_CollectionCertStoreContext_PopulateCRL(
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_List *crlList = NULL;
Packit 40b132
        PKIX_PL_CRL *crlItem = NULL;
Packit 40b132
        char *dirName = NULL;
Packit 40b132
        char *pathName = NULL;
Packit 40b132
        PKIX_UInt32 dirNameLen = 0;
Packit 40b132
        PRErrorCode prError = 0;
Packit 40b132
        PRDir *dir = NULL;
Packit 40b132
        PRDirEntry *dirEntry = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_PopulateCRL");
Packit 40b132
        PKIX_NULLCHECK_ONE(colCertStoreContext);
Packit 40b132
Packit 40b132
        /* convert directory to ascii */
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_String_GetEncoded
Packit 40b132
                    (colCertStoreContext->storeDir,
Packit 40b132
                    PKIX_ESCASCII,
Packit 40b132
                    (void **)&dirName,
Packit 40b132
                    &dirNameLen,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_STRINGGETENCODEDFAILED);
Packit 40b132
Packit 40b132
        /* create CRL list, if no CRL file, should return an empty list */
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_List_Create(&crlList, plContext),
Packit 40b132
                    PKIX_LISTCREATEFAILED);
Packit 40b132
Packit 40b132
        /* open directory and read in .crl files */
Packit 40b132
Packit 40b132
        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n");
Packit 40b132
        dir = PR_OpenDir(dirName);
Packit 40b132
Packit 40b132
        if (!dir) {
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG
Packit 40b132
                        ("\t\t Directory Name:%s\n", dirName);
Packit 40b132
                PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n");
Packit 40b132
        dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);
Packit 40b132
Packit 40b132
        if (!dirEntry) {
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Empty directory.\n");
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_GetError.\n");
Packit 40b132
                prError = PR_GetError();
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n");
Packit 40b132
        PR_SetError(0, 0);
Packit 40b132
Packit 40b132
        while (dirEntry != NULL && prError == 0) {
Packit 40b132
                if (PL_strrstr(dirEntry->name, ".crl") ==
Packit 40b132
                    dirEntry->name + PL_strlen(dirEntry->name) - 4) {
Packit 40b132
Packit 40b132
                        PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                (PKIX_PL_Malloc
Packit 40b132
                                (dirNameLen + PL_strlen(dirEntry->name) + 2,
Packit 40b132
                                (void **)&pathName,
Packit 40b132
                                plContext),
Packit 40b132
                                PKIX_MALLOCFAILED);
Packit 40b132
Packit 40b132
                        if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){
Packit 40b132
Packit 40b132
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                                    ("\t\t Calling PL_strcpy for dirName.\n");
Packit 40b132
                                PL_strcpy(pathName, dirName);
Packit 40b132
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                                    ("\t\t Calling PL_strcat for dirName.\n");
Packit 40b132
                                PL_strcat(pathName, "/");
Packit 40b132
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                                        ("\t\t Calling PL_strcat for /.\n");
Packit 40b132
                                PL_strcat(pathName, dirEntry->name);
Packit 40b132
Packit 40b132
                        PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                (pkix_pl_CollectionCertStoreContext_CreateCRL
Packit 40b132
                                (pathName, &crlItem, plContext),
Packit 40b132
                                PKIX_COLLECTIONCERTSTORECONTEXTCREATECRLFAILED);
Packit 40b132
Packit 40b132
                                if (!PKIX_ERROR_RECEIVED){
Packit 40b132
                                        PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                                (PKIX_List_AppendItem
Packit 40b132
                                                (crlList,
Packit 40b132
                                                (PKIX_PL_Object *)crlItem,
Packit 40b132
                                                plContext),
Packit 40b132
                                                PKIX_LISTAPPENDITEMFAILED);
Packit 40b132
                                }
Packit 40b132
                        }
Packit 40b132
Packit 40b132
                        PKIX_DECREF(crlItem);
Packit 40b132
                        PKIX_FREE(pathName);
Packit 40b132
                }
Packit 40b132
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_SetError.\n");
Packit 40b132
                PR_SetError(0, 0);
Packit 40b132
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_ReadDir.\n");
Packit 40b132
                dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);
Packit 40b132
Packit 40b132
                if (!dirEntry) {
Packit 40b132
                    PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_GetError.\n");
Packit 40b132
                    prError = PR_GetError();
Packit 40b132
                }
Packit 40b132
        }
Packit 40b132
Packit 40b132
        if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) {
Packit 40b132
                PKIX_ERROR(PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_List_SetImmutable(crlList, plContext),
Packit 40b132
                    PKIX_LISTSETIMMUTABLEFAILED);
Packit 40b132
Packit 40b132
        PKIX_INCREF(crlList);
Packit 40b132
        colCertStoreContext->crlList = crlList;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        if (dir) {
Packit 40b132
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
Packit 40b132
                        ("\t\t Calling PR_CloseDir.\n");
Packit 40b132
                PR_CloseDir(dir);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_FREE(pathName);
Packit 40b132
        PKIX_FREE(dirName);
Packit 40b132
Packit 40b132
        if (PKIX_ERROR_RECEIVED){
Packit 40b132
                PKIX_DECREF(crlList);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_DECREF(crlItem);
Packit 40b132
        PKIX_DECREF(crlList);
Packit 40b132
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_GetSelectedCert
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Finds the Certs that match the criterion of the CertSelector pointed
Packit 40b132
 *  to by "selector" using the List of Certs pointed to by "certList" and
Packit 40b132
 *  stores the matching Certs at "pSelectedCertList".
Packit 40b132
 *
Packit 40b132
 *  Not recursive to sub-directory.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS
Packit 40b132
 *  "certList" - Address of List of Certs to be searched. Must be non-NULL.
Packit 40b132
 *  "colCertStoreContext" - Address of CollectionCertStoreContext
Packit 40b132
 *              where the cached Certs are stored.
Packit 40b132
 *  "selector" - CertSelector for chosing Cert based on Params set
Packit 40b132
 *  "pSelectedCertList" - Certs that qualified by selector.
Packit 40b132
 *  "plContext" - Platform-specific context pointer.
Packit 40b132
 *
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Not Thread Safe - A lock at top level is required.
Packit 40b132
 *
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CollectionCertStoreContext Error if the function fails in
Packit 40b132
 *              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_CollectionCertStoreContext_GetSelectedCert(
Packit 40b132
        PKIX_List *certList,
Packit 40b132
        PKIX_CertSelector *selector,
Packit 40b132
        PKIX_List **pSelectedCertList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_List *selectCertList = NULL;
Packit 40b132
        PKIX_PL_Cert *certItem = NULL;
Packit 40b132
        PKIX_CertSelector_MatchCallback certSelectorMatch = NULL;
Packit 40b132
        PKIX_UInt32 numCerts = 0;
Packit 40b132
        PKIX_UInt32 i = 0;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_GetSelectedCert");
Packit 40b132
        PKIX_NULLCHECK_THREE(certList, selector, pSelectedCertList);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
Packit 40b132
                    (selector, &certSelectorMatch, plContext),
Packit 40b132
                    PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_List_GetLength(certList, &numCerts, plContext),
Packit 40b132
                    PKIX_LISTGETLENGTHFAILED);
Packit 40b132
Packit 40b132
        if (certSelectorMatch) {
Packit 40b132
Packit 40b132
                PKIX_CHECK(PKIX_List_Create(&selectCertList, plContext),
Packit 40b132
                            PKIX_LISTCREATEFAILED);
Packit 40b132
Packit 40b132
                for (i = 0; i < numCerts; i++) {
Packit 40b132
                        PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                (PKIX_List_GetItem
Packit 40b132
                                (certList,
Packit 40b132
                                i,
Packit 40b132
                                (PKIX_PL_Object **) &certItem,
Packit 40b132
                                plContext),
Packit 40b132
                                PKIX_LISTGETITEMFAILED);
Packit 40b132
Packit 40b132
                        if (!PKIX_ERROR_RECEIVED){
Packit 40b132
                                PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                        (certSelectorMatch
Packit 40b132
                                        (selector, certItem, plContext),
Packit 40b132
                                        PKIX_CERTSELECTORMATCHFAILED);
Packit 40b132
Packit 40b132
                                if (!PKIX_ERROR_RECEIVED){
Packit 40b132
                                        PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                                (PKIX_List_AppendItem
Packit 40b132
                                                (selectCertList,
Packit 40b132
                                                (PKIX_PL_Object *)certItem,
Packit 40b132
                                                plContext),
Packit 40b132
                                                PKIX_LISTAPPENDITEMFAILED);
Packit 40b132
                                }
Packit 40b132
                        }
Packit 40b132
Packit 40b132
                        PKIX_DECREF(certItem);
Packit 40b132
                }
Packit 40b132
Packit 40b132
        } else {
Packit 40b132
Packit 40b132
                PKIX_INCREF(certList);
Packit 40b132
Packit 40b132
                selectCertList = certList;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pSelectedCertList = selectCertList;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_GetSelectedCRL
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Finds the CRLs that match the criterion of the CRLSelector pointed
Packit 40b132
 *  to by "selector" using the List of CRLs pointed to by "crlList" and
Packit 40b132
 *  stores the matching CRLs at "pSelectedCrlList".
Packit 40b132
 *
Packit 40b132
 *  Not recursive to sub-directory.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS
Packit 40b132
 *  "crlList" - Address of List of CRLs to be searched. Must be non-NULL
Packit 40b132
 *  "selector" - CRLSelector for chosing CRL based on Params set
Packit 40b132
 *  "pSelectedCrlList" - CRLs that qualified by selector.
Packit 40b132
 *  "plContext" - Platform-specific context pointer.
Packit 40b132
 *
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Not Thread Safe - A lock at top level is required.
Packit 40b132
 *
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CollectionCertStoreContext Error if the function fails in
Packit 40b132
 *              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_CollectionCertStoreContext_GetSelectedCRL(
Packit 40b132
        PKIX_List *crlList,
Packit 40b132
        PKIX_CRLSelector *selector,
Packit 40b132
        PKIX_List **pSelectedCrlList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_List *selectCrlList = NULL;
Packit 40b132
        PKIX_PL_CRL *crlItem = NULL;
Packit 40b132
        PKIX_CRLSelector_MatchCallback crlSelectorMatch = NULL;
Packit 40b132
        PKIX_UInt32 numCrls = 0;
Packit 40b132
        PKIX_UInt32 i = 0;
Packit 40b132
        PKIX_Boolean match = PKIX_FALSE;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_GetSelectedCRL");
Packit 40b132
        PKIX_NULLCHECK_THREE(crlList, selector, pSelectedCrlList);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CRLSelector_GetMatchCallback
Packit 40b132
                    (selector, &crlSelectorMatch, plContext),
Packit 40b132
                    PKIX_CRLSELECTORGETMATCHCALLBACKFAILED);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_List_GetLength(crlList, &numCrls, plContext),
Packit 40b132
                    PKIX_LISTGETLENGTHFAILED);
Packit 40b132
Packit 40b132
        if (crlSelectorMatch) {
Packit 40b132
Packit 40b132
                PKIX_CHECK(PKIX_List_Create(&selectCrlList, plContext),
Packit 40b132
                            PKIX_LISTCREATEFAILED);
Packit 40b132
Packit 40b132
                for (i = 0; i < numCrls; i++) {
Packit 40b132
                        PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem
Packit 40b132
                                (crlList,
Packit 40b132
                                i,
Packit 40b132
                                (PKIX_PL_Object **) &crlItem,
Packit 40b132
                                plContext),
Packit 40b132
                                PKIX_LISTGETITEMFAILED);
Packit 40b132
Packit 40b132
                        if (!PKIX_ERROR_RECEIVED){
Packit 40b132
                                PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                        (crlSelectorMatch
Packit 40b132
                                        (selector, crlItem, &match, plContext),
Packit 40b132
                                        PKIX_CRLSELECTORMATCHFAILED);
Packit 40b132
Packit 40b132
                                if (!(PKIX_ERROR_RECEIVED) && match) {
Packit 40b132
                                        PKIX_CHECK_ONLY_FATAL
Packit 40b132
                                                (PKIX_List_AppendItem
Packit 40b132
                                                (selectCrlList,
Packit 40b132
                                                (PKIX_PL_Object *)crlItem,
Packit 40b132
                                                plContext),
Packit 40b132
                                                PKIX_LISTAPPENDITEMFAILED);
Packit 40b132
                                }
Packit 40b132
                        }
Packit 40b132
Packit 40b132
                        PKIX_DECREF(crlItem);
Packit 40b132
                }
Packit 40b132
        } else {
Packit 40b132
Packit 40b132
                PKIX_INCREF(crlList);
Packit 40b132
Packit 40b132
                selectCrlList = crlList;
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
        *pSelectedCrlList = selectCrlList;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStore_GetCert
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Retrieve Certs in a list of PKIX_PL_Cert object.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "colCertStoreContext"
Packit 40b132
 *      The object CertStore is the object passed in by checker call.
Packit 40b132
 *  "crlSelector"
Packit 40b132
 *      CRLSelector specifies criteria for chosing CRL's
Packit 40b132
 *  "pNBIOContext"
Packit 40b132
 *      Address where platform-dependent information is returned for CertStores
Packit 40b132
 *      that use non-blocking I/O. Must be non-NULL.
Packit 40b132
 *  "pCertList"
Packit 40b132
 *      Address where object pointer will be returned. 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
Packit 40b132
 *      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_CollectionCertStore_GetCert(
Packit 40b132
        PKIX_CertStore *certStore,
Packit 40b132
        PKIX_CertSelector *selector,
Packit 40b132
        PKIX_VerifyNode *verifyNode,
Packit 40b132
        void **pNBIOContext,
Packit 40b132
        PKIX_List **pCerts,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
Packit 40b132
        PKIX_List *selectedCerts = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_GetCert");
Packit 40b132
        PKIX_NULLCHECK_FOUR(certStore, selector, pNBIOContext, pCerts);
Packit 40b132
Packit 40b132
        *pNBIOContext = NULL;   /* We don't use non-blocking I/O */
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
Packit 40b132
                    (certStore,
Packit 40b132
                    (PKIX_PL_Object **) &colCertStoreContext,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
Packit 40b132
Packit 40b132
        if (colCertStoreContext->certList == NULL) {
Packit 40b132
Packit 40b132
                PKIX_OBJECT_LOCK(colCertStoreContext);
Packit 40b132
Packit 40b132
                /*
Packit 40b132
                 * Certs in the directory are cached based on the
Packit 40b132
                 * assumption that the directory contents won't be
Packit 40b132
                 * changed dynamically.
Packit 40b132
                 */
Packit 40b132
                if (colCertStoreContext->certList == NULL){
Packit 40b132
                    PKIX_CHECK(pkix_pl_CollectionCertStoreContext_PopulateCert
Packit 40b132
                            (colCertStoreContext, plContext),
Packit 40b132
                            PKIX_COLLECTIONCERTSTORECONTEXTPOPULATECERTFAILED);
Packit 40b132
                }
Packit 40b132
Packit 40b132
                PKIX_OBJECT_UNLOCK(colCertStoreContext);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_pl_CollectionCertStoreContext_GetSelectedCert
Packit 40b132
                    (colCertStoreContext->certList,
Packit 40b132
                    selector,
Packit 40b132
                    &selectedCerts,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCERTFAILED);
Packit 40b132
Packit 40b132
        *pCerts = selectedCerts;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
	PKIX_OBJECT_UNLOCK(lockedObject);
Packit 40b132
        PKIX_DECREF(colCertStoreContext);
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStore_GetCRL
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Retrieve CRL's in a list of PKIX_PL_CRL object.
Packit 40b132
 *
Packit 40b132
 * PARAMETERS:
Packit 40b132
 *  "colCertStoreContext"
Packit 40b132
 *      The object CertStore is passed in by checker call.
Packit 40b132
 *  "crlSelector"
Packit 40b132
 *      CRLSelector specifies criteria for chosing CRL's
Packit 40b132
 *  "pNBIOContext"
Packit 40b132
 *      Address where platform-dependent information is returned for CertStores
Packit 40b132
 *      that use non-blocking I/O. Must be non-NULL.
Packit 40b132
 *  "pCrlList"
Packit 40b132
 *      Address where object pointer will be returned. 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
Packit 40b132
 *      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_CollectionCertStore_GetCRL(
Packit 40b132
        PKIX_CertStore *certStore,
Packit 40b132
        PKIX_CRLSelector *selector,
Packit 40b132
        void **pNBIOContext,
Packit 40b132
        PKIX_List **pCrlList,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
Packit 40b132
        PKIX_List *selectCrl = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_GetCRL");
Packit 40b132
        PKIX_NULLCHECK_FOUR(certStore, selector, pNBIOContext, pCrlList);
Packit 40b132
Packit 40b132
        *pNBIOContext = NULL;   /* We don't use non-blocking I/O */
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
Packit 40b132
                    (certStore,
Packit 40b132
                    (PKIX_PL_Object **) &colCertStoreContext,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
Packit 40b132
Packit 40b132
        if (colCertStoreContext->crlList == NULL) {
Packit 40b132
Packit 40b132
                PKIX_OBJECT_LOCK(colCertStoreContext);
Packit 40b132
Packit 40b132
                /*
Packit 40b132
                 * CRLs in the directory are cached based on the
Packit 40b132
                 * assumption that the directory contents won't be
Packit 40b132
                 * changed dynamically.
Packit 40b132
                 */
Packit 40b132
                if (colCertStoreContext->crlList == NULL){
Packit 40b132
                    PKIX_CHECK(pkix_pl_CollectionCertStoreContext_PopulateCRL
Packit 40b132
                            (colCertStoreContext, plContext),
Packit 40b132
                            PKIX_COLLECTIONCERTSTORECONTEXTPOPULATECRLFAILED);
Packit 40b132
                }
Packit 40b132
Packit 40b132
                PKIX_OBJECT_UNLOCK(colCertStoreContext);
Packit 40b132
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_pl_CollectionCertStoreContext_GetSelectedCRL
Packit 40b132
                    (colCertStoreContext->crlList,
Packit 40b132
                    selector,
Packit 40b132
                    &selectCrl,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED);
Packit 40b132
Packit 40b132
        *pCrlList = selectCrl;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
	PKIX_OBJECT_UNLOCK(lockedObject);
Packit 40b132
        PKIX_DECREF(colCertStoreContext);
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CollectionCertStoreContext_RegisterSelf
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Registers PKIX_PL_COLLECTIONCERTSTORECONTEXT_TYPE and its related
Packit 40b132
 *  functions with systemClasses[]
Packit 40b132
 *
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Not Thread Safe - for performance and complexity reasons
Packit 40b132
 *
Packit 40b132
 *  Since this function is only called by PKIX_PL_Initialize, which should
Packit 40b132
 *  only be called once, it is acceptable that this function is not
Packit 40b132
 *  thread-safe.
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_CollectionCertStoreContext_RegisterSelf(void *plContext)
Packit 40b132
{
Packit 40b132
        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
Packit 40b132
        pkix_ClassTable_Entry entry;
Packit 40b132
Packit 40b132
        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
Packit 40b132
                    "pkix_pl_CollectionCertStoreContext_RegisterSelf");
Packit 40b132
Packit 40b132
        entry.description = "CollectionCertStoreContext";
Packit 40b132
        entry.objCounter = 0;
Packit 40b132
        entry.typeObjectSize = sizeof(PKIX_PL_CollectionCertStoreContext);
Packit 40b132
        entry.destructor = pkix_pl_CollectionCertStoreContext_Destroy;
Packit 40b132
        entry.equalsFunction = pkix_pl_CollectionCertStoreContext_Equals;
Packit 40b132
        entry.hashcodeFunction = pkix_pl_CollectionCertStoreContext_Hashcode;
Packit 40b132
        entry.toStringFunction = NULL;
Packit 40b132
        entry.comparator = NULL;
Packit 40b132
        entry.duplicateFunction = NULL;
Packit 40b132
Packit 40b132
        systemClasses[PKIX_COLLECTIONCERTSTORECONTEXT_TYPE] = entry;
Packit 40b132
Packit 40b132
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
Packit 40b132
}
Packit 40b132
Packit 40b132
/* --Public-CollectionCertStoreContext-Functions--------------------------- */
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: PKIX_PL_CollectionCertStore_Create
Packit 40b132
 * (see comments in pkix_samples_modules.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
PKIX_PL_CollectionCertStore_Create(
Packit 40b132
        PKIX_PL_String *storeDir,
Packit 40b132
        PKIX_CertStore **pCertStore,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
Packit 40b132
        PKIX_CertStore *certStore = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTSTORE, "PKIX_PL_CollectionCertStore_Create");
Packit 40b132
        PKIX_NULLCHECK_TWO(storeDir, pCertStore);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_pl_CollectionCertStoreContext_Create
Packit 40b132
                    (storeDir, &colCertStoreContext, plContext),
Packit 40b132
                    PKIX_COULDNOTCREATECOLLECTIONCERTSTORECONTEXTOBJECT);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_CertStore_Create
Packit 40b132
                    (pkix_pl_CollectionCertStore_GetCert,
Packit 40b132
                    pkix_pl_CollectionCertStore_GetCRL,
Packit 40b132
                    NULL, /* GetCertContinue */
Packit 40b132
                    NULL, /* GetCRLContinue */
Packit 40b132
                    pkix_pl_CollectionCertStore_CheckTrust,
Packit 40b132
                    NULL,      /* can not store crls */
Packit 40b132
                    NULL,      /* can not do revocation check */
Packit 40b132
                    (PKIX_PL_Object *)colCertStoreContext,
Packit 40b132
                    PKIX_TRUE, /* cache flag */
Packit 40b132
                    PKIX_TRUE, /* local - no network I/O */
Packit 40b132
                    &certStore,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_CERTSTORECREATEFAILED);
Packit 40b132
Packit 40b132
        PKIX_DECREF(colCertStoreContext);
Packit 40b132
Packit 40b132
        *pCertStore = certStore;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        PKIX_RETURN(CERTSTORE);
Packit 40b132
}