Revise EVP_PKEY param handling
authorMatt Caswell <matt@openssl.org>
Wed, 4 Sep 2019 11:46:02 +0000 (12:46 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 9 Sep 2019 13:00:00 +0000 (14:00 +0100)
We add new functions for getting parameters and discovering the gettable
and settable parameters. We also make EVP_PKEY_CTX_get_signature_md() a
function and implement it in terms of the new functions.

This enables applications to discover the set of parameters that are
supported for a given algorithm implementation.

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9753)

13 files changed:
crypto/evp/evp_locl.h
crypto/evp/exchange.c
crypto/evp/pmeth_fn.c
crypto/evp/pmeth_lib.c
doc/man3/EVP_PKEY_CTX_ctrl.pod
doc/man7/provider-keyexch.pod
doc/man7/provider-signature.pod
include/openssl/core_numbers.h
include/openssl/evp.h
providers/common/exchange/dh_exch.c
providers/common/signature/dsa.c
test/evp_extra_test.c
util/libcrypto.num

index 722eecfe432ab643c1a25db7ffad311adc813b21..b338823f844c75e0cfb1b6123b01b8e437c4c925 100644 (file)
@@ -110,7 +110,8 @@ struct evp_keyexch_st {
     OSSL_OP_keyexch_derive_fn *derive;
     OSSL_OP_keyexch_freectx_fn *freectx;
     OSSL_OP_keyexch_dupctx_fn *dupctx;
     OSSL_OP_keyexch_derive_fn *derive;
     OSSL_OP_keyexch_freectx_fn *freectx;
     OSSL_OP_keyexch_dupctx_fn *dupctx;
-    OSSL_OP_keyexch_set_params_fn *set_params;
+    OSSL_OP_keyexch_set_ctx_params_fn *set_ctx_params;
+    OSSL_OP_keyexch_settable_ctx_params_fn *settable_ctx_params;
 } /* EVP_KEYEXCH */;
 
 struct evp_signature_st {
 } /* EVP_KEYEXCH */;
 
 struct evp_signature_st {
@@ -130,7 +131,10 @@ struct evp_signature_st {
     OSSL_OP_signature_verify_recover_fn *verify_recover;
     OSSL_OP_signature_freectx_fn *freectx;
     OSSL_OP_signature_dupctx_fn *dupctx;
     OSSL_OP_signature_verify_recover_fn *verify_recover;
     OSSL_OP_signature_freectx_fn *freectx;
     OSSL_OP_signature_dupctx_fn *dupctx;
-    OSSL_OP_signature_set_params_fn *set_params;
+    OSSL_OP_signature_get_ctx_params_fn *get_ctx_params;
+    OSSL_OP_signature_gettable_ctx_params_fn *gettable_ctx_params;
+    OSSL_OP_signature_set_ctx_params_fn *set_ctx_params;
+    OSSL_OP_signature_settable_ctx_params_fn *settable_ctx_params;
 } /* EVP_SIGNATURE */;
 
 int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
 } /* EVP_SIGNATURE */;
 
 int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
index e9b7259cd1c455de7aca7e79cf02fb7f46241010..1f14a368a2dbc4f08565c47086c6017d667a2f5b 100644 (file)
@@ -50,7 +50,7 @@ static void *evp_keyexch_from_dispatch(const char *name,
     EVP_KEYMGMT *keymgmt = EVP_KEYMGMT_fetch(keymgmt_data->ctx, name,
                                              keymgmt_data->properties);
     EVP_KEYEXCH *exchange = NULL;
     EVP_KEYMGMT *keymgmt = EVP_KEYMGMT_fetch(keymgmt_data->ctx, name,
                                              keymgmt_data->properties);
     EVP_KEYEXCH *exchange = NULL;
-    int fncnt = 0;
+    int fncnt = 0, paramfncnt = 0;
 
     if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) {
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE);
 
     if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) {
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE);
@@ -102,19 +102,28 @@ static void *evp_keyexch_from_dispatch(const char *name,
                 break;
             exchange->dupctx = OSSL_get_OP_keyexch_dupctx(fns);
             break;
                 break;
             exchange->dupctx = OSSL_get_OP_keyexch_dupctx(fns);
             break;
-        case OSSL_FUNC_KEYEXCH_SET_PARAMS:
-            if (exchange->set_params != NULL)
+        case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS:
+            if (exchange->set_ctx_params != NULL)
                 break;
                 break;
-            exchange->set_params = OSSL_get_OP_keyexch_set_params(fns);
+            exchange->set_ctx_params = OSSL_get_OP_keyexch_set_ctx_params(fns);
+            paramfncnt++;
+            break;
+        case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS:
+            if (exchange->settable_ctx_params != NULL)
+                break;
+            exchange->settable_ctx_params
+                = OSSL_get_OP_keyexch_settable_ctx_params(fns);
+            paramfncnt++;
             break;
         }
     }
             break;
         }
     }
-    if (fncnt != 4) {
+    if (fncnt != 4 || (paramfncnt != 0 && paramfncnt != 2)) {
         /*
          * In order to be a consistent set of functions we must have at least
          * a complete set of "exchange" functions: init, derive, newctx,
         /*
          * In order to be a consistent set of functions we must have at least
          * a complete set of "exchange" functions: init, derive, newctx,
-         * and freectx. The dupctx, set_peer and set_params functions are
-         * optional.
+         * and freectx. The set_ctx_params and settable_ctx_params functions are
+         * optional, but if one of them is present then the other one must also
+         * be present. The dupctx and set_peer functions are optional.
          */
         EVPerr(EVP_F_EVP_KEYEXCH_FROM_DISPATCH,
                EVP_R_INVALID_PROVIDER_FUNCTIONS);
          */
         EVPerr(EVP_F_EVP_KEYEXCH_FROM_DISPATCH,
                EVP_R_INVALID_PROVIDER_FUNCTIONS);
index 8fdb31c2180fbbc95f147ad9632b7ecf49bd107e..dfdc85f1d59f8b2ab5d9156e21ed019467b54c40 100644 (file)
@@ -51,6 +51,7 @@ static void *evp_signature_from_dispatch(const char *name,
                                              keymgmt_data->properties);
     EVP_SIGNATURE *signature = NULL;
     int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0;
                                              keymgmt_data->properties);
     EVP_SIGNATURE *signature = NULL;
     int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0;
+    int gparamfncnt = 0, sparamfncnt = 0;
 
     if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) {
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE);
 
     if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) {
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE);
@@ -123,21 +124,49 @@ static void *evp_signature_from_dispatch(const char *name,
                 break;
             signature->dupctx = OSSL_get_OP_signature_dupctx(fns);
             break;
                 break;
             signature->dupctx = OSSL_get_OP_signature_dupctx(fns);
             break;
-        case OSSL_FUNC_SIGNATURE_SET_PARAMS:
-            if (signature->set_params != NULL)
+        case OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS:
+            if (signature->get_ctx_params != NULL)
                 break;
                 break;
-            signature->set_params = OSSL_get_OP_signature_set_params(fns);
+            signature->get_ctx_params
+                = OSSL_get_OP_signature_get_ctx_params(fns);
+            gparamfncnt++;
+            break;
+        case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS:
+            if (signature->gettable_ctx_params != NULL)
+                break;
+            signature->gettable_ctx_params
+                = OSSL_get_OP_signature_gettable_ctx_params(fns);
+            gparamfncnt++;
+            break;
+        case OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS:
+            if (signature->set_ctx_params != NULL)
+                break;
+            signature->set_ctx_params
+                = OSSL_get_OP_signature_set_ctx_params(fns);
+            sparamfncnt++;
+            break;
+        case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS:
+            if (signature->settable_ctx_params != NULL)
+                break;
+            signature->settable_ctx_params
+                = OSSL_get_OP_signature_settable_ctx_params(fns);
+            sparamfncnt++;
             break;
         }
     }
     if (ctxfncnt != 2
             break;
         }
     }
     if (ctxfncnt != 2
-        || (signfncnt != 2 && verifyfncnt != 2 && verifyrecfncnt != 2)) {
+        || (signfncnt != 2 && verifyfncnt != 2 && verifyrecfncnt != 2)
+        || (gparamfncnt != 0 && gparamfncnt != 2)
+        || (sparamfncnt != 0 && sparamfncnt != 2)) {
         /*
          * In order to be a consistent set of functions we must have at least
          * a set of context functions (newctx and freectx) as well as a pair of
          * "signature" functions: (sign_init, sign) or (verify_init verify) or
         /*
          * In order to be a consistent set of functions we must have at least
          * a set of context functions (newctx and freectx) as well as a pair of
          * "signature" functions: (sign_init, sign) or (verify_init verify) or
-         * (verify_recover_init, verify_recover). The dupctx and set_params
-         * functions are optional.
+         * (verify_recover_init, verify_recover). set_ctx_params and
+         * settable_ctx_params are optional, but if one of them is present then
+         * the other one must also be present. The same applies to
+         * get_ctx_params and gettable_ctx_params. The dupctx function is
+         * optional.
          */
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
         goto err;
          */
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
         goto err;
index 534f857df1b7dce586784cea31a8d308761e41b5..4c98212c6a29813300eaad15dbd1935b91dfa43f 100644 (file)
@@ -404,15 +404,49 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
     OPENSSL_free(ctx);
 }
 
     OPENSSL_free(ctx);
 }
 
+int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
+{
+    if (ctx->sigprovctx != NULL
+            && ctx->signature != NULL
+            && ctx->signature->get_ctx_params != NULL)
+        return ctx->signature->get_ctx_params(ctx->sigprovctx, params);
+    return 0;
+}
+
+const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx)
+{
+    if (ctx->signature != NULL
+            && ctx->signature->gettable_ctx_params != NULL)
+        return ctx->signature->gettable_ctx_params();
+
+    return NULL;
+}
+
 int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
 {
 int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
 {
-    if (ctx->exchprovctx != NULL && ctx->exchange != NULL)
-        return ctx->exchange->set_params(ctx->exchprovctx, params);
-    if (ctx->sigprovctx != NULL && ctx->signature != NULL)
-        return ctx->signature->set_params(ctx->sigprovctx, params);
+    if (ctx->exchprovctx != NULL
+            && ctx->exchange != NULL
+            && ctx->exchange->set_ctx_params != NULL)
+        return ctx->exchange->set_ctx_params(ctx->exchprovctx, params);
+    if (ctx->sigprovctx != NULL
+            && ctx->signature != NULL
+            && ctx->signature->set_ctx_params != NULL)
+        return ctx->signature->set_ctx_params(ctx->sigprovctx, params);
     return 0;
 }
 
     return 0;
 }
 
+const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
+{
+    if (ctx->exchange != NULL
+            && ctx->exchange->settable_ctx_params != NULL)
+        return ctx->exchange->settable_ctx_params();
+    if (ctx->signature != NULL
+            && ctx->signature->settable_ctx_params != NULL)
+        return ctx->signature->settable_ctx_params();
+
+    return NULL;
+}
+
 #ifndef OPENSSL_NO_DH
 int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
 {
 #ifndef OPENSSL_NO_DH
 int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
 {
@@ -431,36 +465,78 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
 }
 #endif
 
 }
 #endif
 
+int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
+{
+    OSSL_PARAM sig_md_params[3], *p = sig_md_params;
+    /* 80 should be big enough */
+    char name[80] = "";
+    const EVP_MD *tmp;
+
+    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;
+    }
+
+    /* TODO(3.0): Remove this eventually when no more legacy */
+    if (ctx->sigprovctx == NULL)
+        return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
+                                 EVP_PKEY_CTRL_GET_MD, 0, (void *)(md));
+
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
+                                            name,
+                                            sizeof(name));
+    *p++ = OSSL_PARAM_construct_end();
+
+    if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params))
+        return 0;
+
+    tmp = EVP_get_digestbyname(name);
+    if (tmp == NULL)
+        return 0;
+
+    *md = tmp;
+
+    return 1;
+}
+
 int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
 {
 int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
 {
-    OSSL_PARAM sig_md_params[3];
+    OSSL_PARAM sig_md_params[3], *p = sig_md_params;
     size_t mdsize;
     const char *name;
 
     size_t mdsize;
     const char *name;
 
+    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;
+    }
+
     /* TODO(3.0): Remove this eventually when no more legacy */
     if (ctx->sigprovctx == NULL)
         return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
                                  EVP_PKEY_CTRL_MD, 0, (void *)(md));
 
     /* TODO(3.0): Remove this eventually when no more legacy */
     if (ctx->sigprovctx == NULL)
         return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
                                  EVP_PKEY_CTRL_MD, 0, (void *)(md));
 
-    if (md == NULL)
-        return 1;
-
-    mdsize = EVP_MD_size(md);
-    name = EVP_MD_name(md);
-    sig_md_params[0] = OSSL_PARAM_construct_utf8_string(
-                           OSSL_SIGNATURE_PARAM_DIGEST,
-                           /*
-                            * Cast away the const. This is read only so should
-                            * be safe
-                            */
-                           (char *)name,
-                           strlen(name) + 1);
-    sig_md_params[1] = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
-                                                   &mdsize);
-    sig_md_params[2] = OSSL_PARAM_construct_end();
+    if (md == NULL) {
+        name = "";
+        mdsize = 0;
+    } else {
+        mdsize = EVP_MD_size(md);
+        name = EVP_MD_name(md);
+    }
 
 
-    return EVP_PKEY_CTX_set_params(ctx, sig_md_params);
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
+                                            /*
+                                             * Cast away the const. This is read
+                                             * only so should be safe
+                                             */
+                                            (char *)name,
+                                            strlen(name) + 1);
+    *p++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
+                                       &mdsize);
+    *p++ = OSSL_PARAM_construct_end();
 
 
+    return EVP_PKEY_CTX_set_params(ctx, sig_md_params);
 }
 
 static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
 }
 
 static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
index 9d1812f6bd65a38e7855a7433d5bd8edd8342ed8..18b984162e5709dbaeacc57595ae092b00315462 100644 (file)
@@ -2,7 +2,10 @@
 
 =head1 NAME
 
 
 =head1 NAME
 
+EVP_PKEY_CTX_get_params,
+EVP_PKEY_CTX_gettable_params,
 EVP_PKEY_CTX_set_params,
 EVP_PKEY_CTX_set_params,
+EVP_PKEY_CTX_settable_params,
 EVP_PKEY_CTX_ctrl,
 EVP_PKEY_CTX_ctrl_str,
 EVP_PKEY_CTX_ctrl_uint64,
 EVP_PKEY_CTX_ctrl,
 EVP_PKEY_CTX_ctrl_str,
 EVP_PKEY_CTX_ctrl_uint64,
@@ -63,7 +66,10 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
 
  #include <openssl/evp.h>
 
 
  #include <openssl/evp.h>
 
+ int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
+ const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx);
  int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
  int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
+ const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx);
 
  int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
                        int cmd, int p1, void *p2);
 
  int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
                        int cmd, int p1, void *p2);
@@ -144,16 +150,20 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
 
 =head1 DESCRIPTION
 
 
 =head1 DESCRIPTION
 
-The EVP_PKEY_CTX_set_params() function sends arbitrary parameters to the
-algorithm implementation.
+The EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params() functions get and
+send arbitrary parameters from and to the algorithm implementation respectively.
 Not all parameters may be supported by all providers.
 See L<OSSL_PROVIDER(3)> for more information on providers.
 See L<OSSL_PARAM(3)> for more information on parameters.
 Not all parameters may be supported by all providers.
 See L<OSSL_PROVIDER(3)> for more information on providers.
 See L<OSSL_PARAM(3)> for more information on parameters.
+These functions must only be called after the EVP_PKEY_CTX has been initialised
+for use in an operation (for example by L<EVP_PKEY_sign_init_ex(3)>,
+L<EVP_PKEY_derive_init_ex(3)> or other similar functions).
+
 The parameters currently supported by the default provider are:
 
 =over 4
 
 The parameters currently supported by the default provider are:
 
 =over 4
 
-=item OSSL_EXCHANGE_PARAM_PAD (uint type)
+=item "exchange-pad" (B<OSSL_EXCHANGE_PARAM_PAD>) <uint>
 
 Sets the DH padding mode.
 If B<OSSL_EXCHANGE_PARAM_PAD> is 1 then the  shared secret is padded with zeroes
 
 Sets the DH padding mode.
 If B<OSSL_EXCHANGE_PARAM_PAD> is 1 then the  shared secret is padded with zeroes
@@ -161,19 +171,29 @@ up to the size of the DH prime B<p>.
 If B<OSSL_EXCHANGE_PARAM_PAD> is zero (the default) then no padding is
 performed.
 
 If B<OSSL_EXCHANGE_PARAM_PAD> is zero (the default) then no padding is
 performed.
 
-=item OSSL_SIGNATURE_PARAM_DIGEST (UTF8 string type)
+=item "digest" (B<OSSL_SIGNATURE_PARAM_DIGEST>) <utf8 string>
 
 
-Sets the name of the digest algorithm used for the input to the signature
-functions.
+Gets and sets the name of the digest algorithm used for the input to the
+signature functions.
 
 
-=item OSSL_SIGNATURE_PARAM_DIGEST_SIZE (size_t type)
+=item "digest-size" (B<OSSL_SIGNATURE_PARAM_DIGEST_SIZE>) <size_t>
 
 
-Sets the output size of the digest algorithm used for the input to the signature
-functions.
+Gets and sets the output size of the digest algorithm used for the input to the
+signature functions.
 The internal algorithm that supports this parameter is DSA.
 
 =back
 
 The internal algorithm that supports this parameter is DSA.
 
 =back
 
+EVP_PKEY_CTX_gettable_params() and EVP_PKEY_CTX_settable_params() gets a
+constant B<OSSL_PARAM> array that decribes the  gettable and
+settable parameters for the current algorithm implementation, i.e. parameters
+that can be used with EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params()
+respectively.
+See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
+These functions must only be called after the EVP_PKEY_CTX has been initialised
+for use in an operation (for example by L<EVP_PKEY_sign_init_ex(3)>,
+L<EVP_PKEY_derive_init_ex(3)> or other similar functions).
+
 The function EVP_PKEY_CTX_ctrl() sends a control operation to the context
 B<ctx>. The key type used must match B<keytype> if it is not -1. The parameter
 B<optype> is a mask indicating which operations the control can be applied to.
 The function EVP_PKEY_CTX_ctrl() sends a control operation to the context
 B<ctx>. The key type used must match B<keytype> if it is not -1. The parameter
 B<optype> is a mask indicating which operations the control can be applied to.
@@ -199,13 +219,13 @@ B<pkeyutl>, B<genpkey> and B<req> commands.
 The function EVP_PKEY_CTX_md() sends a message digest control operation
 to the context B<ctx>. The message digest is specified by its name B<md>.
 
 The function EVP_PKEY_CTX_md() sends a message digest control operation
 to the context B<ctx>. The message digest is specified by its name B<md>.
 
-All the remaining "functions" are implemented as macros.
+The EVP_PKEY_CTX_set_signature_md() function sets the message digest type used
+in a signature. It can be used in the RSA, DSA and ECDSA algorithms.
 
 
-The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used
+The EVP_PKEY_CTX_get_signature_md() function gets the message digest type used
 in a signature. It can be used in the RSA, DSA and ECDSA algorithms.
 
 in a signature. It can be used in the RSA, DSA and ECDSA algorithms.
 
-The EVP_PKEY_CTX_get_signature_md() macro gets the message digest type used in a
-signature. It can be used in the RSA, DSA and ECDSA algorithms.
+All the remaining "functions" are implemented as macros.
 
 Key generation typically involves setting up parameters to be used and
 generating the private and public key data. Some algorithm implementations
 
 Key generation typically involves setting up parameters to be used and
 generating the private and public key data. Some algorithm implementations
@@ -471,9 +491,15 @@ allocate adequate memory space for the B<id> before calling EVP_PKEY_CTX_get1_id
 
 =head1 RETURN VALUES
 
 
 =head1 RETURN VALUES
 
-EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0
-or a negative value for failure. In particular a return value of -2
-indicates the operation is not supported by the public key algorithm.
+EVP_PKEY_CTX_set_params() returns 1 for success or 0 otherwise.
+EVP_PKEY_CTX_settable_params() returns an OSSL_PARAM array on success or NULL on
+error.
+It may also return NULL if there are no settable parameters available.
+
+EVP_PKEY_CTX_set_signature_md(), EVP_PKEY_CTX_set_dh_pad(), EVP_PKEY_CTX_ctrl()
+and its macros return a positive value for success and 0 or a negative value for
+failure. In particular a return value of -2 indicates the operation is not
+supported by the public key algorithm.
 
 =head1 SEE ALSO
 
 
 =head1 SEE ALSO
 
@@ -492,8 +518,9 @@ The
 EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and EVP_PKEY_CTX_get1_id_len()
 macros were added in 1.1.1, other functions were added in OpenSSL 1.0.0.
 
 EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and EVP_PKEY_CTX_get1_id_len()
 macros were added in 1.1.1, other functions were added in OpenSSL 1.0.0.
 
-EVP_PKEY_CTX_set_dh_pad() was a macro in OpenSSL 1.1.1 and below.
-From OpenSSL 3.0 it is a function.
+EVP_PKEY_CTX_get_signature_md(), EVP_PKEY_CTX_set_signature_md() and
+EVP_PKEY_CTX_set_dh_pad() were macros in OpenSSL 1.1.1 and below. From OpenSSL
+3.0 they are functions.
 
 =head1 COPYRIGHT
 
 
 =head1 COPYRIGHT
 
index 71830c12c62f71c201a1ca9af2483dd56dc11443..9ef294395c86bdffca1c9a4303ffaea547863ceb 100644 (file)
@@ -29,8 +29,8 @@ provider-keyexch - The keyexch library E<lt>-E<gt> provider functions
                        size_t outlen);
 
  /* Key Exchange parameters */
                        size_t outlen);
 
  /* Key Exchange parameters */
- int OP_keyexch_set_params(void *ctx, const OSSL_PARAM params[]);
-
+ int OP_keyexch_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_keyexch_settable_ctx_params(void);
 
 =head1 DESCRIPTION
 
 
 =head1 DESCRIPTION
 
@@ -61,15 +61,16 @@ For example, the "function" OP_keyexch_newctx() has these:
 B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as
 macros in L<openssl-core_numbers.h(7)>, as follows:
 
 B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as
 macros in L<openssl-core_numbers.h(7)>, as follows:
 
- OP_keyexch_newctx           OSSL_FUNC_KEYEXCH_NEWCTX
- OP_keyexch_freectx          OSSL_FUNC_KEYEXCH_FREECTX
- OP_keyexch_dupctx           OSSL_FUNC_KEYEXCH_DUPCTX
+ OP_keyexch_newctx                OSSL_FUNC_KEYEXCH_NEWCTX
+ OP_keyexch_freectx               OSSL_FUNC_KEYEXCH_FREECTX
+ OP_keyexch_dupctx                OSSL_FUNC_KEYEXCH_DUPCTX
 
 
- OP_keyexch_init             OSSL_FUNC_KEYEXCH_INIT
- OP_keyexch_set_peer         OSSL_FUNC_KEYEXCH_SET_PEER
- OP_keyexch_derive           OSSL_FUNC_KEYEXCH_DERIVE
+ OP_keyexch_init                  OSSL_FUNC_KEYEXCH_INIT
+ OP_keyexch_set_peer              OSSL_FUNC_KEYEXCH_SET_PEER
+ OP_keyexch_derive                OSSL_FUNC_KEYEXCH_DERIVE
 
 
- OP_keyexch_set_params       OSSL_FUNC_KEYEXCH_SET_PARAMS
+ OP_keyexch_set_ctx_params        OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS
+ OP_keyexch_settable_ctx_params   OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS
 
 A key exchange algorithm implementation may not implement all of these functions.
 In order to be a consistent set of functions a provider must implement
 
 A key exchange algorithm implementation may not implement all of these functions.
 In order to be a consistent set of functions a provider must implement
@@ -127,8 +128,8 @@ written to B<*secretlen>.
 See L<OSSL_PARAM(3)> for further details on the parameters structure used by
 the OP_keyexch_set_params() function.
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure used by
 the OP_keyexch_set_params() function.
 
-OP_keyexch_set_params() sets key exchange parameters associated with the given
-provider side key exchange context B<ctx> to B<params>.
+OP_keyexch_set_ctx_params() sets key exchange parameters associated with the
+given provider side key exchange context B<ctx> to B<params>.
 Any parameter settings are additional to any that were previously set.
 
 Parameters currently recognised by built-in key exchange algorithms are as
 Any parameter settings are additional to any that were previously set.
 
 Parameters currently recognised by built-in key exchange algorithms are as
@@ -151,6 +152,11 @@ possible secret size.
 
 =back
 
 
 =back
 
+OP_keyexch_settable_ctx_params() gets a constant B<OSSL_PARAM> array that
+decribes the settable parameters, i.e. parameters that can be used with
+OP_signature_set_ctx_params().
+See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
+
 =head1 RETURN VALUES
 
 OP_keyexch_newctx() and OP_keyexch_dupctx() should return the newly created
 =head1 RETURN VALUES
 
 OP_keyexch_newctx() and OP_keyexch_dupctx() should return the newly created
index 3894afd03cec16f9b710f3bc63a58b6153132dc4..1ab4831035cd7f758c56238a32ede87687c49fc4 100644 (file)
@@ -39,8 +39,10 @@ provider-signature - The signature library E<lt>-E<gt> provider functions
                                  const unsigned char *sig, size_t siglen);
 
  /* Signature parameters */
                                  const unsigned char *sig, size_t siglen);
 
  /* Signature parameters */
- int OP_signature_set_params(void *ctx, const OSSL_PARAM params[]);
-
+ int OP_signature_get_ctx_params(void *ctx, OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_signature_gettable_ctx_params(void);
+ int OP_signature_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_signature_settable_ctx_params(void);
 
 =head1 DESCRIPTION
 
 
 =head1 DESCRIPTION
 
@@ -86,7 +88,10 @@ macros in L<openssl-core_numbers.h(7)>, as follows:
  OP_signature_verify_recover_init    OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT
  OP_signature_verify_recover         OSSL_FUNC_SIGNATURE_VERIFY_RECOVER
 
  OP_signature_verify_recover_init    OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT
  OP_signature_verify_recover         OSSL_FUNC_SIGNATURE_VERIFY_RECOVER
 
- OP_signature_set_params             OSSL_FUNC_SIGNATURE_SET_PARAMS
+ OP_signature_get_ctx_params         OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS
+ OP_signature_gettable_ctx_params    OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS
+ OP_signature_set_ctx_params         OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS
+ OP_signature_settable_ctx_params    OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS
 
 A signature algorithm implementation may not implement all of these functions.
 In order to be a consistent set of functions a provider must implement
 
 A signature algorithm implementation may not implement all of these functions.
 In order to be a consistent set of functions a provider must implement
@@ -174,10 +179,12 @@ the B<routlen> parameter.
 =head2 Signature Parameters
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure used by
 =head2 Signature Parameters
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure used by
-the OP_signature_set_params() function.
+the OP_signature_get_ctx_params() and OP_signature_set_ctx_params() functions.
 
 
-OP_signature_set_params() sets signature parameters associated with the given
-provider side key exchange context B<ctx> to B<params>.
+OP_signature_get_ctx_params() gets signature parameters associated with the
+given provider side signature context B<ctx> and stored them in B<params>.
+OP_signature_set_ctx_params() sets the signature parameters associated with the
+given provider side signature context B<ctx> to B<params>.
 Any parameter settings are additional to any that were previously set.
 
 Parameters currently recognised by built-in signature algorithms are as
 Any parameter settings are additional to any that were previously set.
 
 Parameters currently recognised by built-in signature algorithms are as
@@ -187,27 +194,30 @@ algorithms:
 
 =over 4
 
 
 =over 4
 
-=item B<OSSL_SIGNATURE_PARAM_DIGEST> (UTF8 string)
+=item "digest" (B<OSSL_SIGNATURE_PARAM_DIGEST>) <utf8 string>
 
 
-Sets the name of the digest algorithm used for the input to the signature
+Get or sets the name of the digest algorithm used for the input to the signature
 functions.
 
 functions.
 
-=item B<OSSL_SIGNATURE_PARAM_DIGEST_SIZE> (size_t)
+=item "digest-size" (B<OSSL_SIGNATURE_PARAM_DIGEST_SIZE>) <size_t>
 
 
-Sets the output size of the digest algorithm used for the input to the signature
-functions.
+Gets or sets the output size of the digest algorithm used for the input to the
+signature functions.
 
 =back
 
 
 =back
 
+OP_signature_gettable_ctx_params() and OP_signature_settable_ctx_params() get a
+constant B<OSSL_PARAM> array that decribes the gettable and settable parameters,
+i.e. parameters that can be used with OP_signature_get_ctx_params() and
+OP_signature_set_ctx_params() respectively.
+See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
+
 =head1 RETURN VALUES
 
 OP_signature_newctx() and OP_signature_dupctx() should return the newly created
 provider side signature, or NULL on failure.
 
 =head1 RETURN VALUES
 
 OP_signature_newctx() and OP_signature_dupctx() should return the newly created
 provider side signature, or NULL on failure.
 
-OP_signature_sign_init(), OP_signature_sign(), OP_signature_verify_init(),
-OP_signature_verify(), OP_signature_verify_recover_init(),
-OP_signature_verify_recover() and OP_signature_set_params() should return 1 for
-success or 0 on error.
+All other functions should return 1 for success or 0 on error.
 
 =head1 SEE ALSO
 
 
 =head1 SEE ALSO
 
index 35e6056ba1f22a28e744ee24606c60d081531ef4..002582012eaeda86f75f948e7ceb241dd5e18a03 100644 (file)
@@ -389,7 +389,8 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_exportkey_types, (void))
 # define OSSL_FUNC_KEYEXCH_SET_PEER                    4
 # define OSSL_FUNC_KEYEXCH_FREECTX                     5
 # define OSSL_FUNC_KEYEXCH_DUPCTX                      6
 # define OSSL_FUNC_KEYEXCH_SET_PEER                    4
 # define OSSL_FUNC_KEYEXCH_FREECTX                     5
 # define OSSL_FUNC_KEYEXCH_DUPCTX                      6
