~ubuntu-branches/ubuntu/karmic/nss/karmic-updates

« back to all changes in this revision

Viewing changes to mozilla/security/nss/cmd/vfychain/vfychain.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2009-06-16 13:23:47 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090616132347-311ysb8oep74b98y
Tags: 3.12.3-0ubuntu1
* new upstream release 3.12.3 RTM (NSS_3_12_3_RTM) (LP: #387751)
* adjust patches to changed upstream code base
  - update debian/patches/38_kbsd.patch
* needs nspr >= 4.7.4
  - update debian/control
* update 85_security_load.patch to latest debian version
  - update debian/patches/85_security_load.patch
* add new symbols for 3.12.3
  - update debian/libnss3-1d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
Usage(const char *progName)
82
82
{
83
83
    fprintf(stderr, 
84
 
        "Usage: %s [options] certfile [[options] certfile] ...\n"
 
84
        "Usage: %s [options] [revocation options] certfile "
 
85
            "[[options] certfile] ...\n"
85
86
        "\tWhere options are:\n"
86
87
        "\t-a\t\t Following certfile is base64 encoded\n"
87
88
        "\t-b YYMMDDHHMMZ\t Validate date (default: now)\n"
88
89
        "\t-d directory\t Database directory\n"
 
90
        "\t-i number of consecutive verifications\n"
89
91
        "\t-f \t\t Enable cert fetching from AIA URL\n"
90
92
        "\t-o oid\t\t Set policy OID for cert validation(Format OID.1.2.3)\n"
91
93
        "\t-p \t\t Use PKIX Library to validate certificate by calling:\n"
92
94
        "\t\t\t   * CERT_VerifyCertificate if specified once,\n"
93
95
        "\t\t\t   * CERT_PKIXVerifyCert if specified twice and more.\n"
94
96
        "\t-r\t\t Following certfile is raw binary DER (default)\n"
95
 
        "\t-s\t\t Status checking, following a configuration description.\n"
96
 
        "\t\t\t Implemented as of today are:\n"
97
 
        "\t\t\t   * allow-crl (default)\n"
98
 
        "\t\t\t   * allow-crl-and-ocsp\n"
99
97
        "\t-t\t\t Following cert is explicitly trusted (overrides db trust).\n"
100
98
        "\t-u usage \t 0=SSL client, 1=SSL server, 2=SSL StepUp, 3=SSL CA,\n"
101
99
        "\t\t\t 4=Email signer, 5=Email recipient, 6=Object signer,\n"
102
100
        "\t\t\t 9=ProtectedObjectSigner, 10=OCSP responder, 11=Any CA\n"
103
101
        "\t-v\t\t Verbose mode. Prints root cert subject(double the\n"
104
102
        "\t\t\t argument for whole root cert info)\n"
105
 
        "\t-w password\t Database password.\n",
106
 
        "\t-W pwfile\t Password file.\n",
107
 
        progName);
 
103
        "\t-w password\t Database password.\n"
 
104
        "\t-W pwfile\t Password file.\n\n"
 
105
        "\tRevocation options for PKIX API(invoked with -pp options) is a\n"
 
106
        "\tcollection of the following flags:\n"
 
107
        "\t\t[-g type [-h flags] [-m type [-s flags]] ...] ...\n"
 
108
        "\tWhere:\n"
 
109
        "\t-g test type\t Sets status checking test type. Possible values\n"
 
110
        "\t\t\tare \"leaf\" or \"chain\"\n"
 
111
        "\t-h test flags\t Sets revocation flags for the test type it\n"
 
112
        "\t\t\tfollows. Possible flags: \"testLocalInfoFirst\" and\n"
 
113
        "\t\t\t\"requireFreshInfo\".\n"
 
114
        "\t-m method type\t Sets method type for the test type it follows.\n"
 
115
        "\t\t\tPossible types are \"crl\" and \"ocsp\".\n"
 
116
        "\t-s method flags\t Sets revocation flags for the method it follows.\n"
 
117
        "\t\t\tPossible types are \"doNotUse\", \"forbidFetching\",\n"
 
118
        "\t\t\t\"ignoreDefaultSrc\", \"requireInfo\" and \"failIfNoInfo\".\n",
 
119
        progName);
108
120
    exit(1);
109
121
}
110
122
 
229
241
    return cert;
230
242
}
231
243
 
232
 
#define REVCONFIG_ALLOW_CRL "allow-crl"
233
 
#define REVCONFIG_ALLOW_CRL_OCSP "allow-crl-and-ocsp"
 
