X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=apps%2Fpkeyutl.c;h=4de2a5659048ef76aa31da2761810c7b6f5eeab6;hb=914f97eecc9166fbfdb50c2d04e2b9f9d0c52198;hp=6b012211e429c710ee11365198438a8a865d37b3;hpb=5ffc33244cd4d66e47dfa66ce89cb38d0f3074cc;p=openssl.git diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index 6b012211e4..4de2a56590 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,6 +15,8 @@ #include #include +DEFINE_STACK_OF_STRING() + #define KEY_NONE 0 #define KEY_PRIVKEY 1 #define KEY_PUBKEY 2 @@ -23,7 +25,8 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, const char *keyfile, int keyform, int key_type, char *passinarg, int pkey_op, ENGINE *e, - const int impl, int rawin, EVP_PKEY **ppkey); + const int impl, int rawin, EVP_PKEY **ppkey, + OPENSSL_CTX *libctx, const char *propq); static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, ENGINE *e); @@ -44,51 +47,63 @@ typedef enum OPTION_choice { OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN, OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_PKEYOPT_PASSIN, OPT_KDF, - OPT_KDFLEN, OPT_R_ENUM, + OPT_KDFLEN, OPT_R_ENUM, OPT_PROV_ENUM, + OPT_CONFIG, OPT_RAWIN, OPT_DIGEST } OPTION_CHOICE; const OPTIONS pkeyutl_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"engine_impl", OPT_ENGINE_IMPL, '-', + "Also use engine given by -engine for crypto operations"}, +#endif + {"sign", OPT_SIGN, '-', "Sign input data with private key"}, + {"verify", OPT_VERIFY, '-', "Verify with public key"}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, + {"derive", OPT_DERIVE, '-', "Derive shared secret"}, + OPT_CONFIG_OPTION, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file - default stdin"}, {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"}, - {"digest", OPT_DIGEST, 's', - "Specify the digest algorithm when signing the raw input data"}, - {"out", OPT_OUT, '>', "Output file - default stdout"}, {"pubin", OPT_PUBIN, '-', "Input is a public key"}, + {"inkey", OPT_INKEY, 's', "Input private key file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, + {"peerform", OPT_PEERFORM, 'E', "Peer key format (DER/PEM/P12/ENGINE)"}, {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, + {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, + {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, + {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file - default stdout"}, {"asn1parse", OPT_ASN1PARSE, '-', "asn1parse the output data"}, {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, - {"sign", OPT_SIGN, '-', "Sign input data with private key"}, - {"verify", OPT_VERIFY, '-', "Verify with public key"}, {"verifyrecover", OPT_VERIFYRECOVER, '-', "Verify with public key, recover original data"}, - {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, - {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, - {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, - {"derive", OPT_DERIVE, '-', "Derive shared secret"}, - {"kdf", OPT_KDF, 's', "Use KDF algorithm"}, - {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"}, - {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, - {"inkey", OPT_INKEY, 's', "Input private key file"}, - {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"}, - {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, + + OPT_SECTION("Signing/Derivation"), + {"digest", OPT_DIGEST, 's', + "Specify the digest algorithm when signing the raw input data"}, {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, {"pkeyopt_passin", OPT_PKEYOPT_PASSIN, 's', "Public key option that is read as a passphrase argument opt:passphrase"}, + {"kdf", OPT_KDF, 's', "Use KDF algorithm"}, + {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, - {"engine_impl", OPT_ENGINE_IMPL, '-', - "Also use engine given by -engine for crypto operations"}, -#endif + OPT_PROV_OPTIONS, {NULL} }; int pkeyutl_main(int argc, char **argv) { + CONF *conf = NULL; BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -111,6 +126,8 @@ int pkeyutl_main(int argc, char **argv) int rawin = 0; const EVP_MD *md = NULL; int filesize = -1; + OPENSSL_CTX *libctx = app_get0_libctx(); + const char *propq = NULL; prog = opt_init(argc, argv, pkeyutl_options); while ((o = opt_next()) != OPT_EOF) { @@ -146,17 +163,26 @@ int pkeyutl_main(int argc, char **argv) passinarg = opt_arg(); break; case OPT_PEERFORM: - if (!opt_format(opt_arg(), OPT_FMT_PDE, &peerform)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &peerform)) goto opthelp; break; case OPT_KEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_R_CASES: if (!opt_rand(o)) goto end; break; + case OPT_CONFIG: + conf = app_load_config_modules(opt_arg()); + if (conf == NULL) + goto end; + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; @@ -266,7 +292,8 @@ int pkeyutl_main(int argc, char **argv) goto opthelp; } ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type, - passinarg, pkey_op, e, engine_impl, rawin, &pkey); + passinarg, pkey_op, e, engine_impl, rawin, &pkey, + libctx, propq); if (ctx == NULL) { BIO_printf(bio_err, "%s: Error initializing context\n", prog); ERR_print_errors(bio_err); @@ -469,6 +496,7 @@ int pkeyutl_main(int argc, char **argv) OPENSSL_free(sig); sk_OPENSSL_STRING_free(pkeyopts); sk_OPENSSL_STRING_free(pkeyopts_passin); + NCONF_free(conf); return ret; } @@ -476,7 +504,8 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, const char *keyfile, int keyform, int key_type, char *passinarg, int pkey_op, ENGINE *e, const int engine_impl, int rawin, - EVP_PKEY **ppkey) + EVP_PKEY **ppkey, + OPENSSL_CTX *libctx, const char *propq) { EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -504,7 +533,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, break; case KEY_CERT: - x = load_cert(keyfile, keyform, "Certificate"); + x = load_cert(keyfile, FORMAT_UNDEF, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); @@ -532,28 +561,19 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, goto end; } } - ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); + if (impl != NULL) + ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); + else + ctx = EVP_PKEY_CTX_new_from_name(libctx, kdfalg, propq); } else { if (pkey == NULL) goto end; -#ifndef OPENSSL_NO_EC - /* SM2 needs a special treatment */ - if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { - EC_KEY *eckey = NULL; - const EC_GROUP *group = NULL; - int nid; - - if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL - || (group = EC_KEY_get0_group(eckey)) == NULL - || (nid = EC_GROUP_get_curve_name(group)) == 0) - goto end; - if (nid == NID_sm2) - EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); - } -#endif *pkeysize = EVP_PKEY_size(pkey); - ctx = EVP_PKEY_CTX_new(pkey, impl); + if (impl != NULL) + ctx = EVP_PKEY_CTX_new(pkey, impl); + else + ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (ppkey != NULL) *ppkey = pkey; EVP_PKEY_free(pkey);