-# define OSSL_FUNC_KEYEXCH_SET_PARAMS                  7
+# define OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS              7
+# define OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS         8
 
 OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_newctx, (void *provctx))
 OSSL_CORE_MAKE_FUNC(int, OP_keyexch_init, (void *ctx, void *provkey))
 
 OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_newctx, (void *provctx))
 OSSL_CORE_MAKE_FUNC(int, OP_keyexch_init, (void *ctx, void *provkey))
@@ -398,8 +399,10 @@ OSSL_CORE_MAKE_FUNC(int, OP_keyexch_derive, (void *ctx,  unsigned char *secret,
 OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_peer, (void *ctx, void *provkey))
 OSSL_CORE_MAKE_FUNC(void, OP_keyexch_freectx, (void *ctx))
 OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_dupctx, (void *ctx))
 OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_peer, (void *ctx, void *provkey))
 OSSL_CORE_MAKE_FUNC(void, OP_keyexch_freectx, (void *ctx))
 OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_dupctx, (void *ctx))
-OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_params, (void *ctx,
-                                                 const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_ctx_params, (void *ctx,
+                                                     const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keyexch_settable_ctx_params,
+                    (void))
 
 /* Signature */
 
 
 /* Signature */
 
@@ -412,7 +415,10 @@ OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_params, (void *ctx,
 # define OSSL_FUNC_SIGNATURE_VERIFY_RECOVER          7
 # define OSSL_FUNC_SIGNATURE_FREECTX                 8
 # define OSSL_FUNC_SIGNATURE_DUPCTX                  9
 # define OSSL_FUNC_SIGNATURE_VERIFY_RECOVER          7
 # define OSSL_FUNC_SIGNATURE_FREECTX                 8
 # define OSSL_FUNC_SIGNATURE_DUPCTX                  9
-# define OSSL_FUNC_SIGNATURE_SET_PARAMS             10
+# define OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS         10
+# define OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS    11
+# define OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS         12
+# define OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS    13
 
 OSSL_CORE_MAKE_FUNC(void *, OP_signature_newctx, (void *provctx))
 OSSL_CORE_MAKE_FUNC(int, OP_signature_sign_init, (void *ctx, void *provkey))
 
 OSSL_CORE_MAKE_FUNC(void *, OP_signature_newctx, (void *provctx))
 OSSL_CORE_MAKE_FUNC(int, OP_signature_sign_init, (void *ctx, void *provkey))
@@ -436,8 +442,14 @@ OSSL_CORE_MAKE_FUNC(int, OP_signature_verify_recover, (void *ctx,
                                                        size_t siglen))
 OSSL_CORE_MAKE_FUNC(void, OP_signature_freectx, (void *ctx))
 OSSL_CORE_MAKE_FUNC(void *, OP_signature_dupctx, (void *ctx))
                                                        size_t siglen))
 OSSL_CORE_MAKE_FUNC(void, OP_signature_freectx, (void *ctx))
 OSSL_CORE_MAKE_FUNC(void *, OP_signature_dupctx, (void *ctx))
-OSSL_CORE_MAKE_FUNC(int, OP_signature_set_params, (void *ctx,
-                                                   const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(int, OP_signature_get_ctx_params,
+                    (void *ctx, OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_signature_gettable_ctx_params,
+                    (void))
+OSSL_CORE_MAKE_FUNC(int, OP_signature_set_ctx_params,
+                    (void *ctx, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_signature_settable_ctx_params,
+                    (void))
 
 # ifdef __cplusplus
 }
 
 # ifdef __cplusplus
 }
index 2ea8d2799f8de571f320dfdd0555a91f66f51e22..69d70e5e9c674a6034ebd748605720fe120aff45 100644 (file)
@@ -1337,6 +1337,7 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
                                      int (*pkey_security_bits) (const EVP_PKEY
                                                                 *pk));
 
                                      int (*pkey_security_bits) (const EVP_PKEY
                                                                 *pk));
 
+int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
 int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
 
 # define EVP_PKEY_OP_UNDEFINED           0
 int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
 
 # define EVP_PKEY_OP_UNDEFINED           0
@@ -1364,10 +1365,6 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
 # define EVP_PKEY_OP_TYPE_GEN \
                 (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
 
 # define EVP_PKEY_OP_TYPE_GEN \
                 (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
 
-# define  EVP_PKEY_CTX_get_signature_md(ctx, pmd)        \
-                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
-                                        EVP_PKEY_CTRL_GET_MD, 0, (void *)(pmd))
-
 # define  EVP_PKEY_CTX_set_mac_key(ctx, key, len)        \
                 EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN,  \
                                   EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)(key))
 # define  EVP_PKEY_CTX_set_mac_key(ctx, key, len)        \
                 EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN,  \
                                   EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)(key))
@@ -1427,7 +1424,10 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
 EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
 
 EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
 
+int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
+const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
 int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
+const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
                       int cmd, int p1, void *p2);
 int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
 int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
                       int cmd, int p1, void *p2);
 int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
index 5ff8318725ba3d07718a4a1694bc1a584d24cc0c..cfbda43fb861207f3068b23678fbd903c566629d 100644 (file)
@@ -20,6 +20,8 @@ static OSSL_OP_keyexch_set_peer_fn dh_set_peer;
 static OSSL_OP_keyexch_derive_fn dh_derive;
 static OSSL_OP_keyexch_freectx_fn dh_freectx;
 static OSSL_OP_keyexch_dupctx_fn dh_dupctx;
 static OSSL_OP_keyexch_derive_fn dh_derive;
 static OSSL_OP_keyexch_freectx_fn dh_freectx;
 static OSSL_OP_keyexch_dupctx_fn dh_dupctx;
+static OSSL_OP_keyexch_set_ctx_params_fn dh_set_ctx_params;
+static OSSL_OP_keyexch_settable_ctx_params_fn dh_settable_ctx_params;
 
 /*
  * What's passed as an actual key is defined by the KEYMGMT interface.
 
 /*
  * What's passed as an actual key is defined by the KEYMGMT interface.
@@ -124,7 +126,7 @@ static void *dh_dupctx(void *vpdhctx)
     return dstctx;
 }
 
     return dstctx;
 }
 
-static int dh_set_params(void *vpdhctx, const OSSL_PARAM params[])
+static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
 {
     PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
     const OSSL_PARAM *p;
 {
     PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
     const OSSL_PARAM *p;
@@ -140,6 +142,16 @@ static int dh_set_params(void *vpdhctx, const OSSL_PARAM params[])
     return 1;
 }
 
     return 1;
 }
 
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL),
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *dh_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
 const OSSL_DISPATCH dh_keyexch_functions[] = {
     { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
     { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
 const OSSL_DISPATCH dh_keyexch_functions[] = {
     { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
     { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
@@ -147,6 +159,8 @@ const OSSL_DISPATCH dh_keyexch_functions[] = {
     { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
     { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
     { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
     { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
     { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
     { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
-    { OSSL_FUNC_KEYEXCH_SET_PARAMS, (void (*)(void))dh_set_params },
+    { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params },
+    { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS,
+      (void (*)(void))dh_settable_ctx_params },
     { 0, NULL }
 };
     { 0, NULL }
 };
index c0cd29381cc087626aecd865a9d46cb080544d44..dc4eb6c6d4a30918dc7b2ede3d2e3e040ba48930 100644 (file)
@@ -20,7 +20,10 @@ static OSSL_OP_signature_verify_init_fn dsa_signature_init;
 static OSSL_OP_signature_sign_fn dsa_sign;
 static OSSL_OP_signature_freectx_fn dsa_freectx;
 static OSSL_OP_signature_dupctx_fn dsa_dupctx;
 static OSSL_OP_signature_sign_fn dsa_sign;
 static OSSL_OP_signature_freectx_fn dsa_freectx;
 static OSSL_OP_signature_dupctx_fn dsa_dupctx;
-static OSSL_OP_signature_set_params_fn dsa_set_params;
+static OSSL_OP_signature_get_ctx_params_fn dsa_get_ctx_params;
+static OSSL_OP_signature_gettable_ctx_params_fn dsa_gettable_ctx_params;
+static OSSL_OP_signature_set_ctx_params_fn dsa_set_ctx_params;
+static OSSL_OP_signature_settable_ctx_params_fn dsa_settable_ctx_params;
 
 /*
  * What's passed as an actual key is defined by the KEYMGMT interface.
 
 /*
  * What's passed as an actual key is defined by the KEYMGMT interface.
@@ -31,6 +34,8 @@ static OSSL_OP_signature_set_params_fn dsa_set_params;
 typedef struct {
     DSA *dsa;
     size_t mdsize;
 typedef struct {
     DSA *dsa;
     size_t mdsize;
+    /* Should be big enough */
+    char mdname[80];
 } PROV_DSA_CTX;
 
 static void *dsa_newctx(void *provctx)
 } PROV_DSA_CTX;
 
 static void *dsa_newctx(void *provctx)
@@ -116,24 +121,74 @@ static void *dsa_dupctx(void *vpdsactx)
     return dstctx;
 }
 
     return dstctx;
 }
 
-static int dsa_set_params(void *vpdsactx, const OSSL_PARAM params[])
+static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+    OSSL_PARAM *p;
+
+    if (pdsactx == NULL || params == NULL)
+        return 0;
+
+    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
+    if (p != NULL && !OSSL_PARAM_set_size_t(p, pdsactx->mdsize))
+        return 0;
+
+    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
+    if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->mdname))
+        return 0;
+
+    return 1;
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
+    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *dsa_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[])
 {
     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
     const OSSL_PARAM *p;
 {
     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
     const OSSL_PARAM *p;
-    size_t mdsize;
+    char *mdname;
 
     if (pdsactx == NULL || params == NULL)
         return 0;
 
     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
 
     if (pdsactx == NULL || params == NULL)
         return 0;
 
     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
-    if (p == NULL || !OSSL_PARAM_get_size_t(p, &mdsize))
+    if (p != NULL && !OSSL_PARAM_get_size_t(p, &pdsactx->mdsize))
         return 0;
 
         return 0;
 
-    pdsactx->mdsize = mdsize;
+    /*
+     * We never actually use the mdname, but we do support getting it later.
+     * This can be useful for applications that want to know the MD that they
+     * previously set.
+     */
+    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
+    mdname = pdsactx->mdname;
+    if (p != NULL
+            && !OSSL_PARAM_get_utf8_string(p, &mdname, sizeof(pdsactx->mdname)))
+        return 0;
 
     return 1;
 }
 
 
     return 1;
 }
 
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
+    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *dsa_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
 const OSSL_DISPATCH dsa_signature_functions[] = {
     { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
     { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_signature_init },
 const OSSL_DISPATCH dsa_signature_functions[] = {
     { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
     { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_signature_init },
@@ -142,6 +197,11 @@ const OSSL_DISPATCH dsa_signature_functions[] = {
     { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify },
     { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
     { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
     { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify },
     { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
     { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
-    { OSSL_FUNC_SIGNATURE_SET_PARAMS, (void (*)(void))dsa_set_params },
+    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))dsa_get_ctx_params },
+    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
+      (void (*)(void))dsa_gettable_ctx_params },
+    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))dsa_set_ctx_params },
+    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
+      (void (*)(void))dsa_settable_ctx_params },
     { 0, NULL }
 };
     { 0, NULL }
 };
index 1ad62d2f791ae3565936a932a704f61b9fdbdc37..7b7c632dd1dbad990e679e469994c0ef5d9884e6 100644 (file)
@@ -19,6 +19,8 @@
 #include <openssl/pem.h>
 #include <openssl/kdf.h>
 #include <openssl/provider.h>
 #include <openssl/pem.h>
 #include <openssl/kdf.h>
 #include <openssl/provider.h>
+#include <openssl/core_names.h>
+#include <openssl/dsa.h>
 #include "testutil.h"
 #include "internal/nelem.h"
 #include "internal/evp_int.h"
 #include "testutil.h"
 #include "internal/nelem.h"
 #include "internal/evp_int.h"
@@ -1393,6 +1395,117 @@ static int test_EVP_CIPHER_fetch(int tst)
     return ret;
 }
 
     return ret;
 }
 
