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_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 {
@@ -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_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,
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;
-    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);
@@ -102,19 +102,28 @@ static void *evp_keyexch_from_dispatch(const char *name,
                 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;
-            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;
         }
     }
-    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,
-         * 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);
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;
+    int gparamfncnt = 0, sparamfncnt = 0;
 
     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;
-        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;
-            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
-        || (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
-         * (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;
index 534f857df1b7dce586784cea31a8d308761e41b5..4c98212c6a29813300eaad15dbd1935b91dfa43f 100644 (file)
@@ -404,15 +404,49 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *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)
 {
-    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;
 }
 
+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)
 {
@@ -431,36 +465,78 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
 }
 #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)
 {
-    OSSL_PARAM sig_md_params[3];
+    OSSL_PARAM sig_md_params[3], *p = sig_md_params;
     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));
 
-    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,
index 9d1812f6bd65a38e7855a7433d5bd8edd8342ed8..18b984162e5709dbaeacc57595ae092b00315462 100644 (file)
@@ -2,7 +2,10 @@
 
 =head1 NAME
 
+EVP_PKEY_CTX_get_params,
+EVP_PKEY_CTX_gettable_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,
@@ -63,7 +66,10 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
 
  #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);
+ 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);
@@ -144,16 +150,20 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
 
 =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.
+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
 
-=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
@@ -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.
 
-=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
 
+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.
@@ -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>.
 
-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.
 
-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
@@ -471,9 +491,15 @@ allocate adequate memory space for the B<id> before calling EVP_PKEY_CTX_get1_id
 
 =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
 
@@ -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_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
 
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 */
- 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
 
@@ -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:
 
- 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
@@ -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.
 
-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
@@ -151,6 +152,11 @@ possible secret size.
 
 =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
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 */
- 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
 
@@ -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_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
@@ -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
-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
@@ -187,27 +194,30 @@ algorithms:
 
 =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.
 
-=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
 
+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.
 
-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
 
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_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))
@@ -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_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 */
 
@@ -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_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))
@@ -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))
-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
 }
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 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
@@ -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_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))
@@ -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);
 
+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);
+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,
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_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.
@@ -124,7 +126,7 @@ static void *dh_dupctx(void *vpdhctx)
     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;
@@ -140,6 +142,16 @@ static int dh_set_params(void *vpdhctx, const OSSL_PARAM params[])
     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 },
@@ -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_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 }
 };
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_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.
@@ -31,6 +34,8 @@ static OSSL_OP_signature_set_params_fn dsa_set_params;
 typedef struct {
     DSA *dsa;
     size_t mdsize;
+    /* Should be big enough */
+    char mdname[80];
 } PROV_DSA_CTX;
 
 static void *dsa_newctx(void *provctx)
@@ -116,24 +121,74 @@ static void *dsa_dupctx(void *vpdsactx)
     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;
-    size_t mdsize;
+    char *mdname;
 
     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;
 
-    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;
 }
 
+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 },
@@ -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_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 }
 };
index 1ad62d2f791ae3565936a932a704f61b9fdbdc37..7b7c632dd1dbad990e679e469994c0ef5d9884e6 100644 (file)
@@ -19,6 +19,8 @@
 #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"
@@ -1393,6 +1395,117 @@ static int test_EVP_CIPHER_fetch(int tst)
     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);
@@ -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_TEST(test_EVP_PKEY_CTX_get_set_params);
     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_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: