security/nss/cmd/digest/digest.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/cmd/digest/digest.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,224 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "secutil.h"
     1.9 +#include "pk11func.h"
    1.10 +#include "secoid.h"
    1.11 +
    1.12 +#if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
    1.13 +#if !defined(WIN32)
    1.14 +extern int fread(char *, size_t, size_t, FILE*);
    1.15 +extern int fwrite(char *, size_t, size_t, FILE*);
    1.16 +extern int fprintf(FILE *, char *, ...);
    1.17 +#endif
    1.18 +#endif
    1.19 +
    1.20 +#include "plgetopt.h"
    1.21 +
    1.22 +static SECOidData *
    1.23 +HashTypeToOID(HASH_HashType hashtype)
    1.24 +{
    1.25 +    SECOidTag hashtag;
    1.26 +
    1.27 +    if (hashtype <= HASH_AlgNULL || hashtype >= HASH_AlgTOTAL)
    1.28 +	return NULL;
    1.29 +
    1.30 +    switch (hashtype) {
    1.31 +      case HASH_AlgMD2:
    1.32 +	hashtag = SEC_OID_MD2;
    1.33 +	break;
    1.34 +      case HASH_AlgMD5:
    1.35 +	hashtag = SEC_OID_MD5;
    1.36 +	break;
    1.37 +      case HASH_AlgSHA1:
    1.38 +	hashtag = SEC_OID_SHA1;
    1.39 +	break;
    1.40 +      default:
    1.41 +	fprintf(stderr, "A new hash type has been added to HASH_HashType.\n");
    1.42 +	fprintf(stderr, "This program needs to be updated!\n");
    1.43 +	return NULL;
    1.44 +    }
    1.45 +
    1.46 +    return SECOID_FindOIDByTag(hashtag);
    1.47 +}
    1.48 +
    1.49 +static SECOidData *
    1.50 +HashNameToOID(const char *hashName)
    1.51 +{
    1.52 +    HASH_HashType htype;
    1.53 +    SECOidData *hashOID;
    1.54 +
    1.55 +    for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
    1.56 +	hashOID = HashTypeToOID(htype);
    1.57 +	if (PORT_Strcasecmp(hashName, hashOID->desc) == 0)
    1.58 +	    break;
    1.59 +    }
    1.60 +
    1.61 +    if (htype == HASH_AlgTOTAL)
    1.62 +	return NULL;
    1.63 +
    1.64 +    return hashOID;
    1.65 +}
    1.66 +
    1.67 +static void
    1.68 +Usage(char *progName)
    1.69 +{
    1.70 +    HASH_HashType htype;
    1.71 +
    1.72 +    fprintf(stderr,
    1.73 +	    "Usage:  %s -t type [-i input] [-o output]\n",
    1.74 +	    progName);
    1.75 +    fprintf(stderr, "%-20s Specify the digest method (must be one of\n",
    1.76 +	    "-t type");
    1.77 +    fprintf(stderr, "%-20s ", "");
    1.78 +    for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
    1.79 +	fprintf(stderr, "%s", HashTypeToOID(htype)->desc);
    1.80 +	if (htype == (HASH_AlgTOTAL - 2))
    1.81 +	    fprintf(stderr, " or ");
    1.82 +	else if (htype != (HASH_AlgTOTAL - 1))
    1.83 +	    fprintf(stderr, ", ");
    1.84 +    }
    1.85 +    fprintf(stderr, " (case ignored))\n");
    1.86 +    fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
    1.87 +	    "-i input");
    1.88 +    fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
    1.89 +	    "-o output");
    1.90 +    exit(-1);
    1.91 +}
    1.92 +
    1.93 +static int
    1.94 +DigestFile(FILE *outFile, FILE *inFile, SECOidData *hashOID)
    1.95 +{
    1.96 +    int nb;
    1.97 +    unsigned char ibuf[4096], digest[32];
    1.98 +    PK11Context *hashcx;
    1.99 +    unsigned int len;
   1.100 +    SECStatus rv;
   1.101 +
   1.102 +    hashcx = PK11_CreateDigestContext(hashOID->offset);
   1.103 +    if (hashcx == NULL) {
   1.104 +	return -1;
   1.105 +    }
   1.106 +    PK11_DigestBegin(hashcx);
   1.107 +
   1.108 +
   1.109 +    for (;;) {
   1.110 +	if (feof(inFile)) break;
   1.111 +	nb = fread(ibuf, 1, sizeof(ibuf), inFile);
   1.112 +	if (nb != sizeof(ibuf)) {
   1.113 +	    if (nb == 0) {
   1.114 +		if (ferror(inFile)) {
   1.115 +		    PORT_SetError(SEC_ERROR_IO);
   1.116 +		    PK11_DestroyContext(hashcx,PR_TRUE);
   1.117 +		    return -1;
   1.118 +		}
   1.119 +		/* eof */
   1.120 +		break;
   1.121 +	    }
   1.122 +	}
   1.123 +	rv = PK11_DigestOp(hashcx, ibuf, nb);
   1.124 +	if (rv != SECSuccess) {
   1.125 +	   PK11_DestroyContext(hashcx, PR_TRUE);
   1.126 +	   return -1;
   1.127 +	}
   1.128 +    }
   1.129 +
   1.130 +    rv = PK11_DigestFinal(hashcx, digest, &len, 32);
   1.131 +    PK11_DestroyContext(hashcx, PR_TRUE);
   1.132 +
   1.133 +    if (rv != SECSuccess) return -1;
   1.134 +
   1.135 +    nb = fwrite(digest, 1, len, outFile);
   1.136 +    if (nb != len) {
   1.137 +	PORT_SetError(SEC_ERROR_IO);
   1.138 +	return -1;
   1.139 +    }
   1.140 +
   1.141 +    return 0;
   1.142 +}
   1.143 +
   1.144 +#include "nss.h"
   1.145 +
   1.146 +int
   1.147 +main(int argc, char **argv)
   1.148 +{
   1.149 +    char *progName;
   1.150 +    FILE *inFile, *outFile;
   1.151 +    char *hashName;
   1.152 +    SECOidData *hashOID;
   1.153 +    PLOptState *optstate;
   1.154 +    PLOptStatus status;
   1.155 +    SECStatus   rv;
   1.156 +
   1.157 +    progName = strrchr(argv[0], '/');
   1.158 +    progName = progName ? progName+1 : argv[0];
   1.159 +
   1.160 +    inFile = NULL;
   1.161 +    outFile = NULL;
   1.162 +    hashName = NULL;
   1.163 +
   1.164 +    rv = NSS_Init("/tmp");
   1.165 +    if (rv != SECSuccess) {
   1.166 +    	fprintf(stderr, "%s: NSS_Init failed in directory %s\n",
   1.167 +	        progName, "/tmp");
   1.168 +        return -1;
   1.169 +    }
   1.170 +
   1.171 +    /*
   1.172 +     * Parse command line arguments
   1.173 +     */
   1.174 +    optstate = PL_CreateOptState(argc, argv, "t:i:o:");
   1.175 +    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
   1.176 +	switch (optstate->option) {
   1.177 +	  case '?':
   1.178 +	    Usage(progName);
   1.179 +	    break;
   1.180 +
   1.181 +	  case 'i':
   1.182 +	    inFile = fopen(optstate->value, "r");
   1.183 +	    if (!inFile) {
   1.184 +		fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
   1.185 +			progName, optstate->value);
   1.186 +		return -1;
   1.187 +	    }
   1.188 +	    break;
   1.189 +
   1.190 +	  case 'o':
   1.191 +	    outFile = fopen(optstate->value, "w");
   1.192 +	    if (!outFile) {
   1.193 +		fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
   1.194 +			progName, optstate->value);
   1.195 +		return -1;
   1.196 +	    }
   1.197 +	    break;
   1.198 +
   1.199 +	  case 't':
   1.200 +	    hashName = strdup(optstate->value);
   1.201 +	    break;
   1.202 +	}
   1.203 +    }
   1.204 +
   1.205 +    if (!hashName) Usage(progName);
   1.206 +
   1.207 +    if (!inFile) inFile = stdin;
   1.208 +    if (!outFile) outFile = stdout;
   1.209 +
   1.210 +    hashOID = HashNameToOID(hashName);
   1.211 +    if (hashOID == NULL) {
   1.212 +	fprintf(stderr, "%s: invalid digest type\n", progName);
   1.213 +	Usage(progName);
   1.214 +    }
   1.215 +
   1.216 +    if (DigestFile(outFile, inFile, hashOID)) {
   1.217 +	fprintf(stderr, "%s: problem digesting data (%s)\n",
   1.218 +		progName, SECU_Strerror(PORT_GetError()));
   1.219 +	return -1;
   1.220 +    }
   1.221 +
   1.222 +    if (NSS_Shutdown() != SECSuccess) {
   1.223 +        exit(1);
   1.224 +    } 
   1.225 +    
   1.226 +    return 0;
   1.227 +}

mercurial