+/* Test getting and setting parameters on an EVP_PKEY_CTX */
+static int test_EVP_PKEY_CTX_get_set_params(void)
+{
+    EVP_PKEY_CTX *ctx = NULL;
+    EVP_SIGNATURE *dsaimpl = NULL;
+    const OSSL_PARAM *params;
+    OSSL_PARAM ourparams[2], *param = ourparams;
+    DSA *dsa = NULL;
+    BIGNUM *p = NULL, *q = NULL, *g = NULL;
+    EVP_PKEY *pkey = NULL;
+    int ret = 0;
+    const EVP_MD *md;
+    size_t mdsize = SHA512_DIGEST_LENGTH;
+
+    /*
+     * Setup the parameters for our DSA object. For our purposes they don't have
+     * to actually be *valid* parameters. We just need to set something. We
+     * don't even need a pub_key/priv_key.
+     */
+    dsa = DSA_new();
+    p = BN_new();
+    q = BN_new();
+    g = BN_new();
+    if (!TEST_ptr(dsa)
+            || !TEST_ptr(p)
+            || !TEST_ptr(q)
+            || !TEST_ptr(g)
+            || !DSA_set0_pqg(dsa, p, q, g))
+        goto err;
+    p = q = g = NULL;
+
+    pkey = EVP_PKEY_new();
+    if (!TEST_ptr(pkey)
+            || !TEST_true(EVP_PKEY_assign_DSA(pkey, dsa)))
+        goto err;
+
+    dsa = NULL;
+
+    /* Initialise a sign operation */
+    ctx = EVP_PKEY_CTX_new(pkey, NULL);
+    dsaimpl = EVP_SIGNATURE_fetch(NULL, "DSA", NULL);
+    if (!TEST_ptr(ctx)
+            || !TEST_ptr(dsaimpl)
+            || !TEST_int_gt(EVP_PKEY_sign_init_ex(ctx, dsaimpl), 0))
+        goto err;
+
+    /*
+     * We should be able to query the parameters now. The default DSA
+     * implementation supports exactly one parameter - so we expect to see that
+     * returned and no more.
+     */
+    params = EVP_PKEY_CTX_settable_params(ctx);
+    if (!TEST_ptr(params)
+            || !TEST_int_eq(strcmp(params[0].key,
+                            OSSL_SIGNATURE_PARAM_DIGEST_SIZE), 0)
+            || !TEST_int_eq(strcmp(params[1].key, OSSL_SIGNATURE_PARAM_DIGEST),
+                            0)
+               /* The final key should be NULL */
+            || !TEST_ptr_null(params[2].key))
+        goto err;
+
+    /* Gettable params are the same as the settable ones */
+    params = EVP_PKEY_CTX_gettable_params(ctx);
+    if (!TEST_ptr(params)
+            || !TEST_int_eq(strcmp(params[0].key,
+                            OSSL_SIGNATURE_PARAM_DIGEST_SIZE), 0)
+            || !TEST_int_eq(strcmp(params[1].key, OSSL_SIGNATURE_PARAM_DIGEST),
+                            0)
+               /* The final key should be NULL */
+            || !TEST_ptr_null(params[2].key))
+        goto err;
+
+    /*
+     * Test getting and setting params via EVP_PKEY_CTX_set_params() and
+     * EVP_PKEY_CTX_get_params()
+     */
+    *param++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
+                                           &mdsize);
+    *param++ = OSSL_PARAM_construct_end();
+
+    if (!TEST_true(EVP_PKEY_CTX_set_params(ctx, ourparams)))
+        goto err;
+
+    mdsize = 0;
+    if (!TEST_true(EVP_PKEY_CTX_get_params(ctx, ourparams))
+            || !TEST_size_t_eq(mdsize, SHA512_DIGEST_LENGTH))
+        goto err;
+
+    /*
+     * Test the TEST_PKEY_CTX_set_signature_md() and
+     * TEST_PKEY_CTX_get_signature_md() functions
+     */
+    if (!TEST_int_gt(EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()), 0)
+            || !TEST_int_gt(EVP_PKEY_CTX_get_signature_md(ctx, &md), 0)
+            || !TEST_ptr_eq(md, EVP_sha256()))
+        goto err;
+
+    ret = 1;
+
+ err:
+    EVP_PKEY_CTX_free(ctx);
+    EVP_SIGNATURE_free(dsaimpl);
+    EVP_PKEY_free(pkey);
+    DSA_free(dsa);
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+
+    return ret;
+}
+
 int setup_tests(void)
 {
     ADD_TEST(test_EVP_DigestSignInit);
 int setup_tests(void)
 {
     ADD_TEST(test_EVP_DigestSignInit);
@@ -1429,5 +1542,6 @@ int setup_tests(void)
     ADD_ALL_TESTS(test_EVP_MD_fetch, 5);
     ADD_ALL_TESTS(test_EVP_CIPHER_fetch, 5);
 #endif
     ADD_ALL_TESTS(test_EVP_MD_fetch, 5);
     ADD_ALL_TESTS(test_EVP_CIPHER_fetch, 5);
 #endif
+    ADD_TEST(test_EVP_PKEY_CTX_get_set_params);
     return 1;
 }
     return 1;
 }
index a1a36f1f77407802ef2658ced1d514d9236b23f2..e5c869af448093a75e6f727d891ea2c67173d5f2 100644 (file)
@@ -4748,3 +4748,7 @@ EVP_PKEY_sign_init_ex                   4864      3_0_0   EXIST::FUNCTION:
 EVP_PKEY_CTX_set_signature_md           4865   3_0_0   EXIST::FUNCTION:
 EVP_PKEY_verify_init_ex                 4866   3_0_0   EXIST::FUNCTION:
 EVP_PKEY_verify_recover_init_ex         4867   3_0_0   EXIST::FUNCTION:
 EVP_PKEY_CTX_set_signature_md           4865   3_0_0   EXIST::FUNCTION:
 EVP_PKEY_verify_init_ex                 4866   3_0_0   EXIST::FUNCTION:
 EVP_PKEY_verify_recover_init_ex         4867   3_0_0   EXIST::FUNCTION:
+EVP_PKEY_CTX_get_signature_md           4868   3_0_0   EXIST::FUNCTION:
+EVP_PKEY_CTX_get_params                 4869   3_0_0   EXIST::FUNCTION:
+EVP_PKEY_CTX_gettable_params            4870   3_0_0   EXIST::FUNCTION:
+EVP_PKEY_CTX_settable_params            4871   3_0_0   EXIST::FUNCTION: