Index: nss/mozilla/security/nss/lib/libpkix/pkix/top/pkix_validate.c |
=================================================================== |
--- nss/mozilla/security/nss/lib/libpkix/pkix/top/pkix_validate.c (revision 162724) |
+++ nss/mozilla/security/nss/lib/libpkix/pkix/top/pkix_validate.c (working copy) |
@@ -9,6 +9,7 @@ |
*/ |
#include "pkix_validate.h" |
+#include "pkix_pl_common.h" |
/* --Private-Functions-------------------------------------------- */ |
@@ -700,6 +701,10 @@ |
void *nbioContext = NULL; |
PKIX_PL_Cert *cert = NULL; |
PKIX_PL_Cert *issuer = NULL; |
+ PKIX_PL_NssContext *nssContext = NULL; |
+ CERTCertList *certList = NULL; |
+ const CERTChainVerifyCallback *chainVerifyCallback = NULL; |
+ CERTCertificate *nssCert = NULL; |
PKIX_ENTER(VALIDATE, "pkix_CheckChain"); |
PKIX_NULLCHECK_FOUR(certs, checkers, revChecker, pCertCheckedIndex); |
@@ -709,11 +714,70 @@ |
nbioContext = *pNBIOContext; |
*pNBIOContext = NULL; |
revChecking = *pRevChecking; |
+ nssContext = (PKIX_PL_NssContext *)plContext; |
+ chainVerifyCallback = &nssContext->chainVerifyCallback; |
+ if (chainVerifyCallback->isChainValid != NULL) { |
+ PRBool chainOK = PR_FALSE; /*assume failure*/ |
+ SECStatus rv; |
+ |
+ certList = CERT_NewCertList(); |
+ if (certList == NULL) { |
+ PKIX_ERROR_ALLOC_ERROR(); |
+ } |
+ |
+ /* Add the trust anchor to the list */ |
+ PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert |
+ (anchor, &cert, plContext), |
+ PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); |
+ |
+ PKIX_CHECK( |
+ PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContext), |
+ PKIX_CERTGETCERTCERTIFICATEFAILED); |
+ |
+ rv = CERT_AddCertToListHead(certList, nssCert); |
+ if (rv != SECSuccess) { |
+ PKIX_ERROR_ALLOC_ERROR(); |
+ } |
+ /* the certList takes ownership of nssCert on success */ |
+ nssCert = NULL; |
+ PKIX_DECREF(cert); |
+ |
+ /* Add the rest of the chain to the list */ |
+ for (j = *pCertCheckedIndex; j < numCerts; j++) { |
+ PKIX_CHECK(PKIX_List_GetItem( |
+ certs, j, (PKIX_PL_Object **)&cert, plContext), |
+ PKIX_LISTGETITEMFAILED); |
+ |
+ PKIX_CHECK( |
+ PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContext), |
+ PKIX_CERTGETCERTCERTIFICATEFAILED); |
+ |
+ rv = CERT_AddCertToListHead(certList, nssCert); |
+ if (rv != SECSuccess) { |
+ PKIX_ERROR_ALLOC_ERROR(); |
+ } |
+ /* the certList takes ownership of nssCert on success */ |
+ nssCert = NULL; |
+ PKIX_DECREF(cert); |
+ } |
+ |
+ rv = (*chainVerifyCallback->isChainValid) |
+ (chainVerifyCallback->isChainValidArg, certList, &chainOK); |
+ if (rv != SECSuccess) { |
+ PKIX_ERROR_FATAL(PKIX_CHAINVERIFYCALLBACKFAILED); |
+ } |
+ |
+ if (!chainOK) { |
+ PKIX_ERROR(PKIX_CHAINVERIFYCALLBACKFAILED); |
+ } |
+ |
+ } |
+ |
PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert |
(anchor, &cert, plContext), |
PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); |
- |
+ |
for (j = *pCertCheckedIndex; j < numCerts; j++) { |
PORT_Assert(cert); |
@@ -809,6 +873,14 @@ |
} |
fatal: |
+ if (nssCert) { |
+ CERT_DestroyCertificate(nssCert); |
+ } |
+ |
+ if (certList) { |
+ CERT_DestroyCertList(certList); |
+ } |
+ |
PKIX_DECREF(checkCertError); |
PKIX_DECREF(cert); |
PKIX_DECREF(issuer); |