244
 
 
245
#define REVCONFIG_TEST_UNDEFINED      0
 
246
#define REVCONFIG_TEST_LEAF           1
 
247
#define REVCONFIG_TEST_CHAIN          2
 
248
#define REVCONFIG_METHOD_CRL          1
 
249
#define REVCONFIG_METHOD_OCSP         2
 
250
 
 
251
#define REVCONFIG_TEST_LEAF_STR       "leaf"
 
252
#define REVCONFIG_TEST_CHAIN_STR      "chain"
 
253
#define REVCONFIG_METHOD_CRL_STR      "crl"
 
254
#define REVCONFIG_METHOD_OCSP_STR     "ocsp"
 
255
 
 
256
#define REVCONFIG_TEST_TESTLOCALINFOFIRST_STR     "testLocalInfoFirst"
 
257
#define REVCONFIG_TEST_REQUIREFRESHINFO_STR       "requireFreshInfo"
 
258
#define REVCONFIG_METHOD_DONOTUSEMETHOD_STR       "doNotUse"
 
259
#define REVCONFIG_METHOD_FORBIDNETWORKFETCHIN_STR "forbidFetching"
 
260
#define REVCONFIG_METHOD_IGNOREDEFAULTSRC_STR     "ignoreDefaultSrc"
 
261
#define REVCONFIG_METHOD_REQUIREINFO_STR          "requireInfo"
 
262
#define REVCONFIG_METHOD_FAILIFNOINFO_STR         "failIfNoInfo" 
 
263
 
 
264
#define REV_METHOD_INDEX_MAX  4
 
265
 
 
266
typedef struct RevMethodsStruct {
 
267
    uint testType;
 
268
    char *testTypeStr;
 
269
    uint testFlags;
 
270
    char *testFlagsStr;
 
271
    uint methodType;
 
272
    char *methodTypeStr;
 
273
    uint methodFlags;
 
274
    char *methodFlagsStr;
 
275
} RevMethods;
 
276
 
 
277
RevMethods revMethodsData[REV_METHOD_INDEX_MAX];
 
278
 
 
279
SECStatus
 
280
parseRevMethodsAndFlags()
 
281
{
 
282
    int i;
 
283
    uint testType = 0;
 
284
 
 
285
    for(i = 0;i < REV_METHOD_INDEX_MAX;i++) {
 
286
        /* testType */
 
287
        if (revMethodsData[i].testTypeStr) {
 
288
            char *typeStr = revMethodsData[i].testTypeStr;
 
289
 
 
290
            testType = 0;
 
291
            if (!PORT_Strcmp(typeStr, REVCONFIG_TEST_LEAF_STR)) {
 
292
                testType = REVCONFIG_TEST_LEAF;
 
293
            } else if (!PORT_Strcmp(typeStr, REVCONFIG_TEST_CHAIN_STR)) {
 
294
                testType = REVCONFIG_TEST_CHAIN;
 
295
            }
 
296
        }
 
297
        if (!testType) {
 
298
            return SECFailure;
 
299
        }
 
300
        revMethodsData[i].testType = testType;
 
301
        /* testFlags */
 
302
        if (revMethodsData[i].testFlagsStr) {
 
303
            char *flagStr = revMethodsData[i].testFlagsStr;
 
304
            uint testFlags = 0;
 
305
 
 
306
            if (PORT_Strstr(flagStr, REVCONFIG_TEST_TESTLOCALINFOFIRST_STR)) {
 
307
                testFlags |= CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST;
 
308
            } 
 
309
            if (PORT_Strstr(flagStr, REVCONFIG_TEST_REQUIREFRESHINFO_STR)) {
 
310
                testFlags |= CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE;
 
311
            }
 
312
            revMethodsData[i].testFlags = testFlags;
 
313
        }
 
314
        /* method type */
 
315
        if (revMethodsData[i].methodTypeStr) {
 
316
            char *methodStr = revMethodsData[i].methodTypeStr;
 
317
            uint methodType = 0;
 
318
            
 
319
            if (!PORT_Strcmp(methodStr, REVCONFIG_METHOD_CRL_STR)) {
 
320
                methodType = REVCONFIG_METHOD_CRL;
 
321
            } else if (!PORT_Strcmp(methodStr, REVCONFIG_METHOD_OCSP_STR)) {
 
322
                methodType = REVCONFIG_METHOD_OCSP;
 
323
            }
 
324
            if (!methodType) {
 
325
                return SECFailure;
 
326
            }
 
327
            revMethodsData[i].methodType = methodType;
 
328
        }
 
329
        if (!revMethodsData[i].methodType) {
 
330
            revMethodsData[i].testType = REVCONFIG_TEST_UNDEFINED;
 
331
            continue;
 
332
        }
 
333
        /* method flags */
 
334
        if (revMethodsData[i].methodFlagsStr) {
 
335
            char *flagStr = revMethodsData[i].methodFlagsStr;
 
336
            uint methodFlags = 0;
 
337
 
 
338
            if (!PORT_Strstr(flagStr, REVCONFIG_METHOD_DONOTUSEMETHOD_STR)) {
 
339
                methodFlags |= CERT_REV_M_TEST_USING_THIS_METHOD;
 
340
            } 
 
341
            if (PORT_Strstr(flagStr,
 
342
                            REVCONFIG_METHOD_FORBIDNETWORKFETCHIN_STR)) {
 
343
                methodFlags |= CERT_REV_M_FORBID_NETWORK_FETCHING;
 
344
            }
 
345
            if (PORT_Strstr(flagStr, REVCONFIG_METHOD_IGNOREDEFAULTSRC_STR)) {
 
346
                methodFlags |= CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
 
347
            }
 
348
            if (PORT_Strstr(flagStr, REVCONFIG_METHOD_REQUIREINFO_STR)) {
 
349
                methodFlags |= CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE;
 
350
            }
 
351
            if (PORT_Strstr(flagStr, REVCONFIG_METHOD_FAILIFNOINFO_STR)) {
 
352
                methodFlags |= CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO;
 
353
            }
 
354
            revMethodsData[i].methodFlags = methodFlags;
 
355
        } else {
 
356
            revMethodsData[i].methodFlags |= CERT_REV_M_TEST_USING_THIS_METHOD;
 
357
        }
 
358
    }
 
359
    return SECSuccess;
 
360
}
 
361
 
 
362
SECStatus
 
363
configureRevocationParams(CERTRevocationFlags *flags)
 
364
{
 
365
   int i;
 
366
   uint testType = REVCONFIG_TEST_UNDEFINED;
 
367
   static CERTRevocationTests *revTests = NULL;
 
368
   PRUint64 *revFlags;
 
369
 
 
370
   for(i = 0;i < REV_METHOD_INDEX_MAX;i++) {
 
371
       if (revMethodsData[i].testType == REVCONFIG_TEST_UNDEFINED) {
 
372
           continue;
 
373
       }
 
374
       if (revMethodsData[i].testType != testType) {
 
375
           testType = revMethodsData[i].testType;
 
376
           if (testType == REVCONFIG_TEST_CHAIN) {
 
377
               revTests = &flags->chainTests;
 
378
           } else {
 
379
               revTests = &flags->leafTests;
 
380
           }
 
381
           revTests->number_of_preferred_methods = 0;
 
382
           revTests->preferred_methods = 0;
 
383
           revFlags = revTests->cert_rev_flags_per_method;
 
384
       }
 
385
       /* Set the number of the methods independently to the max number of
 
386
        * methods. If method flags are not set it will be ignored due to
 
387
        * default DO_NOT_USE flag. */
 
388
       revTests->number_of_defined_methods = cert_revocation_method_count;
 
389
       revTests->cert_rev_method_independent_flags |=
 
390
           revMethodsData[i].testFlags;
 
391
       if (revMethodsData[i].methodType == REVCONFIG_METHOD_CRL) {
 
392
           revFlags[cert_revocation_method_crl] =
 
393
               revMethodsData[i].methodFlags;
 
394
       } else if (revMethodsData[i].methodType == REVCONFIG_METHOD_OCSP) {
 
395
           revFlags[cert_revocation_method_ocsp] =
 
396
               revMethodsData[i].methodFlags;
 
397
       }
 
398
   }
 
399
   return SECSuccess;
 
400
}
 
401
 
 
402
void
 
403
freeRevocationMethodData()
 
404
{
 
405
    int i = 0;
 
406
    for(;i < REV_METHOD_INDEX_MAX;i++) {
 
407
        if (revMethodsData[i].testTypeStr) {
 
408
            PORT_Free(revMethodsData[i].testTypeStr);
 
409
        }
 
410
        if (revMethodsData[i].testFlagsStr) {
 
411
            PORT_Free(revMethodsData[i].testFlagsStr);
 
412
        }
 
413
        if (revMethodsData[i].methodTypeStr) {
 
414
            PORT_Free(revMethodsData[i].methodTypeStr);
 
415
        }
 
416
        if (revMethodsData[i].methodFlagsStr) {
 
417
            PORT_Free(revMethodsData[i].methodFlagsStr);
 
418
        }
 
419
    }
 
420
}
234
421
 
