Add EVP_PKEY_gettable_params support for accessing EVP_PKEY key data fields
authorShane Lontis <shane.lontis@oracle.com>
Wed, 1 Apr 2020 05:51:18 +0000 (15:51 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Wed, 1 Apr 2020 05:51:18 +0000 (15:51 +1000)
Currently only RSA, EC and ECX are supported (DH and DSA need to be added to the keygen
PR's seperately because the fields supported have changed significantly).

The API's require the keys to be provider based.

Made the keymanagement export and get_params functions share the same code by supplying
support functions that work for both a OSSL_PARAM_BLD as well as a OSSL_PARAM[].
This approach means that complex code is not required to build an
empty OSSL_PARAM[] with the correct sized fields before then doing a second
pass to populate the array.

The RSA factor arrays have been changed to use unique key names to simplify the interface
needed by the user.

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

22 files changed:
crypto/build.info
crypto/evp/p_lib.c
crypto/param_build_set.c [new file with mode: 0644]
crypto/rsa/build.info
crypto/rsa/rsa_ameth.c
crypto/rsa/rsa_backend.c
crypto/rsa/rsa_mp_names.c [new file with mode: 0644]
doc/man3/EVP_PKEY_fromdata.pod
doc/man3/EVP_PKEY_gettable_params.pod [new file with mode: 0644]
doc/man7/provider-keymgmt.pod
include/crypto/rsa.h
include/internal/param_build_set.h [new file with mode: 0644]
include/openssl/core_names.h
include/openssl/evp.h
providers/implementations/keymgmt/build.info
providers/implementations/keymgmt/ec_kmgmt.c
providers/implementations/keymgmt/ecx_kmgmt.c
providers/implementations/keymgmt/rsa_kmgmt.c
providers/implementations/serializers/serializer_rsa.c
test/evp_pkey_provided_test.c
test/keymgmt_internal_test.c
util/libcrypto.num

index a688248acf7e713d89039afef0ae0df0cd28f375..baa31ee8e183fec4228b1c8baac5fb91de6fff6b 100644 (file)
@@ -70,7 +70,8 @@ SOURCE[../providers/libfips.a]=$CORE_COMMON
 $UTIL_COMMON=\
         cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \
         ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \
 $UTIL_COMMON=\
         cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \
         ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \
-        context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM
+        context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM \
+        param_build_set.c
 $UTIL_DEFINE=$CPUIDDEF
 
 SOURCE[../libcrypto]=$UTIL_COMMON \
 $UTIL_DEFINE=$CPUIDDEF
 
 SOURCE[../libcrypto]=$UTIL_COMMON \
index 9ed238e3664b0b9a1553a01c7a38f09a99ad6840..b176f100e8d945784fcea2f0976ab4919b7e0005 100644 (file)
@@ -1459,3 +1459,163 @@ int evp_pkey_downgrade(EVP_PKEY *pk)
     return 0;     /* No downgrade, but at least the key is restored */
 }
 #endif  /* FIPS_MODE */
     return 0;     /* No downgrade, but at least the key is restored */
 }
 #endif  /* FIPS_MODE */
+
+const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey)
+{
+    if (pkey == NULL
+        || pkey->keymgmt == NULL
+        || pkey->keydata == NULL)
+        return 0;
+    return evp_keymgmt_gettable_params(pkey->keymgmt);
+}
+
+/*
+ * For the following methods param->return_size is set to a value
+ * larger than can be returned by the call to evp_keymgmt_get_params().
+ * If it is still this value then the parameter was ignored - and in this
+ * case it returns an error..
+ */
+
+int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn)
+{
+    int ret = 0;
+    OSSL_PARAM params[2];
+    unsigned char buffer[2048];
+    /*
+     * Use -1 as the terminator here instead of sizeof(buffer) + 1 since
+     * -1 is less likely to be a valid value.
+     */
+    const size_t not_set = (size_t)-1;
+    unsigned char *buf = NULL;
+    size_t buf_sz = 0;
+
+    if (pkey == NULL
+        || pkey->keymgmt == NULL
+        || pkey->keydata == NULL
+        || key_name == NULL
+        || bn == NULL)
+        return 0;
+
+    memset(buffer, 0, sizeof(buffer));
+    params[0] = OSSL_PARAM_construct_BN(key_name, buffer, sizeof(buffer));
+    /* If the return_size is still not_set then we know it was not found */
+    params[0].return_size = not_set;
+    params[1] = OSSL_PARAM_construct_end();
+    if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) {
+        if (params[0].return_size == not_set
+            || params[0].return_size == 0)
+            return 0;
+        buf_sz = params[0].return_size;
+        /*
+         * If it failed because the buffer was too small then allocate the
+         * required buffer size and retry.
+         */
+        buf = OPENSSL_zalloc(buf_sz);
+        if (buf == NULL)
+            return 0;
+        params[0].data = buf;
+        params[0].data_size = buf_sz;
+
+        if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+            goto err;
+    }
+    /* Fail if the param was not found */
+    if (params[0].return_size == not_set)
+        goto err;
+    ret = OSSL_PARAM_get_BN(params, bn);
+err:
+    OPENSSL_free(buf);
+    return ret;
+}
+
+int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
+                                    unsigned char *buf, size_t max_buf_sz,
+                                    size_t *out_sz)
+{
+    OSSL_PARAM params[2];
+    const size_t not_set = max_buf_sz + 1;
+
+    if (pkey == NULL
+        || pkey->keymgmt == NULL
+        || pkey->keydata == NULL
+        || key_name == NULL)
+        return 0;
+
+    params[0] = OSSL_PARAM_construct_octet_string(key_name, buf, max_buf_sz);
+    params[0].return_size = not_set;
+    params[1] = OSSL_PARAM_construct_end();
+    if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+        return 0;
+    if (params[0].return_size == not_set)
+        return 0;
+    if (out_sz != NULL)
+        *out_sz = params[0].return_size;
+    return 1;
+}
+
+int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
+                                    char *str, size_t max_buf_sz,
+                                    size_t *out_sz)
+{
+    OSSL_PARAM params[2];
+    const size_t not_set = max_buf_sz + 1;
+
+    if (pkey == NULL
+        || pkey->keymgmt == NULL
+        || pkey->keydata == NULL
+        || key_name == NULL)
+        return 0;
+
+    params[0] = OSSL_PARAM_construct_utf8_string(key_name, str, max_buf_sz);
+    params[0].return_size = not_set;
+    params[1] = OSSL_PARAM_construct_end();
+    if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+        return 0;
+    if (params[0].return_size == not_set)
+        return 0;
+    if (out_sz != NULL)
+        *out_sz = params[0].return_size;
+    return 1;
+}
+
+int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out)
+{
+    OSSL_PARAM params[2];
+    const size_t not_set = sizeof(int) + 1;
+
+    if (pkey == NULL
+        || pkey->keymgmt == NULL
+        || pkey->keydata == NULL
+        || key_name == NULL)
+        return 0;
+
+    params[0] = OSSL_PARAM_construct_int(key_name, out);
+    params[0].return_size = not_set;
+    params[1] = OSSL_PARAM_construct_end();
+    if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+        return 0;
+    if (params[0].return_size == not_set)
+        return 0;
+    return 1;
+}
+
+int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out)
+{
+    OSSL_PARAM params[2];
+    const size_t not_set = sizeof(size_t) + 1;
+
+    if (pkey == NULL
+        || pkey->keymgmt == NULL
+        || pkey->keydata == NULL
+        || key_name == NULL)
+        return 0;
+
+    params[0] = OSSL_PARAM_construct_size_t(key_name, out);
+    params[0].return_size = not_set;
+    params[1] = OSSL_PARAM_construct_end();
+    if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+        return 0;
+    if (params[0].return_size == not_set)
+        return 0;
+    return 1;
+}
diff --git a/crypto/param_build_set.c b/crypto/param_build_set.c
new file mode 100644 (file)
index 0000000..b74b0d5
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Key Management utility functions to share functionality between the export()
+ * and get_params() methods.
+ * export() uses OSSL_PARAM_BLD, and get_params() used the OSSL_PARAM[] to
+ * fill in parameter data for the same key and data fields.
+ */
+
+#include <openssl/core_names.h>
+#include "internal/param_build_set.h"
+
+DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
+
+int ossl_param_build_set_int(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                             const char *key, int num)
+{
+    if (bld != NULL)
+        return OSSL_PARAM_BLD_push_int(bld, key, num);
+    p = OSSL_PARAM_locate(p, key);
+    if (p != NULL)
+        return OSSL_PARAM_set_int(p, num);
+    return 1;
+}
+
+int ossl_param_build_set_utf8_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                     const char *key, const char *buf)
+{
+    if (bld != NULL)
+        return OSSL_PARAM_BLD_push_utf8_string(bld, key, buf, 0);
+    p = OSSL_PARAM_locate(p, key);
+    if (p != NULL)
+        return OSSL_PARAM_set_utf8_string(p, buf);
+    return 1;
+}
+
+int ossl_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                      const char *key,
+                                      const unsigned char *data,
+                                      size_t data_len)
+{
+    if (bld != NULL)
+        return OSSL_PARAM_BLD_push_octet_string(bld, key, data, data_len);
+
+    p = OSSL_PARAM_locate(p, key);
+    if (p != NULL)
+        return OSSL_PARAM_set_octet_string(p, data, data_len);
+    return 1;
+}
+
+int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                const char *key, const BIGNUM *bn,  size_t sz)
+{
+    if (bld != NULL)
+        return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn, sz);
+    p = OSSL_PARAM_locate(p, key);
+    if (p != NULL) {
+        if (sz > p->data_size)
+            return 0;
+        /* TODO(3.0) Change to use OSSL_PARAM_set_BN_pad */
+        p->data_size = sz;
+        return OSSL_PARAM_set_BN(p, bn);
+    }
+    return 1;
+}
+
+int ossl_param_build_set_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                            const char *key, const BIGNUM *bn)
+{
+    if (bld != NULL)
+        return OSSL_PARAM_BLD_push_BN(bld, key, bn);
+
+    p = OSSL_PARAM_locate(p, key);
+    if (p != NULL)
+        return OSSL_PARAM_set_BN(p, bn) > 0;
+    return 1;
+}
+
+int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *params,
+                                      const char *names[],
+                                      STACK_OF(BIGNUM_const) *stk)
+{
+    int i, sz = sk_BIGNUM_const_num(stk);
+    OSSL_PARAM *p;
+
+
+    if (bld != NULL) {
+        for (i = 0; i < sz && names[i] != NULL; ++i) {
+            if (!OSSL_PARAM_BLD_push_BN(bld, names[i],
+                                        sk_BIGNUM_const_value(stk, i)))
+                return 0;
+        }
+        return 1;
+    }
+
+    for (i = 0; i < sz && names[i] != NULL; ++i) {
+        p = OSSL_PARAM_locate(params, names[i]);
+        if (p != NULL) {
+            if (!OSSL_PARAM_set_BN(p, sk_BIGNUM_const_value(stk, i)))
+                return 0;
+        }
+    }
+    return 1;
+}
index c1d1a3769b8d3acc65040e197a98f21dd2368330..792120273973abe92d0e27db2ce91663898ebbad 100644 (file)
@@ -2,7 +2,8 @@ LIBS=../../libcrypto
 
 $COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_aid.c rsa_pk1.c \
         rsa_none.c rsa_oaep.c rsa_chk.c rsa_pss.c rsa_x931.c rsa_crpt.c \
 
 $COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_aid.c rsa_pk1.c \
         rsa_none.c rsa_oaep.c rsa_chk.c rsa_pss.c rsa_x931.c rsa_crpt.c \
-        rsa_x931g.c rsa_sp800_56b_gen.c rsa_sp800_56b_check.c rsa_backend.c
+        rsa_x931g.c rsa_sp800_56b_gen.c rsa_sp800_56b_check.c rsa_backend.c \
+        rsa_mp_names.c
 
 SOURCE[../../libcrypto]=$COMMON\
         rsa_saos.c rsa_err.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \
 
 SOURCE[../../libcrypto]=$COMMON\
         rsa_saos.c rsa_err.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \
index ec8df4a718533e8fff0bdd59ebbc33879c7d786f..fb378ae03984845797753c289e0e73b0a6dc3e29 100644 (file)
@@ -20,7 +20,7 @@
 #include <openssl/bn.h>
 #include <openssl/cms.h>
 #include <openssl/core_names.h>
 #include <openssl/bn.h>
 #include <openssl/cms.h>
 #include <openssl/core_names.h>
-#include "openssl/param_build.h"
+#include <openssl/param_build.h>
 #include "crypto/asn1.h"
 #include "crypto/evp.h"
 #include "crypto/rsa.h"
 #include "crypto/asn1.h"
 #include "crypto/evp.h"
 #include "crypto/rsa.h"
@@ -1142,27 +1142,24 @@ static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
             goto err;
         selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
 
             goto err;
         selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
 
-        for (i = 0; i < numprimes; i++) {
+        for (i = 0; i < numprimes  && rsa_mp_factor_names[i] != NULL; i++) {
             const BIGNUM *num = sk_BIGNUM_const_value(primes, i);
 
             const BIGNUM *num = sk_BIGNUM_const_value(primes, i);
 
-            if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR,
-                                        num))
+            if (!OSSL_PARAM_BLD_push_BN(tmpl, rsa_mp_factor_names[i], num))
                 goto err;
         }
 
                 goto err;
         }
 
-        for (i = 0; i < numexps; i++) {
+        for (i = 0; i < numexps && rsa_mp_exp_names[i] != NULL; i++) {
             const BIGNUM *num = sk_BIGNUM_const_value(exps, i);
 
             const BIGNUM *num = sk_BIGNUM_const_value(exps, i);
 
-            if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT,
-                                        num))
+            if (!OSSL_PARAM_BLD_push_BN(tmpl, rsa_mp_exp_names[i], num))
                 goto err;
         }
 
                 goto err;
         }
 
-        for (i = 0; i < numcoeffs; i++) {
+        for (i = 0; i < numcoeffs && rsa_mp_coeff_names[i] != NULL; i++) {
             const BIGNUM *num = sk_BIGNUM_const_value(coeffs, i);
 
             const BIGNUM *num = sk_BIGNUM_const_value(coeffs, i);
 
-            if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_COEFFICIENT,
-                                        num))
+            if (!OSSL_PARAM_BLD_push_BN(tmpl, rsa_mp_coeff_names[i], num))
                 goto err;
         }
     }
                 goto err;
         }
     }
index f68d38cc1ad155adc833e125b5c82fead2c6c036..57a539c05134ff00be5e5e7dde0431fbece33baf 100644 (file)
 DEFINE_STACK_OF(BIGNUM)
 
 static int collect_numbers(STACK_OF(BIGNUM) *numbers,
 DEFINE_STACK_OF(BIGNUM)
 
 static int collect_numbers(STACK_OF(BIGNUM) *numbers,
-                           const OSSL_PARAM params[], const char *key)
+                           const OSSL_PARAM params[], const char *names[])
 {
     const OSSL_PARAM *p = NULL;
 {
     const OSSL_PARAM *p = NULL;
+    int i;
 
     if (numbers == NULL)
         return 0;
 
 
     if (numbers == NULL)
         return 0;
 
-    for (p = params; (p = OSSL_PARAM_locate_const(p, key)) != NULL; p++) {
-        BIGNUM *tmp = NULL;
+    for (i = 0; names[i] != NULL; i++){
+        p = OSSL_PARAM_locate_const(params, names[i]);
+        if (p != NULL) {
+            BIGNUM *tmp = NULL;
 
 
-        if (!OSSL_PARAM_get_BN(p, &tmp)
-            || sk_BIGNUM_push(numbers, tmp) == 0)
-            return 0;
+            if (!OSSL_PARAM_get_BN(p, &tmp)
+                || sk_BIGNUM_push(numbers, tmp) == 0)
+                return 0;
+        }
     }
 
     return 1;
     }
 
     return 1;
@@ -65,11 +69,11 @@ int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[])
 
     if (is_private) {
         if (!collect_numbers(factors = sk_BIGNUM_new_null(), params,
 
     if (is_private) {
         if (!collect_numbers(factors = sk_BIGNUM_new_null(), params,
-                             OSSL_PKEY_PARAM_RSA_FACTOR)
+                             rsa_mp_factor_names)
             || !collect_numbers(exps = sk_BIGNUM_new_null(), params,
             || !collect_numbers(exps = sk_BIGNUM_new_null(), params,
-                                OSSL_PKEY_PARAM_RSA_EXPONENT)
+                                rsa_mp_exp_names)
             || !collect_numbers(coeffs = sk_BIGNUM_new_null(), params,
             || !collect_numbers(coeffs = sk_BIGNUM_new_null(), params,
-                                OSSL_PKEY_PARAM_RSA_COEFFICIENT))
+                                rsa_mp_coeff_names))
             goto err;
 
         /* It's ok if this private key just has n, e and d */
             goto err;
 
         /* It's ok if this private key just has n, e and d */
diff --git a/crypto/rsa/rsa_mp_names.c b/crypto/rsa/rsa_mp_names.c
new file mode 100644 (file)
index 0000000..e69321a
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core_names.h>
+#include "crypto/rsa.h"
+
+/*
+ * The following tables are constants used during RSA parameter building
+ * operations. It is easier to point to one of these fixed strings than have
+ * to dynamically add and generate the names on the fly.
+ */
+
+/*
+ * A fixed table of names for the RSA prime factors starting with
+ * P,Q and up to 8 additional primes.
+ */
+const char *rsa_mp_factor_names[] = {
+    OSSL_PKEY_PARAM_RSA_FACTOR1,
+    OSSL_PKEY_PARAM_RSA_FACTOR2,
+#ifndef FIPS_MODE
+    OSSL_PKEY_PARAM_RSA_FACTOR3,
+    OSSL_PKEY_PARAM_RSA_FACTOR4,
+    OSSL_PKEY_PARAM_RSA_FACTOR5,
+    OSSL_PKEY_PARAM_RSA_FACTOR6,
+    OSSL_PKEY_PARAM_RSA_FACTOR7,
+    OSSL_PKEY_PARAM_RSA_FACTOR8,
+    OSSL_PKEY_PARAM_RSA_FACTOR9,
+    OSSL_PKEY_PARAM_RSA_FACTOR10,
+#endif
+    NULL
+};
+
+/*
+ * A fixed table of names for the RSA exponents starting with
+ * DP,DQ and up to 8 additional exponents.
+ */
+const char *rsa_mp_exp_names[] = {
+    OSSL_PKEY_PARAM_RSA_EXPONENT1,
+    OSSL_PKEY_PARAM_RSA_EXPONENT2,
+#ifndef FIPS_MODE
+    OSSL_PKEY_PARAM_RSA_EXPONENT3,
+    OSSL_PKEY_PARAM_RSA_EXPONENT4,
+    OSSL_PKEY_PARAM_RSA_EXPONENT5,
+    OSSL_PKEY_PARAM_RSA_EXPONENT6,
+    OSSL_PKEY_PARAM_RSA_EXPONENT7,
+    OSSL_PKEY_PARAM_RSA_EXPONENT8,
+    OSSL_PKEY_PARAM_RSA_EXPONENT9,
+    OSSL_PKEY_PARAM_RSA_EXPONENT10,
+#endif
+    NULL
+};
+
+/*
+ * A fixed table of names for the RSA coefficients starting with
+ * QINV and up to 8 additional exponents.
+ */
+const char *rsa_mp_coeff_names[] = {
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT2,
+#ifndef FIPS_MODE
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT3,
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT4,
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT5,
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT6,
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT7,
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT8,
+    OSSL_PKEY_PARAM_RSA_COEFFICIENT9,
+#endif
+    NULL
+};
index 2d0059d32fe307c24e74ab204597a44de2e5aee5..e3ddf680585de30e5e7b947c5c632226c3bf8220 100644 (file)
@@ -52,7 +52,7 @@ not supported by the public key algorithm.
 
 =head1 SEE ALSO
 
 
 =head1 SEE ALSO
 
-L<EVP_PKEY_CTX_new(3)>, L<provider(7)>
+L<EVP_PKEY_CTX_new(3)>, L<provider(7)>, L<EVP_PKEY_gettable_params(3)>
 
 =head1 HISTORY
 
 
 =head1 HISTORY
 
diff --git a/doc/man3/EVP_PKEY_gettable_params.pod b/doc/man3/EVP_PKEY_gettable_params.pod
new file mode 100644 (file)
index 0000000..87d25c7
--- /dev/null
@@ -0,0 +1,108 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_gettable_params, EVP_PKEY_get_int_param, EVP_PKEY_get_size_t_param,
+EVP_PKEY_get_bn_param, EVP_PKEY_get_utf8_string_param,
+EVP_PKEY_get_octet_string_param
+- retrieve key parameters from a key
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey);
+ int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out);
+ int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out);
+ int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn);
+ int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
+                                    char *str, size_t max_buf_sz, size_t *out_sz);
+ int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
+                                    unsigned char *buf, size_t max_buf_sz,
+                                    size_t *out_sz);
+
+=head1 DESCRIPTION
+
+EVP_PKEY_gettable_params() returns a constant list of I<params> indicating
+the names and types of key parameters that can be retrieved.
+See L<OSSL_PARAM(3)> for information about parameters.
+
+EVP_PKEY_get_int_param() retrieves a key I<pkey> integer value I<*out>
+associated with a name of I<key_name>.
+
+EVP_PKEY_get_size_t_param() retrieves a key I<pkey> size_t value I<*out>
+associated with a name of I<key_name>.
+
+EVP_PKEY_get_bn_param() retrieves a key I<pkey> BIGNUM value I<**bn>
+associated with a name of I<key_name>. If I<*bn> is NULL then the BIGNUM
+is allocated by the method.
+
+EVP_PKEY_get_utf8_string_param() get a key I<pkey> UTF8 string value int a buffer
+I<str> of maximum size I<max_buf_sz> associated with a name of I<key_name>.
+I<*out_sz> is the returned size of the string if it is not NULL.
+
+EVP_PKEY_get_octet_string_param() copy a I<pkey>'s octet string value into a buffer
+I<buf> of maximum size I<max_buf_sz> associated with a name of I<key_name>.
+I<*out_sz> is the returned size of the buffer if it is not NULL.
+
+=head1 NOTES
+
+These functions only work for B<EVP_PKEY>s that contain a provider side key.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_gettable_params() returns NULL on error or if it is not supported,
+
+All other methods return 1 if a value associated with the key's I<key_name> was
+successfully returned, or 0 if there was an error.
+An error may be returned by methods EVP_PKEY_get_utf8_string_param() and
+EVP_PKEY_get_octet_string_param() if I<max_buf_sz> is not big enough to hold the
+value.
+
+=head1 EXAMPLES
+
+ #include <openssl/evp.h>
+
+ char *curve_name[64];
+ unsigned char pub[256];
+ BIGNUM *bn_priv = NULL;
+
+ /*
+  * NB: assumes 'key' is set up before the next step. In this example the key
+  * is an EC key.
+  */
+
+ if (!EVP_PKEY_get_utf8_string_param(key, OSSL_PKEY_PARAM_EC_NAME,
+                                     curve_name, sizeof(curve_name), &len)) {
+   /* Error */
+ }
+ if (!EVP_PKEY_get_octet_string_param(key, OSSL_PKEY_PARAM_PUB_KEY,
+                                      pub, sizeof(pub), &len)) {
+     /* Error */
+ }
+ if (!EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_PRIV_KEY, &bn_priv)) {
+     /* Error */
+ }
+
+
+ BN_clear_free(bn_priv);
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)>, L<provider-keymgmt(7)>, L<OSSL_PARAM(3)>
+
+=head1 HISTORY
+
+These functions were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
+
index 59e538dbac032ed212780726a4ca0d912d1fdd14..00596a0a4ba87e7581f37e31f1ba2bbb5219d018 100644 (file)
@@ -334,20 +334,74 @@ The RSA "e" value.
 
 The RSA "d" value.
 
 
 The RSA "d" value.
 
-=item "rsa-factor" (B<OSSL_PKEY_PARAM_RSA_FACTOR>) <unsigned integer>
+=item "rsa-factor1" (B<OSSL_PKEY_PARAM_RSA_FACTOR1>) <unsigned integer>
 
 
-An RSA factor. In 2 prime RSA these are often known as "p" or "q". This value
-may be repeated up to 10 times in a single key.
+=item "rsa-factor2" (B<OSSL_PKEY_PARAM_RSA_FACTOR2>) <unsigned integer>
 
 
-=item "rsa-exponent" (B<OSSL_PKEY_PARAM_RSA_EXPONENT>) <unsigned integer>
+=item "rsa-factor3" (B<OSSL_PKEY_PARAM_RSA_FACTOR3>) <unsigned integer>
 
 
-An RSA CRT (Chinese Remainder Theorem) exponent. This value may be repeated up
-to 10 times in a single key.
+=item "rsa-factor4" (B<OSSL_PKEY_PARAM_RSA_FACTOR4>) <unsigned integer>
 
 
-=item "rsa-coefficient" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT>) <unsigned integer>
+=item "rsa-factor5" (B<OSSL_PKEY_PARAM_RSA_FACTOR5>) <unsigned integer>
 
 
-An RSA CRT (Chinese Remainder Theorem) coefficient. This value may be repeated
-up to 9 times in a single key.
+=item "rsa-factor6" (B<OSSL_PKEY_PARAM_RSA_FACTOR6>) <unsigned integer>
+
+=item "rsa-factor7" (B<OSSL_PKEY_PARAM_RSA_FACTOR7>) <unsigned integer>
+
+=item "rsa-factor8" (B<OSSL_PKEY_PARAM_RSA_FACTOR8>) <unsigned integer>
+
+=item "rsa-factor9" (B<OSSL_PKEY_PARAM_RSA_FACTOR9>) <unsigned integer>
+
+=item "rsa-factor10" (B<OSSL_PKEY_PARAM_RSA_FACTOR10>) <unsigned integer>
+
+RSA prime factors. The factors are known as "p", "q" and "r_i" in RFC8017.
+Up to eight additional "r_i" prime factors are supported.
+
+=item "rsa-exponent1" (B<OSSL_PKEY_PARAM_RSA_EXPONENT1>) <unsigned integer>
+
+=item "rsa-exponent2" (B<OSSL_PKEY_PARAM_RSA_EXPONENT2>) <unsigned integer>
+
+=item "rsa-exponent3" (B<OSSL_PKEY_PARAM_RSA_EXPONENT3>) <unsigned integer>
+
+=item "rsa-exponent4" (B<OSSL_PKEY_PARAM_RSA_EXPONENT4>) <unsigned integer>
+
+=item "rsa-exponent5" (B<OSSL_PKEY_PARAM_RSA_EXPONENT5>) <unsigned integer>
+
+=item "rsa-exponent6" (B<OSSL_PKEY_PARAM_RSA_EXPONENT6>) <unsigned integer>
+
+=item "rsa-exponent7" (B<OSSL_PKEY_PARAM_RSA_EXPONENT7>) <unsigned integer>
+
+=item "rsa-exponent8" (B<OSSL_PKEY_PARAM_RSA_EXPONENT8>) <unsigned integer>
+
+=item "rsa-exponent9" (B<OSSL_PKEY_PARAM_RSA_EXPONENT9>) <unsigned integer>
+
+=item "rsa-exponent10" (B<OSSL_PKEY_PARAM_RSA_EXPONENT10>) <unsigned integer>
+
+RSA CRT (Chinese Remainder Theorem) exponents. The exponents are known
+as "dP", "dQ" and "d_i in RFC8017".
+Up to eight additional "d_i" exponents are supported.
+
+=item "rsa-coefficient1" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT1>) <unsigned integer>
+
+=item "rsa-coefficient2" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT2>) <unsigned integer>
+
+=item "rsa-coefficient3" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT3>) <unsigned integer>
+
+=item "rsa-coefficient4" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT4>) <unsigned integer>
+
+=item "rsa-coefficient5" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT5>) <unsigned integer>
+
+=item "rsa-coefficient6" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT6>) <unsigned integer>
+
+=item "rsa-coefficient7" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT7>) <unsigned integer>
+
+=item "rsa-coefficient8" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT8>) <unsigned integer>
+
+=item "rsa-coefficient9" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT9>) <unsigned integer>
+
+RSA CRT (Chinese Remainder Theorem) coefficients. The coefficients are known as
+"qInv" and "t_i".
+Up to eight additional "t_i" exponents are supported.
 
 =back
 
 
 =back
 
@@ -427,11 +481,13 @@ The private key value.
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure.
 
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure.
 
-Parameters currently recognised by built-in keymgmt algorithms
-are as follows.
+The Built-in Import/Export Types listed above are also Information Parameters.
 Not all parameters are relevant to, or are understood by all keymgmt
 algorithms:
 
 Not all parameters are relevant to, or are understood by all keymgmt
 algorithms:
 
+Parameters currently recognised by built-in keymgmt algorithms
+also include the following.
+
 =over 4
 
 =item "bits" (B<OSSL_PKEY_PARAM_BITS>) <integer>
 =over 4
 
 =item "bits" (B<OSSL_PKEY_PARAM_BITS>) <integer>
