/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "signtool.h" #include "pk11func.h" #include "certdb.h" static int num_trav_certs = 0; static SECStatus cert_trav_callback(CERTCertificate *cert, SECItem *k, void *data); /********************************************************************* * * L i s t C e r t s */ int ListCerts(char *key, int list_certs) { int failed = 0; SECStatus rv; CERTCertDBHandle *db; CERTCertificate *cert; CERTVerifyLog errlog; errlog.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (errlog.arena == NULL) { out_of_memory(); } errlog.head = NULL; errlog.tail = NULL; errlog.count = 0; db = CERT_GetDefaultCertDB(); if (list_certs == 2) { PR_fprintf(outputFD, "\nS Certificates\n"); PR_fprintf(outputFD, "- ------------\n"); } else { PR_fprintf(outputFD, "\nObject signing certificates\n"); PR_fprintf(outputFD, "---------------------------------------\n"); } num_trav_certs = 0; /* Traverse ALL tokens in all slots, authenticating to them all */ rv = PK11_TraverseSlotCerts(cert_trav_callback, (void *)&list_certs, &pwdata); if (rv) { PR_fprintf(outputFD, "**Traverse of ALL slots & tokens failed**\n"); return -1; } if (num_trav_certs == 0) { PR_fprintf(outputFD, "You don't appear to have any object signing certificates.\n"); } if (list_certs == 2) { PR_fprintf(outputFD, "- ------------\n"); } else { PR_fprintf(outputFD, "---------------------------------------\n"); } if (list_certs == 1) { PR_fprintf(outputFD, "For a list including CA's, use \"%s -L\"\n", PROGRAM_NAME); } if (list_certs == 2) { PR_fprintf(outputFD, "Certificates that can be used to sign objects have *'s to " "their left.\n"); } if (key) { /* Do an analysis of the given cert */ cert = PK11_FindCertFromNickname(key, &pwdata); if (cert) { PR_fprintf(outputFD, "\nThe certificate with nickname \"%s\" was found:\n", cert->nickname); PR_fprintf(outputFD, "\tsubject name: %s\n", cert->subjectName); PR_fprintf(outputFD, "\tissuer name: %s\n", cert->issuerName); PR_fprintf(outputFD, "\n"); rv = CERT_CertTimesValid(cert); if (rv != SECSuccess) { PR_fprintf(outputFD, "**This certificate is expired**\n"); } else { PR_fprintf(outputFD, "This certificate is not expired.\n"); } rv = CERT_VerifyCert(db, cert, PR_TRUE, certUsageObjectSigner, PR_Now(), &pwdata, &errlog); if (rv != SECSuccess) { failed = 1; if (errlog.count > 0) { PR_fprintf(outputFD, "**Certificate validation failed for the " "following reason(s):**\n"); } else { PR_fprintf(outputFD, "**Certificate validation failed**"); } } else { PR_fprintf(outputFD, "This certificate is valid.\n"); } displayVerifyLog(&errlog); } else { failed = 1; PR_fprintf(outputFD, "The certificate with nickname \"%s\" was NOT FOUND\n", key); } } if (errlog.arena != NULL) { PORT_FreeArena(errlog.arena, PR_FALSE); } if (failed) { return -1; } return 0; } /******************************************************************** * * c e r t _ t r a v _ c a l l b a c k */ static SECStatus cert_trav_callback(CERTCertificate *cert, SECItem *k, void *data) { int list_certs = 1; char *name; if (data) { list_certs = *((int *)data); } #define LISTING_USER_SIGNING_CERTS (list_certs == 1) #define LISTING_ALL_CERTS (list_certs == 2) name = cert->nickname; if (name) { int isSigningCert; isSigningCert = cert->nsCertType & NS_CERT_TYPE_OBJECT_SIGNING; if (!isSigningCert && LISTING_USER_SIGNING_CERTS) return (SECSuccess); /* Display this name or email address */ num_trav_certs++; if (LISTING_ALL_CERTS) { PR_fprintf(outputFD, "%s ", isSigningCert ? "*" : " "); } PR_fprintf(outputFD, "%s\n", name); if (LISTING_USER_SIGNING_CERTS) { int rv = SECFailure; if (rv) { CERTCertificate *issuerCert; issuerCert = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner); if (issuerCert) { if (issuerCert->nickname && issuerCert->nickname[0]) { PR_fprintf(outputFD, " Issued by: %s\n", issuerCert->nickname); rv = SECSuccess; } CERT_DestroyCertificate(issuerCert); } } if (rv && cert->issuerName && cert->issuerName[0]) { PR_fprintf(outputFD, " Issued by: %s \n", cert->issuerName); } { char *expires; expires = DER_TimeChoiceDayToAscii(&cert->validity.notAfter); if (expires) { PR_fprintf(outputFD, " Expires: %s\n", expires); PORT_Free(expires); } } rv = CERT_VerifyCertNow(cert->dbhandle, cert, PR_TRUE, certUsageObjectSigner, &pwdata); if (rv != SECSuccess) { rv = PORT_GetError(); PR_fprintf(outputFD, " ++ Error ++ THIS CERTIFICATE IS NOT VALID (%s)\n", secErrorString(rv)); } } } return (SECSuccess); }