1 /**********************************************************************
3 * Copyright (c) 2005-2006 Cryptocom LTD *
4 * This file is distributed under the same license as OpenSSL *
6 * Almost drop-in replacement for md5sum and sha1sum *
7 * which computes GOST R 34.11-94 hashsum instead *
9 **********************************************************************/
17 #define BUF_SIZE 262144
18 int hash_file(gost_hash_ctx
*ctx
,char *filename
,char *sum
,int mode
);
19 int hash_stream(gost_hash_ctx
*ctx
,int fd
, char *sum
);
20 int get_line(FILE *f
,char *hash
,char *filename
);
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");
37 int main(int argc
,char **argv
)
42 int open_mode
= O_RDONLY
;
43 gost_subst_block
*b
= &GostR3411_94_CryptoProParamSet
;
44 FILE *check_file
= NULL
;
47 while( (c
=getopt(argc
,argv
,"bc::tv"))!=-1)
51 case 'v': verbose
=1; break;
52 case 't': b
= &GostR3411_94_TestParamSet
; break;
53 case 'b': open_mode
|= O_BINARY
; break;
57 check_file
= fopen(optarg
,"r");
70 fprintf(stderr
,"invalid option %c",optopt
);
74 init_gost_hash_ctx(&ctx
,b
);
77 char inhash
[65],calcsum
[65],filename
[PATH_MAX
];
78 int failcount
=0,count
=0;;
79 if (check_file
==stdin
&& optind
<argc
)
81 check_file
=fopen(argv
[optind
],"r");
88 while (get_line(check_file
,inhash
,filename
))
90 if (!hash_file(&ctx
,filename
,calcsum
,open_mode
))
95 if (!strncmp(calcsum
,inhash
,65))
99 fprintf(stderr
,"%s\tOK\n",filename
);
106 fprintf(stderr
,"%s\tFAILED\n",filename
);
110 fprintf(stderr
,"%s: GOST hash sum check failed for '%s'\n",
116 if (verbose
&& failcount
)
118 fprintf(stderr
,"%s: %d of %d file(f) failed GOST hash sum check\n",
119 argv
[0],failcount
,count
);
121 exit (failcount
?1:0);
126 if (!hash_stream(&ctx
,fileno(stdin
),sum
))
131 printf("%s -\n",sum
);
134 for (i
=optind
;i
<argc
;i
++)
137 if (!hash_file(&ctx
,argv
[i
],sum
,open_mode
))
143 printf("%s %s\n",sum
,argv
[i
]);
149 int hash_file(gost_hash_ctx
*ctx
,char *filename
,char *sum
,int mode
)
152 if ((fd
=open(filename
,mode
))<0)
157 if (!hash_stream(ctx
,fd
,sum
))
166 int hash_stream(gost_hash_ctx
*ctx
,int fd
, char *sum
)
168 unsigned char buffer
[BUF_SIZE
];
172 while ((bytes
=read(fd
,buffer
,BUF_SIZE
))>0)
174 hash_block(ctx
,buffer
,bytes
);
180 finish_hash(ctx
,buffer
);
183 sprintf(sum
+2*i
,"%02x",buffer
[31-i
]);
188 int get_line(FILE *f
,char *hash
,char *filename
)
191 if (fread(hash
,1,64,f
)<64) return 0;
195 if (hash
[i
]<'0' || (hash
[i
]>'9' && hash
[i
]<'A') || (hash
[i
]>'F'
196 && hash
[i
]<'a')||hash
[i
]>'f')
198 fprintf(stderr
,"Not a hash value '%s'\n",hash
);
204 fprintf(stderr
,"Malformed input line\n");
207 i
=strlen(fgets(filename
,PATH_MAX
,f
));
208 while (filename
[--i
]=='\n'||filename
[i
]=='\r') filename
[i
]=0;