summaryrefslogtreecommitdiffstats
path: root/crypto/rsa
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2021-04-07 19:35:13 +0200
committerTomas Mraz <tomas@openssl.org>2021-04-15 09:19:39 +0200
commit4a9fe33c8e12f4fefae0471c0834f8e674dc7e4e (patch)
tree479171af7347523257b843893173927cbbc6e572 /crypto/rsa
parentb9cd82f95bf99eab4e1b0420918e7139db091c4b (diff)
Implement provider-side keymgmt_dup function
To avoid mutating key data add OSSL_FUNC_KEYMGMT_DUP function to the provider API and implement it for all asym-key key managements. Use it when copying everything to an empty EVP_PKEY which is the case with EVP_PKEY_dup(). Fixes #14658 Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/14793)
Diffstat (limited to 'crypto/rsa')
-rw-r--r--crypto/rsa/rsa_ameth.c94
-rw-r--r--crypto/rsa/rsa_backend.c95
2 files changed, 96 insertions, 93 deletions
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index e633fa5c93..45e0000117 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -884,98 +884,6 @@ static int rsa_pss_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
return rsa_int_import_from(params, vpctx, RSA_FLAG_TYPE_RSASSAPSS);
}
-static ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f)
-{
- if (f != NULL && (*out = BN_dup(f)) == NULL)
- return 0;
- return 1;
-}
-
-static RSA *rsa_dup(const RSA *rsa)
-{
- RSA *dupkey = NULL;
- int pnum, i;
-
- /* Do not try to duplicate foreign RSA keys */
- if (RSA_get_method(rsa) != RSA_PKCS1_OpenSSL())
- return NULL;
-
- if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL)
- return NULL;
-
- /* private and public key */
- if (!rsa_bn_dup_check(&dupkey->n, rsa->n))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->e, rsa->e))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->d, rsa->d))
- goto err;
-
- /* factors and crt params */
- if (!rsa_bn_dup_check(&dupkey->p, rsa->p))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->q, rsa->q))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp))
- goto err;
-
- /* multiprime */
- pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos);
- if (pnum > 0) {
- dupkey->prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum);
- for (i = 0; i < pnum; i++) {
- const RSA_PRIME_INFO *pinfo = NULL;
- RSA_PRIME_INFO *duppinfo = NULL;
-
- if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) {
- ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- /* push first so cleanup in error case works */
- (void)sk_RSA_PRIME_INFO_push(dupkey->prime_infos, duppinfo);
-
- pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i);
- if (!rsa_bn_dup_check(&duppinfo->r, pinfo->r))
- goto err;
- if (!rsa_bn_dup_check(&duppinfo->d, pinfo->d))
- goto err;
- if (!rsa_bn_dup_check(&duppinfo->t, pinfo->t))
- goto err;
- }
- if (!ossl_rsa_multip_calc_product(dupkey))
- goto err;
- }
-
- dupkey->version = rsa->version;
- dupkey->flags = rsa->flags;
-
- dupkey->pss_params = rsa->pss_params;
-
- if (rsa->pss != NULL) {
- dupkey->pss = RSA_PSS_PARAMS_dup(rsa->pss);
- if (rsa->pss->maskGenAlgorithm != NULL
- && dupkey->pss->maskGenAlgorithm == NULL) {
- dupkey->pss->maskHash = ossl_x509_algor_mgf1_decode(rsa->pss->maskGenAlgorithm);
- if (dupkey->pss->maskHash == NULL)
- goto err;
- }
- }
-
- if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_RSA,
- &dupkey->ex_data, &rsa->ex_data))
- goto err;
-
- return dupkey;
-
- err:
- RSA_free(dupkey);
- return NULL;
-}
-
static int rsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
{
RSA *rsa = from->pkey.rsa;
@@ -983,7 +891,7 @@ static int rsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
int ret;
if (rsa != NULL) {
- dupkey = rsa_dup(rsa);
+ dupkey = ossl_rsa_dup(rsa);
if (dupkey == NULL)
return 0;
}
diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c
index 01ee875058..92be5f610a 100644
--- a/crypto/rsa/rsa_backend.c
+++ b/crypto/rsa/rsa_backend.c
@@ -22,6 +22,7 @@
#include "internal/param_build_set.h"
#include "crypto/asn1.h"
#include "crypto/rsa.h"
+#include "rsa_local.h"
#include "e_os.h" /* strcasecmp for Windows() */
@@ -322,6 +323,100 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params,
return ret;
}
+static ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f)
+{
+ if (f != NULL && (*out = BN_dup(f)) == NULL)
+ return 0;
+ return 1;
+}
+
+RSA *ossl_rsa_dup(const RSA *rsa)
+{
+ RSA *dupkey = NULL;
+#ifndef FIPS_MODULE
+ int pnum, i;
+
+ /* Do not try to duplicate foreign RSA keys */
+ if (RSA_get_method(rsa) != RSA_PKCS1_OpenSSL())
+ return NULL;
+#endif
+
+ if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL)
+ return NULL;
+
+ /* private and public key */
+ if (!rsa_bn_dup_check(&dupkey->n, rsa->n))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->e, rsa->e))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->d, rsa->d))
+ goto err;
+
+ /* factors and crt params */
+ if (!rsa_bn_dup_check(&dupkey->p, rsa->p))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->q, rsa->q))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp))
+ goto err;
+
+ dupkey->version = rsa->version;
+ dupkey->flags = rsa->flags;
+ dupkey->pss_params = rsa->pss_params;
+
+#ifndef FIPS_MODULE
+ /* multiprime */
+ pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos);
+ if (pnum > 0) {
+ dupkey->prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum);
+ for (i = 0; i < pnum; i++) {
+ const RSA_PRIME_INFO *pinfo = NULL;
+ RSA_PRIME_INFO *duppinfo = NULL;
+
+ if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) {
+ ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ /* push first so cleanup in error case works */
+ (void)sk_RSA_PRIME_INFO_push(dupkey->prime_infos, duppinfo);
+
+ pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i);
+ if (!rsa_bn_dup_check(&duppinfo->r, pinfo->r))
+ goto err;
+ if (!rsa_bn_dup_check(&duppinfo->d, pinfo->d))
+ goto err;
+ if (!rsa_bn_dup_check(&duppinfo->t, pinfo->t))
+ goto err;
+ }
+ if (!ossl_rsa_multip_calc_product(dupkey))
+ goto err;
+ }
+
+ if (rsa->pss != NULL) {
+ dupkey->pss = RSA_PSS_PARAMS_dup(rsa->pss);
+ if (rsa->pss->maskGenAlgorithm != NULL
+ && dupkey->pss->maskGenAlgorithm == NULL) {
+ dupkey->pss->maskHash = ossl_x509_algor_mgf1_decode(rsa->pss->maskGenAlgorithm);
+ if (dupkey->pss->maskHash == NULL)
+ goto err;
+ }
+ }
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_RSA,
+ &dupkey->ex_data, &rsa->ex_data))
+ goto err;
+#endif
+
+ return dupkey;
+
+ err:
+ RSA_free(dupkey);
+ return NULL;
+}
+
#ifndef FIPS_MODULE
RSA_PSS_PARAMS *ossl_rsa_pss_decode(const X509_ALGOR *alg)
{