index a92e666a3db8f87b99c31cc6b78bbc608ba1d6e1..3a85510be07bfe8b8054fbeb24362ca30741dec4 100644 (file)
@@ -40,4 +40,8 @@ int int_rsa_verify(int dtype, const unsigned char *m,
 const unsigned char *rsa_digestinfo_encoding(int md_nid, size_t *len);
 const unsigned char *rsa_algorithmidentifier_encoding(int md_nid, size_t *len);
 
 const unsigned char *rsa_digestinfo_encoding(int md_nid, size_t *len);
 const unsigned char *rsa_algorithmidentifier_encoding(int md_nid, size_t *len);
 
+extern const char *rsa_mp_factor_names[];
+extern const char *rsa_mp_exp_names[];
+extern const char *rsa_mp_coeff_names[];
+
 #endif
 #endif
diff --git a/include/internal/param_build_set.h b/include/internal/param_build_set.h
new file mode 100644 (file)
index 0000000..36d3b91
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/safestack.h>
+#include <openssl/param_build.h>
+
+int ossl_param_build_set_int(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                             const char *key, int num);
+int ossl_param_build_set_utf8_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                     const char *key, const char *buf);
+int ossl_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                      const char *key,
+                                      const unsigned char *data,
+                                      size_t data_len);
+int ossl_param_build_set_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                            const char *key, const BIGNUM *bn);
+int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                const char *key, const BIGNUM *bn,  size_t sz);
+int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                      const char *names[],
+                                      STACK_OF(BIGNUM_const) *stk);
index 2d48f00da249106698e9ae641b73c176cdc7605a..c8a88285d8bce28aa6c970d4b1473fa49298de55 100644 (file)
@@ -220,6 +220,37 @@ extern "C" {
 #define OSSL_PKEY_PARAM_RSA_FACTOR      "rsa-factor"
 #define OSSL_PKEY_PARAM_RSA_EXPONENT    "rsa-exponent"
 #define OSSL_PKEY_PARAM_RSA_COEFFICIENT "rsa-coefficient"
 #define OSSL_PKEY_PARAM_RSA_FACTOR      "rsa-factor"
 #define OSSL_PKEY_PARAM_RSA_EXPONENT    "rsa-exponent"
 #define OSSL_PKEY_PARAM_RSA_COEFFICIENT "rsa-coefficient"
+#define OSSL_PKEY_PARAM_RSA_FACTOR1      OSSL_PKEY_PARAM_RSA_FACTOR"1"
+#define OSSL_PKEY_PARAM_RSA_FACTOR2      OSSL_PKEY_PARAM_RSA_FACTOR"2"
+#define OSSL_PKEY_PARAM_RSA_FACTOR3      OSSL_PKEY_PARAM_RSA_FACTOR"3"
+#define OSSL_PKEY_PARAM_RSA_FACTOR4      OSSL_PKEY_PARAM_RSA_FACTOR"4"
+#define OSSL_PKEY_PARAM_RSA_FACTOR5      OSSL_PKEY_PARAM_RSA_FACTOR"5"
+#define OSSL_PKEY_PARAM_RSA_FACTOR6      OSSL_PKEY_PARAM_RSA_FACTOR"6"
+#define OSSL_PKEY_PARAM_RSA_FACTOR7      OSSL_PKEY_PARAM_RSA_FACTOR"7"
+#define OSSL_PKEY_PARAM_RSA_FACTOR8      OSSL_PKEY_PARAM_RSA_FACTOR"8"
+#define OSSL_PKEY_PARAM_RSA_FACTOR9      OSSL_PKEY_PARAM_RSA_FACTOR"9"
+#define OSSL_PKEY_PARAM_RSA_FACTOR10     OSSL_PKEY_PARAM_RSA_FACTOR"10"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT1    OSSL_PKEY_PARAM_RSA_EXPONENT"1"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT2    OSSL_PKEY_PARAM_RSA_EXPONENT"2"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT3    OSSL_PKEY_PARAM_RSA_EXPONENT"3"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT4    OSSL_PKEY_PARAM_RSA_EXPONENT"4"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT5    OSSL_PKEY_PARAM_RSA_EXPONENT"5"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT6    OSSL_PKEY_PARAM_RSA_EXPONENT"6"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT7    OSSL_PKEY_PARAM_RSA_EXPONENT"7"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT8    OSSL_PKEY_PARAM_RSA_EXPONENT"8"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT9    OSSL_PKEY_PARAM_RSA_EXPONENT"9"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT10   OSSL_PKEY_PARAM_RSA_EXPONENT"10"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT1 OSSL_PKEY_PARAM_RSA_COEFFICIENT"1"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT2 OSSL_PKEY_PARAM_RSA_COEFFICIENT"2"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT3 OSSL_PKEY_PARAM_RSA_COEFFICIENT"3"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT4 OSSL_PKEY_PARAM_RSA_COEFFICIENT"4"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT5 OSSL_PKEY_PARAM_RSA_COEFFICIENT"5"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT6 OSSL_PKEY_PARAM_RSA_COEFFICIENT"6"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT7 OSSL_PKEY_PARAM_RSA_COEFFICIENT"7"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT8 OSSL_PKEY_PARAM_RSA_COEFFICIENT"8"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT9 OSSL_PKEY_PARAM_RSA_COEFFICIENT"9"
+
+
 /* Key generation parameters */
 #define OSSL_PKEY_PARAM_RSA_BITS        OSSL_PKEY_PARAM_BITS
 #define OSSL_PKEY_PARAM_RSA_PRIMES      "primes"
 /* Key generation parameters */
 #define OSSL_PKEY_PARAM_RSA_BITS        OSSL_PKEY_PARAM_BITS
 #define OSSL_PKEY_PARAM_RSA_PRIMES      "primes"
index d461f24999c98f71df431e3c1b04ef0d6381ee3c..4903fc5f4233d2315d0d1aea2543764b34d7b904 100644 (file)
@@ -1593,6 +1593,16 @@ int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM param[]);
 const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx);
 const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM param[]);
 const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx);
 const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx);
+const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey);
+int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out);
+int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out);
+int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn);
+int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
+                                    char *str, size_t max_buf_sz, size_t *out_sz);
+int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
+                                    unsigned char *buf, size_t max_buf_sz,
+                                    size_t *out_sz);
+
 int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
 int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
 int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
index 89d33e32f0f8c70bdaf1fb74a8656d41a66cecf3..92cac52e1171c970e62e41494cfb5cce8255ff81 100644 (file)
@@ -4,7 +4,6 @@
 $DH_GOAL=../../libimplementations.a
 $DSA_GOAL=../../libimplementations.a
 $EC_GOAL=../../libimplementations.a
 $DH_GOAL=../../libimplementations.a
 $DSA_GOAL=../../libimplementations.a
 $EC_GOAL=../../libimplementations.a
-$RSA_GOAL=../../libimplementations.a
 $ECX_GOAL=../../libimplementations.a
 
 IF[{- !$disabled{dh} -}]
 $ECX_GOAL=../../libimplementations.a
 
 IF[{- !$disabled{dh} -}]
@@ -16,7 +15,9 @@ ENDIF
 IF[{- !$disabled{ec} -}]
   SOURCE[$EC_GOAL]=ec_kmgmt.c
 ENDIF
 IF[{- !$disabled{ec} -}]
   SOURCE[$EC_GOAL]=ec_kmgmt.c
 ENDIF
-SOURCE[$RSA_GOAL]=rsa_kmgmt.c
 IF[{- !$disabled{ec} -}]
   SOURCE[$ECX_GOAL]=ecx_kmgmt.c
 ENDIF
 IF[{- !$disabled{ec} -}]
   SOURCE[$ECX_GOAL]=ecx_kmgmt.c
 ENDIF
+
+SOURCE[../../libfips.a]=rsa_kmgmt.c
+SOURCE[../../libnonfips.a]=rsa_kmgmt.c
index 82ef3d3a67818baff3ee2b9400429839e131ea63..77d4753723d5e8625aed7543d62db736ff9e7e36 100644 (file)
 #include <openssl/core_names.h>
 #include <openssl/bn.h>
 #include <openssl/objects.h>
 #include <openssl/core_names.h>
 #include <openssl/bn.h>
 #include <openssl/objects.h>
-#include <openssl/params.h>
 #include "crypto/bn.h"
 #include "crypto/ec.h"
 #include "crypto/bn.h"
 #include "crypto/ec.h"
-#include "openssl/param_build.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
+#include "internal/param_build_set.h"
 
 static OSSL_OP_keymgmt_new_fn ec_newdata;
 static OSSL_OP_keymgmt_free_fn ec_freedata;
 
 static OSSL_OP_keymgmt_new_fn ec_newdata;
 static OSSL_OP_keymgmt_free_fn ec_freedata;
@@ -40,8 +39,8 @@ static OSSL_OP_keymgmt_export_fn ec_export;
 static OSSL_OP_keymgmt_export_types_fn ec_export_types;
 static OSSL_OP_keymgmt_query_operation_name_fn ec_query_operation_name;
 
 static OSSL_OP_keymgmt_export_types_fn ec_export_types;
 static OSSL_OP_keymgmt_query_operation_name_fn ec_query_operation_name;
 
-#define EC_POSSIBLE_SELECTIONS                 \
-    (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS )
+#define EC_POSSIBLE_SELECTIONS                                                 \
+    (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS)
 
 static
 const char *ec_query_operation_name(int operation_id)
 
 static
 const char *ec_query_operation_name(int operation_id)
@@ -56,7 +55,8 @@ const char *ec_query_operation_name(int operation_id)
 }
 
 static ossl_inline
 }
 
 static ossl_inline
-int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
+int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
+                        OSSL_PARAM params[])
 {
     const EC_GROUP *ecg;
     int curve_nid;
 {
     const EC_GROUP *ecg;
     int curve_nid;
@@ -71,11 +71,7 @@ int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
     curve_nid = EC_GROUP_get_curve_name(ecg);
 
     if (curve_nid == NID_undef) {
     curve_nid = EC_GROUP_get_curve_name(ecg);
 
     if (curve_nid == NID_undef) {
-        /* explicit parameters */
-
-        /*
-         * TODO(3.0): should we support explicit parameters curves?
-         */
+        /* TODO(3.0): should we support explicit parameters curves? */
         return 0;
     } else {
         /* named curve */
         return 0;
     } else {
         /* named curve */
@@ -83,9 +79,10 @@ int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
 
         if ((curve_name = ec_curve_nid2name(curve_nid)) == NULL)
             return 0;
 
         if ((curve_name = ec_curve_nid2name(curve_nid)) == NULL)
             return 0;
+        if (!ossl_param_build_set_utf8_string(tmpl, params,
+                                              OSSL_PKEY_PARAM_EC_NAME,
+                                              curve_name))
 
 
-        if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_EC_NAME,
-                                             curve_name, 0))
             return 0;
     }
 
             return 0;
     }
 
@@ -100,12 +97,13 @@ int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
  * parameters are exported separately.
  */
 static ossl_inline
  * parameters are exported separately.
  */
 static ossl_inline
-int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, int include_private)
+int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
+                  OSSL_PARAM params[], int include_private,
+                  unsigned char **pub_key)
 {
     const BIGNUM *priv_key = NULL;
     const EC_POINT *pub_point = NULL;
     const EC_GROUP *ecg = NULL;
 {
     const BIGNUM *priv_key = NULL;
     const EC_POINT *pub_point = NULL;
     const EC_GROUP *ecg = NULL;
-    unsigned char *pub_key = NULL;
     size_t pub_key_len = 0;
     int ret = 0;
 
     size_t pub_key_len = 0;
     int ret = 0;
 
@@ -120,10 +118,10 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, int include_private
         /* convert pub_point to a octet string according to the SECG standard */
         if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
                                               POINT_CONVERSION_COMPRESSED,
         /* convert pub_point to a octet string according to the SECG standard */
         if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
                                               POINT_CONVERSION_COMPRESSED,
-                                              &pub_key, NULL)) == 0
-            || !OSSL_PARAM_BLD_push_octet_string(tmpl,
-                                                 OSSL_PKEY_PARAM_PUB_KEY,
-                                                 pub_key, pub_key_len))
+                                              pub_key, NULL)) == 0
+            || !ossl_param_build_set_octet_string(tmpl, params,
+                                                  OSSL_PKEY_PARAM_PUB_KEY,
+                                                  *pub_key, pub_key_len))
             goto err;
     }
 
             goto err;
     }
 
@@ -168,21 +166,20 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, int include_private
         if (ecbits <= 0)
             goto err;
         sz = (ecbits + 7 ) / 8;
         if (ecbits <= 0)
             goto err;
         sz = (ecbits + 7 ) / 8;
-        if (!OSSL_PARAM_BLD_push_BN_pad(tmpl,
-                                        OSSL_PKEY_PARAM_PRIV_KEY,
-                                        priv_key, sz))
+
+        if (!ossl_param_build_set_bn_pad(tmpl, params,
+                                         OSSL_PKEY_PARAM_PRIV_KEY,
+                                         priv_key, sz))
             goto err;
     }
             goto err;
     }
-
     ret = 1;
     ret = 1;
-
  err:
  err:
-    OPENSSL_free(pub_key);
     return ret;
 }
 
 static ossl_inline
     return ret;
 }
 
 static ossl_inline
-int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
+int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
+                          OSSL_PARAM params[])
 {
     int ecdh_cofactor_mode = 0;
 
 {
     int ecdh_cofactor_mode = 0;
 
@@ -191,12 +188,9 @@ int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
 
     ecdh_cofactor_mode =
         (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
 
     ecdh_cofactor_mode =
         (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
-    if (!OSSL_PARAM_BLD_push_int(tmpl,
-                OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
-                ecdh_cofactor_mode))
-        return 0;
-
-    return 1;
+    return ossl_param_build_set_int(tmpl, params,
+                                    OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
+                                    ecdh_cofactor_mode);
 }
 
 static
 }
 
 static
@@ -314,6 +308,7 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
     EC_KEY *ec = keydata;
     OSSL_PARAM_BLD *tmpl;
     OSSL_PARAM *params = NULL;
     EC_KEY *ec = keydata;
     OSSL_PARAM_BLD *tmpl;
     OSSL_PARAM *params = NULL;
+    unsigned char *pub_key = NULL;
     int ok = 1;
 
     if (ec == NULL)
     int ok = 1;
 
     if (ec == NULL)
@@ -346,15 +341,16 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
         return 0;
 
     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
         return 0;
 
     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
-        ok = ok && domparams_to_params(ec, tmpl);
+        ok = ok && domparams_to_params(ec, tmpl, NULL);
+
     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
         int include_private =
             selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
 
     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
         int include_private =
             selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
 
-        ok = ok && key_to_params(ec, tmpl, include_private);
+        ok = ok && key_to_params(ec, tmpl, NULL, include_private, &pub_key);
     }
     if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
     }
     if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
-        ok = ok && otherparams_to_params(ec, tmpl);
+        ok = ok && otherparams_to_params(ec, tmpl, NULL);
 
     if (!ok
         || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
 
     if (!ok
         || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
@@ -364,6 +360,7 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
     OSSL_PARAM_BLD_free_params(params);
 err:
     OSSL_PARAM_BLD_free(tmpl);
     OSSL_PARAM_BLD_free_params(params);
 err:
     OSSL_PARAM_BLD_free(tmpl);
+    OPENSSL_free(pub_key);
     return ok;
 }
 
     return ok;
 }
 
@@ -423,9 +420,11 @@ const OSSL_PARAM *ec_export_types(int selection)
 static
 int ec_get_params(void *key, OSSL_PARAM params[])
 {
 static
 int ec_get_params(void *key, OSSL_PARAM params[])
 {
+    int ret;
     EC_KEY *eck = key;
     const EC_GROUP *ecg = NULL;
     OSSL_PARAM *p;
     EC_KEY *eck = key;
     const EC_GROUP *ecg = NULL;
     OSSL_PARAM *p;
+    unsigned char *pub_key = NULL;
 
     ecg = EC_KEY_get0_group(eck);
     if (ecg == NULL)
 
     ecg = EC_KEY_get0_group(eck);
     if (ecg == NULL)
@@ -485,15 +484,21 @@ int ec_get_params(void *key, OSSL_PARAM params[])
         if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode))
             return 0;
     }
         if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode))
             return 0;
     }
-
-    return 1;
+    ret = domparams_to_params(eck, NULL, params)
+          && key_to_params(eck, NULL, params, 1, &pub_key)
+          && otherparams_to_params(eck, NULL, params);
+    OPENSSL_free(pub_key);
+    return ret;
 }
 
 static const OSSL_PARAM ec_known_gettable_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
 }
 
 static const OSSL_PARAM ec_known_gettable_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
+    EC_IMEXPORTABLE_DOM_PARAMETERS,
+    EC_IMEXPORTABLE_PUBLIC_KEY,
+    EC_IMEXPORTABLE_PRIVATE_KEY,
+    EC_IMEXPORTABLE_OTHER_PARAMETERS,
     OSSL_PARAM_END
 };
 
     OSSL_PARAM_END
 };
 
index be11f0b85e23b8626cf2b6f198bdbee08bf1b606..ca53a93f5ec8e644f80086cad8d0563a24a85599 100644 (file)
 #include <assert.h>
 #include <openssl/core_numbers.h>
 #include <openssl/core_names.h>
 #include <assert.h>
 #include <openssl/core_numbers.h>
 #include <openssl/core_names.h>
-#include <openssl/params.h>
-#include "openssl/param_build.h"
 #include "crypto/ecx.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
 #include "crypto/ecx.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
+#include "internal/param_build_set.h"
 
 static OSSL_OP_keymgmt_new_fn x25519_new_key;
 static OSSL_OP_keymgmt_new_fn x448_new_key;
 
 static OSSL_OP_keymgmt_new_fn x25519_new_key;
 static OSSL_OP_keymgmt_new_fn x448_new_key;
@@ -90,18 +89,21 @@ static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
     return ok;
 }
 
     return ok;
 }
 
-static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl)
+static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
+                         OSSL_PARAM params[])
 {
     if (key == NULL)
         return 0;
 
 {
     if (key == NULL)
         return 0;
 
-    if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
-                                          key->pubkey, key->keylen))
+    if (!ossl_param_build_set_octet_string(tmpl, params,
+                                           OSSL_PKEY_PARAM_PUB_KEY,
+                                           key->pubkey, key->keylen))
         return 0;
 
     if (key->privkey != NULL
         return 0;
 
     if (key->privkey != NULL
-        && !OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
-                                             key->privkey, key->keylen))
+        && !ossl_param_build_set_octet_string(tmpl, params,
+                                              OSSL_PKEY_PARAM_PRIV_KEY,
+                                              key->privkey, key->keylen))
         return 0;
 
     return 1;
         return 0;
 
     return 1;
@@ -113,7 +115,7 @@ static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
     ECX_KEY *key = keydata;
     OSSL_PARAM_BLD *tmpl;
     OSSL_PARAM *params = NULL;
     ECX_KEY *key = keydata;
     OSSL_PARAM_BLD *tmpl;
     OSSL_PARAM *params = NULL;
-    int ret;
+    int ret = 0;
 
     if (key == NULL)
         return 0;
 
     if (key == NULL)
         return 0;
@@ -123,24 +125,30 @@ static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
         return 0;
 
     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
         return 0;
 
     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
-            && !key_to_params(key, tmpl)) {
-        OSSL_PARAM_BLD_free(tmpl);
-        return 0;
-    }
+         && !key_to_params(key, tmpl, NULL))
+        goto err;
+
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
+         && !key_to_params(key, tmpl, NULL))
+        goto err;
 
     params = OSSL_PARAM_BLD_to_param(tmpl);
 
     params = OSSL_PARAM_BLD_to_param(tmpl);
-    OSSL_PARAM_BLD_free(tmpl);
     if (params == NULL)
     if (params == NULL)
-        return 0;
+        goto err;
 
     ret = param_cb(params, cbarg);
     OSSL_PARAM_BLD_free_params(params);
 
     ret = param_cb(params, cbarg);
     OSSL_PARAM_BLD_free_params(params);
+err:
+    OSSL_PARAM_BLD_free(tmpl);
     return ret;
 }
 
     return ret;
 }
 
+#define ECX_KEY_TYPES()                                                        \
+OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),                     \
+OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
+
 static const OSSL_PARAM ecx_key_types[] = {
 static const OSSL_PARAM ecx_key_types[] = {
-    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
-    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+    ECX_KEY_TYPES(),
     OSSL_PARAM_END
 };
 static const OSSL_PARAM *ecx_imexport_types(int selection)
     OSSL_PARAM_END
 };
 static const OSSL_PARAM *ecx_imexport_types(int selection)
@@ -150,9 +158,10 @@ static const OSSL_PARAM *ecx_imexport_types(int selection)
     return NULL;
 }
 
     return NULL;
 }
 
-static int ecx_get_params(OSSL_PARAM params[], int bits, int secbits,
+static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
                           int size)
 {
                           int size)
 {
+    ECX_KEY *ecx = key;
     OSSL_PARAM *p;
 
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
     OSSL_PARAM *p;
 
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
@@ -164,33 +173,38 @@ static int ecx_get_params(OSSL_PARAM params[], int bits, int secbits,
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
         && !OSSL_PARAM_set_int(p, size))
         return 0;
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
         && !OSSL_PARAM_set_int(p, size))
         return 0;
-    return 1;
+    return key_to_params(ecx, NULL, params);
 }
 
 static int x25519_get_params(void *key, OSSL_PARAM params[])
 {
 }
 
 static int x25519_get_params(void *key, OSSL_PARAM params[])
 {
-    return ecx_get_params(params, X25519_BITS, X25519_SECURITY_BITS, X25519_KEYLEN);
+    return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
+                          X25519_KEYLEN);
 }
 
 static int x448_get_params(void *key, OSSL_PARAM params[])
 {
 }
 
 static int x448_get_params(void *key, OSSL_PARAM params[])
 {
-    return ecx_get_params(params, X448_BITS, X448_SECURITY_BITS, X448_KEYLEN);
+    return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
+                          X448_KEYLEN);
 }
 
 static int ed25519_get_params(void *key, OSSL_PARAM params[])
 {
 }
 
 static int ed25519_get_params(void *key, OSSL_PARAM params[])
 {
-    return ecx_get_params(params, ED25519_BITS, ED25519_SECURITY_BITS, ED25519_KEYLEN);
+    return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
+                          ED25519_KEYLEN);
 }
 
 static int ed448_get_params(void *key, OSSL_PARAM params[])
 {
 }
 
 static int ed448_get_params(void *key, OSSL_PARAM params[])
 {
-    return ecx_get_params(params, ED448_BITS, ED448_SECURITY_BITS, ED448_KEYLEN);
+    return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
+                          ED448_KEYLEN);
 }
 
 static const OSSL_PARAM ecx_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
 }
 
 static const OSSL_PARAM ecx_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
+    ECX_KEY_TYPES(),
     OSSL_PARAM_END
 };
 
     OSSL_PARAM_END
 };
 
index 50647eb6f5650b849eab96b50a3c655d7f41e05b..8ea394115b43990f1133a28fa106c8cd1ac5506b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #include <openssl/err.h>
 #include <openssl/rsa.h>
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <openssl/rsa.h>
 #include <openssl/evp.h>
-#include <openssl/params.h>
-#include <openssl/types.h>
-#include "openssl/param_build.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
 #include "crypto/rsa.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
 #include "crypto/rsa.h"
+#include "internal/param_build_set.h"
 
 static OSSL_OP_keymgmt_new_fn rsa_newdata;
 static OSSL_OP_keymgmt_gen_init_fn rsa_gen_init;
 
 static OSSL_OP_keymgmt_new_fn rsa_newdata;
 static OSSL_OP_keymgmt_gen_init_fn rsa_gen_init;
@@ -45,32 +43,13 @@ static OSSL_OP_keymgmt_export_fn rsa_export;
 static OSSL_OP_keymgmt_export_types_fn rsa_export_types;
 
 #define RSA_DEFAULT_MD "SHA256"
 static OSSL_OP_keymgmt_export_types_fn rsa_export_types;
 
 #define RSA_DEFAULT_MD "SHA256"
-#define RSA_POSSIBLE_SELECTIONS                 \
+#define RSA_POSSIBLE_SELECTIONS                                                \
     (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
 
 DEFINE_STACK_OF(BIGNUM)
 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
 
     (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
 
 DEFINE_STACK_OF(BIGNUM)
 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
 
-static int export_numbers(OSSL_PARAM_BLD *tmpl, const char *key,
-                          STACK_OF(BIGNUM_const) *numbers)
-{
-    int i, nnum;
-
-    if (numbers == NULL)
-        return 0;
-
-    nnum = sk_BIGNUM_const_num(numbers);
-
-    for (i = 0; i < nnum; i++) {
-        if (!OSSL_PARAM_BLD_push_BN(tmpl, key,
-                                    sk_BIGNUM_const_value(numbers, i)))
-            return 0;
-    }
-
-    return 1;
-}
-
-static int key_to_params(RSA *rsa, OSSL_PARAM_BLD *tmpl)
+static int key_to_params(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
 {
     int ret = 0;
     const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
 {
     int ret = 0;
     const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
@@ -84,21 +63,16 @@ static int key_to_params(RSA *rsa, OSSL_PARAM_BLD *tmpl)
     RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
     rsa_get0_all_params(rsa, factors, exps, coeffs);
 
     RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
     rsa_get0_all_params(rsa, factors, exps, coeffs);
 
-    if (rsa_n != NULL
-        && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, rsa_n))
-        goto err;
-    if (rsa_e != NULL
-        && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, rsa_e))
-        goto err;
-    if (rsa_d != NULL
-        && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_D, rsa_d))
-        goto err;
-
-    if (!export_numbers(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR, factors)
-        || !export_numbers(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT, exps)
-        || !export_numbers(tmpl, OSSL_PKEY_PARAM_RSA_COEFFICIENT, coeffs))
+    if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_N, rsa_n)
+        || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_E, rsa_e)
+        || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_D, rsa_d)
+        || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_factor_names,
+                                              factors)
+        || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_exp_names,
+                                              exps)
+        || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_coeff_names,
+                                              coeffs))
         goto err;
         goto err;
-
     ret = 1;
  err:
     sk_BIGNUM_const_free(factors);
     ret = 1;
  err:
     sk_BIGNUM_const_free(factors);
@@ -189,20 +163,70 @@ static int rsa_export(void *keydata, int selection,
         return 0;
 
     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
         return 0;
 
     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
-        ok = ok && key_to_params(rsa, tmpl);
+        ok = ok && key_to_params(rsa, tmpl, NULL);
 
     if (!ok
 
     if (!ok
-        || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
-        OSSL_PARAM_BLD_free(tmpl);
-        return 0;
-    }
-    OSSL_PARAM_BLD_free(tmpl);
+        || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
+        goto err;
 
     ok = param_callback(params, cbarg);
     OSSL_PARAM_BLD_free_params(params);
 
     ok = param_callback(params, cbarg);
     OSSL_PARAM_BLD_free_params(params);
+err:
+    OSSL_PARAM_BLD_free(tmpl);
     return ok;
 }
 
     return ok;
 }
 
+#ifdef FIPS_MODE
+/* In fips mode there are no multi-primes. */
+# define RSA_KEY_MP_TYPES()                                                    \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR1, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR2, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT2, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0),
+#else
+/*
+ * We allow up to 10 prime factors (starting with p, q).
+ * NOTE: there is only 9 OSSL_PKEY_PARAM_RSA_COEFFICIENT
+ */
+# define RSA_KEY_MP_TYPES()                                                    \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR1, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR2, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR3, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR4, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR5, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR6, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR7, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR8, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR9, NULL, 0),                           \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR10, NULL, 0),                          \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT2, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT3, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT4, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT5, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT6, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT7, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT8, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT9, NULL, 0),                         \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT10, NULL, 0),                        \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0),                      \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT2, NULL, 0),                      \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT3, NULL, 0),                      \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT4, NULL, 0),                      \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT5, NULL, 0),                      \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT6, NULL, 0),                      \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT7, NULL, 0),                      \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT8, NULL, 0),                      \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT9, NULL, 0),
+#endif
+
+#define RSA_KEY_TYPES()                                                        \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, NULL, 0),                                 \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0),                                 \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_D, NULL, 0),                                 \
+RSA_KEY_MP_TYPES()
+
 /*
  * This provider can export everything in an RSA key, so we use the exact
  * same type description for export as for import.  Other providers might
 /*
  * This provider can export everything in an RSA key, so we use the exact
  * same type description for export as for import.  Other providers might
@@ -211,41 +235,8 @@ static int rsa_export(void *keydata, int selection,
  * different arrays.
  */
 static const OSSL_PARAM rsa_key_types[] = {
  * different arrays.
  */
 static const OSSL_PARAM rsa_key_types[] = {
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_D, NULL, 0),
-    /* We tolerate up to 10 factors... */
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
-    /* ..., up to 10 CRT exponents... */
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
-    /* ..., and up to 9 CRT coefficients */
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
+    RSA_KEY_TYPES()
+    OSSL_PARAM_END
 };
 /*
  * We lied about the amount of factors, exponents and coefficients, the
 };
 /*
  * We lied about the amount of factors, exponents and coefficients, the
@@ -266,7 +257,6 @@ static const OSSL_PARAM *rsa_import_types(int selection)
     return rsa_imexport_types(selection);
 }
 
     return rsa_imexport_types(selection);
 }
 
-
 static const OSSL_PARAM *rsa_export_types(int selection)
 {
     return rsa_imexport_types(selection);
 static const OSSL_PARAM *rsa_export_types(int selection)
 {
     return rsa_imexport_types(selection);
@@ -312,8 +302,7 @@ static int rsa_get_params(void *key, OSSL_PARAM params[])
         if (!OSSL_PARAM_set_utf8_string(p, RSA_DEFAULT_MD))
             return 0;
     }
         if (!OSSL_PARAM_set_utf8_string(p, RSA_DEFAULT_MD))
             return 0;
     }
-
-    return 1;
+    return key_to_params(rsa, NULL, params);
 }
 
 static const OSSL_PARAM rsa_params[] = {
 }
 
 static const OSSL_PARAM rsa_params[] = {
@@ -321,6 +310,7 @@ static const OSSL_PARAM rsa_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
     OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
     OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
+    RSA_KEY_TYPES()
     OSSL_PARAM_END
 };
 
     OSSL_PARAM_END
 };
 
index ddc70749276aa401c0b5e9a8d5456a82bbb1c6ca..21898f9e3d4355bbba978940c70d4bbe07ec2489 100644 (file)
@@ -116,4 +116,3 @@ int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv)
     sk_BIGNUM_const_free(coeffs);
     return ret;
 }
     sk_BIGNUM_const_free(coeffs);
     return ret;
 }
-
index 6ba61c3cdaee271e6b3fe9bf603246202e38d9b0..9f8d0086f7b587644fa927895a3b85b974de1e2f 100644 (file)
@@ -7,6 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
  * https://www.openssl.org/source/license.html
  */
 
