summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-12-04 06:32:24 +0100
committerRichard Levitte <levitte@openssl.org>2020-12-08 20:13:54 +0100
commit88bddad42ee27483d153a0b0c0edd13b2b5fdbc0 (patch)
treefd271110a0be056d687571762287de1357a78c53
parenta73a1892221e04ddb8ff9ec85ebaa48b5a853de6 (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.txt1
-rw-r--r--crypto/evp/evp_err.c2
-rw-r--r--crypto/evp/p_lib.c97
-rw-r--r--doc/man3/EVP_PKEY_get_group_name.pod46
-rw-r--r--include/internal/evp.h23
-rw-r--r--include/openssl/evp.h2
-rw-r--r--include/openssl/evperr.h1
-rw-r--r--util/libcrypto.num2
-rw-r--r--util/missingcrypto.txt2
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)