~andersk/ubuntu/oneiric/openssl/spurious-reboot

« back to all changes in this revision

Viewing changes to apps/dgst.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Martin
  • Date: 2004-05-24 17:02:29 UTC
  • Revision ID: james.westby@ubuntu.com-20040524170229-ixlo08bbbly0xied
Tags: upstream-0.9.7d
ImportĀ upstreamĀ versionĀ 0.9.7d

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* apps/dgst.c */
 
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 
3
 * All rights reserved.
 
4
 *
 
5
 * This package is an SSL implementation written
 
6
 * by Eric Young (eay@cryptsoft.com).
 
7
 * The implementation was written so as to conform with Netscapes SSL.
 
8
 * 
 
9
 * This library is free for commercial and non-commercial use as long as
 
10
 * the following conditions are aheared to.  The following conditions
 
11
 * apply to all code found in this distribution, be it the RC4, RSA,
 
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 
13
 * included with this distribution is covered by the same copyright terms
 
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 
15
 * 
 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
 
17
 * the code are not to be removed.
 
18
 * If this package is used in a product, Eric Young should be given attribution
 
19
 * as the author of the parts of the library used.
 
20
 * This can be in the form of a textual message at program startup or
 
21
 * in documentation (online or textual) provided with the package.
 
22
 * 
 
23
 * Redistribution and use in source and binary forms, with or without
 
24
 * modification, are permitted provided that the following conditions
 
25
 * are met:
 
26
 * 1. Redistributions of source code must retain the copyright
 
27
 *    notice, this list of conditions and the following disclaimer.
 
28
 * 2. Redistributions in binary form must reproduce the above copyright
 
29
 *    notice, this list of conditions and the following disclaimer in the
 
30
 *    documentation and/or other materials provided with the distribution.
 
31
 * 3. All advertising materials mentioning features or use of this software
 
32
 *    must display the following acknowledgement:
 
33
 *    "This product includes cryptographic software written by
 
34
 *     Eric Young (eay@cryptsoft.com)"
 
35
 *    The word 'cryptographic' can be left out if the rouines from the library
 
36
 *    being used are not cryptographic related :-).
 
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 
38
 *    the apps directory (application code) you must include an acknowledgement:
 
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 
40
 * 
 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
51
 * SUCH DAMAGE.
 
52
 * 
 
53
 * The licence and distribution terms for any publically available version or
 
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 
55
 * copied and put under another distribution licence
 
56
 * [including the GNU Public Licence.]
 
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
 
 
70
#undef BUFSIZE
 
71
#define BUFSIZE 1024*8
 
72
 
 
73
#undef PROG
 
74
#define PROG    dgst_main
 
75
 
 
76
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
 
77
          EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
 
78
          const char *file);
 
79
 
 
80
int MAIN(int, char **);
 
81
 
 
82
int MAIN(int argc, char **argv)
 
83
        {
 
84
        ENGINE *e = NULL;
 
85
        unsigned char *buf=NULL;
 
86
        int i,err=0;
 
87
        const EVP_MD *md=NULL,*m;
 
88
        BIO *in=NULL,*inp;
 
89
        BIO *bmd=NULL;
 
90
        BIO *out = NULL;
 
91
        const char *name;
 
92
#define PROG_NAME_SIZE  39
 
93
        char pname[PROG_NAME_SIZE+1];
 
94
        int separator=0;
 
95
        int debug=0;
 
96
        int keyform=FORMAT_PEM;
 
97
        const char *outfile = NULL, *keyfile = NULL;
 
98
        const char *sigfile = NULL, *randfile = NULL;
 
99
        int out_bin = -1, want_pub = 0, do_verify = 0;
 
100
        EVP_PKEY *sigkey = NULL;
 
101
        unsigned char *sigbuf = NULL;
 
102
        int siglen = 0;
 
103
#ifndef OPENSSL_NO_ENGINE
 
104
        char *engine=NULL;
 
105
#endif
 
106
 
 
107
        apps_startup();
 
108
 
 
109
        if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
 
110
                {
 
111
                BIO_printf(bio_err,"out of memory\n");
 
112
                goto end;
 
113
                }
 
114
        if (bio_err == NULL)
 
115
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
 
116
                        BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
 
117
 
 
118
        if (!load_config(bio_err, NULL))
 
119
                goto end;
 
120
 
 
121
        /* first check the program name */
 
122
        program_name(argv[0],pname,sizeof pname);
 
123
 
 
124
        md=EVP_get_digestbyname(pname);
 
125
 
 
126
        argc--;
 
127
        argv++;
 
128
        while (argc > 0)
 
129
                {
 
130
                if ((*argv)[0] != '-') break;
 
131
                if (strcmp(*argv,"-c") == 0)
 
132
                        separator=1;
 
133
                else if (strcmp(*argv,"-rand") == 0)
 
134
                        {
 
135
                        if (--argc < 1) break;
 
136
                        randfile=*(++argv);
 
137
                        }
 
138
                else if (strcmp(*argv,"-out") == 0)
 
139
                        {
 
140
                        if (--argc < 1) break;
 
141
                        outfile=*(++argv);
 
142
                        }
 
143
                else if (strcmp(*argv,"-sign") == 0)
 
144
                        {
 
145
                        if (--argc < 1) break;
 
146
                        keyfile=*(++argv);
 
147
                        }
 
148
                else if (strcmp(*argv,"-verify") == 0)
 
149
                        {
 
150
                        if (--argc < 1) break;
 
151
                        keyfile=*(++argv);
 
152
                        want_pub = 1;
 
153
                        do_verify = 1;
 
154
                        }
 
155
                else if (strcmp(*argv,"-prverify") == 0)
 
156
                        {
 
157
                        if (--argc < 1) break;
 
158
                        keyfile=*(++argv);
 
159
                        do_verify = 1;
 
160
                        }
 
161
                else if (strcmp(*argv,"-signature") == 0)
 
162
                        {
 
163
                        if (--argc < 1) break;
 
164
                        sigfile=*(++argv);
 
165
                        }
 
166
                else if (strcmp(*argv,"-keyform") == 0)
 
167
                        {
 
168
                        if (--argc < 1) break;
 
169
                        keyform=str2fmt(*(++argv));
 
170
                        }
 
171
#ifndef OPENSSL_NO_ENGINE
 
172
                else if (strcmp(*argv,"-engine") == 0)
 
173
                        {
 
174
                        if (--argc < 1) break;
 
175
                        engine= *(++argv);
 
176
                        }
 
177
#endif
 
178
                else if (strcmp(*argv,"-hex") == 0)
 
179
                        out_bin = 0;
 
180
                else if (strcmp(*argv,"-binary") == 0)
 
181
                        out_bin = 1;
 
182
                else if (strcmp(*argv,"-d") == 0)
 
183
                        debug=1;
 
184
                else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
 
185
                        md=m;
 
186
                else
 
187
                        break;
 
188
                argc--;
 
189
                argv++;
 
190
                }
 
191
 
 
192
        if (md == NULL)
 
193
                md=EVP_md5();
 
194
 
 
195
        if(do_verify && !sigfile) {
 
196
                BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
 
197
                err = 1; 
 
198
                goto end;
 
199
        }
 
200
 
 
201
        if ((argc > 0) && (argv[0][0] == '-')) /* bad option */
 
202
                {
 
203
                BIO_printf(bio_err,"unknown option '%s'\n",*argv);
 
204
                BIO_printf(bio_err,"options are\n");
 
205
                BIO_printf(bio_err,"-c              to output the digest with separating colons\n");
 
206
                BIO_printf(bio_err,"-d              to output debug info\n");
 
207
                BIO_printf(bio_err,"-hex            output as hex dump\n");
 
208
                BIO_printf(bio_err,"-binary         output in binary form\n");
 
209
                BIO_printf(bio_err,"-sign   file    sign digest using private key in file\n");
 
210
                BIO_printf(bio_err,"-verify file    verify a signature using public key in file\n");
 
211
                BIO_printf(bio_err,"-prverify file  verify a signature using private key in file\n");
 
212
                BIO_printf(bio_err,"-keyform arg    key file format (PEM or ENGINE)\n");
 
213
                BIO_printf(bio_err,"-signature file signature to verify\n");
 
214
                BIO_printf(bio_err,"-binary         output in binary form\n");
 
215
#ifndef OPENSSL_NO_ENGINE
 
216
                BIO_printf(bio_err,"-engine e       use engine e, possibly a hardware device.\n");
 
217
#endif
 
218
 
 
219
                BIO_printf(bio_err,"-%3s to use the %s message digest algorithm (default)\n",
 
220
                        LN_md5,LN_md5);
 
221
                BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
 
222
                        LN_md4,LN_md4);
 
223
                BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
 
224
                        LN_md2,LN_md2);
 
225
                BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
 
226
                        LN_sha1,LN_sha1);
 
227
                BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
 
228
                        LN_sha,LN_sha);
 
229
                BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
 
230
                        LN_mdc2,LN_mdc2);
 
231
                BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
 
232
                        LN_ripemd160,LN_ripemd160);
 
233
                err=1;
 
234
                goto end;
 
235
                }
 
236
 
 
237
#ifndef OPENSSL_NO_ENGINE
 
238
        e = setup_engine(bio_err, engine, 0);
 
239
#endif
 
240
 
 
241
        in=BIO_new(BIO_s_file());
 
242
        bmd=BIO_new(BIO_f_md());
 
243
        if (debug)
 
244
                {
 
245
                BIO_set_callback(in,BIO_debug_callback);
 
246
                /* needed for windows 3.1 */
 
247
                BIO_set_callback_arg(in,bio_err);
 
248
                }
 
249
 
 
250
        if ((in == NULL) || (bmd == NULL))
 
251
                {
 
252
                ERR_print_errors(bio_err);
 
253
                goto end;
 
254
                }
 
255
 
 
256
        if(out_bin == -1) {
 
257
                if(keyfile) out_bin = 1;
 
258
                else out_bin = 0;
 
259
        }
 
260
 
 
261
        if(randfile)
 
262
                app_RAND_load_file(randfile, bio_err, 0);
 
263
 
 
264
        if(outfile) {
 
265
                if(out_bin)
 
266
                        out = BIO_new_file(outfile, "wb");
 
267
                else    out = BIO_new_file(outfile, "w");
 
268
        } else {
 
269
                out = BIO_new_fp(stdout, BIO_NOCLOSE);
 
270
#ifdef OPENSSL_SYS_VMS
 
271
                {
 
272
                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
 
273
                out = BIO_push(tmpbio, out);
 
274
                }
 
275
#endif
 
276
        }
 
277
 
 
278
        if(!out) {
 
279
                BIO_printf(bio_err, "Error opening output file %s\n", 
 
280
                                        outfile ? outfile : "(stdout)");
 
281
                ERR_print_errors(bio_err);
 
282
                goto end;
 
283
        }
 
284
 
 
285
        if(keyfile)
 
286
                {
 
287
                if (want_pub)
 
288
                        sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
 
289
                                e, "key file");
 
290
                else
 
291
                        sigkey = load_key(bio_err, keyfile, keyform, 0, NULL,
 
292
                                e, "key file");
 
293
                if (!sigkey)
 
294
                        {
 
295
                        /* load_[pub]key() has already printed an appropriate
 
296
                           message */
 
297
                        goto end;
 
298
                        }
 
299
                }
 
300
 
 
301
        if(sigfile && sigkey) {
 
302
                BIO *sigbio;
 
303
                sigbio = BIO_new_file(sigfile, "rb");
 
304
                siglen = EVP_PKEY_size(sigkey);
 
305
                sigbuf = OPENSSL_malloc(siglen);
 
306
                if(!sigbio) {
 
307
                        BIO_printf(bio_err, "Error opening signature file %s\n",
 
308
                                                                sigfile);
 
309
                        ERR_print_errors(bio_err);
 
310
                        goto end;
 
311
                }
 
312
                siglen = BIO_read(sigbio, sigbuf, siglen);
 
313
                BIO_free(sigbio);
 
314
                if(siglen <= 0) {
 
315
                        BIO_printf(bio_err, "Error reading signature file %s\n",
 
316
                                                                sigfile);
 
317
                        ERR_print_errors(bio_err);
 
318
                        goto end;
 
319
                }
 
320
        }
 
321
                
 
322
 
 
323
 
 
324
        /* we use md as a filter, reading from 'in' */
 
325
        BIO_set_md(bmd,md);
 
326
        inp=BIO_push(bmd,in);
 
327
 
 
328
        if (argc == 0)
 
