diff options
Diffstat (limited to 'security/nss/lib/certhigh/certvfypkix.c')
-rw-r--r-- | security/nss/lib/certhigh/certvfypkix.c | 2318 |
1 files changed, 0 insertions, 2318 deletions
diff --git a/security/nss/lib/certhigh/certvfypkix.c b/security/nss/lib/certhigh/certvfypkix.c deleted file mode 100644 index a37a722b4..000000000 --- a/security/nss/lib/certhigh/certvfypkix.c +++ /dev/null @@ -1,2318 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* - * nss_pkix_proxy.h - * - * PKIX - NSS proxy functions - * - * NOTE: All structures, functions, data types are parts of library private - * api and are subjects to change in any following releases. - * - */ -#include "prerror.h" -#include "prprf.h" - -#include "nspr.h" -#include "pk11func.h" -#include "certdb.h" -#include "cert.h" -#include "secerr.h" -#include "nssb64.h" -#include "secasn1.h" -#include "secder.h" -#include "pkit.h" - -#include "pkix_pl_common.h" - -extern PRLogModuleInfo *pkixLog; - -#ifdef DEBUG_volkov -/* Temporary declarations of functioins. Will be removed with fix for - * 391183 */ -extern char * -pkix_Error2ASCII(PKIX_Error *error, void *plContext); - -extern void -cert_PrintCert(PKIX_PL_Cert *pkixCert, void *plContext); - -extern PKIX_Error * -cert_PrintCertChain(PKIX_List *pkixCertChain, void *plContext); - -#endif /* DEBUG */ - -#ifdef PKIX_OBJECT_LEAK_TEST - -extern PKIX_UInt32 -pkix_pl_lifecycle_ObjectLeakCheck(int *); - -extern SECStatus -pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable); - -PRInt32 parallelFnInvocationCount; -#endif /* PKIX_OBJECT_LEAK_TEST */ - - -static PRBool usePKIXValidationEngine = PR_FALSE; - -/* - * FUNCTION: CERT_SetUsePKIXForValidation - * DESCRIPTION: - * - * Enables or disables use of libpkix for certificate validation - * - * PARAMETERS: - * "enable" - * PR_TRUE: enables use of libpkix for cert validation. - * PR_FALSE: disables. - * THREAD SAFETY: - * NOT Thread Safe. - * RETURNS: - * Returns SECSuccess if successfully enabled - */ -SECStatus -CERT_SetUsePKIXForValidation(PRBool enable) -{ - usePKIXValidationEngine = (enable > 0) ? PR_TRUE : PR_FALSE; - return SECSuccess; -} - -/* - * FUNCTION: CERT_GetUsePKIXForValidation - * DESCRIPTION: - * - * Checks if libpkix building function should be use for certificate - * chain building. - * - * PARAMETERS: - * NONE - * THREAD SAFETY: - * NOT Thread Safe - * RETURNS: - * Returns PR_TRUE if libpkix should be used. PR_FALSE otherwise. - */ -PRBool -CERT_GetUsePKIXForValidation() -{ - return usePKIXValidationEngine; -} - -#ifdef NOTDEF -/* - * FUNCTION: cert_NssKeyUsagesToPkix - * DESCRIPTION: - * - * Converts nss key usage bit field(PRUint32) to pkix key usage - * bit field. - * - * PARAMETERS: - * "nssKeyUsage" - * Nss key usage bit field. - * "pkixKeyUsage" - * Pkix key usage big field. - * "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 Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error* -cert_NssKeyUsagesToPkix( - PRUint32 nssKeyUsage, - PKIX_UInt32 *pPkixKeyUsage, - void *plContext) -{ - PKIX_UInt32 pkixKeyUsage = 0; - - PKIX_ENTER(CERTVFYPKIX, "cert_NssKeyUsagesToPkix"); - PKIX_NULLCHECK_ONE(pPkixKeyUsage); - - *pPkixKeyUsage = 0; - - if (nssKeyUsage & KU_DIGITAL_SIGNATURE) { - pkixKeyUsage |= PKIX_DIGITAL_SIGNATURE; - } - - if (nssKeyUsage & KU_NON_REPUDIATION) { - pkixKeyUsage |= PKIX_NON_REPUDIATION; - } - - if (nssKeyUsage & KU_KEY_ENCIPHERMENT) { - pkixKeyUsage |= PKIX_KEY_ENCIPHERMENT; - } - - if (nssKeyUsage & KU_DATA_ENCIPHERMENT) { - pkixKeyUsage |= PKIX_DATA_ENCIPHERMENT; - } - - if (nssKeyUsage & KU_KEY_AGREEMENT) { - pkixKeyUsage |= PKIX_KEY_AGREEMENT; - } - - if (nssKeyUsage & KU_KEY_CERT_SIGN) { - pkixKeyUsage |= PKIX_KEY_CERT_SIGN; - } - - if (nssKeyUsage & KU_CRL_SIGN) { - pkixKeyUsage |= PKIX_CRL_SIGN; - } - - if (nssKeyUsage & KU_ENCIPHER_ONLY) { - pkixKeyUsage |= PKIX_ENCIPHER_ONLY; - } - - /* Not supported. XXX we should support this once it is - * fixed in NSS */ - /* pkixKeyUsage |= PKIX_DECIPHER_ONLY; */ - - *pPkixKeyUsage = pkixKeyUsage; - - PKIX_RETURN(CERTVFYPKIX); -} - -extern SECOidTag ekuOidStrings[]; - -enum { - ekuIndexSSLServer = 0, - ekuIndexSSLClient, - ekuIndexCodeSigner, - ekuIndexEmail, - ekuIndexTimeStamp, - ekuIndexStatusResponder, - ekuIndexUnknown -} ekuIndex; - -typedef struct { - SECCertUsage certUsage; - PRUint32 ekuStringIndex; -} SECCertUsageToEku; - -const SECCertUsageToEku certUsageEkuStringMap[] = { - {certUsageSSLClient, ekuIndexSSLClient}, - {certUsageSSLServer, ekuIndexSSLServer}, - {certUsageSSLCA, ekuIndexSSLServer}, - {certUsageEmailSigner, ekuIndexEmail}, - {certUsageEmailRecipient, ekuIndexEmail}, - {certUsageObjectSigner, ekuIndexCodeSigner}, - {certUsageUserCertImport, ekuIndexUnknown}, - {certUsageVerifyCA, ekuIndexUnknown}, - {certUsageProtectedObjectSigner, ekuIndexUnknown}, - {certUsageStatusResponder, ekuIndexStatusResponder}, - {certUsageAnyCA, ekuIndexUnknown}, -}; - -/* - * FUNCTION: cert_NssCertificateUsageToPkixKUAndEKU - * DESCRIPTION: - * - * Converts nss CERTCertificateUsage bit field to pkix key and - * extended key usages. - * - * PARAMETERS: - * "cert" - * Pointer to CERTCertificate structure of validating cert. - * "requiredCertUsages" - * Required usage that will be converted to pkix eku and ku. - * "requiredKeyUsage", - * Additional key usages impose to cert. - * "isCA", - * it true, convert usages for cert that is a CA cert. - * "ppkixEKUList" - * Returned address of a list of pkix extended key usages. - * "ppkixKU" - * Returned address of pkix required key usages bit field. - * "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 Cert Verify Error if the function fails in an unrecoverable way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error* -cert_NssCertificateUsageToPkixKUAndEKU( - CERTCertificate *cert, - SECCertUsage requiredCertUsage, - PRUint32 requiredKeyUsages, - PRBool isCA, - PKIX_List **ppkixEKUList, - PKIX_UInt32 *ppkixKU, - void *plContext) -{ - PKIX_List *ekuOidsList = NULL; - PKIX_PL_OID *ekuOid = NULL; - int i = 0; - int ekuIndex = ekuIndexUnknown; - - PKIX_ENTER(CERTVFYPKIX, "cert_NssCertificateUsageToPkixEku"); - PKIX_NULLCHECK_TWO(ppkixEKUList, ppkixKU); - - PKIX_CHECK( - PKIX_List_Create(&ekuOidsList, plContext), - PKIX_LISTCREATEFAILED); - - for (;i < PR_ARRAY_SIZE(certUsageEkuStringMap);i++) { - const SECCertUsageToEku *usageToEkuElem = - &certUsageEkuStringMap[i]; - if (usageToEkuElem->certUsage == requiredCertUsage) { - ekuIndex = usageToEkuElem->ekuStringIndex; - break; - } - } - if (ekuIndex != ekuIndexUnknown) { - PRUint32 reqKeyUsage = 0; - PRUint32 reqCertType = 0; - - CERT_KeyUsageAndTypeForCertUsage(requiredCertUsage, isCA, - &reqKeyUsage, - &reqCertType); - - requiredKeyUsages |= reqKeyUsage; - - PKIX_CHECK( - PKIX_PL_OID_Create(ekuOidStrings[ekuIndex], &ekuOid, - plContext), - PKIX_OIDCREATEFAILED); - - PKIX_CHECK( - PKIX_List_AppendItem(ekuOidsList, (PKIX_PL_Object *)ekuOid, - plContext), - PKIX_LISTAPPENDITEMFAILED); - - PKIX_DECREF(ekuOid); - } - - PKIX_CHECK( - cert_NssKeyUsagesToPkix(requiredKeyUsages, ppkixKU, plContext), - PKIX_NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED); - - *ppkixEKUList = ekuOidsList; - ekuOidsList = NULL; - -cleanup: - - PKIX_DECREF(ekuOid); - PKIX_DECREF(ekuOidsList); - - PKIX_RETURN(CERTVFYPKIX); -} - -#endif - -/* - * FUNCTION: cert_ProcessingParamsSetKeyAndCertUsage - * DESCRIPTION: - * - * Converts cert usage to pkix KU type and sets - * converted data into PKIX_ProcessingParams object. It also sets - * proper cert usage into nsscontext object. - * - * PARAMETERS: - * "procParams" - * Pointer to PKIX_ProcessingParams used during validation. - * "requiredCertUsage" - * Required certificate usages the certificate and chain is built and - * validated for. - * "requiredKeyUsage" - * Request additional key usages the certificate should be validated for. - * "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 Cert Verify Error if the function fails in an unrecoverable way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error* -cert_ProcessingParamsSetKeyAndCertUsage( - PKIX_ProcessingParams *procParams, - SECCertUsage requiredCertUsage, - PRUint32 requiredKeyUsages, - void *plContext) -{ - PKIX_CertSelector *certSelector = NULL; - PKIX_ComCertSelParams *certSelParams = NULL; - PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext*)plContext; - - PKIX_ENTER(CERTVFYPKIX, "cert_ProcessingParamsSetKeyAndCertUsage"); - PKIX_NULLCHECK_TWO(procParams, nssContext); - - PKIX_CHECK( - pkix_pl_NssContext_SetCertUsage( - ((SECCertificateUsage)1) << requiredCertUsage, nssContext), - PKIX_NSSCONTEXTSETCERTUSAGEFAILED); - - if (requiredKeyUsages) { - PKIX_CHECK( - PKIX_ProcessingParams_GetTargetCertConstraints(procParams, - &certSelector, plContext), - PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); - - PKIX_CHECK( - PKIX_CertSelector_GetCommonCertSelectorParams(certSelector, - &certSelParams, plContext), - PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED); - - - PKIX_CHECK( - PKIX_ComCertSelParams_SetKeyUsage(certSelParams, requiredKeyUsages, - plContext), - PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED); - } -cleanup: - PKIX_DECREF(certSelector); - PKIX_DECREF(certSelParams); - - PKIX_RETURN(CERTVFYPKIX); -} - -/* - * Unused parameters: - * - * CERTCertList *initialChain, - * CERTCertStores certStores, - * CERTCertRevCheckers certRevCheckers, - * CERTCertChainCheckers certChainCheckers, - * SECItem *initPolicies, - * PRBool policyQualifierRejected, - * PRBool anyPolicyInhibited, - * PRBool reqExplicitPolicy, - * PRBool policyMappingInhibited, - * PKIX_CertSelector certConstraints, - */ - -/* - * FUNCTION: cert_CreatePkixProcessingParams - * DESCRIPTION: - * - * Creates and fills in PKIX_ProcessingParams structure to be used - * for certificate chain building. - * - * PARAMETERS: - * "cert" - * Pointer to the CERTCertificate: the leaf certificate of a chain. - * "time" - * Validity time. - * "wincx" - * Nss db password token. - * "useArena" - * Flags to use arena for data allocation during chain building process. - * "pprocParams" - * Address to return created processing parameters. - * "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 Cert Verify Error if the function fails in an unrecoverable way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error* -cert_CreatePkixProcessingParams( - CERTCertificate *cert, - PRBool checkSig, /* not used yet. See bug 391476 */ - PRTime time, - void *wincx, - PRBool useArena, - PRBool disableOCSPRemoteFetching, - PKIX_ProcessingParams **pprocParams, - void **pplContext) -{ - PKIX_List *anchors = NULL; - PKIX_PL_Cert *targetCert = NULL; - PKIX_PL_Date *date = NULL; - PKIX_ProcessingParams *procParams = NULL; - PKIX_CertSelector *certSelector = NULL; - PKIX_ComCertSelParams *certSelParams = NULL; - PKIX_CertStore *certStore = NULL; - PKIX_List *certStores = NULL; - PKIX_RevocationChecker *revChecker = NULL; - PKIX_UInt32 methodFlags = 0; - void *plContext = NULL; - CERTStatusConfig *statusConfig = NULL; - - PKIX_ENTER(CERTVFYPKIX, "cert_CreatePkixProcessingParams"); - PKIX_NULLCHECK_TWO(cert, pprocParams); - - PKIX_CHECK( - PKIX_PL_NssContext_Create(0, useArena, wincx, &plContext), - PKIX_NSSCONTEXTCREATEFAILED); - - *pplContext = plContext; - -#ifdef PKIX_NOTDEF - /* Functions should be implemented in patch for 390532 */ - PKIX_CHECK( - pkix_pl_NssContext_SetCertSignatureCheck(checkSig, - (PKIX_PL_NssContext*)plContext), - PKIX_NSSCONTEXTSETCERTSIGNCHECKFAILED); - -#endif /* PKIX_NOTDEF */ - - PKIX_CHECK( - PKIX_ProcessingParams_Create(&procParams, plContext), - PKIX_PROCESSINGPARAMSCREATEFAILED); - - PKIX_CHECK( - PKIX_ComCertSelParams_Create(&certSelParams, plContext), - PKIX_COMCERTSELPARAMSCREATEFAILED); - - PKIX_CHECK( - PKIX_PL_Cert_CreateFromCERTCertificate(cert, &targetCert, plContext), - PKIX_CERTCREATEWITHNSSCERTFAILED); - - PKIX_CHECK( - PKIX_ComCertSelParams_SetCertificate(certSelParams, - targetCert, plContext), - PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED); - - PKIX_CHECK( - PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext), - PKIX_COULDNOTCREATECERTSELECTOROBJECT); - - PKIX_CHECK( - PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, - certSelParams, plContext), - PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED); - - PKIX_CHECK( - PKIX_ProcessingParams_SetTargetCertConstraints(procParams, - certSelector, plContext), - PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED); - - /* Turn off quialification of target cert since leaf cert is - * already check for date validity, key usages and extended - * key usages. */ - PKIX_CHECK( - PKIX_ProcessingParams_SetQualifyTargetCert(procParams, PKIX_FALSE, - plContext), - PKIX_PROCESSINGPARAMSSETQUALIFYTARGETCERTFLAGFAILED); - - PKIX_CHECK( - PKIX_PL_Pk11CertStore_Create(&certStore, plContext), - PKIX_PK11CERTSTORECREATEFAILED); - - PKIX_CHECK( - PKIX_List_Create(&certStores, plContext), - PKIX_UNABLETOCREATELIST); - - PKIX_CHECK( - PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, - plContext), - PKIX_LISTAPPENDITEMFAILED); - - PKIX_CHECK( - PKIX_ProcessingParams_SetCertStores(procParams, certStores, - plContext), - PKIX_PROCESSINGPARAMSADDCERTSTOREFAILED); - - PKIX_CHECK( - PKIX_PL_Date_CreateFromPRTime(time, &date, plContext), - PKIX_DATECREATEFROMPRTIMEFAILED); - - PKIX_CHECK( - PKIX_ProcessingParams_SetDate(procParams, date, plContext), - PKIX_PROCESSINGPARAMSSETDATEFAILED); - - PKIX_CHECK( - PKIX_RevocationChecker_Create( - PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST | - PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT, - PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST | - PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT, - &revChecker, plContext), - PKIX_REVOCATIONCHECKERCREATEFAILED); - - PKIX_CHECK( - PKIX_ProcessingParams_SetRevocationChecker(procParams, revChecker, - plContext), - PKIX_PROCESSINGPARAMSSETREVOCATIONCHECKERFAILED); - - /* CRL method flags */ - methodFlags = - PKIX_REV_M_TEST_USING_THIS_METHOD | - PKIX_REV_M_FORBID_NETWORK_FETCHING | - PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */ - PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */ - PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO; - - /* add CRL revocation method to check the leaf certificate */ - PKIX_CHECK( - PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams, - PKIX_RevocationMethod_CRL, methodFlags, - 0, NULL, PKIX_TRUE, plContext), - PKIX_REVOCATIONCHECKERADDMETHODFAILED); - - /* add CRL revocation method for other certs in the chain. */ - PKIX_CHECK( - PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams, - PKIX_RevocationMethod_CRL, methodFlags, - 0, NULL, PKIX_FALSE, plContext), - PKIX_REVOCATIONCHECKERADDMETHODFAILED); - - /* For compatibility with the old code, need to check that - * statusConfig is set in the db handle and status checker - * is defined befor allow ocsp status check on the leaf cert.*/ - statusConfig = CERT_GetStatusConfig(CERT_GetDefaultCertDB()); - if (statusConfig != NULL && statusConfig->statusChecker != NULL) { - - /* Enable OCSP revocation checking for the leaf cert. */ - /* OCSP method flags */ - methodFlags = - PKIX_REV_M_TEST_USING_THIS_METHOD | - PKIX_REV_M_ALLOW_NETWORK_FETCHING | /* 0 */ - PKIX_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE | /* 0 */ - PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */ - PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */ - PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO; - - /* Disabling ocsp fetching when checking the status - * of ocsp response signer. Here and in the next if, - * adjust flags for ocsp signer cert validation case. */ - if (disableOCSPRemoteFetching) { - methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING; - } - - if (ocsp_FetchingFailureIsVerificationFailure() - && !disableOCSPRemoteFetching) { - methodFlags |= - PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO; - } - - /* add OCSP revocation method to check only the leaf certificate.*/ - PKIX_CHECK( - PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams, - PKIX_RevocationMethod_OCSP, methodFlags, - 1, NULL, PKIX_TRUE, plContext), - PKIX_REVOCATIONCHECKERADDMETHODFAILED); - } - - PKIX_CHECK( - PKIX_ProcessingParams_SetAnyPolicyInhibited(procParams, PR_FALSE, - plContext), - PKIX_PROCESSINGPARAMSSETANYPOLICYINHIBITED); - - PKIX_CHECK( - PKIX_ProcessingParams_SetExplicitPolicyRequired(procParams, PR_FALSE, - plContext), - PKIX_PROCESSINGPARAMSSETEXPLICITPOLICYREQUIRED); - - PKIX_CHECK( - PKIX_ProcessingParams_SetPolicyMappingInhibited(procParams, PR_FALSE, - plContext), - PKIX_PROCESSINGPARAMSSETPOLICYMAPPINGINHIBITED); - - *pprocParams = procParams; - procParams = NULL; - -cleanup: - PKIX_DECREF(anchors); - PKIX_DECREF(targetCert); - PKIX_DECREF(date); - PKIX_DECREF(certSelector); - PKIX_DECREF(certSelParams); - PKIX_DECREF(certStore); - PKIX_DECREF(certStores); - PKIX_DECREF(procParams); - PKIX_DECREF(revChecker); - - PKIX_RETURN(CERTVFYPKIX); -} - -/* - * FUNCTION: cert_PkixToNssCertsChain - * DESCRIPTION: - * - * Converts pkix cert list into nss cert list. - * - * PARAMETERS: - * "pkixCertChain" - * Pkix certificate list. - * "pvalidChain" - * An address of returned nss certificate list. - * "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 Cert Verify Error if the function fails in an unrecoverable way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error* -cert_PkixToNssCertsChain( - PKIX_List *pkixCertChain, - CERTCertList **pvalidChain, - void *plContext) -{ - PRArenaPool *arena = NULL; - CERTCertificate *nssCert = NULL; - CERTCertList *validChain = NULL; - PKIX_PL_Object *certItem = NULL; - PKIX_UInt32 length = 0; - PKIX_UInt32 i = 0; - - PKIX_ENTER(CERTVFYPKIX, "cert_PkixToNssCertsChain"); - PKIX_NULLCHECK_ONE(pvalidChain); - - if (pkixCertChain == NULL) { - goto cleanup; - } - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PKIX_ERROR(PKIX_OUTOFMEMORY); - } - validChain = (CERTCertList*)PORT_ArenaZAlloc(arena, sizeof(CERTCertList)); - if (validChain == NULL) { - PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); - } - PR_INIT_CLIST(&validChain->list); - validChain->arena = arena; - arena = NULL; - - PKIX_CHECK( - PKIX_List_GetLength(pkixCertChain, &length, plContext), - PKIX_LISTGETLENGTHFAILED); - - for (i = 0; i < length; i++){ - CERTCertListNode *node = NULL; - - PKIX_CHECK( - PKIX_List_GetItem(pkixCertChain, i, &certItem, plContext), - PKIX_LISTGETITEMFAILED); - - PKIX_CHECK( - PKIX_PL_Cert_GetCERTCertificate((PKIX_PL_Cert*)certItem, &nssCert, - plContext), - PKIX_CERTGETCERTCERTIFICATEFAILED); - - node = - (CERTCertListNode *)PORT_ArenaZAlloc(validChain->arena, - sizeof(CERTCertListNode)); - if ( node == NULL ) { - PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); - } - - PR_INSERT_BEFORE(&node->links, &validChain->list); - - node->cert = nssCert; - nssCert = NULL; - - PKIX_DECREF(certItem); - } - - *pvalidChain = validChain; - -cleanup: - if (PKIX_ERROR_RECEIVED){ - if (validChain) { - CERT_DestroyCertList(validChain); - } else if (arena) { - PORT_FreeArena(arena, PR_FALSE); - } - if (nssCert) { - CERT_DestroyCertificate(nssCert); - } - } - PKIX_DECREF(certItem); - - PKIX_RETURN(CERTVFYPKIX); -} - - -/* - * FUNCTION: cert_BuildAndValidateChain - * DESCRIPTION: - * - * The function builds and validates a cert chain based on certificate - * selection criterias from procParams. This function call PKIX_BuildChain - * to accomplish chain building. If PKIX_BuildChain returns with incomplete - * IO, the function waits with PR_Poll until the blocking IO is finished and - * return control back to PKIX_BuildChain. - * - * PARAMETERS: - * "procParams" - * Processing parameters to be used during chain building. - * "pResult" - * Returned build result. - * "pVerifyNode" - * Returned pointed to verify node structure: the tree-like structure - * that reports points of chain building failures. - * "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 Cert Verify Error if the function fails in an unrecoverable way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error* -cert_BuildAndValidateChain( - PKIX_ProcessingParams *procParams, - PKIX_BuildResult **pResult, - PKIX_VerifyNode **pVerifyNode, - void *plContext) -{ - PKIX_BuildResult *result = NULL; - PKIX_VerifyNode *verifyNode = NULL; - void *nbioContext = NULL; - void *state = NULL; - - PKIX_ENTER(CERTVFYPKIX, "cert_BuildAndVerifyChain"); - PKIX_NULLCHECK_TWO(procParams, pResult); - - do { - if (nbioContext && state) { - /* PKIX-XXX: need to test functionality of NBIO handling in libPkix. - * See bug 391180 */ - PRInt32 filesReady = 0; - PRPollDesc *pollDesc = (PRPollDesc*)nbioContext; - filesReady = PR_Poll(pollDesc, 1, PR_INTERVAL_NO_TIMEOUT); - if (filesReady <= 0) { - PKIX_ERROR(PKIX_PRPOLLRETBADFILENUM); - } - } - - PKIX_CHECK( - PKIX_BuildChain(procParams, &nbioContext, &state, - &result, &verifyNode, plContext), - PKIX_UNABLETOBUILDCHAIN); - - } while (nbioContext && state); - - *pResult = result; - -cleanup: - if (pVerifyNode) { - *pVerifyNode = verifyNode; - } - - PKIX_RETURN(CERTVFYPKIX); -} - - -/* - * FUNCTION: cert_PkixErrorToNssCode - * DESCRIPTION: - * - * Converts pkix error(PKIX_Error) structure to PR error codes. - * - * PKIX-XXX to be implemented. See 391183. - * - * PARAMETERS: - * "error" - * Pkix error that will be converted. - * "nssCode" - * Corresponding nss error code. - * "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 Cert Verify Error if the function fails in an unrecoverable way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error * -cert_PkixErrorToNssCode( - PKIX_Error *error, - SECErrorCodes *pNssErr, - void *plContext) -{ - int errLevel = 0; - PKIX_Int32 nssErr = 0; - PKIX_Error *errPtr = error; - - PKIX_ENTER(CERTVFYPKIX, "cert_PkixErrorToNssCode"); - PKIX_NULLCHECK_TWO(error, pNssErr); - - /* Loop until we find at least one error with non-null - * plErr code, that is going to be nss error code. */ - while (errPtr) { - if (errPtr->plErr && !nssErr) { - nssErr = errPtr->plErr; - if (!pkixLog) break; - } - if (pkixLog) { -#ifdef PKIX_ERROR_DESCRIPTION - PR_LOG(pkixLog, 2, ("Error at level %d: %s\n", errLevel, - PKIX_ErrorText[errPtr->errCode])); -#else - PR_LOG(pkixLog, 2, ("Error at level %d: Error code %d\n", errLevel, - errPtr->errCode)); -#endif /* PKIX_ERROR_DESCRIPTION */ - } - errPtr = errPtr->cause; - errLevel += 1; - } - PORT_Assert(nssErr); - if (!nssErr) { - *pNssErr = SEC_ERROR_LIBPKIX_INTERNAL; - } else { - *pNssErr = nssErr; - } - - PKIX_RETURN(CERTVFYPKIX); -} - -/* - * FUNCTION: cert_GetLogFromVerifyNode - * DESCRIPTION: - * - * Recursive function that converts verify node tree-like set of structures - * to CERTVerifyLog. - * - * PARAMETERS: - * "log" - * Pointed to already allocated CERTVerifyLog structure. - * "node" - * A node of PKIX_VerifyNode tree. - * "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 Cert Verify Error if the function fails in an unrecoverable way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error * -cert_GetLogFromVerifyNode( - CERTVerifyLog *log, - PKIX_VerifyNode *node, - void *plContext) -{ - PKIX_List *children = NULL; - PKIX_VerifyNode *childNode = NULL; - - PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode"); - - children = node->children; - - if (children == NULL) { - PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT; - if (node->error && node->error->errCode != errCode) { -#ifdef DEBUG_volkov - char *string = pkix_Error2ASCII(node->error, plContext); - fprintf(stderr, "Branch search finished with error: \t%s\n", string); - PKIX_PL_Free(string, NULL); -#endif - if (log != NULL) { - SECErrorCodes nssErrorCode = 0; - CERTCertificate *cert = NULL; - - cert = node->verifyCert->nssCert; - - PKIX_CHECK( - cert_PkixErrorToNssCode(node->error, &nssErrorCode, - plContext), - PKIX_GETPKIXERRORCODEFAILED); - - cert_AddToVerifyLog(log, cert, nssErrorCode, node->depth, NULL); - } - } - PKIX_RETURN(CERTVFYPKIX); - } else { - PRUint32 i = 0; - PKIX_UInt32 length = 0; - - PKIX_CHECK( - PKIX_List_GetLength(children, &length, plContext), - PKIX_LISTGETLENGTHFAILED); - - for (i = 0; i < length; i++){ - - PKIX_CHECK( - PKIX_List_GetItem(children, i, (PKIX_PL_Object**)&childNode, - plContext), - PKIX_LISTGETITEMFAILED); - - PKIX_CHECK( - cert_GetLogFromVerifyNode(log, childNode, plContext), - PKIX_ERRORINRECURSIVEEQUALSCALL); - - PKIX_DECREF(childNode); - } - } - -cleanup: - PKIX_DECREF(childNode); - - PKIX_RETURN(CERTVFYPKIX); -} - -/* - * FUNCTION: cert_GetBuildResults - * DESCRIPTION: - * - * Converts pkix build results to nss results. This function is called - * regardless of build result. - * - * If it called after chain was successfully constructed, then it will - * convert: - * * pkix cert list that represent the chain to nss cert list - * * trusted root the chain was anchored to nss certificate. - * - * In case of failure it will convert: - * * pkix error to PR error code(will set it with PORT_SetError) - * * pkix validation log to nss CERTVerifyLog - * - * PARAMETERS: - * "buildResult" - * Build results returned by PKIX_BuildChain. - * "verifyNode" - * Tree-like structure of chain building/validation failures - * returned by PKIX_BuildChain. Ignored in case of success. - * "error" - * Final error returned by PKIX_BuildChain. Should be NULL in - * case of success. - * "log" - * Address of pre-allocated(if not NULL) CERTVerifyLog structure. - * "ptrustedRoot" - * Address of returned trusted root the chain was anchored to. - * "pvalidChain" - * Address of returned valid chain. - * "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 Cert Verify Error if the function fails in an unrecoverable way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error* -cert_GetBuildResults( - PKIX_BuildResult *buildResult, - PKIX_VerifyNode *verifyNode, - PKIX_Error *error, - CERTVerifyLog *log, - CERTCertificate **ptrustedRoot, - CERTCertList **pvalidChain, - void *plContext) -{ - PKIX_ValidateResult *validResult = NULL; - CERTCertList *validChain = NULL; - CERTCertificate *trustedRoot = NULL; - PKIX_TrustAnchor *trustAnchor = NULL; - PKIX_PL_Cert *trustedCert = NULL; - PKIX_List *pkixCertChain = NULL; -#ifdef DEBUG_volkov - PKIX_Error *tmpPkixError = NULL; -#endif /* DEBUG */ - - PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults"); - if (buildResult == NULL && error == NULL) { - PKIX_ERROR(PKIX_NULLARGUMENT); - } - - if (error) { - SECErrorCodes nssErrorCode = 0; -#ifdef DEBUG_volkov - char *temp = pkix_Error2ASCII(error, plContext); - fprintf(stderr, "BUILD ERROR:\n%s\n", temp); - PKIX_PL_Free(temp, NULL); -#endif /* DEBUG */ - if (verifyNode) { - PKIX_Error *tmpError = - cert_GetLogFromVerifyNode(log, verifyNode, plContext); - if (tmpError) { - PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext); - } - } - cert_PkixErrorToNssCode(error, &nssErrorCode, plContext); - PORT_SetError(nssErrorCode); - goto cleanup; - } - - if (pvalidChain) { - PKIX_CHECK( - PKIX_BuildResult_GetCertChain(buildResult, &pkixCertChain, - plContext), - PKIX_BUILDRESULTGETCERTCHAINFAILED); - -#ifdef DEBUG_volkov - tmpPkixError = cert_PrintCertChain(pkixCertChain, plContext); - if (tmpPkixError) { - PKIX_PL_Object_DecRef((PKIX_PL_Object*)tmpPkixError, plContext); - } -#endif - - PKIX_CHECK( - cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext), - PKIX_CERTCHAINTONSSCHAINFAILED); - } - - if (ptrustedRoot) { - PKIX_CHECK( - PKIX_BuildResult_GetValidateResult(buildResult, &validResult, - plContext), - PKIX_BUILDRESULTGETVALIDATERESULTFAILED); - - PKIX_CHECK( - PKIX_ValidateResult_GetTrustAnchor(validResult, &trustAnchor, - plContext), - PKIX_VALIDATERESULTGETTRUSTANCHORFAILED); - - PKIX_CHECK( - PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustedCert, - plContext), - PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); - -#ifdef DEBUG_volkov - if (pvalidChain == NULL) { - cert_PrintCert(trustedCert, plContext); - } -#endif - - PKIX_CHECK( - PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot, - plContext), - PKIX_CERTGETCERTCERTIFICATEFAILED); - } - - PORT_Assert(!PKIX_ERROR_RECEIVED); - - if (trustedRoot) { - *ptrustedRoot = trustedRoot; - } - if (validChain) { - *pvalidChain = validChain; - } - -cleanup: - if (PKIX_ERROR_RECEIVED) { - if (trustedRoot) { - CERT_DestroyCertificate(trustedRoot); - } - if (validChain) { - CERT_DestroyCertList(validChain); - } - } - PKIX_DECREF(trustAnchor); - PKIX_DECREF(trustedCert); - PKIX_DECREF(pkixCertChain); - PKIX_DECREF(validResult); - PKIX_DECREF(error); - PKIX_DECREF(verifyNode); - PKIX_DECREF(buildResult); - - PKIX_RETURN(CERTVFYPKIX); -} - -/* - * FUNCTION: cert_VerifyCertChainPkix - * DESCRIPTION: - * - * The main wrapper function that is called from CERT_VerifyCert and - * CERT_VerifyCACertForUsage functions to validate cert with libpkix. - * - * PARAMETERS: - * "cert" - * Leaf certificate of a chain we want to build. - * "checkSig" - * Certificate signatures will not be verified if this - * flag is set to PR_FALSE. - * "requiredUsage" - * Required usage for certificate and chain. - * "time" - * Validity time. - * "wincx" - * Nss database password token. - * "log" - * Address of already allocated CERTVerifyLog structure. Not - * used if NULL; - * "pSigerror" - * Address of PRBool. If not NULL, returns true is cert chain - * was invalidated because of bad certificate signature. - * "pRevoked" - * Address of PRBool. If not NULL, returns true is cert chain - * was invalidated because a revoked certificate was found in - * the chain. - * THREAD SAFETY: - * Thread Safe (see Thread Safety Definitions in Programmer's Guide) - * RETURNS: - * SECFailure is chain building process has failed. SECSuccess otherwise. - */ -SECStatus -cert_VerifyCertChainPkix( - CERTCertificate *cert, - PRBool checkSig, - SECCertUsage requiredUsage, - PRTime time, - void *wincx, - CERTVerifyLog *log, - PRBool *pSigerror, - PRBool *pRevoked) -{ - PKIX_ProcessingParams *procParams = NULL; - PKIX_BuildResult *result = NULL; - PKIX_VerifyNode *verifyNode = NULL; - PKIX_Error *error = NULL; - - SECStatus rv = SECFailure; - void *plContext = NULL; -#ifdef DEBUG_volkov - CERTCertificate *trustedRoot = NULL; - CERTCertList *validChain = NULL; -#endif /* DEBUG */ - -#ifdef PKIX_OBJECT_LEAK_TEST - int leakedObjNum = 0; - int memLeakLoopCount = 0; - int objCountTable[PKIX_NUMTYPES]; - int fnInvLocalCount = 0; - PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine; - - if (usePKIXValidationEngine) { - /* current memory leak testing implementation does not allow - * to run simultaneous tests one the same or a different threads. - * Setting the variable to false, to make additional chain - * validations be handled by old nss. */ - usePKIXValidationEngine = PR_FALSE; - } - testStartFnStackPosition = 2; - fnStackNameArr[0] = "cert_VerifyCertChainPkix"; - fnStackInvCountArr[0] = 0; - PKIX_Boolean abortOnLeak = - (PR_GetEnv("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? - PKIX_FALSE : PKIX_TRUE; - runningLeakTest = PKIX_TRUE; - - /* Prevent multi-threaded run of object leak test */ - fnInvLocalCount = PR_ATOMIC_INCREMENT(¶llelFnInvocationCount); - PORT_Assert(fnInvLocalCount == 1); - -do { - rv = SECFailure; - plContext = NULL; - procParams = NULL; - result = NULL; - verifyNode = NULL; - error = NULL; -#ifdef DEBUG_volkov - trustedRoot = NULL; - validChain = NULL; -#endif /* DEBUG */ - errorGenerated = PKIX_FALSE; - stackPosition = 0; - - if (leakedObjNum) { - pkix_pl_lifecycle_ObjectTableUpdate(objCountTable); - } - memLeakLoopCount += 1; -#endif /* PKIX_OBJECT_LEAK_TEST */ - - error = - cert_CreatePkixProcessingParams(cert, checkSig, time, wincx, - PR_FALSE/*use arena*/, - requiredUsage == certUsageStatusResponder, - &procParams, &plContext); - if (error) { - goto cleanup; - } - - error = - cert_ProcessingParamsSetKeyAndCertUsage(procParams, requiredUsage, 0, - plContext); - if (error) { - goto cleanup; - } - - error = - cert_BuildAndValidateChain(procParams, &result, &verifyNode, plContext); - if (error) { - goto cleanup; - } - - if (pRevoked) { - /* Currently always PR_FALSE. Will be fixed as a part of 394077 */ - *pRevoked = PR_FALSE; - } - if (pSigerror) { - /* Currently always PR_FALSE. Will be fixed as a part of 394077 */ - *pSigerror = PR_FALSE; - } - rv = SECSuccess; - -cleanup: - error = cert_GetBuildResults(result, verifyNode, error, log, -#ifdef DEBUG_volkov - &trustedRoot, &validChain, -#else - NULL, NULL, -#endif /* DEBUG */ - plContext); - if (error) { -#ifdef DEBUG_volkov - char *temp = pkix_Error2ASCII(error, plContext); - fprintf(stderr, "GET BUILD RES ERRORS:\n%s\n", temp); - PKIX_PL_Free(temp, NULL); -#endif /* DEBUG */ - PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); - } -#ifdef DEBUG_volkov - if (trustedRoot) { - CERT_DestroyCertificate(trustedRoot); - } - if (validChain) { - CERT_DestroyCertList(validChain); - } -#endif /* DEBUG */ - if (procParams) { - PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext); - } - if (plContext) { - PKIX_PL_NssContext_Destroy(plContext); - } - -#ifdef PKIX_OBJECT_LEAK_TEST - leakedObjNum = - pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL); - - if (pkixLog && leakedObjNum) { - PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d." - "Stack %s\n", memLeakLoopCount, errorFnStackString)); - } - PR_Free(errorFnStackString); - errorFnStackString = NULL; - if (abortOnLeak) { - PORT_Assert(leakedObjNum == 0); - } - -} while (errorGenerated); - - runningLeakTest = PKIX_FALSE; - PR_ATOMIC_DECREMENT(¶llelFnInvocationCount); - usePKIXValidationEngine = savedUsePkixEngFlag; -#endif /* PKIX_OBJECT_LEAK_TEST */ - - return rv; -} - -PKIX_CertSelector * -cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext) -{ - PKIX_ComCertSelParams *certSelParams = NULL; - PKIX_CertSelector *certSelector = NULL; - PKIX_CertSelector *r= NULL; - PKIX_PL_Cert *eeCert = NULL; - PKIX_Error *error = NULL; - - error = PKIX_PL_Cert_CreateFromCERTCertificate(target, &eeCert, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_ComCertSelParams_Create(&certSelParams, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_ComCertSelParams_SetCertificate( - certSelParams, eeCert, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_CertSelector_SetCommonCertSelectorParams - (certSelector, certSelParams, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certSelector, plContext); - if (error == NULL) r = certSelector; - -cleanup: - if (certSelParams != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelParams, plContext); - - if (eeCert != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)eeCert, plContext); - - if (certSelector != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext); - - if (error != NULL) { - SECErrorCodes nssErr; - - cert_PkixErrorToNssCode(error, &nssErr, plContext); - PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); - PORT_SetError(nssErr); - } - - return r; -} - -static PKIX_List * -cert_GetCertStores(void *plContext) -{ - PKIX_CertStore *certStore = NULL; - PKIX_List *certStores = NULL; - PKIX_List *r = NULL; - PKIX_Error *error = NULL; - - error = PKIX_PL_Pk11CertStore_Create(&certStore, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_List_Create(&certStores, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_List_AppendItem( certStores, - (PKIX_PL_Object *)certStore, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certStores, plContext); - if (error == NULL) r = certStores; - -cleanup: - if (certStores != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext); - - if (certStore != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStore, plContext); - - if (error != NULL) { - SECErrorCodes nssErr; - - cert_PkixErrorToNssCode(error, &nssErr, plContext); - PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); - PORT_SetError(nssErr); - } - - return r; -} - - -struct fake_PKIX_PL_CertStruct { - CERTCertificate *nssCert; -}; - -/* This needs to be part of the PKIX_PL_* */ -/* This definitely needs to go away, and be replaced with - a real accessor function in PKIX */ -static CERTCertificate * -cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert) -{ - struct fake_PKIX_PL_CertStruct *fcert = NULL; - - fcert = (struct fake_PKIX_PL_CertStruct*)pkix_cert; - - return CERT_DupCertificate(fcert->nssCert); -} - -PKIX_List *cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plContext) -{ - PKIX_List *r = NULL; - PKIX_List *policyList = NULL; - PKIX_PL_OID *policyOID = NULL; - PKIX_Error *error = NULL; - int i; - - error = PKIX_List_Create(&policyList, plContext); - if (error != NULL) { - goto cleanup; - } - - for (i=0; i<oidCount; i++) { - error = PKIX_PL_OID_Create(oids[i], &policyOID, plContext); - if (error) { - goto cleanup; - } - error = PKIX_List_AppendItem(policyList, - (PKIX_PL_Object *)policyOID, plContext); - if (error != NULL) { - goto cleanup; - } - PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext); - policyOID = NULL; - } - - error = PKIX_List_SetImmutable(policyList, plContext); - if (error != NULL) goto cleanup; - - error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)policyList, plContext); - if (error == NULL) r = policyList; - -cleanup: - if (policyOID != NULL) { - PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext); - } - if (policyList != NULL) { - PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyList, plContext); - } - if (error != NULL) { - PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); - } - - return r; -} - -CERTValOutParam * -cert_pkix_FindOutputParam(CERTValOutParam *params, const CERTValParamOutType t) -{ - CERTValOutParam *i; - if (params == NULL) { - return NULL; - } - for (i = params; i->type != cert_po_end; i++) { - if (i->type == t) { - return i; - } - } - return NULL; -} - - -static PKIX_Error* -setRevocationMethod(PKIX_RevocationChecker *revChecker, - PKIX_ProcessingParams *procParams, - const CERTRevocationTests *revTest, - CERTRevocationMethodIndex certRevMethod, - PKIX_RevocationMethodType pkixRevMethod, - PKIX_Boolean verifyResponderUsages, - PKIX_Boolean isLeafTest, - void *plContext) -{ - PKIX_UInt32 methodFlags = 0; - PKIX_Error *error = NULL; - int priority = 0; - - if (revTest->number_of_defined_methods <= certRevMethod) { - return NULL; - } - if (revTest->preferred_methods) { - int i = 0; - for (;i < revTest->number_of_preferred_methods;i++) { - if (revTest->preferred_methods[i] == certRevMethod) - break; - } - priority = i; - } - methodFlags = revTest->cert_rev_flags_per_method[certRevMethod]; - if (verifyResponderUsages && - pkixRevMethod == PKIX_RevocationMethod_OCSP) { - methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING; - } - error = - PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams, - pkixRevMethod, methodFlags, - priority, NULL, - isLeafTest, plContext); - return error; -} - - -SECStatus -cert_pkixSetParam(PKIX_ProcessingParams *procParams, - const CERTValInParam *param, void *plContext) -{ - PKIX_Error * error = NULL; - SECStatus r=SECSuccess; - PKIX_PL_Date *date = NULL; - PKIX_List *policyOIDList = NULL; - PKIX_List *certListPkix = NULL; - const CERTRevocationFlags *flags; - SECErrorCodes errCode = SEC_ERROR_INVALID_ARGS; - const CERTCertList *certList = NULL; - CERTCertListNode *node; - PKIX_PL_Cert *certPkix = NULL; - PKIX_TrustAnchor *trustAnchor = NULL; - PKIX_PL_Date *revDate = NULL; - PKIX_RevocationChecker *revChecker = NULL; - PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext; - - /* XXX we need a way to map generic PKIX error to generic NSS errors */ - - switch (param->type) { - - case cert_pi_policyOID: - - /* needed? */ - error = PKIX_ProcessingParams_SetExplicitPolicyRequired( - procParams, PKIX_TRUE, plContext); - - if (error != NULL) { - break; - } - - policyOIDList = cert_PKIXMakeOIDList(param->value.array.oids, - param->value.arraySize,plContext); - if (policyOIDList == NULL) { - r = SECFailure; - PORT_SetError(SEC_ERROR_INVALID_ARGS); - break; - } - - error = PKIX_ProcessingParams_SetInitialPolicies( - procParams,policyOIDList,plContext); - break; - - case cert_pi_date: - if (param->value.scalar.time == 0) { - error = PKIX_PL_Date_Create_UTCTime(NULL, &date, plContext); - if (error != NULL) { - errCode = SEC_ERROR_INVALID_TIME; - break; - } - } else { - error = pkix_pl_Date_CreateFromPRTime(param->value.scalar.time, - &date, plContext); - if (error != NULL) { - errCode = SEC_ERROR_INVALID_TIME; - break; - } - } - - error = PKIX_ProcessingParams_SetDate(procParams, date, plContext); - if (error != NULL) { - errCode = SEC_ERROR_INVALID_TIME; - } - break; - - case cert_pi_revocationFlags: - { - PKIX_UInt32 leafIMFlags = 0; - PKIX_UInt32 chainIMFlags = 0; - PKIX_Boolean validatingResponderCert = PKIX_FALSE; - - flags = param->value.pointer.revocation; - if (!flags) { - PORT_SetError(errCode); - r = SECFailure; - break; - } - - leafIMFlags = - flags->leafTests.cert_rev_method_independent_flags; - chainIMFlags = - flags->chainTests.cert_rev_method_independent_flags; - - error = - PKIX_RevocationChecker_Create(leafIMFlags, chainIMFlags, - &revChecker, plContext); - if (error) { - break; - } - - error = - PKIX_ProcessingParams_SetRevocationChecker(procParams, - revChecker, plContext); - if (error) { - break; - } - - if (((PKIX_PL_NssContext*)plContext)->certificateUsage & - certificateUsageStatusResponder) { - validatingResponderCert = PKIX_TRUE; - } - - error = setRevocationMethod(revChecker, - procParams, &flags->leafTests, - cert_revocation_method_crl, - PKIX_RevocationMethod_CRL, - validatingResponderCert, - PKIX_TRUE, plContext); - if (error) { - break; - } - - error = setRevocationMethod(revChecker, - procParams, &flags->leafTests, - cert_revocation_method_ocsp, - PKIX_RevocationMethod_OCSP, - validatingResponderCert, - PKIX_TRUE, plContext); - if (error) { - break; - } - - error = setRevocationMethod(revChecker, - procParams, &flags->chainTests, - cert_revocation_method_crl, - PKIX_RevocationMethod_CRL, - validatingResponderCert, - PKIX_FALSE, plContext); - if (error) { - break; - } - - error = setRevocationMethod(revChecker, - procParams, &flags->chainTests, - cert_revocation_method_ocsp, - PKIX_RevocationMethod_OCSP, - validatingResponderCert, - PKIX_FALSE, plContext); - if (error) { - break; - } - - } - break; - - case cert_pi_trustAnchors: - certList = param->value.pointer.chain; - if (!certList) { - PORT_SetError(errCode); - r = SECFailure; - break; - } - error = PKIX_List_Create(&certListPkix, plContext); - if (error != NULL) { - break; - } - for(node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); - node = CERT_LIST_NEXT(node) ) { - error = PKIX_PL_Cert_CreateFromCERTCertificate(node->cert, - &certPkix, plContext); - if (error) { - break; - } - error = PKIX_TrustAnchor_CreateWithCert(certPkix, &trustAnchor, - plContext); - if (error) { - break; - } - error = PKIX_List_AppendItem(certListPkix, - (PKIX_PL_Object*)trustAnchor, plContext); - if (error) { - break; - } - PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext); - trustAnchor = NULL; - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext); - certPkix = NULL; - } - error = - PKIX_ProcessingParams_SetTrustAnchors(procParams, certListPkix, - plContext); - break; - - case cert_pi_useAIACertFetch: - error = - PKIX_ProcessingParams_SetUseAIAForCertFetching(procParams, - (PRBool)(param->value.scalar.b != 0), - plContext); - break; - - case cert_pi_chainVerifyCallback: - { - const CERTChainVerifyCallback *chainVerifyCallback = - param->value.pointer.chainVerifyCallback; - if (!chainVerifyCallback || !chainVerifyCallback->isChainValid) { - PORT_SetError(errCode); - r = SECFailure; - break; - } - - nssContext->chainVerifyCallback = *chainVerifyCallback; - } - break; - - default: - PORT_SetError(errCode); - r = SECFailure; - break; - } - - if (policyOIDList != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOIDList, plContext); - - if (date != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)date, plContext); - - if (revDate != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)revDate, plContext); - - if (revChecker != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)revChecker, plContext); - - if (certListPkix) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certListPkix, plContext); - - if (trustAnchor) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext); - - if (certPkix) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext); - - if (error != NULL) { - PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); - PORT_SetError(errCode); - r = SECFailure; - } - - return r; - -} - -void -cert_pkixDestroyValOutParam(CERTValOutParam *params) -{ - CERTValOutParam *i; - - if (params == NULL) { - return; - } - for (i = params; i->type != cert_po_end; i++) { - switch (i->type) { - case cert_po_trustAnchor: - if (i->value.pointer.cert) { - CERT_DestroyCertificate(i->value.pointer.cert); - i->value.pointer.cert = NULL; - } - break; - - case cert_po_certList: - if (i->value.pointer.chain) { - CERT_DestroyCertList(i->value.pointer.chain); - i->value.pointer.chain = NULL; - } - break; - - default: - break; - } - } -} - -static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags[2] = { - /* crl */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FORBID_NETWORK_FETCHING - | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, - /* ocsp */ - CERT_REV_M_TEST_USING_THIS_METHOD -}; - -static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags[2] = { - /* crl */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FORBID_NETWORK_FETCHING - | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, - /* ocsp */ - 0 -}; - -static CERTRevocationMethodIndex -certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference = { - cert_revocation_method_crl -}; - -static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy = { - { - /* leafTests */ - 2, - certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags, - 1, - &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference, - 0 - }, - { - /* chainTests */ - 2, - certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags, - 0, - 0, - 0 - } -}; - -extern const CERTRevocationFlags* -CERT_GetClassicOCSPEnabledSoftFailurePolicy() -{ - return &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy; -} - - -static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags[2] = { - /* crl */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FORBID_NETWORK_FETCHING - | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, - /* ocsp */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO -}; - -static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags[2] = { - /* crl */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FORBID_NETWORK_FETCHING - | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, - /* ocsp */ - 0 -}; - -static CERTRevocationMethodIndex -certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference = { - cert_revocation_method_crl -}; - -static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy = { - { - /* leafTests */ - 2, - certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags, - 1, - &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference, - 0 - }, - { - /* chainTests */ - 2, - certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags, - 0, - 0, - 0 - } -}; - -extern const CERTRevocationFlags* -CERT_GetClassicOCSPEnabledHardFailurePolicy() -{ - return &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy; -} - - -static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags[2] = { - /* crl */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FORBID_NETWORK_FETCHING - | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, - /* ocsp */ - 0 -}; - -static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags[2] = { - /* crl */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FORBID_NETWORK_FETCHING - | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, - /* ocsp */ - 0 -}; - -static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Disabled_Policy = { - { - /* leafTests */ - 2, - certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags, - 0, - 0, - 0 - }, - { - /* chainTests */ - 2, - certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags, - 0, - 0, - 0 - } -}; - -extern const CERTRevocationFlags* -CERT_GetClassicOCSPDisabledPolicy() -{ - return &certRev_NSS_3_11_Ocsp_Disabled_Policy; -} - - -static PRUint64 certRev_PKIX_Verify_Nist_Policy_LeafFlags[2] = { - /* crl */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO - | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE, - /* ocsp */ - 0 -}; - -static PRUint64 certRev_PKIX_Verify_Nist_Policy_ChainFlags[2] = { - /* crl */ - CERT_REV_M_TEST_USING_THIS_METHOD - | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO - | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE, - /* ocsp */ - 0 -}; - -static const CERTRevocationFlags certRev_PKIX_Verify_Nist_Policy = { - { - /* leafTests */ - 2, - certRev_PKIX_Verify_Nist_Policy_LeafFlags, - 0, - 0, - 0 - }, - { - /* chainTests */ - 2, - certRev_PKIX_Verify_Nist_Policy_ChainFlags, - 0, - 0, - 0 - } -}; - -extern const CERTRevocationFlags* -CERT_GetPKIXVerifyNistRevocationPolicy() -{ - return &certRev_PKIX_Verify_Nist_Policy; -} - -CERTRevocationFlags * -CERT_AllocCERTRevocationFlags( - PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods, - PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods) -{ - CERTRevocationFlags *flags; - - flags = PORT_New(CERTRevocationFlags); - if (!flags) - return(NULL); - - flags->leafTests.number_of_defined_methods = number_leaf_methods; - flags->leafTests.cert_rev_flags_per_method = - PORT_NewArray(PRUint64, number_leaf_methods); - - flags->leafTests.number_of_preferred_methods = number_leaf_pref_methods; - flags->leafTests.preferred_methods = - PORT_NewArray(CERTRevocationMethodIndex, number_leaf_pref_methods); - - flags->chainTests.number_of_defined_methods = number_chain_methods; - flags->chainTests.cert_rev_flags_per_method = - PORT_NewArray(PRUint64, number_chain_methods); - - flags->chainTests.number_of_preferred_methods = number_chain_pref_methods; - flags->chainTests.preferred_methods = - PORT_NewArray(CERTRevocationMethodIndex, number_chain_pref_methods); - - if (!flags->leafTests.cert_rev_flags_per_method - || !flags->leafTests.preferred_methods - || !flags->chainTests.cert_rev_flags_per_method - || !flags->chainTests.preferred_methods) { - CERT_DestroyCERTRevocationFlags(flags); - return (NULL); - } - - return flags; -} - -void CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags) -{ - if (!flags) - return; - - if (flags->leafTests.cert_rev_flags_per_method) - PORT_Free(flags->leafTests.cert_rev_flags_per_method); - - if (flags->leafTests.preferred_methods) - PORT_Free(flags->leafTests.preferred_methods); - - if (flags->chainTests.cert_rev_flags_per_method) - PORT_Free(flags->chainTests.cert_rev_flags_per_method); - - if (flags->chainTests.preferred_methods) - PORT_Free(flags->chainTests.preferred_methods); - - PORT_Free(flags); -} - -/* - * CERT_PKIXVerifyCert - * - * Verify a Certificate using the PKIX library. - * - * Parameters: - * cert - the target certificate to verify. Must be non-null - * params - an array of type/value parameters which can be - * used to modify the behavior of the validation - * algorithm, or supply additional constraints. - * - * outputTrustAnchor - the trust anchor which the certificate - * chains to. The caller is responsible - * for freeing this. - * - * Example Usage: - * CERTValParam args[3]; - * args[0].type = cvpt_policyOID; - * args[0].value.si = oid; - * args[1].type = revCheckRequired; - * args[1].value.b = PR_TRUE; - * args[2].type = cvpt_end; - * - * CERT_PKIXVerifyCert(cert, &output, args - */ -SECStatus CERT_PKIXVerifyCert( - CERTCertificate *cert, - SECCertificateUsage usages, - CERTValInParam *paramsIn, - CERTValOutParam *paramsOut, - void *wincx) -{ - SECStatus r = SECFailure; - PKIX_Error * error = NULL; - PKIX_ProcessingParams *procParams = NULL; - PKIX_BuildResult * buildResult = NULL; - void * nbioContext = NULL; /* for non-blocking IO */ - void * buildState = NULL; /* for non-blocking IO */ - PKIX_CertSelector * certSelector = NULL; - PKIX_List * certStores = NULL; - PKIX_ValidateResult * valResult = NULL; - PKIX_VerifyNode * verifyNode = NULL; - PKIX_TrustAnchor * trustAnchor = NULL; - PKIX_PL_Cert * trustAnchorCert = NULL; - PKIX_List * builtCertList = NULL; - CERTValOutParam * oparam = NULL; - int i=0; - - void *plContext = NULL; - -#ifdef PKIX_OBJECT_LEAK_TEST - int leakedObjNum = 0; - int memLeakLoopCount = 0; - int objCountTable[PKIX_NUMTYPES]; - int fnInvLocalCount = 0; - PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine; - - if (usePKIXValidationEngine) { - /* current memory leak testing implementation does not allow - * to run simultaneous tests one the same or a different threads. - * Setting the variable to false, to make additional chain - * validations be handled by old nss. */ - usePKIXValidationEngine = PR_FALSE; - } - testStartFnStackPosition = 1; - fnStackNameArr[0] = "CERT_PKIXVerifyCert"; - fnStackInvCountArr[0] = 0; - PKIX_Boolean abortOnLeak = - (PR_GetEnv("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? - PKIX_FALSE : PKIX_TRUE; - runningLeakTest = PKIX_TRUE; - - /* Prevent multi-threaded run of object leak test */ - fnInvLocalCount = PR_ATOMIC_INCREMENT(¶llelFnInvocationCount); - PORT_Assert(fnInvLocalCount == 1); - -do { - r = SECFailure; - error = NULL; - procParams = NULL; - buildResult = NULL; - nbioContext = NULL; /* for non-blocking IO */ - buildState = NULL; /* for non-blocking IO */ - certSelector = NULL; - certStores = NULL; - valResult = NULL; - verifyNode = NULL; - trustAnchor = NULL; - trustAnchorCert = NULL; - builtCertList = NULL; - oparam = NULL; - i=0; - errorGenerated = PKIX_FALSE; - stackPosition = 0; - - if (leakedObjNum) { - pkix_pl_lifecycle_ObjectTableUpdate(objCountTable); - } - memLeakLoopCount += 1; -#endif /* PKIX_OBJECT_LEAK_TEST */ - - error = PKIX_PL_NssContext_Create( - 0, PR_FALSE /*use arena*/, wincx, &plContext); - if (error != NULL) { /* need pkix->nss error map */ - PORT_SetError(SEC_ERROR_CERT_NOT_VALID); - goto cleanup; - } - - error = pkix_pl_NssContext_SetCertUsage(usages, plContext); - if (error != NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto cleanup; - } - - error = PKIX_ProcessingParams_Create(&procParams, plContext); - if (error != NULL) { /* need pkix->nss error map */ - PORT_SetError(SEC_ERROR_CERT_NOT_VALID); - goto cleanup; - } - - /* local cert store should be set into procParams before - * filling in revocation settings. */ - certStores = cert_GetCertStores(plContext); - if (certStores == NULL) { - goto cleanup; - } - error = PKIX_ProcessingParams_SetCertStores - (procParams, certStores, plContext); - if (error != NULL) { - goto cleanup; - } - - /* now process the extensible input parameters structure */ - if (paramsIn != NULL) { - i=0; - while (paramsIn[i].type != cert_pi_end) { - if (paramsIn[i].type >= cert_pi_max) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto cleanup; - } - if (cert_pkixSetParam(procParams, - ¶msIn[i],plContext) != SECSuccess) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto cleanup; - } - i++; - } - } - - certSelector = cert_GetTargetCertConstraints(cert, plContext); - if (certSelector == NULL) { - goto cleanup; - } - error = PKIX_ProcessingParams_SetTargetCertConstraints - (procParams, certSelector, plContext); - if (error != NULL) { - goto cleanup; - } - - error = PKIX_BuildChain( procParams, &nbioContext, - &buildState, &buildResult, &verifyNode, - plContext); - if (error != NULL) { - goto cleanup; - } - - error = PKIX_BuildResult_GetValidateResult( buildResult, &valResult, - plContext); - if (error != NULL) { - goto cleanup; - } - - error = PKIX_ValidateResult_GetTrustAnchor( valResult, &trustAnchor, - plContext); - if (error != NULL) { - goto cleanup; - } - - if (trustAnchor != NULL) { - error = PKIX_TrustAnchor_GetTrustedCert( trustAnchor, &trustAnchorCert, - plContext); - if (error != NULL) { - goto cleanup; - } - } - -#ifdef PKIX_OBJECT_LEAK_TEST - /* Can not continue if error was generated but not returned. - * Jumping to cleanup. */ - if (errorGenerated) goto cleanup; -#endif /* PKIX_OBJECT_LEAK_TEST */ - - oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_trustAnchor); - if (oparam != NULL) { - if (trustAnchorCert != NULL) { - oparam->value.pointer.cert = - cert_NSSCertFromPKIXCert(trustAnchorCert); - } else { - oparam->value.pointer.cert = NULL; - } - } - - error = PKIX_BuildResult_GetCertChain( buildResult, &builtCertList, - plContext); - if (error != NULL) { - goto cleanup; - } - - oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_certList); - if (oparam != NULL) { - error = cert_PkixToNssCertsChain(builtCertList, - &oparam->value.pointer.chain, - plContext); - if (error) goto cleanup; - } - - r = SECSuccess; - -cleanup: - if (verifyNode) { - /* Return validation log only upon error. */ - oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_errorLog); -#ifdef PKIX_OBJECT_LEAK_TEST - if (!errorGenerated) -#endif /* PKIX_OBJECT_LEAK_TEST */ - if (r && oparam != NULL) { - PKIX_Error *tmpError = - cert_GetLogFromVerifyNode(oparam->value.pointer.log, - verifyNode, plContext); - if (tmpError) { - PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext); - } - } - PKIX_PL_Object_DecRef((PKIX_PL_Object *)verifyNode, plContext); - } - - if (procParams != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext); - - if (trustAnchorCert != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchorCert, plContext); - - if (trustAnchor != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext); - - if (valResult != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)valResult, plContext); - - if (buildResult != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)buildResult, plContext); - - if (certStores != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext); - - if (certSelector != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext); - - if (builtCertList != NULL) - PKIX_PL_Object_DecRef((PKIX_PL_Object *)builtCertList, plContext); - - if (error != NULL) { - SECErrorCodes nssErrorCode = 0; - - cert_PkixErrorToNssCode(error, &nssErrorCode, plContext); - cert_pkixDestroyValOutParam(paramsOut); - PORT_SetError(nssErrorCode); - PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); - } - - PKIX_PL_NssContext_Destroy(plContext); - -#ifdef PKIX_OBJECT_LEAK_TEST - leakedObjNum = - pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL); - - if (pkixLog && leakedObjNum) { - PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d." - "Stack %s\n", memLeakLoopCount, errorFnStackString)); - } - PR_Free(errorFnStackString); - errorFnStackString = NULL; - if (abortOnLeak) { - PORT_Assert(leakedObjNum == 0); - } - -} while (errorGenerated); - - runningLeakTest = PKIX_FALSE; - PR_ATOMIC_DECREMENT(¶llelFnInvocationCount); - usePKIXValidationEngine = savedUsePkixEngFlag; -#endif /* PKIX_OBJECT_LEAK_TEST */ - - return r; -} |