digest.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:6k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #include "secutil.h"
  34. #include "pk11func.h"
  35. #include "secoid.h"
  36. #if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
  37. #if !defined(WIN32)
  38. extern int fread(char *, size_t, size_t, FILE*);
  39. extern int fwrite(char *, size_t, size_t, FILE*);
  40. extern int fprintf(FILE *, char *, ...);
  41. #endif
  42. #endif
  43. #include "plgetopt.h"
  44. static SECOidData *
  45. HashTypeToOID(HASH_HashType hashtype)
  46. {
  47.     SECOidTag hashtag;
  48.     if (hashtype <= HASH_AlgNULL || hashtype >= HASH_AlgTOTAL)
  49. return NULL;
  50.     switch (hashtype) {
  51.       case HASH_AlgMD2:
  52. hashtag = SEC_OID_MD2;
  53. break;
  54.       case HASH_AlgMD5:
  55. hashtag = SEC_OID_MD5;
  56. break;
  57.       case HASH_AlgSHA1:
  58. hashtag = SEC_OID_SHA1;
  59. break;
  60.       default:
  61. fprintf(stderr, "A new hash type has been added to HASH_HashType.n");
  62. fprintf(stderr, "This program needs to be updated!n");
  63. return NULL;
  64.     }
  65.     return SECOID_FindOIDByTag(hashtag);
  66. }
  67. static SECOidData *
  68. HashNameToOID(const char *hashName)
  69. {
  70.     HASH_HashType htype;
  71.     SECOidData *hashOID;
  72.     for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
  73. hashOID = HashTypeToOID(htype);
  74. if (PORT_Strcasecmp(hashName, hashOID->desc) == 0)
  75.     break;
  76.     }
  77.     if (htype == HASH_AlgTOTAL)
  78. return NULL;
  79.     return hashOID;
  80. }
  81. static void
  82. Usage(char *progName)
  83. {
  84.     HASH_HashType htype;
  85.     fprintf(stderr,
  86.     "Usage:  %s -t type [-i input] [-o output]n",
  87.     progName);
  88.     fprintf(stderr, "%-20s Specify the digest method (must be one ofn",
  89.     "-t type");
  90.     fprintf(stderr, "%-20s ", "");
  91.     for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
  92. fprintf(stderr, HashTypeToOID(htype)->desc);
  93. if (htype == (HASH_AlgTOTAL - 2))
  94.     fprintf(stderr, " or ");
  95. else if (htype != (HASH_AlgTOTAL - 1))
  96.     fprintf(stderr, ", ");
  97.     }
  98.     fprintf(stderr, " (case ignored))n");
  99.     fprintf(stderr, "%-20s Define an input file to use (default is stdin)n",
  100.     "-i input");
  101.     fprintf(stderr, "%-20s Define an output file to use (default is stdout)n",
  102.     "-o output");
  103.     exit(-1);
  104. }
  105. static int
  106. DigestFile(FILE *outFile, FILE *inFile, SECOidData *hashOID)
  107. {
  108.     int nb;
  109.     unsigned char ibuf[4096], digest[32];
  110.     PK11Context *hashcx;
  111.     unsigned int len;
  112.     SECStatus rv;
  113.     hashcx = PK11_CreateDigestContext(hashOID->offset);
  114.     if (hashcx == NULL) {
  115. return -1;
  116.     }
  117.     PK11_DigestBegin(hashcx);
  118.     for (;;) {
  119. if (feof(inFile)) break;
  120. nb = fread(ibuf, 1, sizeof(ibuf), inFile);
  121. if (nb != sizeof(ibuf)) {
  122.     if (nb == 0) {
  123. if (ferror(inFile)) {
  124.     PORT_SetError(SEC_ERROR_IO);
  125.     PK11_DestroyContext(hashcx,PR_TRUE);
  126.     return -1;
  127. }
  128. /* eof */
  129. break;
  130.     }
  131. }
  132. rv = PK11_DigestOp(hashcx, ibuf, nb);
  133. if (rv != SECSuccess) {
  134.    PK11_DestroyContext(hashcx, PR_TRUE);
  135.    return -1;
  136. }
  137.     }
  138.     rv = PK11_DigestFinal(hashcx, digest, &len, 32);
  139.     PK11_DestroyContext(hashcx, PR_TRUE);
  140.     if (rv != SECSuccess) return -1;
  141.     nb = fwrite(digest, 1, len, outFile);
  142.     if (nb != len) {
  143. PORT_SetError(SEC_ERROR_IO);
  144. return -1;
  145.     }
  146.     return 0;
  147. }
  148. #include "nss.h"
  149. int
  150. main(int argc, char **argv)
  151. {
  152.     char *progName;
  153.     int opt;
  154.     FILE *inFile, *outFile;
  155.     char *hashName;
  156.     SECOidData *hashOID;
  157.     PLOptState *optstate;
  158.     PLOptStatus status;
  159.     SECStatus   rv;
  160.     progName = strrchr(argv[0], '/');
  161.     progName = progName ? progName+1 : argv[0];
  162.     inFile = NULL;
  163.     outFile = NULL;
  164.     hashName = NULL;
  165.     rv = NSS_Init("/tmp");
  166.     if (rv != SECSuccess) {
  167.      fprintf(stderr, "%s: NSS_Init failed in directory %sn",
  168.         progName, "/tmp");
  169.         return -1;
  170.     }
  171.     /*
  172.      * Parse command line arguments
  173.      */
  174.     optstate = PL_CreateOptState(argc, argv, "t:i:o:");
  175.     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
  176. switch (optstate->option) {
  177.   case '?':
  178.     Usage(progName);
  179.     break;
  180.   case 'i':
  181.     inFile = fopen(optstate->value, "r");
  182.     if (!inFile) {
  183. fprintf(stderr, "%s: unable to open "%s" for readingn",
  184. progName, optstate->value);
  185. return -1;
  186.     }
  187.     break;
  188.   case 'o':
  189.     outFile = fopen(optstate->value, "w");
  190.     if (!outFile) {
  191. fprintf(stderr, "%s: unable to open "%s" for writingn",
  192. progName, optstate->value);
  193. return -1;
  194.     }
  195.     break;
  196.   case 't':
  197.     hashName = strdup(optstate->value);
  198.     break;
  199. }
  200.     }
  201.     if (!hashName) Usage(progName);
  202.     if (!inFile) inFile = stdin;
  203.     if (!outFile) outFile = stdout;
  204.     hashOID = HashNameToOID(hashName);
  205.     if (hashOID == NULL) {
  206. fprintf(stderr, "%s: invalid digest typen", progName);
  207. Usage(progName);
  208.     }
  209.     if (DigestFile(outFile, inFile, hashOID)) {
  210. fprintf(stderr, "%s: problem digesting data (%s)n",
  211. progName, SECU_Strerror(PORT_GetError()));
  212. return -1;
  213.     }
  214.     return 0;
  215. }