1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59: #include <stdio.h>
60: #include <string.h>
61: #include <stdlib.h>
62: #include "apps.h"
63: #include <openssl/bio.h>
64: #include <openssl/err.h>
65: #include <openssl/evp.h>
66: #include <openssl/objects.h>
67: #include <openssl/x509.h>
68: #include <openssl/pem.h>
69: #include <openssl/hmac.h>
70:
71: #undef BUFSIZE
72: #define BUFSIZE 1024*8
73:
74: #undef PROG
75: #define PROG dgst_main
76:
77: int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
78: EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
79: const char *file,BIO *bmd,const char *hmac_key);
80:
81: int MAIN(int, char **);
82:
83: int MAIN(int argc, char **argv)
84: {
85: ENGINE *e = NULL;
86: unsigned char *buf=NULL;
87: int i,err=0;
88: const EVP_MD *md=NULL,*m;
89: BIO *in=NULL,*inp;
90: BIO *bmd=NULL;
91: BIO *out = NULL;
92: const char *name;
93: #define PROG_NAME_SIZE 39
94: char pname[PROG_NAME_SIZE+1];
95: int separator=0;
96: int debug=0;
97: int keyform=FORMAT_PEM;
98: const char *outfile = NULL, *keyfile = NULL;
99: const char *sigfile = NULL, *randfile = NULL;
100: int out_bin = -1, want_pub = 0, do_verify = 0;
101: EVP_PKEY *sigkey = NULL;
102: unsigned char *sigbuf = NULL;
103: int siglen = 0;
104: char *passargin = NULL, *passin = NULL;
105: #ifndef OPENSSL_NO_ENGINE
106: char *engine=NULL;
107: #endif
108: char *hmac_key=NULL;
109:
110: apps_startup();
111:
112: if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
113: {
114: BIO_printf(bio_err,"out of memory\n");
115: goto end;
116: }
117: if (bio_err == NULL)
118: if ((bio_err=BIO_new(BIO_s_file())) != NULL)
119: BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
120:
121: if (!load_config(bio_err, NULL))
122: goto end;
123:
124:
125: program_name(argv[0],pname,sizeof pname);
126:
127: md=EVP_get_digestbyname(pname);
128:
129: argc--;
130: argv++;
131: while (argc > 0)
132: {
133: if ((*argv)[0] != '-') break;
134: if (strcmp(*argv,"-c") == 0)
135: separator=1;
136: else if (strcmp(*argv,"-rand") == 0)
137: {
138: if (--argc < 1) break;
139: randfile=*(++argv);
140: }
141: else if (strcmp(*argv,"-out") == 0)
142: {
143: if (--argc < 1) break;
144: outfile=*(++argv);
145: }
146: else if (strcmp(*argv,"-sign") == 0)
147: {
148: if (--argc < 1) break;
149: keyfile=*(++argv);
150: }
151: else if (!strcmp(*argv,"-passin"))
152: {
153: if (--argc < 1)
154: break;
155: passargin=*++argv;
156: }
157: else if (strcmp(*argv,"-verify") == 0)
158: {
159: if (--argc < 1) break;
160: keyfile=*(++argv);
161: want_pub = 1;
162: do_verify = 1;
163: }
164: else if (strcmp(*argv,"-prverify") == 0)
165: {
166: if (--argc < 1) break;
167: keyfile=*(++argv);
168: do_verify = 1;
169: }
170: else if (strcmp(*argv,"-signature") == 0)
171: {
172: if (--argc < 1) break;
173: sigfile=*(++argv);
174: }
175: else if (strcmp(*argv,"-keyform") == 0)
176: {
177: if (--argc < 1) break;
178: keyform=str2fmt(*(++argv));
179: }
180: #ifndef OPENSSL_NO_ENGINE
181: else if (strcmp(*argv,"-engine") == 0)
182: {
183: if (--argc < 1) break;
184: engine= *(++argv);
185: }
186: #endif
187: else if (strcmp(*argv,"-hex") == 0)
188: out_bin = 0;
189: else if (strcmp(*argv,"-binary") == 0)
190: out_bin = 1;
191: else if (strcmp(*argv,"-d") == 0)
192: debug=1;
193: else if (!strcmp(*argv,"-hmac"))
194: {
195: if (--argc < 1)
196: break;
197: hmac_key=*++argv;
198: }
199: else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
200: md=m;
201: else
202: break;
203: argc--;
204: argv++;
205: }
206:
207: if (md == NULL)
208: md=EVP_md5();
209:
210: if(do_verify && !sigfile) {
211: BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
212: err = 1;
213: goto end;
214: }
215:
216: if ((argc > 0) && (argv[0][0] == '-'))
217: {
218: BIO_printf(bio_err,"unknown option '%s'\n",*argv);
219: BIO_printf(bio_err,"options are\n");
220: BIO_printf(bio_err,"-c to output the digest with separating colons\n");
221: BIO_printf(bio_err,"-d to output debug info\n");
222: BIO_printf(bio_err,"-hex output as hex dump\n");
223: BIO_printf(bio_err,"-binary output in binary form\n");
224: BIO_printf(bio_err,"-sign file sign digest using private key in file\n");
225: BIO_printf(bio_err,"-verify file verify a signature using public key in file\n");
226: BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n");
227: BIO_printf(bio_err,"-keyform arg key file format (PEM or ENGINE)\n");
228: BIO_printf(bio_err,"-signature file signature to verify\n");
229: BIO_printf(bio_err,"-binary output in binary form\n");
230: #ifndef OPENSSL_NO_ENGINE
231: BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n");
232: #endif
233:
234: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm (default)\n",
235: LN_md5,LN_md5);
236: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
237: LN_md4,LN_md4);
238: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
239: LN_md2,LN_md2);
240: #ifndef OPENSSL_NO_SHA
241: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
242: LN_sha1,LN_sha1);
243: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
244: LN_sha,LN_sha);
245: #ifndef OPENSSL_NO_SHA256
246: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
247: LN_sha224,LN_sha224);
248: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
249: LN_sha256,LN_sha256);
250: #endif
251: #ifndef OPENSSL_NO_SHA512
252: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
253: LN_sha384,LN_sha384);
254: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
255: LN_sha512,LN_sha512);
256: #endif
257: #endif
258: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
259: LN_mdc2,LN_mdc2);
260: BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
261: LN_ripemd160,LN_ripemd160);
262: err=1;
263: goto end;
264: }
265:
266: #ifndef OPENSSL_NO_ENGINE
267: e = setup_engine(bio_err, engine, 0);
268: #endif
269:
270: in=BIO_new(BIO_s_file());
271: bmd=BIO_new(BIO_f_md());
272: if (debug)
273: {
274: BIO_set_callback(in,BIO_debug_callback);
275:
276: BIO_set_callback_arg(in,(char *)bio_err);
277: }
278:
279: if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
280: {
281: BIO_printf(bio_err, "Error getting password\n");
282: goto end;
283: }
284:
285: if ((in == NULL) || (bmd == NULL))
286: {
287: ERR_print_errors(bio_err);
288: goto end;
289: }
290:
291: if(out_bin == -1) {
292: if(keyfile) out_bin = 1;
293: else out_bin = 0;
294: }
295:
296: if(randfile)
297: app_RAND_load_file(randfile, bio_err, 0);
298:
299: if(outfile) {
300: if(out_bin)
301: out = BIO_new_file(outfile, "wb");
302: else out = BIO_new_file(outfile, "w");
303: } else {
304: out = BIO_new_fp(stdout, BIO_NOCLOSE);
305: #ifdef OPENSSL_SYS_VMS
306: {
307: BIO *tmpbio = BIO_new(BIO_f_linebuffer());
308: out = BIO_push(tmpbio, out);
309: }
310: #endif
311: }
312:
313: if(!out) {
314: BIO_printf(bio_err, "Error opening output file %s\n",
315: outfile ? outfile : "(stdout)");
316: ERR_print_errors(bio_err);
317: goto end;
318: }
319:
320: if(keyfile)
321: {
322: if (want_pub)
323: sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
324: e, "key file");
325: else
326: sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
327: e, "key file");
328: if (!sigkey)
329: {
330:
331:
332: goto end;
333: }
334: }
335:
336: if(sigfile && sigkey) {
337: BIO *sigbio;
338: sigbio = BIO_new_file(sigfile, "rb");
339: siglen = EVP_PKEY_size(sigkey);
340: sigbuf = OPENSSL_malloc(siglen);
341: if(!sigbio) {
342: BIO_printf(bio_err, "Error opening signature file %s\n",
343: sigfile);
344: ERR_print_errors(bio_err);
345: goto end;
346: }
347: siglen = BIO_read(sigbio, sigbuf, siglen);
348: BIO_free(sigbio);
349: if(siglen <= 0) {
350: BIO_printf(bio_err, "Error reading signature file %s\n",
351: sigfile);
352: ERR_print_errors(bio_err);
353: goto end;
354: }
355: }
356:
357:
358:
359:
360: if (!BIO_set_md(bmd,md))
361: {
362: BIO_printf(bio_err, "Error setting digest %s\n", pname);
363: ERR_print_errors(bio_err);
364: goto end;
365: }
366:
367: inp=BIO_push(bmd,in);
368:
369: if (argc == 0)
370: {
371: BIO_set_fp(in,stdin,BIO_NOCLOSE);
372: err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
373: siglen,"","(stdin)",bmd,hmac_key);
374: }
375: else
376: {
377: name=OBJ_nid2sn(md->type);
378: for (i=0; i<argc; i++)
379: {
380: char *tmp,*tofree=NULL;
381: int r;
382:
383: if (BIO_read_filename(in,argv[i]) <= 0)
384: {
385: perror(argv[i]);
386: err++;
387: continue;
388: }
389: if(!out_bin)
390: {
391: size_t len = strlen(name)+strlen(argv[i])+(hmac_key ? 5 : 0)+5;
392: tmp=tofree=OPENSSL_malloc(len);
393: BIO_snprintf(tmp,len,"%s%s(%s)= ",
394: hmac_key ? "HMAC-" : "",name,argv[i]);
395: }
396: else
397: tmp="";
398: r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
399: siglen,tmp,argv[i],bmd,hmac_key);
400: if(r)
401: err=r;
402: if(tofree)
403: OPENSSL_free(tofree);
404: (void)BIO_reset(bmd);
405: }
406: }
407: end:
408: if (buf != NULL)
409: {
410: OPENSSL_cleanse(buf,BUFSIZE);
411: OPENSSL_free(buf);
412: }
413: if (in != NULL) BIO_free(in);
414: if (passin)
415: OPENSSL_free(passin);
416: BIO_free_all(out);
417: EVP_PKEY_free(sigkey);
418: if(sigbuf) OPENSSL_free(sigbuf);
419: if (bmd != NULL) BIO_free(bmd);
420: apps_shutdown();
421: OPENSSL_EXIT(err);
422: }
423:
424: int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
425: EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
426: const char *file,BIO *bmd,const char *hmac_key)
427: {
428: unsigned int len;
429: int i;
430: EVP_MD_CTX *md_ctx;
431: HMAC_CTX hmac_ctx;
432:
433: if (hmac_key)
434: {
435: EVP_MD *md;
436:
437: BIO_get_md(bmd,&md);
438: HMAC_CTX_init(&hmac_ctx);
439: HMAC_Init_ex(&hmac_ctx,hmac_key,strlen(hmac_key),md, NULL);
440: BIO_get_md_ctx(bmd,&md_ctx);
441: BIO_set_md_ctx(bmd,&hmac_ctx.md_ctx);
442: }
443: for (;;)
444: {
445: i=BIO_read(bp,(char *)buf,BUFSIZE);
446: if(i < 0)
447: {
448: BIO_printf(bio_err, "Read Error in %s\n",file);
449: ERR_print_errors(bio_err);
450: return 1;
451: }
452: if (i == 0) break;
453: }
454: if(sigin)
455: {
456: EVP_MD_CTX *ctx;
457: BIO_get_md_ctx(bp, &ctx);
458: i = EVP_VerifyFinal(ctx, sigin, (unsigned int)siglen, key);
459: if(i > 0)
460: BIO_printf(out, "Verified OK\n");
461: else if(i == 0)
462: {
463: BIO_printf(out, "Verification Failure\n");
464: return 1;
465: }
466: else
467: {
468: BIO_printf(bio_err, "Error Verifying Data\n");
469: ERR_print_errors(bio_err);
470: return 1;
471: }
472: return 0;
473: }
474: if(key)
475: {
476: EVP_MD_CTX *ctx;
477: BIO_get_md_ctx(bp, &ctx);
478: if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key))
479: {
480: BIO_printf(bio_err, "Error Signing Data\n");
481: ERR_print_errors(bio_err);
482: return 1;
483: }
484: }
485: else if(hmac_key)
486: {
487: HMAC_Final(&hmac_ctx,buf,&len);
488: HMAC_CTX_cleanup(&hmac_ctx);
489: }
490: else
491: len=BIO_gets(bp,(char *)buf,BUFSIZE);
492:
493: if(binout) BIO_write(out, buf, len);
494: else
495: {
496: BIO_write(out,title,strlen(title));
497: for (i=0; i<(int)len; i++)
498: {
499: if (sep && (i != 0))
500: BIO_printf(out, ":");
501: BIO_printf(out, "%02x",buf[i]);
502: }
503: BIO_printf(out, "\n");
504: }
505: if (hmac_key)
506: {
507: BIO_set_md_ctx(bmd,md_ctx);
508: }
509: return 0;
510: }
511: