Back to index

lightning-sunbird  0.9+nobinonly
list.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #include "signtool.h"
00038 #include "pk11func.h"
00039 #include "certdb.h"
00040 
00041 static int    num_trav_certs = 0;
00042 static SECStatus cert_trav_callback(CERTCertificate *cert, SECItem *k,
00043                      void *data);
00044 
00045 /*********************************************************************
00046  *
00047  * L i s t C e r t s
00048  */
00049 int
00050 ListCerts(char *key, int list_certs)
00051 {
00052     int       failed = 0;
00053     SECStatus rv;
00054     char      *ugly_list;
00055     CERTCertDBHandle * db;
00056 
00057     CERTCertificate * cert;
00058     CERTVerifyLog errlog;
00059 
00060     errlog.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
00061     if ( errlog.arena == NULL) {
00062        out_of_memory();
00063     }
00064     errlog.head = NULL;
00065     errlog.tail = NULL;
00066     errlog.count = 0;
00067 
00068     ugly_list = PORT_ZAlloc (16);
00069 
00070     if (ugly_list == NULL) {
00071        out_of_memory();
00072     }
00073 
00074     *ugly_list = 0;
00075 
00076     db = CERT_GetDefaultCertDB();
00077 
00078     if (list_certs == 2) {
00079        PR_fprintf(outputFD, "\nS Certificates\n");
00080        PR_fprintf(outputFD, "- ------------\n");
00081     } else {
00082        PR_fprintf(outputFD, "\nObject signing certificates\n");
00083        PR_fprintf(outputFD, "---------------------------------------\n");
00084     }
00085 
00086     num_trav_certs = 0;
00087 
00088     /* Traverse non-internal DBs */
00089     rv = PK11_TraverseSlotCerts(cert_trav_callback, (void * )&list_certs,
00090                      NULL /*wincx*/);
00091 
00092     if (rv) {
00093        PR_fprintf(outputFD, "**Traverse of non-internal DBs failed**\n");
00094        return - 1;
00095     }
00096 
00097     if (num_trav_certs == 0) {
00098        PR_fprintf(outputFD,
00099            "You don't appear to have any object signing certificates.\n");
00100     }
00101 
00102     if (list_certs == 2) {
00103        PR_fprintf(outputFD, "- ------------\n");
00104     } else {
00105        PR_fprintf(outputFD, "---------------------------------------\n");
00106     }
00107 
00108     if (list_certs == 1) {
00109        PR_fprintf(outputFD,
00110            "For a list including CA's, use \"%s -L\"\n", PROGRAM_NAME);
00111     }
00112 
00113     if (list_certs == 2) {
00114        PR_fprintf(outputFD,
00115            "Certificates that can be used to sign objects have *'s to "
00116            "their left.\n");
00117     }
00118 
00119     if (key) {
00120        /* Do an analysis of the given cert */
00121 
00122        cert = PK11_FindCertFromNickname(key, NULL /*wincx*/);
00123 
00124        if (cert) {
00125            PR_fprintf(outputFD,
00126                "\nThe certificate with nickname \"%s\" was found:\n",
00127                                     cert->nickname);
00128            PR_fprintf(outputFD, "\tsubject name: %s\n", cert->subjectName);
00129            PR_fprintf(outputFD, "\tissuer name: %s\n", cert->issuerName);
00130 
00131            PR_fprintf(outputFD, "\n");
00132 
00133            rv = CERT_CertTimesValid (cert);
00134            if (rv != SECSuccess) {
00135               PR_fprintf(outputFD, "**This certificate is expired**\n");
00136            } else {
00137               PR_fprintf(outputFD, "This certificate is not expired.\n");
00138            }
00139 
00140            rv = CERT_VerifyCert (db, cert, PR_TRUE,
00141                certUsageObjectSigner, PR_Now(), NULL, &errlog);
00142 
00143            if (rv != SECSuccess) {
00144               failed = 1;
00145               if (errlog.count > 0) {
00146                   PR_fprintf(outputFD,
00147                       "**Certificate validation failed for the "
00148                       "following reason(s):**\n");
00149               } else {
00150                   PR_fprintf(outputFD, "**Certificate validation failed**");
00151               }
00152            } else {
00153               PR_fprintf(outputFD, "This certificate is valid.\n");
00154            }
00155            displayVerifyLog(&errlog);
00156 
00157 
00158        } else {
00159            failed = 1;
00160            PR_fprintf(outputFD,
00161                "The certificate with nickname \"%s\" was NOT FOUND\n", key);
00162        }
00163     }
00164 
00165     if (errlog.arena != NULL) {
00166        PORT_FreeArena(errlog.arena, PR_FALSE);
00167     }
00168 
00169     if (failed) {
00170        return - 1;
00171     }
00172     return 0;
00173 }
00174 
00175 
00176 /********************************************************************
00177  *
00178  * c e r t _ t r a v _ c a l l b a c k
00179  */
00180 static SECStatus
00181 cert_trav_callback(CERTCertificate *cert, SECItem *k, void *data)
00182 {
00183     int       isSigningCert;
00184     int       list_certs = 1;
00185 
00186     char      *name, *issuerCN, *expires;
00187     CERTCertificate * issuerCert = NULL;
00188 
00189     if (data) {
00190        list_certs = *((int * )data);
00191     }
00192 
00193     if (cert->nickname) {
00194        name = cert->nickname;
00195 
00196        isSigningCert = cert->nsCertType & NS_CERT_TYPE_OBJECT_SIGNING;
00197        issuerCert = CERT_FindCertIssuer (cert, PR_Now(), certUsageObjectSigner);
00198        issuerCN = CERT_GetCommonName (&cert->issuer);
00199 
00200        if (!isSigningCert && list_certs == 1)
00201            return (SECSuccess);
00202 
00203        /* Add this name or email to list */
00204 
00205        if (name) {
00206            int       rv;
00207 
00208            num_trav_certs++;
00209            if (list_certs == 2) {
00210               PR_fprintf(outputFD, "%s ", isSigningCert ? "*" : " ");
00211            }
00212            PR_fprintf(outputFD, "%s\n", name);
00213 
00214            if (list_certs == 1) {
00215               if (issuerCert == NULL) {
00216                   PR_fprintf(outputFD,
00217                       "\t++ Error ++ Unable to find issuer certificate\n");
00218                   return SECSuccess; 
00219                         /*function was a success even if cert is bogus*/
00220               }
00221               if (issuerCN == NULL)
00222                   PR_fprintf(outputFD, "    Issued by: %s\n",
00223                        issuerCert->nickname);
00224               else
00225                   PR_fprintf(outputFD,
00226                       "    Issued by: %s (%s)\n", issuerCert->nickname,
00227                        issuerCN);
00228 
00229               expires = DER_TimeChoiceDayToAscii(&cert->validity.notAfter);
00230 
00231               if (expires)
00232                   PR_fprintf(outputFD, "    Expires: %s\n", expires);
00233 
00234               rv = CERT_CertTimesValid (cert);
00235 
00236               if (rv != SECSuccess)
00237                   PR_fprintf(outputFD, 
00238                      "    ++ Error ++ THIS CERTIFICATE IS EXPIRED\n");
00239 
00240               if (rv == SECSuccess) {
00241                   rv = CERT_VerifyCertNow (cert->dbhandle, cert,
00242                       PR_TRUE, certUsageObjectSigner, NULL);
00243 
00244                   if (rv != SECSuccess) {
00245                      rv = PORT_GetError();
00246                      PR_fprintf(outputFD,
00247                      "    ++ Error ++ THIS CERTIFICATE IS NOT VALID (%s)\n",
00248                                                  secErrorString(rv));            
00249                   }
00250               }
00251 
00252               expires = DER_TimeChoiceDayToAscii(&issuerCert->validity.notAfter);
00253               if (expires == NULL) 
00254                   expires = "(unknown)";
00255 
00256               rv = CERT_CertTimesValid (issuerCert);
00257 
00258               if (rv != SECSuccess)
00259                   PR_fprintf(outputFD,
00260                       "    ++ Error ++ ISSUER CERT \"%s\" EXPIRED ON %s\n",
00261                      issuerCert->nickname, expires);
00262 
00263               if (rv == SECSuccess) {
00264                   rv = CERT_VerifyCertNow (issuerCert->dbhandle, issuerCert, 
00265                       PR_TRUE, certUsageVerifyCA, NULL);
00266                   if (rv != SECSuccess) {
00267                      rv = PORT_GetError();
00268                      PR_fprintf(outputFD,
00269                      "    ++ Error ++ ISSUER CERT \"%s\" IS NOT VALID (%s)\n",
00270                           issuerCert->nickname, secErrorString(rv));
00271                   }
00272               }
00273            }
00274        }
00275     }
00276 
00277     return (SECSuccess);
00278 }
00279 
00280