summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrichard.freedman%sun.com <devnull@localhost>2006-06-12 20:24:13 +0000
committerrichard.freedman%sun.com <devnull@localhost>2006-06-12 20:24:13 +0000
commit585d233fe7bd7ab68d0da78b3547e5432bebdcfa (patch)
tree7d03c0fc77a66281afcc4b71e1cf709a4c6b5fc4
parentaaecdffd2b56eec8b1d88428fec69bf84f2bda4f (diff)
downloadnss-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).
-rwxr-xr-xsecurity/nss/cmd/libpkix/pkix/top/buildchain/test_buildchain.c41
-rw-r--r--security/nss/cmd/libpkix/pkix/top/buildchain_partialchain/test_buildchain_partialchain.c124
-rwxr-xr-xsecurity/nss/cmd/libpkix/pkix/top/buildchain_resourcelimits/test_buildchain_resourcelimits.c2
-rwxr-xr-xsecurity/nss/cmd/libpkix/pkix/top/buildchain_uchecker/test_buildchain_uchecker.c1
-rwxr-xr-xsecurity/nss/cmd/libpkix/sample_apps/build_chain/build_chain.c1
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix.h8
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_verifynode.c345
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_verifynode.h13
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_build.c637
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_build.h1
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_validate.c96
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_validate.h17
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/pkix_tools.h13
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)