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)
This commit is contained in:
Richard Levitte 2020-12-04 06:32:24 +01:00
parent a73a189222
commit 88bddad42e
9 changed files with 107 additions and 69 deletions

View File

@ -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

View File

@ -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"},

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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:

View File

@ -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)