Example #1
0
/*
 * FUNCTION: pkix_PolicyNode_Create
 * DESCRIPTION:
 *
 *  Creates a new PolicyNode using the OID pointed to by "validPolicy", the List
 *  of CertPolicyQualifiers pointed to by "qualifierSet", the criticality
 *  indicated by the Boolean value of "criticality", and the List of OIDs
 *  pointed to by "expectedPolicySet", and stores the result at "pObject". The
 *  criticality should be derived from whether the certificate policy extension
 *  was marked as critical in the certificate that led to creation of this
 *  PolicyNode. The "qualifierSet" and "expectedPolicySet" Lists are made
 *  immutable. The PolicyNode pointers to parent and to children are initialized
 *  to NULL, and the depth is set to zero; those values should be set by using
 *  the pkix_PolicyNode_AddToParent function.
 *
 * PARAMETERS
 *  "validPolicy"
 *      Address of OID of the valid policy for the path. Must be non-NULL
 *  "qualifierSet"
 *      Address of List of CertPolicyQualifiers associated with the validpolicy.
 *      May be NULL
 *  "criticality"
 *      Boolean indicator of whether the criticality should be set in this
 *      PolicyNode
 *  "expectedPolicySet"
 *      Address of List of OIDs that would satisfy this policy in the next
 *      certificate. Must be non-NULL
 *  "pObject"
 *      Address where the PolicyNode pointer will be stored. Must be non-NULL.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a PolicyNode Error if the function fails  in a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
PKIX_Error *
pkix_PolicyNode_Create(
    PKIX_PL_OID *validPolicy,
    PKIX_List *qualifierSet,
    PKIX_Boolean criticality,
    PKIX_List *expectedPolicySet,
    PKIX_PolicyNode **pObject,
    void *plContext)
{
    PKIX_PolicyNode *node = NULL;

    PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Create");

    PKIX_NULLCHECK_THREE(validPolicy, expectedPolicySet, pObject);

    PKIX_CHECK(PKIX_PL_Object_Alloc
               (PKIX_CERTPOLICYNODE_TYPE,
                sizeof (PKIX_PolicyNode),
                (PKIX_PL_Object **)&node,
                plContext),
               PKIX_COULDNOTCREATEPOLICYNODEOBJECT);

    PKIX_INCREF(validPolicy);
    node->validPolicy = validPolicy;

    PKIX_INCREF(qualifierSet);
    node->qualifierSet = qualifierSet;
    if (qualifierSet) {
        PKIX_CHECK(PKIX_List_SetImmutable(qualifierSet, plContext),
                   PKIX_LISTSETIMMUTABLEFAILED);
    }

    node->criticality = criticality;

    PKIX_INCREF(expectedPolicySet);
    node->expectedPolicySet = expectedPolicySet;
    PKIX_CHECK(PKIX_List_SetImmutable(expectedPolicySet, plContext),
               PKIX_LISTSETIMMUTABLEFAILED);

    node->parent = NULL;
    node->children = NULL;
    node->depth = 0;

    *pObject = node;
    node = NULL;

cleanup:

    PKIX_DECREF(node);

    PKIX_RETURN(CERTPOLICYNODE);
}
Example #2
0
/*
 * FUNCTION: PKIX_ProcessingParams_GetInitialPolicies
 *      (see comments in pkix_params.h)
 */
PKIX_Error *
PKIX_ProcessingParams_GetInitialPolicies(
        PKIX_ProcessingParams *params,
        PKIX_List **pInitPolicies, /* list of PKIX_PL_OID */
        void *plContext)
{

        PKIX_ENTER(PROCESSINGPARAMS,
                "PKIX_ProcessingParams_GetInitialPolicies");

        PKIX_NULLCHECK_TWO(params, pInitPolicies);

        if (params->initialPolicies == NULL) {
                PKIX_CHECK(PKIX_List_Create
                        (&params->initialPolicies, plContext),
                        PKIX_UNABLETOCREATELIST);
                PKIX_CHECK(PKIX_List_SetImmutable
                        (params->initialPolicies, plContext),
                        PKIX_UNABLETOMAKELISTIMMUTABLE);
                PKIX_CHECK(PKIX_PL_Object_InvalidateCache
                        ((PKIX_PL_Object *)params, plContext),
                        PKIX_OBJECTINVALIDATECACHEFAILED);
        }

        PKIX_INCREF(params->initialPolicies);
        *pInitPolicies = params->initialPolicies;

cleanup:

        PKIX_RETURN(PROCESSINGPARAMS);
}
Example #3
0
/*
 * FUNCTION: PKIX_PolicyNode_GetPolicyQualifiers
 * (see description of this function in pkix_results.h)
 */
