Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/apps/dgst.c
34859 views
1
/*
2
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (the "License"). You may not use
5
* this file except in compliance with the License. You can obtain a copy
6
* in the file LICENSE in the source distribution or at
7
* https://www.openssl.org/source/license.html
8
*/
9
10
#include <stdio.h>
11
#include <string.h>
12
#include <stdlib.h>
13
#include "apps.h"
14
#include "progs.h"
15
#include <openssl/bio.h>
16
#include <openssl/err.h>
17
#include <openssl/evp.h>
18
#include <openssl/objects.h>
19
#include <openssl/x509.h>
20
#include <openssl/pem.h>
21
#include <openssl/hmac.h>
22
#include <ctype.h>
23
24
#undef BUFSIZE
25
#define BUFSIZE 1024*8
26
27
static int do_fp_oneshot_sign(BIO *out, EVP_MD_CTX *ctx, BIO *in, int sep, int binout,
28
EVP_PKEY *key, unsigned char *sigin, int siglen,
29
const char *sig_name, const char *file);
30
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen,
31
EVP_PKEY *key, unsigned char *sigin, int siglen,
32
const char *sig_name, const char *md_name,
33
const char *file);
34
static void show_digests(const OBJ_NAME *name, void *bio_);
35
36
struct doall_dgst_digests {
37
BIO *bio;
38
int n;
39
};
40
41
typedef enum OPTION_choice {
42
OPT_COMMON,
43
OPT_LIST,
44
OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
45
OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL,
46
OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT,
47
OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, OPT_XOFLEN,
48
OPT_DIGEST,
49
OPT_R_ENUM, OPT_PROV_ENUM
50
} OPTION_CHOICE;
51
52
const OPTIONS dgst_options[] = {
53
{OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"},
54
55
OPT_SECTION("General"),
56
{"help", OPT_HELP, '-', "Display this summary"},
57
{"list", OPT_LIST, '-', "List digests"},
58
#ifndef OPENSSL_NO_ENGINE
59
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
60
{"engine_impl", OPT_ENGINE_IMPL, '-',
61
"Also use engine given by -engine for digest operations"},
62
#endif
63
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
64
65
OPT_SECTION("Output"),
66
{"c", OPT_C, '-', "Print the digest with separating colons"},
67
{"r", OPT_R, '-', "Print the digest in coreutils format"},
68
{"out", OPT_OUT, '>', "Output to filename rather than stdout"},
69
{"keyform", OPT_KEYFORM, 'f', "Key file format (ENGINE, other values ignored)"},
70
{"hex", OPT_HEX, '-', "Print as hex dump"},
71
{"binary", OPT_BINARY, '-', "Print in binary form"},
72
{"xoflen", OPT_XOFLEN, 'p', "Output length for XOF algorithms. To obtain the maximum security strength set this to 32 (or greater) for SHAKE128, and 64 (or greater) for SHAKE256"},
73
{"d", OPT_DEBUG, '-', "Print debug info"},
74
{"debug", OPT_DEBUG, '-', "Print debug info"},
75
76
OPT_SECTION("Signing"),
77
{"sign", OPT_SIGN, 's', "Sign digest using private key"},
78
{"verify", OPT_VERIFY, 's', "Verify a signature using public key"},
79
{"prverify", OPT_PRVERIFY, 's', "Verify a signature using private key"},
80
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
81
{"signature", OPT_SIGNATURE, '<', "File with signature to verify"},
82
{"hmac", OPT_HMAC, 's', "Create hashed MAC with key"},
83
{"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"},
84
{"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"},
85
{"", OPT_DIGEST, '-', "Any supported digest"},
86
{"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-',
87
"Compute HMAC with the key used in OpenSSL-FIPS fingerprint"},
88
89
OPT_R_OPTIONS,
90
OPT_PROV_OPTIONS,
91
92
OPT_PARAMETERS(),
93
{"file", 0, 0, "Files to digest (optional; default is stdin)"},
94
{NULL}
95
};
96
97
int dgst_main(int argc, char **argv)
98
{
99
BIO *in = NULL, *inp = NULL, *bmd = NULL, *out = NULL;
100
ENGINE *e = NULL, *impl = NULL;
101
EVP_PKEY *sigkey = NULL;
102
STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
103
char *hmac_key = NULL;
104
char *mac_name = NULL, *digestname = NULL;
105
char *passinarg = NULL, *passin = NULL;
106
EVP_MD *md = NULL;
107
const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
108
const char *sigfile = NULL;
109
const char *md_name = NULL;
110
OPTION_CHOICE o;
111
int separator = 0, debug = 0, keyform = FORMAT_UNDEF, siglen = 0;
112
int i, ret = EXIT_FAILURE, out_bin = -1, want_pub = 0, do_verify = 0;
113
int xoflen = 0;
114
unsigned char *buf = NULL, *sigbuf = NULL;
115
int engine_impl = 0;
116
struct doall_dgst_digests dec;
117
EVP_MD_CTX *signctx = NULL;
118
int oneshot_sign = 0;
119
120
buf = app_malloc(BUFSIZE, "I/O buffer");
121
md = (EVP_MD *)EVP_get_digestbyname(argv[0]);
122
if (md != NULL)
123
digestname = argv[0];
124
125
opt_set_unknown_name("digest");
126
prog = opt_init(argc, argv, dgst_options);
127
while ((o = opt_next()) != OPT_EOF) {
128
switch (o) {
129
case OPT_EOF:
130
case OPT_ERR:
131
opthelp:
132
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
133
goto end;
134
case OPT_HELP:
135
opt_help(dgst_options);
136
ret = EXIT_SUCCESS;
137
goto end;
138
case OPT_LIST:
139
BIO_printf(bio_out, "Supported digests:\n");
140
dec.bio = bio_out;
141
dec.n = 0;
142
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,
143
show_digests, &dec);
144
BIO_printf(bio_out, "\n");
145
ret = EXIT_SUCCESS;
146
goto end;
147
case OPT_C:
148
separator = 1;
149
break;
150
case OPT_R:
151
separator = 2;
152
break;
153
case OPT_R_CASES:
154
if (!opt_rand(o))
155
goto end;
156
break;
157
case OPT_OUT:
158
outfile = opt_arg();
159
break;
160
case OPT_SIGN:
161
keyfile = opt_arg();
162
break;
163
case OPT_PASSIN:
164
passinarg = opt_arg();
165
break;
166
case OPT_VERIFY:
167
keyfile = opt_arg();
168
want_pub = do_verify = 1;
169
break;
170
case OPT_PRVERIFY:
171
keyfile = opt_arg();
172
do_verify = 1;
173
break;
174
case OPT_SIGNATURE:
175
sigfile = opt_arg();
176
break;
177
case OPT_KEYFORM:
178
if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
179
goto opthelp;
180
break;
181
case OPT_ENGINE:
182
e = setup_engine(opt_arg(), 0);
183
break;
184
case OPT_ENGINE_IMPL:
185
engine_impl = 1;
186
break;
187
case OPT_HEX:
188
out_bin = 0;
189
break;
190
case OPT_BINARY:
191
out_bin = 1;
192
break;
193
case OPT_XOFLEN:
194
xoflen = atoi(opt_arg());
195
break;
196
case OPT_DEBUG:
197
debug = 1;
198
break;
199
case OPT_FIPS_FINGERPRINT:
200
hmac_key = "etaonrishdlcupfm";
201
break;
202
case OPT_HMAC:
203
hmac_key = opt_arg();
204
break;
205
case OPT_MAC:
206
mac_name = opt_arg();
207
break;
208
case OPT_SIGOPT:
209
if (!sigopts)
210
sigopts = sk_OPENSSL_STRING_new_null();
211
if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
212
goto opthelp;
213
break;
214
case OPT_MACOPT:
215
if (!macopts)
216
macopts = sk_OPENSSL_STRING_new_null();
217
if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg()))
218
goto opthelp;
219
break;
220
case OPT_DIGEST:
221
digestname = opt_unknown();
222
break;
223
case OPT_PROV_CASES:
224
if (!opt_provider(o))
225
goto end;
226
break;
227
}
228
}
229
230
/* Remaining args are files to digest. */
231
argc = opt_num_rest();
232
argv = opt_rest();
233
if (keyfile != NULL && argc > 1) {
234
BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog);
235
goto end;
236
}
237
if (!app_RAND_load())
238
goto end;
239
240
if (digestname != NULL) {
241
if (!opt_md(digestname, &md))
242
goto opthelp;
243
}
244
245
if (do_verify && sigfile == NULL) {
246
BIO_printf(bio_err,
247
"No signature to verify: use the -signature option\n");
248
goto end;
249
}
250
if (engine_impl)
251
impl = e;
252
253
in = BIO_new(BIO_s_file());
254
bmd = BIO_new(BIO_f_md());
255
if (in == NULL || bmd == NULL)
256
goto end;
257
258
if (debug) {
259
BIO_set_callback_ex(in, BIO_debug_callback_ex);
260
/* needed for windows 3.1 */
261
BIO_set_callback_arg(in, (char *)bio_err);
262
}
263
264
if (!app_passwd(passinarg, NULL, &passin, NULL)) {
265
BIO_printf(bio_err, "Error getting password\n");
266
goto end;
267
}
268
269
if (out_bin == -1) {
270
if (keyfile != NULL)
271
out_bin = 1;
272
else
273
out_bin = 0;
274
}
275
276
out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
277
if (out == NULL)
278
goto end;
279
280
if ((!(mac_name == NULL) + !(keyfile == NULL) + !(hmac_key == NULL)) > 1) {
281
BIO_printf(bio_err, "MAC and signing key cannot both be specified\n");
282
goto end;
283
}
284
285
if (keyfile != NULL) {
286
if (want_pub)
287
sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key");
288
else
289
sigkey = load_key(keyfile, keyform, 0, passin, e, "private key");
290
if (sigkey == NULL) {
291
/*
292
* load_[pub]key() has already printed an appropriate message
293
*/
294
goto end;
295
}
296
{
297
char def_md[80];
298
299
if (EVP_PKEY_get_default_digest_name(sigkey, def_md,
300
sizeof(def_md)) == 2
301
&& strcmp(def_md, "UNDEF") == 0)
302
oneshot_sign = 1;
303
signctx = EVP_MD_CTX_new();
304
if (signctx == NULL)
305
goto end;
306
}
307
}
308
309
if (mac_name != NULL) {
310
EVP_PKEY_CTX *mac_ctx = NULL;
311
312
if (!init_gen_str(&mac_ctx, mac_name, impl, 0, NULL, NULL))
313
goto end;
314
if (macopts != NULL) {
315
for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
316
char *macopt = sk_OPENSSL_STRING_value(macopts, i);
317
318
if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
319
EVP_PKEY_CTX_free(mac_ctx);
320
BIO_printf(bio_err, "MAC parameter error \"%s\"\n", macopt);
321
goto end;
322
}
323
}
324
}
325
326
sigkey = app_keygen(mac_ctx, mac_name, 0, 0 /* not verbose */);
327
/* Verbose output would make external-tests gost-engine fail */
328
EVP_PKEY_CTX_free(mac_ctx);
329
if (sigkey == NULL)
330
goto end;
331
}
332
333
if (hmac_key != NULL) {
334
if (md == NULL) {
335
md = (EVP_MD *)EVP_sha256();
336
digestname = SN_sha256;
337
}
338
sigkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, impl,
339
(unsigned char *)hmac_key,
340
strlen(hmac_key));
341
if (sigkey == NULL)
342
goto end;
343
}
344
345
if (sigkey != NULL) {
346
EVP_MD_CTX *mctx = NULL;
347
EVP_PKEY_CTX *pctx = NULL;
348
int res;
349
350
if (oneshot_sign) {
351
mctx = signctx;
352
} else if (BIO_get_md_ctx(bmd, &mctx) <= 0) {
353
BIO_printf(bio_err, "Error getting context\n");
354
goto end;
355
}
356
if (do_verify)
357
if (impl == NULL)
358
res = EVP_DigestVerifyInit_ex(mctx, &pctx, digestname,
359
app_get0_libctx(),
360
app_get0_propq(), sigkey, NULL);
361
else
362
res = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey);
363
else
364
if (impl == NULL)
365
res = EVP_DigestSignInit_ex(mctx, &pctx, digestname,
366
app_get0_libctx(),
367
app_get0_propq(), sigkey, NULL);
368
else
369
res = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey);
370
if (res == 0) {
371
BIO_printf(bio_err, "Error setting context\n");
372
goto end;
373
}
374
if (sigopts != NULL) {
375
for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
376
char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
377
378
if (pkey_ctrl_string(pctx, sigopt) <= 0) {
379
BIO_printf(bio_err, "Signature parameter error \"%s\"\n",
380
sigopt);
381
goto end;
382
}
383
}
384
}
385
}
386
/* we use md as a filter, reading from 'in' */
387
else {
388
EVP_MD_CTX *mctx = NULL;
389
390
if (oneshot_sign) {
391
BIO_printf(bio_err, "Oneshot algorithms don't use a digest\n");
392
goto end;
393
}
394
if (BIO_get_md_ctx(bmd, &mctx) <= 0) {
395
BIO_printf(bio_err, "Error getting context\n");
396
goto end;
397
}
398
if (md == NULL)
399
md = (EVP_MD *)EVP_sha256();
400
if (!EVP_DigestInit_ex(mctx, md, impl)) {
401
BIO_printf(bio_err, "Error setting digest\n");
402
goto end;
403
}
404
}
405
406
if (sigfile != NULL && sigkey != NULL) {
407
BIO *sigbio = BIO_new_file(sigfile, "rb");
408
409
if (sigbio == NULL) {
410
BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
411
goto end;
412
}
413
siglen = EVP_PKEY_get_size(sigkey);
414
sigbuf = app_malloc(siglen, "signature buffer");
415
siglen = BIO_read(sigbio, sigbuf, siglen);
416
BIO_free(sigbio);
417
if (siglen <= 0) {
418
BIO_printf(bio_err, "Error reading signature file %s\n", sigfile);
419
goto end;
420
}
421
}
422
if (!oneshot_sign) {
423
inp = BIO_push(bmd, in);
424
425
if (md == NULL) {
426
EVP_MD_CTX *tctx;
427
428
BIO_get_md_ctx(bmd, &tctx);
429
md = EVP_MD_CTX_get1_md(tctx);
430
}
431
if (md != NULL)
432
md_name = EVP_MD_get0_name(md);
433
}
434
if (xoflen > 0) {
435
if (!EVP_MD_xof(md)) {
436
BIO_printf(bio_err, "Length can only be specified for XOF\n");
437
goto end;
438
}
439
/*
440
* Signing using XOF is not supported by any algorithms currently since
441
* each algorithm only calls EVP_DigestFinal_ex() in their sign_final
442
* and verify_final methods.
443
*/
444
if (sigkey != NULL) {
445
BIO_printf(bio_err, "Signing key cannot be specified for XOF\n");
446
goto end;
447
}
448
}
449
450
if (argc == 0) {
451
BIO_set_fp(in, stdin, BIO_NOCLOSE);
452
if (oneshot_sign)
453
ret = do_fp_oneshot_sign(out, signctx, in, separator, out_bin,
454
sigkey, sigbuf, siglen, NULL, "stdin");
455
else
456
ret = do_fp(out, buf, inp, separator, out_bin, xoflen,
457
sigkey, sigbuf, siglen, NULL, md_name, "stdin");
458
} else {
459
const char *sig_name = NULL;
460
461
if (out_bin == 0) {
462
if (sigkey != NULL)
463
sig_name = EVP_PKEY_get0_type_name(sigkey);
464
}
465
ret = EXIT_SUCCESS;
466
for (i = 0; i < argc; i++) {
467
if (BIO_read_filename(in, argv[i]) <= 0) {
468
perror(argv[i]);
469
ret = EXIT_FAILURE;
470
continue;
471
} else {
472
if (oneshot_sign) {
473
if (do_fp_oneshot_sign(out, signctx, in, separator, out_bin,
474
sigkey, sigbuf, siglen, sig_name,
475
argv[i]))
476
ret = EXIT_FAILURE;
477
} else {
478
if (do_fp(out, buf, inp, separator, out_bin, xoflen,
479
sigkey, sigbuf, siglen, sig_name, md_name, argv[i]))
480
ret = EXIT_FAILURE;
481
}
482
}
483
(void)BIO_reset(bmd);
484
}
485
}
486
end:
487
if (ret != EXIT_SUCCESS)
488
ERR_print_errors(bio_err);
489
OPENSSL_clear_free(buf, BUFSIZE);
490
BIO_free(in);
491
OPENSSL_free(passin);
492
BIO_free_all(out);
493
EVP_MD_free(md);
494
EVP_PKEY_free(sigkey);
495
EVP_MD_CTX_free(signctx);
496
sk_OPENSSL_STRING_free(sigopts);
497
sk_OPENSSL_STRING_free(macopts);
498
OPENSSL_free(sigbuf);
499
BIO_free(bmd);
500
release_engine(e);
501
return ret;
502
}
503
504
static void show_digests(const OBJ_NAME *name, void *arg)
505
{
506
struct doall_dgst_digests *dec = (struct doall_dgst_digests *)arg;
507
EVP_MD *md = NULL;
508
509
/* Filter out signed digests (a.k.a signature algorithms) */
510
if (strstr(name->name, "rsa") != NULL || strstr(name->name, "RSA") != NULL)
511
return;
512
513
if (!islower((unsigned char)*name->name))
514
return;
515
516
/* Filter out message digests that we cannot use */
517
md = EVP_MD_fetch(app_get0_libctx(), name->name, app_get0_propq());
518
if (md == NULL) {
519
if (EVP_get_digestbyname(name->name) == NULL)
520
return;
521
}
522
523
BIO_printf(dec->bio, "-%-25s", name->name);
524
if (++dec->n == 3) {
525
BIO_printf(dec->bio, "\n");
526
dec->n = 0;
527
} else {
528
BIO_printf(dec->bio, " ");
529
}
530
531
EVP_MD_free(md);
532
}
533
534
/*
535
* The newline_escape_filename function performs newline escaping for any
536
* filename that contains a newline. This function also takes a pointer
537
* to backslash. The backslash pointer is a flag to indicating whether a newline
538
* is present in the filename. If a newline is present, the backslash flag is
539
* set and the output format will contain a backslash at the beginning of the
540
* digest output. This output format is to replicate the output format found
541
* in the '*sum' checksum programs. This aims to preserve backward
542
* compatibility.
543
*/
544
static const char *newline_escape_filename(const char *file, int *backslash)
545
{
546
size_t i, e = 0, length = strlen(file), newline_count = 0, mem_len = 0;
547
char *file_cpy = NULL;
548
549
for (i = 0; i < length; i++)
550
if (file[i] == '\n')
551
newline_count++;
552
553
mem_len = length + newline_count + 1;
554
file_cpy = app_malloc(mem_len, file);
555
i = 0;
556
557
while (e < length) {
558
const char c = file[e];
559
if (c == '\n') {
560
file_cpy[i++] = '\\';
561
file_cpy[i++] = 'n';
562
*backslash = 1;
563
} else {
564
file_cpy[i++] = c;
565
}
566
e++;
567
}
568
file_cpy[i] = '\0';
569
return (const char*)file_cpy;
570
}
571
572
static void print_out(BIO *out, unsigned char *buf, size_t len,
573
int sep, int binout,
574
const char *sig_name, const char *md_name, const char *file)
575
{
576
int i, backslash = 0;
577
578
if (binout) {
579
BIO_write(out, buf, len);
580
} else if (sep == 2) {
581
file = newline_escape_filename(file, &backslash);
582
583
if (backslash == 1)
584
BIO_puts(out, "\\");
585
586
for (i = 0; i < (int)len; i++)
587
BIO_printf(out, "%02x", buf[i]);
588
589
BIO_printf(out, " *%s\n", file);
590
OPENSSL_free((char *)file);
591
} else {
592
if (sig_name != NULL) {
593
BIO_puts(out, sig_name);
594
if (md_name != NULL)
595
BIO_printf(out, "-%s", md_name);
596
BIO_printf(out, "(%s)= ", file);
597
} else if (md_name != NULL) {
598
BIO_printf(out, "%s(%s)= ", md_name, file);
599
} else {
600
BIO_printf(out, "(%s)= ", file);
601
}
602
for (i = 0; i < (int)len; i++) {
603
if (sep && (i != 0))
604
BIO_printf(out, ":");
605
BIO_printf(out, "%02x", buf[i]);
606
}
607
BIO_printf(out, "\n");
608
}
609
}
610
611
static void print_verify_result(BIO *out, int i)
612
{
613
if (i > 0)
614
BIO_printf(out, "Verified OK\n");
615
else if (i == 0)
616
BIO_printf(out, "Verification failure\n");
617
else
618
BIO_printf(bio_err, "Error verifying data\n");
619
}
620
621
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen,
622
EVP_PKEY *key, unsigned char *sigin, int siglen,
623
const char *sig_name, const char *md_name,
624
const char *file)
625
{
626
size_t len = BUFSIZE;
627
int i, ret = EXIT_FAILURE;
628
unsigned char *allocated_buf = NULL;
629
630
while (BIO_pending(bp) || !BIO_eof(bp)) {
631
i = BIO_read(bp, (char *)buf, BUFSIZE);
632
if (i < 0) {
633
BIO_printf(bio_err, "Read error in %s\n", file);
634
goto end;
635
}
636
if (i == 0)
637
break;
638
}
639
if (sigin != NULL) {
640
EVP_MD_CTX *ctx;
641
BIO_get_md_ctx(bp, &ctx);
642
i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen);
643
print_verify_result(out, i);
644
if (i > 0)
645
ret = EXIT_SUCCESS;
646
goto end;
647
}
648
if (key != NULL) {
649
EVP_MD_CTX *ctx;
650
size_t tmplen;
651
652
BIO_get_md_ctx(bp, &ctx);
653
if (!EVP_DigestSignFinal(ctx, NULL, &tmplen)) {
654
BIO_printf(bio_err, "Error getting maximum length of signed data\n");
655
goto end;
656
}
657
if (tmplen > BUFSIZE) {
658
len = tmplen;
659
allocated_buf = app_malloc(len, "Signature buffer");
660
buf = allocated_buf;
661
}
662
if (!EVP_DigestSignFinal(ctx, buf, &len)) {
663
BIO_printf(bio_err, "Error signing data\n");
664
goto end;
665
}
666
} else if (xoflen > 0) {
667
EVP_MD_CTX *ctx;
668
669
len = xoflen;
670
if (len > BUFSIZE) {
671
allocated_buf = app_malloc(len, "Digest buffer");
672
buf = allocated_buf;
673
}
674
675
BIO_get_md_ctx(bp, &ctx);
676
677
if (!EVP_DigestFinalXOF(ctx, buf, len)) {
678
BIO_printf(bio_err, "Error Digesting Data\n");
679
goto end;
680
}
681
} else {
682
len = BIO_gets(bp, (char *)buf, BUFSIZE);
683
if ((int)len < 0)
684
goto end;
685
}
686
print_out(out, buf, len, sep, binout, sig_name, md_name, file);
687
ret = EXIT_SUCCESS;
688
end:
689
if (allocated_buf != NULL)
690
OPENSSL_clear_free(allocated_buf, len);
691
692
return ret;
693
}
694
695
/*
696
* Some new algorithms only support one shot operations.
697
* For these we need to buffer all input and then do the sign on the
698
* total buffered input. These algorithms set a NULL digest name which is
699
* then used inside EVP_DigestVerify() and EVP_DigestSign().
700
*/
701
static int do_fp_oneshot_sign(BIO *out, EVP_MD_CTX *ctx, BIO *in, int sep, int binout,
702
EVP_PKEY *key, unsigned char *sigin, int siglen,
703
const char *sig_name, const char *file)
704
{
705
int res, ret = EXIT_FAILURE;
706
size_t len = 0;
707
int buflen = 0;
708
int maxlen = 16 * 1024 * 1024;
709
uint8_t *buf = NULL, *sig = NULL;
710
711
buflen = bio_to_mem(&buf, maxlen, in);
712
if (buflen <= 0) {
713
BIO_printf(bio_err, "Read error in %s\n", file);
714
return ret;
715
}
716
if (sigin != NULL) {
717
res = EVP_DigestVerify(ctx, sigin, siglen, buf, buflen);
718
print_verify_result(out, res);
719
if (res > 0)
720
ret = EXIT_SUCCESS;
721
goto end;
722
}
723
if (key != NULL) {
724
if (EVP_DigestSign(ctx, NULL, &len, buf, buflen) != 1) {
725
BIO_printf(bio_err, "Error getting maximum length of signed data\n");
726
goto end;
727
}
728
sig = app_malloc(len, "Signature buffer");
729
if (EVP_DigestSign(ctx, sig, &len, buf, buflen) != 1) {
730
BIO_printf(bio_err, "Error signing data\n");
731
goto end;
732
}
733
print_out(out, sig, len, sep, binout, sig_name, NULL, file);
734
ret = EXIT_SUCCESS;
735
} else {
736
BIO_printf(bio_err, "key must be set for one-shot algorithms\n");
737
goto end;
738
}
739
740
end:
741
OPENSSL_free(sig);
742
OPENSSL_clear_free(buf, buflen);
743
744
return ret;
745
}
746
747