/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ #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) { SECStatus rv; char *ugly_list; 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; ugly_list = PORT_ZAlloc (16); if (ugly_list == NULL) { out_of_memory(); } *ugly_list = 0; db= OpenCertDB(PR_TRUE /*readOnly*/); 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 non-internal DBs */ rv = PK11_TraverseSlotCerts(cert_trav_callback, (void*)&list_certs, NULL /*wincx*/); /* Traverse Internal DB */ rv = SEC_TraversePermCerts(db, cert_trav_callback, (void*)&list_certs); 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 (rv) { return -1; } 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 */ SECStatus rv; cert = PK11_FindCertFromNickname(key, NULL /*wincx*/); 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(), NULL, &errlog); if (rv != SECSuccess) { 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 { PR_fprintf(outputFD, "The certificate with nickname \"%s\" was NOT FOUND\n", key); } } if(errlog.arena != NULL) { PORT_FreeArena(errlog.arena, PR_FALSE); } 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 isSigningCert; int list_certs = 1; char *name, *issuerCN, *expires; CERTCertificate *issuerCert = NULL; if(data) { list_certs = *((int*)data); } if (cert->nickname) { name = cert->nickname; isSigningCert = cert->nsCertType & NS_CERT_TYPE_OBJECT_SIGNING; issuerCert = CERT_FindCertIssuer (cert, PR_Now(), certUsageObjectSigner); issuerCN = CERT_GetCommonName (&cert->issuer); if (!isSigningCert && list_certs == 1) return (SECSuccess); /* Add this name or email to list */ if (name) { int rv; num_trav_certs++; if(list_certs == 2) { PR_fprintf(outputFD, "%s ", isSigningCert ? "*" : " "); } PR_fprintf(outputFD, "%s\n", name); if (list_certs == 1) { if(issuerCert == NULL) { PR_fprintf(outputFD, "\t++ Error ++ Unable to find issuer certificate\n"); return SECSuccess; /*function was a success even if cert is bogus*/ } if (issuerCN == NULL) PR_fprintf(outputFD, " Issued by: %s\n", issuerCert->nickname); else PR_fprintf(outputFD, " Issued by: %s (%s)\n", issuerCert->nickname, issuerCN); expires = DER_UTCDayToAscii (&cert->validity.notAfter); if (expires) PR_fprintf(outputFD, " Expires: %s\n", expires); rv = CERT_CertTimesValid (cert); if (rv != SECSuccess) PR_fprintf(outputFD, " ++ Error ++ THIS CERTIFICATE IS EXPIRED\n"); if (rv == SECSuccess) { rv = CERT_VerifyCertNow (cert->dbhandle, cert, PR_TRUE, certUsageObjectSigner, NULL); if (rv != SECSuccess) { rv = PORT_GetError(); PR_fprintf(outputFD, " ++ Error ++ THIS CERTIFICATE IS NOT VALID (%s)\n", secErrorString(rv)); } } expires = DER_UTCDayToAscii (&issuerCert->validity.notAfter); if (expires == NULL) expires = "(unknown)"; rv = CERT_CertTimesValid (issuerCert); if (rv != SECSuccess) PR_fprintf(outputFD, " ++ Error ++ ISSUER CERT \"%s\" EXPIRED ON %s\n", issuerCert->nickname, expires); if (rv == SECSuccess) { /* rv = CERT_VerifyCertNow (issuerCert->dbhandle, issuerCert, PR_TRUE, certUsageVerifyCA, NULL); */ rv = CERT_VerifyCertNow (issuerCert->dbhandle, issuerCert, PR_TRUE, certUsageAnyCA, NULL); if (rv != SECSuccess) { rv = PORT_GetError(); PR_fprintf(outputFD, " ++ Error ++ ISSUER CERT \"%s\" IS NOT VALID (%s)\n", issuerCert->nickname, secErrorString(rv)); } } } } } return (SECSuccess); }