PKIX_Error *
PKIX_PolicyNode_GetPolicyQualifiers(
    PKIX_PolicyNode *node,
    PKIX_List **pQualifiers,  /* list of PKIX_PL_CertPolicyQualifier */
    void *plContext)
{
    PKIX_List *qualifiers = NULL;

    PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetPolicyQualifiers");

    PKIX_NULLCHECK_TWO(node, pQualifiers);

    PKIX_INCREF(node->qualifierSet);
    qualifiers = node->qualifierSet;

    if (!qualifiers) {
        PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext),
                   PKIX_LISTCREATEFAILED);
    }

    PKIX_CHECK(PKIX_List_SetImmutable(qualifiers, plContext),
               PKIX_LISTSETIMMUTABLEFAILED);

    *pQualifiers = qualifiers;

cleanup:

    PKIX_RETURN(CERTPOLICYNODE);
}
Example #4
0
/*
 * FUNCTION: PKIX_PolicyNode_GetChildren
 * (see description of this function in pkix_results.h)
 */
PKIX_Error *
PKIX_PolicyNode_GetChildren(
    PKIX_PolicyNode *node,
    PKIX_List **pChildren,  /* list of PKIX_PolicyNode */
    void *plContext)
{
    PKIX_List *children = NULL;

    PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetChildren");

    PKIX_NULLCHECK_TWO(node, pChildren);

    PKIX_INCREF(node->children);
    children = node->children;

    if (!children) {
        PKIX_CHECK(PKIX_List_Create(&children, plContext),
                   PKIX_LISTCREATEFAILED);
    }

    PKIX_CHECK(PKIX_List_SetImmutable(children, plContext),
               PKIX_LISTSETIMMUTABLEFAILED);

    *pChildren = children;

cleanup:
    if (PKIX_ERROR_RECEIVED) {
        PKIX_DECREF(children);
    }

    PKIX_RETURN(CERTPOLICYNODE);
}
/*
 * FUNCTION: PKIX_ProcessingParams_Create (see comments in pkix_params.h)
 */
PKIX_Error *
PKIX_ProcessingParams_Create(
        PKIX_ProcessingParams **pParams,
        void *plContext)
{
        PKIX_ProcessingParams *params = NULL;

        PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_Create");
        PKIX_NULLCHECK_ONE(pParams);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_PROCESSINGPARAMS_TYPE,
                    sizeof (PKIX_ProcessingParams),
                    (PKIX_PL_Object **)&params,
                    plContext),
                    PKIX_COULDNOTCREATEPROCESSINGPARAMSOBJECT);

        /* initialize fields */
        PKIX_CHECK(PKIX_List_Create(&params->trustAnchors, plContext),
                   PKIX_LISTCREATEFAILED);
        PKIX_CHECK(PKIX_List_SetImmutable(params->trustAnchors, plContext),
                    PKIX_LISTSETIMMUTABLEFAILED);

        params->hintCerts = NULL;
        params->constraints = NULL;
        params->date = NULL;
        params->initialPolicies = NULL;
        params->initialPolicyMappingInhibit = PKIX_FALSE;
        params->initialAnyPolicyInhibit = PKIX_FALSE;
        params->initialExplicitPolicy = PKIX_FALSE;
        params->qualifiersRejected = PKIX_FALSE;
        params->certChainCheckers = NULL;
        params->revCheckers = NULL;
        params->certStores = NULL;
        params->resourceLimits = NULL;

        params->isCrlRevocationCheckingEnabled = PKIX_TRUE;

        params->isCrlRevocationCheckingEnabledWithNISTPolicy = PKIX_TRUE;

        params->useAIAForCertFetching = PKIX_FALSE;

        *pParams = params;
        params = NULL;

cleanup:

        PKIX_DECREF(params);

        PKIX_RETURN(PROCESSINGPARAMS);

}
PKIX_List *
createCertChainPlus(
        char *dirName,
        char *certNames[],
        PKIX_PL_Cert *certs[],
        PKIX_UInt32 numCerts,
        void *plContext)
{
        PKIX_List *certList = NULL;
        PKIX_UInt32 i;

        PKIX_TEST_STD_VARS();

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certList, plContext));

        for (i = 0; i < numCerts; i++) {

                certs[i] = createCert(dirName, certNames[i], plContext);

                /* Create Cert may fail */
                if (certs[i] == NULL) {
                        PKIX_TEST_DECREF_BC(certList);
                        goto cleanup;
                }

                PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                                            (certList,
                                            (PKIX_PL_Object *)certs[i],
                                            plContext));
        }

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable
                                    (certList, plContext));

cleanup:

        if (PKIX_TEST_ERROR_RECEIVED){
                PKIX_TEST_DECREF_AC(certList);
        }

        for (i = 0; i < numCerts; i++) {
                PKIX_TEST_DECREF_AC(certs[i]);
        }

        PKIX_TEST_RETURN();

        return (certList);

}
Example #7
0
/*
 * FUNCTION: pkix_pl_CRL_GetCRLEntries
 * DESCRIPTION:
 *
 *  Retrieves a pointer to the List of CRLEntries found in the CRL pointed to
 *  by "crl" and stores it at "pCRLEntries". If there are no CRLEntries,
 *  this functions stores NULL at "pCRLEntries".
 *
 * PARAMETERS:
 *  "crl"
 *      Address of CRL whose CRL Entries are to be retrieved. Must be non-NULL.
 *  "pCRLEntries"
 *      Address where object pointer will be stored. Must be non-NULL.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a CRL Error if the function fails in a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_CRL_GetCRLEntries(
        PKIX_PL_CRL *crl,
        PKIX_List **pCrlEntries,
        void *plContext)
{
        PKIX_List *entryList = NULL;
        CERTCrl *nssCrl = NULL;

        PKIX_ENTER(CRL, "pkix_pl_CRL_GetCRLEntries");
        PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlEntries);

        /* if we don't have a cached copy from before, we create one */
        if (crl->crlEntryList == NULL) {

                PKIX_OBJECT_LOCK(crl);

                if (crl->crlEntryList == NULL){

                        nssCrl = &(crl->nssSignedCrl->crl);

                        PKIX_CHECK(pkix_pl_CRLEntry_Create
                                    (nssCrl->entries, &entryList, plContext),
                                    PKIX_CRLENTRYCREATEFAILED);

                        PKIX_CHECK(PKIX_List_SetImmutable
                                    (entryList, plContext),
                                    PKIX_LISTSETIMMUTABLEFAILED);

                        crl->crlEntryList = entryList;
                }

                PKIX_OBJECT_UNLOCK(crl);

        }

        PKIX_INCREF(crl->crlEntryList);

        *pCrlEntries = crl->crlEntryList;

cleanup:

        PKIX_RETURN(CRL);
}
Example #8
0
/*
 * FUNCTION: PKIX_ProcessingParams_SetTrustAnchors
 * (see comments in pkix_params.h)
 */
PKIX_Error *
PKIX_ProcessingParams_SetTrustAnchors(
        PKIX_ProcessingParams *params,
        PKIX_List *anchors,  /* list of TrustAnchor */
        void *plContext)
{
        PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_SetTrustAnchors");
        PKIX_NULLCHECK_TWO(params, anchors);

        PKIX_DECREF(params->trustAnchors);

        PKIX_INCREF(anchors);
        params->trustAnchors = anchors;
        PKIX_CHECK(PKIX_List_SetImmutable(params->trustAnchors, plContext),
                    PKIX_LISTSETIMMUTABLEFAILED);

cleanup:
        PKIX_RETURN(PROCESSINGPARAMS);
}
PKIX_List *
createCertChain(
        char *dirName,
        char *firstCertFileName,
        char *secondCertFileName,
        void *plContext)
{
        PKIX_PL_Cert *firstCert = NULL;
        PKIX_PL_Cert *secondCert = NULL;
        PKIX_List *certList = NULL;

        PKIX_TEST_STD_VARS();

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certList, plContext));

        firstCert = createCert(dirName, firstCertFileName, plContext);

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (certList, (PKIX_PL_Object *)firstCert, plContext));

        if (secondCertFileName){
                secondCert = createCert(dirName, secondCertFileName, plContext);

                PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                        (certList, (PKIX_PL_Object *)secondCert, plContext));
        }

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable
                                    (certList, plContext));

cleanup:

        if (PKIX_TEST_ERROR_RECEIVED){
                PKIX_TEST_DECREF_AC(certList);
        }

        PKIX_TEST_DECREF_AC(firstCert);
        PKIX_TEST_DECREF_AC(secondCert);

        PKIX_TEST_RETURN();

        return (certList);
}
static
void testGetSetInitialPolicies(
        PKIX_ProcessingParams *goodObject,
        char *asciiPolicyOID)
{
        PKIX_PL_OID *policyOID = NULL;
        PKIX_List* setPolicyList = NULL;
        PKIX_List* getPolicyList = NULL;

        PKIX_TEST_STD_VARS();
        subTest("PKIX_ProcessingParams_Get/SetInitialPolicies");

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (asciiPolicyOID, &policyOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setPolicyList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (setPolicyList, (PKIX_PL_Object *)policyOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_SetImmutable(setPolicyList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetInitialPolicies
                (goodObject, setPolicyList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetInitialPolicies
                (goodObject, &getPolicyList, plContext));

        testEqualsHelper
                ((PKIX_PL_Object *)setPolicyList,
                (PKIX_PL_Object *)getPolicyList,
                PKIX_TRUE,
                plContext);

cleanup:
        PKIX_TEST_DECREF_AC(policyOID);
        PKIX_TEST_DECREF_AC(setPolicyList);
        PKIX_TEST_DECREF_AC(getPolicyList);

        PKIX_TEST_RETURN();
}
static
void testNistTest2(char *dirName)
{
#define PKIX_TEST_NUM_CERTS     2
        char *trustAnchor =
                "TrustAnchorRootCertificate.crt";
        char *intermediateCert =
                "GoodCACert.crt";
        char *endEntityCert =
                "ValidCertificatePathTest1EE.crt";
        char *certNames[PKIX_TEST_NUM_CERTS];
        char *asciiNist1Policy = "2.16.840.1.101.3.2.1.48.1";
        PKIX_PL_Cert *certs[PKIX_TEST_NUM_CERTS] = { NULL, NULL };

        PKIX_ValidateParams *valParams = NULL;
        PKIX_ValidateResult *valResult = NULL;
        PKIX_List *chain = NULL;
        PKIX_PL_OID *Nist1PolicyOID = NULL;
        PKIX_List *initialPolicies = NULL;
        char *anchorName = NULL;

        PKIX_TEST_STD_VARS();

        subTest("testNistTest2: Creating the cert chain");
        /*
         * Create a chain, but don't include the first certName.
         * That's the anchor, and is supplied separately from
         * the chain.
         */
        certNames[0] = intermediateCert;
        certNames[1] = endEntityCert;
        chain = createCertChainPlus
                (dirName, certNames, certs, PKIX_TEST_NUM_CERTS, plContext);

        subTest("testNistTest2: Creating the Validate Parameters");
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (asciiNist1Policy, &Nist1PolicyOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_Create(&initialPolicies, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (initialPolicies, (PKIX_PL_Object *)Nist1PolicyOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable
                (initialPolicies, plContext));

        valParams = createValidateParams
                (dirName,
                trustAnchor,
                NULL,
                NULL,
                initialPolicies,
                PKIX_FALSE,
                PKIX_FALSE,
                PKIX_FALSE,
                PKIX_FALSE,
                chain,
                plContext);

        subTest("testNistTest2: Validating the chain");
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain
                (valParams, &valResult, NULL, plContext));


cleanup:

        PKIX_PL_Free(anchorName, plContext);

        PKIX_TEST_DECREF_AC(Nist1PolicyOID);
        PKIX_TEST_DECREF_AC(initialPolicies);
        PKIX_TEST_DECREF_AC(valParams);
        PKIX_TEST_DECREF_AC(valResult);
        PKIX_TEST_DECREF_AC(chain);

        PKIX_TEST_RETURN();
}
/*
 * FUNCTION: pkix_pl_LdapCertStore_GetCRL
 *  (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
 */
PKIX_Error *
pkix_pl_LdapCertStore_GetCRL(
        PKIX_CertStore *store,
        PKIX_CRLSelector *selector,
        void **pNBIOContext,
        PKIX_List **pCrlList,
        void *plContext)
{
        LDAPRequestParams requestParams;
        void *pollDesc = NULL;
        PRArenaPool *requestArena = NULL;
        PKIX_UInt32 numNames = 0;
        PKIX_UInt32 thisName = 0;
        PKIX_PL_CRL *candidate = NULL;
        PKIX_List *responses = NULL;
        PKIX_List *issuerNames = NULL;
        PKIX_List *filteredCRLs = NULL;
        PKIX_List *unfilteredCRLs = NULL;
        PKIX_PL_X500Name *issuer = NULL;
        PKIX_PL_LdapCertStoreContext *lcs = NULL;
        PKIX_ComCRLSelParams *params = NULL;

        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCRL");
        PKIX_NULLCHECK_THREE(store, selector, pCrlList);

        requestParams.baseObject = "c=US";
        requestParams.scope = WHOLE_SUBTREE;
        requestParams.derefAliases = NEVER_DEREF;
        requestParams.sizeLimit = 0;
        requestParams.timeLimit = 0;
        requestParams.attributes = LDAPATTR_CERTREVLIST | LDAPATTR_AUTHREVLIST;
        /* Prepare elements for request filter */

        /* XXX Place CRLDP code here. Handle the case when */
        /* RFC 5280. Paragraph: 4.2.1.13: */
        /* If the distributionPoint field contains a directoryName, the entry */
        /* for that directoryName contains the current CRL for the associated */
        /* reasons and the CRL is issued by the associated cRLIssuer.  The CRL */
        /* may be stored in either the certificateRevocationList or */
        /* authorityRevocationList attribute.  The CRL is to be obtained by the */
        /* application from whatever directory server is locally configured. */
        /* The protocol the application uses to access the directory (e.g., DAP */
        /* or LDAP) is a local matter. */



        /*
         * Get a short-lived arena. We'll be done with this space once
         * the request is encoded.
         */
        PKIX_PL_NSSCALLRV
            (CERTSTORE, requestArena, PORT_NewArena, (DER_DEFAULT_CHUNKSIZE));

        if (!requestArena) {
                PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
        }

        PKIX_CHECK(PKIX_CRLSelector_GetCommonCRLSelectorParams
                (selector, &params, plContext),
                PKIX_CRLSELECTORGETCOMCERTSELPARAMSFAILED);

        PKIX_CHECK(PKIX_ComCRLSelParams_GetIssuerNames
                (params, &issuerNames, plContext),
                PKIX_COMCRLSELPARAMSGETISSUERNAMESFAILED);

        /*
         * The specification for PKIX_ComCRLSelParams_GetIssuerNames in
         * pkix_crlsel.h says that if the criterion is not set we get a null
         * pointer. If we get an empty List the criterion is impossible to
         * meet ("must match at least one of the names in the List").
         */
        if (issuerNames) {

                PKIX_CHECK(PKIX_List_GetLength
                        (issuerNames, &numNames, plContext),
                        PKIX_LISTGETLENGTHFAILED);

                if (numNames > 0) {
                        for (thisName = 0; thisName < numNames; thisName++) {
                                PKIX_CHECK(PKIX_List_GetItem
                                (issuerNames,
                                thisName,
                                (PKIX_PL_Object **)&issuer,
                                plContext),
                                PKIX_LISTGETITEMFAILED);

                                PKIX_CHECK
                                        (pkix_pl_LdapCertStore_MakeNameAVAList
                                        (requestArena,
                                        issuer,
                                        &(requestParams.nc),
                                        plContext),
                                        PKIX_LDAPCERTSTOREMAKENAMEAVALISTFAILED);

                                PKIX_DECREF(issuer);

                                if (*requestParams.nc == NULL) {
                                        /*
                                         * The issuer may not include any
                                         * components that we know how to
                                         * encode. We do not return an error,
                                         * because the caller did not
                                         * necessarily do anything wrong, but
                                         * we return an empty List.
                                         */
                                        PKIX_PL_NSSCALL
                                                (CERTSTORE, PORT_FreeArena,
                                                (requestArena, PR_FALSE));

                                        PKIX_CHECK(PKIX_List_Create
                                                (&filteredCRLs, plContext),
                                                PKIX_LISTCREATEFAILED);

                                        PKIX_CHECK(PKIX_List_SetImmutable
                                                (filteredCRLs, plContext),
                                               PKIX_LISTSETIMMUTABLEFAILED);

                                        *pNBIOContext = NULL;
                                        *pCrlList = filteredCRLs;
                                        goto cleanup;
                                }

                                /*
                                 * LDAP Servers don't seem to be able to handle
                                 * requests with more than more than one name.
                                 */
                                break;
                        }
                } else {
                        PKIX_ERROR(PKIX_IMPOSSIBLECRITERIONFORCRLQUERY);
                }
        } else {
                PKIX_ERROR(PKIX_IMPOSSIBLECRITERIONFORCRLQUERY);
        }

        /* All request fields are done */

        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
                (store, (PKIX_PL_Object **)&lcs, plContext),
                PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);

        PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
                ((PKIX_PL_LdapClient *)lcs,
                &requestParams,
                &pollDesc,
                &responses,
                plContext),
                PKIX_LDAPCLIENTINITIATEREQUESTFAILED);

        PKIX_CHECK(pkix_pl_LdapCertStore_DestroyAVAList
                (requestParams.nc, plContext),
                PKIX_LDAPCERTSTOREDESTROYAVALISTFAILED);

        if (requestArena) {
                PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
                        (requestArena, PR_FALSE));
        }

        if (pollDesc != NULL) {
                /* client is waiting for non-blocking I/O to complete */
                *pNBIOContext = (void *)pollDesc;
                *pCrlList = NULL;
                goto cleanup;
        }
        /* client has finished! */

        if (responses) {

                /*
                 * We have a List of LdapResponse objects that still have to be
                 * turned into Crls.
                 */
                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCrlList
                        (responses, &unfilteredCRLs, plContext),
                        PKIX_LDAPCERTSTOREBUILDCRLLISTFAILED);

                PKIX_CHECK(pkix_CRLSelector_Select
                        (selector, unfilteredCRLs, &filteredCRLs, plContext),
                        PKIX_CRLSELECTORSELECTFAILED);

        }

        /* Don't throw away the list if one CRL was bad! */
        pkixTempErrorReceived = PKIX_FALSE;

        *pNBIOContext = NULL;
        *pCrlList = filteredCRLs;

cleanup:

        if (PKIX_ERROR_RECEIVED) {
                PKIX_DECREF(filteredCRLs);
        }

        PKIX_DECREF(params);
        PKIX_DECREF(issuerNames);
        PKIX_DECREF(issuer);
        PKIX_DECREF(candidate);
        PKIX_DECREF(responses);
        PKIX_DECREF(unfilteredCRLs);
        PKIX_DECREF(lcs);

        PKIX_RETURN(CERTSTORE);
}
/*
 * FUNCTION: pkix_pl_LdapCertStore_GetCert
 *  (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
 */
