tor-browser

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

pp.c (6853B)


      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 /*
      6 * Pretty-print some well-known BER or DER encoded data (e.g. certificates,
      7 * keys, pkcs7)
      8 */
      9 
     10 #include "secutil.h"
     11 
     12 #if defined(__sun) && !defined(SVR4)
     13 extern int fprintf(FILE *, char *, ...);
     14 #endif
     15 
     16 #include "plgetopt.h"
     17 
     18 #include "pk11func.h"
     19 #include "nspr.h"
     20 #include "nss.h"
     21 
     22 static void
     23 Usage(char *progName)
     24 {
     25    fprintf(stderr,
     26            "Usage:  %s [-t type] [-a] [-i input] [-o output] [-w] [-u]\n",
     27            progName);
     28    fprintf(stderr, "Pretty prints a file containing ASN.1 data in DER or ascii format.\n");
     29    fprintf(stderr, "%-14s Specify input and display type:", "-t type");
     30    fprintf(stderr, " %s (sk),", SEC_CT_PRIVATE_KEY);
     31    fprintf(stderr, "\n");
     32    fprintf(stderr, "%-14s %s (pk), %s (c), %s (cr),\n", "", SEC_CT_PUBLIC_KEY,
     33            SEC_CT_CERTIFICATE, SEC_CT_CERTIFICATE_REQUEST);
     34    fprintf(stderr, "%-14s %s (ci), %s (p7), %s (p12), %s or %s (n).\n", "",
     35            SEC_CT_CERTIFICATE_ID, SEC_CT_PKCS7, SEC_CT_PKCS12,
     36            SEC_CT_CRL, SEC_CT_NAME);
     37    fprintf(stderr, "%-14s (Use either the long type name or the shortcut.)\n", "");
     38    fprintf(stderr, "%-14s Input is in ascii encoded form (RFC1113)\n",
     39            "-a");
     40    fprintf(stderr, "%-14s Define an input file to use (default is stdin)\n",
     41            "-i input");
     42    fprintf(stderr, "%-14s Define an output file to use (default is stdout)\n",
     43            "-o output");
     44    fprintf(stderr, "%-14s Don't wrap long output lines\n",
     45            "-w");
     46    fprintf(stderr, "%-14s Use UTF-8 (default is to show non-ascii as .)\n",
     47            "-u");
     48    exit(-1);
     49 }
     50 
     51 int
     52 main(int argc, char **argv)
     53 {
     54    int rv, ascii;
     55    char *progName;
     56    FILE *outFile;
     57    PRFileDesc *inFile;
     58    SECItem der, data;
     59    char *typeTag;
     60    PLOptState *optstate;
     61    PRBool wrap = PR_TRUE;
     62 
     63    progName = strrchr(argv[0], '/');
     64    progName = progName ? progName + 1 : argv[0];
     65 
     66    ascii = 0;
     67    inFile = 0;
     68    outFile = 0;
     69    typeTag = 0;
     70    optstate = PL_CreateOptState(argc, argv, "at:i:o:uw");
     71    while (PL_GetNextOpt(optstate) == PL_OPT_OK) {
     72        switch (optstate->option) {
     73            case '?':
     74                Usage(progName);
     75                break;
     76 
     77            case 'a':
     78                ascii = 1;
     79                break;
     80 
     81            case 'i':
     82                inFile = PR_Open(optstate->value, PR_RDONLY, 0);
     83                if (!inFile) {
     84                    fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
     85                            progName, optstate->value);
     86                    PORT_Free(typeTag);
     87                    PL_DestroyOptState(optstate);
     88                    return -1;
     89                }
     90                break;
     91 
     92            case 'o':
     93                outFile = fopen(optstate->value, "w");
     94                if (!outFile) {
     95                    fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
     96                            progName, optstate->value);
     97                    PORT_Free(typeTag);
     98                    PL_DestroyOptState(optstate);
     99                    return -1;
    100                }
    101                break;
    102 
    103            case 't':
    104                typeTag = strdup(optstate->value);
    105                break;
    106 
    107            case 'u':
    108                SECU_EnableUtf8Display(PR_TRUE);
    109                break;
    110 
    111            case 'w':
    112                wrap = PR_FALSE;
    113                break;
    114        }
    115    }
    116    PL_DestroyOptState(optstate);
    117    if (!typeTag)
    118        Usage(progName);
    119 
    120    if (!inFile)
    121        inFile = PR_STDIN;
    122    if (!outFile)
    123        outFile = stdout;
    124 
    125    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    126    rv = NSS_NoDB_Init(NULL);
    127    if (rv != SECSuccess) {
    128        fprintf(stderr, "%s: NSS_NoDB_Init failed (%s)\n",
    129                progName, SECU_Strerror(PORT_GetError()));
    130        exit(1);
    131    }
    132    SECU_RegisterDynamicOids();
    133 
    134    rv = SECU_ReadDERFromFile(&der, inFile, ascii, PR_FALSE);
    135    if (rv != SECSuccess) {
    136        fprintf(stderr, "%s: SECU_ReadDERFromFile failed\n", progName);
    137        exit(1);
    138    }
    139 
    140    /* Data is untyped, using the specified type */
    141    data.data = der.data;
    142    data.len = der.len;
    143 
    144    SECU_EnableWrap(wrap);
    145 
    146    /* Pretty print it */
    147    if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE) == 0 ||
    148        PORT_Strcmp(typeTag, "c") == 0) {
    149        rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0,
    150                                  SECU_PrintCertificate);
    151    } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_ID) == 0 ||
    152               PORT_Strcmp(typeTag, "ci") == 0) {
    153        rv = SECU_PrintSignedContent(outFile, &data, 0, 0,
    154                                     SECU_PrintDumpDerIssuerAndSerial);
    155    } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0 ||
    156               PORT_Strcmp(typeTag, "cr") == 0) {
    157        rv = SECU_PrintSignedData(outFile, &data, "Certificate Request", 0,
    158                                  SECU_PrintCertificateRequest);
    159    } else if (PORT_Strcmp(typeTag, SEC_CT_CRL) == 0) {
    160        rv = SECU_PrintSignedData(outFile, &data, "CRL", 0, SECU_PrintCrl);
    161    } else if (PORT_Strcmp(typeTag, SEC_CT_PRIVATE_KEY) == 0 ||
    162               PORT_Strcmp(typeTag, "sk") == 0) {
    163        rv = SECU_PrintPrivateKey(outFile, &data, "Private Key", 0);
    164    } else if (PORT_Strcmp(typeTag, SEC_CT_PUBLIC_KEY) == 0 ||
    165               PORT_Strcmp(typeTag, "pk") == 0) {
    166        rv = SECU_PrintSubjectPublicKeyInfo(outFile, &data, "Public Key", 0);
    167    } else if (PORT_Strcmp(typeTag, SEC_CT_PKCS7) == 0 ||
    168               PORT_Strcmp(typeTag, "p7") == 0) {
    169        rv = SECU_PrintPKCS7ContentInfo(outFile, &data,
    170                                        "PKCS #7 Content Info", 0);
    171    } else if (PORT_Strcmp(typeTag, SEC_CT_NAME) == 0 ||
    172               PORT_Strcmp(typeTag, "n") == 0) {
    173        rv = SECU_PrintDERName(outFile, &data, "Name", 0);
    174    } else if (PORT_Strcmp(typeTag, SEC_CT_PKCS12) == 0 ||
    175               PORT_Strcmp(typeTag, "p12") == 0) {
    176        rv = SECU_PrintPKCS12(outFile, &data, "PKCS #12 File", 0);
    177    } else {
    178        fprintf(stderr, "%s: don't know how to print out '%s' files\n",
    179                progName, typeTag);
    180        SECU_PrintAny(outFile, &data, "File contains", 0);
    181        return -1;
    182    }
    183 
    184    PORT_Free(typeTag);
    185 
    186    if (inFile != PR_STDIN)
    187        PR_Close(inFile);
    188    PORT_Free(der.data);
    189    if (rv) {
    190        fprintf(stderr, "%s: problem converting data (%s)\n",
    191                progName, SECU_Strerror(PORT_GetError()));
    192    }
    193    if (NSS_Shutdown() != SECSuccess) {
    194        fprintf(stderr, "%s: NSS_Shutdown failed (%s)\n",
    195                progName, SECU_Strerror(PORT_GetError()));
    196        rv = SECFailure;
    197    }
    198    PR_Cleanup();
    199    return rv;
    200 }