tor-browser

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

digest.c (5279B)


      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 "secutil.h"
      6 #include "pk11func.h"
      7 #include "sechash.h"
      8 #include "secoid.h"
      9 
     10 #if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
     11 #if !defined(WIN32)
     12 extern int fread(char *, size_t, size_t, FILE *);
     13 extern int fwrite(char *, size_t, size_t, FILE *);
     14 extern int fprintf(FILE *, char *, ...);
     15 #endif
     16 #endif
     17 
     18 #include "plgetopt.h"
     19 
     20 static SECOidData *
     21 HashNameToOID(const char *hashName)
     22 {
     23    HASH_HashType htype;
     24    SECOidData *hashOID;
     25 
     26    for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
     27        hashOID = SECOID_FindOIDByTag(HASH_GetHashOidTagByHashType(htype));
     28        if (PORT_Strcasecmp(hashName, hashOID->desc) == 0)
     29            break;
     30    }
     31 
     32    if (htype == HASH_AlgTOTAL)
     33        return NULL;
     34 
     35    return hashOID;
     36 }
     37 
     38 static void
     39 Usage(char *progName)
     40 {
     41    HASH_HashType htype;
     42 
     43    fprintf(stderr,
     44            "Usage:  %s -t type [-i input] [-o output]\n",
     45            progName);
     46    fprintf(stderr, "%-20s Specify the digest method (must be one of\n",
     47            "-t type");
     48    fprintf(stderr, "%-20s ", "");
     49    for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
     50        fputs(SECOID_FindOIDByTag(HASH_GetHashOidTagByHashType(htype))->desc,
     51              stderr);
     52        if (htype == (HASH_AlgTOTAL - 2))
     53            fprintf(stderr, " or ");
     54        else if (htype != (HASH_AlgTOTAL - 1))
     55            fprintf(stderr, ", ");
     56    }
     57    fprintf(stderr, " (case ignored))\n");
     58    fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
     59            "-i input");
     60    fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
     61            "-o output");
     62    exit(-1);
     63 }
     64 
     65 static int
     66 DigestFile(FILE *outFile, FILE *inFile, SECOidData *hashOID)
     67 {
     68    int nb;
     69    unsigned char ibuf[4096], digest[HASH_LENGTH_MAX];
     70    PK11Context *hashcx;
     71    unsigned int len;
     72    SECStatus rv;
     73 
     74    hashcx = PK11_CreateDigestContext(hashOID->offset);
     75    if (hashcx == NULL) {
     76        return -1;
     77    }
     78    PK11_DigestBegin(hashcx);
     79 
     80    for (;;) {
     81        if (feof(inFile))
     82            break;
     83        nb = fread(ibuf, 1, sizeof(ibuf), inFile);
     84        if (nb != sizeof(ibuf)) {
     85            if (nb == 0) {
     86                if (ferror(inFile)) {
     87                    PORT_SetError(SEC_ERROR_IO);
     88                    PK11_DestroyContext(hashcx, PR_TRUE);
     89                    return -1;
     90                }
     91                /* eof */
     92                break;
     93            }
     94        }
     95        rv = PK11_DigestOp(hashcx, ibuf, nb);
     96        if (rv != SECSuccess) {
     97            PK11_DestroyContext(hashcx, PR_TRUE);
     98            return -1;
     99        }
    100    }
    101 
    102    rv = PK11_DigestFinal(hashcx, digest, &len, HASH_LENGTH_MAX);
    103    PK11_DestroyContext(hashcx, PR_TRUE);
    104 
    105    if (rv != SECSuccess)
    106        return -1;
    107 
    108    nb = fwrite(digest, 1, len, outFile);
    109    if (nb != len) {
    110        PORT_SetError(SEC_ERROR_IO);
    111        return -1;
    112    }
    113 
    114    return 0;
    115 }
    116 
    117 #include "nss.h"
    118 
    119 int
    120 main(int argc, char **argv)
    121 {
    122    char *progName;
    123    FILE *inFile, *outFile;
    124    char *hashName;
    125    SECOidData *hashOID;
    126    PLOptState *optstate;
    127    PLOptStatus status;
    128    SECStatus rv;
    129 
    130    progName = strrchr(argv[0], '/');
    131    progName = progName ? progName + 1 : argv[0];
    132 
    133    inFile = NULL;
    134    outFile = NULL;
    135    hashName = NULL;
    136 
    137    rv = NSS_Init("/tmp");
    138    if (rv != SECSuccess) {
    139        fprintf(stderr, "%s: NSS_Init failed in directory %s\n",
    140                progName, "/tmp");
    141        return -1;
    142    }
    143 
    144    /*
    145     * Parse command line arguments
    146     */
    147    optstate = PL_CreateOptState(argc, argv, "t:i:o:");
    148    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
    149        switch (optstate->option) {
    150            case '?':
    151                Usage(progName);
    152                break;
    153 
    154            case 'i':
    155                inFile = fopen(optstate->value, "r");
    156                if (!inFile) {
    157                    fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
    158                            progName, optstate->value);
    159                    return -1;
    160                }
    161                break;
    162 
    163            case 'o':
    164                outFile = fopen(optstate->value, "w");
    165                if (!outFile) {
    166                    fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
    167                            progName, optstate->value);
    168                    return -1;
    169                }
    170                break;
    171 
    172            case 't':
    173                hashName = strdup(optstate->value);
    174                break;
    175        }
    176    }
    177 
    178    if (!hashName)
    179        Usage(progName);
    180 
    181    if (!inFile)
    182        inFile = stdin;
    183    if (!outFile)
    184        outFile = stdout;
    185 
    186    hashOID = HashNameToOID(hashName);
    187    free(hashName);
    188    if (hashOID == NULL) {
    189        fprintf(stderr, "%s: invalid digest type\n", progName);
    190        Usage(progName);
    191    }
    192 
    193    if (DigestFile(outFile, inFile, hashOID)) {
    194        fprintf(stderr, "%s: problem digesting data (%s)\n",
    195                progName, SECU_Strerror(PORT_GetError()));
    196        return -1;
    197    }
    198 
    199    if (NSS_Shutdown() != SECSuccess) {
    200        exit(1);
    201    }
    202 
    203    return 0;
    204 }