EVP: Adapt diverse OSSL_PARAM setters and getters
authorRichard Levitte <levitte@openssl.org>
Wed, 20 Jan 2021 22:10:48 +0000 (23:10 +0100)
committerRichard Levitte <levitte@openssl.org>
Tue, 23 Feb 2021 12:41:48 +0000 (13:41 +0100)
EVP_PKEY_get_group_name() now simply calls EVP_PKEY_get_utf8_string_param().
EVP_PKEY_CTX_set_group_name() now simply calls EVP_PKEY_CTX_set_params().

EVP_PKEY_get_bn_param(), EVP_PKEY_get_octet_string_param(),
EVP_PKEY_get_utf8_string_param() and EVP_PKEY_get_int_param() can now
handle legacy EVP_PKEYs by calling evp_pkey_get_params_to_ctrl().

EVP_PKEY_CTX_get_params() can now handle a legacy backed EVP_PKEY_CTX
by calling evp_pkey_ctx_get_params_to_ctrl().

Note: EVP_PKEY_CTX_set_params() doesn't call the translator yet.
      Should it ever?

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13913)

crypto/evp/evp_lib.c
crypto/evp/p_lib.c
crypto/evp/pmeth_lib.c

index 427ffc813a3d7baede6fb32f1d7ac80feb9fdab7..f6598a8b3f017e6484a2028d553d8a920458597f 100644 (file)
@@ -983,32 +983,8 @@ int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
 int EVP_PKEY_CTX_set_group_name(EVP_PKEY_CTX *ctx, const char *name)
 {
     OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
-    OSSL_PARAM *p = params;
-
-    if (ctx == NULL) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
 
-    if (!EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
-#ifndef FIPS_MODULE
-        int nid;
-
-        /* Could be a legacy key, try and convert to a ctrl */
-        if (ctx->pmeth != NULL && (nid = OBJ_txt2nid(name)) != NID_undef) {
-            if (ctx->pmeth->pkey_id == EVP_PKEY_DH)
-                return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH,
-                                         EVP_PKEY_OP_PARAMGEN
-                                         | EVP_PKEY_OP_KEYGEN,
-                                         EVP_PKEY_CTRL_DH_NID, nid, NULL);
-            if (ctx->pmeth->pkey_id == EVP_PKEY_EC)
-                return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
-                                         EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN,
-                                         EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID,
-                                         nid, NULL);
-        }
-#endif
+    if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
         return -2;
@@ -1017,8 +993,8 @@ int EVP_PKEY_CTX_set_group_name(EVP_PKEY_CTX *ctx, const char *name)
     if (name == NULL)
         return -1;
 
-    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
-                                            (char *)name, 0);
+    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
+                                                 (char *)name, 0);
     return EVP_PKEY_CTX_set_params(ctx, params);
 }
 
index e655adde05f6128f2bbbe8e9fdf798c6bda4120f..653a3b7743ac65972ca9477d96befb21dfa3ebfb 100644 (file)
@@ -1228,60 +1228,8 @@ 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:
-            {
-                const EC_GROUP *grp = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey));
-                int nid = NID_undef;
-
-                if (grp != NULL)
-                    nid = EC_GROUP_get_curve_name(grp);
-                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) {
-                    const DH_NAMED_GROUP *dh_group =
-                        ossl_ffc_uid_to_dh_named_group(uid);
-
-                    name = ossl_ffc_named_group_get_name(dh_group);
-                }
-            }
-            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;
+    return EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
+                                          gname, gname_sz, gname_len);
 }
 
 int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
@@ -2144,7 +2092,7 @@ int EVP_PKEY_set_bn_param(EVP_PKEY *pkey, const char *key_name,
     if (key_name == NULL
         || bn == NULL
         || pkey == NULL
-        || !evp_pkey_is_provided(pkey))
+        || !evp_pkey_is_assigned(pkey))
         return 0;
 
     bsize = BN_num_bytes(bn);
@@ -2194,12 +2142,28 @@ const OSSL_PARAM *EVP_PKEY_settable_params(const EVP_PKEY *pkey)
 
 int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[])
 {
-    if (pkey == NULL)
-        return 0;
-
-    pkey->dirty_cnt++;
-    return evp_pkey_is_provided(pkey)
-        && evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params);
+    if (pkey != NULL) {
+        if (evp_pkey_is_provided(pkey)) {
+            pkey->dirty_cnt++;
+            return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params);
+        }
+#ifndef FIPS_MODULE
+        /*
+         * TODO?
+         * We will hopefully never find the need to set individual data in
+         * EVP_PKEYs with a legacy internal key, but we can't be entirely
+         * sure.  This bit of code can be enabled if we find the need.  If
+         * not, it can safely be removed when #legacy support is removed.
+         */
+# if 0
+        else if (evp_pkey_is_legacy(pkey)) {
+            return evp_pkey_set_params_to_ctrl(pkey, params);
+        }
+# endif
+#endif
+    }
+    ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY);
+    return 0;
 }
 
 const OSSL_PARAM *EVP_PKEY_gettable_params(const EVP_PKEY *pkey)
@@ -2211,9 +2175,16 @@ const OSSL_PARAM *EVP_PKEY_gettable_params(const EVP_PKEY *pkey)
 
 int EVP_PKEY_get_params(const EVP_PKEY *pkey, OSSL_PARAM params[])
 {
-    return pkey != NULL
-        && evp_pkey_is_provided(pkey)
-        && evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params);
+    if (pkey != NULL) {
+        if (evp_pkey_is_provided(pkey))
+            return evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params);
+#ifndef FIPS_MODULE
+        else if (evp_pkey_is_legacy(pkey))
+            return evp_pkey_get_params_to_ctrl(pkey, params);
+#endif
+    }
+    ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY);
+    return 0;
 }
 
 #ifndef FIPS_MODULE
index abea7b02df59fe32f125b863ce913b6930384f54..c83ebaecc77482d688d2806b72a00002df3b196c 100644 (file)
@@ -655,65 +655,83 @@ int EVP_PKEY_CTX_is_a(EVP_PKEY_CTX *ctx, const char *keytype)
 
 int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
 {
-    if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
-            && ctx->op.kex.exchprovctx != NULL
+    switch (evp_pkey_ctx_state(ctx)) {
+    case EVP_PKEY_STATE_PROVIDER:
+        if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
             && ctx->op.kex.exchange != NULL
             && ctx->op.kex.exchange->set_ctx_params != NULL)
-        return ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx,
-                                                    params);
-    if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
-            && ctx->op.sig.sigprovctx != NULL
+            return
+                ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx,
+                                                     params);
+        if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
             && ctx->op.sig.signature != NULL
             && ctx->op.sig.signature->set_ctx_params != NULL)
-        return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx,
-                                                     params);
-    if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
-            && ctx->op.ciph.ciphprovctx != NULL
+            return
+                ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx,
+                                                      params);
+        if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
             && ctx->op.ciph.cipher != NULL
             && ctx->op.ciph.cipher->set_ctx_params != NULL)
-        return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx,
-                                                     params);
-    if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
-        && ctx->op.keymgmt.genctx != NULL
-        && ctx->keymgmt != NULL
-        && ctx->keymgmt->gen_set_params != NULL)
-        return evp_keymgmt_gen_set_params(ctx->keymgmt, ctx->op.keymgmt.genctx,
-                                          params);
-    if (EVP_PKEY_CTX_IS_KEM_OP(ctx)
-        && ctx->op.encap.kemprovctx != NULL
-        && ctx->op.encap.kem != NULL
-        && ctx->op.encap.kem->set_ctx_params != NULL)
-        return ctx->op.encap.kem->set_ctx_params(ctx->op.encap.kemprovctx,
-                                                 params);
+            return
+                ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx,
+                                                    params);
+        if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
+            && ctx->keymgmt != NULL
+            && ctx->keymgmt->gen_set_params != NULL)
+            return
+                evp_keymgmt_gen_set_params(ctx->keymgmt, ctx->op.keymgmt.genctx,
+                                           params);
+        if (EVP_PKEY_CTX_IS_KEM_OP(ctx)
+            && ctx->op.encap.kem != NULL
+            && ctx->op.encap.kem->set_ctx_params != NULL)
+            return
+                ctx->op.encap.kem->set_ctx_params(ctx->op.encap.kemprovctx,
+                                                  params);
+        break;
+#ifndef FIPS_MODULE
+    case EVP_PKEY_STATE_UNKNOWN:
+    case EVP_PKEY_STATE_LEGACY:
+        return evp_pkey_ctx_set_params_to_ctrl(ctx, params);
+#endif
+    }
     return 0;
 }
 
 int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
 {
-    if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
-            && ctx->op.kex.exchprovctx != NULL
+    switch (evp_pkey_ctx_state(ctx)) {
+    case EVP_PKEY_STATE_PROVIDER:
+        if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
             && ctx->op.kex.exchange != NULL
             && ctx->op.kex.exchange->get_ctx_params != NULL)
-        return ctx->op.kex.exchange->get_ctx_params(ctx->op.kex.exchprovctx,
-                                                    params);
-    if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
-            && ctx->op.sig.sigprovctx != NULL
+            return
+                ctx->op.kex.exchange->get_ctx_params(ctx->op.kex.exchprovctx,
+                                                     params);
+        if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
             && ctx->op.sig.signature != NULL
             && ctx->op.sig.signature->get_ctx_params != NULL)
-        return ctx->op.sig.signature->get_ctx_params(ctx->op.sig.sigprovctx,
-                                                     params);
-    if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
-            && ctx->op.ciph.ciphprovctx != NULL
+            return
+                ctx->op.sig.signature->get_ctx_params(ctx->op.sig.sigprovctx,
+                                                      params);
+        if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
             && ctx->op.ciph.cipher != NULL
             && ctx->op.ciph.cipher->get_ctx_params != NULL)
-        return ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.ciphprovctx,
-                                                   params);
-    if (EVP_PKEY_CTX_IS_KEM_OP(ctx)
-        && ctx->op.encap.kemprovctx != NULL
-        && ctx->op.encap.kem != NULL
-        && ctx->op.encap.kem->get_ctx_params != NULL)
-        return ctx->op.encap.kem->get_ctx_params(ctx->op.encap.kemprovctx,
-                                                 params);
+            return
+                ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.ciphprovctx,
+                                                    params);
+        if (EVP_PKEY_CTX_IS_KEM_OP(ctx)
+            && ctx->op.encap.kem != NULL
+            && ctx->op.encap.kem->get_ctx_params != NULL)
+            return
+                ctx->op.encap.kem->get_ctx_params(ctx->op.encap.kemprovctx,
+                                                  params);
+        break;
+#ifndef FIPS_MODULE
+    case EVP_PKEY_STATE_UNKNOWN:
+    case EVP_PKEY_STATE_LEGACY:
+        return evp_pkey_ctx_get_params_to_ctrl(ctx, params);
+#endif
+    }
     return 0;
 }