PKIX_Error *
pkix_pl_LdapCertStore_GetCert(
        PKIX_CertStore *store,
        PKIX_CertSelector *selector,
        PKIX_VerifyNode *verifyNode,
        void **pNBIOContext,
        PKIX_List **pCertList,
        void *plContext)
{
        PRArenaPool *requestArena = NULL;
        LDAPRequestParams requestParams;
        void *pollDesc = NULL;
        PKIX_Int32 minPathLen = 0;
        PKIX_Boolean cacheFlag = PKIX_FALSE;
        PKIX_ComCertSelParams *params = NULL;
        PKIX_PL_LdapCertStoreContext *lcs = NULL;
        PKIX_List *responses = NULL;
        PKIX_List *unfilteredCerts = NULL;
        PKIX_List *filteredCerts = NULL;
        PKIX_PL_X500Name *subjectName = 0;

        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCert");
        PKIX_NULLCHECK_THREE(store, selector, pCertList);

        requestParams.baseObject = "c=US";
        requestParams.scope = WHOLE_SUBTREE;
        requestParams.derefAliases = NEVER_DEREF;
        requestParams.sizeLimit = 0;
        requestParams.timeLimit = 0;

        /* Prepare elements for request filter */

        /*
         * Get a short-lived arena. We'll be done with this space once
         * the request is encoded.
         */
        requestArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (!requestArena) {
                PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
        }

        PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
                (selector, &params, plContext),
                PKIX_CERTSELECTORGETCOMCERTSELPARAMSFAILED);

        /*
         * If we have the subject name for the desired subject,
         * ask the server for Certs with that subject.
         */
        PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
                (params, &subjectName, plContext),
                PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);

        PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints
                (params, &minPathLen, plContext),
                PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED);

        if (subjectName) {
                PKIX_CHECK(pkix_pl_LdapCertStore_MakeNameAVAList
                        (requestArena,
                        subjectName,
                        &(requestParams.nc),
                        plContext),
                        PKIX_LDAPCERTSTOREMAKENAMEAVALISTFAILED);

                if (*requestParams.nc == NULL) {
                        /*
                         * The subjectName may not include any components
                         * that we know how to encode. We do not return
                         * an error, because the caller did not necessarily
                         * do anything wrong, but we return an empty List.
                         */
                        PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
                                (requestArena, PR_FALSE));

                        PKIX_CHECK(PKIX_List_Create(&filteredCerts, plContext),
                                PKIX_LISTCREATEFAILED);

                        PKIX_CHECK(PKIX_List_SetImmutable
                                (filteredCerts, plContext),
                                PKIX_LISTSETIMMUTABLEFAILED);

                        *pNBIOContext = NULL;
                        *pCertList = filteredCerts;
                        filteredCerts = NULL;
                        goto cleanup;
                }
        } else {
                PKIX_ERROR(PKIX_INSUFFICIENTCRITERIAFORCERTQUERY);
        }

        /* Prepare attribute field of request */

        requestParams.attributes = 0;

        if (minPathLen < 0) {
                requestParams.attributes |= LDAPATTR_USERCERT;
        }

        if (minPathLen > -2) {
                requestParams.attributes |=
                        LDAPATTR_CACERT | LDAPATTR_CROSSPAIRCERT;
        }

        /* All request fields are done */

        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
                (store, (PKIX_PL_Object **)&lcs, plContext),
                PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);

        PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
                ((PKIX_PL_LdapClient *)lcs,
                &requestParams,
                &pollDesc,
                &responses,
                plContext),
                PKIX_LDAPCLIENTINITIATEREQUESTFAILED);

        PKIX_CHECK(pkix_pl_LdapCertStore_DestroyAVAList
                (requestParams.nc, plContext),
                PKIX_LDAPCERTSTOREDESTROYAVALISTFAILED);

        if (requestArena) {
                PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
                        (requestArena, PR_FALSE));
                requestArena = NULL;
        }

        if (pollDesc != NULL) {
                /* client is waiting for non-blocking I/O to complete */
                *pNBIOContext = (void *)pollDesc;
                *pCertList = NULL;
                goto cleanup;
        }
        /* LdapClient has given us a response! */

        if (responses) {
                PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
                        (store, &cacheFlag, plContext),
                        PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);

                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
                        (responses, &unfilteredCerts, plContext),
                        PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);

                PKIX_CHECK(pkix_CertSelector_Select
                        (selector, unfilteredCerts, &filteredCerts, plContext),
                        PKIX_CERTSELECTORSELECTFAILED);
        }

        *pNBIOContext = NULL;
        *pCertList = filteredCerts;
        filteredCerts = NULL;

