summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralexei.volkov.bugs%sun.com <devnull@localhost>2009-04-01 20:41:29 +0000
committeralexei.volkov.bugs%sun.com <devnull@localhost>2009-04-01 20:41:29 +0000
commite08bf52f186daca756e4c90dee4ce4f30579daf8 (patch)
tree22cb821b8a8f75da1940c45ee1e8bac1b3f894fc
parent4bb8e2ca761791a80fa8d17c3501aff2c86506fe (diff)
downloadnss-hg-e08bf52f186daca756e4c90dee4ce4f30579daf8.tar.gz
412468 - modify certutil, vfychain and vfyserv utilities to use CERT_PKIXVerifyCert function. add option to validate the same cert multiple times. r=nelson
-rw-r--r--security/nss/cmd/vfychain/vfychain.c318
1 files changed, 163 insertions, 155 deletions
diff --git a/security/nss/cmd/vfychain/vfychain.c b/security/nss/cmd/vfychain/vfychain.c
index 3d04e53c6..fb60bad0f 100644
--- a/security/nss/cmd/vfychain/vfychain.c
+++ b/security/nss/cmd/vfychain/vfychain.c
@@ -87,6 +87,7 @@ Usage(const char *progName)
"\t-a\t\t Following certfile is base64 encoded\n"
"\t-b YYMMDDHHMMZ\t Validate date (default: now)\n"
"\t-d directory\t Database directory\n"
+ "\t-i number of consecutive verifications\n"
"\t-f \t\t Enable cert fetching from AIA URL\n"
"\t-o oid\t\t Set policy OID for cert validation(Format OID.1.2.3)\n"
"\t-p \t\t Use PKIX Library to validate certificate by calling:\n"
@@ -457,12 +458,13 @@ main(int argc, char *argv[], char *envp[])
int revDataIndex = 0;
PRBool ocsp_fetchingFailureIsAFailure = PR_TRUE;
PRBool useDefaultRevFlags = PR_TRUE;
+ int vfyCounts = 1;
PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
progName = PL_strdup(argv[0]);
- optstate = PL_CreateOptState(argc, argv, "ab:c:d:efg:h:m:o:prs:tu:vw:W:");
+ optstate = PL_CreateOptState(argc, argv, "ab:c:d:efg:h:i:m:o:prs:tu:vw:W:");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch(optstate->option) {
case 0 : /* positional parameter */ goto breakout;
@@ -489,6 +491,8 @@ main(int argc, char *argv[], char *envp[])
case 'h' :
revMethodsData[revDataIndex].
testFlagsStr = PL_strdup(optstate->value);break;
+ case 'i' : vfyCounts = PORT_Atoi(optstate->value); break;
+ break;
case 'm' :
if (revMethodsData[revDataIndex].methodTypeStr) {
revDataIndex += 1;
@@ -599,171 +603,175 @@ breakout:
if (status == PL_OPT_BAD || !firstCert)
Usage(progName);
- if (!time)
- time = PR_Now();
-
/* Initialize log structure */
log.arena = PORT_NewArena(512);
log.head = log.tail = NULL;
log.count = 0;
- if (usePkix < 2) {
- /* NOW, verify the cert chain. */
- if (usePkix) {
- /* Use old API with libpkix validation lib */
- CERT_SetUsePKIXForValidation(PR_TRUE);
- }
- defaultDB = CERT_GetDefaultCertDB();
- secStatus = CERT_VerifyCertificate(defaultDB, firstCert,
- PR_TRUE /* check sig */,
- certUsage,
- time,
- &pwdata, /* wincx */
- &log, /* error log */
- NULL);/* returned usages */
- } else do {
- static CERTValOutParam cvout[4];
- static CERTValInParam cvin[6];
- SECOidTag oidTag;
- int inParamIndex = 0;
- static PRUint64 revFlagsLeaf[2];
- static PRUint64 revFlagsChain[2];
- static CERTRevocationFlags rev;
-
- if (oidStr) {
- PRArenaPool *arena;
- SECOidData od;
- memset(&od, 0, sizeof od);
- od.offset = SEC_OID_UNKNOWN;
- od.desc = "User Defined Policy OID";
- od.mechanism = CKM_INVALID_MECHANISM;
- od.supportedExtension = INVALID_CERT_EXTENSION;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- fprintf(stderr, "out of memory");
- goto punt;
+ do {
+ if (usePkix < 2) {
+ /* NOW, verify the cert chain. */
+ if (usePkix) {
+ /* Use old API with libpkix validation lib */
+ CERT_SetUsePKIXForValidation(PR_TRUE);
}
+ if (!time)
+ time = PR_Now();
+
+ defaultDB = CERT_GetDefaultCertDB();
+ secStatus = CERT_VerifyCertificate(defaultDB, firstCert,
+ PR_TRUE /* check sig */,
+ certUsage,
+ time,
+ &pwdata, /* wincx */
+ &log, /* error log */
+ NULL);/* returned usages */
+ } else do {
+ static CERTValOutParam cvout[4];
+ static CERTValInParam cvin[6];
+ SECOidTag oidTag;
+ int inParamIndex = 0;
+ static PRUint64 revFlagsLeaf[2];
+ static PRUint64 revFlagsChain[2];
+ static CERTRevocationFlags rev;
+
+ if (oidStr) {
+ PRArenaPool *arena;
+ SECOidData od;
+ memset(&od, 0, sizeof od);
+ od.offset = SEC_OID_UNKNOWN;
+ od.desc = "User Defined Policy OID";
+ od.mechanism = CKM_INVALID_MECHANISM;
+ od.supportedExtension = INVALID_CERT_EXTENSION;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( !arena ) {
+ fprintf(stderr, "out of memory");
+ goto punt;
+ }
+
+ secStatus = SEC_StringToOID(arena, &od.oid, oidStr, 0);
+ if (secStatus != SECSuccess) {
+ PORT_FreeArena(arena, PR_FALSE);
+ fprintf(stderr, "Can not encode oid: %s(%s)\n", oidStr,
+ SECU_Strerror(PORT_GetError()));
+ break;
+ }
+
+ oidTag = SECOID_AddEntry(&od);
+ PORT_FreeArena(arena, PR_FALSE);
+ if (oidTag == SEC_OID_UNKNOWN) {
+ fprintf(stderr, "Can not add new oid to the dynamic "
+ "table: %s\n", oidStr);
+ secStatus = SECFailure;
+ break;
+ }
+
+ cvin[inParamIndex].type = cert_pi_policyOID;
+ cvin[inParamIndex].value.arraySize = 1;
+ cvin[inParamIndex].value.array.oids = &oidTag;
+
+ inParamIndex++;
+ }
+
+ if (trustedCertList) {
+ cvin[inParamIndex].type = cert_pi_trustAnchors;
+ cvin[inParamIndex].value.pointer.chain = trustedCertList;
+
+ inParamIndex++;
+ }
+
+ cvin[inParamIndex].type = cert_pi_useAIACertFetch;
+ cvin[inParamIndex].value.scalar.b = certFetching;
+ inParamIndex++;
+
+ rev.leafTests.cert_rev_flags_per_method = revFlagsLeaf;
+ rev.chainTests.cert_rev_flags_per_method = revFlagsChain;
+ secStatus = configureRevocationParams(&rev);
+ if (secStatus) {
+ fprintf(stderr, "Can not config revocation parameters ");
+ break;
+ }
+
+ cvin[inParamIndex].type = cert_pi_revocationFlags;
+ cvin[inParamIndex].value.pointer.revocation = &rev;
+ inParamIndex++;
+
+ if (time) {
+ cvin[inParamIndex].type = cert_pi_date;
+ cvin[inParamIndex].value.scalar.time = time;
+ inParamIndex++;
+ }
+
+ cvin[inParamIndex].type = cert_pi_end;
+
+ cvout[0].type = cert_po_trustAnchor;
+ cvout[0].value.pointer.cert = NULL;
+ cvout[1].type = cert_po_certList;
+ cvout[1].value.pointer.chain = NULL;
+
+ /* setting pointer to CERTVerifyLog. Initialized structure
+ * will be used CERT_PKIXVerifyCert */
+ cvout[2].type = cert_po_errorLog;
+ cvout[2].value.pointer.log = &log;
+
+ cvout[3].type = cert_po_end;
+
+ secStatus = CERT_PKIXVerifyCert(firstCert, certUsage,
+ cvin, cvout, &pwdata);
+ if (secStatus != SECSuccess) {
+ break;
+ }
+ issuerCert = cvout[0].value.pointer.cert;
+ builtChain = cvout[1].value.pointer.chain;
+ } while (0);
+
+ /* Display validation results */
+ if (secStatus != SECSuccess || log.count > 0) {
+ CERTVerifyLogNode *node = NULL;
+ PRIntn err = PR_GetError();
+ fprintf(stderr, "Chain is bad, %d = %s\n", err, SECU_Strerror(err));
- secStatus = SEC_StringToOID(arena, &od.oid, oidStr, 0);
- if (secStatus != SECSuccess) {
- PORT_FreeArena(arena, PR_FALSE);
- fprintf(stderr, "Can not encode oid: %s(%s)\n", oidStr,
- SECU_Strerror(PORT_GetError()));
- break;
+ SECU_displayVerifyLog(stderr, &log, verbose);
+ /* Have cert refs in the log only in case of failure.
+ * Destroy them. */
+ for (node = log.head; node; node = node->next) {
+ if (node->cert)
+ CERT_DestroyCertificate(node->cert);
}
-
- oidTag = SECOID_AddEntry(&od);
- PORT_FreeArena(arena, PR_FALSE);
- if (oidTag == SEC_OID_UNKNOWN) {
- fprintf(stderr, "Can not add new oid to the dynamic "
- "table: %s\n", oidStr);
- secStatus = SECFailure;
- break;
+ rv = 1;
+ } else {
+ fprintf(stderr, "Chain is good!\n");
+ if (issuerCert) {
+ if (verbose > 1) {
+ rv = SEC_PrintCertificateAndTrust(issuerCert, "Root Certificate",
+ NULL);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "problem printing certificate");
+ }
+ } else if (verbose > 0) {
+ SECU_PrintName(stdout, &issuerCert->subject, "Root "
+ "Certificate Subject:", 0);
+ }
+ CERT_DestroyCertificate(issuerCert);
}
-
- cvin[inParamIndex].type = cert_pi_policyOID;
- cvin[inParamIndex].value.arraySize = 1;
- cvin[inParamIndex].value.array.oids = &oidTag;
-
- inParamIndex++;
- }
-
- if (trustedCertList) {
- cvin[inParamIndex].type = cert_pi_trustAnchors;
- cvin[inParamIndex].value.pointer.chain = trustedCertList;
-
- inParamIndex++;
- }
-
- cvin[inParamIndex].type = cert_pi_useAIACertFetch;
- cvin[inParamIndex].value.scalar.b = certFetching;
- inParamIndex++;
-
- rev.leafTests.cert_rev_flags_per_method = revFlagsLeaf;
- rev.chainTests.cert_rev_flags_per_method = revFlagsChain;
- secStatus = configureRevocationParams(&rev);
- if (secStatus) {
- fprintf(stderr, "Can not config revocation parameters ");
- break;
- }
-
- cvin[inParamIndex].type = cert_pi_revocationFlags;
- cvin[inParamIndex].value.pointer.revocation = &rev;
- inParamIndex++;
-
- cvin[inParamIndex].type = cert_pi_date;
- cvin[inParamIndex].value.scalar.time = time;
- inParamIndex++;
-
- cvin[inParamIndex].type = cert_pi_end;
-
- cvout[0].type = cert_po_trustAnchor;
- cvout[0].value.pointer.cert = NULL;
- cvout[1].type = cert_po_certList;
- cvout[1].value.pointer.chain = NULL;
-
- /* setting pointer to CERTVerifyLog. Initialized structure
- * will be used CERT_PKIXVerifyCert */
- cvout[2].type = cert_po_errorLog;
- cvout[2].value.pointer.log = &log;
-
- cvout[3].type = cert_po_end;
-
- secStatus = CERT_PKIXVerifyCert(firstCert, certUsage,
- cvin, cvout, &pwdata);
- if (secStatus != SECSuccess) {
- break;
- }
- issuerCert = cvout[0].value.pointer.cert;
- builtChain = cvout[1].value.pointer.chain;
- } while (0);
-
- /* Display validation results */
- if (secStatus != SECSuccess || log.count > 0) {
- CERTVerifyLogNode *node = NULL;
- PRIntn err = PR_GetError();
- fprintf(stderr, "Chain is bad, %d = %s\n", err, SECU_Strerror(err));
-
- SECU_displayVerifyLog(stderr, &log, verbose);
- /* Have cert refs in the log only in case of failure.
- * Destroy them. */
- for (node = log.head; node; node = node->next) {
- if (node->cert)
- CERT_DestroyCertificate(node->cert);
- }
- rv = 1;
- } else {
- fprintf(stderr, "Chain is good!\n");
- if (issuerCert) {
- if (verbose > 1) {
- rv = SEC_PrintCertificateAndTrust(issuerCert, "Root Certificate",
- NULL);
- if (rv != SECSuccess) {
- SECU_PrintError(progName, "problem printing certificate");
- }
- } else if (verbose > 0) {
- SECU_PrintName(stdout, &issuerCert->subject, "Root "
- "Certificate Subject:", 0);
- }
- CERT_DestroyCertificate(issuerCert);
- }
- if (builtChain) {
- CERTCertListNode *node;
- int count = 0;
- char buff[256];
-
- if (verbose) {
- for(node = CERT_LIST_HEAD(builtChain); !CERT_LIST_END(node, builtChain);
- node = CERT_LIST_NEXT(node), count++ ) {
- sprintf(buff, "Certificate %d Subject", count + 1);
- SECU_PrintName(stdout, &node->cert->subject, buff, 0);
+ if (builtChain) {
+ CERTCertListNode *node;
+ int count = 0;
+ char buff[256];
+
+ if (verbose) {
+ for(node = CERT_LIST_HEAD(builtChain); !CERT_LIST_END(node, builtChain);
+ node = CERT_LIST_NEXT(node), count++ ) {
+ sprintf(buff, "Certificate %d Subject", count + 1);
+ SECU_PrintName(stdout, &node->cert->subject, buff, 0);
+ }
}
+ CERT_DestroyCertList(builtChain);
}
- CERT_DestroyCertList(builtChain);
- }
- rv = 0;
- }
+ rv = 0;
+ }
+ } while (--vfyCounts > 0);
/* Need to destroy CERTVerifyLog arena at the end */
PORT_FreeArena(log.arena, PR_FALSE);