tor-browser

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

build_chain.c (7486B)


      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 * buildChain.c
      6 *
      7 * Tests Cert Chain Building
      8 *
      9 */
     10 
     11 #include <stdio.h>
     12 #include <string.h>
     13 #include <stddef.h>
     14 
     15 #include "pkix_pl_generalname.h"
     16 #include "pkix_pl_cert.h"
     17 #include "pkix.h"
     18 #include "testutil.h"
     19 #include "prlong.h"
     20 #include "plstr.h"
     21 #include "prthread.h"
     22 #include "nspr.h"
     23 #include "prtypes.h"
     24 #include "prtime.h"
     25 #include "pk11func.h"
     26 #include "secasn1.h"
     27 #include "cert.h"
     28 #include "cryptohi.h"
     29 #include "secoid.h"
     30 #include "certdb.h"
     31 #include "secitem.h"
     32 #include "keythi.h"
     33 #include "nss.h"
     34 
     35 static void *plContext = NULL;
     36 
     37 static void
     38 printUsage(void)
     39 {
     40    (void)printf("\nUSAGE:\tbuildChain "
     41                 "<trustedCert> <targetCert> <certStoreDirectory>\n\n");
     42    (void)printf("Builds a chain of certificates between "
     43                 "<trustedCert> and <targetCert>\n"
     44                 "using the certs and CRLs in <certStoreDirectory>.\n");
     45 }
     46 
     47 static PKIX_PL_Cert *
     48 createCert(char *inFileName)
     49 {
     50    PKIX_PL_ByteArray *byteArray = NULL;
     51    void *buf = NULL;
     52    PRFileDesc *inFile = NULL;
     53    PKIX_UInt32 len;
     54    SECItem certDER;
     55    SECStatus rv;
     56    /* default: NULL cert (failure case) */
     57    PKIX_PL_Cert *cert = NULL;
     58 
     59    PKIX_TEST_STD_VARS();
     60 
     61    certDER.data = NULL;
     62 
     63    inFile = PR_Open(inFileName, PR_RDONLY, 0);
     64 
     65    if (!inFile) {
     66        pkixTestErrorMsg = "Unable to open cert file";
     67        goto cleanup;
     68    } else {
     69        rv = SECU_ReadDERFromFile(&certDER, inFile, PR_FALSE, PR_FALSE);
     70        if (!rv) {
     71            buf = (void *)certDER.data;
     72            len = certDER.len;
     73 
     74            PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_ByteArray_Create(buf, len, &byteArray, plContext));
     75 
     76            PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_Create(byteArray, &cert, plContext));
     77 
     78            SECITEM_FreeItem(&certDER, PR_FALSE);
     79        } else {
     80            pkixTestErrorMsg = "Unable to read DER from cert file";
     81            goto cleanup;
     82        }
     83    }
     84 
     85 cleanup:
     86 
     87    if (inFile) {
     88        PR_Close(inFile);
     89    }
     90 
     91    if (PKIX_TEST_ERROR_RECEIVED) {
     92        SECITEM_FreeItem(&certDER, PR_FALSE);
     93    }
     94 
     95    PKIX_TEST_DECREF_AC(byteArray);
     96 
     97    PKIX_TEST_RETURN();
     98 
     99    return (cert);
    100 }
    101 
    102 int
    103 build_chain(int argc, char *argv[])
    104 {
    105    PKIX_BuildResult *buildResult = NULL;
    106    PKIX_ComCertSelParams *certSelParams = NULL;
    107    PKIX_CertSelector *certSelector = NULL;
    108    PKIX_TrustAnchor *anchor = NULL;
    109    PKIX_List *anchors = NULL;
    110    PKIX_List *certs = NULL;
    111    PKIX_PL_Cert *cert = NULL;
    112    PKIX_ProcessingParams *procParams = NULL;
    113    char *trustedCertFile = NULL;
    114    char *targetCertFile = NULL;
    115    char *storeDirAscii = NULL;
    116    PKIX_PL_String *storeDirString = NULL;
    117    PKIX_PL_Cert *trustedCert = NULL;
    118    PKIX_PL_Cert *targetCert = NULL;
    119    PKIX_UInt32 actualMinorVersion, numCerts, i;
    120    PKIX_UInt32 j = 0;
    121    PKIX_CertStore *certStore = NULL;
    122    PKIX_List *certStores = NULL;
    123    char *asciiResult = NULL;
    124    PKIX_Boolean useArenas = PKIX_FALSE;
    125    void *buildState = NULL; /* needed by pkix_build for non-blocking I/O */
    126    void *nbioContext = NULL;
    127 
    128    PKIX_TEST_STD_VARS();
    129 
    130    if (argc < 4) {
    131        printUsage();
    132        return (0);
    133    }
    134 
    135    useArenas = PKIX_TEST_ARENAS_ARG(argv[1]);
    136 
    137    PKIX_TEST_EXPECT_NO_ERROR(PKIX_Initialize(PKIX_TRUE, /* nssInitNeeded */
    138                                              useArenas,
    139                                              PKIX_MAJOR_VERSION,
    140                                              PKIX_MINOR_VERSION,
    141                                              PKIX_MINOR_VERSION,
    142                                              &actualMinorVersion,
    143                                              &plContext));
    144 
    145    /* create processing params with list of trust anchors */
    146    trustedCertFile = argv[j + 1];
    147    trustedCert = createCert(trustedCertFile);
    148 
    149    PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
    150    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
    151    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
    152    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
    153 
    154    /* create CertSelector with target certificate in params */
    155    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
    156 
    157    targetCertFile = argv[j + 2];
    158    targetCert = createCert(targetCertFile);
    159 
    160    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext));
    161 
    162    PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
    163 
    164    PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
    165 
    166    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
    167 
    168    /* create CertStores */
    169 
    170    storeDirAscii = argv[j + 3];
    171 
    172    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, storeDirAscii, 0, &storeDirString, plContext));
    173 
    174    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(storeDirString, &certStore, plContext));
    175    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext));
    176    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext));
    177 
    178    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext));
    179 
    180    /* build cert chain using processing params and return buildResult */
    181 
    182    PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildChain(procParams,
    183                                              &nbioContext,
    184                                              &buildState,
    185                                              &buildResult,
    186                                              NULL,
    187                                              plContext));
    188 
    189    /*
    190     * As long as we use only CertStores with blocking I/O, we can omit
    191     * checking for completion with nbioContext.
    192     */
    193 
    194    PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, plContext));
    195 
    196    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
    197 
    198    printf("\n");
    199 
    200    for (i = 0; i < numCerts; i++) {
    201        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, i, (PKIX_PL_Object **)&cert, plContext));
    202 
    203        asciiResult = PKIX_Cert2ASCII(cert);
    204 
    205        printf("CERT[%d]:\n%s\n", i, asciiResult);
    206 
    207        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, plContext));
    208        asciiResult = NULL;
    209 
    210        PKIX_TEST_DECREF_BC(cert);
    211    }
    212 
    213 cleanup:
    214 
    215    if (PKIX_TEST_ERROR_RECEIVED) {
    216        (void)printf("FAILED TO BUILD CHAIN\n");
    217    } else {
    218        (void)printf("SUCCESSFULLY BUILT CHAIN\n");
    219    }
    220 
    221    PKIX_PL_Free(asciiResult, plContext);
    222 
    223    PKIX_TEST_DECREF_AC(certs);
    224    PKIX_TEST_DECREF_AC(cert);
    225    PKIX_TEST_DECREF_AC(certStore);
    226    PKIX_TEST_DECREF_AC(certStores);
    227    PKIX_TEST_DECREF_AC(storeDirString);
    228    PKIX_TEST_DECREF_AC(trustedCert);
    229    PKIX_TEST_DECREF_AC(targetCert);
    230    PKIX_TEST_DECREF_AC(anchor);
    231    PKIX_TEST_DECREF_AC(anchors);
    232    PKIX_TEST_DECREF_AC(procParams);
    233    PKIX_TEST_DECREF_AC(certSelParams);
    234    PKIX_TEST_DECREF_AC(certSelector);
    235    PKIX_TEST_DECREF_AC(buildResult);
    236 
    237    PKIX_TEST_RETURN();
    238 
    239    PKIX_Shutdown(plContext);
    240 
    241    return (0);
    242 }