diff options
author | Richard Levitte <levitte@openssl.org> | 2020-12-04 06:32:24 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2020-12-08 20:13:54 +0100 |
commit | 88bddad42ee27483d153a0b0c0edd13b2b5fdbc0 (patch) | |
tree | fd271110a0be056d687571762287de1357a78c53 | |
parent | a73a1892221e04ddb8ff9ec85ebaa48b5a853de6 (diff) |
EVP: Add EVP_PKEY_get_group_name() to extract the group name of a pkey
This replaces the internal evp_pkey_get_EC_KEY_curve_nid()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13436)
-rw-r--r-- | crypto/err/openssl.txt | 1 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 2 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 97 | ||||
-rw-r--r-- | doc/man3/EVP_PKEY_get_group_name.pod | 46 | ||||
-rw-r--r-- | include/internal/evp.h | 23 | ||||
-rw-r--r-- | include/openssl/evp.h | 2 | ||||
-rw-r--r-- | include/openssl/evperr.h | 1 | ||||
-rw-r--r-- | util/libcrypto.num | 2 | ||||
-rw-r--r-- | util/missingcrypto.txt | 2 |
9 files changed, 107 insertions, 69 deletions
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index a19ca7ceb9..491f3a7cdb 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2624,6 +2624,7 @@ EVP_R_UNSUPPORTED_KEYLENGTH:123:unsupported keylength EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION:124:\ unsupported key derivation function EVP_R_UNSUPPORTED_KEY_SIZE:108:unsupported key size +EVP_R_UNSUPPORTED_KEY_TYPE:224:unsupported key type EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS:135:unsupported number of rounds EVP_R_UNSUPPORTED_PRF:125:unsupported prf EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM:118:unsupported private key algorithm diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 3a4253b353..c2259f0beb 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -176,6 +176,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "unsupported key derivation function"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_TYPE), + "unsupported key type"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS), "unsupported number of rounds"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PRF), "unsupported prf"}, diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index af14706939..6211019b62 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -32,10 +32,10 @@ #include <openssl/encoder.h> #include <openssl/core_names.h> +#include "internal/ffc.h" #include "crypto/asn1.h" #include "crypto/evp.h" #include "crypto/ecx.h" -#include "internal/evp.h" #include "internal/provider.h" #include "evp_local.h" @@ -1056,48 +1056,6 @@ int EVP_PKEY_can_sign(const EVP_PKEY *pkey) return 0; } -#ifndef OPENSSL_NO_EC -/* - * TODO rewrite when we have proper data extraction functions - * Note: an octet pointer would be desirable! - */ -static OSSL_CALLBACK get_ec_curve_name_cb; -static int get_ec_curve_name_cb(const OSSL_PARAM params[], void *arg) -{ - const OSSL_PARAM *p = NULL; - - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME)) != NULL) - return OSSL_PARAM_get_utf8_string(p, arg, 0); - - /* If there is no curve name, this is not an EC key */ - return 0; -} - -int evp_pkey_get_EC_KEY_curve_nid(const EVP_PKEY *pkey) -{ - int ret = NID_undef; - - if (pkey->keymgmt == NULL) { - if (EVP_PKEY_base_id(pkey) == EVP_PKEY_EC) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - - ret = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - } - } else if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "SM2")) { - char *curve_name = NULL; - - ret = evp_keymgmt_util_export(pkey, - OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, - get_ec_curve_name_cb, &curve_name); - if (ret) - ret = ec_curve_name2nid(curve_name); - OPENSSL_free(curve_name); - } - - return ret; -} -#endif - static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent) { BIO_set_indent(*out, saved_indent); @@ -1259,6 +1217,59 @@ int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey, } } +int EVP_PKEY_get_group_name(const EVP_PKEY *pkey, char *gname, size_t gname_sz, + size_t *gname_len) +{ + if (evp_pkey_is_legacy(pkey)) { + const char *name = NULL; + + switch (EVP_PKEY_base_id(pkey)) { +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + { + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + + if (nid != NID_undef) + name = ec_curve_nid2name(nid); + } + break; +#endif +#ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: + { + DH *dh = EVP_PKEY_get0_DH(pkey); + int uid = DH_get_nid(dh); + + if (uid != NID_undef) + name = ossl_ffc_named_group_from_uid(uid); + } + break; +#endif + default: + break; + } + + if (gname_len != NULL) + *gname_len = (name == NULL ? 0 : strlen(name)); + if (name != NULL) { + if (gname != NULL) + OPENSSL_strlcpy(gname, name, gname_sz); + return 1; + } + } else if (evp_pkey_is_provided(pkey)) { + if (EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, + gname, gname_sz, gname_len)) + return 1; + } else { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY); + return 0; + } + + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + return 0; +} + int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid) { int rv, default_nid; diff --git a/doc/man3/EVP_PKEY_get_group_name.pod b/doc/man3/EVP_PKEY_get_group_name.pod new file mode 100644 index 0000000000..964d6b8007 --- /dev/null +++ b/doc/man3/EVP_PKEY_get_group_name.pod @@ -0,0 +1,46 @@ +=pod + +=head1 NAME + +EVP_PKEY_get_group_name - get private key group name + +=head1 SYNOPSIS + + #include <openssl/evp.h> + + int EVP_PKEY_get_group_name(EVP_PKEY *pkey, char *gname, size_t gname_sz, + size_t *gname_len); + +=head1 DESCRIPTION + +EVP_PKEY_get_group_name() fills in the group name of the I<pkey> into +I<gname>, up to at most I<gname_sz> bytes including the ending NUL byte +and assigns I<*gname_len> the actual size of the name, if I<pkey>'s key type +supports it. +I<gname> as well as I<gname_len> may individually be NULL, and won't be +filled in or assigned in that case. + +=head1 NOTES + +Among the standard OpenSSL key types, this is only supported for DH, EC and +SM2 keys. Other providers may support this for additional key types. + +=head1 RETURN VALUES + +EVP_PKEY_get_group_name() returns 1 if the group name could be filled in, +otherwise 0. + +=head1 HISTORY + +This function was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 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 +in the file LICENSE in the source distribution or at +L<https://www.openssl.org/source/license.html>. + +=cut diff --git a/include/internal/evp.h b/include/internal/evp.h deleted file mode 100644 index 404e48322c..0000000000 --- a/include/internal/evp.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_INTERNAL_EVP_H -# define OSSL_INTERNAL_EVP_H - -# include <openssl/evp.h> - -# ifndef OPENSSL_NO_EC -/* - * TODO(3.0) While waiting for more generic getters, we have these functions - * as an interim solution. This should be removed when the generic getters - * appear. - */ -int evp_pkey_get_EC_KEY_curve_nid(const EVP_PKEY *pkey); -# endif -#endif diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 28b6f4f399..4978d6e204 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1984,6 +1984,8 @@ void EVP_add_alg_module(void); int EVP_PKEY_CTX_set_group_name(EVP_PKEY_CTX *ctx, const char *name); int EVP_PKEY_CTX_get_group_name(EVP_PKEY_CTX *ctx, char *name, size_t namelen); +int EVP_PKEY_get_group_name(const EVP_PKEY *pkey, char *name, size_t name_sz, + size_t *gname_len); OSSL_LIB_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx); const char *EVP_PKEY_CTX_get0_propq(EVP_PKEY_CTX *ctx); diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index f98cca3104..2fdd99336f 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -258,6 +258,7 @@ # define EVP_R_UNSUPPORTED_KEYLENGTH 123 # define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 # define EVP_R_UNSUPPORTED_KEY_SIZE 108 +# define EVP_R_UNSUPPORTED_KEY_TYPE 224 # define EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS 135 # define EVP_R_UNSUPPORTED_PRF 125 # define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 diff --git a/util/libcrypto.num b/util/libcrypto.num index e25e52442d..50f0885f0b 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4996,7 +4996,6 @@ EVP_PKEY_get_utf8_string_param ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_get_octet_string_param ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_is_a ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_can_sign ? 3_0_0 EXIST::FUNCTION: -evp_pkey_get_EC_KEY_curve_nid ? 3_0_0 EXIST::FUNCTION:EC X509_STORE_CTX_new_ex ? 3_0_0 EXIST::FUNCTION: CT_POLICY_EVAL_CTX_new_ex ? 3_0_0 EXIST::FUNCTION:CT CTLOG_new_ex ? 3_0_0 EXIST::FUNCTION:CT @@ -5284,3 +5283,4 @@ PEM_write_PrivateKey_ex ? 3_0_0 EXIST::FUNCTION:STDIO PEM_write_bio_PrivateKey_ex ? 3_0_0 EXIST::FUNCTION: PEM_write_PUBKEY_ex ? 3_0_0 EXIST::FUNCTION:STDIO PEM_write_bio_PUBKEY_ex ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_get_group_name ? 3_0_0 EXIST::FUNCTION: diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt index 211a2c5737..915669ba26 100644 --- a/util/missingcrypto.txt +++ b/util/missingcrypto.txt @@ -1540,8 +1540,6 @@ conf_ssl_name_find(3) d2i_X509_bio(3) d2i_X509_fp(3) err_free_strings_int(3) -# The following is internal but exported by libcrypto -evp_pkey_get_EC_KEY_curve_nid(3) i2a_ACCESS_DESCRIPTION(3) i2a_ASN1_ENUMERATED(3) i2a_ASN1_INTEGER(3) |