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 +}