235
422
PRBool
236
 
isAllowedRevConfig(const char *name)
 
423
isOCSPEnabled()
237
424
{
238
 
    if (strcmp(REVCONFIG_ALLOW_CRL, name) == 0)
239
 
        return PR_TRUE;
240
 
 
241
 
    if (strcmp(REVCONFIG_ALLOW_CRL_OCSP, name) == 0)
242
 
        return PR_TRUE;
243
 
 
 
425
    int i;
 
426
 
 
427
    for(i = 0;i < REV_METHOD_INDEX_MAX;i++) {
 
428
        if (revMethodsData[i].methodType == REVCONFIG_METHOD_OCSP) {
 
429
            return PR_TRUE;
 
430
        }
 
431
    }
244
432
    return PR_FALSE;
245
433
}
246
434
 
266
454
    int                  usage;
267
455
    CERTVerifyLog        log;
268
456
    CERTCertList        *builtChain = NULL;
269
 
    char *               revConfig    = NULL;
270
457
    PRBool               certFetching = PR_FALSE;
 
458
    int                  revDataIndex = 0;
 
459
    PRBool               ocsp_fetchingFailureIsAFailure = PR_TRUE;
 
460
    PRBool               useDefaultRevFlags = PR_TRUE;
 
461
    int                  vfyCounts = 1;
271
462
 
272
463
    PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
273
464
 
274
465
    progName = PL_strdup(argv[0]);
275
466
 
276
 
    optstate = PL_CreateOptState(argc, argv, "ab:d:fo:prs:tu:vw:W:");
 
467
    optstate = PL_CreateOptState(argc, argv, "ab:c:d:efg:h:i:m:o:prs:tu:vw:W:");
277
468
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
278
469
        switch(optstate->option) {
279
470
        case  0  : /* positional parameter */  goto breakout;
281
472
        case 'b' : secStatus = DER_AsciiToTime(&time, optstate->value);
282
473
                   if (secStatus != SECSuccess) Usage(progName); break;
283
474
        case 'd' : certDir  = PL_strdup(optstate->value);     break;
 
475
        case 'e' : ocsp_fetchingFailureIsAFailure = PR_FALSE;  break;
284
476
        case 'f' : certFetching = PR_TRUE;                    break;
 
477
        case 'g' : 
 
478
                   if (revMethodsData[revDataIndex].testTypeStr ||
 
479
                       revMethodsData[revDataIndex].methodTypeStr) {
 
480
                       revDataIndex += 1;
 
481
                       if (revDataIndex == REV_METHOD_INDEX_MAX) {
 
482
                           fprintf(stderr, "Invalid revocation configuration"
 
483
                                   "specified.\n");
 
484
                           secStatus = SECFailure;
 
485
                           break;
 
486
                       }
 
487
                   }
 
488
                   useDefaultRevFlags = PR_FALSE;
 
489
                   revMethodsData[revDataIndex].
 
490
                       testTypeStr = PL_strdup(optstate->value); break;
 
491
        case 'h' : 
 
492
                   revMethodsData[revDataIndex].
 
493
                       testFlagsStr = PL_strdup(optstate->value);break;
 
494
        case 'i' : vfyCounts = PORT_Atoi(optstate->value);       break;
 
495
                   break;
 
496
        case 'm' : 
 
497
                   if (revMethodsData[revDataIndex].methodTypeStr) {
 
498
                       revDataIndex += 1;
 
499
                       if (revDataIndex == REV_METHOD_INDEX_MAX) {
 
500
                           fprintf(stderr, "Invalid revocation configuration"
 
501
                                   "specified.\n");
 
502
                           secStatus = SECFailure;
 
503
                           break;
 
504
                       }
 
505
                   }
 
506
                   useDefaultRevFlags = PR_FALSE;
 
507
                   revMethodsData[revDataIndex].
 
508
                       methodTypeStr = PL_strdup(optstate->value); break;
285
509
        case 'o' : oidStr = PL_strdup(optstate->value);       break;
286
510
        case 'p' : usePkix += 1;                              break;
287
511
        case 'r' : isAscii  = PR_FALSE;                       break;
288
 
        case 's' : revConfig  = PL_strdup(optstate->value);   break;
 
512
        case 's' : 
 
513
                   revMethodsData[revDataIndex].
 
514
                       methodFlagsStr = PL_strdup(optstate->value); break;
289
515
        case 't' : trusted  = PR_TRUE;                        break;
290
516
        case 'u' : usage    = PORT_Atoi(optstate->value);
291
517
                   if (usage < 0 || usage > 62) Usage(progName);
322
548
        }
323
549
    }
324
550
 
325
 
    if (revConfig && !isAllowedRevConfig(revConfig)) {
 
551
    if (!useDefaultRevFlags && parseRevMethodsAndFlags()) {
326
552
        fprintf(stderr, "Invalid revocation configuration specified.\n");
327
553
        goto punt;
328
554
    }
343
569
        exitErr("NSS_Init");
344
570
    }
345
571
    SECU_RegisterDynamicOids();
346
 
    if (revConfig && strcmp(REVCONFIG_ALLOW_CRL_OCSP, revConfig) == 0) {
 
572
    if (isOCSPEnabled()) {
347
573
        CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
348
574
        CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB());
 
575
        if (!ocsp_fetchingFailureIsAFailure) {
 
576
            CERT_SetOCSPFailureMode(ocspMode_FailureIsNotAVerificationFailure);
 
577
        }
349
578
    }
350
579
 
351
580
    while (status == PL_OPT_OK) {
374
603
    if (status == PL_OPT_BAD || !firstCert)
375
604
        Usage(progName);
376
605
 
377
 
    if (!time)
378
 
        time = PR_Now();
379
 
 
380
606
    /* Initialize log structure */
381
607
    log.arena = PORT_NewArena(512);
382
608
    log.head = log.tail = NULL;
383
609
    log.count = 0;
384
610
 
385
 
    if (usePkix < 2) {
386
 
        /* NOW, verify the cert chain. */
387
 
        if (usePkix) {
388
 
            /* Use old API with libpkix validation lib */
389
 
            CERT_SetUsePKIXForValidation(PR_TRUE);
390
 
        }
391
 
        defaultDB = CERT_GetDefaultCertDB();
392
 
        secStatus = CERT_VerifyCertificate(defaultDB, firstCert, 
393
 
                                           PR_TRUE /* check sig */,
394
 
                                           certUsage, 
395
 
                                           time, 
396
 
                                           &pwdata, /* wincx  */
397
 
                                           &log, /* error log */
 
611
    do {
 
612
        if (usePkix < 2) {
 
613
            /* NOW, verify the cert chain. */
 
614
            if (usePkix) {
 
615
                /* Use old API with libpkix validation lib */
 
616
                CERT_SetUsePKIXForValidation(PR_TRUE);
 
617
            }
 
618
            if (!time)
 
619
                time = PR_Now();
 
620
 
 
621
            defaultDB = CERT_GetDefaultCertDB();
 
622
            secStatus = CERT_VerifyCertificate(defaultDB, firstCert, 
 
623
                                               PR_TRUE /* check sig */,
 
624
                                               certUsage, 
 
625
                                               time,
 
626
                                               &pwdata, /* wincx  */
 
627
                                               &log, /* error log */
398
628
                                           NULL);/* returned usages */
399
 
    } else do {
400
 
        static CERTValOutParam cvout[4];
401
 
        static CERTValInParam cvin[6];
402
 
        SECOidTag oidTag;
403
 
        int inParamIndex = 0;
404
 
        static CERTRevocationFlags rev;
405
 
        static PRUint64 revFlags[2];
406
 
 
407
 
        if (oidStr) {
408
 
            PRArenaPool *arena;
409
 
            SECOidData od;
410
 
            memset(&od, 0, sizeof od);
411
 
            od.offset = SEC_OID_UNKNOWN;
412
 
            od.desc = "User Defined Policy OID";
413
 
            od.mechanism = CKM_INVALID_MECHANISM;
414
 
            od.supportedExtension = INVALID_CERT_EXTENSION;
415
 
 
416
 
            arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
417
 
            if ( !arena ) {
418
 
                fprintf(stderr, "out of memory");
419
 
                goto punt;
420
 
            }
421
 
            
422
 
            secStatus = SEC_StringToOID(arena, &od.oid, oidStr, 0);
423
 
            if (secStatus != SECSuccess) {
424
 
                PORT_FreeArena(arena, PR_FALSE);
425
 
                fprintf(stderr, "Can not encode oid: %s(%s)\n", oidStr,
426
 
                        SECU_Strerror(PORT_GetError()));
427
 
                break;
428
 
            }
429
 
            
430
 
            oidTag = SECOID_AddEntry(&od);
431
 
            PORT_FreeArena(arena, PR_FALSE);
432
 
            if (oidTag == SEC_OID_UNKNOWN) {
433
 
                fprintf(stderr, "Can not add new oid to the dynamic "
434
 
                        "table: %s\n", oidStr);
435
 
                secStatus = SECFailure;
436
 
                break;
437
 
            }
438
 
 
439
 
            cvin[inParamIndex].type = cert_pi_policyOID;
440
 
            cvin[inParamIndex].value.arraySize = 1;
441
 
            cvin[inParamIndex].value.array.oids = &oidTag;
442
 
 
443
 
            inParamIndex++;
444
 
        }
445
 
 
446
 
        if (trustedCertList) {
447
 
            cvin[inParamIndex].type = cert_pi_trustAnchors;
448
 
            cvin[inParamIndex].value.pointer.chain = trustedCertList;
449
 
            
450
 
            inParamIndex++;
451
 
        }
452
 
 
453
 
        cvin[inParamIndex].type = cert_pi_useAIACertFetch;
454
 
        cvin[inParamIndex].value.scalar.b = certFetching;
455
 
        inParamIndex++;
456
 
 
457
 
        cvin[inParamIndex].type = cert_pi_date;
458
 
        cvin[inParamIndex].value.scalar.time = time;
459
 
        inParamIndex++;
460
 
 
461
 
        revFlags[cert_revocation_method_crl] = 
462
 
            CERT_REV_M_TEST_USING_THIS_METHOD;
463
 
        rev.leafTests.number_of_defined_methods = 
464
 
            cert_revocation_method_crl +1;
465
 
        rev.chainTests.number_of_defined_methods = 
466
 
            cert_revocation_method_crl +1;
467
 
 
468
 
        if (revConfig && strcmp(REVCONFIG_ALLOW_CRL_OCSP, revConfig) == 0) {
469
 
            revFlags[cert_revocation_method_ocsp] = 
470
 
                CERT_REV_M_TEST_USING_THIS_METHOD;
471
 
            rev.leafTests.number_of_defined_methods = 
472
 
                cert_revocation_method_ocsp +1;
473
 
            rev.chainTests.number_of_defined_methods = 
474
 
                cert_revocation_method_ocsp +1;
475
 
        }
476
 
 
477
 
        rev.leafTests.cert_rev_flags_per_method = revFlags;
478
 
        rev.leafTests.number_of_preferred_methods = 0;
479
 
        rev.leafTests.preferred_methods = 0;
480
 
        rev.leafTests.cert_rev_method_independent_flags = 0;
481
 
      
482
 
        rev.chainTests.cert_rev_flags_per_method = revFlags;
483
 
        rev.chainTests.number_of_preferred_methods = 0;
484
 
        rev.chainTests.preferred_methods = 0;
485
 
        rev.chainTests.cert_rev_method_independent_flags = 0;
486
 
 
487
 
        cvin[inParamIndex].type = cert_pi_revocationFlags;
488
 
        cvin[inParamIndex].value.pointer.revocation = &rev;
489
 
        inParamIndex++;
490
 
 
491
 
        cvin[inParamIndex].type = cert_pi_end;
492
 
        
493
 
        cvout[0].type = cert_po_trustAnchor;
494
 
        cvout[0].value.pointer.cert = NULL;
495
 
        cvout[1].type = cert_po_certList;
496
 
        cvout[1].value.pointer.chain = NULL;
497
 
 
498
 
        /* setting pointer to CERTVerifyLog. Initialized structure
499
 
         * will be used CERT_PKIXVerifyCert */
500
 
        cvout[2].type = cert_po_errorLog;
501
 
        cvout[2].value.pointer.log = &log;
502
 
 
503
 
        cvout[3].type = cert_po_end;
504
 
        
505
 
        secStatus = CERT_PKIXVerifyCert(firstCert, certUsage,
506
 
                                        cvin, cvout, &pwdata);
507
 
        if (secStatus != SECSuccess) {
508
 
            break;
509
 
        }
510
 
        issuerCert = cvout[0].value.pointer.cert;
511
 
        builtChain = cvout[1].value.pointer.chain;
512
 
    } while (0);
513
 
 
514
 
    /* Display validation results */
515
 
    if (secStatus != SECSuccess || log.count > 0) {
516
 
        CERTVerifyLogNode *node = NULL;
517
 
        PRIntn err = PR_GetError();
518
 
        fprintf(stderr, "Chain is bad, %d = %s\n", err, SECU_Strerror(err));
519
 
 
520
 
        SECU_displayVerifyLog(stderr, &log, verbose); 
521
 
        /* Have cert refs in the log only in case of failure.
522
 
         * Destroy them. */
523
 
        for (node = log.head; node; node = node->next) {
524
 
            if (node->cert)
525
 
                CERT_DestroyCertificate(node->cert);
526
 
        }
527
 
        rv = 1;
528
 
    } else {
529
 
        fprintf(stderr, "Chain is good!\n");
530
 
        if (issuerCert) {
531
 
           if (verbose > 1) {
532
 
               rv = SEC_PrintCertificateAndTrust(issuerCert, "Root Certificate",
533
 
                                                 NULL);
534
 
               if (rv != SECSuccess) {
535
 
                 SECU_PrintError(progName, "problem printing certificate");
536
 
               }
537
 
           } else if (verbose > 0) {
538
 
              SECU_PrintName(stdout, &issuerCert->subject, "Root "
539
 
                             "Certificate Subject:", 0);
540
 
           }
541
 
           CERT_DestroyCertificate(issuerCert);
542
 
        }
543
 
         if (builtChain) {
544
 
            CERTCertListNode *node;
545
 
            int count = 0;
546
 
            char buff[256];
547
 
 
548
 
            if (verbose) { 
549
 
                for(node = CERT_LIST_HEAD(builtChain); !CERT_LIST_END(node, builtChain);
550
 
                    node = CERT_LIST_NEXT(node), count++ ) {
551
 
                    sprintf(buff, "Certificate %d Subject", count + 1);
552
 
                    SECU_PrintName(stdout, &node->cert->subject, buff, 0);
553
 
                }
554
 
            }
555
 
            CERT_DestroyCertList(builtChain);
556
 
         }
557
 
        rv = 0;
558
 
    }
 
629
        } else do {
 
630
                static CERTValOutParam cvout[4];
 
631
                static CERTValInParam cvin[6];
 
632
                SECOidTag oidTag;
 
633
                int inParamIndex = 0;
 
634
                static PRUint64 revFlagsLeaf[2];
 
635
                static PRUint64 revFlagsChain[2];
 
636
                static CERTRevocationFlags rev;
 
637
                
 
638
                if (oidStr) {
 
639
                    PRArenaPool *arena;
 
640
                    SECOidData od;
 
641
                    memset(&od, 0, sizeof od);
 
642
                    od.offset = SEC_OID_UNKNOWN;
 
643
                    od.desc = "User Defined Policy OID";
 
644
                    od.mechanism = CKM_INVALID_MECHANISM;
 
645
                    od.supportedExtension = INVALID_CERT_EXTENSION;
 
646
 
 
647
                    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
 
648
                    if ( !arena ) {
 
649
                        fprintf(stderr, "out of memory");
 
650
                        goto punt;
 
651
                    }
 
652
                    
 
653
                    secStatus = SEC_StringToOID(arena, &od.oid, oidStr, 0);
 
654
                    if (secStatus != SECSuccess) {
 
655
                        PORT_FreeArena(arena, PR_FALSE);
 
656
                        fprintf(stderr, "Can not encode oid: %s(%s)\n", oidStr,
 
657
                                SECU_Strerror(PORT_GetError()));
 
658
                        break;
 
659
                    }
 
660
                    
 
661
                    oidTag = SECOID_AddEntry(&od);
 
662
                    PORT_FreeArena(arena, PR_FALSE);
 
663
                    if (oidTag == SEC_OID_UNKNOWN) {
 
664
                        fprintf(stderr, "Can not add new oid to the dynamic "
 
665
                                "table: %s\n", oidStr);
 
666
                        secStatus = SECFailure;
 
667
                        break;
 
668
                    }
 
669
                    
 
670
                    cvin[inParamIndex].type = cert_pi_policyOID;
 
671
                    cvin[inParamIndex].value.arraySize = 1;
 
672
                    cvin[inParamIndex].value.array.oids = &oidTag;
 
673
                    
 
674
                    inParamIndex++;
 
675
                }
 
676
                
 
677
                if (trustedCertList) {
 
678
                    cvin[inParamIndex].type = cert_pi_trustAnchors;
 
679
                    cvin[inParamIndex].value.pointer.chain = trustedCertList;
 
680
                    
 
681
                    inParamIndex++;
 
682
                }
 
683
                
 
684
                cvin[inParamIndex].type = cert_pi_useAIACertFetch;
 
685
                cvin[inParamIndex].value.scalar.b = certFetching;
 
686
                inParamIndex++;
 
687
                
 
688
                rev.leafTests.cert_rev_flags_per_method = revFlagsLeaf;
 
689
                rev.chainTests.cert_rev_flags_per_method = revFlagsChain;
 
690
                secStatus = configureRevocationParams(&rev);
 
691
                if (secStatus) {
 
692
                    fprintf(stderr, "Can not config revocation parameters ");
 
693
                    break;
 
694
                }
 
695
                
 
696
                cvin[inParamIndex].type = cert_pi_revocationFlags;
 
697
                cvin[inParamIndex].value.pointer.revocation = &rev;
 
698
                inParamIndex++;
 
699
                
 
700
                if (time) {
 
701
                    cvin[inParamIndex].type = cert_pi_date;
 
702
                    cvin[inParamIndex].value.scalar.time = time;
 
703
                    inParamIndex++;
 
704
                }
 
705
                
 
706
                cvin[inParamIndex].type = cert_pi_end;
 
707
                
 
708
                cvout[0].type = cert_po_trustAnchor;
 
709
                cvout[0].value.pointer.cert = NULL;
 
710
                cvout[1].type = cert_po_certList;
 
711
                cvout[1].value.pointer.chain = NULL;
 
712
                
 
713
                /* setting pointer to CERTVerifyLog. Initialized structure
 
714
                 * will be used CERT_PKIXVerifyCert */
 
715
                cvout[2].type = cert_po_errorLog;
 
716
                cvout[2].value.pointer.log = &log;
 
717
                
 
718
                cvout[3].type = cert_po_end;
 
719
                
 
720
                secStatus = CERT_PKIXVerifyCert(firstCert, certUsage,
 
721
                                                cvin, cvout, &pwdata);
 
722
                if (secStatus != SECSuccess) {
 
723
                    break;
 
724
                }
 
725
                issuerCert = cvout[0].value.pointer.cert;
 
726
                builtChain = cvout[1].value.pointer.chain;
 
727
            } while (0);
 
728
        
 
729
        /* Display validation results */
 
730
        if (secStatus != SECSuccess || log.count > 0) {
 
731
            CERTVerifyLogNode *node = NULL;
 
732
            PRIntn err = PR_GetError();
 
733
            fprintf(stderr, "Chain is bad, %d = %s\n", err, SECU_Strerror(err));
 
734
            
 
735
            SECU_displayVerifyLog(stderr, &log, verbose); 
 
736
            /* Have cert refs in the log only in case of failure.
 
737
             * Destroy them. */
 
738
            for (node = log.head; node; node = node->next) {
 
739
                if (node->cert)
 
740
                    CERT_DestroyCertificate(node->cert);
 
741
            }
 
742
            rv = 1;
 
743
        } else {
 
744
            fprintf(stderr, "Chain is good!\n");
 
745
            if (issuerCert) {
 
746
                if (verbose > 1) {
 
747
                    rv = SEC_PrintCertificateAndTrust(issuerCert, "Root Certificate",
 
748
                                                      NULL);
 
749
                    if (rv != SECSuccess) {
 
750
                        SECU_PrintError(progName, "problem printing certificate");
 
751
                    }
 
752
                } else if (verbose > 0) {
 
753
                    SECU_PrintName(stdout, &issuerCert->subject, "Root "
 
754
                                   "Certificate Subject:", 0);
 
755
                }
 
756
                CERT_DestroyCertificate(issuerCert);
 
757
            }
 
758
            if (builtChain) {
 
759
                CERTCertListNode *node;
 
760
                int count = 0;
 
761
                char buff[256];
 
762
                
 
763
                if (verbose) { 
 
764
                    for(node = CERT_LIST_HEAD(builtChain); !CERT_LIST_END(node, builtChain);
 
765
                        node = CERT_LIST_NEXT(node), count++ ) {
 
766
                        sprintf(buff, "Certificate %d Subject", count + 1);
 
767
                        SECU_PrintName(stdout, &node->cert->subject, buff, 0);
 
768
                    }
 
769
                }
 
770
                CERT_DestroyCertList(builtChain);
 
771
            }
 
772
            rv = 0;
 
773
        }
 
774
    } while (--vfyCounts > 0);
559
775
 
560
776
    /* Need to destroy CERTVerifyLog arena at the end */
561
777
    PORT_FreeArena(log.arena, PR_FALSE);
569
785
    PORT_Free(progName);
570
786
    PORT_Free(certDir);
571
787
    PORT_Free(oidStr);
572
 
    PORT_Free(revConfig);
 
788
    freeRevocationMethodData();
573
789
    if (pwdata.data) {
574
790
        PORT_Free(pwdata.data);
575
791
    }