diff options
author | alexei.volkov.bugs%sun.com <devnull@localhost> | 2009-04-20 05:17:48 +0000 |
---|---|---|
committer | alexei.volkov.bugs%sun.com <devnull@localhost> | 2009-04-20 05:17:48 +0000 |
commit | 4e042517c0282569a1c6cafc3e11587e617c555a (patch) | |
tree | 72cde12688994f2ab55b5d4295b64065a0d6836a | |
parent | 203334ec409157c87cb995ddd243c32c2ef6302f (diff) | |
download | nss-hg-4e042517c0282569a1c6cafc3e11587e617c555a.tar.gz |
485155 - NSS_ENABLE_PKIX_VERIFY=1 causes sec_error_unknown_issuer errors. r=nelson
8 files changed, 243 insertions, 149 deletions
diff --git a/security/nss/lib/certhigh/certvfypkix.c b/security/nss/lib/certhigh/certvfypkix.c index d4dac5b79..45065c074 100644 --- a/security/nss/lib/certhigh/certvfypkix.c +++ b/security/nss/lib/certhigh/certvfypkix.c @@ -130,6 +130,7 @@ CERT_GetUsePKIXForValidation() return usePKIXValidationEngine; } +#ifdef NOTDEF /* * FUNCTION: cert_NssKeyUsagesToPkix * DESCRIPTION: @@ -337,12 +338,13 @@ cleanup: PKIX_RETURN(CERTVFYPKIX); } +#endif /* - * FUNCTION: cert_ProcessingParamsSetKuAndEku + * FUNCTION: cert_ProcessingParamsSetKeyAndCertUsage * DESCRIPTION: * - * Converts cert usage to pkix KU and EKU types and sets + * Converts cert usage to pkix KU type and sets * converted data into PKIX_ProcessingParams object. It also sets * proper cert usage into nsscontext object. * @@ -354,8 +356,6 @@ cleanup: * validated for. * "requiredKeyUsage" * Request additional key usages the certificate should be validated for. - * "isCA" - * Should the cert be verifyed as CA cert for the usages. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: @@ -366,21 +366,17 @@ cleanup: * Returns a Fatal Error if the function fails in an unrecoverable way. */ static PKIX_Error* -cert_ProcessingParamsSetKuAndEku( +cert_ProcessingParamsSetKeyAndCertUsage( PKIX_ProcessingParams *procParams, - CERTCertificate *cert, - PRBool isCA, SECCertUsage requiredCertUsage, PRUint32 requiredKeyUsages, void *plContext) { - PKIX_List *extKeyUsage = NULL; PKIX_CertSelector *certSelector = NULL; PKIX_ComCertSelParams *certSelParams = NULL; PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext*)plContext; - PKIX_UInt32 keyUsage = 0; - PKIX_ENTER(CERTVFYPKIX, "cert_ProcessingParamsSetKuAndEku"); + PKIX_ENTER(CERTVFYPKIX, "cert_ProcessingParamsSetKeyAndCertUsage"); PKIX_NULLCHECK_TWO(procParams, nssContext); PKIX_CHECK( @@ -388,37 +384,24 @@ cert_ProcessingParamsSetKuAndEku( ((SECCertificateUsage)1) << requiredCertUsage, nssContext), PKIX_NSSCONTEXTSETCERTUSAGEFAILED); - PKIX_CHECK( - cert_NssCertificateUsageToPkixKUAndEKU(cert, requiredCertUsage, - requiredKeyUsages, isCA, - &extKeyUsage, &keyUsage, - plContext), - PKIX_CANNOTCONVERTCERTUSAGETOPKIXKEYANDEKUSAGES); - - 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, keyUsage, - plContext), - PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED); - - PKIX_CHECK( - PKIX_ComCertSelParams_SetExtendedKeyUsage(certSelParams, - extKeyUsage, - plContext), - PKIX_COMCERTSELPARAMSSETEXTKEYUSAGEFAILED); - + 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(extKeyUsage); PKIX_DECREF(certSelector); PKIX_DECREF(certSelParams); @@ -1274,8 +1257,8 @@ do { } error = - cert_ProcessingParamsSetKuAndEku(procParams, cert, PR_TRUE, - requiredUsage, 0, plContext); + cert_ProcessingParamsSetKeyAndCertUsage(procParams, requiredUsage, 0, + plContext); if (error) { goto cleanup; } diff --git a/security/nss/lib/libpkix/include/pkix_errorstrings.h b/security/nss/lib/libpkix/include/pkix_errorstrings.h index 64298604c..182f8493a 100755 --- a/security/nss/lib/libpkix/include/pkix_errorstrings.h +++ b/security/nss/lib/libpkix/include/pkix_errorstrings.h @@ -136,10 +136,11 @@ PKIX_ERRORENTRY(CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED,PKIX_CertChainChe PKIX_ERRORENTRY(CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION,CertChain fails Certificate Policy validation,SEC_ERROR_POLICY_VALIDATION_FAILED), PKIX_ERRORENTRY(CERTCHAINTONSSCHAINFAILED,Fail to convert pkix cert chain to nss cert chain,0), PKIX_ERRORENTRY(CERTCHAINTOPKIXCERTLISTFAILED,Failed to convert nss cert chain to pkix cert chain,0), +PKIX_ERRORENTRY(CERTCHECKCERTTYPEFAILED,Check cert type failed,SEC_ERROR_INADEQUATE_CERT_TYPE), PKIX_ERRORENTRY(CERTCHECKCERTVALIDTIMESFAILED,CERT_CheckCertValidTimes failed,SEC_ERROR_EXPIRED_CERTIFICATE), PKIX_ERRORENTRY(CERTCHECKCRLFAILED,Fail to get crl cache issued by cert,0), PKIX_ERRORENTRY(CERTCHECKEXTENDEDKEYUSAGEFAILED,pkix_pl_Cert_CheckExtendedKeyUsage failed,0), -PKIX_ERRORENTRY(CERTCHECKKEYUSAGEFAILED,CERT_CheckKeyUsage failed,0), +PKIX_ERRORENTRY(CERTCHECKKEYUSAGEFAILED,CERT_CheckKeyUsage failed,SEC_ERROR_INADEQUATE_KEY_USAGE), PKIX_ERRORENTRY(CERTCHECKNAMECONSTRAINTSFAILED,PKIX_PL_Cert_CheckNameConstraints failed,0), PKIX_ERRORENTRY(CERTCHECKVALIDITYFAILED,PKIX_PL_Cert_CheckValidity failed,SEC_ERROR_CERT_NOT_VALID), PKIX_ERRORENTRY(CERTCOMPLETECRLDECODEDENTRIESFAILED,CERT_CompleteCRLDecodedEntries failed,0), @@ -267,6 +268,7 @@ PKIX_ERRORENTRY(CERTSTOREGETTRUSTCALLBACKFAILED,PKIX_CertStore_GetTrustCallback PKIX_ERRORENTRY(CERTSTOREHASHCODEFAILED,pkix_CertStore_Hashcode failed,0), PKIX_ERRORENTRY(CERTTOSTRINGFAILED,PKIX_PL_Cert_ToString failed,0), PKIX_ERRORENTRY(CERTTOSTRINGHELPERFAILED,pkix_pl_Cert_ToString_Helper failed,0), +PKIX_ERRORENTRY(CERTVERIFYCERTTYPEFAILED,PKIX_PL_Cert_VerifyCertAndKeyType failed,0), PKIX_ERRORENTRY(CERTVERIFYKEYUSAGEFAILED,PKIX_PL_Cert_VerifyKeyUsage failed,0), PKIX_ERRORENTRY(CERTVERIFYSIGNATUREFAILED,PKIX_PL_Cert_VerifySignature failed,0), PKIX_ERRORENTRY(CHAINREJECTEDBYREVOCATIONCHECKER,Chain rejected by Revocation Checker,0), @@ -1080,6 +1082,7 @@ PKIX_ERRORENTRY(UNRECOGNIZEDREQUESTMETHOD,Unrecognized request method,0), PKIX_ERRORENTRY(UNRECOGNIZEDTIMETYPE,Unrecognized time type,0), PKIX_ERRORENTRY(UNSUPPORTEDCRLDPTYPE,CrlDp type is not supported,0), PKIX_ERRORENTRY(UNSUPPORTEDVERSIONOFHTTPCLIENT,Unsupported version of Http Client,0), +PKIX_ERRORENTRY(UNSUPPORTEDCERTUSAGE,Specified certificate usage is unsupported,SEC_ERROR_CERT_USAGES_INVALID), PKIX_ERRORENTRY(URLPARSINGFAILED,URL Parsing failed,0), PKIX_ERRORENTRY(USERCHECKERCHECKFAILED,userCheckerCheck failed,0), PKIX_ERRORENTRY(UTF16ALIGNMENTERROR,UTF16 Alignment Error,SEC_ERROR_INVALID_ARGS), diff --git a/security/nss/lib/libpkix/include/pkix_pl_pki.h b/security/nss/lib/libpkix/include/pkix_pl_pki.h index c1402528b..32d3a79a4 100755 --- a/security/nss/lib/libpkix/include/pkix_pl_pki.h +++ b/security/nss/lib/libpkix/include/pkix_pl_pki.h @@ -1394,6 +1394,34 @@ PKIX_PL_Cert_VerifyKeyUsage( void *plContext); /* + * FUNCTION: PKIX_PL_Cert_VerifyCertAndKeyType + * DESCRIPTION: + * + * Verifies cert and key types against certificate usage that is + * a part of plContext(pkix_pl_nsscontext) structure. Throws an error + * if cert or key types does not match. + * + * PARAMETERS: + * "cert" + * Address of Cert whose keyUsage bits are to be verified. + * Must be non-NULL. + * "isLeafCert" + * What type of a cert has been verified. + * "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 Error if the function fails in a non-fatal way. + * Returns a Fatal Error if the function fails in an unrecoverable way. + */ +PKIX_Error * +PKIX_PL_Cert_VerifyCertAndKeyType( + PKIX_PL_Cert *cert, + PKIX_Boolean isChainCert, + void *plContext); + +/* * FUNCTION: PKIX_PL_Cert_CheckValidity * DESCRIPTION: * diff --git a/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.c b/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.c index f02ce4295..23eda7ac1 100755 --- a/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.c +++ b/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.c @@ -1179,6 +1179,7 @@ pkix_CertSelector_DefaultMatch( PKIX_UInt32 selVersion = 0xFFFFFFFF; PKIX_UInt32 certVersion = 0; PKIX_Boolean result = PKIX_TRUE; + PKIX_Boolean isLeafCert = PKIX_TRUE; #ifdef PKIX_BUILDDEBUG PKIX_PL_String *certString = NULL; @@ -1192,6 +1193,11 @@ pkix_CertSelector_DefaultMatch( PKIX_INCREF(selector->params); params = selector->params; + /* Are we looking for CAs? */ + PKIX_CHECK(PKIX_ComCertSelParams_GetLeafCertFlag + (params, &isLeafCert, plContext), + PKIX_COMCERTSELPARAMSGETLEAFCERTFLAGFAILED); + if (params == NULL){ goto cleanup; } @@ -1322,6 +1328,11 @@ pkix_CertSelector_DefaultMatch( (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED); + /* Check key usage and cert type based on certificate usage. */ + PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, !isLeafCert, + plContext), + PKIX_CERTVERIFYCERTTYPEFAILED); + /* Next two check are for user supplied additional KU and EKU. */ PKIX_CHECK(pkix_CertSelector_Match_ExtendedKeyUsage (params, cert, &result, plContext), diff --git a/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c b/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c index 787ab26df..7f8aa90c9 100755 --- a/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c +++ b/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c @@ -278,7 +278,7 @@ PKIX_ComCertSelParams_Create( params->subjKeyId = NULL; params->subjPubKey = NULL; params->subjPKAlgId = NULL; - params->leafCertFlag = PKIX_TRUE; + params->leafCertFlag = PKIX_FALSE; *pParams = params; diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c index 09697d3d8..2d3140986 100755 --- a/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c +++ b/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c @@ -362,86 +362,94 @@ pkix_TargetCertChecker_Check( PKIX_ERROR(PKIX_SUBJALTNAMECHECKFAILED); } - } if (state->certsRemaining == 0) { - if (state->certSelector != NULL) { - - PKIX_CHECK(PKIX_CertSelector_GetMatchCallback - (state->certSelector, + if (state->certSelector != NULL) { + PKIX_CHECK(PKIX_CertSelector_GetMatchCallback + (state->certSelector, &certSelectorMatch, plContext), - PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); + PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); - PKIX_CHECK(certSelectorMatch - (state->certSelector, + PKIX_CHECK(certSelectorMatch + (state->certSelector, cert, plContext), - PKIX_CERTSELECTORMATCHFAILED); - /* - * There are two Extended Key Usage Checkings - * available : - * 1) here at the targetcertchecker where we - * verify the Extended Key Usage OIDs application - * specifies via ComCertSelParams are included - * in Cert's Extended Key Usage OID's. Note, - * this is an OID to OID comparison and only last - * Cert is checked. - * 2) at user defined ekuchecker where checking - * is applied to all Certs on the chain and - * the NSS Extended Key Usage algorithm is - * used. In order to invoke this checking, not - * only does the ComCertSelparams needs to be - * set, the EKU initialize call is required to - * activate the checking. - * - * XXX We use the same ComCertSelParams Set/Get - * functions to set the parameters for both cases. - * We may want to separate them in the future. - */ - - PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage - (cert, &certExtKeyUsageList, plContext), - PKIX_CERTGETEXTENDEDKEYUSAGEFAILED); - - - if (state->extKeyUsageList != NULL && - certExtKeyUsageList != NULL) { - - PKIX_CHECK(PKIX_List_GetLength - (state->extKeyUsageList, &numItems, plContext), - PKIX_LISTGETLENGTHFAILED); - - for (i = 0; i < numItems; i++) { - - PKIX_CHECK(PKIX_List_GetItem - (state->extKeyUsageList, - i, - (PKIX_PL_Object **) &name, - plContext), - PKIX_LISTGETITEMFAILED); - - PKIX_CHECK(pkix_List_Contains - (certExtKeyUsageList, - (PKIX_PL_Object *) name, - &checkPassed, - plContext), - PKIX_LISTCONTAINSFAILED); - - PKIX_DECREF(name); - - if (checkPassed != PKIX_TRUE) { - PKIX_ERROR - (PKIX_EXTENDEDKEYUSAGECHECKINGFAILED); - - } - } - - } - + PKIX_CERTSELECTORMATCHFAILED); + } else { + /* Check at least cert/key usages if target cert selector + * is not set. */ + PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, + PKIX_FALSE /* is chain cert*/, + plContext), + PKIX_CERTVERIFYCERTTYPEFAILED); + } + /* + * There are two Extended Key Usage Checkings + * available : + * 1) here at the targetcertchecker where we + * verify the Extended Key Usage OIDs application + * specifies via ComCertSelParams are included + * in Cert's Extended Key Usage OID's. Note, + * this is an OID to OID comparison and only last + * Cert is checked. + * 2) at user defined ekuchecker where checking + * is applied to all Certs on the chain and + * the NSS Extended Key Usage algorithm is + * used. In order to invoke this checking, not + * only does the ComCertSelparams needs to be + * set, the EKU initialize call is required to + * activate the checking. + * + * XXX We use the same ComCertSelParams Set/Get + * functions to set the parameters for both cases. + * We may want to separate them in the future. + */ + + PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage + (cert, &certExtKeyUsageList, plContext), + PKIX_CERTGETEXTENDEDKEYUSAGEFAILED); + + + if (state->extKeyUsageList != NULL && + certExtKeyUsageList != NULL) { + + PKIX_CHECK(PKIX_List_GetLength + (state->extKeyUsageList, &numItems, plContext), + PKIX_LISTGETLENGTHFAILED); + + for (i = 0; i < numItems; i++) { + + PKIX_CHECK(PKIX_List_GetItem + (state->extKeyUsageList, + i, + (PKIX_PL_Object **) &name, + plContext), + PKIX_LISTGETITEMFAILED); + + PKIX_CHECK(pkix_List_Contains + (certExtKeyUsageList, + (PKIX_PL_Object *) name, + &checkPassed, + plContext), + PKIX_LISTCONTAINSFAILED); + + PKIX_DECREF(name); + + if (checkPassed != PKIX_TRUE) { + PKIX_ERROR + (PKIX_EXTENDEDKEYUSAGECHECKINGFAILED); + + } } + } + } else { + /* Check key usage and cert type based on certificate usage. */ + PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, PKIX_TRUE, + plContext), + PKIX_CERTVERIFYCERTTYPEFAILED); } /* Remove Critical Extension OID from list */ diff --git a/security/nss/lib/libpkix/pkix/top/pkix_build.c b/security/nss/lib/libpkix/pkix/top/pkix_build.c index 20aa6d39b..cc112e842 100755 --- a/security/nss/lib/libpkix/pkix/top/pkix_build.c +++ b/security/nss/lib/libpkix/pkix/top/pkix_build.c @@ -1038,7 +1038,7 @@ pkix_Build_ValidationCheckers( PKIX_ForwardBuilderState *state, PKIX_List *certChain, PKIX_TrustAnchor *anchor, - PKIX_Boolean addEkuChecker, + PKIX_Boolean chainRevalidationStage, void *plContext) { PKIX_List *checkers = NULL; @@ -1051,8 +1051,8 @@ pkix_Build_ValidationCheckers( PKIX_CertChainChecker *sigChecker = NULL; PKIX_CertChainChecker *policyChecker = NULL; PKIX_CertChainChecker *userChecker = NULL; - PKIX_CertChainChecker *ekuChecker = NULL; - PKIX_List *userCheckersList = NULL; + PKIX_CertChainChecker *checker = NULL; + PKIX_CertSelector *certSelector = NULL; PKIX_List *userCheckerExtOIDs = NULL; PKIX_PL_OID *oid = NULL; PKIX_Boolean supportForwardChecking = PKIX_FALSE; @@ -1080,21 +1080,31 @@ pkix_Build_ValidationCheckers( procParams = state->buildConstants.procParams; - /* Do need to add eku checker for chains, that we just - * built. KU and EKU get checked by certificate selector - * during chain construction. For other cases when trying - * short cut or for cached chain we need to verify key - * usage again. For those cases the function shoud be - * called with addEkuChecker set to true. */ - if (addEkuChecker) { - PKIX_CHECK( - PKIX_EkuChecker_Create(procParams, &ekuChecker, - plContext), - PKIX_EKUCHECKERINITIALIZEFAILED); + /* Do need to add a number of checker to revalidate + * a built chain. KU, EKU, CertType and Validity Date + * get checked by certificate selector during chain + * construction, but needed to be checked for chain from + * the cache.*/ + if (chainRevalidationStage) { + PKIX_CHECK(pkix_ExpirationChecker_Initialize + (state->buildConstants.testDate, &checker, plContext), + PKIX_EXPIRATIONCHECKERINITIALIZEFAILED); + PKIX_CHECK(PKIX_List_AppendItem + (checkers, (PKIX_PL_Object *)checker, plContext), + PKIX_LISTAPPENDITEMFAILED); + PKIX_DECREF(checker); + PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints + (procParams, &certSelector, plContext), + PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); + + PKIX_CHECK(pkix_TargetCertChecker_Initialize + (certSelector, numChainCerts, &checker, plContext), + PKIX_EXPIRATIONCHECKERINITIALIZEFAILED); PKIX_CHECK(PKIX_List_AppendItem - (checkers, (PKIX_PL_Object *)ekuChecker, plContext), + (checkers, (PKIX_PL_Object *)checker, plContext), PKIX_LISTAPPENDITEMFAILED); + PKIX_DECREF(checker); } PKIX_CHECK(PKIX_ProcessingParams_GetInitialPolicies @@ -1247,16 +1257,16 @@ cleanup: PKIX_DECREF(oid); PKIX_DECREF(reversedCertChain); PKIX_DECREF(buildCheckedCritExtOIDsList); + PKIX_DECREF(checker); PKIX_DECREF(checkers); PKIX_DECREF(initialPolicies); PKIX_DECREF(trustedCert); PKIX_DECREF(trustedPubKey); + PKIX_DECREF(certSelector); PKIX_DECREF(sigChecker); PKIX_DECREF(policyChecker); PKIX_DECREF(userChecker); - PKIX_DECREF(userCheckersList); PKIX_DECREF(userCheckerExtOIDs); - PKIX_DECREF(ekuChecker); PKIX_RETURN(BUILD); } @@ -3041,11 +3051,8 @@ pkix_Build_CheckInCache( (matchingAnchor, &trustedCert, plContext), PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); - if (!state->buildConstants.anchors) { - PKIX_CHECK(PKIX_PL_Cert_IsCertTrusted - (trustedCert, PKIX_FALSE, &trusted, plContext), - PKIX_CERTISCERTTRUSTEDFAILED); - } else { + if (state->buildConstants.anchors && + state->buildConstants.anchors->length) { /* Check if it is one of the trust anchors */ PKIX_CHECK( pkix_List_Contains(state->buildConstants.anchors, @@ -3053,6 +3060,10 @@ pkix_Build_CheckInCache( &trusted, plContext), PKIX_LISTCONTAINSFAILED); + } else { + PKIX_CHECK(PKIX_PL_Cert_IsCertTrusted + (trustedCert, PKIX_FALSE, &trusted, plContext), + PKIX_CERTISCERTTRUSTEDFAILED); } if (!trusted) { @@ -3067,19 +3078,13 @@ pkix_Build_CheckInCache( (buildResult, &certList, plContext), PKIX_BUILDRESULTGETCERTCHAINFAILED); - /* setting this variable will trigger addition rev - * checker into cert chain checker list */ - state->revCheckDelayed = PKIX_TRUE; - PKIX_CHECK(pkix_Build_ValidationCheckers (state, certList, matchingAnchor, - PKIX_TRUE, /* Adding eku checker. */ + PKIX_TRUE, /* Chain revalidation stage. */ plContext), PKIX_BUILDVALIDATIONCHECKERSFAILED); - - state->revCheckDelayed = PKIX_FALSE; PKIX_CHECK_ONLY_FATAL( pkix_Build_ValidateEntireChain(state, matchingAnchor, @@ -3248,6 +3253,11 @@ pkix_Build_InitiateBuildChain( (targetParams, &targetCert, plContext), PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED); + PKIX_CHECK( + PKIX_ComCertSelParams_SetLeafCertFlag(targetParams, + PKIX_TRUE, plContext), + PKIX_COMCERTSELPARAMSSETLEAFCERTFLAGFAILED); + PKIX_CHECK(PKIX_ProcessingParams_GetHintCerts (procParams, &hintCerts, plContext), PKIX_PROCESSINGPARAMSGETHINTCERTSFAILED); @@ -3338,12 +3348,7 @@ pkix_Build_InitiateBuildChain( plContext), PKIX_COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED); - PKIX_CHECK( - PKIX_ComCertSelParams_SetLeafCertFlag(targetParams, - PKIX_TRUE, plContext), - PKIX_COMCERTSELPARAMSSETLEAFCERTFLAGFAILED); - - PKIX_CHECK(PKIX_CertSelector_GetMatchCallback + PKIX_CHECK(PKIX_CertSelector_GetMatchCallback (targetConstraints, &selectorCallback, plContext), PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c index 17de0d8f8..f2156acbd 100644 --- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c +++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c @@ -2986,6 +2986,62 @@ cleanup: } /* + * FUNCTION: PKIX_PL_Cert_VerifyCertAndKeyType (see comments in pkix_pl_pki.h) + */ +PKIX_Error * +PKIX_PL_Cert_VerifyCertAndKeyType( + PKIX_PL_Cert *cert, + PKIX_Boolean isChainCert, + void *plContext) +{ + PKIX_PL_CertBasicConstraints *basicConstraints = NULL; + SECCertificateUsage certificateUsage; + SECCertUsage certUsage = 0; + unsigned int requiredKeyUsage; + unsigned int requiredCertType; + unsigned int certType; + SECStatus rv = SECSuccess; + + PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyCertType"); + PKIX_NULLCHECK_TWO(cert, plContext); + + certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage; + + /* ensure we obtained a single usage bit only */ + PORT_Assert(!(certificateUsage & (certificateUsage - 1))); + + /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */ + while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; } + + /* check key usage and netscape cert type */ + cert_GetCertType(cert->nssCert); + certType = cert->nssCert->nsCertType; + if (isChainCert || + (certUsage != certUsageVerifyCA && certUsage != certUsageAnyCA)) { + rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, isChainCert, + &requiredKeyUsage, + &requiredCertType); + if (rv == SECFailure) { + PKIX_ERROR(PKIX_UNSUPPORTEDCERTUSAGE); + } + } else { + /* use this key usage and cert type for certUsageAnyCA and + * certUsageVerifyCA. */ + requiredKeyUsage = KU_KEY_CERT_SIGN; + requiredCertType = NS_CERT_TYPE_CA; + } + if (CERT_CheckKeyUsage(cert->nssCert, requiredKeyUsage) != SECSuccess) { + PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED); + } + if (!(certType & requiredCertType)) { + PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED); + } +cleanup: + PKIX_DECREF(basicConstraints); + PKIX_RETURN(CERT); +} + +/* * FUNCTION: PKIX_PL_Cert_VerifyKeyUsage (see comments in pkix_pl_pki.h) */ PKIX_Error * |