From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../nss/cmd/libpkix/pkix/top/test_policychecker.c | 535 +++++++++++++++++++++ 1 file changed, 535 insertions(+) create mode 100644 security/nss/cmd/libpkix/pkix/top/test_policychecker.c (limited to 'security/nss/cmd/libpkix/pkix/top/test_policychecker.c') diff --git a/security/nss/cmd/libpkix/pkix/top/test_policychecker.c b/security/nss/cmd/libpkix/pkix/top/test_policychecker.c new file mode 100644 index 0000000000..1318f13ba6 --- /dev/null +++ b/security/nss/cmd/libpkix/pkix/top/test_policychecker.c @@ -0,0 +1,535 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* + * test_policychecker.c + * + * Test Policy Checking + * + */ + +#include "testutil.h" +#include "testutil_nss.h" + +#define PKIX_TEST_MAX_CERTS 10 + +static void *plContext = NULL; + +static void +printUsage(char *testname) +{ + char *fmt = + "USAGE: %s testname" + " [ENE|EE] \"{OID[:OID]*}\" [A|E|P] cert [cert]*\n" + "(The quotes are needed around the OID argument for dbx.)\n" + "(The optional arg A indicates initialAnyPolicyInhibit.)\n" + "(The optional arg E indicates initialExplicitPolicy.)\n" + "(The optional arg P indicates initialPolicyMappingInhibit.)\n"; + printf(fmt, testname); +} + +static void +printUsageMax(PKIX_UInt32 numCerts) +{ + printf("\nUSAGE ERROR: number of certs %d exceed maximum %d\n", + numCerts, PKIX_TEST_MAX_CERTS); +} + +static PKIX_List * +policySetParse(char *policyString) +{ + char *p = NULL; + char *oid = NULL; + char c = '\0'; + PKIX_Boolean validString = PKIX_FALSE; + PKIX_PL_OID *plOID = NULL; + PKIX_List *policySet = NULL; + + PKIX_TEST_STD_VARS(); + + p = policyString; + + /* + * There may or may not be quotes around the initial-policy-set + * string. If they are omitted, dbx will strip off the curly braces. + * If they are included, dbx will strip off the quotes, but if you + * are running directly from a script, without dbx, the quotes will + * not be stripped. We need to be able to handle both cases. + */ + if (*p == '"') { + p++; + } + + if ('{' != *p++) { + return (NULL); + } + oid = p; + + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&policySet, plContext)); + + /* scan to the end of policyString */ + while (!validString) { + /* scan to the end of the current OID string */ + c = *oid; + while ((c != '\0') && (c != ':') && (c != '}')) { + c = *++oid; + } + + if ((c != ':') || (c != '}')) { + *oid = '\0'; /* store a null terminator */ + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(p, &plOID, plContext)); + + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(policySet, + (PKIX_PL_Object *)plOID, + plContext)); + + PKIX_TEST_DECREF_BC(plOID); + plOID = NULL; + if (c == '}') { + /* + * Any exit but this one means + * we were given a badly-formed string. + */ + validString = PKIX_TRUE; + } + p = ++oid; + } + } + +cleanup: + if (!validString) { + PKIX_TEST_DECREF_AC(plOID); + PKIX_TEST_DECREF_AC(policySet); + policySet = NULL; + } + + PKIX_TEST_RETURN(); + + return (policySet); +} + +/* + * FUNCTION: treeToStringHelper + * This function obtains the string representation of a PolicyNode + * Tree and compares it to the expected value. + * PARAMETERS: + * "parent" - a PolicyNode, the root of a PolicyNodeTree; + * must be non-NULL. + * "expected" - the desired string. + * THREAD SAFETY: + * Thread Safe + * + * Multiple threads can safely call this function without worrying + * about conflicts, even if they're operating on the same object. + * RETURNS: + * Nothing. + */ +static void +treeToStringHelper(PKIX_PolicyNode *parent, char *expected) +{ + PKIX_PL_String *stringRep = NULL; + char *actual = NULL; + PKIX_TEST_STD_VARS(); + + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)parent, &stringRep, plContext)); + + actual = PKIX_String2ASCII(stringRep, plContext); + if (actual == NULL) { + pkixTestErrorMsg = "PKIX_String2ASCII Failed"; + goto cleanup; + } + + if (PL_strcmp(actual, expected) != 0) { + testError("unexpected mismatch"); + (void)printf("Actual value:\t%s\n", actual); + (void)printf("Expected value:\t%s\n", expected); + } + +cleanup: + + PKIX_PL_Free(actual, plContext); + + PKIX_TEST_DECREF_AC(stringRep); + + PKIX_TEST_RETURN(); +} + +static void +testPass(char *dirName, char *goodInput, char *diffInput, char *dateAscii) +{ + + PKIX_List *chain = NULL; + PKIX_ValidateParams *valParams = NULL; + PKIX_ValidateResult *valResult = NULL; + + PKIX_TEST_STD_VARS(); + + subTest("Basic-Common-Fields "); + /* + * Tests the Expiration, NameChaining, and Signature Checkers + */ + + chain = createCertChain(dirName, goodInput, diffInput, plContext); + + valParams = createValidateParams(dirName, + goodInput, + diffInput, + dateAscii, + NULL, + PKIX_FALSE, + PKIX_FALSE, + PKIX_FALSE, + PKIX_FALSE, + chain, + plContext); + + PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext)); + +cleanup: + + PKIX_TEST_DECREF_AC(chain); + PKIX_TEST_DECREF_AC(valParams); + PKIX_TEST_DECREF_AC(valResult); + + PKIX_TEST_RETURN(); +} + +static void +testNistTest1(char *dirName) +{ +#define PKIX_TEST_NUM_CERTS 2 + char *trustAnchor = + "TrustAnchorRootCertificate.crt"; + char *intermediateCert = + "GoodCACert.crt"; + char *endEntityCert = + "ValidCertificatePathTest1EE.crt"; + char *certNames[PKIX_TEST_NUM_CERTS]; + char *asciiAnyPolicy = "2.5.29.32.0"; + PKIX_PL_Cert *certs[PKIX_TEST_NUM_CERTS] = { NULL, NULL }; + + PKIX_ValidateParams *valParams = NULL; + PKIX_ValidateResult *valResult = NULL; + PKIX_List *chain = NULL; + PKIX_PL_OID *anyPolicyOID = NULL; + PKIX_List *initialPolicies = NULL; + char *anchorName = NULL; + + PKIX_TEST_STD_VARS(); + + subTest("testNistTest1: Creating the cert chain"); + /* + * Create a chain, but don't include the first certName. + * That's the anchor, and is supplied separately from + * the chain. + */ + certNames[0] = intermediateCert; + certNames[1] = endEntityCert; + chain = createCertChainPlus(dirName, certNames, certs, PKIX_TEST_NUM_CERTS, plContext); + + subTest("testNistTest1: Creating the Validate Parameters"); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(asciiAnyPolicy, &anyPolicyOID, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&initialPolicies, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(initialPolicies, (PKIX_PL_Object *)anyPolicyOID, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable(initialPolicies, plContext)); + + valParams = createValidateParams(dirName, + trustAnchor, + NULL, + NULL, + initialPolicies, + PKIX_FALSE, + PKIX_FALSE, + PKIX_FALSE, + PKIX_FALSE, + chain, + plContext); + + subTest("testNistTest1: Validating the chain"); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext)); + +cleanup: + + PKIX_PL_Free(anchorName, plContext); + + PKIX_TEST_DECREF_AC(anyPolicyOID); + PKIX_TEST_DECREF_AC(initialPolicies); + PKIX_TEST_DECREF_AC(valParams); + PKIX_TEST_DECREF_AC(valResult); + PKIX_TEST_DECREF_AC(chain); + + PKIX_TEST_RETURN(); +} + +static void +testNistTest2(char *dirName) +{ +#define PKIX_TEST_NUM_CERTS 2 + char *trustAnchor = + "TrustAnchorRootCertificate.crt"; + char *intermediateCert = + "GoodCACert.crt"; + char *endEntityCert = + "ValidCertificatePathTest1EE.crt"; + char *certNames[PKIX_TEST_NUM_CERTS]; + char *asciiNist1Policy = "2.16.840.1.101.3.2.1.48.1"; + PKIX_PL_Cert *certs[PKIX_TEST_NUM_CERTS] = { NULL, NULL }; + + PKIX_ValidateParams *valParams = NULL; + PKIX_ValidateResult *valResult = NULL; + PKIX_List *chain = NULL; + PKIX_PL_OID *Nist1PolicyOID = NULL; + PKIX_List *initialPolicies = NULL; + char *anchorName = NULL; + + PKIX_TEST_STD_VARS(); + + subTest("testNistTest2: Creating the cert chain"); + /* + * Create a chain, but don't include the first certName. + * That's the anchor, and is supplied separately from + * the chain. + */ + certNames[0] = intermediateCert; + certNames[1] = endEntityCert; + chain = createCertChainPlus(dirName, certNames, certs, PKIX_TEST_NUM_CERTS, plContext); + + subTest("testNistTest2: Creating the Validate Parameters"); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(asciiNist1Policy, &Nist1PolicyOID, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&initialPolicies, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(initialPolicies, (PKIX_PL_Object *)Nist1PolicyOID, plContext)); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable(initialPolicies, plContext)); + + valParams = createValidateParams(dirName, + trustAnchor, + NULL, + NULL, + initialPolicies, + PKIX_FALSE, + PKIX_FALSE, + PKIX_FALSE, + PKIX_FALSE, + chain, + plContext); + + subTest("testNistTest2: Validating the chain"); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext)); + +cleanup: + + PKIX_PL_Free(anchorName, plContext); + + PKIX_TEST_DECREF_AC(Nist1PolicyOID); + PKIX_TEST_DECREF_AC(initialPolicies); + PKIX_TEST_DECREF_AC(valParams); + PKIX_TEST_DECREF_AC(valResult); + PKIX_TEST_DECREF_AC(chain); + + PKIX_TEST_RETURN(); +} + +static void +printValidPolicyTree(PKIX_ValidateResult *valResult) +{ + PKIX_PolicyNode *validPolicyTree = NULL; + PKIX_PL_String *treeString = NULL; + + PKIX_TEST_STD_VARS(); + PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetPolicyTree(valResult, &validPolicyTree, plContext)); + if (validPolicyTree) { + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)validPolicyTree, + &treeString, + plContext)); + (void)printf("validPolicyTree is\n\t%s\n", + treeString->escAsciiString); + } else { + (void)printf("validPolicyTree is NULL\n"); + } + +cleanup: + + PKIX_TEST_DECREF_AC(validPolicyTree); + PKIX_TEST_DECREF_AC(treeString); + + PKIX_TEST_RETURN(); +} + +int +test_policychecker(int argc, char *argv[]) +{ + + PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE; + PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE; + PKIX_Boolean initialExplicitPolicy = PKIX_FALSE; + PKIX_Boolean expectedResult = PKIX_FALSE; + PKIX_UInt32 chainLength = 0; + PKIX_UInt32 initArgs = 0; + PKIX_UInt32 firstCert = 0; + PKIX_UInt32 i = 0; + PKIX_Int32 j = 0; + PKIX_UInt32 actualMinorVersion; + PKIX_ProcessingParams *procParams = NULL; + char *firstTrustAnchor = "yassir2yassir"; + char *secondTrustAnchor = "yassir2bcn"; + char *dateAscii = "991201000000Z"; + PKIX_ValidateParams *valParams = NULL; + PKIX_ValidateResult *valResult = NULL; + PKIX_List *userInitialPolicySet = NULL; /* List of PKIX_PL_OID */ + char *certNames[PKIX_TEST_MAX_CERTS]; + PKIX_PL_Cert *certs[PKIX_TEST_MAX_CERTS]; + PKIX_List *chain = NULL; + PKIX_Error *validationError = NULL; + PKIX_VerifyNode *verifyTree = NULL; + PKIX_PL_String *verifyString = NULL; + char *dirName = NULL; + char *dataCentralDir = NULL; + char *anchorName = NULL; + + PKIX_TEST_STD_VARS(); + + PKIX_TEST_EXPECT_NO_ERROR( + PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext)); + + /* + * Perform hard-coded tests if no command line args. + * If command line args are provided, they must be: + * arg[1]: test name + * arg[2]: "ENE" or "EE", for "expect no error" or "expect error" + * arg[3]: directory for certificates + * arg[4]: user-initial-policy-set, consisting of braces + * containing zero or more OID sequences, separated by commas + * arg[5]: (optional) "E", indicating initialExplicitPolicy + * arg[firstCert]: the path and filename of the trust anchor certificate + * arg[firstCert+1..(n-1)]: successive certificates in the chain + * arg[n]: the end entity certificate + * + * Example: test_policychecker test1EE ENE + * {2.5.29.32.0,2.5.29.32.3.6} Anchor CA EndEntity + */ + + dirName = argv[3 + j]; + dataCentralDir = argv[4 + j]; + + if (argc <= 5 || ((6 == argc) && (j))) { + + testPass(dataCentralDir, + firstTrustAnchor, + secondTrustAnchor, + dateAscii); + + testNistTest1(dirName); + + testNistTest2(dirName); + + goto cleanup; + } + + if (argc < (7 + j)) { + printUsage(argv[0]); + pkixTestErrorMsg = "Invalid command line arguments."; + goto cleanup; + } + + if (PORT_Strcmp(argv[2 + j], "ENE") == 0) { + expectedResult = PKIX_TRUE; + } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) { + expectedResult = PKIX_FALSE; + } else { + printUsage(argv[0]); + pkixTestErrorMsg = "Invalid command line arguments."; + goto cleanup; + } + + userInitialPolicySet = policySetParse(argv[5 + j]); + if (!userInitialPolicySet) { + printUsage(argv[0]); + pkixTestErrorMsg = "Invalid command line arguments."; + goto cleanup; + } + + for (initArgs = 0; initArgs < 3; initArgs++) { + if (PORT_Strcmp(argv[6 + j + initArgs], "A") == 0) { + initialAnyPolicyInhibit = PKIX_TRUE; + } else if (PORT_Strcmp(argv[6 + j + initArgs], "E") == 0) { + initialExplicitPolicy = PKIX_TRUE; + } else if (PORT_Strcmp(argv[6 + j + initArgs], "P") == 0) { + initialPolicyMappingInhibit = PKIX_TRUE; + } else { + break; + } + } + + firstCert = initArgs + j + 6; + chainLength = argc - (firstCert + 1); + if (chainLength > PKIX_TEST_MAX_CERTS) { + printUsageMax(chainLength); + pkixTestErrorMsg = "Invalid command line arguments."; + goto cleanup; + } + + /* + * Create a chain, but don't include the first certName. + * That's the anchor, and is supplied separately from + * the chain. + */ + for (i = 0; i < chainLength; i++) { + + certNames[i] = argv[i + (firstCert + 1)]; + certs[i] = NULL; + } + chain = createCertChainPlus(dirName, certNames, certs, chainLength, plContext); + + subTest(argv[1 + j]); + + valParams = createValidateParams(dirName, + argv[firstCert], + NULL, + NULL, + userInitialPolicySet, + initialPolicyMappingInhibit, + initialAnyPolicyInhibit, + initialExplicitPolicy, + PKIX_FALSE, + chain, + plContext); + + if (expectedResult == PKIX_TRUE) { + subTest(" (expecting successful validation)"); + + PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext)); + + printValidPolicyTree(valResult); + + } else { + subTest(" (expecting validation to fail)"); + validationError = PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext); + if (!validationError) { + printValidPolicyTree(valResult); + pkixTestErrorMsg = "Should have thrown an error here."; + } + PKIX_TEST_DECREF_BC(validationError); + } + + PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext)); + (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString); + +cleanup: + + PKIX_PL_Free(anchorName, plContext); + + PKIX_TEST_DECREF_AC(verifyString); + PKIX_TEST_DECREF_AC(verifyTree); + PKIX_TEST_DECREF_AC(userInitialPolicySet); + PKIX_TEST_DECREF_AC(chain); + PKIX_TEST_DECREF_AC(valParams); + PKIX_TEST_DECREF_AC(valResult); + PKIX_TEST_DECREF_AC(validationError); + + PKIX_Shutdown(plContext); + + PKIX_TEST_RETURN(); + + endTests("PolicyChecker"); + + return (0); +} -- cgit v1.2.3