aboutsummaryrefslogtreecommitdiff
path: root/openssl/engines/ccgost/gostsum.c
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/engines/ccgost/gostsum.c')
-rw-r--r--openssl/engines/ccgost/gostsum.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/openssl/engines/ccgost/gostsum.c b/openssl/engines/ccgost/gostsum.c
new file mode 100644
index 000000000..d57112eb5
--- /dev/null
+++ b/openssl/engines/ccgost/gostsum.c
@@ -0,0 +1,210 @@
+/**********************************************************************
+ * gostsum.c *
+ * Copyright (c) 2005-2006 Cryptocom LTD *
+ * This file is distributed under the same license as OpenSSL *
+ * *
+ * Almost drop-in replacement for md5sum and sha1sum *
+ * which computes GOST R 34.11-94 hashsum instead *
+ * *
+ **********************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <string.h>
+#include "gosthash.h"
+#define BUF_SIZE 262144
+int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode);
+int hash_stream(gost_hash_ctx *ctx,int fd, char *sum);
+int get_line(FILE *f,char *hash,char *filename);
+void help()
+ {
+ fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n"
+ "\t-c check message digests (default is generate)\n"
+ "\t-v verbose, print file names when checking\n"
+ "\t-b read files in binary mode\n"
+ "\t-t use test GOST paramset (default is CryptoPro paramset)\n"
+ "The input for -c should be the list of message digests and file names\n"
+ "that is printed on stdout by this program when it generates digests.\n");
+ exit(3);
+ }
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+int main(int argc,char **argv)
+ {
+ int c,i;
+ int verbose=0;
+ int errors=0;
+ int open_mode = O_RDONLY;
+ gost_subst_block *b= &GostR3411_94_CryptoProParamSet;
+ FILE *check_file = NULL;
+ gost_hash_ctx ctx;
+
+ while( (c=getopt(argc,argv,"bc::tv"))!=-1)
+ {
+ switch (c)
+ {
+ case 'v': verbose=1; break;
+ case 't': b= &GostR3411_94_TestParamSet; break;
+ case 'b': open_mode |= O_BINARY; break;
+ case 'c':
+ if (optarg)
+ {
+ check_file = fopen(optarg,"r");
+ if (!check_file)
+ {
+ perror(optarg);
+ exit(2);
+ }
+ }
+ else
+ {
+ check_file= stdin;
+ }
+ break;
+ default:
+ fprintf(stderr,"invalid option %c",optopt);
+ help();
+ }
+ }
+ init_gost_hash_ctx(&ctx,b);
+ if (check_file)
+ {
+ char inhash[65],calcsum[65],filename[PATH_MAX];
+ int failcount=0,count=0;;
+ if (check_file==stdin && optind<argc)
+ {
+ check_file=fopen(argv[optind],"r");
+ if (!check_file)
+ {
+ perror(argv[optind]);
+ exit(2);
+ }
+ }
+ while (get_line(check_file,inhash,filename))
+ {
+ if (!hash_file(&ctx,filename,calcsum,open_mode))
+ {
+ exit (2);
+ }
+ count++;
+ if (!strncmp(calcsum,inhash,65))
+ {
+ if (verbose)
+ {
+ fprintf(stderr,"%s\tOK\n",filename);
+ }
+ }
+ else
+ {
+ if (verbose)
+ {
+ fprintf(stderr,"%s\tFAILED\n",filename);
+ }
+ else
+ {
+ fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n",
+ argv[0],filename);
+ }
+ failcount++;
+ }
+ }
+ if (verbose && failcount)
+ {
+ fprintf(stderr,"%s: %d of %d file(f) failed GOST hash sum check\n",
+ argv[0],failcount,count);
+ }
+ exit (failcount?1:0);
+ }
+ if (optind==argc)
+ {
+ char sum[65];
+ if (!hash_stream(&ctx,fileno(stdin),sum))
+ {
+ perror("stdin");
+ exit(1);
+ }
+ printf("%s -\n",sum);
+ exit(0);
+ }
+ for (i=optind;i<argc;i++)
+ {
+ char sum[65];
+ if (!hash_file(&ctx,argv[i],sum,open_mode))
+ {
+ errors++;
+ }
+ else
+ {
+ printf("%s %s\n",sum,argv[i]);
+ }
+ }
+ exit(errors?1:0);
+ }
+
+int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode)
+ {
+ int fd;
+ if ((fd=open(filename,mode))<0)
+ {
+ perror(filename);
+ return 0;
+ }
+ if (!hash_stream(ctx,fd,sum))
+ {
+ perror(filename);
+ return 0;
+ }
+ close(fd);
+ return 1;
+ }
+
+int hash_stream(gost_hash_ctx *ctx,int fd, char *sum)
+ {
+ unsigned char buffer[BUF_SIZE];
+ ssize_t bytes;
+ int i;
+ start_hash(ctx);
+ while ((bytes=read(fd,buffer,BUF_SIZE))>0)
+ {
+ hash_block(ctx,buffer,bytes);
+ }
+ if (bytes<0)
+ {
+ return 0;
+ }
+ finish_hash(ctx,buffer);
+ for (i=0;i<32;i++)
+ {
+ sprintf(sum+2*i,"%02x",buffer[31-i]);
+ }
+ return 1;
+ }
+
+int get_line(FILE *f,char *hash,char *filename)
+ {
+ int i;
+ if (fread(hash,1,64,f)<64) return 0;
+ hash[64]=0;
+ for (i=0;i<64;i++)
+ {
+ if (hash[i]<'0' || (hash[i]>'9' && hash[i]<'A') || (hash[i]>'F'
+ && hash[i]<'a')||hash[i]>'f')
+ {
+ fprintf(stderr,"Not a hash value '%s'\n",hash);
+ return 0;
+ }
+ }
+ if (fgetc(f)!=' ')
+ {
+ fprintf(stderr,"Malformed input line\n");
+ return 0;
+ }
+ i=strlen(fgets(filename,PATH_MAX,f));
+ while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0;
+ return 1;
+ }