/* * FUNCTION: pkix_pl_LdapCertStore_DecodeCrossCertPair * DESCRIPTION: * * This function decodes a DER-encoded CrossCertPair pointed to by * "responseList" and extracts and decodes the Certificates in that pair, * adding the resulting Certs, if the decoding was successful, to the List * (possibly empty) pointed to by "certList". If none of the objects * can be decoded into a Cert, the List is returned unchanged. * * PARAMETERS: * "derCCPItem" * The address of the SECItem containing the DER representation of the * CrossCertPair. Must be non-NULL. * "certList" * The address of the List to which the decoded Certs are added. May be * empty, but 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 CertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_LdapCertStore_DecodeCrossCertPair( SECItem *derCCPItem, PKIX_List *certList, void *plContext) { LDAPCertPair certPair = {{ siBuffer, NULL, 0 }, { siBuffer, NULL, 0 }}; SECStatus rv = SECFailure; PRArenaPool *tempArena = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_DecodeCrossCertPair"); PKIX_NULLCHECK_TWO(derCCPItem, certList); tempArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!tempArena) { PKIX_ERROR(PKIX_OUTOFMEMORY); } rv = SEC_ASN1DecodeItem(tempArena, &certPair, PKIX_PL_LDAPCrossCertPairTemplate, derCCPItem); if (rv != SECSuccess) { goto cleanup; } if (certPair.forward.data != NULL) { PKIX_CHECK( pkix_pl_Cert_CreateToList(&certPair.forward, certList, plContext), PKIX_CERTCREATETOLISTFAILED); } if (certPair.reverse.data != NULL) { PKIX_CHECK( pkix_pl_Cert_CreateToList(&certPair.reverse, certList, plContext), PKIX_CERTCREATETOLISTFAILED); } cleanup: if (tempArena) { PORT_FreeArena(tempArena, PR_FALSE); } PKIX_RETURN(CERTSTORE); }
/* * FUNCTION: certCallback * DESCRIPTION: * * This function processes the null-terminated array of SECItems produced by * extracting the contents of a signedData message received in response to an * HTTP cert query. Its address is supplied as a callback function to * CERT_DecodeCertPackage; it is not expected to be called directly. * * Note that it does not conform to the libpkix API standard of returning * a PKIX_Error*. It returns a SECStatus. * * PARAMETERS: * "arg" * The address of the callbackContext provided as a void* argument to * CERT_DecodeCertPackage. Must be non-NULL. * "secitemCerts" * The address of the null-terminated array of SECItems. Must be non-NULL. * "numcerts" * The number of SECItems found in the signedData. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns SECSuccess if the function succeeds. * Returns SECFailure if the function fails. */ static SECStatus certCallback(void *arg, SECItem **secitemCerts, int numcerts) { callbackContext *cbContext; PKIX_List *pkixCertList = NULL; PKIX_Error *error = NULL; void *plContext = NULL; int itemNum = 0; if ((arg == NULL) || (secitemCerts == NULL)) { return (SECFailure); } cbContext = (callbackContext *)arg; plContext = cbContext->plContext; pkixCertList = cbContext->pkixCertList; for (; itemNum < numcerts; itemNum++ ) { error = pkix_pl_Cert_CreateToList(secitemCerts[itemNum], pkixCertList, plContext); if (error != NULL) { if (error->errClass == PKIX_FATAL_ERROR) { cbContext->error = error; return SECFailure; } /* reuse "error" since we could not destruct the old * * value */ error = PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); if (error) { /* Treat decref failure as a fatal error. * In this case will leak error, but can not do * anything about it. */ error->errClass = PKIX_FATAL_ERROR; cbContext->error = error; return SECFailure; } } } return SECSuccess; }
/* * FUNCTION: pkix_pl_LdapCertStore_BuildCertList * DESCRIPTION: * * This function takes a List of LdapResponse objects pointed to by * "responseList" and extracts and decodes the Certificates in those responses, * storing the List of those Certificates at "pCerts". If none of the objects * can be decoded into a Cert, the returned List is empty. * * PARAMETERS: * "responseList" * The address of the List of LdapResponses. Must be non-NULL. * "pCerts" * The address at which the result is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a CertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_LdapCertStore_BuildCertList( PKIX_List *responseList, PKIX_List **pCerts, void *plContext) { PKIX_UInt32 numResponses = 0; PKIX_UInt32 respIx = 0; LdapAttrMask attrBits = 0; PKIX_PL_LdapResponse *response = NULL; PKIX_List *certList = NULL; LDAPMessage *message = NULL; LDAPSearchResponseEntry *sre = NULL; LDAPSearchResponseAttr **sreAttrArray = NULL; LDAPSearchResponseAttr *sreAttr = NULL; SECItem *attrType = NULL; SECItem **attrVal = NULL; SECItem *derCertItem = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_BuildCertList"); PKIX_NULLCHECK_TWO(responseList, pCerts); PKIX_CHECK(PKIX_List_Create(&certList, plContext), PKIX_LISTCREATEFAILED); /* extract certs from response */ PKIX_CHECK(PKIX_List_GetLength (responseList, &numResponses, plContext), PKIX_LISTGETLENGTHFAILED); for (respIx = 0; respIx < numResponses; respIx++) { PKIX_CHECK(PKIX_List_GetItem (responseList, respIx, (PKIX_PL_Object **)&response, plContext), PKIX_LISTGETITEMFAILED); PKIX_CHECK(pkix_pl_LdapResponse_GetMessage (response, &message, plContext), PKIX_LDAPRESPONSEGETMESSAGEFAILED); sre = &(message->protocolOp.op.searchResponseEntryMsg); sreAttrArray = sre->attributes; /* Get next element of null-terminated array */ sreAttr = *sreAttrArray++; while (sreAttr != NULL) { attrType = &(sreAttr->attrType); PKIX_CHECK(pkix_pl_LdapRequest_AttrTypeToBit (attrType, &attrBits, plContext), PKIX_LDAPREQUESTATTRTYPETOBITFAILED); /* Is this attrVal a Certificate? */ if (((LDAPATTR_CACERT | LDAPATTR_USERCERT) & attrBits) == attrBits) { attrVal = sreAttr->val; derCertItem = *attrVal++; while (derCertItem != 0) { /* create a PKIX_PL_Cert from derCert */ PKIX_CHECK(pkix_pl_Cert_CreateToList (derCertItem, certList, plContext), PKIX_CERTCREATETOLISTFAILED); derCertItem = *attrVal++; } } else if ((LDAPATTR_CROSSPAIRCERT & attrBits) == attrBits){ /* Is this attrVal a CrossPairCertificate? */ attrVal = sreAttr->val; derCertItem = *attrVal++; while (derCertItem != 0) { /* create PKIX_PL_Certs from derCert */ PKIX_CHECK(pkix_pl_LdapCertStore_DecodeCrossCertPair (derCertItem, certList, plContext), PKIX_LDAPCERTSTOREDECODECROSSCERTPAIRFAILED); derCertItem = *attrVal++; } } sreAttr = *sreAttrArray++; } PKIX_DECREF(response); } *pCerts = certList; cleanup: if (PKIX_ERROR_RECEIVED) { PKIX_DECREF(certList); } PKIX_DECREF(response); PKIX_RETURN(CERTSTORE); }