+#include <string.h> /* memset */
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/serializer.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/serializer.h>
@@ -260,7 +261,7 @@ static int test_print_key_using_serializer(const char *alg, const EVP_PKEY *pk)
 
 static int test_fromdata_rsa(void)
 {
 
 static int test_fromdata_rsa(void)
 {
-    int ret = 0;
+    int ret = 0, i;
     EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
     EVP_PKEY *pk = NULL, *copy_pk = NULL;
     /*
     EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
     EVP_PKEY *pk = NULL, *copy_pk = NULL;
     /*
@@ -283,13 +284,15 @@ static int test_fromdata_rsa(void)
         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_N, &key_numbers[N]),
         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_E, &key_numbers[E]),
         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_D, &key_numbers[D]),
         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_N, &key_numbers[N]),
         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_E, &key_numbers[E]),
         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_D, &key_numbers[D]),
-        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR, &key_numbers[P]),
-        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR, &key_numbers[Q]),
-        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT, &key_numbers[DP]),
-        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT, &key_numbers[DQ]),
-        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_COEFFICIENT, &key_numbers[QINV]),
+        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR1, &key_numbers[P]),
+        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR2, &key_numbers[Q]),
+        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT1, &key_numbers[DP]),
+        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT2, &key_numbers[DQ]),
+        OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &key_numbers[QINV]),
         OSSL_PARAM_END
     };
         OSSL_PARAM_END
     };
+    BIGNUM *bn = BN_new();
+    BIGNUM *bn_from = BN_new();
 
     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)))
         goto err;
 
     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)))
         goto err;
@@ -315,10 +318,17 @@ static int test_fromdata_rsa(void)
         || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
         goto err;
 
         || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
         goto err;
 
+    for (i = 0; fromdata_params[i].key != NULL; ++i) {
+        if (!TEST_true(BN_set_word(bn_from, key_numbers[i]))
+            || !TEST_true(EVP_PKEY_get_bn_param(pk, fromdata_params[i].key, &bn))
+            || !TEST_BN_eq(bn, bn_from))
+            goto err;
+    }
     ret = test_print_key_using_pem("RSA", pk)
           && test_print_key_using_serializer("RSA", pk);
     ret = test_print_key_using_pem("RSA", pk)
           && test_print_key_using_serializer("RSA", pk);
-
  err:
  err:
+    BN_free(bn_from);
+    BN_free(bn);
     EVP_PKEY_free(pk);
     EVP_PKEY_free(copy_pk);
     EVP_PKEY_CTX_free(key_ctx);
     EVP_PKEY_free(pk);
     EVP_PKEY_free(copy_pk);
     EVP_PKEY_CTX_free(key_ctx);
@@ -327,6 +337,59 @@ static int test_fromdata_rsa(void)
     return ret;
 }
 
     return ret;
 }
 
+static int test_evp_pkey_get_bn_param_large(void)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
+    EVP_PKEY *pk = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *fromdata_params = NULL;
+    BIGNUM *n = NULL, *e = NULL, *d = NULL, *n_out = NULL;
+    /*
+     * The buffer size chosen here for n_data larger than the buffer used
+     * internally in EVP_PKEY_get_bn_param.
+     */
+    static unsigned char n_data[2050];
+    static const unsigned char e_data[] = {
+        0x1, 0x00, 0x01
+    };
+    static const unsigned char d_data[]= {
+       0x99, 0x33, 0x13, 0x7b
+    };
+
+    /* N is a large buffer */
+    memset(n_data, 0xCE, sizeof(n_data));
+
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
+        || !TEST_ptr(n = BN_bin2bn(n_data, sizeof(n_data), NULL))
+        || !TEST_ptr(e = BN_bin2bn(e_data, sizeof(e_data), NULL))
+        || !TEST_ptr(d = BN_bin2bn(d_data, sizeof(d_data), NULL))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, d))
+        || !TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld))
+        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL))
+        || !TEST_true(EVP_PKEY_key_fromdata_init(ctx))
+        || !TEST_true(EVP_PKEY_fromdata(ctx, &pk, fromdata_params))
+        || !TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, ""))
+        || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &n_out))
+        || !TEST_BN_eq(n, n_out))
+        goto err;
+    ret = 1;
+ err:
+    BN_free(n_out);
+    BN_free(n);
+    BN_free(e);
+    BN_free(d);
+    EVP_PKEY_free(pk);
+    EVP_PKEY_CTX_free(key_ctx);
+    EVP_PKEY_CTX_free(ctx);
+    OSSL_PARAM_BLD_free_params(fromdata_params);
+    OSSL_PARAM_BLD_free(bld);
+    return ret;
+}
+
+
 #ifndef OPENSSL_NO_DH
 /* Array indexes used in test_fromdata_dh */
 #define PRIV_KEY        0
 #ifndef OPENSSL_NO_DH
 /* Array indexes used in test_fromdata_dh */
 #define PRIV_KEY        0
@@ -412,6 +475,9 @@ static int test_fromdata_ecx(int tst)
     EVP_PKEY_CTX *ctx = NULL;
     EVP_PKEY *pk = NULL, *copy_pk = NULL;
     const char *alg = NULL;
     EVP_PKEY_CTX *ctx = NULL;
     EVP_PKEY *pk = NULL, *copy_pk = NULL;
     const char *alg = NULL;
+    size_t len;
+    unsigned char out_pub[ED448_KEYLEN];
+    unsigned char out_priv[ED448_KEYLEN];
 
     /* ED448_KEYLEN > X448_KEYLEN > X25519_KEYLEN == ED25519_KEYLEN */
     static unsigned char key_numbers[4][2][ED448_KEYLEN] = {
 
     /* ED448_KEYLEN > X448_KEYLEN > X25519_KEYLEN == ED25519_KEYLEN */
     static unsigned char key_numbers[4][2][ED448_KEYLEN] = {
@@ -580,6 +646,20 @@ static int test_fromdata_ecx(int tst)
         || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
         goto err;
 
         || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
         goto err;
 
+    if (!TEST_true(EVP_PKEY_get_octet_string_param(
+                       pk, fromdata_params[PRIV_KEY].key,
+                       out_priv, sizeof(out_priv), &len))
+        || !TEST_mem_eq(out_priv, len,
+                        fromdata_params[PRIV_KEY].data,
+                        fromdata_params[PRIV_KEY].data_size)
+        || !TEST_true(EVP_PKEY_get_octet_string_param(
+                          pk, fromdata_params[PUB_KEY].key,
+                          out_pub, sizeof(out_pub), &len))
+        || !TEST_mem_eq(out_pub, len,
+                        fromdata_params[PUB_KEY].data,
+                        fromdata_params[PUB_KEY].data_size))
+        goto err;
+
     ret = test_print_key_using_pem(alg, pk)
           && test_print_key_using_serializer(alg, pk);
 
     ret = test_print_key_using_pem(alg, pk)
           && test_print_key_using_serializer(alg, pk);
 
@@ -591,6 +671,8 @@ err:
     return ret;
 }
 
     return ret;
 }
 
+#define CURVE_NAME 2
+
 static int test_fromdata_ec(void)
 {
     int ret = 0;
 static int test_fromdata_ec(void)
 {
     int ret = 0;
@@ -598,10 +680,13 @@ static int test_fromdata_ec(void)
     EVP_PKEY *pk = NULL, *copy_pk = NULL;
     OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
     BIGNUM *ec_priv_bn = NULL;
     EVP_PKEY *pk = NULL, *copy_pk = NULL;
     OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
     BIGNUM *ec_priv_bn = NULL;
+    BIGNUM *bn_priv = NULL;
     OSSL_PARAM *fromdata_params = NULL;
     const char *alg = "EC";
     OSSL_PARAM *fromdata_params = NULL;
     const char *alg = "EC";
+    const char *curve = "prime256v1";
+    /* UNCOMPRESSED FORMAT */
     static const unsigned char ec_pub_keydata[] = {
     static const unsigned char ec_pub_keydata[] = {
-       0x04,
+       POINT_CONVERSION_UNCOMPRESSED,
        0x1b, 0x93, 0x67, 0x55, 0x1c, 0x55, 0x9f, 0x63,
        0xd1, 0x22, 0xa4, 0xd8, 0xd1, 0x0a, 0x60, 0x6d,
        0x02, 0xa5, 0x77, 0x57, 0xc8, 0xa3, 0x47, 0x73,
        0x1b, 0x93, 0x67, 0x55, 0x1c, 0x55, 0x9f, 0x63,
        0xd1, 0x22, 0xa4, 0xd8, 0xd1, 0x0a, 0x60, 0x6d,
        0x02, 0xa5, 0x77, 0x57, 0xc8, 0xa3, 0x47, 0x73,
@@ -617,6 +702,12 @@ static int test_fromdata_ec(void)
         0xcc, 0x0d, 0x9a, 0x24, 0x6c, 0x86, 0x1b, 0x2e,
         0xdc, 0x4b, 0x4d, 0x35, 0x43, 0xe1, 0x1b, 0xad
     };
         0xcc, 0x0d, 0x9a, 0x24, 0x6c, 0x86, 0x1b, 0x2e,
         0xdc, 0x4b, 0x4d, 0x35, 0x43, 0xe1, 0x1b, 0xad
     };
+    const int compressed_sz = 1 + (sizeof(ec_pub_keydata) - 1) / 2;
+    unsigned char out_pub[sizeof(ec_pub_keydata)];
+    char out_curve_name[80];
+    const OSSL_PARAM *gettable = NULL;
+    size_t len;
+
 
     if (!TEST_ptr(bld))
         goto err;
 
     if (!TEST_ptr(bld))
         goto err;
@@ -625,7 +716,7 @@ static int test_fromdata_ec(void)
         goto err;
 
     if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_NAME,
         goto err;
 
     if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_NAME,
-                                        "prime256v1", 0) <= 0)
+                                        curve, 0) <= 0)
         goto err;
     if (OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY,
                                          ec_pub_keydata,
         goto err;
     if (OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY,
                                          ec_pub_keydata,
@@ -650,9 +741,30 @@ static int test_fromdata_ec(void)
         || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
         goto err;
 
         || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
         goto err;
 
+    if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pk))
+        || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_NAME))
+        || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_PUB_KEY))
+        || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_PRIV_KEY)))
+        goto err;
+
+    if (!EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_EC_NAME,
+                                        out_curve_name, sizeof(out_curve_name),
+                                        &len)
+        || !TEST_str_eq(out_curve_name, curve)
+        || !EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
+                                            out_pub, sizeof(out_pub), &len)
+        || !TEST_true(out_pub[0] == (POINT_CONVERSION_COMPRESSED + 1))
+        || !TEST_mem_eq(out_pub + 1, len - 1,
+                        ec_pub_keydata + 1, compressed_sz - 1)
+        || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY,
+                                            &bn_priv))
+        || !TEST_BN_eq(ec_priv_bn, bn_priv))
+        goto err;
+
     ret = test_print_key_using_pem(alg, pk)
           && test_print_key_using_serializer(alg, pk);
 err:
     ret = test_print_key_using_pem(alg, pk)
           && test_print_key_using_serializer(alg, pk);
 err:
+    BN_free(bn_priv);
     BN_free(ec_priv_bn);
     OSSL_PARAM_BLD_free_params(fromdata_params);
     OSSL_PARAM_BLD_free(bld);
     BN_free(ec_priv_bn);
     OSSL_PARAM_BLD_free_params(fromdata_params);
     OSSL_PARAM_BLD_free(bld);
@@ -674,6 +786,7 @@ int setup_tests(void)
     if (!TEST_ptr(datadir = test_get_argument(0)))
         return 0;
 
     if (!TEST_ptr(datadir = test_get_argument(0)))
         return 0;
 
+    ADD_TEST(test_evp_pkey_get_bn_param_large);
     ADD_TEST(test_fromdata_rsa);
 #ifndef OPENSSL_NO_DH
     ADD_TEST(test_fromdata_dh);
     ADD_TEST(test_fromdata_rsa);
 #ifndef OPENSSL_NO_DH
     ADD_TEST(test_fromdata_dh);
index fd60893a4559dd9a463e33f18b247a9d2686e4fa..d30b3a70afe1f1761ee235eccac6b361ca32502c 100644 (file)
@@ -66,7 +66,7 @@ static FIXTURE *set_up(const char *testcase_name)
 #define DQ      7
 #define E3      8                /* Extra exponent */
 #define QINV    9
 #define DQ      7
 #define E3      8                /* Extra exponent */
 #define QINV    9
-#define C3      10               /* Extra coefficient */
+#define C2      10               /* Extra coefficient */
 
 /*
  * We have to do this because OSSL_PARAM_get_ulong() can't handle params
 
 /*
  * We have to do this because OSSL_PARAM_get_ulong() can't handle params
@@ -92,10 +92,6 @@ static int export_cb(const OSSL_PARAM *params, void *arg)
 {
     unsigned long *keydata = arg;
     const OSSL_PARAM *p = NULL;
 {
     unsigned long *keydata = arg;
     const OSSL_PARAM *p = NULL;
-    int factors_idx;
-    int exponents_idx;
-    int coefficients_idx;
-    int ret = 1;                 /* Ever so hopeful */
 
     if (keydata == NULL)
         return 0;
 
     if (keydata == NULL)
         return 0;
@@ -106,35 +102,31 @@ static int export_cb(const OSSL_PARAM *params, void *arg)
         || !TEST_true(get_ulong_via_BN(p, &keydata[E]))
         || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D))
         || !TEST_true(get_ulong_via_BN(p, &keydata[D])))
         || !TEST_true(get_ulong_via_BN(p, &keydata[E]))
         || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D))
         || !TEST_true(get_ulong_via_BN(p, &keydata[D])))
-        ret = 0;
+        return 0;
 
 
-    for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR),
-             factors_idx = P;
-         p != NULL && factors_idx <= F3;
-         p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_FACTOR),
-         factors_idx++)
-        if (!TEST_true(get_ulong_via_BN(p, &keydata[factors_idx])))
-            ret = 0;
-    for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT),
-             exponents_idx = DP;
-         p != NULL && exponents_idx <= E3;
-         p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_EXPONENT),
-         exponents_idx++)
-        if (!TEST_true(get_ulong_via_BN(p, &keydata[exponents_idx])))
-            ret = 0;
-    for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT),
-             coefficients_idx = QINV;
-         p != NULL && coefficients_idx <= C3;
-         p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_COEFFICIENT),
-         coefficients_idx++)
-        if (!TEST_true(get_ulong_via_BN(p, &keydata[coefficients_idx])))
-            ret = 0;
-
-    if (!TEST_int_le(factors_idx, F3)
-        || !TEST_int_le(exponents_idx, E3)
-        || !TEST_int_le(coefficients_idx, C3))
-        ret = 0;
-    return ret;
+    if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR1))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[P]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR2))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[Q]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR3))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[F3])))
+        return 0;
+
+    if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT1))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[DP]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT2))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[DQ]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT3))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[E3])))
+        return 0;
+
+    if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT1))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[QINV]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT2))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[C2])))
+        return 0;
+
+    return 1;
 }
 
 static int test_pass_rsa(FIXTURE *fixture)
 }
 
 static int test_pass_rsa(FIXTURE *fixture)
@@ -146,9 +138,13 @@ static int test_pass_rsa(FIXTURE *fixture)
     EVP_PKEY *pk = NULL;
     EVP_KEYMGMT *km1 = NULL, *km2 = NULL;
     void *provkey = NULL;
     EVP_PKEY *pk = NULL;
     EVP_KEYMGMT *km1 = NULL, *km2 = NULL;
     void *provkey = NULL;
+    BIGNUM *bn_primes[1] = { NULL };
+    BIGNUM *bn_exps[1] = { NULL };
+    BIGNUM *bn_coeffs[1] = { NULL };
     /*
      * 32-bit RSA key, extracted from this command,
      * executed with OpenSSL 1.0.2:
     /*
      * 32-bit RSA key, extracted from this command,
      * executed with OpenSSL 1.0.2:
+     * An extra factor was added just for testing purposes.
      *
      * openssl genrsa 32 | openssl rsa -text
      */
      *
      * openssl genrsa 32 | openssl rsa -text
      */
@@ -158,12 +154,12 @@ static int test_pass_rsa(FIXTURE *fixture)
         0x7b133399,              /* D */
         0xe963,                  /* P */
         0xceb7,                  /* Q */
         0x7b133399,              /* D */
         0xe963,                  /* P */
         0xceb7,                  /* Q */
-        0,                       /* F3 */
+        1,                       /* F3 */
         0x8599,                  /* DP */
         0xbd87,                  /* DQ */
         0x8599,                  /* DP */
         0xbd87,                  /* DQ */
-        0,                       /* E3 */
+        2,                       /* E3 */
         0xcc3b,                  /* QINV */
         0xcc3b,                  /* QINV */
-        0,                       /* C3 */
+        3,                       /* C3 */
         0                        /* Extra, should remain zero */
     };
     static unsigned long keydata[OSSL_NELEM(expected)] = { 0, };
         0                        /* Extra, should remain zero */
     };
     static unsigned long keydata[OSSL_NELEM(expected)] = { 0, };
@@ -197,6 +193,16 @@ static int test_pass_rsa(FIXTURE *fixture)
         goto err;
     bn1 = bn2 = bn3 = NULL;
 
         goto err;
     bn1 = bn2 = bn3 = NULL;
 
+    if (!TEST_ptr(bn_primes[0] = BN_new())
+        || !TEST_true(BN_set_word(bn_primes[0], expected[F3]))
+        || !TEST_ptr(bn_exps[0] = BN_new())
+        || !TEST_true(BN_set_word(bn_exps[0], expected[E3]))
+        || !TEST_ptr(bn_coeffs[0] = BN_new())
+        || !TEST_true(BN_set_word(bn_coeffs[0], expected[C2]))
+        || !TEST_true(RSA_set0_multi_prime_params(rsa, bn_primes, bn_exps,
+                                                  bn_coeffs, 1)))
+        goto err;
+
     if (!TEST_ptr(pk = EVP_PKEY_new())
         || !TEST_true(EVP_PKEY_assign_RSA(pk, rsa)))
         goto err;
     if (!TEST_ptr(pk = EVP_PKEY_new())
         || !TEST_true(EVP_PKEY_assign_RSA(pk, rsa)))
         goto err;
index 9fc7cfcf184cc68f23aea82fa4537a1fe8af1745..cd0a7d806e653f5ad33fa2c89137e727a50ddfa4 100644 (file)
@@ -5030,3 +5030,9 @@ SRP_Calc_u_ex                           ? 3_0_0   EXIST::FUNCTION:SRP
 SRP_Calc_x_ex                           ?      3_0_0   EXIST::FUNCTION:SRP
 SRP_Calc_client_key_ex                  ?      3_0_0   EXIST::FUNCTION:SRP
 X509v3_cache_extensions                 ?      3_0_0   EXIST::FUNCTION:
 SRP_Calc_x_ex                           ?      3_0_0   EXIST::FUNCTION:SRP
 SRP_Calc_client_key_ex                  ?      3_0_0   EXIST::FUNCTION:SRP
 X509v3_cache_extensions                 ?      3_0_0   EXIST::FUNCTION:
+EVP_PKEY_gettable_params                ?      3_0_0   EXIST::FUNCTION:
+EVP_PKEY_get_int_param                  ?      3_0_0   EXIST::FUNCTION:
+EVP_PKEY_get_size_t_param               ?      3_0_0   EXIST::FUNCTION:
+EVP_PKEY_get_bn_param                   ?      3_0_0   EXIST::FUNCTION:
+EVP_PKEY_get_utf8_string_param          ?      3_0_0   EXIST::FUNCTION:
+EVP_PKEY_get_octet_string_param         ?      3_0_0   EXIST::FUNCTION: