/* * 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); }
/* * 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 (¶ms->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); }
/* * 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); }
/* * 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 **)¶ms, plContext), PKIX_COULDNOTCREATEPROCESSINGPARAMSOBJECT); /* initialize fields */ PKIX_CHECK(PKIX_List_Create(¶ms->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); }
/* * 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); }
/* * 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, ¶ms, 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, ¶ms, 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); }
/* * 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); }