version 1.20, 2022/11/11 17:07:38 |
version 1.21, 2023/03/06 14:32:05 |
|
|
char *sigfile; |
char *sigfile; |
STACK_OF(OPENSSL_STRING) *sigopts; |
STACK_OF(OPENSSL_STRING) *sigopts; |
int want_pub; |
int want_pub; |
} dgst_config; |
} cfg; |
|
|
static int |
static int |
dgst_opt_macopt(char *arg) |
dgst_opt_macopt(char *arg) |
|
|
if (arg == NULL) |
if (arg == NULL) |
return (1); |
return (1); |
|
|
if (dgst_config.macopts == NULL && |
if (cfg.macopts == NULL && |
(dgst_config.macopts = sk_OPENSSL_STRING_new_null()) == NULL) |
(cfg.macopts = sk_OPENSSL_STRING_new_null()) == NULL) |
return (1); |
return (1); |
|
|
if (!sk_OPENSSL_STRING_push(dgst_config.macopts, arg)) |
if (!sk_OPENSSL_STRING_push(cfg.macopts, arg)) |
return (1); |
return (1); |
|
|
return (0); |
return (0); |
|
|
if (*name++ != '-') |
if (*name++ != '-') |
return (1); |
return (1); |
|
|
if ((dgst_config.m = EVP_get_digestbyname(name)) == NULL) |
if ((cfg.m = EVP_get_digestbyname(name)) == NULL) |
return (1); |
return (1); |
|
|
dgst_config.md = dgst_config.m; |
cfg.md = cfg.m; |
|
|
*argsused = 1; |
*argsused = 1; |
return (0); |
return (0); |
|
|
if (arg == NULL) |
if (arg == NULL) |
return (1); |
return (1); |
|
|
dgst_config.keyfile = arg; |
cfg.keyfile = arg; |
dgst_config.do_verify = 1; |
cfg.do_verify = 1; |
return (0); |
return (0); |
} |
} |
|
|
|
|
if (arg == NULL) |
if (arg == NULL) |
return (1); |
return (1); |
|
|
if (dgst_config.sigopts == NULL && |
if (cfg.sigopts == NULL && |
(dgst_config.sigopts = sk_OPENSSL_STRING_new_null()) == NULL) |
(cfg.sigopts = sk_OPENSSL_STRING_new_null()) == NULL) |
return (1); |
return (1); |
|
|
if (!sk_OPENSSL_STRING_push(dgst_config.sigopts, arg)) |
if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg)) |
return (1); |
return (1); |
|
|
return (0); |
return (0); |
|
|
if (arg == NULL) |
if (arg == NULL) |
return (1); |
return (1); |
|
|
dgst_config.keyfile = arg; |
cfg.keyfile = arg; |
dgst_config.want_pub = 1; |
cfg.want_pub = 1; |
dgst_config.do_verify = 1; |
cfg.do_verify = 1; |
return (0); |
return (0); |
} |
} |
|
|
|
|
.name = "binary", |
.name = "binary", |
.desc = "Output the digest or signature in binary form", |
.desc = "Output the digest or signature in binary form", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &dgst_config.out_bin, |
.opt.value = &cfg.out_bin, |
.value = 1, |
.value = 1, |
}, |
}, |
{ |
{ |
.name = "c", |
.name = "c", |
.desc = "Print the digest in two-digit groups separated by colons", |
.desc = "Print the digest in two-digit groups separated by colons", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &dgst_config.separator, |
.opt.value = &cfg.separator, |
.value = 1, |
.value = 1, |
}, |
}, |
{ |
{ |
.name = "d", |
.name = "d", |
.desc = "Print BIO debugging information", |
.desc = "Print BIO debugging information", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &dgst_config.debug, |
.opt.flag = &cfg.debug, |
}, |
}, |
{ |
{ |
.name = "hex", |
.name = "hex", |
.desc = "Output as hex dump", |
.desc = "Output as hex dump", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &dgst_config.out_bin, |
.opt.value = &cfg.out_bin, |
.value = 0, |
.value = 0, |
}, |
}, |
{ |
{ |
|
|
.argname = "key", |
.argname = "key", |
.desc = "Create hashed MAC with key", |
.desc = "Create hashed MAC with key", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &dgst_config.hmac_key, |
.opt.arg = &cfg.hmac_key, |
}, |
}, |
{ |
{ |
.name = "keyform", |
.name = "keyform", |
.argname = "format", |
.argname = "format", |
.desc = "Key file format (PEM)", |
.desc = "Key file format (PEM)", |
.type = OPTION_ARG_FORMAT, |
.type = OPTION_ARG_FORMAT, |
.opt.value = &dgst_config.keyform, |
.opt.value = &cfg.keyform, |
}, |
}, |
{ |
{ |
.name = "mac", |
.name = "mac", |
.argname = "algorithm", |
.argname = "algorithm", |
.desc = "Create MAC (not necessarily HMAC)", |
.desc = "Create MAC (not necessarily HMAC)", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &dgst_config.mac_name, |
.opt.arg = &cfg.mac_name, |
}, |
}, |
{ |
{ |
.name = "macopt", |
.name = "macopt", |
|
|
.argname = "file", |
.argname = "file", |
.desc = "Output to file rather than stdout", |
.desc = "Output to file rather than stdout", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &dgst_config.outfile, |
.opt.arg = &cfg.outfile, |
}, |
}, |
{ |
{ |
.name = "passin", |
.name = "passin", |
.argname = "arg", |
.argname = "arg", |
.desc = "Input file passphrase source", |
.desc = "Input file passphrase source", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &dgst_config.passargin, |
.opt.arg = &cfg.passargin, |
}, |
}, |
{ |
{ |
.name = "prverify", |
.name = "prverify", |
|
|
.name = "r", |
.name = "r", |
.desc = "Output the digest in coreutils format", |
.desc = "Output the digest in coreutils format", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &dgst_config.separator, |
.opt.value = &cfg.separator, |
.value = 2, |
.value = 2, |
}, |
}, |
{ |
{ |
|
|
.argname = "file", |
.argname = "file", |
.desc = "Sign digest using private key in file", |
.desc = "Sign digest using private key in file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &dgst_config.keyfile, |
.opt.arg = &cfg.keyfile, |
}, |
}, |
{ |
{ |
.name = "signature", |
.name = "signature", |
.argname = "file", |
.argname = "file", |
.desc = "Signature to verify", |
.desc = "Signature to verify", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &dgst_config.sigfile, |
.opt.arg = &cfg.sigfile, |
}, |
}, |
{ |
{ |
.name = "sigopt", |
.name = "sigopt", |
|
|
goto end; |
goto end; |
} |
} |
|
|
memset(&dgst_config, 0, sizeof(dgst_config)); |
memset(&cfg, 0, sizeof(cfg)); |
dgst_config.keyform = FORMAT_PEM; |
cfg.keyform = FORMAT_PEM; |
dgst_config.out_bin = -1; |
cfg.out_bin = -1; |
|
|
/* first check the program name */ |
/* first check the program name */ |
program_name(argv[0], pname, sizeof pname); |
program_name(argv[0], pname, sizeof pname); |
|
|
dgst_config.md = EVP_get_digestbyname(pname); |
cfg.md = EVP_get_digestbyname(pname); |
|
|
if (options_parse(argc, argv, dgst_options, NULL, |
if (options_parse(argc, argv, dgst_options, NULL, |
&dgst_config.argsused) != 0) { |
&cfg.argsused) != 0) { |
dgst_usage(); |
dgst_usage(); |
goto end; |
goto end; |
} |
} |
argc -= dgst_config.argsused; |
argc -= cfg.argsused; |
argv += dgst_config.argsused; |
argv += cfg.argsused; |
|
|
if (dgst_config.do_verify && !dgst_config.sigfile) { |
if (cfg.do_verify && !cfg.sigfile) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"No signature to verify: use the -signature option\n"); |
"No signature to verify: use the -signature option\n"); |
goto end; |
goto end; |
|
|
goto end; |
goto end; |
} |
} |
|
|
if (dgst_config.debug) { |
if (cfg.debug) { |
BIO_set_callback(in, BIO_debug_callback); |
BIO_set_callback(in, BIO_debug_callback); |
/* needed for windows 3.1 */ |
/* needed for windows 3.1 */ |
BIO_set_callback_arg(in, (char *) bio_err); |
BIO_set_callback_arg(in, (char *) bio_err); |
} |
} |
if (!app_passwd(bio_err, dgst_config.passargin, NULL, &passin, NULL)) { |
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) { |
BIO_printf(bio_err, "Error getting password\n"); |
BIO_printf(bio_err, "Error getting password\n"); |
goto end; |
goto end; |
} |
} |
if (dgst_config.out_bin == -1) { |
if (cfg.out_bin == -1) { |
if (dgst_config.keyfile) |
if (cfg.keyfile) |
dgst_config.out_bin = 1; |
cfg.out_bin = 1; |
else |
else |
dgst_config.out_bin = 0; |
cfg.out_bin = 0; |
} |
} |
|
|
if (dgst_config.outfile) { |
if (cfg.outfile) { |
if (dgst_config.out_bin) |
if (cfg.out_bin) |
out = BIO_new_file(dgst_config.outfile, "wb"); |
out = BIO_new_file(cfg.outfile, "wb"); |
else |
else |
out = BIO_new_file(dgst_config.outfile, "w"); |
out = BIO_new_file(cfg.outfile, "w"); |
} else { |
} else { |
out = BIO_new_fp(stdout, BIO_NOCLOSE); |
out = BIO_new_fp(stdout, BIO_NOCLOSE); |
} |
} |
|
|
if (!out) { |
if (!out) { |
BIO_printf(bio_err, "Error opening output file %s\n", |
BIO_printf(bio_err, "Error opening output file %s\n", |
dgst_config.outfile ? dgst_config.outfile : "(stdout)"); |
cfg.outfile ? cfg.outfile : "(stdout)"); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
if ((!!dgst_config.mac_name + !!dgst_config.keyfile + |
if ((!!cfg.mac_name + !!cfg.keyfile + |
!!dgst_config.hmac_key) > 1) { |
!!cfg.hmac_key) > 1) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"MAC and Signing key cannot both be specified\n"); |
"MAC and Signing key cannot both be specified\n"); |
goto end; |
goto end; |
} |
} |
if (dgst_config.keyfile) { |
if (cfg.keyfile) { |
if (dgst_config.want_pub) |
if (cfg.want_pub) |
sigkey = load_pubkey(bio_err, dgst_config.keyfile, |
sigkey = load_pubkey(bio_err, cfg.keyfile, |
dgst_config.keyform, 0, NULL, "key file"); |
cfg.keyform, 0, NULL, "key file"); |
else |
else |
sigkey = load_key(bio_err, dgst_config.keyfile, |
sigkey = load_key(bio_err, cfg.keyfile, |
dgst_config.keyform, 0, passin, "key file"); |
cfg.keyform, 0, passin, "key file"); |
if (!sigkey) { |
if (!sigkey) { |
/* |
/* |
* load_[pub]key() has already printed an appropriate |
* load_[pub]key() has already printed an appropriate |
|
|
goto end; |
goto end; |
} |
} |
} |
} |
if (dgst_config.mac_name) { |
if (cfg.mac_name) { |
EVP_PKEY_CTX *mac_ctx = NULL; |
EVP_PKEY_CTX *mac_ctx = NULL; |
int r = 0; |
int r = 0; |
if (!init_gen_str(bio_err, &mac_ctx, dgst_config.mac_name, 0)) |
if (!init_gen_str(bio_err, &mac_ctx, cfg.mac_name, 0)) |
goto mac_end; |
goto mac_end; |
if (dgst_config.macopts) { |
if (cfg.macopts) { |
char *macopt; |
char *macopt; |
for (i = 0; i < sk_OPENSSL_STRING_num( |
for (i = 0; i < sk_OPENSSL_STRING_num( |
dgst_config.macopts); i++) { |
cfg.macopts); i++) { |
macopt = sk_OPENSSL_STRING_value( |
macopt = sk_OPENSSL_STRING_value( |
dgst_config.macopts, i); |
cfg.macopts, i); |
if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { |
if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"MAC parameter error \"%s\"\n", |
"MAC parameter error \"%s\"\n", |
|
|
if (r == 0) |
if (r == 0) |
goto end; |
goto end; |
} |
} |
if (dgst_config.hmac_key) { |
if (cfg.hmac_key) { |
sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, |
sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, |
(unsigned char *) dgst_config.hmac_key, -1); |
(unsigned char *) cfg.hmac_key, -1); |
if (!sigkey) |
if (!sigkey) |
goto end; |
goto end; |
} |
} |
|
|
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
if (dgst_config.do_verify) |
if (cfg.do_verify) |
r = EVP_DigestVerifyInit(mctx, &pctx, dgst_config.md, |
r = EVP_DigestVerifyInit(mctx, &pctx, cfg.md, |
NULL, sigkey); |
NULL, sigkey); |
else |
else |
r = EVP_DigestSignInit(mctx, &pctx, dgst_config.md, |
r = EVP_DigestSignInit(mctx, &pctx, cfg.md, |
NULL, sigkey); |
NULL, sigkey); |
if (!r) { |
if (!r) { |
BIO_printf(bio_err, "Error setting context\n"); |
BIO_printf(bio_err, "Error setting context\n"); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
if (dgst_config.sigopts) { |
if (cfg.sigopts) { |
char *sigopt; |
char *sigopt; |
for (i = 0; i < sk_OPENSSL_STRING_num( |
for (i = 0; i < sk_OPENSSL_STRING_num( |
dgst_config.sigopts); i++) { |
cfg.sigopts); i++) { |
sigopt = sk_OPENSSL_STRING_value( |
sigopt = sk_OPENSSL_STRING_value( |
dgst_config.sigopts, i); |
cfg.sigopts, i); |
if (pkey_ctrl_string(pctx, sigopt) <= 0) { |
if (pkey_ctrl_string(pctx, sigopt) <= 0) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"parameter error \"%s\"\n", |
"parameter error \"%s\"\n", |
|
|
} |
} |
/* we use md as a filter, reading from 'in' */ |
/* we use md as a filter, reading from 'in' */ |
else { |
else { |
if (dgst_config.md == NULL) |
if (cfg.md == NULL) |
dgst_config.md = EVP_sha256(); |
cfg.md = EVP_sha256(); |
if (!BIO_set_md(bmd, dgst_config.md)) { |
if (!BIO_set_md(bmd, cfg.md)) { |
BIO_printf(bio_err, "Error setting digest %s\n", pname); |
BIO_printf(bio_err, "Error setting digest %s\n", pname); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
} |
} |
|
|
if (dgst_config.sigfile && sigkey) { |
if (cfg.sigfile && sigkey) { |
BIO *sigbio; |
BIO *sigbio; |
siglen = EVP_PKEY_size(sigkey); |
siglen = EVP_PKEY_size(sigkey); |
sigbuf = malloc(siglen); |
sigbuf = malloc(siglen); |
|
|
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
sigbio = BIO_new_file(dgst_config.sigfile, "rb"); |
sigbio = BIO_new_file(cfg.sigfile, "rb"); |
if (!sigbio) { |
if (!sigbio) { |
BIO_printf(bio_err, "Error opening signature file %s\n", |
BIO_printf(bio_err, "Error opening signature file %s\n", |
dgst_config.sigfile); |
cfg.sigfile); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
|
|
BIO_free(sigbio); |
BIO_free(sigbio); |
if (siglen <= 0) { |
if (siglen <= 0) { |
BIO_printf(bio_err, "Error reading signature file %s\n", |
BIO_printf(bio_err, "Error reading signature file %s\n", |
dgst_config.sigfile); |
cfg.sigfile); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
} |
} |
inp = BIO_push(bmd, in); |
inp = BIO_push(bmd, in); |
|
|
if (dgst_config.md == NULL) { |
if (cfg.md == NULL) { |
EVP_MD_CTX *tctx; |
EVP_MD_CTX *tctx; |
BIO_get_md_ctx(bmd, &tctx); |
BIO_get_md_ctx(bmd, &tctx); |
dgst_config.md = EVP_MD_CTX_md(tctx); |
cfg.md = EVP_MD_CTX_md(tctx); |
} |
} |
if (argc == 0) { |
if (argc == 0) { |
BIO_set_fp(in, stdin, BIO_NOCLOSE); |
BIO_set_fp(in, stdin, BIO_NOCLOSE); |
err = do_fp(out, buf, inp, dgst_config.separator, |
err = do_fp(out, buf, inp, cfg.separator, |
dgst_config.out_bin, sigkey, sigbuf, siglen, NULL, NULL, |
cfg.out_bin, sigkey, sigbuf, siglen, NULL, NULL, |
"stdin", bmd); |
"stdin", bmd); |
} else { |
} else { |
const char *md_name = NULL, *sig_name = NULL; |
const char *md_name = NULL, *sig_name = NULL; |
if (!dgst_config.out_bin) { |
if (!cfg.out_bin) { |
if (sigkey) { |
if (sigkey) { |
const EVP_PKEY_ASN1_METHOD *ameth; |
const EVP_PKEY_ASN1_METHOD *ameth; |
ameth = EVP_PKEY_get0_asn1(sigkey); |
ameth = EVP_PKEY_get0_asn1(sigkey); |
|
|
EVP_PKEY_asn1_get0_info(NULL, NULL, |
EVP_PKEY_asn1_get0_info(NULL, NULL, |
NULL, NULL, &sig_name, ameth); |
NULL, NULL, &sig_name, ameth); |
} |
} |
md_name = EVP_MD_name(dgst_config.md); |
md_name = EVP_MD_name(cfg.md); |
} |
} |
err = 0; |
err = 0; |
for (i = 0; i < argc; i++) { |
for (i = 0; i < argc; i++) { |
|
|
err++; |
err++; |
continue; |
continue; |
} else { |
} else { |
r = do_fp(out, buf, inp, dgst_config.separator, |
r = do_fp(out, buf, inp, cfg.separator, |
dgst_config.out_bin, sigkey, sigbuf, siglen, |
cfg.out_bin, sigkey, sigbuf, siglen, |
sig_name, md_name, argv[i], bmd); |
sig_name, md_name, argv[i], bmd); |
} |
} |
if (r) |
if (r) |
|
|
free(passin); |
free(passin); |
BIO_free_all(out); |
BIO_free_all(out); |
EVP_PKEY_free(sigkey); |
EVP_PKEY_free(sigkey); |
sk_OPENSSL_STRING_free(dgst_config.sigopts); |
sk_OPENSSL_STRING_free(cfg.sigopts); |
sk_OPENSSL_STRING_free(dgst_config.macopts); |
sk_OPENSSL_STRING_free(cfg.macopts); |
free(sigbuf); |
free(sigbuf); |
BIO_free(bmd); |
BIO_free(bmd); |
|
|