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