Index: mozilla/security/nss/lib/certhigh/certvfypkix.c |
=================================================================== |
--- mozilla/security/nss/lib/certhigh/certvfypkix.c (revision 191424) |
+++ mozilla/security/nss/lib/certhigh/certvfypkix.c (working copy) |
@@ -1,2325 +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; |
- |
- case cert_pi_useOnlyTrustAnchors: |
- error = |
- PKIX_ProcessingParams_SetUseOnlyTrustAnchors(procParams, |
- (PRBool)(param->value.scalar.b != 0), |
- plContext); |
- 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; |
-} |