From 55accfd2f11d02cf4cfdc6077216ae59f1748f6a Mon Sep 17 00:00:00 2001 From: Pauli Date: Wed, 21 Aug 2019 18:53:45 +1000 Subject: [PATCH] App updates for KDF provider conversion. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/9662) --- apps/kdf.c | 49 ++++++++++++++++++------------------------ apps/list.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 30 deletions(-) diff --git a/apps/kdf.c b/apps/kdf.c index 684fd44cc0..c230430697 100644 --- a/apps/kdf.c +++ b/apps/kdf.c @@ -15,6 +15,7 @@ #include #include #include +#include typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -34,27 +35,9 @@ const OPTIONS kdf_options[] = { {NULL} }; -static int kdf_ctrl_string(EVP_KDF_CTX *ctx, const char *value) -{ - int rv; - char *stmp, *vtmp = NULL; - - stmp = OPENSSL_strdup(value); - if (stmp == NULL) - return -1; - vtmp = strchr(stmp, ':'); - if (vtmp != NULL) { - *vtmp = 0; - vtmp++; - } - rv = EVP_KDF_ctrl_str(ctx, stmp, vtmp); - OPENSSL_free(stmp); - return rv; -} - int kdf_main(int argc, char **argv) { - int ret = 1, i, id, out_bin = 0; + int ret = 1, out_bin = 0; OPTION_CHOICE o; STACK_OF(OPENSSL_STRING) *opts = NULL; char *prog, *hexout = NULL; @@ -62,6 +45,7 @@ int kdf_main(int argc, char **argv) unsigned char *dkm_bytes = NULL; size_t dkm_len = 0; BIO *out = NULL; + EVP_KDF *kdf = NULL; EVP_KDF_CTX *ctx = NULL; prog = opt_init(argc, argv, kdf_options); @@ -100,25 +84,31 @@ opthelp: goto opthelp; } - id = OBJ_sn2nid(argv[0]); - if (id == NID_undef) { + if ((kdf = EVP_KDF_fetch(NULL, argv[0], NULL)) == NULL) { BIO_printf(bio_err, "Invalid KDF name %s\n", argv[0]); goto opthelp; } - ctx = EVP_KDF_CTX_new_id(id); + ctx = EVP_KDF_CTX_new(kdf); if (ctx == NULL) goto err; if (opts != NULL) { - for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { - char *opt = sk_OPENSSL_STRING_value(opts, i); - if (kdf_ctrl_string(ctx, opt) <= 0) { - BIO_printf(bio_err, "KDF parameter error '%s'\n", opt); - ERR_print_errors(bio_err); - goto err; - } + int ok = 1; + OSSL_PARAM *params = + app_params_new_from_opts(opts, EVP_KDF_CTX_settable_params(kdf)); + + if (params == NULL) + goto err; + + if (!EVP_KDF_CTX_set_params(ctx, params)) { + BIO_printf(bio_err, "KDF parameter error\n"); + ERR_print_errors(bio_err); + ok = 0; } + app_params_free(params); + if (!ok) + goto err; } out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); @@ -151,6 +141,7 @@ err: ERR_print_errors(bio_err); OPENSSL_clear_free(dkm_bytes, dkm_len); sk_OPENSSL_STRING_free(opts); + EVP_KDF_free(kdf); EVP_KDF_CTX_free(ctx); BIO_free(out); OPENSSL_free(hexout); diff --git a/apps/list.c b/apps/list.c index 3e34228d1e..2b44cac71b 100644 --- a/apps/list.c +++ b/apps/list.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "apps.h" #include "app_params.h" #include "progs.h" @@ -193,6 +194,56 @@ static void list_macs(void) sk_EVP_MAC_pop_free(macs, EVP_MAC_free); } +/* + * KDFs and PRFs + */ +DEFINE_STACK_OF(EVP_KDF) +static int kdf_cmp(const EVP_KDF * const *a, const EVP_KDF * const *b) +{ + int ret = strcasecmp(EVP_KDF_name(*a), EVP_KDF_name(*b)); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_KDF_provider(*a)), + OSSL_PROVIDER_name(EVP_KDF_provider(*b))); + + return ret; +} + +static void collect_kdfs(EVP_KDF *kdf, void *stack) +{ + STACK_OF(EVP_KDF) *kdf_stack = stack; + + sk_EVP_KDF_push(kdf_stack, kdf); + EVP_KDF_up_ref(kdf); +} + +static void list_kdfs(void) +{ + STACK_OF(EVP_KDF) *kdfs = sk_EVP_KDF_new(kdf_cmp); + int i; + + BIO_printf(bio_out, "Provided KDFs and PDFs:\n"); + EVP_KDF_do_all_ex(NULL, collect_kdfs, kdfs); + sk_EVP_KDF_sort(kdfs); + for (i = 0; i < sk_EVP_KDF_num(kdfs); i++) { + const EVP_KDF *m = sk_EVP_KDF_value(kdfs, i); + + BIO_printf(bio_out, " %s", EVP_KDF_name(m)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_KDF_provider(m))); + + if (verbose) { + print_param_types("retrievable algorithm parameters", + EVP_KDF_gettable_params(m), 4); + print_param_types("retrievable operation parameters", + EVP_KDF_CTX_gettable_params(m), 4); + print_param_types("settable operation parameters", + EVP_KDF_CTX_settable_params(m), 4); + } + } + sk_EVP_KDF_pop_free(kdfs, EVP_KDF_free); +} + static void list_missing_help(void) { const FUNCTION *fp; @@ -527,7 +578,7 @@ typedef enum HELPLIST_CHOICE { OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS, OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_ENGINES, OPT_DISABLED, - OPT_MISSING_HELP, OPT_OBJECTS + OPT_KDF_ALGORITHMS, OPT_MISSING_HELP, OPT_OBJECTS } HELPLIST_CHOICE; const OPTIONS list_options[] = { @@ -539,6 +590,8 @@ const OPTIONS list_options[] = { "List of message digest commands"}, {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-', "List of message digest algorithms"}, + {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-', + "List of key derivation and pseudo random function algorithms"}, {"mac-algorithms", OPT_MAC_ALGORITHMS, '-', "List of message authentication code algorithms"}, {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"}, @@ -570,6 +623,7 @@ int list_main(int argc, char **argv) unsigned int commands:1; unsigned int digest_commands:1; unsigned int digest_algorithms:1; + unsigned int kdf_algorithms:1; unsigned int mac_algorithms:1; unsigned int cipher_commands:1; unsigned int cipher_algorithms:1; @@ -607,6 +661,9 @@ opthelp: case OPT_DIGEST_ALGORITHMS: todo.digest_algorithms = 1; break; + case OPT_KDF_ALGORITHMS: + todo.kdf_algorithms = 1; + break; case OPT_MAC_ALGORITHMS: todo.mac_algorithms = 1; break; @@ -654,6 +711,8 @@ opthelp: list_type(FT_md, one); if (todo.digest_algorithms) list_digests(); + if (todo.kdf_algorithms) + list_kdfs(); if (todo.mac_algorithms) list_macs(); if (todo.cipher_commands) -- 2.25.1