1/********************************************************************** 2 * gostsum.c * 3 * Copyright (c) 2005-2006 Cryptocom LTD * 4 * This file is distributed under the same license as OpenSSL * 5 * * 6 * Almost drop-in replacement for md5sum and sha1sum * 7 * which computes GOST R 34.11-94 hashsum instead * 8 * * 9 **********************************************************************/ 10#include <stdio.h> 11#include <stdlib.h> 12#include <unistd.h> 13#include <limits.h> 14#include <fcntl.h> 15#include <string.h> 16#include "gosthash.h" 17#define BUF_SIZE 262144
| 1/********************************************************************** 2 * gostsum.c * 3 * Copyright (c) 2005-2006 Cryptocom LTD * 4 * This file is distributed under the same license as OpenSSL * 5 * * 6 * Almost drop-in replacement for md5sum and sha1sum * 7 * which computes GOST R 34.11-94 hashsum instead * 8 * * 9 **********************************************************************/ 10#include <stdio.h> 11#include <stdlib.h> 12#include <unistd.h> 13#include <limits.h> 14#include <fcntl.h> 15#include <string.h> 16#include "gosthash.h" 17#define BUF_SIZE 262144
|
18int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode); 19int hash_stream(gost_hash_ctx *ctx,int fd, char *sum); 20int get_line(FILE *f,char *hash,char *filename);
| 18int hash_file(gost_hash_ctx * ctx, char *filename, char *sum, int mode); 19int hash_stream(gost_hash_ctx * ctx, int fd, char *sum); 20int get_line(FILE *f, char *hash, char *filename);
|
21void help()
| 21void help()
|
22 { 23 fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n" 24 "\t-c check message digests (default is generate)\n" 25 "\t-v verbose, print file names when checking\n" 26 "\t-b read files in binary mode\n" 27 "\t-t use test GOST paramset (default is CryptoPro paramset)\n" 28 "The input for -c should be the list of message digests and file names\n" 29 "that is printed on stdout by this program when it generates digests.\n"); 30 exit(3); 31 }
| 22{ 23 fprintf(stderr, "gostsum [-bvt] [-c [file]]| [files]\n" 24 "\t-c check message digests (default is generate)\n" 25 "\t-v verbose, print file names when checking\n" 26 "\t-b read files in binary mode\n" 27 "\t-t use test GOST paramset (default is CryptoPro paramset)\n" 28 "The input for -c should be the list of message digests and file names\n" 29 "that is printed on stdout by this program when it generates digests.\n"); 30 exit(3); 31}
|
32 33#ifndef O_BINARY
| 32 33#ifndef O_BINARY
|
34#define O_BINARY 0
| 34# define O_BINARY 0
|
35#endif 36
| 35#endif 36
|
37int main(int argc,char **argv) 38 { 39 int c,i; 40 int verbose=0; 41 int errors=0; 42 int open_mode = O_RDONLY; 43 gost_subst_block *b= &GostR3411_94_CryptoProParamSet; 44 FILE *check_file = NULL; 45 gost_hash_ctx ctx; 46 47 while( (c=getopt(argc,argv,"bc::tv"))!=-1) 48 { 49 switch (c) 50 { 51 case 'v': verbose=1; break; 52 case 't': b= &GostR3411_94_TestParamSet; break; 53 case 'b': open_mode |= O_BINARY; break; 54 case 'c': 55 if (optarg) 56 { 57 check_file = fopen(optarg,"r"); 58 if (!check_file) 59 { 60 perror(optarg); 61 exit(2); 62 } 63 } 64 else 65 { 66 check_file= stdin; 67 } 68 break; 69 default: 70 fprintf(stderr,"invalid option %c",optopt); 71 help(); 72 } 73 } 74 init_gost_hash_ctx(&ctx,b); 75 if (check_file) 76 { 77 char inhash[65],calcsum[65],filename[PATH_MAX]; 78 int failcount=0,count=0;; 79 if (check_file==stdin && optind<argc) 80 { 81 check_file=fopen(argv[optind],"r"); 82 if (!check_file) 83 { 84 perror(argv[optind]); 85 exit(2); 86 } 87 } 88 while (get_line(check_file,inhash,filename)) 89 { 90 if (!hash_file(&ctx,filename,calcsum,open_mode)) 91 { 92 exit (2); 93 } 94 count++; 95 if (!strncmp(calcsum,inhash,65)) 96 { 97 if (verbose) 98 { 99 fprintf(stderr,"%s\tOK\n",filename); 100 } 101 } 102 else 103 { 104 if (verbose) 105 { 106 fprintf(stderr,"%s\tFAILED\n",filename); 107 } 108 else 109 { 110 fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n", 111 argv[0],filename); 112 } 113 failcount++; 114 } 115 } 116 if (verbose && failcount) 117 { 118 fprintf(stderr,"%s: %d of %d file(f) failed GOST hash sum check\n", 119 argv[0],failcount,count); 120 } 121 exit (failcount?1:0); 122 } 123 if (optind==argc) 124 { 125 char sum[65]; 126 if (!hash_stream(&ctx,fileno(stdin),sum)) 127 { 128 perror("stdin"); 129 exit(1); 130 } 131 printf("%s -\n",sum); 132 exit(0); 133 } 134 for (i=optind;i<argc;i++) 135 { 136 char sum[65]; 137 if (!hash_file(&ctx,argv[i],sum,open_mode)) 138 { 139 errors++; 140 } 141 else 142 { 143 printf("%s %s\n",sum,argv[i]); 144 } 145 } 146 exit(errors?1:0); 147 }
| 37int main(int argc, char **argv) 38{ 39 int c, i; 40 int verbose = 0; 41 int errors = 0; 42 int open_mode = O_RDONLY; 43 gost_subst_block *b = &GostR3411_94_CryptoProParamSet; 44 FILE *check_file = NULL; 45 gost_hash_ctx ctx;
|
148
| 46
|
149int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode) 150 { 151 int fd; 152 if ((fd=open(filename,mode))<0) 153 { 154 perror(filename); 155 return 0; 156 } 157 if (!hash_stream(ctx,fd,sum)) 158 { 159 perror(filename); 160 return 0; 161 } 162 close(fd); 163 return 1; 164 }
| 47 while ((c = getopt(argc, argv, "bc::tv")) != -1) { 48 switch (c) { 49 case 'v': 50 verbose = 1; 51 break; 52 case 't': 53 b = &GostR3411_94_TestParamSet; 54 break; 55 case 'b': 56 open_mode |= O_BINARY; 57 break; 58 case 'c': 59 if (optarg) { 60 check_file = fopen(optarg, "r"); 61 if (!check_file) { 62 perror(optarg); 63 exit(2); 64 } 65 } else { 66 check_file = stdin; 67 } 68 break; 69 default: 70 fprintf(stderr, "invalid option %c", optopt); 71 help(); 72 } 73 } 74 init_gost_hash_ctx(&ctx, b); 75 if (check_file) { 76 char inhash[65], calcsum[65], filename[PATH_MAX]; 77 int failcount = 0, count = 0;; 78 if (check_file == stdin && optind < argc) { 79 check_file = fopen(argv[optind], "r"); 80 if (!check_file) { 81 perror(argv[optind]); 82 exit(2); 83 } 84 } 85 while (get_line(check_file, inhash, filename)) { 86 if (!hash_file(&ctx, filename, calcsum, open_mode)) { 87 exit(2); 88 } 89 count++; 90 if (!strncmp(calcsum, inhash, 65)) { 91 if (verbose) { 92 fprintf(stderr, "%s\tOK\n", filename); 93 } 94 } else { 95 if (verbose) { 96 fprintf(stderr, "%s\tFAILED\n", filename); 97 } else { 98 fprintf(stderr, 99 "%s: GOST hash sum check failed for '%s'\n", 100 argv[0], filename); 101 } 102 failcount++; 103 } 104 } 105 if (verbose && failcount) { 106 fprintf(stderr, 107 "%s: %d of %d file(f) failed GOST hash sum check\n", 108 argv[0], failcount, count); 109 } 110 exit(failcount ? 1 : 0); 111 } 112 if (optind == argc) { 113 char sum[65]; 114 if (!hash_stream(&ctx, fileno(stdin), sum)) { 115 perror("stdin"); 116 exit(1); 117 } 118 printf("%s -\n", sum); 119 exit(0); 120 } 121 for (i = optind; i < argc; i++) { 122 char sum[65]; 123 if (!hash_file(&ctx, argv[i], sum, open_mode)) { 124 errors++; 125 } else { 126 printf("%s %s\n", sum, argv[i]); 127 } 128 } 129 exit(errors ? 1 : 0); 130}
|
165
| 131
|
166int hash_stream(gost_hash_ctx *ctx,int fd, char *sum) 167 { 168 unsigned char buffer[BUF_SIZE]; 169 ssize_t bytes; 170 int i; 171 start_hash(ctx); 172 while ((bytes=read(fd,buffer,BUF_SIZE))>0) 173 { 174 hash_block(ctx,buffer,bytes); 175 } 176 if (bytes<0) 177 { 178 return 0; 179 } 180 finish_hash(ctx,buffer); 181 for (i=0;i<32;i++) 182 { 183 sprintf(sum+2*i,"%02x",buffer[31-i]); 184 } 185 return 1; 186 } 187 188int get_line(FILE *f,char *hash,char *filename) 189 { 190 int i; 191 if (fread(hash,1,64,f)<64) return 0; 192 hash[64]=0; 193 for (i=0;i<64;i++) 194 { 195 if (hash[i]<'0' || (hash[i]>'9' && hash[i]<'A') || (hash[i]>'F' 196 && hash[i]<'a')||hash[i]>'f') 197 { 198 fprintf(stderr,"Not a hash value '%s'\n",hash); 199 return 0; 200 } 201 } 202 if (fgetc(f)!=' ') 203 { 204 fprintf(stderr,"Malformed input line\n"); 205 return 0; 206 } 207 i=strlen(fgets(filename,PATH_MAX,f)); 208 while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0; 209 return 1; 210 }
| 132int hash_file(gost_hash_ctx * ctx, char *filename, char *sum, int mode) 133{ 134 int fd; 135 if ((fd = open(filename, mode)) < 0) { 136 perror(filename); 137 return 0; 138 } 139 if (!hash_stream(ctx, fd, sum)) { 140 perror(filename); 141 return 0; 142 } 143 close(fd); 144 return 1; 145} 146 147int hash_stream(gost_hash_ctx * ctx, int fd, char *sum) 148{ 149 unsigned char buffer[BUF_SIZE]; 150 ssize_t bytes; 151 int i; 152 start_hash(ctx); 153 while ((bytes = read(fd, buffer, BUF_SIZE)) > 0) { 154 hash_block(ctx, buffer, bytes); 155 } 156 if (bytes < 0) { 157 return 0; 158 } 159 finish_hash(ctx, buffer); 160 for (i = 0; i < 32; i++) { 161 sprintf(sum + 2 * i, "%02x", buffer[31 - i]); 162 } 163 return 1; 164} 165 166int get_line(FILE *f, char *hash, char *filename) 167{ 168 int i; 169 if (fread(hash, 1, 64, f) < 64) 170 return 0; 171 hash[64] = 0; 172 for (i = 0; i < 64; i++) { 173 if (hash[i] < '0' || (hash[i] > '9' && hash[i] < 'A') 174 || (hash[i] > 'F' && hash[i] < 'a') || hash[i] > 'f') { 175 fprintf(stderr, "Not a hash value '%s'\n", hash); 176 return 0; 177 } 178 } 179 if (fgetc(f) != ' ') { 180 fprintf(stderr, "Malformed input line\n"); 181 return 0; 182 } 183 i = strlen(fgets(filename, PATH_MAX, f)); 184 while (filename[--i] == '\n' || filename[i] == '\r') 185 filename[i] = 0; 186 return 1; 187}
|
| |