From d40b1e08368b3db03f32c9770d96acf3c6a3956a Mon Sep 17 00:00:00 2001 From: tb Date: Mon, 10 Jan 2022 12:17:49 +0000 Subject: [PATCH] Implement openssl pkey -{,pub}check and pkeyparam -check These expose EVP_PKEY_{,public_,param_}check() to the command line. They are currently noops and will be enabled in the upcoming bump. ok inoguchi jsing --- usr.bin/openssl/apps.c | 30 +++++++++++++++++++++++++++++- usr.bin/openssl/apps.h | 4 +++- usr.bin/openssl/pkey.c | 36 ++++++++++++++++++++++++++++++------ usr.bin/openssl/pkeyparam.c | 19 +++++++++++++++++-- 4 files changed, 79 insertions(+), 10 deletions(-) diff --git a/usr.bin/openssl/apps.c b/usr.bin/openssl/apps.c index 392d3cc3393..fd13371f5d3 100644 --- a/usr.bin/openssl/apps.c +++ b/usr.bin/openssl/apps.c @@ -1,4 +1,4 @@ -/* $OpenBSD: apps.c,v 1.61 2021/11/26 16:23:27 tb Exp $ */ +/* $OpenBSD: apps.c,v 1.62 2022/01/10 12:17:49 tb Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -2262,3 +2262,31 @@ show_cipher(const OBJ_NAME *name, void *arg) fprintf(stderr, " -%-24s%s", name->name, (++*n % 3 != 0 ? "" : "\n")); } + +int +pkey_check(BIO *out, EVP_PKEY *pkey, int (check_fn)(EVP_PKEY_CTX *), + const char *desc) +{ + EVP_PKEY_CTX *ctx; + + if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + ERR_print_errors(bio_err); + return 0; + } + + if (check_fn(ctx) == 1) { + BIO_printf(out, "%s valid\n", desc); + } else { + unsigned long err; + + BIO_printf(out, "%s invalid\n", desc); + + while ((err = ERR_get_error()) != 0) + BIO_printf(out, "Detailed error: %s\n", + ERR_reason_error_string(err)); + } + + EVP_PKEY_CTX_free(ctx); + + return 1; +} diff --git a/usr.bin/openssl/apps.h b/usr.bin/openssl/apps.h index e8116bfe440..f4fa5361a79 100644 --- a/usr.bin/openssl/apps.h +++ b/usr.bin/openssl/apps.h @@ -1,4 +1,4 @@ -/* $OpenBSD: apps.h,v 1.30 2021/11/26 16:23:27 tb Exp $ */ +/* $OpenBSD: apps.h,v 1.31 2022/01/10 12:17:49 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -326,4 +326,6 @@ int options_parse(int argc, char **argv, const struct option *opts, void show_cipher(const OBJ_NAME *name, void *arg); +int pkey_check(BIO *out, EVP_PKEY *pkey, int (check_fn)(EVP_PKEY_CTX *), + const char *desc); #endif diff --git a/usr.bin/openssl/pkey.c b/usr.bin/openssl/pkey.c index 06b4c018947..9134fc71925 100644 --- a/usr.bin/openssl/pkey.c +++ b/usr.bin/openssl/pkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pkey.c,v 1.15 2019/07/14 03:30:46 guenther Exp $ */ +/* $OpenBSD: pkey.c,v 1.16 2022/01/10 12:17:49 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006 */ @@ -66,6 +66,7 @@ #include static struct { + int check; const EVP_CIPHER *cipher; char *infile; int informat; @@ -74,6 +75,7 @@ static struct { int outformat; char *passargin; char *passargout; + int pubcheck; int pubin; int pubout; int pubtext; @@ -98,6 +100,12 @@ pkey_opt_cipher(int argc, char **argv, int *argsused) } static const struct option pkey_options[] = { + { + .name = "check", + .desc = "Check validity of key", + .type = OPTION_FLAG, + .opt.flag = &pkey_config.check, + }, { .name = "in", .argname = "file", @@ -146,6 +154,12 @@ static const struct option pkey_options[] = { .type = OPTION_ARG, .opt.arg = &pkey_config.passargout, }, + { + .name = "pubcheck", + .desc = "Check validity of public key", + .type = OPTION_FLAG, + .opt.flag = &pkey_config.pubcheck, + }, { .name = "pubin", .desc = "Expect a public key (default private key)", @@ -186,11 +200,11 @@ pkey_usage() int n = 0; fprintf(stderr, - "usage: pkey [-ciphername] [-in file] [-inform fmt] [-noout] " - "[-out file]\n" - " [-outform fmt] [-passin src] [-passout src] [-pubin] " - "[-pubout] [-text]\n" - " [-text_pub]\n\n"); + "usage: pkey [-check] [-ciphername] [-in file] [-inform fmt] " + "[-noout] [-out file]\n" + " [-outform fmt] [-passin src] [-passout src] [-pubcheck] " + "[-pubin] [-pubout]\n" + " [-text] [-text_pub]\n\n"); options_usage(pkey_options); fprintf(stderr, "\n"); @@ -252,6 +266,16 @@ pkey_main(int argc, char **argv) if (!pkey) goto end; +#if notyet + if (pkey_config.check) { + if (!pkey_check(out, pkey, EVP_PKEY_check, "Key pair")) + goto end; + } else if (pkey_config.pubcheck) { + if (!pkey_check(out, pkey, EVP_PKEY_public_check, "Public key")) + goto end; + } +#endif + if (!pkey_config.noout) { if (pkey_config.outformat == FORMAT_PEM) { if (pkey_config.pubout) diff --git a/usr.bin/openssl/pkeyparam.c b/usr.bin/openssl/pkeyparam.c index 81bed13958c..6ac45585789 100644 --- a/usr.bin/openssl/pkeyparam.c +++ b/usr.bin/openssl/pkeyparam.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pkeyparam.c,v 1.12 2019/07/14 03:30:46 guenther Exp $ */ +/* $OpenBSD: pkeyparam.c,v 1.13 2022/01/10 12:17:49 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006 */ @@ -66,6 +66,7 @@ #include struct { + int check; char *infile; int noout; char *outfile; @@ -73,6 +74,12 @@ struct { } pkeyparam_config; static const struct option pkeyparam_options[] = { + { + .name = "check", + .desc = "Check validity of key parameters", + .type = OPTION_FLAG, + .opt.flag = &pkeyparam_config.check, + }, { .name = "in", .argname = "file", @@ -106,7 +113,7 @@ static void pkeyparam_usage() { fprintf(stderr, - "usage: pkeyparam [-in file] [-noout] [-out file] " + "usage: pkeyparam [-check] [-in file] [-noout] [-out file] " "[-text]\n"); options_usage(pkeyparam_options); } @@ -157,6 +164,14 @@ pkeyparam_main(int argc, char **argv) ERR_print_errors(bio_err); goto end; } + +#if notyet + if (pkeyparam_config.check) { + if (!pkey_check(out, pkey, EVP_PKEY_param_check, "Parameters")) + goto end; + } +#endif + if (!pkeyparam_config.noout) PEM_write_bio_Parameters(out, pkey); -- 2.20.1