diff options
author | richard.freedman%sun.com <devnull@localhost> | 2006-06-12 20:24:13 +0000 |
---|---|---|
committer | richard.freedman%sun.com <devnull@localhost> | 2006-06-12 20:24:13 +0000 |
commit | 585d233fe7bd7ab68d0da78b3547e5432bebdcfa (patch) | |
tree | 7d03c0fc77a66281afcc4b71e1cf709a4c6b5fc4 | |
parent | aaecdffd2b56eec8b1d88428fec69bf84f2bda4f (diff) | |
download | nss-hg-585d233fe7bd7ab68d0da78b3547e5432bebdcfa.tar.gz |
Add verifyNodes to test_buildchain. It calls for an additional argument
to PKIX_Build, so calling sequences in other test_buildchain variants
had to be modified as well (taking a NULL argument, for now).
13 files changed, 925 insertions, 374 deletions
diff --git a/security/nss/cmd/libpkix/pkix/top/buildchain/test_buildchain.c b/security/nss/cmd/libpkix/pkix/top/buildchain/test_buildchain.c index 352d2ded0..6bc433cbc 100755 --- a/security/nss/cmd/libpkix/pkix/top/buildchain/test_buildchain.c +++ b/security/nss/cmd/libpkix/pkix/top/buildchain/test_buildchain.c @@ -41,7 +41,7 @@ * */ -#define debuggingWithoutRevocation +/* #define debuggingWithoutRevocation */ #include "testutil.h" #include "testutil_nss.h" @@ -155,6 +155,8 @@ int main(int argc, char *argv[]) PKIX_Boolean testValid = PKIX_TRUE; PKIX_List *expectedCerts = NULL; PKIX_PL_Cert *dirCert = NULL; + PKIX_VerifyNode *verifyTree = NULL; + PKIX_PL_String *verifyString = NULL; PKIX_PL_String *actualCertsString = NULL; PKIX_PL_String *expectedCertsString = NULL; void *state = NULL; @@ -226,11 +228,11 @@ int main(int argc, char *argv[]) PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedCerts, plContext)); - for (k = ++j; k < argc; k++) { + for (k = ++j; k < (PKIX_UInt32)argc; k++) { dirCert = createCert(dirName, argv[k], plContext); - if (k == (argc - 1)) { + if (k == (PKIX_UInt32)(argc - 1)) { PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef ((PKIX_PL_Object *)dirCert, plContext)); trustedCert = dirCert; @@ -345,6 +347,7 @@ int main(int argc, char *argv[]) (void **)&pollDesc, &state, &buildResult, + &verifyTree, plContext); while (pollDesc != NULL) { @@ -358,6 +361,7 @@ int main(int argc, char *argv[]) (void **)&pollDesc, &state, &buildResult, + &verifyTree, plContext); } @@ -367,16 +371,31 @@ int main(int argc, char *argv[]) } else { /* ENE */ testError("UNEXPECTED ERROR RECEIVED"); } + } else { + if (testValid == PKIX_TRUE) { /* ENE */ + (void) printf("EXPECTED NON-ERROR RECEIVED!\n"); + } else { /* EE */ + (void) printf("UNEXPECTED NON-ERROR RECEIVED!\n"); + } + } + + subTest("Displaying VerifyNode objects"); + + if (verifyTree == NULL) { + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create + (PKIX_ESCASCII, "(null)", 0, &verifyString, plContext)); + } else { + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString + ((PKIX_PL_Object*)verifyTree, &verifyString, plContext)); + } + + (void) printf("verifyTree is\n%s\n", verifyString->escAsciiString); + + if (pkixTestErrorResult) { PKIX_TEST_DECREF_BC(pkixTestErrorResult); goto cleanup; } - if (testValid == PKIX_TRUE) { /* ENE */ - (void) printf("EXPECTED NON-ERROR RECEIVED!\n"); - } else { /* EE */ - (void) printf("UNEXPECTED NON-ERROR RECEIVED!\n"); - } - if (buildResult) { PKIX_TEST_EXPECT_NO_ERROR @@ -452,8 +471,10 @@ int main(int argc, char *argv[]) } - cleanup: + PKIX_TEST_DECREF_AC(verifyString); + PKIX_TEST_DECREF_AC(verifyTree); + PKIX_PL_Free(asciiResult, NULL); PKIX_PL_Free(actualCertsAscii, plContext); PKIX_PL_Free(expectedCertsAscii, plContext); diff --git a/security/nss/cmd/libpkix/pkix/top/buildchain_partialchain/test_buildchain_partialchain.c b/security/nss/cmd/libpkix/pkix/top/buildchain_partialchain/test_buildchain_partialchain.c index 33b5ff921..698671aab 100644 --- a/security/nss/cmd/libpkix/pkix/top/buildchain_partialchain/test_buildchain_partialchain.c +++ b/security/nss/cmd/libpkix/pkix/top/buildchain_partialchain/test_buildchain_partialchain.c @@ -125,18 +125,18 @@ cleanup: /* Test with all Certs in the partial list, no leaf */ static PKIX_Error * testWithNoLeaf( - PKIX_PL_Cert *trustedCert, - PKIX_List *listOfCerts, - PKIX_PL_Cert *targetCert, - PKIX_List *certStores, - PKIX_Boolean testValid, + PKIX_PL_Cert *trustedCert, + PKIX_List *listOfCerts, + PKIX_PL_Cert *targetCert, + PKIX_List *certStores, + PKIX_Boolean testValid, void* plContext) { PKIX_UInt32 numCerts = 0; PKIX_UInt32 i = 0; PKIX_TrustAnchor *anchor = NULL; PKIX_List *anchors = NULL; - PKIX_List *hintCerts = NULL; + PKIX_List *hintCerts = NULL; PKIX_List *revCheckers = NULL; PKIX_List *certs = NULL; PKIX_PL_Cert *cert = NULL; @@ -165,7 +165,7 @@ testWithNoLeaf( /* create CertSelector with no target certificate in params */ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create - (&certSelParams, plContext)); + (&certSelParams, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create (NULL, NULL, &certSelector, plContext)); @@ -176,14 +176,14 @@ testWithNoLeaf( PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints (procParams, certSelector, plContext)); - /* create hintCerts */ - PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate - ((PKIX_PL_Object *)listOfCerts, - (PKIX_PL_Object **)&hintCerts, - plContext)); + /* create hintCerts */ + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate + ((PKIX_PL_Object *)listOfCerts, + (PKIX_PL_Object **)&hintCerts, + plContext)); - PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts - (procParams, hintCerts, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts + (procParams, hintCerts, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores (procParams, certStores, plContext)); @@ -222,6 +222,7 @@ testWithNoLeaf( (void **)&pollDesc, &state, &buildResult, + NULL, plContext); while (pollDesc != NULL) { @@ -235,6 +236,7 @@ testWithNoLeaf( (void **)&pollDesc, &state, &buildResult, + NULL, plContext); } @@ -284,7 +286,7 @@ testWithNoLeaf( PKIX_TEST_DECREF_BC(cert); } - } + } cleanup: PKIX_PL_Free(asciiResult, NULL); @@ -311,18 +313,18 @@ cleanup: /* Test with all Certs in the partial list, leaf duplicates the first one */ static PKIX_Error * testWithDuplicateLeaf( - PKIX_PL_Cert *trustedCert, - PKIX_List *listOfCerts, - PKIX_PL_Cert *targetCert, - PKIX_List *certStores, - PKIX_Boolean testValid, + PKIX_PL_Cert *trustedCert, + PKIX_List *listOfCerts, + PKIX_PL_Cert *targetCert, + PKIX_List *certStores, + PKIX_Boolean testValid, void* plContext) { PKIX_UInt32 numCerts = 0; PKIX_UInt32 i = 0; PKIX_TrustAnchor *anchor = NULL; PKIX_List *anchors = NULL; - PKIX_List *hintCerts = NULL; + PKIX_List *hintCerts = NULL; PKIX_List *revCheckers = NULL; PKIX_List *certs = NULL; PKIX_PL_Cert *cert = NULL; @@ -351,7 +353,7 @@ testWithDuplicateLeaf( /* create CertSelector with target certificate in params */ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create - (&certSelParams, plContext)); + (&certSelParams, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate (certSelParams, targetCert, plContext)); @@ -365,14 +367,14 @@ testWithDuplicateLeaf( PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints (procParams, certSelector, plContext)); - /* create hintCerts */ - PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate - ((PKIX_PL_Object *)listOfCerts, - (PKIX_PL_Object **)&hintCerts, - plContext)); + /* create hintCerts */ + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate + ((PKIX_PL_Object *)listOfCerts, + (PKIX_PL_Object **)&hintCerts, + plContext)); - PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts - (procParams, hintCerts, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts + (procParams, hintCerts, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores (procParams, certStores, plContext)); @@ -411,6 +413,7 @@ testWithDuplicateLeaf( (void **)&pollDesc, &state, &buildResult, + NULL, plContext); while (pollDesc != NULL) { @@ -424,6 +427,7 @@ testWithDuplicateLeaf( (void **)&pollDesc, &state, &buildResult, + NULL, plContext); } @@ -473,7 +477,7 @@ testWithDuplicateLeaf( PKIX_TEST_DECREF_BC(cert); } - } + } cleanup: PKIX_PL_Free(asciiResult, NULL); @@ -500,18 +504,18 @@ cleanup: /* Test with all Certs except the leaf in the partial list */ static PKIX_Error * testWithLeafAndChain( - PKIX_PL_Cert *trustedCert, - PKIX_List *listOfCerts, - PKIX_PL_Cert *targetCert, - PKIX_List *certStores, - PKIX_Boolean testValid, + PKIX_PL_Cert *trustedCert, + PKIX_List *listOfCerts, + PKIX_PL_Cert *targetCert, + PKIX_List *certStores, + PKIX_Boolean testValid, void* plContext) { PKIX_UInt32 numCerts = 0; PKIX_UInt32 i = 0; PKIX_TrustAnchor *anchor = NULL; PKIX_List *anchors = NULL; - PKIX_List *hintCerts = NULL; + PKIX_List *hintCerts = NULL; PKIX_List *revCheckers = NULL; PKIX_List *certs = NULL; PKIX_PL_Cert *cert = NULL; @@ -540,7 +544,7 @@ testWithLeafAndChain( /* create CertSelector with target certificate in params */ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create - (&certSelParams, plContext)); + (&certSelParams, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate (certSelParams, targetCert, plContext)); @@ -554,17 +558,17 @@ testWithLeafAndChain( PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints (procParams, certSelector, plContext)); - /* create hintCerts */ - PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate - ((PKIX_PL_Object *)listOfCerts, - (PKIX_PL_Object **)&hintCerts, - plContext)); + /* create hintCerts */ + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate + ((PKIX_PL_Object *)listOfCerts, + (PKIX_PL_Object **)&hintCerts, + plContext)); - PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem - (hintCerts, 0, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem + (hintCerts, 0, plContext)); - PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts - (procParams, hintCerts, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts + (procParams, hintCerts, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores (procParams, certStores, plContext)); @@ -603,6 +607,7 @@ testWithLeafAndChain( (void **)&pollDesc, &state, &buildResult, + NULL, plContext); while (pollDesc != NULL) { @@ -616,6 +621,7 @@ testWithLeafAndChain( (void **)&pollDesc, &state, &buildResult, + NULL, plContext); } @@ -665,7 +671,7 @@ testWithLeafAndChain( PKIX_TEST_DECREF_BC(cert); } - } + } cleanup: @@ -696,7 +702,7 @@ int main(int argc, char *argv[]) PKIX_UInt32 k = 0; PKIX_Boolean useArenas = PKIX_FALSE; PKIX_Boolean ene = PKIX_TRUE; /* expect no error */ - PKIX_List *listOfCerts = NULL; + PKIX_List *listOfCerts = NULL; PKIX_List *certStores = NULL; PKIX_PL_Cert *dirCert = NULL; PKIX_PL_Cert *trusted = NULL; @@ -773,11 +779,11 @@ int main(int argc, char *argv[]) PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&listOfCerts, plContext)); - for (k = ++j; k < argc; k++) { + for (k = ++j; k < ((PKIX_UInt32)argc); k++) { dirCert = createCert(dirName, argv[k], plContext); - if (k == (argc - 1)) { + if (k == ((PKIX_UInt32)(argc - 1))) { PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef ((PKIX_PL_Object *)dirCert, plContext)); trusted = dirCert; @@ -824,17 +830,17 @@ int main(int argc, char *argv[]) (certStores, (PKIX_PL_Object *)certStore, plContext)); } - subTest("testWithNoLeaf"); - PKIX_TEST_EXPECT_NO_ERROR(testWithNoLeaf - (trusted, listOfCerts, target, certStores, ene, plContext)); + subTest("testWithNoLeaf"); + PKIX_TEST_EXPECT_NO_ERROR(testWithNoLeaf + (trusted, listOfCerts, target, certStores, ene, plContext)); - subTest("testWithDuplicateLeaf"); - PKIX_TEST_EXPECT_NO_ERROR(testWithDuplicateLeaf - (trusted, listOfCerts, target, certStores, ene, plContext)); + subTest("testWithDuplicateLeaf"); + PKIX_TEST_EXPECT_NO_ERROR(testWithDuplicateLeaf + (trusted, listOfCerts, target, certStores, ene, plContext)); - subTest("testWithLeafAndChain"); - PKIX_TEST_EXPECT_NO_ERROR(testWithLeafAndChain - (trusted, listOfCerts, target, certStores, ene, plContext)); + subTest("testWithLeafAndChain"); + PKIX_TEST_EXPECT_NO_ERROR(testWithLeafAndChain + (trusted, listOfCerts, target, certStores, ene, plContext)); cleanup: diff --git a/security/nss/cmd/libpkix/pkix/top/buildchain_resourcelimits/test_buildchain_resourcelimits.c b/security/nss/cmd/libpkix/pkix/top/buildchain_resourcelimits/test_buildchain_resourcelimits.c index 12f87b0f4..e79a2c899 100755 --- a/security/nss/cmd/libpkix/pkix/top/buildchain_resourcelimits/test_buildchain_resourcelimits.c +++ b/security/nss/cmd/libpkix/pkix/top/buildchain_resourcelimits/test_buildchain_resourcelimits.c @@ -137,6 +137,7 @@ static void Test_BuildResult( (void **)&pollDesc, &state, &buildResult, + NULL, plContext); while (pollDesc != NULL) { @@ -150,6 +151,7 @@ static void Test_BuildResult( (void **)&pollDesc, &state, &buildResult, + NULL, plContext); } diff --git a/security/nss/cmd/libpkix/pkix/top/buildchain_uchecker/test_buildchain_uchecker.c b/security/nss/cmd/libpkix/pkix/top/buildchain_uchecker/test_buildchain_uchecker.c index 9f6de6ad2..a489abca8 100755 --- a/security/nss/cmd/libpkix/pkix/top/buildchain_uchecker/test_buildchain_uchecker.c +++ b/security/nss/cmd/libpkix/pkix/top/buildchain_uchecker/test_buildchain_uchecker.c @@ -293,6 +293,7 @@ int main(int argc, char *argv[]) &nbioContext, &buildState, &buildResult, + NULL, plContext); if (testValid == PKIX_TRUE) { /* ENE */ diff --git a/security/nss/cmd/libpkix/sample_apps/build_chain/build_chain.c b/security/nss/cmd/libpkix/sample_apps/build_chain/build_chain.c index c38062034..285c6e7f3 100755 --- a/security/nss/cmd/libpkix/sample_apps/build_chain/build_chain.c +++ b/security/nss/cmd/libpkix/sample_apps/build_chain/build_chain.c @@ -233,6 +233,7 @@ int main(int argc, char *argv[]) &nbioContext, &buildState, &buildResult, + NULL, plContext)); /* diff --git a/security/nss/lib/libpkix/include/pkix.h b/security/nss/lib/libpkix/include/pkix.h index 0de586bec..913acd9c1 100755 --- a/security/nss/lib/libpkix/include/pkix.h +++ b/security/nss/lib/libpkix/include/pkix.h @@ -322,6 +322,11 @@ PKIX_ValidateChain_NB( * If chain building is completed, either successfully or unsuccessfully, NULL * is stored at "pNBIOContext". * + * If "pVerifyTree" is non-NULL, a tree of VerifyNodes is created which + * tracks the results of the building. That is, each node of the tree either + * has a NULL Error component, or it is a leaf node and it contains an Error + * which indicates why the chain building could not proceed on this branch. + * * PARAMETERS: * "params" * Address of ProcessingParams used to build and validate CertChain. @@ -334,6 +339,8 @@ PKIX_ValidateChain_NB( * value previously returned on subsequent calls. * "pResult" * Address where object pointer will be stored. Must be non-NULL. + * "pVerifyTree" + * Address where a VerifyTree is stored, if non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: @@ -349,6 +356,7 @@ PKIX_BuildChain( void **pNBIOContext, void **pState, PKIX_BuildResult **pResult, + PKIX_VerifyNode **pVerifyNode, void *plContext); #ifdef __cplusplus diff --git a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c index f6120d55a..8c3761e9f 100755 --- a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c +++ b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c @@ -112,12 +112,15 @@ cleanup: * FUNCTION: pkix_VerifyNode_AddToChain * DESCRIPTION: * - * Adds the VerifyNode pointed to by "child" to the List of children of - * the VerifyNode pointed to by "parentNode". If "parentNode" had a - * NULL pointer for the List of children, a new List is created containing - * "child". Otherwise "child" is appended to the existing List. The - * parent field in "child" is set to "parent", and the depth field is - * set to one more than the corresponding value in "parent". + * Adds the VerifyNode pointed to by "child", at the appropriate depth, to the + * List of children of the VerifyNode pointed to by "parentNode". The chain of + * VerifyNodes is traversed until a VerifyNode is found at a depth one less + * than that specified in "child". An Error is returned if there is no parent + * at a suitable depth. + * + * If "parentNode" has a NULL pointer for the List of children, a new List is + * created containing "child". Otherwise "child" is appended to the existing + * List. * * Depth, in this context, means distance from the root node, which * is at depth zero. @@ -146,40 +149,39 @@ pkix_VerifyNode_AddToChain( { PKIX_VerifyNode *successor = NULL; PKIX_List *listOfChildren = NULL; - PKIX_UInt32 numChildren = 0; - PKIX_UInt32 parentDepth = 0; + PKIX_UInt32 numChildren = 0; + PKIX_UInt32 parentDepth = 0; PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToChain"); - PKIX_NULLCHECK_TWO(parentNode, child); parentDepth = parentNode->depth; listOfChildren = parentNode->children; if (listOfChildren == NULL) { - if (parentDepth != (child->depth - 1)) { - PKIX_ERROR("Nodes missing from chain"); - } + if (parentDepth != (child->depth - 1)) { + PKIX_ERROR("Nodes missing from chain"); + } PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext), "PKIX_List_Create failed"); - PKIX_CHECK(PKIX_List_AppendItem - (listOfChildren, (PKIX_PL_Object *)child, plContext), - "Could not append child to parent's VerifyNode list"); + PKIX_CHECK(PKIX_List_AppendItem + (listOfChildren, (PKIX_PL_Object *)child, plContext), + "Could not append child to parent's VerifyNode list"); parentNode->children = listOfChildren; } else { - /* get number of children */ - PKIX_CHECK(PKIX_List_GetLength - (listOfChildren, &numChildren, plContext), - "PKIX_List_GetLength failed"); + /* get number of children */ + PKIX_CHECK(PKIX_List_GetLength + (listOfChildren, &numChildren, plContext), + "PKIX_List_GetLength failed"); - if (numChildren != 1) { - PKIX_ERROR("Ambiguous parentage of VerifyNode"); - } + if (numChildren != 1) { + PKIX_ERROR("Ambiguous parentage of VerifyNode"); + } - /* successor = listOfChildren[0] */ + /* successor = listOfChildren[0] */ PKIX_CHECK(PKIX_List_GetItem (listOfChildren, 0, @@ -187,21 +189,150 @@ pkix_VerifyNode_AddToChain( plContext), "PKIX_List_GetItem failed"); - PKIX_CHECK(pkix_VerifyNode_AddToChain - (successor, child, plContext), - "pkix_VerifyNode_AddToChain failed"); - } + PKIX_CHECK(pkix_VerifyNode_AddToChain + (successor, child, plContext), + "pkix_VerifyNode_AddToChain failed"); + } PKIX_CHECK(PKIX_PL_Object_InvalidateCache ((PKIX_PL_Object *)parentNode, plContext), "PKIX_PL_Object_InvalidateCache failed"); cleanup: - PKIX_DECREF(successor); + PKIX_DECREF(successor); PKIX_RETURN(VERIFYNODE); } +/* + * FUNCTION: pkix_VerifyNode_SetDepth + * DESCRIPTION: + * + * The function sets the depth field of each VerifyNode in the List "children" + * to the value given by "depth", and recursively sets the depth of any + * successive generations to the successive values. + * + * PARAMETERS: + * "children" + * The List of VerifyNodes. Must be non-NULL. + * "depth" + * The value of the depth field to be set in members of the 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 Fatal Error if the function fails in an unrecoverable way. + */ +static PKIX_Error * +pkix_VerifyNode_SetDepth(PKIX_List *children, + PKIX_UInt32 depth, + void *plContext) +{ + PKIX_UInt32 numChildren = 0; + PKIX_UInt32 chIx = 0; + PKIX_VerifyNode *child = NULL; + + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_SetDepth"); + PKIX_NULLCHECK_ONE(children); + + PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext), + "PKIX_List_GetLength failed"); + + for (chIx = 0; chIx < numChildren; chIx++) { + PKIX_CHECK(PKIX_List_GetItem + (children, chIx, (PKIX_PL_Object **)&child, plContext), + "PKIX_List_GetItem failed"); + + child->depth = depth; + + if (child->children != NULL) { + PKIX_CHECK(pkix_VerifyNode_SetDepth + (child->children, depth + 1, plContext), + "pkix_VerifyNode_SetDepth failed"); + } + + PKIX_DECREF(child); + } + +cleanup: + + PKIX_DECREF(child); + + PKIX_RETURN(VERIFYNODE); +} + +/* + * FUNCTION: pkix_VerifyNode_AddToTree + * DESCRIPTION: + * + * Adds the VerifyNode pointed to by "child" to the List of children of the + * VerifyNode pointed to by "parentNode". If "parentNode" has a NULL pointer + * for the List of children, a new List is created containing "child". + * Otherwise "child" is appended to the existing List. The depth field of + * "child" is set to one more than the corresponding value in "parent", and + * if the "child" itself has child nodes, their depth fields are updated + * accordingly. + * + * Depth, in this context, means distance from the root node, which + * is at depth zero. + * + * PARAMETERS: + * "parentNode" + * Address of VerifyNode whose List of child VerifyNodes is to be + * created or appended to. Must be non-NULL. + * "child" + * Address of VerifyNode to be added to parentNode's List. Must be + * non-NULL. + * "plContext" + * Platform-specific context pointer. + * THREAD SAFETY: + * Not 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. + */ +PKIX_Error * +pkix_VerifyNode_AddToTree( + PKIX_VerifyNode *parentNode, + PKIX_VerifyNode *child, + void *plContext) +{ + PKIX_List *listOfChildren = NULL; + PKIX_UInt32 numChildren = 0; + PKIX_UInt32 parentDepth = 0; + + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToTree"); + PKIX_NULLCHECK_TWO(parentNode, child); + + parentDepth = parentNode->depth; + listOfChildren = parentNode->children; + if (listOfChildren == NULL) { + + PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext), + "PKIX_List_Create failed"); + + parentNode->children = listOfChildren; + } + + child->depth = parentDepth + 1; + + PKIX_CHECK(PKIX_List_AppendItem + (parentNode->children, (PKIX_PL_Object *)child, plContext), + "Could not append child to parent's VerifyNode list"); + + if (child->children != NULL) { + PKIX_CHECK(pkix_VerifyNode_SetDepth + (child->children, child->depth + 1, plContext), + "pkix_VerifyNode_SetDepth failed"); + } + + +cleanup: + + PKIX_RETURN(VERIFYNODE); +} /* * FUNCTION: pkix_SingleVerifyNode_ToString @@ -235,37 +366,37 @@ pkix_SingleVerifyNode_ToString( PKIX_PL_String *errorString = NULL; PKIX_PL_String *outString = NULL; - PKIX_PL_X500Name *issuerName = NULL; - PKIX_PL_X500Name *subjectName = NULL; - PKIX_PL_String *issuerString = NULL; - PKIX_PL_String *subjectString = NULL; + PKIX_PL_X500Name *issuerName = NULL; + PKIX_PL_X500Name *subjectName = NULL; + PKIX_PL_String *issuerString = NULL; + PKIX_PL_String *subjectString = NULL; PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_ToString"); PKIX_NULLCHECK_THREE(node, pString, node->verifyCert); PKIX_TOSTRING(node->error, &errorString, plContext, - "PKIX_Error_ToString failed"); + "PKIX_Error_ToString failed"); - PKIX_CHECK(PKIX_PL_Cert_GetIssuer - (node->verifyCert, &issuerName, plContext), - "PKIX_PL_Cert_GetIssuer failed"); + PKIX_CHECK(PKIX_PL_Cert_GetIssuer + (node->verifyCert, &issuerName, plContext), + "PKIX_PL_Cert_GetIssuer failed"); - PKIX_TOSTRING(issuerName, &issuerString, plContext, - "PKIX_PL_X500Name_ToString failed"); + PKIX_TOSTRING(issuerName, &issuerString, plContext, + "PKIX_PL_X500Name_ToString failed"); - PKIX_CHECK(PKIX_PL_Cert_GetSubject - (node->verifyCert, &subjectName, plContext), - "PKIX_PL_Cert_GetSubject failed"); + PKIX_CHECK(PKIX_PL_Cert_GetSubject + (node->verifyCert, &subjectName, plContext), + "PKIX_PL_Cert_GetSubject failed"); - PKIX_TOSTRING(subjectName, &subjectString, plContext, - "PKIX_PL_X500Name_ToString failed"); + PKIX_TOSTRING(subjectName, &subjectString, plContext, + "PKIX_PL_X500Name_ToString failed"); - PKIX_CHECK(PKIX_PL_String_Create + PKIX_CHECK(PKIX_PL_String_Create (PKIX_ESCASCII, - "CERT[Issuer:%s, Subject:%s], depth=%d, error=%s", + "CERT[Issuer:%s, Subject:%s], depth=%d, error=%s", 0, - &fmtString, - plContext), + &fmtString, + plContext), "Can't create PKIX_PL_String"); PKIX_CHECK(PKIX_PL_Sprintf @@ -284,10 +415,10 @@ cleanup: PKIX_DECREF(fmtString); PKIX_DECREF(errorString); - PKIX_DECREF(issuerName); - PKIX_DECREF(subjectName); - PKIX_DECREF(issuerString); - PKIX_DECREF(subjectString); + PKIX_DECREF(issuerName); + PKIX_DECREF(subjectName); + PKIX_DECREF(issuerString); + PKIX_DECREF(subjectString); PKIX_RETURN(VERIFYNODE); } @@ -964,104 +1095,42 @@ pkix_VerifyNode_RegisterSelf(void *plContext) PKIX_RETURN(VERIFYNODE); } -#if 0 /* --Public-VerifyNode-Functions----------------------------------- */ /* - * FUNCTION: PKIX_VerifyNode_GetChildren - * (see description of this function in pkix_results.h) - */ -PKIX_Error * -PKIX_VerifyNode_GetChildren( - PKIX_VerifyNode *node, - PKIX_List **pChildren, /* list of PKIX_VerifyNode */ - void *plContext) -{ - PKIX_List *children = NULL; - - PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_GetChildren"); - - PKIX_NULLCHECK_TWO(node, pChildren); - - PKIX_INCREF(node->children); - children = node->children; - - if (!children) { - PKIX_CHECK(PKIX_List_Create(&children, plContext), - "PKIX_List_Create failed"); - } - - PKIX_CHECK(PKIX_List_SetImmutable(children, plContext), - "PKIX_List_SetImmutable failed"); - - *pChildren = children; - -cleanup: - if (PKIX_ERROR_RECEIVED) { - PKIX_DECREF(children); - } - - PKIX_RETURN(VERIFYNODE); -} - -/* - * FUNCTION: PKIX_VerifyNode_GetCert - * (see description of this function in pkix_results.h) - */ -PKIX_Error * -PKIX_VerifyNode_GetCert( - PKIX_VerifyNode *node, - PKIX_PL_Cert **pCert, - void *plContext) -{ - - PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_GetCert"); - - PKIX_NULLCHECK_TWO(node, pCert); - - PKIX_INCREF(node->verifyCert); - *pCert = node->verifyCert; - - PKIX_RETURN(VERIFYNODE); -} - -/* - * FUNCTION: PKIX_VerifyNode_GetError - * (see description of this function in pkix_results.h) - */ -PKIX_Error * -PKIX_VerifyNode_GetError( - PKIX_VerifyNode *node, - PKIX_Error **pError, - void *plContext) -{ - - PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_GetError"); - - PKIX_NULLCHECK_TWO(node, pError); - - *pError = node->error; - - PKIX_RETURN(VERIFYNODE); -} - -/* - * FUNCTION: PKIX_VerifyNode_GetDepth - * (see description of this function in pkix_results.h) + * FUNCTION: PKIX_VerifyNode_SetError + * DESCRIPTION: + * + * This function sets the Error field of the VerifyNode pointed to by "node" + * to contain the Error pointed to by "error". + * + * PARAMETERS: + * "node" + * The address of the VerifyNode to be modified. Must be non-NULL. + * "error" + * The address of the Error to be stored. + * "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. */ PKIX_Error * -pkix_VerifyNode_GetDepth( +pkix_VerifyNode_SetError( PKIX_VerifyNode *node, - PKIX_UInt32 *pDepth, + PKIX_Error *error, void *plContext) { - PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_GetDepth"); + PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_SetError"); - PKIX_NULLCHECK_TWO(node, pDepth); + PKIX_NULLCHECK_TWO(node, error); - *pDepth = node->depth; + PKIX_DECREF(node->error); /* should have been NULL */ + PKIX_INCREF(error); + node->error = error; PKIX_RETURN(VERIFYNODE); } -#endif diff --git a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.h b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.h index 64ab7dd72..e9567a988 100755 --- a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.h +++ b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.h @@ -54,7 +54,6 @@ extern "C" { */ struct PKIX_VerifyNodeStruct { PKIX_PL_Cert *verifyCert; -/* PKIX_VerifyNode *parent; */ PKIX_List *children; /* VerifyNodes */ PKIX_UInt32 depth; PKIX_Error *error; @@ -81,6 +80,18 @@ pkix_VerifyNode_AddToChain( void *plContext); PKIX_Error * +pkix_VerifyNode_AddToTree( + PKIX_VerifyNode *parentNode, + PKIX_VerifyNode *child, + void *plContext); + +PKIX_Error * +pkix_VerifyNode_SetError( + PKIX_VerifyNode *node, + PKIX_Error *error, + void *plContext); + +PKIX_Error * pkix_VerifyNode_RegisterSelf( void *plContext); diff --git a/security/nss/lib/libpkix/pkix/top/pkix_build.c b/security/nss/lib/libpkix/pkix/top/pkix_build.c index 6c490be13..a603eae6b 100755 --- a/security/nss/lib/libpkix/pkix/top/pkix_build.c +++ b/security/nss/lib/libpkix/pkix/top/pkix_build.c @@ -115,6 +115,7 @@ pkix_ForwardBuilderState_Destroy( PKIX_DECREF(state->checkerChain); PKIX_DECREF(state->revCheckers); PKIX_DECREF(state->certSel); + PKIX_DECREF(state->verifyNode); PKIX_DECREF(state->client); /* @@ -260,6 +261,7 @@ pkix_ForwardBuilderState_Create( state->checkerChain = NULL; state->revCheckers = NULL; state->certSel = NULL; + state->verifyNode = NULL; state->client = NULL; PKIX_INCREF(parentState); @@ -395,6 +397,7 @@ pkix_ForwardBuilderState_ToString PKIX_PL_String *trustChainString = NULL; PKIX_PL_String *candidateCertsString = NULL; PKIX_PL_String *certSelString = NULL; + PKIX_PL_String *verifyNodeString = NULL; PKIX_PL_String *parentStateString = NULL; char *asciiFormat = "\n" "\t{buildStatus: \t%s\n" @@ -420,6 +423,7 @@ pkix_ForwardBuilderState_ToString "\ttrustChain: \t%s\n" "\tcandidateCerts: \t%s\n" "\tcertSel: \t%s\n" + "\tverifyNode: \t%s\n" "\tparentState: \t%s}\n"; char *asciiStatus = NULL; @@ -518,6 +522,10 @@ pkix_ForwardBuilderState_ToString "PKIX_PL_Object_ToString failed"); PKIX_TOSTRING + (state->verifyNode, &verifyNodeString, plContext, + "PKIX_PL_Object_ToString failed"); + + PKIX_TOSTRING (state->parentState, &parentStateString, plContext, "PKIX_PL_Object_ToString failed"); @@ -548,6 +556,7 @@ pkix_ForwardBuilderState_ToString trustChainString, candidateCertsString, certSelString, + verifyNodeString, parentStateString), "PKIX_PL_Sprintf failed"); @@ -563,6 +572,7 @@ cleanup: PKIX_DECREF(trustChainString); PKIX_DECREF(candidateCertsString); PKIX_DECREF(certSelString); + PKIX_DECREF(verifyNodeString); PKIX_DECREF(parentStateString); PKIX_RETURN(FORWARDBUILDERSTATE); @@ -718,6 +728,10 @@ pkix_ForwardBuilderState_IsIOPending( * successfully chains, PKIX_TRUE is stored at the address pointed to by * "pPassed". Otherwise PKIX_FALSE is stored. * + * If a non-NULL VerifyNode is supplied, then this function will, in the event + * of a failure, set the Error associated with the failure in the VerifyNode. + * . + * * PARAMETERS: * "candidateCert" * Address of Cert that is being checked. Must be non-NULL. @@ -729,6 +743,8 @@ pkix_ForwardBuilderState_IsIOPending( * Must be non-NULL. * "pPassed" * Address at which Boolean result is stored. Must be non-NULL. + * "verifyNode" + * Address of the VerifyNode to receive the Error. May be NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: @@ -744,6 +760,7 @@ pkix_Build_CheckCertAgainstAnchor( PKIX_TrustAnchor *anchor, PKIX_List *traversedSubjNames, PKIX_Boolean *pPassed, + PKIX_VerifyNode *verifyNode, void *plContext) { PKIX_PL_Cert *trustedCert = NULL; @@ -756,6 +773,8 @@ pkix_Build_CheckCertAgainstAnchor( PKIX_Boolean certMatch = PKIX_TRUE; PKIX_Boolean anchorMatch = PKIX_FALSE; PKIX_PL_PublicKey *trustedPubKey = NULL; + PKIX_VerifyNode *anchorVerifyNode = NULL; + PKIX_Error *verifyError = NULL; PKIX_ENTER(BUILD, "pkix_Build_CheckCertAgainstAnchor"); PKIX_NULLCHECK_THREE(anchor, candidateCert, pPassed); @@ -825,16 +844,58 @@ pkix_Build_CheckCertAgainstAnchor( (trustedCert, &trustedPubKey, plContext), "PKIX_PL_Cert_GetSubjectPublicKey failed"); - PKIX_CHECK_ONLY_FATAL(PKIX_PL_Cert_VerifySignature - (candidateCert, trustedPubKey, plContext), - "PKIX_PL_Cert_VerifySignature failed"); + pkixErrorResult = PKIX_PL_Cert_VerifySignature + (candidateCert, trustedPubKey, plContext); + + if (pkixErrorResult) { + pkixTempResult = PKIX_Error_GetErrorCode + (pkixErrorResult, &pkixErrorCode, plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = + "PKIX_PL_Cert_VerifySignature failed"; + PKIX_RETURN(FATAL); + } + } + +cleanup: - if (!PKIX_ERROR_RECEIVED) { + if (PKIX_ERROR_RECEIVED || !anchorMatch || !certMatch) { + if (verifyNode != NULL) { + if (!anchorMatch) { + PKIX_ERROR_CREATE + (BUILD, + "Anchor did not chain to Cert", + verifyError); + } else if (!certMatch) { + PKIX_ERROR_CREATE + (BUILD, + "Anchor did not pass CertSelector criteria", + verifyError); + } else { + PKIX_INCREF(pkixErrorResult); + verifyError = pkixErrorResult; + } + } + } else { *pPassed = PKIX_TRUE; } -cleanup: + if (verifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_Create + (trustedCert, + 1, + verifyError, + &anchorVerifyNode, + plContext), + "pkix_VerifyNode_Create failed"); + PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree + (verifyNode, anchorVerifyNode, plContext), + "pkix_VerifyNode_AddToTree failed"); + PKIX_DECREF(verifyError); + } + PKIX_DECREF(anchorVerifyNode); PKIX_DECREF(trustedCert); PKIX_DECREF(anchorNC); PKIX_DECREF(certSel); @@ -946,6 +1007,9 @@ cleanup: * by "userCheckers". It then runs the signature validation. Finally, it * determines the appropriate value for "pNeedsCRLChecking". * + * If this Certificate fails verification, and state->verifyNode is non-NULL, + * this function sets the Error code into the verifyNode. + * * PARAMETERS: * "state" * Address of ForwardBuilderState to be used. Must be non-NULL. @@ -976,6 +1040,7 @@ pkix_Build_VerifyCertificate( PKIX_Boolean revocationChecking, PKIX_Boolean *pTrusted, PKIX_Boolean *pNeedsCRLChecking, + PKIX_VerifyNode *verifyNode, void *plContext) { PKIX_UInt32 numUserCheckers = 0; @@ -989,6 +1054,8 @@ pkix_Build_VerifyCertificate( PKIX_PL_PublicKey *candidatePubKey = NULL; PKIX_CertChainChecker *userChecker = NULL; PKIX_CertChainChecker_CheckCallback checkerCheck = NULL; + PKIX_PL_Cert *cert = NULL; + PKIX_Error *verifyError = NULL; void *nbioContext = NULL; PKIX_ENTER(BUILD, "pkix_Build_VerifyCertificate"); @@ -998,16 +1065,8 @@ pkix_Build_VerifyCertificate( *pNeedsCRLChecking = PKIX_FALSE; - PKIX_CHECK(PKIX_List_GetItem - (state->candidateCerts, - state->certIndex, - (PKIX_PL_Object **)&candidateCert, - plContext), - "PKIX_List_GetItem failed"); - - PKIX_DECREF(state->candidateCert); - PKIX_INCREF(candidateCert); - state->candidateCert = candidateCert; + PKIX_INCREF(state->candidateCert); + candidateCert = state->candidateCert; PKIX_CHECK(PKIX_PL_Cert_IsCertTrusted (candidateCert, &trusted, plContext), @@ -1025,8 +1084,20 @@ pkix_Build_VerifyCertificate( "pkix_List_Contains failed"); if (loopFound) { + if (verifyNode != NULL) { + PKIX_ERROR_CREATE + (BUILD, + "Loop discovered: duplicate" + " certificates not allowed", + verifyError); + PKIX_CHECK_FATAL(pkix_VerifyNode_SetError + (verifyNode, verifyError, plContext), + "pkix_VerifyNode_SetError failed"); + PKIX_DECREF(verifyError); + } + /* Even if error logged, still need to abort */ PKIX_ERROR - ("Loop discovered: duplicate certificates not allowed"); + ("Loop discovered: duplicate certificates not allowed"); } if (userCheckers != NULL) { @@ -1057,13 +1128,36 @@ pkix_Build_VerifyCertificate( "PKIX_CertChainChecker_GetCheckCallback " "failed"); - PKIX_CHECK(checkerCheck + pkixErrorResult = checkerCheck (userChecker, candidateCert, NULL, &nbioContext, - plContext), - "checkerCheck failed"); + plContext); + + if (pkixErrorResult) { + pkixTempResult = PKIX_Error_GetErrorCode + (pkixErrorResult, + &pkixErrorCode, + plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = + "userCheckerCheck failed"; + PKIX_RETURN(FATAL); + } else if (verifyNode) { + PKIX_CHECK_FATAL + (pkix_VerifyNode_SetError + (verifyNode, + pkixErrorResult, + plContext), + "pkix_VerifyNode_SetError failed"); + } else { + pkixErrorMsg = + "userCheckerCheck failed"; + } + goto cleanup; + } } PKIX_DECREF(userChecker); @@ -1091,13 +1185,53 @@ pkix_Build_VerifyCertificate( } } - PKIX_CHECK(PKIX_PL_Cert_VerifyKeyUsage - (candidateCert, PKIX_KEY_CERT_SIGN, plContext), - "PKIX_PL_Cert_VerifyKeyUsage failed"); + pkixErrorResult = PKIX_PL_Cert_VerifyKeyUsage + (candidateCert, PKIX_KEY_CERT_SIGN, plContext); + + if (pkixErrorResult) { + pkixTempResult = PKIX_Error_GetErrorCode + (pkixErrorResult, &pkixErrorCode, plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = + "PKIX_PL_Cert_VerifyKeyUsage failed"; + PKIX_RETURN(FATAL); + } else if (verifyNode) { + PKIX_CHECK_FATAL(pkix_VerifyNode_SetError + (verifyNode, pkixErrorResult, plContext), + "pkix_VerifyNode_SetError failed"); + } else { + pkixErrorMsg = + "PKIX_PL_Cert_VerifyKeyUsage failed"; + } + goto cleanup; + } - PKIX_CHECK(PKIX_PL_Cert_VerifySignature - (state->prevCert, candidatePubKey, plContext), - "PKIX_PL_Cert_VerifySignature failed"); + pkixErrorResult = PKIX_PL_Cert_VerifySignature + (state->prevCert, candidatePubKey, plContext); + + if (pkixErrorResult) { + pkixTempResult = PKIX_Error_GetErrorCode + (pkixErrorResult, &pkixErrorCode, plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = + "PKIX_PL_Cert_VerifySignature failed"; + PKIX_RETURN(FATAL); + } else { + pkixErrorMsg = + "PKIX_PL_Cert_VerifySignature failed"; + if (verifyNode) { + PKIX_CHECK_FATAL + (pkix_VerifyNode_SetError + (verifyNode, + pkixErrorResult, + plContext), + "pkix_VerifyNode_SetError failed"); + } + } + goto cleanup; + } if (revocationChecking) { if (!trusted) { @@ -1117,9 +1251,31 @@ pkix_Build_VerifyCertificate( } } - PKIX_CHECK(PKIX_PL_Cert_VerifyKeyUsage - (candidateCert, PKIX_CRL_SIGN, plContext), - "PKIX_PL_Cert_VerifyKeyUsage failed"); + pkixErrorResult = PKIX_PL_Cert_VerifyKeyUsage + (candidateCert, PKIX_KEY_CERT_SIGN, plContext); + + if (pkixErrorResult) { + pkixTempResult = PKIX_Error_GetErrorCode + (pkixErrorResult, + &pkixErrorCode, + plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = + "PKIX_PL_Cert_VerifyKeyUsage failed"; + PKIX_RETURN(FATAL); + } else if (verifyNode) { + PKIX_CHECK_FATAL(pkix_VerifyNode_SetError + (verifyNode, + pkixErrorResult, + plContext), + "pkix_VerifyNode_SetError failed"); + } else { + pkixErrorMsg = + "PKIX_PL_Cert_VerifyKeyUsage failed"; + } + goto cleanup; + } *pNeedsCRLChecking = PKIX_TRUE; } @@ -1396,17 +1552,6 @@ pkix_Build_ValidationCheckers( } } -#if 0 - /* - * This list is obtained here, rather than being put into - * buildConstants, to allow for it to be altered by - * circumstances as yet unknown. - */ - PKIX_CHECK(PKIX_ProcessingParams_GetRevocationCheckers - (procParams, &revCheckers, plContext), - "PKIX_ProcessingParams_GetRevocationCheckers"); -#endif - PKIX_INCREF(reversedCertChain); state->reversedCertChain = reversedCertChain; PKIX_INCREF(buildCheckedCritExtOIDsList); @@ -1483,6 +1628,7 @@ pkix_Build_ValidateEntireChain( PKIX_TrustAnchor *anchor, void **pNBIOContext, PKIX_ValidateResult **pValResult, + PKIX_VerifyNode *verifyNode, void *plContext) { PKIX_UInt32 numChainCerts = 0; @@ -1490,6 +1636,7 @@ pkix_Build_ValidateEntireChain( PKIX_PolicyNode *policyTree = NULL; PKIX_ValidateResult *valResult = NULL; void *nbioContext = PKIX_FALSE; + PKIX_Error *certCheckError = NULL; PKIX_ENTER(BUILD, "pkix_Build_ValidateEntireChain"); PKIX_NULLCHECK_FOUR(state, anchor, pNBIOContext, pValResult); @@ -1500,7 +1647,7 @@ pkix_Build_ValidateEntireChain( (state->reversedCertChain, &numChainCerts, plContext), "PKIX_List_GetLength failed"); - PKIX_CHECK(pkix_CheckChain + certCheckError = pkix_CheckChain (state->reversedCertChain, numChainCerts, state->checkerChain, @@ -1513,15 +1660,33 @@ pkix_Build_ValidateEntireChain( &nbioContext, &subjPubKey, &policyTree, - NULL, - plContext), - "pkix_CheckChain failed"); + NULL, + plContext); if (nbioContext != NULL) { *pNBIOContext = nbioContext; goto cleanup; } + if (certCheckError) { + pkixTempErrorReceived = PKIX_TRUE; + pkixTempResult = PKIX_Error_GetErrorCode + (certCheckError, &pkixErrorCode, plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR){ + pkixErrorMsg = "pkix_CheckChain failed"; + PKIX_RETURN(FATAL); + } + if (verifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_SetError + (verifyNode, certCheckError, plContext), + "pkix_VerifyNode_SetError failed"); + } + pkixErrorResult = certCheckError; + goto cleanup; + } + + if (state->reasonCode != 0) { PKIX_ERROR("Chain rejected by Revocation Checker"); } @@ -2273,6 +2438,9 @@ pkix_BuildForwardDepthFirstSearch( PKIX_ComCertSelParams *certSelParams = NULL; PKIX_TrustAnchor *trustAnchor = NULL; PKIX_PL_Cert *trustedCert = NULL; + PKIX_PL_Cert *cert = NULL; + PKIX_VerifyNode *verifyNode = NULL; + PKIX_Error *verifyError = NULL; void *nbio = NULL; PKIX_ENTER(BUILD, "pkix_BuildForwardDepthFirstSearch"); @@ -2307,6 +2475,19 @@ pkix_BuildForwardDepthFirstSearch( "PKIX_PL_Object_Comparator failed"); if (cmpTimeResult < 0) { + if (state->verifyNode != NULL) { + PKIX_ERROR_CREATE + (BUILD, + "Time consumed exceeds Resource Limits", + verifyError); + PKIX_CHECK_FATAL(pkix_VerifyNode_SetError + (state->verifyNode, + verifyError, + plContext), + "pkix_VerifyNode_SetError failed"); + PKIX_DECREF(verifyError); + } + /* Even if we logged error, we still have to abort */ PKIX_ERROR("Time consumed exceeds Resource Limits"); } } @@ -2399,12 +2580,12 @@ pkix_BuildForwardDepthFirstSearch( "PKIX_PL_Object_ToString failed"); PKIX_CHECK(PKIX_PL_String_GetEncoded - (unString, - PKIX_ESCASCII, - (void **)&unAscii, - &length, - plContext), - "PKIX_PL_String_GetEncoded failed"); + (unString, + PKIX_ESCASCII, + (void **)&unAscii, + &length, + plContext), + "PKIX_PL_String_GetEncoded failed"); PKIX_DEBUG_ARG ("unfilteredCerts = %s\n", unAscii); @@ -2413,6 +2594,7 @@ pkix_BuildForwardDepthFirstSearch( } #endif + /* Note: Certs winnowed here don't get into VerifyTree. */ if (unfilteredCerts) { PKIX_CHECK(pkix_CertSelector_Select (state->certSel, @@ -2476,7 +2658,8 @@ pkix_BuildForwardDepthFirstSearch( (state->status == BUILD_GATHERPENDING)) { #if PKIX_FORWARDBUILDERSTATEDEBUG - PKIX_CHECK(pkix_ForwardBuilderState_DumpState(state, plContext), + PKIX_CHECK(pkix_ForwardBuilderState_DumpState + (state, plContext), "pkix_ForwardBuilderState_DumpState failed"); #endif @@ -2520,16 +2703,55 @@ pkix_BuildForwardDepthFirstSearch( } } - PKIX_CHECK_ONLY_FATAL(pkix_Build_VerifyCertificate + PKIX_DECREF(state->candidateCert); + PKIX_CHECK(PKIX_List_GetItem + (state->candidateCerts, + state->certIndex, + (PKIX_PL_Object **)&(state->candidateCert), + plContext), + "PKIX_List_GetItem failed"); + + if ((state->verifyNode) != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_Create + (state->candidateCert, + 0, + NULL, + &verifyNode, + plContext), + "pkix_VerifyNode_Create failed"); + } + + /* If failure, this function sets Error in verifyNode */ + verifyError = pkix_Build_VerifyCertificate (state, state->buildConstants.userCheckers, revocationCheckingExists, &trusted, &needsCRLChecking, - plContext), - "pkix_Build_VerifyCertificate failed"); + verifyNode, + plContext); + + if (verifyError) { + pkixTempErrorReceived = PKIX_TRUE; + pkixTempResult = PKIX_Error_GetErrorCode + (verifyError, &pkixErrorCode, plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = + "pkix_Build_VerifyCertificate failed"; + PKIX_RETURN(FATAL); + } + } if (PKIX_ERROR_RECEIVED) { + if (state->verifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree + (state->verifyNode, + verifyNode, + plContext), + "pkix_VerifyNode_AddToTree failed"); + PKIX_DECREF(verifyNode); + } state->status = BUILD_GETNEXTCERT; } else if (needsCRLChecking) { state->status = BUILD_CRLPREP; @@ -2568,8 +2790,7 @@ pkix_BuildForwardDepthFirstSearch( plContext), "Object is not a DefaultCRLCheckerState object"); - PKIX_CHECK_ONLY_FATAL - (pkix_DefaultCRLChecker_Check_Helper + verifyError = pkix_DefaultCRLChecker_Check_Helper (state->buildConstants.crlChecker, state->prevCert, candidatePubKey, @@ -2577,8 +2798,18 @@ pkix_BuildForwardDepthFirstSearch( NULL, /* unresolved crit extensions */ state->useOnlyLocal, &nbio, - plContext), - "pkix_DefaultCRLChecker_Check_Helper failed"); + plContext); + if (verifyError) { + pkixTempErrorReceived = PKIX_TRUE; + pkixTempResult = PKIX_Error_GetErrorCode + (verifyError, &pkixErrorCode, plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = + "pkix_DefaultCRLChecker_Check_Helper failed"; + PKIX_RETURN(FATAL); + } + } PKIX_DECREF(candidatePubKey); PKIX_DECREF(crlCheckerState); @@ -2587,6 +2818,18 @@ pkix_BuildForwardDepthFirstSearch( /* IO still pending, resume later */ goto cleanup; } else if (PKIX_ERROR_RECEIVED) { + if (state->verifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_SetError + (verifyNode, verifyError, plContext), + "pkix_VerifyNode_SetError failed"); + PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree + (state->verifyNode, + verifyNode, + plContext), + "pkix_VerifyNode_AddToTree failed"); + PKIX_DECREF(verifyNode); + } + PKIX_DECREF(verifyError); state->status = BUILD_GETNEXTCERT; } else { state->status = BUILD_DATEPREP; @@ -2632,11 +2875,13 @@ pkix_BuildForwardDepthFirstSearch( } if (state->status == BUILD_CHECKTRUSTED2) { - - PKIX_CHECK_ONLY_FATAL - (pkix_Build_ValidateEntireChain - (state, trustAnchor, &nbio, &valResult, plContext), - "pkix_Build_ValidateEntireChain failed"); + PKIX_CHECK_ONLY_FATAL(pkix_Build_ValidateEntireChain + (state, + trustAnchor, + &nbio, &valResult, + verifyNode, + plContext), + "pkix_Build_ValidateEntireChain failed"); if (nbio != NULL) { /* IO still pending, resume later */ @@ -2646,6 +2891,15 @@ pkix_BuildForwardDepthFirstSearch( PKIX_DECREF(state->checkedCritExtOIDs); PKIX_DECREF(state->checkerChain); PKIX_DECREF(state->revCheckers); + if (state->verifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree + (state->verifyNode, + verifyNode, + plContext), + "pkix_VerifyNode_AddToTree failed"); + PKIX_DECREF(verifyNode); + } + if (!PKIX_ERROR_RECEIVED) { *pValResult = valResult; /* Change state so IsIOPending is FALSE */ @@ -2697,12 +2951,17 @@ pkix_BuildForwardDepthFirstSearch( if (state->status == BUILD_CHECKWITHANCHORS) { - /* Does this Trust Anchor chain to this cert? */ + /* + * Does this Trust Anchor chain to this cert? + * (If state->verifyNode is non-NULL, this function + * chains a verifyNode for each anchor checked.) + */ PKIX_CHECK(pkix_Build_CheckCertAgainstAnchor (state->candidateCert, trustAnchor, state->traversedSubjNames, &passed, + verifyNode, plContext), "pkix_CheckCertAgainstAnchor failed"); @@ -2712,8 +2971,7 @@ pkix_BuildForwardDepthFirstSearch( } else { state->status = BUILD_VALCHAIN; } - } - /* else increment anchorIndex and try next anchor */ + } /* else increment anchorIndex and try next */ } if (state->status == BUILD_CRL2PREP) { @@ -2746,8 +3004,7 @@ pkix_BuildForwardDepthFirstSearch( plContext), "Object is not a DefaultCRLCheckerState"); - PKIX_CHECK_ONLY_FATAL - (pkix_DefaultCRLChecker_Check_Helper + verifyError = pkix_DefaultCRLChecker_Check_Helper (state->buildConstants.crlChecker, state->candidateCert, trustedPubKey, @@ -2755,8 +3012,20 @@ pkix_BuildForwardDepthFirstSearch( NULL, /* unresolved crit extensions */ state->useOnlyLocal, &nbio, - plContext), - "pkix_DefaultCRLChecker_Check_Helper failed"); + plContext); + if (verifyError) { + pkixTempErrorReceived = PKIX_TRUE; + pkixTempResult = PKIX_Error_GetErrorCode + (verifyError, + &pkixErrorCode, + plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = "pkix_DefaultCRLChecker" + "_Check_Helper failed"; + PKIX_RETURN(FATAL); + } + } PKIX_DECREF(trustedCert); PKIX_DECREF(trustedPubKey); @@ -2766,6 +3035,16 @@ pkix_BuildForwardDepthFirstSearch( /* IO still pending, resume later */ goto cleanup; } else if (PKIX_ERROR_RECEIVED) { + if (state->verifyNode != NULL) { + PKIX_CHECK_FATAL + (pkix_VerifyNode_SetError + (verifyNode, + verifyError, + plContext), + "pkix_VerifyNode_SetError failed"); + } + PKIX_DECREF(verifyError); + /* try again with the next trust anchor */ state->status = BUILD_CHECKWITHANCHORS; } else { state->status = BUILD_VALCHAIN; @@ -2791,6 +3070,7 @@ pkix_BuildForwardDepthFirstSearch( trustAnchor, &nbio, &valResult, + verifyNode, plContext), "pkix_Build_ValidateEntireChain failed"); @@ -2804,6 +3084,16 @@ pkix_BuildForwardDepthFirstSearch( PKIX_DECREF(state->revCheckers); if (!PKIX_ERROR_RECEIVED) { *pValResult = valResult; + if (state->verifyNode != NULL) { + PKIX_CHECK_FATAL + (pkix_VerifyNode_AddToTree + (state->verifyNode, + verifyNode, + plContext), + "pkix_VerifyNode_AddToTree" + " failed"); + PKIX_DECREF(verifyNode); + } /* Make IsIOPending FALSE */ state->status = BUILD_VALCHAIN; goto cleanup; @@ -2822,7 +3112,23 @@ pkix_BuildForwardDepthFirstSearch( /* Check whether we are allowed to extend the chain */ if ((state->buildConstants.maxDepth != 0) && (state->numDepth <= 1)) { - PKIX_ERROR("Depth would exceed Resource Limits"); + + if (state->verifyNode != NULL) { + PKIX_ERROR_CREATE + (BUILD, + "Depth would exceed Resource Limits", + verifyError); + PKIX_CHECK_FATAL(pkix_VerifyNode_SetError + (verifyNode, verifyError, plContext), + "pkix_VerifyNode_SetError failed"); + PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree + (state->verifyNode, verifyNode, plContext), + "pkix_VerifyNode_AddToTree failed"); + PKIX_DECREF(verifyNode); + PKIX_DECREF(verifyError); + } + /* Even if error logged, still need to abort */ + PKIX_ERROR("Depth would exceed Resource Limits"); } PKIX_CHECK(pkix_IsCertSelfIssued @@ -2894,12 +3200,14 @@ pkix_BuildForwardDepthFirstSearch( PKIX_DECREF(childTraversedSubjNames); PKIX_DECREF(certSelParams); +childState->verifyNode = verifyNode; +verifyNode = NULL; state = childState; /* state->status == BUILD_INITIAL */ continue; /* with while (!outOfOptions) */ } if (state->status == BUILD_GETNEXTCERT) { - + pkixTempErrorReceived = PKIX_FALSE; PKIX_DECREF(state->candidateCert); /* @@ -2922,7 +3230,23 @@ pkix_BuildForwardDepthFirstSearch( if ((state->buildConstants.maxFanout != 0) && (--(state->numFanout) == 0)) { - PKIX_ERROR + + if (state->verifyNode != NULL) { + PKIX_ERROR_CREATE + (BUILD, + "Fanout exceeds" + " Resource Limits", + verifyError); + PKIX_CHECK_FATAL + (pkix_VerifyNode_SetError + (state->verifyNode, + verifyError, + plContext), + "pkix_VerifyNode_SetError failed"); + PKIX_DECREF(verifyError); + } + /* Even if error logged, still need to abort */ + PKIX_ERROR ("Fanout exceeds Resource Limits"); } state->status = BUILD_CERTVALIDATING; @@ -2972,8 +3296,18 @@ pkix_BuildForwardDepthFirstSearch( (state->trustChain, numChained - 1, plContext), "PKIX_List_DeleteItem failed"); parentState = state->parentState; + verifyNode = state->verifyNode; + state->verifyNode = NULL; PKIX_DECREF(state); state = parentState; + if (state->verifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree + (state->verifyNode, + verifyNode, + plContext), + "pkix_VerifyNode_AddToTree failed"); + PKIX_DECREF(verifyNode); + } PKIX_DECREF(validityDate); PKIX_INCREF(state->validityDate); validityDate = state->validityDate; @@ -3005,8 +3339,18 @@ cleanup: if (ioPending == PKIX_FALSE) { while (state->parentState) { parentState = state->parentState; + verifyNode = state->verifyNode; + state->verifyNode = NULL; PKIX_DECREF(state); state = parentState; + if (state->verifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree + (state->verifyNode, + verifyNode, + plContext), + "pkix_VerifyNode_AddToTree failed"); + PKIX_DECREF(verifyNode); + } } state->canBeCached = canBeCached; PKIX_DECREF(state->validityDate); @@ -3080,6 +3424,7 @@ pkix_Build_TryShortcut( PKIX_PL_Cert *trustedCert = NULL; PKIX_PL_PublicKey *trustedPubKey = NULL; PKIX_PL_Object *crlCheckerState = NULL; + PKIX_Error *crlCheckerError = NULL; PKIX_ENTER(BUILD, "pkix_Build_TryShortcut"); PKIX_NULLCHECK_THREE(state, pNBIOContext, pAnchor); @@ -3102,10 +3447,13 @@ pkix_Build_TryShortcut( anchor, targetSubjNames, &passed, + state->verifyNode, plContext), "pkix_CheckCertAgainstAnchor failed"); + if (passed == PKIX_TRUE) { if (state->buildConstants.crlChecker != NULL) { + PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert (anchor, &trustedCert, plContext), "PKIX_TrustAnchor_GetTrustedCert failed"); @@ -3135,8 +3483,8 @@ pkix_Build_TryShortcut( plContext), "pkix_DefaultCRLChecker_Check_SetSelector failed"); - PKIX_CHECK_ONLY_FATAL - (pkix_DefaultCRLChecker_Check_Helper + crlCheckerError = + pkix_DefaultCRLChecker_Check_Helper (state->buildConstants.crlChecker, state->prevCert, trustedPubKey, @@ -3144,8 +3492,21 @@ pkix_Build_TryShortcut( NULL, /* unresolved crit extensions */ PKIX_FALSE, &nbioContext, - plContext), - "pkix_DefaultCRLChecker_Check_Helper failed"); + plContext); + + if (crlCheckerError) { + pkixTempErrorReceived = PKIX_TRUE; + pkixTempResult = PKIX_Error_GetErrorCode + (crlCheckerError, + &pkixErrorCode, + plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = "pkix_DefaultCRL" + "Checker_Check_Helper failed"; + PKIX_RETURN(FATAL); + } + } if (nbioContext != NULL) { state->status = BUILD_SHORTCUTPENDING; @@ -3157,12 +3518,22 @@ pkix_Build_TryShortcut( PKIX_DECREF(trustedPubKey); PKIX_DECREF(crlCheckerState); - if (!PKIX_ERROR_RECEIVED) { - /* Exit loop with anchor set */ - break; - } + } /* if (state->buildConstants.crlChecker != NULL) */ + + if ((state->verifyNode) && (crlCheckerError)) { + PKIX_CHECK_FATAL(pkix_VerifyNode_SetError + (state->verifyNode, + crlCheckerError, + plContext), + "pkix_VerifyNode_SetError failed"); } - } + PKIX_DECREF(crlCheckerError); + if (!PKIX_ERROR_RECEIVED) { + /* Exit loop with anchor set */ + break; + } + + } /* if (passed == PKIX_FALSE) ... else ... */ PKIX_DECREF(trustedPubKey); PKIX_DECREF(anchor); state->anchorIndex++; @@ -3215,6 +3586,8 @@ cleanup: * "pBuildResult" * Address at which the BuildResult is stored, after a successful build. * Must be non-NULL. + * "pVerifyNode" + * Address at which a VerifyNode chain is returned, if non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: @@ -3230,6 +3603,7 @@ pkix_Build_InitiateBuildChain( void **pNBIOContext, PKIX_ForwardBuilderState **pState, PKIX_BuildResult **pBuildResult, + PKIX_VerifyNode **pVerifyNode, void *plContext) { PKIX_UInt32 numAnchors = 0; @@ -3266,6 +3640,7 @@ pkix_Build_InitiateBuildChain( PKIX_ForwardBuilderState *state = NULL; PKIX_CertStore_CheckTrustCallback trustCallback = NULL; PKIX_PL_AIAMgr *aiaMgr = NULL; + PKIX_VerifyNode *verifyNode = NULL; PKIX_ENTER(BUILD, "pkix_Build_InitiateBuildChain"); PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult); @@ -3393,9 +3768,28 @@ pkix_Build_InitiateBuildChain( (targetPubKey, &dsaParamsNeeded, plContext), "PKIX_PL_PublicKey_NeedsDSAParameters failed"); - PKIX_CHECK(PKIX_PL_Cert_CheckValidity - (targetCert, testDate, plContext), - "PKIX_PL_Cert_CheckValidity failed"); + /* Failure here is reportable */ + pkixErrorResult = PKIX_PL_Cert_CheckValidity + (targetCert, testDate, plContext); + if (pkixErrorResult) { + pkixTempResult = PKIX_Error_GetErrorCode + (pkixErrorResult, &pkixErrorCode, plContext); + if (pkixTempResult) return pkixTempResult; + if (pkixErrorCode == PKIX_FATAL_ERROR) { + pkixErrorMsg = "PKIX_PL_Cert_CheckValidity failed"; + PKIX_RETURN(FATAL); + } else if (pVerifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_Create + (targetCert, + 0, + pkixErrorResult, + pVerifyNode, + plContext), + "pkix_VerifyNode_Create failed"); + } + pkixErrorMsg = "PKIX_PL_Cert_CheckValidity failed"; + goto cleanup; + } PKIX_CHECK(pkix_ProcessingParams_GetRevocationEnabled (procParams, &isCrlEnabled, plContext), @@ -3536,7 +3930,17 @@ pkix_Build_InitiateBuildChain( plContext), "PKIX_PL_Date_Create_CurrentOffBySeconds failed"); } - + + if (pVerifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_Create + (targetCert, + 0, + NULL, + &(state->verifyNode), + plContext), + "pkix_VerifyNode_Create failed"); + } + /* Check whether this cert verification has been cached. */ PKIX_CHECK(pkix_CacheCertChain_Lookup (targetCert, @@ -3591,9 +3995,10 @@ pkix_Build_InitiateBuildChain( matchingAnchor, &nbioContext, &valResult, + verifyNode, plContext), "pkix_Build_ValidateEntireChain failed"); - + if (nbioContext != NULL) { /* IO still pending, resume later */ *pNBIOContext = nbioContext; @@ -3603,9 +4008,21 @@ pkix_Build_InitiateBuildChain( PKIX_DECREF(state->checkedCritExtOIDs); PKIX_DECREF(state->checkerChain); PKIX_DECREF(state->revCheckers); + if (state->verifyNode != NULL) { + PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree + (state->verifyNode, + verifyNode, + plContext), + "pkix_VerifyNode_AddToTree failed"); + PKIX_DECREF(verifyNode); + } + if (!PKIX_ERROR_RECEIVED) { /* The result from cache is still valid. */ *pBuildResult = buildResult; + if (pVerifyNode != NULL) { + *pVerifyNode = state->verifyNode; + } goto cleanup; } } @@ -3636,7 +4053,7 @@ pkix_Build_InitiateBuildChain( } /* - * We can avoid the search if this chain, with any of our trust + * We can avoid the search if this cert, with any of our trust * anchors, forms a complete trust chain. */ PKIX_CHECK_ONLY_FATAL(pkix_Build_TryShortcut @@ -3677,19 +4094,29 @@ pkix_Build_InitiateBuildChain( *pBuildResult = NULL; /* no valResult means the build has failed */ - } else if (valResult == NULL) { + } else { + if (pVerifyNode != NULL) { + PKIX_INCREF(state->verifyNode); + *pVerifyNode = state->verifyNode; + } - PKIX_DECREF(state); - *pState = NULL; - PKIX_ERROR("Unable to build chain"); + if (valResult == NULL) { - } else { + PKIX_DECREF(state); + *pState = NULL; + PKIX_ERROR("Unable to build chain"); - PKIX_CHECK(pkix_BuildResult_Create - (valResult, state->trustChain, &buildResult, plContext), - "pkix_BuildResult_Create failed"); + } else { - *pBuildResult = buildResult; + PKIX_CHECK(pkix_BuildResult_Create + (valResult, + state->trustChain, + &buildResult, + plContext), + "pkix_BuildResult_Create failed"); + + *pBuildResult = buildResult; + } } PKIX_INCREF(state); @@ -3759,6 +4186,7 @@ pkix_Build_ResumeBuildChain( void **pNBIOContext, PKIX_ForwardBuilderState **pState, PKIX_BuildResult **pBuildResult, + PKIX_VerifyNode **pVerifyNode, void *plContext) { PKIX_ForwardBuilderState *state = NULL; @@ -3823,6 +4251,7 @@ PKIX_BuildChain( void **pNBIOContext, void **pState, PKIX_BuildResult **pBuildResult, + PKIX_VerifyNode **pVerifyNode, void *plContext) { PKIX_ForwardBuilderState *state = NULL; @@ -3841,6 +4270,7 @@ PKIX_BuildChain( &nbioContext, &state, &buildResult, + pVerifyNode, plContext), "pkix_Build_InitiateBuildChain failed"); } else { @@ -3852,11 +4282,16 @@ PKIX_BuildChain( &nbioContext, &state, &buildResult, + pVerifyNode, plContext), "pkix_Build_InitiateBuildChain failed"); } else { PKIX_CHECK(pkix_Build_ResumeBuildChain - (&nbioContext, &state, &buildResult, plContext), + (&nbioContext, + &state, + &buildResult, + pVerifyNode, + plContext), "pkix_Build_InitiateBuildChain failed"); } } @@ -3874,11 +4309,13 @@ PKIX_BuildChain( } else { /* * If we made a successful chain by combining the target Cert - * with one of the Trust Anchors, we never created a - * ForwardBuilderState. We treat this situation as + * with one of the Trust Anchors, we may have never created a + * validityDate. We treat this situation as * canBeCached = PKIX_FALSE. */ - if ((state != NULL) && (state->canBeCached)) { + if ((state != NULL) && + ((state->validityDate) != NULL) && + (state->canBeCached)) { PKIX_CHECK(pkix_CacheCertChain_Add (state->buildConstants.targetCert, state->buildConstants.anchors, diff --git a/security/nss/lib/libpkix/pkix/top/pkix_build.h b/security/nss/lib/libpkix/pkix/top/pkix_build.h index b59af747b..5077a5057 100755 --- a/security/nss/lib/libpkix/pkix/top/pkix_build.h +++ b/security/nss/lib/libpkix/pkix/top/pkix_build.h @@ -136,6 +136,7 @@ struct PKIX_ForwardBuilderStateStruct{ PKIX_List *checkerChain; PKIX_List *revCheckers; PKIX_CertSelector *certSel; + PKIX_VerifyNode *verifyNode; void *client; /* messageHandler, such as LDAPClient */ PKIX_ForwardBuilderState *parentState; BuildConstants buildConstants; diff --git a/security/nss/lib/libpkix/pkix/top/pkix_validate.c b/security/nss/lib/libpkix/pkix/top/pkix_validate.c index 4d9c92ca8..c82746357 100755 --- a/security/nss/lib/libpkix/pkix/top/pkix_validate.c +++ b/security/nss/lib/libpkix/pkix/top/pkix_validate.c @@ -83,30 +83,30 @@ static PKIX_Error * pkix_AddToVerifyLog( PKIX_PL_Cert *cert, PKIX_UInt32 depth, - PKIX_Error *error, - PKIX_VerifyNode **pVerifyTree, + PKIX_Error *error, + PKIX_VerifyNode **pVerifyTree, void *plContext) { - PKIX_VerifyNode *verifyNode = NULL; + PKIX_VerifyNode *verifyNode = NULL; PKIX_ENTER(VALIDATE, "pkix_AddToVerifyLog"); PKIX_NULLCHECK_ONE(cert); - if (pVerifyTree) { /* nothing to do if no address given for log */ + if (pVerifyTree) { /* nothing to do if no address given for log */ - PKIX_CHECK(pkix_VerifyNode_Create - (cert, depth, error, &verifyNode, plContext), - "pkix_VerifyNode_Create failed"); + PKIX_CHECK(pkix_VerifyNode_Create + (cert, depth, error, &verifyNode, plContext), + "pkix_VerifyNode_Create failed"); - if (depth == 0) { - /* We just created the root node */ - *pVerifyTree = verifyNode; - } else { - PKIX_CHECK(pkix_VerifyNode_AddToChain - (*pVerifyTree, verifyNode, plContext), - "pkix_VerifyNode_AddToChain failed"); - } + if (depth == 0) { + /* We just created the root node */ + *pVerifyTree = verifyNode; + } else { + PKIX_CHECK(pkix_VerifyNode_AddToChain + (*pVerifyTree, verifyNode, plContext), + "pkix_VerifyNode_AddToChain failed"); + } } cleanup: @@ -173,7 +173,7 @@ pkix_CheckCert( PKIX_UInt32 numCheckers; PKIX_UInt32 numUnresCritExtOIDs = 0; PKIX_UInt32 checkerIndex = 0; - PKIX_Error *checkerError = NULL; + PKIX_Error *checkerError = NULL; void *nbioContext = NULL; PKIX_ENTER(VALIDATE, "pkix_CheckCert"); @@ -211,9 +211,9 @@ pkix_CheckCert( &nbioContext, plContext); - if (checkerError) { - goto cleanup; - } + if (checkerError) { + goto cleanup; + } if (nbioContext != NULL) { *pCheckerIndex = checkerIndex; @@ -271,18 +271,18 @@ cleanup: PKIX_DECREF(checker); PKIX_DECREF(unresCritExtOIDs); - if (checkerError) { - PKIX_PL_String *errorDesc = NULL; - void *enc = NULL; - PKIX_UInt32 len = 0; - (void)PKIX_Error_GetDescription - (checkerError, &errorDesc, plContext); - (void)PKIX_PL_String_GetEncoded - (errorDesc, PKIX_ESCASCII, &enc, &len, plContext); - PKIX_LOG_ERROR(enc); - PKIX_DECREF(errorDesc); - return (checkerError); - } + if (checkerError) { + PKIX_PL_String *errorDesc = NULL; + void *enc = NULL; + PKIX_UInt32 len = 0; + (void)PKIX_Error_GetDescription + (checkerError, &errorDesc, plContext); + (void)PKIX_PL_String_GetEncoded + (errorDesc, PKIX_ESCASCII, &enc, &len, plContext); + PKIX_LOG_ERROR(enc); + PKIX_DECREF(errorDesc); + return (checkerError); + } PKIX_RETURN(VALIDATE); @@ -887,13 +887,13 @@ pkix_CheckChain( void **pNBIOContext, PKIX_PL_PublicKey **pFinalSubjPubKey, PKIX_PolicyNode **pPolicyTree, - PKIX_VerifyNode **pVerifyTree, + PKIX_VerifyNode **pVerifyTree, void *plContext) { PKIX_UInt32 j = 0; PKIX_UInt32 reasonCode = 0; PKIX_Boolean revChecking = PKIX_FALSE; - PKIX_Error *checkCertError = NULL; + PKIX_Error *checkCertError = NULL; void *nbioContext = NULL; PKIX_PL_Cert *cert = NULL; @@ -966,8 +966,8 @@ pkix_CheckChain( *pCheckerIndex = 0; } - PKIX_CHECK(pkix_AddToVerifyLog(cert, j, NULL, pVerifyTree, plContext), - "pkix_AddToVerifyLog failed"); + PKIX_CHECK(pkix_AddToVerifyLog(cert, j, NULL, pVerifyTree, plContext), + "pkix_AddToVerifyLog failed"); PKIX_DECREF(cert); } @@ -980,16 +980,16 @@ pkix_CheckChain( cleanup: - if (PKIX_ERROR_RECEIVED) { - PKIX_INCREF(pkixErrorResult); - checkCertError = pkixErrorResult; - } + if (PKIX_ERROR_RECEIVED) { + PKIX_INCREF(pkixErrorResult); + checkCertError = pkixErrorResult; + } - if (checkCertError) { - pkixTempResult = pkix_AddToVerifyLog - (cert, j, checkCertError, pVerifyTree, plContext); - pkixErrorResult = checkCertError; - } + if (checkCertError) { + pkixTempResult = pkix_AddToVerifyLog + (cert, j, checkCertError, pVerifyTree, plContext); + pkixErrorResult = checkCertError; + } PKIX_DECREF(cert); @@ -1080,7 +1080,7 @@ PKIX_Error * PKIX_ValidateChain( PKIX_ValidateParams *valParams, PKIX_ValidateResult **pResult, - PKIX_VerifyNode **pVerifyTree, + PKIX_VerifyNode **pVerifyTree, void *plContext) { PKIX_Error *chainFailed = NULL; @@ -1218,7 +1218,7 @@ PKIX_ValidateChain( &nbioContext, &finalPubKey, &validPolicyTree, - pVerifyTree, + pVerifyTree, plContext); if (chainFailed || (reasonCode != 0)) { @@ -1375,7 +1375,7 @@ PKIX_ValidateChain_NB( PKIX_List **pCheckers, void **pNBIOContext, PKIX_ValidateResult **pResult, - PKIX_VerifyNode **pVerifyTree, + PKIX_VerifyNode **pVerifyTree, void *plContext) { PKIX_UInt32 numCerts = 0; @@ -1484,7 +1484,7 @@ PKIX_ValidateChain_NB( &nbioContext, &finalPubKey, &validPolicyTree, - pVerifyTree, + pVerifyTree, plContext); if (nbioContext != NULL) { diff --git a/security/nss/lib/libpkix/pkix/top/pkix_validate.h b/security/nss/lib/libpkix/pkix/top/pkix_validate.h index 78c5858c2..4eec3b955 100755 --- a/security/nss/lib/libpkix/pkix/top/pkix_validate.h +++ b/security/nss/lib/libpkix/pkix/top/pkix_validate.h @@ -63,24 +63,9 @@ pkix_CheckChain( void **pNBIOContext, PKIX_PL_PublicKey **pFinalSubjPubKey, PKIX_PolicyNode **pPolicyTree, - PKIX_VerifyNode **pVerifyTree, + PKIX_VerifyNode **pVerifyTree, void *plContext); -#if 0 -PKIX_Error * -PKIX_ValidateChain_NB( - PKIX_ValidateParams *valParams, - PKIX_UInt32 *pCertIndex, - PKIX_UInt32 *pAnchorIndex, - PKIX_UInt32 *pCheckerIndex, - PKIX_Boolean *pRevChecking, - PKIX_List **pCheckers, - void **pNBIOContext, - PKIX_ValidateResult **pResult, - PKIX_VerifyNode **pVerifyTree, - void *plContext); -#endif - #ifdef __cplusplus } #endif diff --git a/security/nss/lib/libpkix/pkix/util/pkix_tools.h b/security/nss/lib/libpkix/pkix/util/pkix_tools.h index 7ab855a7b..8612b6a20 100755 --- a/security/nss/lib/libpkix/pkix/util/pkix_tools.h +++ b/security/nss/lib/libpkix/pkix/util/pkix_tools.h @@ -194,8 +194,8 @@ extern "C" { #define PKIX_CHECK_FATAL(func, desc) \ do { \ - pkixErrorResult = (func); \ - if (pkixErrorResult) { \ + pkixTempResult = (func); \ + if (pkixTempResult) { \ PKIX_ERROR_FATAL(desc); \ } \ } while (0) @@ -325,6 +325,15 @@ extern "C" { else return (pkixReturnResult); \ } +#define PKIX_ERROR_CREATE(type, desc, error) \ + { \ + pkixTempResult = (PKIX_Error*)pkix_Throw \ + (PKIX_ ## type ## _ERROR, myFuncName, (desc), \ + NULL, &error, plContext); \ + if (pkixTempResult) error = pkixTempResult; \ + } + + #define PKIX_ERROR_RECEIVED (pkixErrorReceived || pkixErrorResult ||\ pkixTempErrorReceived) |