tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }