tor-browser

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

libpkix_buildthreads.c (9417B)


      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 * libpkixBuildThreads.c
      6 *
      7 * libpkix Builder Performance Evaluation application (multi-threaded)
      8 *
      9 */
     10 
     11 #include <stdio.h>
     12 #include <string.h>
     13 
     14 #include "secutil.h"
     15 
     16 #include "nspr.h"
     17 #include "prtypes.h"
     18 #include "prtime.h"
     19 #include "prlong.h"
     20 
     21 #include "pk11func.h"
     22 #include "secasn1.h"
     23 #include "cert.h"
     24 #include "cryptohi.h"
     25 #include "secoid.h"
     26 #include "certdb.h"
     27 #include "nss.h"
     28 
     29 #include "pkix.h"
     30 #include "pkix_tools.h"
     31 #include "pkix_pl_cert.h"
     32 
     33 #include "testutil.h"
     34 #include "testutil_nss.h"
     35 
     36 static void *plContext = NULL;
     37 
     38 #undef pkixTempResult
     39 #define PERF_DECREF(obj)                                                                \
     40    {                                                                                   \
     41        PKIX_Error *pkixTempResult = NULL;                                              \
     42        if (obj) {                                                                      \
     43            pkixTempResult = PKIX_PL_Object_DecRef((PKIX_PL_Object *)(obj), plContext); \
     44            obj = NULL;                                                                 \
     45        }                                                                               \
     46    }
     47 
     48 static void finish(char *message, int code);
     49 
     50 typedef struct ThreadDataStr tData;
     51 
     52 struct ThreadDataStr {
     53    CERTCertificate *anchor;
     54    char *eecertName;
     55    PRIntervalTime duration;
     56    CERTCertDBHandle *handle;
     57    PRUint32 iterations;
     58 };
     59 
     60 #define PKIX_LOGGER_ON 1
     61 
     62 #ifdef PKIX_LOGGER_ON
     63 
     64 char *logLevels[] = {
     65    "None",
     66    "Fatal Error",
     67    "Error",
     68    "Warning",
     69    "Debug",
     70    "Trace"
     71 };
     72 
     73 static PKIX_Error *
     74 loggerCallback(
     75    PKIX_Logger *logger,
     76    PKIX_PL_String *message,
     77    PKIX_UInt32 logLevel,
     78    PKIX_ERRORCLASS logComponent,
     79    void *plContext)
     80 {
     81    char *msg = NULL;
     82    static int callCount = 0;
     83 
     84    msg = PKIX_String2ASCII(message, plContext);
     85    printf("Logging %s (%s): %s\n",
     86           logLevels[logLevel],
     87           PKIX_ERRORCLASSNAMES[logComponent],
     88           msg);
     89    PR_Free((void *)msg);
     90 
     91    return (NULL);
     92 }
     93 
     94 #endif /* PKIX_LOGGER_ON */
     95 
     96 static void
     97 ThreadEntry(void *data)
     98 {
     99    tData *tdata = (tData *)data;
    100    PRIntervalTime duration = tdata->duration;
    101    PRIntervalTime start = PR_IntervalNow();
    102 
    103    PKIX_List *anchors = NULL;
    104    PKIX_ProcessingParams *procParams = NULL;
    105    PKIX_BuildResult *buildResult = NULL;
    106    CERTCertificate *nsseecert;
    107    PKIX_PL_Cert *eeCert = NULL;
    108    PKIX_CertStore *certStore = NULL;
    109    PKIX_List *certStores = NULL;
    110    PKIX_ComCertSelParams *certSelParams = NULL;
    111    PKIX_CertSelector *certSelector = NULL;
    112    PKIX_PL_Date *nowDate = NULL;
    113    void *state = NULL;       /* only relevant with non-blocking I/O */
    114    void *nbioContext = NULL; /* only relevant with non-blocking I/O */
    115 
    116    PR_ASSERT(duration);
    117    if (!duration) {
    118        return;
    119    }
    120 
    121    do {
    122 
    123        /* libpkix code */
    124 
    125        /* keep more update time, testing cache */
    126        PKIX_PL_Date_Create_UTCTime(NULL, &nowDate, plContext);
    127 
    128        /* CertUsage is 0x10 and no NSS arena */
    129        /* We haven't determined how we obtain the value of wincx */
    130 
    131        nsseecert = CERT_FindCertByNicknameOrEmailAddr(tdata->handle,
    132                                                       tdata->eecertName);
    133        if (!nsseecert)
    134            finish("Unable to find eecert.\n", 1);
    135 
    136        pkix_pl_Cert_CreateWithNSSCert(nsseecert, &eeCert, plContext);
    137 
    138        PKIX_List_Create(&anchors, plContext);
    139 
    140        /*
    141         * This code is retired.
    142         *      pkix_pl_Cert_CreateWithNSSCert
    143         *              (tdata->anchor, &anchorCert, NULL);
    144         *      PKIX_TrustAnchor_CreateWithCert(anchorCert, &anchor, NULL);
    145         *      PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, NULL);
    146         */
    147 
    148        PKIX_ProcessingParams_Create(anchors, &procParams, plContext);
    149 
    150        PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_TRUE, plContext);
    151 
    152        PKIX_ProcessingParams_SetDate(procParams, nowDate, plContext);
    153 
    154        /* create CertSelector with target certificate in params */
    155 
    156        PKIX_ComCertSelParams_Create(&certSelParams, plContext);
    157 
    158        PKIX_ComCertSelParams_SetCertificate(certSelParams, eeCert, plContext);
    159 
    160        PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext);
    161 
    162        PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext);
    163 
    164        PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext);
    165 
    166        PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
    167 
    168        PKIX_List_Create(&certStores, plContext);
    169        PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext);
    170        PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext);
    171 
    172        PKIX_BuildChain(procParams,
    173                        &nbioContext,
    174                        &state,
    175                        &buildResult,
    176                        NULL,
    177                        plContext);
    178 
    179        /*
    180         * As long as we use only CertStores with blocking I/O, we
    181         * know we must be done at this point.
    182         */
    183 
    184        if (!buildResult) {
    185            (void)fprintf(stderr, "libpkix BuildChain failed.\n");
    186            PORT_Assert(0);
    187            return;
    188        }
    189 
    190        tdata->iterations++;
    191 
    192        PERF_DECREF(nowDate);
    193        PERF_DECREF(anchors);
    194        PERF_DECREF(procParams);
    195        PERF_DECREF(buildResult);
    196        PERF_DECREF(certStore);
    197        PERF_DECREF(certStores);
    198        PERF_DECREF(certSelParams);
    199        PERF_DECREF(certSelector);
    200        PERF_DECREF(eeCert);
    201 
    202    } while ((PR_IntervalNow() - start) < duration);
    203 }
    204 
    205 static void
    206 Test(
    207    CERTCertificate *anchor,
    208    char *eecertName,
    209    PRIntervalTime duration,
    210    CERTCertDBHandle *handle,
    211    PRUint32 threads)
    212 {
    213    tData data;
    214    tData **alldata;
    215    PRIntervalTime starttime, endtime, elapsed;
    216    PRUint32 msecs;
    217    float total = 0;
    218    PRThread **pthreads = NULL;
    219    PRUint32 i = 0;
    220 
    221    data.duration = duration;
    222    data.anchor = anchor;
    223    data.eecertName = eecertName;
    224    data.handle = handle;
    225 
    226    data.iterations = 0;
    227 
    228    starttime = PR_IntervalNow();
    229    pthreads = (PRThread **)PR_Malloc(threads * sizeof(PRThread *));
    230    alldata = (tData **)PR_Malloc(threads * sizeof(tData *));
    231    for (i = 0; i < threads; i++) {
    232        alldata[i] = (tData *)PR_Malloc(sizeof(tData));
    233        *alldata[i] = data;
    234        pthreads[i] =
    235            PR_CreateThread(PR_USER_THREAD,
    236                            ThreadEntry,
    237                            (void *)alldata[i],
    238                            PR_PRIORITY_NORMAL,
    239                            PR_GLOBAL_THREAD,
    240                            PR_JOINABLE_THREAD,
    241                            0);
    242    }
    243 
    244    for (i = 0; i < threads; i++) {
    245        tData *args = alldata[i];
    246        PR_JoinThread(pthreads[i]);
    247        total += args->iterations;
    248        PR_Free((void *)args);
    249    }
    250 
    251    PR_Free((void *)pthreads);
    252    PR_Free((void *)alldata);
    253    endtime = PR_IntervalNow();
    254 
    255    endtime = PR_IntervalNow();
    256    elapsed = endtime - starttime;
    257    msecs = PR_IntervalToMilliseconds(elapsed);
    258    total /= msecs;
    259    total *= 1000;
    260    (void)fprintf(stdout, "%f operations per second.\n", total);
    261 }
    262 
    263 static void
    264 finish(char *message, int code)
    265 {
    266    (void)printf(message);
    267    exit(code);
    268 }
    269 
    270 static void
    271 usage(char *progname)
    272 {
    273    (void)printf("Usage : %s <-d certStoreDirectory> <duration> <threads> "
    274                 "<anchorNickname> <eecertNickname>\n\n",
    275                 progname);
    276    finish("", 0);
    277 }
    278 
    279 int
    280 libpkix_buildthreads(int argc, char **argv)
    281 {
    282    CERTCertDBHandle *handle = NULL;
    283    CERTCertificate *eecert = NULL;
    284    PRIntervalTime duration = PR_SecondsToInterval(1);
    285    PRUint32 threads = 1;
    286    PKIX_UInt32 actualMinorVersion;
    287    PKIX_UInt32 j = 0;
    288    PKIX_Logger *logger = NULL;
    289    void *wincx = NULL;
    290 
    291    /* if (argc != 5) -- when TrustAnchor used to be on command line */
    292    if (argc != 4) {
    293        usage(argv[0]);
    294    }
    295    if (atoi(argv[1]) > 0) {
    296        duration = PR_SecondsToInterval(atoi(argv[1]));
    297    }
    298    if (atoi(argv[2]) > 0) {
    299        threads = atoi(argv[2]);
    300    }
    301 
    302    PKIX_PL_NssContext_Create(certificateUsageEmailSigner, PKIX_FALSE,
    303                              NULL, &plContext);
    304 
    305    handle = CERT_GetDefaultCertDB();
    306    PR_ASSERT(handle);
    307 
    308 #ifdef PKIX_LOGGER_ON
    309 
    310    /* set logger to log trace and up */
    311    PKIX_SetLoggers(NULL, plContext);
    312    PKIX_Logger_Create(loggerCallback, NULL, &logger, plContext);
    313    PKIX_Logger_SetMaxLoggingLevel(logger, PKIX_LOGGER_LEVEL_WARNING, plContext);
    314    PKIX_AddLogger(logger, plContext);
    315 
    316 #endif /* PKIX_LOGGER_ON */
    317 
    318    /*
    319         * This code is retired
    320         *      anchor = CERT_FindCertByNicknameOrEmailAddr(handle, argv[3]);
    321         *      if (!anchor) finish("Unable to find anchor.\n", 1);
    322         *
    323         *      eecert = CERT_FindCertByNicknameOrEmailAddr(handle, argv[4]);
    324 
    325         *      if (!eecert) finish("Unable to find eecert.\n", 1);
    326         *
    327         *      Test(anchor, eecert, duration, threads);
    328         */
    329 
    330    Test(NULL, argv[3], duration, handle, threads);
    331 
    332    PERF_DECREF(logger);
    333 
    334    PKIX_Shutdown(plContext);
    335 
    336    return (0);
    337 }