tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_policychecker.c (16932B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 /*
      5 * test_policychecker.c
      6 *
      7 * Test Policy Checking
      8 *
      9 */
     10 
     11 #include "testutil.h"
     12 #include "testutil_nss.h"
     13 
     14 #define PKIX_TEST_MAX_CERTS 10
     15 
     16 static void *plContext = NULL;
     17 
     18 static void
     19 printUsage(char *testname)
     20 {
     21    char *fmt =
     22        "USAGE: %s testname"
     23        " [ENE|EE] \"{OID[:OID]*}\" [A|E|P] cert [cert]*\n"
     24        "(The quotes are needed around the OID argument for dbx.)\n"
     25        "(The optional arg A indicates initialAnyPolicyInhibit.)\n"
     26        "(The optional arg E indicates initialExplicitPolicy.)\n"
     27        "(The optional arg P indicates initialPolicyMappingInhibit.)\n";
     28    printf(fmt, testname);
     29 }
     30 
     31 static void
     32 printUsageMax(PKIX_UInt32 numCerts)
     33 {
     34    printf("\nUSAGE ERROR: number of certs %d exceed maximum %d\n",
     35           numCerts, PKIX_TEST_MAX_CERTS);
     36 }
     37 
     38 static PKIX_List *
     39 policySetParse(char *policyString)
     40 {
     41    char *p = NULL;
     42    char *oid = NULL;
     43    char c = '\0';
     44    PKIX_Boolean validString = PKIX_FALSE;
     45    PKIX_PL_OID *plOID = NULL;
     46    PKIX_List *policySet = NULL;
     47 
     48    PKIX_TEST_STD_VARS();
     49 
     50    p = policyString;
     51 
     52    /*
     53     * There may or may not be quotes around the initial-policy-set
     54     * string. If they are omitted, dbx will strip off the curly braces.
     55     * If they are included, dbx will strip off the quotes, but if you
     56     * are running directly from a script, without dbx, the quotes will
     57     * not be stripped. We need to be able to handle both cases.
     58     */
     59    if (*p == '"') {
     60        p++;
     61    }
     62 
     63    if ('{' != *p++) {
     64        return (NULL);
     65    }
     66    oid = p;
     67 
     68    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&policySet, plContext));
     69 
     70    /* scan to the end of policyString */
     71    while (!validString) {
     72        /* scan to the end of the current OID string */
     73        c = *oid;
     74        while ((c != '\0') && (c != ':') && (c != '}')) {
     75            c = *++oid;
     76        }
     77 
     78        if ((c != ':') || (c != '}')) {
     79            *oid = '\0'; /* store a null terminator */
     80            PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(p, &plOID, plContext));
     81 
     82            PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(policySet,
     83                                                           (PKIX_PL_Object *)plOID,
     84                                                           plContext));
     85 
     86            PKIX_TEST_DECREF_BC(plOID);
     87            plOID = NULL;
     88            if (c == '}') {
     89                /*
     90                 * Any exit but this one means
     91                 * we were given a badly-formed string.
     92                 */
     93                validString = PKIX_TRUE;
     94            }
     95            p = ++oid;
     96        }
     97    }
     98 
     99 cleanup:
    100    if (!validString) {
    101        PKIX_TEST_DECREF_AC(plOID);
    102        PKIX_TEST_DECREF_AC(policySet);
    103        policySet = NULL;
    104    }
    105 
    106    PKIX_TEST_RETURN();
    107 
    108    return (policySet);
    109 }
    110 
    111 /*
    112 * FUNCTION: treeToStringHelper
    113 *  This function obtains the string representation of a PolicyNode
    114 *  Tree and compares it to the expected value.
    115 * PARAMETERS:
    116 *  "parent" - a PolicyNode, the root of a PolicyNodeTree;
    117 *      must be non-NULL.
    118 *  "expected" - the desired string.
    119 * THREAD SAFETY:
    120 *  Thread Safe
    121 *
    122 *  Multiple threads can safely call this function without worrying
    123 *  about conflicts, even if they're operating on the same object.
    124 * RETURNS:
    125 *  Nothing.
    126 */
    127 static void
    128 treeToStringHelper(PKIX_PolicyNode *parent, char *expected)
    129 {
    130    PKIX_PL_String *stringRep = NULL;
    131    char *actual = NULL;
    132    PKIX_TEST_STD_VARS();
    133 
    134    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)parent, &stringRep, plContext));
    135 
    136    actual = PKIX_String2ASCII(stringRep, plContext);
    137    if (actual == NULL) {
    138        pkixTestErrorMsg = "PKIX_String2ASCII Failed";
    139        goto cleanup;
    140    }
    141 
    142    if (PL_strcmp(actual, expected) != 0) {
    143        testError("unexpected mismatch");
    144        (void)printf("Actual value:\t%s\n", actual);
    145        (void)printf("Expected value:\t%s\n", expected);
    146    }
    147 
    148 cleanup:
    149 
    150    PKIX_PL_Free(actual, plContext);
    151 
    152    PKIX_TEST_DECREF_AC(stringRep);
    153 
    154    PKIX_TEST_RETURN();
    155 }
    156 
    157 static void
    158 testPass(char *dirName, char *goodInput, char *diffInput, char *dateAscii)
    159 {
    160 
    161    PKIX_List *chain = NULL;
    162    PKIX_ValidateParams *valParams = NULL;
    163    PKIX_ValidateResult *valResult = NULL;
    164 
    165    PKIX_TEST_STD_VARS();
    166 
    167    subTest("Basic-Common-Fields <pass>");
    168    /*
    169     * Tests the Expiration, NameChaining, and Signature Checkers
    170     */
    171 
    172    chain = createCertChain(dirName, goodInput, diffInput, plContext);
    173 
    174    valParams = createValidateParams(dirName,
    175                                     goodInput,
    176                                     diffInput,
    177                                     dateAscii,
    178                                     NULL,
    179                                     PKIX_FALSE,
    180                                     PKIX_FALSE,
    181                                     PKIX_FALSE,
    182                                     PKIX_FALSE,
    183                                     chain,
    184                                     plContext);
    185 
    186    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
    187 
    188 cleanup:
    189 
    190    PKIX_TEST_DECREF_AC(chain);
    191    PKIX_TEST_DECREF_AC(valParams);
    192    PKIX_TEST_DECREF_AC(valResult);
    193 
    194    PKIX_TEST_RETURN();
    195 }
    196 
    197 static void
    198 testNistTest1(char *dirName)
    199 {
    200 #define PKIX_TEST_NUM_CERTS 2
    201    char *trustAnchor =
    202        "TrustAnchorRootCertificate.crt";
    203    char *intermediateCert =
    204        "GoodCACert.crt";
    205    char *endEntityCert =
    206        "ValidCertificatePathTest1EE.crt";
    207    char *certNames[PKIX_TEST_NUM_CERTS];
    208    char *asciiAnyPolicy = "2.5.29.32.0";
    209    PKIX_PL_Cert *certs[PKIX_TEST_NUM_CERTS] = { NULL, NULL };
    210 
    211    PKIX_ValidateParams *valParams = NULL;
    212    PKIX_ValidateResult *valResult = NULL;
    213    PKIX_List *chain = NULL;
    214    PKIX_PL_OID *anyPolicyOID = NULL;
    215    PKIX_List *initialPolicies = NULL;
    216    char *anchorName = NULL;
    217 
    218    PKIX_TEST_STD_VARS();
    219 
    220    subTest("testNistTest1: Creating the cert chain");
    221    /*
    222     * Create a chain, but don't include the first certName.
    223     * That's the anchor, and is supplied separately from
    224     * the chain.
    225     */
    226    certNames[0] = intermediateCert;
    227    certNames[1] = endEntityCert;
    228    chain = createCertChainPlus(dirName, certNames, certs, PKIX_TEST_NUM_CERTS, plContext);
    229 
    230    subTest("testNistTest1: Creating the Validate Parameters");
    231    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(asciiAnyPolicy, &anyPolicyOID, plContext));
    232    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&initialPolicies, plContext));
    233    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(initialPolicies, (PKIX_PL_Object *)anyPolicyOID, plContext));
    234    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable(initialPolicies, plContext));
    235 
    236    valParams = createValidateParams(dirName,
    237                                     trustAnchor,
    238                                     NULL,
    239                                     NULL,
    240                                     initialPolicies,
    241                                     PKIX_FALSE,
    242                                     PKIX_FALSE,
    243                                     PKIX_FALSE,
    244                                     PKIX_FALSE,
    245                                     chain,
    246                                     plContext);
    247 
    248    subTest("testNistTest1: Validating the chain");
    249    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
    250 
    251 cleanup:
    252 
    253    PKIX_PL_Free(anchorName, plContext);
    254 
    255    PKIX_TEST_DECREF_AC(anyPolicyOID);
    256    PKIX_TEST_DECREF_AC(initialPolicies);
    257    PKIX_TEST_DECREF_AC(valParams);
    258    PKIX_TEST_DECREF_AC(valResult);
    259    PKIX_TEST_DECREF_AC(chain);
    260 
    261    PKIX_TEST_RETURN();
    262 }
    263 
    264 static void
    265 testNistTest2(char *dirName)
    266 {
    267 #define PKIX_TEST_NUM_CERTS 2
    268    char *trustAnchor =
    269        "TrustAnchorRootCertificate.crt";
    270    char *intermediateCert =
    271        "GoodCACert.crt";
    272    char *endEntityCert =
    273        "ValidCertificatePathTest1EE.crt";
    274    char *certNames[PKIX_TEST_NUM_CERTS];
    275    char *asciiNist1Policy = "2.16.840.1.101.3.2.1.48.1";
    276    PKIX_PL_Cert *certs[PKIX_TEST_NUM_CERTS] = { NULL, NULL };
    277 
    278    PKIX_ValidateParams *valParams = NULL;
    279    PKIX_ValidateResult *valResult = NULL;
    280    PKIX_List *chain = NULL;
    281    PKIX_PL_OID *Nist1PolicyOID = NULL;
    282    PKIX_List *initialPolicies = NULL;
    283    char *anchorName = NULL;
    284 
    285    PKIX_TEST_STD_VARS();
    286 
    287    subTest("testNistTest2: Creating the cert chain");
    288    /*
    289     * Create a chain, but don't include the first certName.
    290     * That's the anchor, and is supplied separately from
    291     * the chain.
    292     */
    293    certNames[0] = intermediateCert;
    294    certNames[1] = endEntityCert;
    295    chain = createCertChainPlus(dirName, certNames, certs, PKIX_TEST_NUM_CERTS, plContext);
    296 
    297    subTest("testNistTest2: Creating the Validate Parameters");
    298    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(asciiNist1Policy, &Nist1PolicyOID, plContext));
    299    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&initialPolicies, plContext));
    300    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(initialPolicies, (PKIX_PL_Object *)Nist1PolicyOID, plContext));
    301    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable(initialPolicies, plContext));
    302 
    303    valParams = createValidateParams(dirName,
    304                                     trustAnchor,
    305                                     NULL,
    306                                     NULL,
    307                                     initialPolicies,
    308                                     PKIX_FALSE,
    309                                     PKIX_FALSE,
    310                                     PKIX_FALSE,
    311                                     PKIX_FALSE,
    312                                     chain,
    313                                     plContext);
    314 
    315    subTest("testNistTest2: Validating the chain");
    316    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
    317 
    318 cleanup:
    319 
    320    PKIX_PL_Free(anchorName, plContext);
    321 
    322    PKIX_TEST_DECREF_AC(Nist1PolicyOID);
    323    PKIX_TEST_DECREF_AC(initialPolicies);
    324    PKIX_TEST_DECREF_AC(valParams);
    325    PKIX_TEST_DECREF_AC(valResult);
    326    PKIX_TEST_DECREF_AC(chain);
    327 
    328    PKIX_TEST_RETURN();
    329 }
    330 
    331 static void
    332 printValidPolicyTree(PKIX_ValidateResult *valResult)
    333 {
    334    PKIX_PolicyNode *validPolicyTree = NULL;
    335    PKIX_PL_String *treeString = NULL;
    336 
    337    PKIX_TEST_STD_VARS();
    338    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetPolicyTree(valResult, &validPolicyTree, plContext));
    339    if (validPolicyTree) {
    340        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)validPolicyTree,
    341                                                          &treeString,
    342                                                          plContext));
    343        (void)printf("validPolicyTree is\n\t%s\n",
    344                     treeString->escAsciiString);
    345    } else {
    346        (void)printf("validPolicyTree is NULL\n");
    347    }
    348 
    349 cleanup:
    350 
    351    PKIX_TEST_DECREF_AC(validPolicyTree);
    352    PKIX_TEST_DECREF_AC(treeString);
    353 
    354    PKIX_TEST_RETURN();
    355 }
    356 
    357 int
    358 test_policychecker(int argc, char *argv[])
    359 {
    360 
    361    PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE;
    362    PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE;
    363    PKIX_Boolean initialExplicitPolicy = PKIX_FALSE;
    364    PKIX_Boolean expectedResult = PKIX_FALSE;
    365    PKIX_UInt32 chainLength = 0;
    366    PKIX_UInt32 initArgs = 0;
    367    PKIX_UInt32 firstCert = 0;
    368    PKIX_UInt32 i = 0;
    369    PKIX_Int32 j = 0;
    370    PKIX_UInt32 actualMinorVersion;
    371    PKIX_ProcessingParams *procParams = NULL;
    372    char *firstTrustAnchor = "yassir2yassir";
    373    char *secondTrustAnchor = "yassir2bcn";
    374    char *dateAscii = "991201000000Z";
    375    PKIX_ValidateParams *valParams = NULL;
    376    PKIX_ValidateResult *valResult = NULL;
    377    PKIX_List *userInitialPolicySet = NULL; /* List of PKIX_PL_OID */
    378    char *certNames[PKIX_TEST_MAX_CERTS];
    379    PKIX_PL_Cert *certs[PKIX_TEST_MAX_CERTS];
    380    PKIX_List *chain = NULL;
    381    PKIX_Error *validationError = NULL;
    382    PKIX_VerifyNode *verifyTree = NULL;
    383    PKIX_PL_String *verifyString = NULL;
    384    char *dirName = NULL;
    385    char *dataCentralDir = NULL;
    386    char *anchorName = NULL;
    387 
    388    PKIX_TEST_STD_VARS();
    389 
    390    PKIX_TEST_EXPECT_NO_ERROR(
    391        PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
    392 
    393    /*
    394     * Perform hard-coded tests if no command line args.
    395     * If command line args are provided, they must be:
    396     * arg[1]: test name
    397     * arg[2]: "ENE" or "EE", for "expect no error" or "expect error"
    398     * arg[3]: directory for certificates
    399     * arg[4]: user-initial-policy-set, consisting of braces
    400     *      containing zero or more OID sequences, separated by commas
    401     * arg[5]: (optional) "E", indicating initialExplicitPolicy
    402     * arg[firstCert]: the path and filename of the trust anchor certificate
    403     * arg[firstCert+1..(n-1)]: successive certificates in the chain
    404     * arg[n]: the end entity certificate
    405     *
    406     * Example: test_policychecker test1EE ENE
    407     *      {2.5.29.32.0,2.5.29.32.3.6} Anchor CA EndEntity
    408     */
    409 
    410    dirName = argv[3 + j];
    411    dataCentralDir = argv[4 + j];
    412 
    413    if (argc <= 5 || ((6 == argc) && (j))) {
    414 
    415        testPass(dataCentralDir,
    416                 firstTrustAnchor,
    417                 secondTrustAnchor,
    418                 dateAscii);
    419 
    420        testNistTest1(dirName);
    421 
    422        testNistTest2(dirName);
    423 
    424        goto cleanup;
    425    }
    426 
    427    if (argc < (7 + j)) {
    428        printUsage(argv[0]);
    429        pkixTestErrorMsg = "Invalid command line arguments.";
    430        goto cleanup;
    431    }
    432 
    433    if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
    434        expectedResult = PKIX_TRUE;
    435    } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
    436        expectedResult = PKIX_FALSE;
    437    } else {
    438        printUsage(argv[0]);
    439        pkixTestErrorMsg = "Invalid command line arguments.";
    440        goto cleanup;
    441    }
    442 
    443    userInitialPolicySet = policySetParse(argv[5 + j]);
    444    if (!userInitialPolicySet) {
    445        printUsage(argv[0]);
    446        pkixTestErrorMsg = "Invalid command line arguments.";
    447        goto cleanup;
    448    }
    449 
    450    for (initArgs = 0; initArgs < 3; initArgs++) {
    451        if (PORT_Strcmp(argv[6 + j + initArgs], "A") == 0) {
    452            initialAnyPolicyInhibit = PKIX_TRUE;
    453        } else if (PORT_Strcmp(argv[6 + j + initArgs], "E") == 0) {
    454            initialExplicitPolicy = PKIX_TRUE;
    455        } else if (PORT_Strcmp(argv[6 + j + initArgs], "P") == 0) {
    456            initialPolicyMappingInhibit = PKIX_TRUE;
    457        } else {
    458            break;
    459        }
    460    }
    461 
    462    firstCert = initArgs + j + 6;
    463    chainLength = argc - (firstCert + 1);
    464    if (chainLength > PKIX_TEST_MAX_CERTS) {
    465        printUsageMax(chainLength);
    466        pkixTestErrorMsg = "Invalid command line arguments.";
    467        goto cleanup;
    468    }
    469 
    470    /*
    471     * Create a chain, but don't include the first certName.
    472     * That's the anchor, and is supplied separately from
    473     * the chain.
    474     */
    475    for (i = 0; i < chainLength; i++) {
    476 
    477        certNames[i] = argv[i + (firstCert + 1)];
    478        certs[i] = NULL;
    479    }
    480    chain = createCertChainPlus(dirName, certNames, certs, chainLength, plContext);
    481 
    482    subTest(argv[1 + j]);
    483 
    484    valParams = createValidateParams(dirName,
    485                                     argv[firstCert],
    486                                     NULL,
    487                                     NULL,
    488                                     userInitialPolicySet,
    489                                     initialPolicyMappingInhibit,
    490                                     initialAnyPolicyInhibit,
    491                                     initialExplicitPolicy,
    492                                     PKIX_FALSE,
    493                                     chain,
    494                                     plContext);
    495 
    496    if (expectedResult == PKIX_TRUE) {
    497        subTest("   (expecting successful validation)");
    498 
    499        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
    500 
    501        printValidPolicyTree(valResult);
    502 
    503    } else {
    504        subTest("   (expecting validation to fail)");
    505        validationError = PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext);
    506        if (!validationError) {
    507            printValidPolicyTree(valResult);
    508            pkixTestErrorMsg = "Should have thrown an error here.";
    509        }
    510        PKIX_TEST_DECREF_BC(validationError);
    511    }
    512 
    513    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
    514    (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
    515 
    516 cleanup:
    517 
    518    PKIX_PL_Free(anchorName, plContext);
    519 
    520    PKIX_TEST_DECREF_AC(verifyString);
    521    PKIX_TEST_DECREF_AC(verifyTree);
    522    PKIX_TEST_DECREF_AC(userInitialPolicySet);
    523    PKIX_TEST_DECREF_AC(chain);
    524    PKIX_TEST_DECREF_AC(valParams);
    525    PKIX_TEST_DECREF_AC(valResult);
    526    PKIX_TEST_DECREF_AC(validationError);
    527 
    528    PKIX_Shutdown(plContext);
    529 
    530    PKIX_TEST_RETURN();
    531 
    532    endTests("PolicyChecker");
    533 
    534    return (0);
    535 }