cleanup:

        PKIX_DECREF(params);
        PKIX_DECREF(subjectName);
        PKIX_DECREF(responses);
        PKIX_DECREF(unfilteredCerts);
        PKIX_DECREF(filteredCerts);
        PKIX_DECREF(lcs);

        PKIX_RETURN(CERTSTORE);
}
/*
 * FUNCTION: pkix_pl_LdapCertStore_GetCRLContinue
 *  (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
 */
PKIX_Error *
pkix_pl_LdapCertStore_GetCRLContinue(
        PKIX_CertStore *store,
        PKIX_CRLSelector *selector,
        void **pNBIOContext,
        PKIX_List **pCrlList,
        void *plContext)
{
        void *nbio = NULL;
        PKIX_PL_CRL *candidate = NULL;
        PKIX_List *responses = NULL;
        PKIX_PL_LdapCertStoreContext *lcs = NULL;
        PKIX_List *filteredCRLs = NULL;
        PKIX_List *unfilteredCRLs = NULL;

        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCRLContinue");
        PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCrlList);

        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
                (store, (PKIX_PL_Object **)&lcs, plContext),
                PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);

        PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
                ((PKIX_PL_LdapClient *)lcs, &nbio, &responses, plContext),
                PKIX_LDAPCLIENTRESUMEREQUESTFAILED);

        if (nbio != NULL) {
                /* client is waiting for non-blocking I/O to complete */
                *pNBIOContext = (void *)nbio;
                *pCrlList = NULL;
                goto cleanup;
        }
        /* client has finished! */

        if (responses) {

                /*
                 * We have a List of LdapResponse objects that still have to be
                 * turned into Crls.
                 */
                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCrlList
                        (responses, &unfilteredCRLs, plContext),
                        PKIX_LDAPCERTSTOREBUILDCRLLISTFAILED);

                PKIX_CHECK(pkix_CRLSelector_Select
                        (selector, unfilteredCRLs, &filteredCRLs, plContext),
                        PKIX_CRLSELECTORSELECTFAILED);

                PKIX_CHECK(PKIX_List_SetImmutable(filteredCRLs, plContext),
                        PKIX_LISTSETIMMUTABLEFAILED);

        }

        /* Don't throw away the list if one CRL was bad! */
        pkixTempErrorReceived = PKIX_FALSE;

        *pCrlList = filteredCRLs;