329
                {
 
330
                BIO_set_fp(in,stdin,BIO_NOCLOSE);
 
331
                err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
 
332
                          siglen,"","(stdin)");
 
333
                }
 
334
        else
 
335
                {
 
336
                name=OBJ_nid2sn(md->type);
 
337
                for (i=0; i<argc; i++)
 
338
                        {
 
339
                        char *tmp,*tofree=NULL;
 
340
                        int r;
 
341
 
 
342
                        if (BIO_read_filename(in,argv[i]) <= 0)
 
343
                                {
 
344
                                perror(argv[i]);
 
345
                                err++;
 
346
                                continue;
 
347
                                }
 
348
                        if(!out_bin)
 
349
                                {
 
350
                                size_t len = strlen(name)+strlen(argv[i])+5;
 
351
                                tmp=tofree=OPENSSL_malloc(len);
 
352
                                BIO_snprintf(tmp,len,"%s(%s)= ",name,argv[i]);
 
353
                                }
 
354
                        else
 
355
                                tmp="";
 
356
                        r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
 
357
                                siglen,tmp,argv[i]);
 
358
                        if(r)
 
359
                            err=r;
 
360
                        if(tofree)
 
361
                                OPENSSL_free(tofree);
 
362
                        (void)BIO_reset(bmd);
 
363
                        }
 
364
                }
 
365
end:
 
366
        if (buf != NULL)
 
367
                {
 
368
                OPENSSL_cleanse(buf,BUFSIZE);
 
369
                OPENSSL_free(buf);
 
370
                }
 
371
        if (in != NULL) BIO_free(in);
 
372
        BIO_free_all(out);
 
373
        EVP_PKEY_free(sigkey);
 
374
        if(sigbuf) OPENSSL_free(sigbuf);
 
375
        if (bmd != NULL) BIO_free(bmd);
 
376
        apps_shutdown();
 
377
        OPENSSL_EXIT(err);
 
378
        }
 
379
 
 
380
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
 
381
          EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
 
382
          const char *file)
 
383
        {
 
384
        int len;
 
385
        int i;
 
386
 
 
387
        for (;;)
 
388
                {
 
389
                i=BIO_read(bp,(char *)buf,BUFSIZE);
 
390
                if(i < 0)
 
391
                        {
 
392
                        BIO_printf(bio_err, "Read Error in %s\n",file);
 
393
                        ERR_print_errors(bio_err);
 
394
                        return 1;
 
395
                        }
 
396
                if (i == 0) break;
 
397
                }
 
398
        if(sigin)
 
399
                {
 
400
                EVP_MD_CTX *ctx;
 
401
                BIO_get_md_ctx(bp, &ctx);
 
402
                i = EVP_VerifyFinal(ctx, sigin, (unsigned int)siglen, key); 
 
403
                if(i > 0)
 
404
                        BIO_printf(out, "Verified OK\n");
 
405
                else if(i == 0)
 
406
                        {
 
407
                        BIO_printf(out, "Verification Failure\n");
 
408
                        return 1;
 
409
                        }
 
410
                else
 
411
                        {
 
412
                        BIO_printf(bio_err, "Error Verifying Data\n");
 
413
                        ERR_print_errors(bio_err);
 
414
                        return 1;
 
415
                        }
 
416
                return 0;
 
417
                }
 
418
        if(key)
 
419
                {
 
420
                EVP_MD_CTX *ctx;
 
421
                BIO_get_md_ctx(bp, &ctx);
 
422
                if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key)) 
 
423
                        {
 
424
                        BIO_printf(bio_err, "Error Signing Data\n");
 
425
                        ERR_print_errors(bio_err);
 
426
                        return 1;
 
427
                        }
 
428
                }
 
429
        else
 
430
                len=BIO_gets(bp,(char *)buf,BUFSIZE);
 
431
 
 
432
        if(binout) BIO_write(out, buf, len);
 
433
        else 
 
434
                {
 
435
                BIO_write(out,title,strlen(title));
 
436
                for (i=0; i<len; i++)
 
437
                        {
 
438
                        if (sep && (i != 0))
 
439
                                BIO_printf(out, ":");
 
440
                        BIO_printf(out, "%02x",buf[i]);
 
441
                        }
 
442
                BIO_printf(out, "\n");
 
443
                }
 
444
        return 0;
 
445
        }
 
446