list.c (6361B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "signtool.h" 6 #include "pk11func.h" 7 #include "certdb.h" 8 9 static int num_trav_certs = 0; 10 static SECStatus cert_trav_callback(CERTCertificate *cert, SECItem *k, 11 void *data); 12 13 /********************************************************************* 14 * 15 * L i s t C e r t s 16 */ 17 int 18 ListCerts(char *key, int list_certs) 19 { 20 int failed = 0; 21 SECStatus rv; 22 CERTCertDBHandle *db; 23 24 CERTCertificate *cert; 25 CERTVerifyLog errlog; 26 27 errlog.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 28 if (errlog.arena == NULL) { 29 out_of_memory(); 30 } 31 errlog.head = NULL; 32 errlog.tail = NULL; 33 errlog.count = 0; 34 35 db = CERT_GetDefaultCertDB(); 36 37 if (list_certs == 2) { 38 PR_fprintf(outputFD, "\nS Certificates\n"); 39 PR_fprintf(outputFD, "- ------------\n"); 40 } else { 41 PR_fprintf(outputFD, "\nObject signing certificates\n"); 42 PR_fprintf(outputFD, "---------------------------------------\n"); 43 } 44 45 num_trav_certs = 0; 46 47 /* Traverse ALL tokens in all slots, authenticating to them all */ 48 rv = PK11_TraverseSlotCerts(cert_trav_callback, (void *)&list_certs, 49 &pwdata); 50 51 if (rv) { 52 PR_fprintf(outputFD, "**Traverse of ALL slots & tokens failed**\n"); 53 return -1; 54 } 55 56 if (num_trav_certs == 0) { 57 PR_fprintf(outputFD, 58 "You don't appear to have any object signing certificates.\n"); 59 } 60 61 if (list_certs == 2) { 62 PR_fprintf(outputFD, "- ------------\n"); 63 } else { 64 PR_fprintf(outputFD, "---------------------------------------\n"); 65 } 66 67 if (list_certs == 1) { 68 PR_fprintf(outputFD, 69 "For a list including CA's, use \"%s -L\"\n", PROGRAM_NAME); 70 } 71 72 if (list_certs == 2) { 73 PR_fprintf(outputFD, 74 "Certificates that can be used to sign objects have *'s to " 75 "their left.\n"); 76 } 77 78 if (key) { 79 /* Do an analysis of the given cert */ 80 81 cert = PK11_FindCertFromNickname(key, &pwdata); 82 83 if (cert) { 84 PR_fprintf(outputFD, 85 "\nThe certificate with nickname \"%s\" was found:\n", 86 cert->nickname); 87 PR_fprintf(outputFD, "\tsubject name: %s\n", cert->subjectName); 88 PR_fprintf(outputFD, "\tissuer name: %s\n", cert->issuerName); 89 90 PR_fprintf(outputFD, "\n"); 91 92 rv = CERT_CertTimesValid(cert); 93 if (rv != SECSuccess) { 94 PR_fprintf(outputFD, "**This certificate is expired**\n"); 95 } else { 96 PR_fprintf(outputFD, "This certificate is not expired.\n"); 97 } 98 99 rv = CERT_VerifyCert(db, cert, PR_TRUE, 100 certUsageObjectSigner, PR_Now(), &pwdata, &errlog); 101 102 if (rv != SECSuccess) { 103 failed = 1; 104 if (errlog.count > 0) { 105 PR_fprintf(outputFD, 106 "**Certificate validation failed for the " 107 "following reason(s):**\n"); 108 } else { 109 PR_fprintf(outputFD, "**Certificate validation failed**"); 110 } 111 } else { 112 PR_fprintf(outputFD, "This certificate is valid.\n"); 113 } 114 displayVerifyLog(&errlog); 115 116 } else { 117 failed = 1; 118 PR_fprintf(outputFD, 119 "The certificate with nickname \"%s\" was NOT FOUND\n", key); 120 } 121 } 122 123 if (errlog.arena != NULL) { 124 PORT_FreeArena(errlog.arena, PR_FALSE); 125 } 126 127 if (failed) { 128 return -1; 129 } 130 return 0; 131 } 132 133 /******************************************************************** 134 * 135 * c e r t _ t r a v _ c a l l b a c k 136 */ 137 static SECStatus 138 cert_trav_callback(CERTCertificate *cert, SECItem *k, void *data) 139 { 140 int list_certs = 1; 141 char *name; 142 143 if (data) { 144 list_certs = *((int *)data); 145 } 146 147 #define LISTING_USER_SIGNING_CERTS (list_certs == 1) 148 #define LISTING_ALL_CERTS (list_certs == 2) 149 150 name = cert->nickname; 151 if (name) { 152 int isSigningCert; 153 154 isSigningCert = cert->nsCertType & NS_CERT_TYPE_OBJECT_SIGNING; 155 if (!isSigningCert && LISTING_USER_SIGNING_CERTS) 156 return (SECSuccess); 157 158 /* Display this name or email address */ 159 num_trav_certs++; 160 161 if (LISTING_ALL_CERTS) { 162 PR_fprintf(outputFD, "%s ", isSigningCert ? "*" : " "); 163 } 164 PR_fprintf(outputFD, "%s\n", name); 165 166 if (LISTING_USER_SIGNING_CERTS) { 167 int rv = SECFailure; 168 if (rv) { 169 CERTCertificate *issuerCert; 170 issuerCert = CERT_FindCertIssuer(cert, PR_Now(), 171 certUsageObjectSigner); 172 if (issuerCert) { 173 if (issuerCert->nickname && issuerCert->nickname[0]) { 174 PR_fprintf(outputFD, " Issued by: %s\n", 175 issuerCert->nickname); 176 rv = SECSuccess; 177 } 178 CERT_DestroyCertificate(issuerCert); 179 } 180 } 181 if (rv && cert->issuerName && cert->issuerName[0]) { 182 PR_fprintf(outputFD, " Issued by: %s \n", cert->issuerName); 183 } 184 { 185 char *expires; 186 expires = DER_TimeChoiceDayToAscii(&cert->validity.notAfter); 187 if (expires) { 188 PR_fprintf(outputFD, " Expires: %s\n", expires); 189 PORT_Free(expires); 190 } 191 } 192 193 rv = CERT_VerifyCertNow(cert->dbhandle, cert, 194 PR_TRUE, certUsageObjectSigner, &pwdata); 195 196 if (rv != SECSuccess) { 197 rv = PORT_GetError(); 198 PR_fprintf(outputFD, 199 " ++ Error ++ THIS CERTIFICATE IS NOT VALID (%s)\n", 200 secErrorString(rv)); 201 } 202 } 203 } 204 205 return (SECSuccess); 206 }