cleanup:
        if (PKIX_ERROR_RECEIVED) {
                PKIX_DECREF(filteredCRLs);
        }

        PKIX_DECREF(candidate);
        PKIX_DECREF(responses);
        PKIX_DECREF(unfilteredCRLs);
        PKIX_DECREF(lcs);

        PKIX_RETURN(CERTSTORE);
}
/*
 * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCRL
 * DESCRIPTION:
 *
 *  Create list of CRLs from *.crl files at directory specified in dirName,
 *  Not recursive to sub-dirctory. Also assume the directory contents are
 *  not changed dynamically.
 *
 * PARAMETERS
 *  "colCertStoreContext" - Address of CollectionCertStoreContext
 *              where the dirName is specified and where the return
 *              CRLs are stored as a list. Must be non-NULL.
 *  "plContext" - Platform-specific context pointer.
 *
 * THREAD SAFETY:
 *  Not Thread Safe - A lock at top level is required.
 *
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a CollectionCertStoreContext Error if the function fails in
 *              a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_CollectionCertStoreContext_PopulateCRL(
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext,
        void *plContext)
{
        PKIX_List *crlList = NULL;
        PKIX_PL_CRL *crlItem = NULL;
        char *dirName = NULL;
        char *pathName = NULL;
        PKIX_UInt32 dirNameLen = 0;
        PRErrorCode prError = 0;
        PRDir *dir = NULL;
        PRDirEntry *dirEntry = NULL;

        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
                    "pkix_pl_CollectionCertStoreContext_PopulateCRL");
        PKIX_NULLCHECK_ONE(colCertStoreContext);

        /* convert directory to ascii */

        PKIX_CHECK(PKIX_PL_String_GetEncoded
                    (colCertStoreContext->storeDir,
                    PKIX_ESCASCII,
                    (void **)&dirName,
                    &dirNameLen,
                    plContext),
                    PKIX_STRINGGETENCODEDFAILED);

        /* create CRL list, if no CRL file, should return an empty list */

        PKIX_CHECK(PKIX_List_Create(&crlList, plContext),
                    PKIX_LISTCREATEFAILED);

        /* open directory and read in .crl files */

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n");
        dir = PR_OpenDir(dirName);

        if (!dir) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG
                        ("\t\t Directory Name:%s\n", dirName);
                PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY);
        }

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n");
        dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);

        if (!dirEntry) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Empty directory.\n");
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_GetError.\n");
                prError = PR_GetError();
        }

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n");
        PR_SetError(0, 0);

        while (dirEntry != NULL && prError == 0) {
                if (PL_strrstr(dirEntry->name, ".crl") ==
                    dirEntry->name + PL_strlen(dirEntry->name) - 4) {

                        PKIX_CHECK_ONLY_FATAL
                                (PKIX_PL_Malloc
                                (dirNameLen + PL_strlen(dirEntry->name) + 2,
                                (void **)&pathName,
                                plContext),
                                PKIX_MALLOCFAILED);

                        if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){

                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                    ("\t\t Calling PL_strcpy for dirName.\n");
                                PL_strcpy(pathName, dirName);
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                    ("\t\t Calling PL_strcat for dirName.\n");
                                PL_strcat(pathName, "/");
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                        ("\t\t Calling PL_strcat for /.\n");
                                PL_strcat(pathName, dirEntry->name);

                        PKIX_CHECK_ONLY_FATAL
                                (pkix_pl_CollectionCertStoreContext_CreateCRL
                                (pathName, &crlItem, plContext),
                                PKIX_COLLECTIONCERTSTORECONTEXTCREATECRLFAILED);

                                if (!PKIX_ERROR_RECEIVED){
                                        PKIX_CHECK_ONLY_FATAL
                                                (PKIX_List_AppendItem
                                                (crlList,
                                                (PKIX_PL_Object *)crlItem,
                                                plContext),
                                                PKIX_LISTAPPENDITEMFAILED);
                                }
                        }

                        PKIX_DECREF(crlItem);
                        PKIX_FREE(pathName);
                }

                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_SetError.\n");
                PR_SetError(0, 0);

                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_ReadDir.\n");
                dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);

                if (!dirEntry) {
                    PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_GetError.\n");
                    prError = PR_GetError();
                }
        }

        if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) {
                PKIX_ERROR(PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED);
        }

        PKIX_CHECK(PKIX_List_SetImmutable(crlList, plContext),
                    PKIX_LISTSETIMMUTABLEFAILED);

        PKIX_INCREF(crlList);
        colCertStoreContext->crlList = crlList;

cleanup:
        if (dir) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_CloseDir.\n");
                PR_CloseDir(dir);
        }

        PKIX_FREE(pathName);
        PKIX_FREE(dirName);

        if (PKIX_ERROR_RECEIVED){
                PKIX_DECREF(crlList);
        }

        PKIX_DECREF(crlItem);
        PKIX_DECREF(crlList);

        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
}
Example #16
0
/*
 * FUNCTION: PKIX_Logger_GetLoggers (see comments in pkix_util.h)
 */
PKIX_Error *
PKIX_GetLoggers(
        PKIX_List **pLoggers,  /* list of PKIX_Logger */
        void *plContext)
{
        PKIX_List *list = NULL;
        PKIX_List *savedPkixLoggersDebugTrace = NULL;
        PKIX_List *savedPkixLoggersErrors = NULL;
        PKIX_Logger *logger = NULL;
        PKIX_Logger *dupLogger = NULL;
        PKIX_UInt32 i, length;
        PKIX_Boolean locked = PKIX_FALSE;

        PKIX_ENTER(LOGGER, "PKIX_Logger_GetLoggers");
        PKIX_NULLCHECK_ONE(pLoggers);

        PKIX_CHECK(PKIX_PL_MonitorLock_Enter(pkixLoggerLock, plContext),
                PKIX_MONITORLOCKENTERFAILED);
        locked = PKIX_TRUE;

        /*
         * Temporarily disable DEBUG/TRACE Logging to avoid possible
         * deadlock:
         * When the Logger List is being accessed, e.g. by PKIX_ENTER or
         * PKIX_DECREF, pkix_Logger_Check may check whether logging
         * is requested, creating a deadlock situation.
         */
        savedPkixLoggersDebugTrace = pkixLoggersDebugTrace;
        pkixLoggersDebugTrace = NULL;
        savedPkixLoggersErrors = pkixLoggersErrors;
        pkixLoggersErrors = NULL;

        if (pkixLoggers == NULL) {
                length = 0;
        } else {
                PKIX_CHECK(PKIX_List_GetLength
                    (pkixLoggers, &length, plContext),
                    PKIX_LISTGETLENGTHFAILED);
        }

        /* Create a list and copy the pkixLoggers item to the list */
        PKIX_CHECK(PKIX_List_Create(&list, plContext),
                    PKIX_LISTCREATEFAILED);

        for (i = 0; i < length; i++) {

            PKIX_CHECK(PKIX_List_GetItem
                        (pkixLoggers,
                        i,
                        (PKIX_PL_Object **) &logger,
                        plContext),
                        PKIX_LISTGETITEMFAILED);

            PKIX_CHECK(pkix_Logger_Duplicate
                        ((PKIX_PL_Object *)logger,
                        (PKIX_PL_Object **)&dupLogger,
                        plContext),
                        PKIX_LOGGERDUPLICATEFAILED);

            PKIX_CHECK(PKIX_List_AppendItem
                        (list,
                        (PKIX_PL_Object *) dupLogger,
                        plContext),
                        PKIX_LISTAPPENDITEMFAILED);

            PKIX_DECREF(logger);
            PKIX_DECREF(dupLogger);
        }

        /* Set the list to be immutable */
        PKIX_CHECK(PKIX_List_SetImmutable(list, plContext),
                        PKIX_LISTSETIMMUTABLEFAILED);

        *pLoggers = list;

cleanup:

        PKIX_DECREF(logger);

        /* Restore logging capability */
        pkixLoggersDebugTrace = savedPkixLoggersDebugTrace;
        pkixLoggersErrors = savedPkixLoggersErrors;

        if (locked) {
                PKIX_CHECK(PKIX_PL_MonitorLock_Exit(pkixLoggerLock, plContext),
                        PKIX_MONITORLOCKEXITFAILED);
        }

        PKIX_RETURN(LOGGER);
}