mirror of https://github.com/openssl/openssl.git
				
				
				
			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)
This commit is contained in:
		
							parent
							
								
									b9cd82f95b
								
							
						
					
					
						commit
						4a9fe33c8e
					
				|  | @ -536,46 +536,6 @@ static int dhx_pkey_import_from(const OSSL_PARAM params[], void *vpctx) | |||
|     return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DHX); | ||||
| } | ||||
| 
 | ||||
| static ossl_inline int dh_bn_dup_check(BIGNUM **out, const BIGNUM *f) | ||||
| { | ||||
|     if (f != NULL && (*out = BN_dup(f)) == NULL) | ||||
|         return 0; | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static DH *dh_dup(const DH *dh) | ||||
| { | ||||
|     DH *dupkey = NULL; | ||||
| 
 | ||||
|     /* Do not try to duplicate foreign DH keys */ | ||||
|     if (ossl_dh_get_method(dh) != DH_OpenSSL()) | ||||
|         return NULL; | ||||
| 
 | ||||
|     if ((dupkey = ossl_dh_new_ex(dh->libctx)) == NULL) | ||||
|         return NULL; | ||||
| 
 | ||||
|     dupkey->length = DH_get_length(dh); | ||||
|     if (!ossl_ffc_params_copy(&dupkey->params, &dh->params)) | ||||
|         goto err; | ||||
| 
 | ||||
|     dupkey->flags = dh->flags; | ||||
| 
 | ||||
|     if (!dh_bn_dup_check(&dupkey->pub_key, dh->pub_key)) | ||||
|         goto err; | ||||
|     if (!dh_bn_dup_check(&dupkey->priv_key, dh->priv_key)) | ||||
|         goto err; | ||||
| 
 | ||||
|     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DH, | ||||
|                             &dupkey->ex_data, &dh->ex_data)) | ||||
|         goto err; | ||||
| 
 | ||||
|     return dupkey; | ||||
| 
 | ||||
|  err: | ||||
|     DH_free(dupkey); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static int dh_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) | ||||
| { | ||||
|     DH *dh = from->pkey.dh; | ||||
|  | @ -583,7 +543,7 @@ static int dh_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) | |||
|     int ret; | ||||
| 
 | ||||
|     if (dh != NULL) { | ||||
|         dupkey = dh_dup(dh); | ||||
|         dupkey = ossl_dh_dup(dh); | ||||
|         if (dupkey == NULL) | ||||
|             return 0; | ||||
|     } | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| #include <openssl/core_names.h> | ||||
| #include "internal/param_build_set.h" | ||||
| #include "crypto/dh.h" | ||||
| #include "dh_local.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * The intention with the "backend" source file is to offer backend functions | ||||
|  | @ -117,6 +118,49 @@ int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) | |||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static ossl_inline int dh_bn_dup_check(BIGNUM **out, const BIGNUM *f) | ||||
| { | ||||
|     if (f != NULL && (*out = BN_dup(f)) == NULL) | ||||
|         return 0; | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| DH *ossl_dh_dup(const DH *dh) | ||||
| { | ||||
|     DH *dupkey = NULL; | ||||
| 
 | ||||
| #ifndef FIPS_MODULE | ||||
|     /* Do not try to duplicate foreign DH keys */ | ||||
|     if (ossl_dh_get_method(dh) != DH_OpenSSL()) | ||||
|         return NULL; | ||||
| #endif | ||||
| 
 | ||||
|     if ((dupkey = ossl_dh_new_ex(dh->libctx)) == NULL) | ||||
|         return NULL; | ||||
| 
 | ||||
|     dupkey->length = DH_get_length(dh); | ||||
|     if (!ossl_ffc_params_copy(&dupkey->params, &dh->params)) | ||||
|         goto err; | ||||
| 
 | ||||
|     dupkey->flags = dh->flags; | ||||
| 
 | ||||
|     if (!dh_bn_dup_check(&dupkey->pub_key, dh->pub_key)) | ||||
|         goto err; | ||||
|     if (!dh_bn_dup_check(&dupkey->priv_key, dh->priv_key)) | ||||
|         goto err; | ||||
| 
 | ||||
| #ifndef FIPS_MODULE | ||||
|     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DH, | ||||
|                             &dupkey->ex_data, &dh->ex_data)) | ||||
|         goto err; | ||||
| #endif | ||||
| 
 | ||||
|     return dupkey; | ||||
| 
 | ||||
|  err: | ||||
|     DH_free(dupkey); | ||||
|     return NULL; | ||||
| } | ||||
| #ifndef FIPS_MODULE | ||||
| DH *ossl_dh_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, | ||||
|                            OSSL_LIB_CTX *libctx, const char *propq) | ||||
|  |  | |||
|  | @ -325,3 +325,5 @@ int ossl_dh_get0_nid(const DH *dh) | |||
| { | ||||
|     return dh->params.nid; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -500,45 +500,6 @@ static int dsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx) | |||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) | ||||
| { | ||||
|     if (f != NULL && (*out = BN_dup(f)) == NULL) | ||||
|         return 0; | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static DSA *dsa_dup(const DSA *dsa) | ||||
| { | ||||
|     DSA *dupkey = NULL; | ||||
| 
 | ||||
|     /* Do not try to duplicate foreign DSA keys */ | ||||
|     if (DSA_get_method((DSA *)dsa) != DSA_OpenSSL()) | ||||
|         return NULL; | ||||
| 
 | ||||
|     if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL) | ||||
|         return NULL; | ||||
| 
 | ||||
|     if (!ossl_ffc_params_copy(&dupkey->params, &dsa->params)) | ||||
|         goto err; | ||||
| 
 | ||||
|     dupkey->flags = dsa->flags; | ||||
| 
 | ||||
|     if (!dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key)) | ||||
|         goto err; | ||||
|     if (!dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key)) | ||||
|         goto err; | ||||
| 
 | ||||
|     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA, | ||||
|                             &dupkey->ex_data, &dsa->ex_data)) | ||||
|         goto err; | ||||
| 
 | ||||
|     return dupkey; | ||||
| 
 | ||||
|  err: | ||||
|     DSA_free(dupkey); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) | ||||
| { | ||||
|     DSA *dsa = from->pkey.dsa; | ||||
|  | @ -546,7 +507,7 @@ static int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) | |||
|     int ret; | ||||
| 
 | ||||
|     if (dsa != NULL) { | ||||
|         dupkey = dsa_dup(dsa); | ||||
|         dupkey = ossl_dsa_dup(dsa); | ||||
|         if (dupkey == NULL) | ||||
|             return 0; | ||||
|     } | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ | |||
| #include <openssl/core_names.h> | ||||
| #include <openssl/err.h> | ||||
| #include "crypto/dsa.h" | ||||
| #include "dsa_local.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * The intention with the "backend" source file is to offer backend support | ||||
|  | @ -56,6 +57,49 @@ int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[]) | |||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) | ||||
| { | ||||
|     if (f != NULL && (*out = BN_dup(f)) == NULL) | ||||
|         return 0; | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| DSA *ossl_dsa_dup(const DSA *dsa) | ||||
| { | ||||
|     DSA *dupkey = NULL; | ||||
| 
 | ||||
| #ifndef FIPS_MODULE | ||||
|     /* Do not try to duplicate foreign DSA keys */ | ||||
|     if (DSA_get_method((DSA *)dsa) != DSA_OpenSSL()) | ||||
|         return NULL; | ||||
| #endif | ||||
| 
 | ||||
|     if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL) | ||||
|         return NULL; | ||||
| 
 | ||||
|     if (!ossl_ffc_params_copy(&dupkey->params, &dsa->params)) | ||||
|         goto err; | ||||
| 
 | ||||
|     dupkey->flags = dsa->flags; | ||||
| 
 | ||||
|     if (!dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key)) | ||||
|         goto err; | ||||
|     if (!dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key)) | ||||
|         goto err; | ||||
| 
 | ||||
| #ifndef FIPS_MODULE | ||||
|     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA, | ||||
|                             &dupkey->ex_data, &dsa->ex_data)) | ||||
|         goto err; | ||||
| #endif | ||||
| 
 | ||||
|     return dupkey; | ||||
| 
 | ||||
|  err: | ||||
|     DSA_free(dupkey); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| #ifndef FIPS_MODULE | ||||
| DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, | ||||
|                              OSSL_LIB_CTX *libctx, const char *propq) | ||||
|  |  | |||
|  | @ -358,3 +358,4 @@ int ossl_dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]) | |||
|         dsa->dirty_cnt++; | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -92,6 +92,49 @@ int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], | |||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key) | ||||
| { | ||||
|     ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); | ||||
| 
 | ||||
|     if (ret == NULL) { | ||||
|         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     ret->lock = CRYPTO_THREAD_lock_new(); | ||||
|     if (ret->lock == NULL) { | ||||
|         OPENSSL_free(ret); | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     ret->libctx = key->libctx; | ||||
|     ret->haspubkey = key->haspubkey; | ||||
|     ret->keylen = key->keylen; | ||||
|     ret->type = key->type; | ||||
|     ret->references = 1; | ||||
| 
 | ||||
|     if (key->propq != NULL) { | ||||
|         ret->propq = OPENSSL_strdup(key->propq); | ||||
|         if (ret->propq == NULL) | ||||
|             goto err; | ||||
|     } | ||||
| 
 | ||||
|     memcpy(ret->pubkey, key->pubkey, sizeof(ret->pubkey)); | ||||
| 
 | ||||
|     if (key->privkey != NULL) { | ||||
|         if (ossl_ecx_key_allocate_privkey(ret) == NULL) | ||||
|             goto err; | ||||
|         memcpy(ret->privkey, key->privkey, ret->keylen); | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| 
 | ||||
| err: | ||||
|     ossl_ecx_key_free(ret); | ||||
|     ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| #ifndef FIPS_MODULE | ||||
| ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg, | ||||
|                          const unsigned char *p, int plen, | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
|  * https://www.openssl.org/source/license.html
 | ||||
|  */ | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <openssl/err.h> | ||||
| #include "crypto/ecx.h" | ||||
| 
 | ||||
|  | @ -39,7 +40,6 @@ ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey | |||
| 
 | ||||
|     if (propq != NULL) { | ||||
|         ret->propq = OPENSSL_strdup(propq); | ||||
|         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); | ||||
|         if (ret->propq == NULL) | ||||
|             goto err; | ||||
|     } | ||||
|  | @ -96,3 +96,4 @@ unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key) | |||
| 
 | ||||
|     return key->privkey; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -406,16 +406,18 @@ static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx, | |||
| 
 | ||||
| static int ecx_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) | ||||
| { | ||||
|     ECX_KEY *ecx = from->pkey.ecx; | ||||
|     ECX_KEY *ecx = from->pkey.ecx, *dupkey = NULL; | ||||
|     int ret; | ||||
| 
 | ||||
|     /* We can do just up-ref as ECX keys are immutable */ | ||||
|     if (ecx != NULL && !ossl_ecx_key_up_ref(ecx)) | ||||
|     if (ecx != NULL) { | ||||
|         dupkey = ossl_ecx_key_dup(ecx); | ||||
|         if (dupkey == NULL) | ||||
|             return 0; | ||||
|     } | ||||
| 
 | ||||
|     ret = EVP_PKEY_assign(to, from->type, ecx); | ||||
|     ret = EVP_PKEY_assign(to, from->type, dupkey); | ||||
|     if (!ret) | ||||
|         ossl_ecx_key_free(ecx); | ||||
|         ossl_ecx_key_free(dupkey); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -113,6 +113,7 @@ struct evp_keymgmt_st { | |||
|     OSSL_FUNC_keymgmt_export_fn *export; | ||||
|     OSSL_FUNC_keymgmt_export_types_fn *export_types; | ||||
|     OSSL_FUNC_keymgmt_copy_fn *copy; | ||||
|     OSSL_FUNC_keymgmt_dup_fn *dup; | ||||
| } /* EVP_KEYMGMT */ ; | ||||
| 
 | ||||
| struct evp_keyexch_st { | ||||
|  |  | |||
|  | @ -459,6 +459,12 @@ int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection) | |||
|             evp_keymgmt_freedata(to_keymgmt, alloc_keydata); | ||||
|             return 0; | ||||
|         } | ||||
|     } else if (to_keymgmt == from->keymgmt && to_keymgmt->dup != NULL | ||||
|                && to_keydata == NULL | ||||
|                && selection == OSSL_KEYMGMT_SELECT_ALL) { | ||||
|         to_keydata = alloc_keydata = evp_keymgmt_dup(to_keymgmt, from->keydata); | ||||
|         if (to_keydata == NULL) | ||||
|             return 0; | ||||
|     } else if (match_type(to_keymgmt, from->keymgmt)) { | ||||
|         struct evp_keymgmt_util_try_import_data_st import_data; | ||||
| 
 | ||||
|  |  | |||
|  | @ -133,6 +133,10 @@ static void *keymgmt_from_algorithm(int name_id, | |||
|             if (keymgmt->copy == NULL) | ||||
|                 keymgmt->copy = OSSL_FUNC_keymgmt_copy(fns); | ||||
|             break; | ||||
|         case OSSL_FUNC_KEYMGMT_DUP: | ||||
|             if (keymgmt->dup == NULL) | ||||
|                 keymgmt->dup = OSSL_FUNC_keymgmt_dup(fns); | ||||
|             break; | ||||
|         case OSSL_FUNC_KEYMGMT_VALIDATE: | ||||
|             if (keymgmt->validate == NULL) | ||||
|                 keymgmt->validate = OSSL_FUNC_keymgmt_validate(fns); | ||||
|  | @ -472,3 +476,11 @@ int evp_keymgmt_copy(const EVP_KEYMGMT *keymgmt, | |||
|         return 0; | ||||
|     return keymgmt->copy(keydata_to, keydata_from, selection); | ||||
| } | ||||
| 
 | ||||
| void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt, const void *keydata_from) | ||||
| { | ||||
|     /* We assume no dup if the implementation doesn't have a function */ | ||||
|     if (keymgmt->dup == NULL) | ||||
|         return NULL; | ||||
|     return keymgmt->dup(keydata_from); | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
|  |  | |||
|  | @ -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) | ||||
| { | ||||
|  |  | |||
|  | @ -55,6 +55,9 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions | |||
|  /* Key object copy */ | ||||
|  int OSSL_FUNC_keymgmt_copy(void *keydata_to, const void *keydata_from, int selection); | ||||
| 
 | ||||
|  /* Key object duplication, a constructor */ | ||||
|  void *OSSL_FUNC_keymgmt_dup(const void *keydata_from); | ||||
| 
 | ||||
|  /* Key object validation */ | ||||
|  int OSSL_FUNC_keymgmt_validate(const void *keydata, int selection, int checktype); | ||||
| 
 | ||||
|  | @ -119,6 +122,7 @@ macros in L<openssl-core_dispatch.h(7)>, as follows: | |||
|  OSSL_FUNC_keymgmt_export_types         OSSL_FUNC_KEYMGMT_EXPORT_TYPES | ||||
| 
 | ||||
|  OSSL_FUNC_keymgmt_copy                 OSSL_FUNC_KEYMGMT_COPY | ||||
|  OSSL_FUNC_keymgmt_dup                  OSSL_FUNC_KEYMGMT_DUP | ||||
| 
 | ||||
| =head2 Key Objects | ||||
| 
 | ||||
|  | @ -342,6 +346,9 @@ from I<keydata_from> to I<keydata_to>.  It is assumed that the caller | |||
| has ensured that I<keydata_to> and I<keydata_from> are both owned by | ||||
| the implementation of this function. | ||||
| 
 | ||||
| OSSL_FUNC_keymgmt_dup() should duplicate the key data I<keydata_from> and | ||||
| create a new provider side key object with the data. | ||||
| 
 | ||||
| =head2 Common Information Parameters | ||||
| 
 | ||||
| See L<OSSL_PARAM(3)> for further details on the parameters structure. | ||||
|  | @ -379,8 +386,8 @@ Bits of security is defined in SP800-57. | |||
| 
 | ||||
| =head1 RETURN VALUES | ||||
| 
 | ||||
| OSSL_FUNC_keymgmt_new() should return a valid reference to the newly created provider | ||||
| side key object, or NULL on failure. | ||||
| OSSL_FUNC_keymgmt_new() and OSSL_FUNC_keymgmt_dup() should return a valid | ||||
| reference to the newly created provider side key object, or NULL on failure. | ||||
| 
 | ||||
| OSSL_FUNC_keymgmt_import(), OSSL_FUNC_keymgmt_export(), OSSL_FUNC_keymgmt_get_params() and | ||||
| OSSL_FUNC_keymgmt_set_params() should return 1 for success or 0 on error. | ||||
|  |  | |||
|  | @ -56,5 +56,6 @@ int ossl_dh_kdf_X9_42_asn1(unsigned char *out, size_t outlen, | |||
|                            const unsigned char *ukm, size_t ukmlen, | ||||
|                            const EVP_MD *md, | ||||
|                            OSSL_LIB_CTX *libctx, const char *propq); | ||||
| DH *ossl_dh_dup(const DH *dh); | ||||
| 
 | ||||
| #endif  /* OSSL_CRYPTO_DH_H */ | ||||
|  |  | |||
|  | @ -43,5 +43,6 @@ int ossl_dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, | |||
|                                    int *ret); | ||||
| int ossl_dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret); | ||||
| int ossl_dsa_check_pairwise(const DSA *dsa); | ||||
| DSA *ossl_dsa_dup(const DSA *dsa); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -83,6 +83,7 @@ void ossl_ecx_key_set0_libctx(ECX_KEY *key, OSSL_LIB_CTX *libctx); | |||
| unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key); | ||||
| void ossl_ecx_key_free(ECX_KEY *key); | ||||
| int ossl_ecx_key_up_ref(ECX_KEY *key); | ||||
| ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key); | ||||
| 
 | ||||
| int ossl_x25519(uint8_t out_shared_key[32], const uint8_t private_key[32], | ||||
|                 const uint8_t peer_public_value[32]); | ||||
|  |  | |||
|  | @ -813,6 +813,8 @@ const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt, | |||
| int evp_keymgmt_copy(const EVP_KEYMGMT *keymgmt, | ||||
|                      void *keydata_to, const void *keydata_from, | ||||
|                      int selection); | ||||
| void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt, | ||||
|                       const void *keydata_from); | ||||
| 
 | ||||
| /* Pulling defines out of C source files */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -63,6 +63,7 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, | |||
| int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, | ||||
|                              STACK_OF(BIGNUM_const) *exps, | ||||
|                              STACK_OF(BIGNUM_const) *coeffs); | ||||
| RSA *ossl_rsa_dup(const RSA *rsa); | ||||
| 
 | ||||
| int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); | ||||
| int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]); | ||||
|  |  | |||
|  | @ -598,8 +598,12 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_export_types, | |||
| /* Copy function, only works for matching keymgmt */ | ||||
| # define OSSL_FUNC_KEYMGMT_COPY                       44 | ||||
| OSSL_CORE_MAKE_FUNC(int, keymgmt_copy, | ||||
|                     ( void *keydata_to, const void *keydata_from, | ||||
|                     (void *keydata_to, const void *keydata_from, | ||||
|                      int selection)) | ||||
| /* Dup function, constructor */ | ||||
| # define OSSL_FUNC_KEYMGMT_DUP                        45 | ||||
| OSSL_CORE_MAKE_FUNC(void *, keymgmt_dup, | ||||
|                     (const void *keydata_from)) | ||||
| 
 | ||||
| /* Key Exchange */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ static OSSL_FUNC_keymgmt_import_fn dh_import; | |||
| static OSSL_FUNC_keymgmt_import_types_fn dh_import_types; | ||||
| static OSSL_FUNC_keymgmt_export_fn dh_export; | ||||
| static OSSL_FUNC_keymgmt_export_types_fn dh_export_types; | ||||
| static OSSL_FUNC_keymgmt_dup_fn dh_dup; | ||||
| 
 | ||||
| #define DH_POSSIBLE_SELECTIONS                                                 \ | ||||
|     (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) | ||||
|  | @ -707,7 +708,7 @@ static void dh_gen_cleanup(void *genctx) | |||
|     OPENSSL_free(gctx); | ||||
| } | ||||
| 
 | ||||
| void *dh_load(const void *reference, size_t reference_sz) | ||||
| static void *dh_load(const void *reference, size_t reference_sz) | ||||
| { | ||||
|     DH *dh = NULL; | ||||
| 
 | ||||
|  | @ -721,6 +722,13 @@ void *dh_load(const void *reference, size_t reference_sz) | |||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static void *dh_dup(const void *keydata_from) | ||||
| { | ||||
|     if (ossl_prov_is_running()) | ||||
|         return ossl_dh_dup(keydata_from); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| const OSSL_DISPATCH ossl_dh_keymgmt_functions[] = { | ||||
|     { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dh_newdata }, | ||||
|     { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dh_gen_init }, | ||||
|  | @ -743,6 +751,7 @@ const OSSL_DISPATCH ossl_dh_keymgmt_functions[] = { | |||
|     { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dh_import_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dh_export }, | ||||
|     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dh_dup }, | ||||
|     { 0, NULL } | ||||
| }; | ||||
| 
 | ||||
|  | @ -776,5 +785,6 @@ const OSSL_DISPATCH ossl_dhx_keymgmt_functions[] = { | |||
|     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, | ||||
|       (void (*)(void))dhx_query_operation_name }, | ||||
|     { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dh_dup }, | ||||
|     { 0, NULL } | ||||
| }; | ||||
|  |  | |||
|  | @ -44,6 +44,7 @@ static OSSL_FUNC_keymgmt_import_fn dsa_import; | |||
| static OSSL_FUNC_keymgmt_import_types_fn dsa_import_types; | ||||
| static OSSL_FUNC_keymgmt_export_fn dsa_export; | ||||
| static OSSL_FUNC_keymgmt_export_types_fn dsa_export_types; | ||||
| static OSSL_FUNC_keymgmt_dup_fn dsa_dup; | ||||
| 
 | ||||
| #define DSA_DEFAULT_MD "SHA256" | ||||
| #define DSA_POSSIBLE_SELECTIONS                                                \ | ||||
|  | @ -597,7 +598,7 @@ static void dsa_gen_cleanup(void *genctx) | |||
|     OPENSSL_free(gctx); | ||||
| } | ||||
| 
 | ||||
| void *dsa_load(const void *reference, size_t reference_sz) | ||||
| static void *dsa_load(const void *reference, size_t reference_sz) | ||||
| { | ||||
|     DSA *dsa = NULL; | ||||
| 
 | ||||
|  | @ -611,6 +612,13 @@ void *dsa_load(const void *reference, size_t reference_sz) | |||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static void *dsa_dup(const void *keydata_from) | ||||
| { | ||||
|     if (ossl_prov_is_running()) | ||||
|         return ossl_dsa_dup(keydata_from); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = { | ||||
|     { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata }, | ||||
|     { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init }, | ||||
|  | @ -631,5 +639,6 @@ const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = { | |||
|     { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dsa_import_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dsa_export }, | ||||
|     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dsa_export_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dsa_dup }, | ||||
|     { 0, NULL } | ||||
| }; | ||||
|  |  | |||
|  | @ -55,6 +55,7 @@ static OSSL_FUNC_keymgmt_import_types_fn ec_import_types; | |||
| static OSSL_FUNC_keymgmt_export_fn ec_export; | ||||
| static OSSL_FUNC_keymgmt_export_types_fn ec_export_types; | ||||
| static OSSL_FUNC_keymgmt_query_operation_name_fn ec_query_operation_name; | ||||
| static OSSL_FUNC_keymgmt_dup_fn ec_dup; | ||||
| #ifndef FIPS_MODULE | ||||
| # ifndef OPENSSL_NO_SM2 | ||||
| static OSSL_FUNC_keymgmt_new_fn sm2_newdata; | ||||
|  | @ -1361,6 +1362,13 @@ static void *sm2_load(const void *reference, size_t reference_sz) | |||
| # endif | ||||
| #endif | ||||
| 
 | ||||
| static void *ec_dup(const void *keydata_from) | ||||
| { | ||||
|     if (ossl_prov_is_running()) | ||||
|         return EC_KEY_dup(keydata_from); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { | ||||
|     { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata }, | ||||
|     { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init }, | ||||
|  | @ -1386,6 +1394,7 @@ const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { | |||
|     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, | ||||
|       (void (*)(void))ec_query_operation_name }, | ||||
|     { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup }, | ||||
|     { 0, NULL } | ||||
| }; | ||||
| 
 | ||||
|  | @ -1416,6 +1425,7 @@ const OSSL_DISPATCH ossl_sm2_keymgmt_functions[] = { | |||
|     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, | ||||
|       (void (*)(void))sm2_query_operation_name }, | ||||
|     { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup }, | ||||
|     { 0, NULL } | ||||
| }; | ||||
| # endif | ||||
|  |  | |||
|  | @ -71,6 +71,7 @@ static OSSL_FUNC_keymgmt_import_fn ecx_import; | |||
| static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types; | ||||
| static OSSL_FUNC_keymgmt_export_fn ecx_export; | ||||
| static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types; | ||||
| static OSSL_FUNC_keymgmt_dup_fn ecx_dup; | ||||
| 
 | ||||
| #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR) | ||||
| 
 | ||||
|  | @ -691,6 +692,13 @@ void *ecx_load(const void *reference, size_t reference_sz) | |||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static void *ecx_dup(const void *keydata_from) | ||||
| { | ||||
|     if (ossl_prov_is_running()) | ||||
|         return ossl_ecx_key_dup(keydata_from); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type) | ||||
| { | ||||
|     uint8_t pub[64]; | ||||
|  | @ -788,6 +796,7 @@ static int ed448_validate(const void *keydata, int selection, int checktype) | |||
|         { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \ | ||||
|         { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \ | ||||
|         { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \ | ||||
|         { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \ | ||||
|         { 0, NULL } \ | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ static OSSL_FUNC_keymgmt_import_types_fn rsa_import_types; | |||
| static OSSL_FUNC_keymgmt_export_fn rsa_export; | ||||
| static OSSL_FUNC_keymgmt_export_types_fn rsa_export_types; | ||||
| static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_query_operation_name; | ||||
| static OSSL_FUNC_keymgmt_dup_fn rsa_dup; | ||||
| 
 | ||||
| #define RSA_DEFAULT_MD "SHA256" | ||||
| #define RSA_PSS_DEFAULT_MD OSSL_DIGEST_NAME_SHA1 | ||||
|  | @ -645,6 +646,13 @@ static void *rsapss_load(const void *reference, size_t reference_sz) | |||
|     return common_load(reference, reference_sz, RSA_FLAG_TYPE_RSASSAPSS); | ||||
| } | ||||
| 
 | ||||
| static void *rsa_dup(const void *keydata_from) | ||||
| { | ||||
|     if (ossl_prov_is_running()) | ||||
|         return ossl_rsa_dup(keydata_from); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| /* For any RSA key, we use the "RSA" algorithms regardless of sub-type. */ | ||||
| static const char *rsa_query_operation_name(int operation_id) | ||||
| { | ||||
|  | @ -671,6 +679,7 @@ const OSSL_DISPATCH ossl_rsa_keymgmt_functions[] = { | |||
|     { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))rsa_import_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))rsa_export }, | ||||
|     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup }, | ||||
|     { 0, NULL } | ||||
| }; | ||||
| 
 | ||||
|  | @ -695,5 +704,6 @@ const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = { | |||
|     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types }, | ||||
|     { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, | ||||
|       (void (*)(void))rsa_query_operation_name }, | ||||
|     { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup }, | ||||
|     { 0, NULL } | ||||
| }; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue