Add EVP_PKEY_set_alias_type
authorJack Lloyd <jack.lloyd@ribose.com>
Mon, 18 Jun 2018 19:49:15 +0000 (15:49 -0400)
committerMatt Caswell <matt@openssl.org>
Tue, 19 Jun 2018 10:29:44 +0000 (11:29 +0100)
Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6443)

crypto/err/openssl.txt
crypto/evp/evp_err.c
crypto/evp/p_lib.c
crypto/evp/pmeth_lib.c
doc/man3/EVP_PKEY_set1_RSA.pod
include/openssl/evp.h
include/openssl/evperr.h
util/libcrypto.num

index 4b8e8c4..363cca7 100644 (file)
@@ -774,6 +774,7 @@ EVP_F_EVP_PKEY_PARAMGEN_INIT:149:EVP_PKEY_paramgen_init
 EVP_F_EVP_PKEY_PARAM_CHECK:189:EVP_PKEY_param_check
 EVP_F_EVP_PKEY_PUBLIC_CHECK:190:EVP_PKEY_public_check
 EVP_F_EVP_PKEY_SET1_ENGINE:187:EVP_PKEY_set1_engine
+EVP_F_EVP_PKEY_SET_ALIAS_TYPE:206:EVP_PKEY_set_alias_type
 EVP_F_EVP_PKEY_SIGN:140:EVP_PKEY_sign
 EVP_F_EVP_PKEY_SIGN_INIT:141:EVP_PKEY_sign_init
 EVP_F_EVP_PKEY_VERIFY:142:EVP_PKEY_verify
index 4403fa5..3e14a7b 100644 (file)
@@ -122,6 +122,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
      "EVP_PKEY_public_check"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET1_ENGINE, 0),
      "EVP_PKEY_set1_engine"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET_ALIAS_TYPE, 0),
+     "EVP_PKEY_set_alias_type"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN, 0), "EVP_PKEY_sign"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN_INIT, 0), "EVP_PKEY_sign_init"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, 0), "EVP_PKEY_verify"},
index d78f1d2..9429be9 100644 (file)
@@ -356,6 +356,26 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
 {
     return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
 }
+
+int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
+{
+    if (pkey->type == type) {
+        return 1; /* it already is that type */
+    }
+
+    /*
+     * The application is requesting to alias this to a different pkey type,
+     * but not one that resolves to the base type.
+     */
+    if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) {
+        EVPerr(EVP_F_EVP_PKEY_SET_ALIAS_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
+        return 0;
+    }
+
+    pkey->type = type;
+    return 1;
+}
+
 #ifndef OPENSSL_NO_ENGINE
 int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
 {
index cf4dd43..c7dc453 100644 (file)
@@ -101,10 +101,9 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
 {
     EVP_PKEY_CTX *ret;
     const EVP_PKEY_METHOD *pmeth;
+
     if (id == -1) {
-        if (!pkey || !pkey->ameth)
-            return NULL;
-        id = pkey->ameth->pkey_id;
+        id = pkey->type;
     }
 #ifndef OPENSSL_NO_ENGINE
     if (e == NULL && pkey != NULL)
index 884cf91..2a1ec92 100644 (file)
@@ -7,7 +7,7 @@ EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY,
 EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA, EVP_PKEY_get0_DH, EVP_PKEY_get0_EC_KEY,
 EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH,
 EVP_PKEY_assign_EC_KEY, EVP_PKEY_get0_hmac, EVP_PKEY_type, EVP_PKEY_id,
-EVP_PKEY_base_id, EVP_PKEY_set1_engine - EVP_PKEY assignment functions
+EVP_PKEY_base_id, EVP_PKEY_set_alias_type, EVP_PKEY_set1_engine - EVP_PKEY assignment functions
 
 =head1 SYNOPSIS
 
@@ -37,6 +37,7 @@ EVP_PKEY_base_id, EVP_PKEY_set1_engine - EVP_PKEY assignment functions
  int EVP_PKEY_id(const EVP_PKEY *pkey);
  int EVP_PKEY_base_id(const EVP_PKEY *pkey);
  int EVP_PKEY_type(int type);
+ int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type);
 
  int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *engine);
 
@@ -78,6 +79,10 @@ must be called after the key algorithm and components are set up.
 If B<engine> does not include an B<EVP_PKEY_METHOD> for B<pkey> an
 error occurs.
 
+EVP_PKEY_set_alias_type() allows modifying a EVP_PKEY to use a
+different set of algorithms than the default. This is currently used
+to support SM2 keys, which use an identical encoding to ECDSA.
+
 =head1 NOTES
 
 In accordance with the OpenSSL naming convention the key obtained
@@ -98,6 +103,13 @@ is no longer possible: the equivalent is EVP_PKEY_base_id(pkey).
 EVP_PKEY_set1_engine() is typically used by an ENGINE returning an HSM
 key as part of its routine to load a private key.
 
+=head1 EXAMPLES
+
+After loading an ECC key, it is possible to convert it to using SM2
+algorithms with EVP_PKEY_set_alias_type:
+
+ EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
+
 =head1 RETURN VALUES
 
 EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
@@ -115,6 +127,8 @@ type or B<NID_undef> (equivalently B<EVP_PKEY_NONE>) on error.
 
 EVP_PKEY_set1_engine() returns 1 for success and 0 for failure.
 
+EVP_PKEY_set_alias_type() returns 1 for success and 0 for error.
+
 =head1 SEE ALSO
 
 L<EVP_PKEY_new(3)>
index 33ff674..185cc29 100644 (file)
@@ -995,6 +995,7 @@ int EVP_PKEY_security_bits(const EVP_PKEY *pkey);
 int EVP_PKEY_size(EVP_PKEY *pkey);
 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
 int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
+int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type);
 # ifndef OPENSSL_NO_ENGINE
 int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e);
 # endif
index 8ab1765..3484fa8 100644 (file)
@@ -96,6 +96,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_F_EVP_PKEY_PARAM_CHECK                       189
 # define EVP_F_EVP_PKEY_PUBLIC_CHECK                      190
 # define EVP_F_EVP_PKEY_SET1_ENGINE                       187
+# define EVP_F_EVP_PKEY_SET_ALIAS_TYPE                    206
 # define EVP_F_EVP_PKEY_SIGN                              140
 # define EVP_F_EVP_PKEY_SIGN_INIT                         141
 # define EVP_F_EVP_PKEY_VERIFY                            142
index a25f65f..f5122e2 100644 (file)
@@ -4567,3 +4567,4 @@ EVP_PKEY_get_raw_public_key             4518      1_1_1   EXIST::FUNCTION:
 EVP_PKEY_get_raw_private_key            4519   1_1_1   EXIST::FUNCTION:
 EVP_PKEY_asn1_set_get_priv_key          4520   1_1_1   EXIST::FUNCTION:
 EVP_PKEY_asn1_set_get_pub_key           4521   1_1_1   EXIST::FUNCTION:
+EVP_PKEY_set_alias_type                 4522   1_1_1   EXIST::FUNCTION: