diff --git a/src/wp_dh_kmgmt.c b/src/wp_dh_kmgmt.c index 84eb3c1a..ecf570cb 100644 --- a/src/wp_dh_kmgmt.c +++ b/src/wp_dh_kmgmt.c @@ -3086,6 +3086,30 @@ static int wp_dh_export_object(wp_DhEncDecCtx* ctx, wp_Dh* dh, size_t size, return wp_dh_export(dh, ctx->selection, exportCb, exportCbArg); } +/** + * Create a DH key object and import the key data into it. + * + * @param [in] ctx DH encoder/decoder context object. + * @param [in] selection Parts of key to import. + * @param [in] params Array of parameters with key data. + * @return New DH key object on success. + * @return NULL on failure. + */ +static wp_Dh* wp_dh_import_object(wp_DhEncDecCtx* ctx, int selection, + const OSSL_PARAM params[]) +{ + wp_Dh* dh; + + WOLFPROV_ENTER(WP_LOG_COMP_DH, "wp_dh_import_object"); + + dh = wp_dh_new(ctx->provCtx); + if ((dh != NULL) && (!wp_dh_import(dh, selection, params))) { + wp_dh_free(dh); + dh = NULL; + } + return dh; +} + /* * DH Parameters */ @@ -3170,7 +3194,7 @@ const OSSL_DISPATCH wp_dh_type_specific_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_dh_type_specific_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_dh_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_dh_free }, { 0, NULL } }; @@ -3200,7 +3224,7 @@ const OSSL_DISPATCH wp_dh_type_specific_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_dh_type_specific_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_dh_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_dh_free }, { 0, NULL } }; @@ -3284,7 +3308,7 @@ const OSSL_DISPATCH wp_dh_spki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_dh_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_dh_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_dh_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_dh_free }, { 0, NULL } }; @@ -3312,7 +3336,7 @@ const OSSL_DISPATCH wp_dh_spki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_dh_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_dh_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_dh_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_dh_free }, { 0, NULL } }; @@ -3396,7 +3420,7 @@ const OSSL_DISPATCH wp_dh_pki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_dh_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_dh_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_dh_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_dh_free }, { 0, NULL } }; @@ -3424,7 +3448,7 @@ const OSSL_DISPATCH wp_dh_pki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_dh_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_dh_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_dh_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_dh_free }, { 0, NULL } }; @@ -3456,7 +3480,7 @@ const OSSL_DISPATCH wp_dh_epki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_dh_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_dh_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_dh_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_dh_free }, { 0, NULL } }; @@ -3484,7 +3508,7 @@ const OSSL_DISPATCH wp_dh_epki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_dh_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_dh_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_dh_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_dh_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_dh_free }, { 0, NULL } }; diff --git a/src/wp_ecc_kmgmt.c b/src/wp_ecc_kmgmt.c index 8ce9cc42..c84f5825 100644 --- a/src/wp_ecc_kmgmt.c +++ b/src/wp_ecc_kmgmt.c @@ -3272,6 +3272,27 @@ static int wp_ecc_export_object(wp_EccEncDecCtx* ctx, wp_Ecc* ecc, size_t size, return wp_ecc_export(ecc, ctx->selection, exportCb, exportCbArg); } +/** + * Create an ECC key object and import the key data into it. + * + * @param [in] ctx ECC encoder/decoder context object. + * @param [in] selection Parts of key to import. + * @param [in] params Array of parameters with key data. + * @return New ECC key object on success. + * @return NULL on failure. + */ +static wp_Ecc* wp_ecc_import_object(wp_EccEncDecCtx* ctx, int selection, + const OSSL_PARAM params[]) +{ + wp_Ecc* ecc = wp_ecc_new(ctx->provCtx); + + if ((ecc != NULL) && (!wp_ecc_import(ecc, selection, params))) { + wp_ecc_free(ecc); + ecc = NULL; + } + return ecc; +} + /* * ECC Type-Specific */ @@ -3355,7 +3376,7 @@ const OSSL_DISPATCH wp_ecc_type_specific_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_type_specific_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3386,7 +3407,7 @@ const OSSL_DISPATCH wp_ecc_type_specific_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_type_specific_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3470,7 +3491,7 @@ const OSSL_DISPATCH wp_ecc_spki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecc_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3498,7 +3519,7 @@ const OSSL_DISPATCH wp_ecc_spki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecc_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3582,7 +3603,7 @@ const OSSL_DISPATCH wp_ecc_pki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecc_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3610,7 +3631,7 @@ const OSSL_DISPATCH wp_ecc_pki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecc_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3642,7 +3663,7 @@ const OSSL_DISPATCH wp_ecc_epki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecc_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3670,7 +3691,7 @@ const OSSL_DISPATCH wp_ecc_epki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecc_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3758,7 +3779,7 @@ const OSSL_DISPATCH wp_ecc_x9_62_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_x9_62_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; @@ -3788,7 +3809,7 @@ const OSSL_DISPATCH wp_ecc_x9_62_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecc_x9_62_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecc_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecc_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecc_free }, { 0, NULL } }; diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index 2b35cac4..52beeddf 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -2217,6 +2217,59 @@ static int wp_ecx_decode_enc_pki(wp_EcxEncDecCtx* ctx, wp_Ecx* ecx, } #endif +/** + * Create an ECX key object of the type the context was created for. + * + * @param [in] provCtx Provider context. + * @param [in] keyType Type of ECX key to create. + * @param [out] dataType Data type name of the key. May be NULL. + * @return New ECX key object on success. + * @return NULL on failure. + */ +static wp_Ecx* wp_ecx_new_by_type(WOLFPROV_CTX* provCtx, int keyType, + const char** dataType) +{ + wp_Ecx* ecx; + const char* name = NULL; + +#ifdef WP_HAVE_X25519 + if (keyType == WP_KEY_TYPE_X25519) { + ecx = wp_x25519_new(provCtx); + name = "X25519"; + } + else +#endif /* WP_HAVE_X25519 */ +#ifdef WP_HAVE_ED25519 + if (keyType == WP_KEY_TYPE_ED25519) { + ecx = wp_ed25519_new(provCtx); + name = "ED25519"; + } + else +#endif /* WP_HAVE_ED25519 */ +#ifdef WP_HAVE_X448 + if (keyType == WP_KEY_TYPE_X448) { + ecx = wp_x448_new(provCtx); + name = "X448"; + } + else +#endif /* WP_HAVE_X448 */ +#ifdef WP_HAVE_ED448 + if (keyType == WP_KEY_TYPE_ED448) { + ecx = wp_ed448_new(provCtx); + name = "ED448"; + } + else +#endif /* WP_HAVE_ED448 */ + { + ecx = NULL; + } + + if (dataType != NULL) { + *dataType = name; + } + return ecx; +} + /** * Decode the data in the core BIO. * @@ -2256,37 +2309,7 @@ static int wp_ecx_decode(wp_EcxEncDecCtx* ctx, OSSL_CORE_BIO* cBio, if (ok) { ctx->selection = selection; -#ifdef WP_HAVE_X25519 - if (ctx->keyType == WP_KEY_TYPE_X25519) { - ecx = wp_x25519_new(ctx->provCtx); - dataType = "X25519"; - } - else -#endif /* WP_HAVE_X25519 */ -#ifdef WP_HAVE_ED25519 - if (ctx->keyType == WP_KEY_TYPE_ED25519) { - ecx = wp_ed25519_new(ctx->provCtx); - dataType = "ED25519"; - } - else -#endif /* WP_HAVE_ED25519 */ -#ifdef WP_HAVE_X448 - if (ctx->keyType == WP_KEY_TYPE_X448) { - ecx = wp_x448_new(ctx->provCtx); - dataType = "X448"; - } - else -#endif /* WP_HAVE_X448 */ -#ifdef WP_HAVE_ED448 - if (ctx->keyType == WP_KEY_TYPE_ED448) { - ecx = wp_ed448_new(ctx->provCtx); - dataType = "ED448"; - } - else -#endif /* WP_HAVE_ED448 */ - { - ecx = NULL; - } + ecx = wp_ecx_new_by_type(ctx->provCtx, ctx->keyType, &dataType); if (ecx == NULL) { ok = 0; } @@ -2496,6 +2519,27 @@ static int wp_ecx_export_object(wp_EcxEncDecCtx* ctx, wp_Ecx* ecx, size_t size, return wp_ecx_export(ecx, ctx->selection, exportCb, exportCbArg); } +/** + * Create an ECX key object and import the key data into it. + * + * @param [in] ctx ECX encoder/decoder context object. + * @param [in] selection Parts of key to import. + * @param [in] params Array of parameters with key data. + * @return New ECX key object on success. + * @return NULL on failure. + */ +static wp_Ecx* wp_ecx_import_object(wp_EcxEncDecCtx* ctx, int selection, + const OSSL_PARAM params[]) +{ + wp_Ecx* ecx = wp_ecx_new_by_type(ctx->provCtx, ctx->keyType, NULL); + + if ((ecx != NULL) && (!wp_ecx_import(ecx, selection, params))) { + wp_ecx_free(ecx); + ecx = NULL; + } + return ecx; +} + /* * ECX SubkectPublicKeyInfo */ @@ -2680,7 +2724,7 @@ const OSSL_DISPATCH wp_x25519_spki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -2709,7 +2753,7 @@ const OSSL_DISPATCH wp_x25519_spki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -2832,7 +2876,7 @@ const OSSL_DISPATCH wp_x25519_pki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -2861,7 +2905,7 @@ const OSSL_DISPATCH wp_x25519_pki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -2894,7 +2938,7 @@ const OSSL_DISPATCH wp_x25519_epki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -2923,7 +2967,7 @@ const OSSL_DISPATCH wp_x25519_epki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3013,7 +3057,7 @@ const OSSL_DISPATCH wp_ed25519_spki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3042,7 +3086,7 @@ const OSSL_DISPATCH wp_ed25519_spki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3102,7 +3146,7 @@ const OSSL_DISPATCH wp_ed25519_pki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3131,7 +3175,7 @@ const OSSL_DISPATCH wp_ed25519_pki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3164,7 +3208,7 @@ const OSSL_DISPATCH wp_ed25519_epki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3193,7 +3237,7 @@ const OSSL_DISPATCH wp_ed25519_epki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3319,7 +3363,7 @@ const OSSL_DISPATCH wp_x448_spki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3348,7 +3392,7 @@ const OSSL_DISPATCH wp_x448_spki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3471,7 +3515,7 @@ const OSSL_DISPATCH wp_x448_pki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3500,7 +3544,7 @@ const OSSL_DISPATCH wp_x448_pki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3533,7 +3577,7 @@ const OSSL_DISPATCH wp_x448_epki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3562,7 +3606,7 @@ const OSSL_DISPATCH wp_x448_epki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3651,7 +3695,7 @@ const OSSL_DISPATCH wp_ed448_spki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3680,7 +3724,7 @@ const OSSL_DISPATCH wp_ed448_spki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3740,7 +3784,7 @@ const OSSL_DISPATCH wp_ed448_pki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3769,7 +3813,7 @@ const OSSL_DISPATCH wp_ed448_pki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3802,7 +3846,7 @@ const OSSL_DISPATCH wp_ed448_epki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; @@ -3831,7 +3875,7 @@ const OSSL_DISPATCH wp_ed448_epki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_ecx_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_ecx_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_ecx_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_ecx_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_ecx_free }, { 0, NULL } }; diff --git a/src/wp_mldsa_kmgmt.c b/src/wp_mldsa_kmgmt.c index 76854dad..4a47fc1d 100644 --- a/src/wp_mldsa_kmgmt.c +++ b/src/wp_mldsa_kmgmt.c @@ -1665,6 +1665,30 @@ static int wp_mldsa_export_object(wp_MlDsaEncDecCtx* ctx, wp_MlDsa* mldsa, return wp_mldsa_export(mldsa, ctx->selection, exportCb, exportCbArg); } +/** + * Create an ML-DSA key object and import the key data into it. + * + * @param [in] ctx ML-DSA encoder/decoder context object. + * @param [in] selection Parts of key to import. + * @param [in] params Array of parameters with key data. + * @return New ML-DSA key object on success. + * @return NULL on failure. + */ +static wp_MlDsa* wp_mldsa_import_object(wp_MlDsaEncDecCtx* ctx, int selection, + const OSSL_PARAM params[]) +{ + wp_MlDsa* mldsa = NULL; + + if (ctx->newKey != NULL) { + mldsa = ctx->newKey(ctx->provCtx); + } + if ((mldsa != NULL) && (!wp_mldsa_import(mldsa, selection, params))) { + wp_mldsa_free(mldsa); + mldsa = NULL; + } + return mldsa; +} + /** * Return whether the SPKI decoder/encoder handles this part of the key. * @@ -1843,7 +1867,7 @@ const OSSL_DISPATCH wp_##alg##_##fmt##_##enc##_encoder_functions[] = { (DFUNC)wp_mldsa_enc_dec_set_ctx_params },\ { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)dsel }, \ { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_mldsa_encode },\ - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_mldsa_import },\ + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_mldsa_import_object },\ { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_mldsa_free },\ { 0, NULL } \ }; diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index 0cce58ea..8ce43975 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -3804,6 +3804,27 @@ static int wp_rsa_export_object(wp_RsaEncDecCtx* ctx, wp_Rsa* rsa, size_t size, return wp_rsa_export(rsa, ctx->selection, exportCb, exportCbArg); } +/** + * Create an RSA key object and import the key data into it. + * + * @param [in] ctx RSA encoder/decoder context object. + * @param [in] selection Parts of key to import. + * @param [in] params Array of parameters with key data. + * @return New RSA key object on success. + * @return NULL on failure. + */ +static wp_Rsa* wp_rsa_import_object(wp_RsaEncDecCtx* ctx, int selection, + const OSSL_PARAM params[]) +{ + wp_Rsa* rsa = wp_rsa_base_new(ctx->provCtx, ctx->type); + + if ((rsa != NULL) && (!wp_rsa_import(rsa, selection, params))) { + wp_rsa_free(rsa); + rsa = NULL; + } + return rsa; +} + /* * RSA SubjectPublicKeyInfo */ @@ -3885,7 +3906,7 @@ const OSSL_DISPATCH wp_rsa_spki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -3914,7 +3935,7 @@ const OSSL_DISPATCH wp_rsa_spki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4000,7 +4021,7 @@ const OSSL_DISPATCH wp_rsa_pki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4029,7 +4050,7 @@ const OSSL_DISPATCH wp_rsa_pki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4062,7 +4083,7 @@ const OSSL_DISPATCH wp_rsa_epki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4091,7 +4112,7 @@ const OSSL_DISPATCH wp_rsa_epki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4207,7 +4228,7 @@ const OSSL_DISPATCH wp_rsa_kp_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_kp_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4238,7 +4259,7 @@ const OSSL_DISPATCH wp_rsa_kp_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_kp_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4296,7 +4317,7 @@ const OSSL_DISPATCH wp_rsapss_spki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4325,7 +4346,7 @@ const OSSL_DISPATCH wp_rsapss_spki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_spki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4383,7 +4404,7 @@ const OSSL_DISPATCH wp_rsapss_pki_der_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; @@ -4412,7 +4433,7 @@ const OSSL_DISPATCH wp_rsapss_pki_pem_encoder_functions[] = { { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, (DFUNC)wp_rsa_enc_dec_set_ctx_params }, { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_pki_does_selection }, { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode }, - { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import }, + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, (DFUNC)wp_rsa_import_object }, { OSSL_FUNC_ENCODER_FREE_OBJECT, (DFUNC)wp_rsa_free }, { 0, NULL } }; diff --git a/test/test_dh.c b/test/test_dh.c index 8365108c..d8935e2b 100644 --- a/test/test_dh.c +++ b/test/test_dh.c @@ -2329,4 +2329,62 @@ int test_dh_pgen_controls(void *data) return err; } +/* + * Encoding a key that another provider manages goes through the encoder's + * import-object: OpenSSL hands it the encoder context and uses the key object + * it returns. + */ +int test_dh_encoder_import_object(void *data) +{ + /* wolfProvider names only the FFDHE groups. */ + static const struct { + const char* group; + int accept; + } cases[] = { + { "ffdhe2048", 1 }, + { "modp_1536", 0 }, + }; + int err = 0; + EVP_PKEY_CTX* ctx; + EVP_PKEY* pkey; + OSSL_PARAM params[2]; + size_t i; + + (void)data; + + for (i = 0; (err == 0) && (i < sizeof(cases) / sizeof(*cases)); i++) { + ctx = NULL; + pkey = NULL; + + params[0] = OSSL_PARAM_construct_utf8_string( + OSSL_PKEY_PARAM_GROUP_NAME, (char*)cases[i].group, 0); + params[1] = OSSL_PARAM_construct_end(); + + err = (ctx = EVP_PKEY_CTX_new_from_name(osslLibCtx, "DH", NULL)) + == NULL; + if (err == 0) { + err = EVP_PKEY_keygen_init(ctx) != 1; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_params(ctx, params) != 1; + } + if (err == 0) { + err = EVP_PKEY_generate(ctx, &pkey) != 1; + } + if ((err == 0) && cases[i].accept) { + err = test_encoder_import_object("DH", + "output=der,structure=PrivateKeyInfo", pkey, EVP_PKEY_KEYPAIR); + } + else if (err == 0) { + err = test_encoder_import_object_rejected("DH", + "output=der,structure=PrivateKeyInfo", pkey, EVP_PKEY_KEYPAIR); + } + + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + } + + return err; +} + #endif /* WP_HAVE_DH */ diff --git a/test/test_ecc.c b/test/test_ecc.c index 78c710e8..856339a6 100644 --- a/test/test_ecc.c +++ b/test/test_ecc.c @@ -3959,4 +3959,51 @@ int test_ec_tls_group_p192(void *data) return err; } + +#ifdef WP_HAVE_EC_P256 +/* + * Encoding a key that another provider manages goes through the encoder's + * import-object: OpenSSL hands it the encoder context and uses the key object + * it returns. + */ +int test_ecc_encoder_import_object(void *data) +{ + int err; + EVP_PKEY* pkey = NULL; + + (void)data; + + pkey = EVP_PKEY_Q_keygen(osslLibCtx, NULL, "EC", "P-256"); + err = (pkey == NULL); + if (err == 0) { + err = test_encoder_import_object("EC", + "output=pem,structure=SubjectPublicKeyInfo", pkey, + EVP_PKEY_PUBLIC_KEY); + } + if (err == 0) { + err = test_encoder_import_object("EC", + "output=der,structure=PrivateKeyInfo", pkey, EVP_PKEY_KEYPAIR); + } + EVP_PKEY_free(pkey); + +#ifndef OPENSSL_NO_EC2M + /* wolfSSL has no binary curves. */ + pkey = NULL; + if (err == 0) { + pkey = EVP_PKEY_Q_keygen(osslLibCtx, NULL, "EC", "sect233k1"); + err = (pkey == NULL); + } + if (err == 0) { + err = test_encoder_import_object_rejected("EC", + "output=pem,structure=SubjectPublicKeyInfo", pkey, + EVP_PKEY_PUBLIC_KEY); + } + EVP_PKEY_free(pkey); +#endif + + return err; +} + +#endif /* WP_HAVE_EC_P256 */ + #endif /* WP_HAVE_ECC */ diff --git a/test/test_ecx.c b/test/test_ecx.c index 5551b9c3..54f5a544 100644 --- a/test/test_ecx.c +++ b/test/test_ecx.c @@ -1584,3 +1584,66 @@ int test_ecx_x_security_bits(void *data) #endif /* defined(WP_HAVE_X25519) || defined(WP_HAVE_X448) */ +#if defined(WP_HAVE_X25519) || defined(WP_HAVE_ED25519) || \ + defined(WP_HAVE_X448) || defined(WP_HAVE_ED448) +/* + * Encoding a key that another provider manages goes through the encoder's + * import-object: OpenSSL hands it the encoder context and uses the key object + * it returns. Cover every key type wp_ecx_new_by_type() handles. + */ +int test_ecx_encoder_import_object(void *data) +{ + static const char* names[] = { +#ifdef WP_HAVE_X25519 + "X25519", +#endif +#ifdef WP_HAVE_ED25519 + "ED25519", +#endif +#ifdef WP_HAVE_X448 + "X448", +#endif +#ifdef WP_HAVE_ED448 + "ED448", +#endif + }; + int err = 0; + EVP_PKEY* pkey; + size_t i; +#ifdef WP_HAVE_ED25519 + unsigned char badPub[ED25519_PUB_KEY_SIZE]; +#endif + + (void)data; + + for (i = 0; (err == 0) && (i < ARRAY_SIZE(names)); i++) { + pkey = EVP_PKEY_Q_keygen(osslLibCtx, NULL, names[i]); + err = (pkey == NULL); + if (err == 0) { + err = test_encoder_import_object(names[i], + "output=der,structure=PrivateKeyInfo", pkey, + EVP_PKEY_KEYPAIR); + } + EVP_PKEY_free(pkey); + } + +#ifdef WP_HAVE_ED25519 + /* An ED25519 public key whose y is not below the field prime. */ + pkey = NULL; + XMEMSET(badPub, 0xff, sizeof(badPub)); + if (err == 0) { + pkey = EVP_PKEY_new_raw_public_key_ex(osslLibCtx, "ED25519", NULL, + badPub, sizeof(badPub)); + err = (pkey == NULL); + } + if (err == 0) { + err = test_encoder_import_object_rejected("ED25519", + "output=der,structure=SubjectPublicKeyInfo", pkey, + EVP_PKEY_PUBLIC_KEY); + } + EVP_PKEY_free(pkey); +#endif + + return err; +} +#endif diff --git a/test/test_mldsa.c b/test/test_mldsa.c index 64ec6f42..0ef6d31b 100644 --- a/test/test_mldsa.c +++ b/test/test_mldsa.c @@ -1262,4 +1262,34 @@ int test_mldsa_encode_epki(void* data) } #endif /* WP_HAVE_EPKI_TEST */ + +/* + * Encoding a key that another provider manages goes through the encoder's + * import-object: OpenSSL hands it the encoder context and uses the key object + * it returns. + */ +int test_mldsa_encoder_import_object(void *data) +{ + int err; + EVP_PKEY* pkey = NULL; + + (void)data; + + pkey = EVP_PKEY_Q_keygen(osslLibCtx, NULL, "ML-DSA-44"); + err = (pkey == NULL); + if (err == 0) { + err = test_encoder_import_object("ML-DSA-44", + "output=pem,structure=SubjectPublicKeyInfo", pkey, + EVP_PKEY_PUBLIC_KEY); + } + if (err == 0) { + err = test_encoder_import_object("ML-DSA-44", + "output=der,structure=PrivateKeyInfo", pkey, EVP_PKEY_KEYPAIR); + } + + EVP_PKEY_free(pkey); + + return err; +} + #endif /* WP_HAVE_MLDSA */ diff --git a/test/test_pkey.c b/test/test_pkey.c index 94025425..93f938e7 100644 --- a/test/test_pkey.c +++ b/test/test_pkey.c @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include int test_digest_sign(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, unsigned char *data, size_t len, const char *md, const EVP_MD *mgf1Md, unsigned char *sig, @@ -561,3 +564,412 @@ int test_epki_encode_decode(EVP_PKEY* pkey, const char* fmt, return err; } + +/** + * Find an implementation in a provider's operation table. + * + * @param [in] prov Provider to query. + * @param [in] opId Operation identifier, e.g. OSSL_OP_ENCODER. + * @param [in] name Algorithm name to match, e.g. "RSA". + * @param [in] props Substring the properties must contain. May be NULL. + * @return Dispatch table of the implementation on success. + * @return NULL when no implementation matches. + */ +static const OSSL_DISPATCH* test_prov_find(OSSL_PROVIDER* prov, int opId, + const char* name, const char* props) +{ + const OSSL_DISPATCH* impl = NULL; + const OSSL_ALGORITHM* algs; + const OSSL_ALGORITHM* alg; + int noCache = 0; + size_t nameLen = XSTRLEN(name); + const char* p; + + algs = OSSL_PROVIDER_query_operation(prov, opId, &noCache); + for (alg = algs; (impl == NULL) && (alg != NULL) && + (alg->algorithm_names != NULL); alg++) { + if ((props != NULL) && ((alg->property_definition == NULL) || + (strstr(alg->property_definition, props) == NULL))) { + continue; + } + /* Algorithm names are a colon separated list - match one whole name. */ + for (p = alg->algorithm_names; p != NULL; p = strchr(p, ':')) { + if (p[0] == ':') { + p++; + } + if ((strncmp(p, name, nameLen) == 0) && + ((p[nameLen] == '\0') || (p[nameLen] == ':'))) { + impl = alg->implementation; + break; + } + } + } + if (algs != NULL) { + OSSL_PROVIDER_unquery_operation(prov, opId, algs); + } + + return impl; +} + +/** + * Get a function out of a dispatch table. + * + * @param [in] disp Dispatch table to search. + * @param [in] id Function identifier to find. + * @return Function pointer on success. + * @return NULL when not in the table. + */ +static void (*test_disp_get(const OSSL_DISPATCH* disp, int id))(void) +{ + void (*fp)(void) = NULL; + + for (; (fp == NULL) && (disp != NULL) && (disp->function_id != 0); disp++) { + if (disp->function_id == id) { + fp = disp->function; + } + } + + return fp; +} + +/** Parameters holding key material, which the imported key must give back. */ +static const char* test_key_material[] = { + OSSL_PKEY_PARAM_PUB_KEY, + OSSL_PKEY_PARAM_PRIV_KEY, + OSSL_PKEY_PARAM_RSA_N, + OSSL_PKEY_PARAM_RSA_E, + OSSL_PKEY_PARAM_RSA_D, +}; +#define TEST_KEY_MATERIAL_CNT \ + (int)(sizeof(test_key_material) / sizeof(*test_key_material)) + +/** Comparison state passed to the key-management export callback. */ +typedef struct { + /** Parameters the key was imported from. */ + const OSSL_PARAM* expected; + /** Bit per test_key_material entry that was exported and matched. */ + int matchedMaterial; + /** Number of parameters that were compared and matched. */ + int matched; + /** Set when an exported parameter differs from the imported one. */ + int err; +} TEST_EXPORT_CMP; + +/** + * Check an uncompressed and a compressed SEC1 encoding hold the same EC point. + * + * @param [in] full Uncompressed encoding: 0x04 || X || Y. + * @param [in] fullLen Length of the uncompressed encoding in bytes. + * @param [in] comp Compressed encoding: 0x02 or 0x03 || X. + * @param [in] compLen Length of the compressed encoding in bytes. + * @return 1 when both encode the same point, 0 otherwise. + */ +static int test_ec_point_same(const unsigned char* full, size_t fullLen, + const unsigned char* comp, size_t compLen) +{ + int same = 0; + size_t coordLen; + + if ((compLen >= 2) && (fullLen == (2 * compLen) - 1) && + (full[0] == 0x04) && ((comp[0] == 0x02) || (comp[0] == 0x03))) { + coordLen = compLen - 1; + /* The compressed prefix carries the low bit of Y. */ + same = (memcmp(full + 1, comp + 1, coordLen) == 0) && + ((full[fullLen - 1] & 1) == (comp[0] & 1)); + } + + return same; +} + +/** + * Compare one exported parameter with the value it was imported from. + * + * @param [in] got Exported parameter. + * @param [in] exp Parameter the key was imported from. + * @return 1 when the values match. + * @return 0 when the values differ. + * @return -1 when the parameter type is not compared. + */ +static int test_param_cmp(const OSSL_PARAM* got, const OSSL_PARAM* exp) +{ + int same = -1; + int64_t gotInt = 0; + int64_t expInt = 0; + BIGNUM* gotBn = NULL; + BIGNUM* expBn = NULL; + + if (got->data_type == OSSL_PARAM_INTEGER) { + same = (OSSL_PARAM_get_int64(got, &gotInt) == 1) && + (OSSL_PARAM_get_int64(exp, &expInt) == 1) && + (gotInt == expInt); + } + else if (got->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { + same = (OSSL_PARAM_get_BN(got, &gotBn) == 1) && + (OSSL_PARAM_get_BN(exp, &expBn) == 1) && + (BN_cmp(gotBn, expBn) == 0); + BN_free(gotBn); + BN_free(expBn); + } + else if ((got->data_type == OSSL_PARAM_OCTET_STRING) || + (got->data_type == OSSL_PARAM_UTF8_STRING)) { + /* A zero size means the string is NUL terminated - not a match. */ + same = (got->data_size != 0) && (got->data_size == exp->data_size) && + (memcmp(got->data, exp->data, got->data_size) == 0); + /* OpenSSL before 3.0.8 exports the EC public key compressed. */ + if ((!same) && (got->data_type == OSSL_PARAM_OCTET_STRING) && + (XSTRCMP(got->key, OSSL_PKEY_PARAM_PUB_KEY) == 0)) { + same = test_ec_point_same((const unsigned char*)got->data, + got->data_size, (const unsigned char*)exp->data, + exp->data_size); + } + } + + return same; +} + +/** + * Key-management export callback - compare against the imported parameters. + * + * @param [in] params Parameters exported from the imported key. + * @param [in] arg Comparison state. + * @return 1 always - failures are recorded in the comparison state. + */ +static int test_export_cmp_cb(const OSSL_PARAM params[], void* arg) +{ + TEST_EXPORT_CMP* cmp = (TEST_EXPORT_CMP*)arg; + const OSSL_PARAM* exp; + int same; + int i; + int j; + + for (i = 0; (params != NULL) && (params[i].key != NULL); i++) { + exp = OSSL_PARAM_locate_const(cmp->expected, params[i].key); + if ((exp == NULL) || (exp->data_type != params[i].data_type)) { + continue; + } + same = test_param_cmp(¶ms[i], exp); + if (same == 0) { + PRINT_ERR_MSG("Imported key parameter differs: %s", params[i].key); + cmp->err = 1; + } + else if (same == 1) { + cmp->matched++; + for (j = 0; j < TEST_KEY_MATERIAL_CNT; j++) { + if (XSTRCMP(params[i].key, test_key_material[j]) == 0) { + cmp->matchedMaterial |= 1 << j; + } + } + } + } + + return 1; +} + +/** + * Check that every key-material parameter in the source was matched. + * + * @param [in] params Parameters the key was imported from. + * @param [in] cmp Comparison state after the export. + * @return 0 when all key material came back, non-zero otherwise. + */ +static int test_key_material_missing(const OSSL_PARAM* params, + const TEST_EXPORT_CMP* cmp) +{ + int err = 0; + int j; + + for (j = 0; j < TEST_KEY_MATERIAL_CNT; j++) { + if ((OSSL_PARAM_locate_const(params, test_key_material[j]) != NULL) && + ((cmp->matchedMaterial & (1 << j)) == 0)) { + PRINT_ERR_MSG("Imported key lost parameter: %s", + test_key_material[j]); + err = 1; + } + } + + return err; +} + +/** + * Run an encoder's OSSL_FUNC_ENCODER_IMPORT_OBJECT on another provider's key. + * + * Hands import-object the selection and parameters OpenSSL's encoder passes + * when the key's provider differs from the encoder's, then checks the result + * against the selected parts of the key. + * + * @param [in] algName Algorithm name of the encoder, e.g. "RSA". + * @param [in] encProps Substring of the encoder properties selecting the + * structure and output, in the order the provider + * registers them, + * e.g. "output=pem,structure=SubjectPublicKeyInfo". + * @param [in] pkey Key held by another provider. + * @param [in] selection Parts of the key to encode. + * @param [in] expectKey 1 when import must return a key holding the key + * data, 0 when import must return NULL. + * @return 0 on success, non-zero on failure. + */ +static int test_encoder_import_object_ex(const char* algName, + const char* encProps, EVP_PKEY* pkey, int selection, int expectKey) +{ + int err = 0; + const OSSL_DISPATCH* encDisp = NULL; + const OSSL_DISPATCH* kmDisp = NULL; + OSSL_FUNC_encoder_newctx_fn* newCtx = NULL; + OSSL_FUNC_encoder_freectx_fn* freeCtx = NULL; + OSSL_FUNC_encoder_import_object_fn* importObj = NULL; + OSSL_FUNC_encoder_free_object_fn* freeObj = NULL; + OSSL_FUNC_keymgmt_export_fn* kmExport = NULL; + OSSL_PARAM* params = NULL; + OSSL_PARAM* expected = NULL; + void* encCtx = NULL; + void* key = NULL; + int keyOk = 0; + int exportSel = selection; + TEST_EXPORT_CMP cmp; + + XMEMSET(&cmp, 0, sizeof(cmp)); + + PRINT_MSG("Encoder import-object %s: %s (%s)", + expectKey ? "accepts" : "rejects", algName, encProps); + + /* OpenSSL exports a private key with its public key, but passes + * import-object the caller's selection. */ + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + exportSel |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + } + + encDisp = test_prov_find(wpProv, OSSL_OP_ENCODER, algName, encProps); + err = (encDisp == NULL); + if (err) { + PRINT_ERR_MSG("No %s encoder with properties %s", algName, encProps); + } + if (err == 0) { + kmDisp = test_prov_find(wpProv, OSSL_OP_KEYMGMT, algName, NULL); + err = (kmDisp == NULL); + if (err) { + PRINT_ERR_MSG("No %s key management", algName); + } + } + if (err == 0) { + newCtx = (OSSL_FUNC_encoder_newctx_fn*)test_disp_get(encDisp, + OSSL_FUNC_ENCODER_NEWCTX); + freeCtx = (OSSL_FUNC_encoder_freectx_fn*)test_disp_get(encDisp, + OSSL_FUNC_ENCODER_FREECTX); + importObj = (OSSL_FUNC_encoder_import_object_fn*)test_disp_get(encDisp, + OSSL_FUNC_ENCODER_IMPORT_OBJECT); + freeObj = (OSSL_FUNC_encoder_free_object_fn*)test_disp_get(encDisp, + OSSL_FUNC_ENCODER_FREE_OBJECT); + kmExport = (OSSL_FUNC_keymgmt_export_fn*)test_disp_get(kmDisp, + OSSL_FUNC_KEYMGMT_EXPORT); + err = (newCtx == NULL) || (freeCtx == NULL) || (importObj == NULL) || + (freeObj == NULL) || (kmExport == NULL); + if (err) { + PRINT_ERR_MSG("Encoder is missing a dispatch entry"); + } + } + /* The parameters OpenSSL hands to import-object come from the other + * provider's key management export. */ + if (err == 0) { + err = EVP_PKEY_todata(pkey, exportSel, ¶ms) != 1; + if (err) { + PRINT_ERR_MSG("Failed to get key data"); + } + } + if ((err == 0) && expectKey) { + expected = params; + if (exportSel != selection) { + err = EVP_PKEY_todata(pkey, selection, &expected) != 1; + if (err) { + PRINT_ERR_MSG("Failed to get selected key data"); + } + } + } + if (err == 0) { + encCtx = newCtx(OSSL_PROVIDER_get0_provider_ctx(wpProv)); + err = (encCtx == NULL); + if (err) { + PRINT_ERR_MSG("Failed to create encoder context"); + } + } + if (err == 0) { + key = importObj(encCtx, selection, params); + /* A key-management import returning 1/0 lands here as 1, and the + * encoder context is not a key object either. */ + keyOk = (key != NULL) && (key != encCtx) && (key != (void*)1); + if ((!expectKey) && (key != NULL)) { + PRINT_ERR_MSG("Import object returned a key it cannot hold"); + err = 1; + } + else if (expectKey && (!keyOk)) { + PRINT_ERR_MSG("Import object did not return a key object"); + err = 1; + } + } + if ((err == 0) && expectKey) { + cmp.expected = expected; + err = kmExport(key, selection, test_export_cmp_cb, &cmp) != 1; + if (err) { + PRINT_ERR_MSG("Failed to export the imported key"); + } + } + if ((err == 0) && expectKey) { + err = cmp.err || (cmp.matched == 0) || + test_key_material_missing(expected, &cmp); + if (err) { + PRINT_ERR_MSG("Imported key does not hold the key data"); + } + } + + if (keyOk) { + freeObj(key); + } + if (encCtx != NULL) { + freeCtx(encCtx); + } + if (expected != params) { + OSSL_PARAM_free(expected); + } + OSSL_PARAM_free(params); + if (err) { + ERR_print_errors_fp(stderr); + } + else { + ERR_clear_error(); + } + + return err; +} + +/** + * Check an encoder's import-object builds a key from another provider's key. + * + * @param [in] algName Algorithm name of the encoder, e.g. "RSA". + * @param [in] encProps Substring of the encoder properties, e.g. + * "output=pem,structure=SubjectPublicKeyInfo". + * @param [in] pkey Key held by another provider. + * @param [in] selection Parts of the key to encode. + * @return 0 on success, non-zero on failure. + */ +int test_encoder_import_object(const char* algName, const char* encProps, + EVP_PKEY* pkey, int selection) +{ + return test_encoder_import_object_ex(algName, encProps, pkey, selection, + 1); +} + +/** + * Check an encoder's import-object returns NULL for a key it cannot hold. + * + * @param [in] algName Algorithm name of the encoder, e.g. "RSA". + * @param [in] encProps Substring of the encoder properties, e.g. + * "output=pem,structure=SubjectPublicKeyInfo". + * @param [in] pkey Key held by another provider. + * @param [in] selection Parts of the key to encode. + * @return 0 on success, non-zero on failure. + */ +int test_encoder_import_object_rejected(const char* algName, + const char* encProps, EVP_PKEY* pkey, int selection) +{ + return test_encoder_import_object_ex(algName, encProps, pkey, selection, + 0); +} diff --git a/test/test_rsa.c b/test/test_rsa.c index efbc9aaa..005f6036 100644 --- a/test/test_rsa.c +++ b/test/test_rsa.c @@ -3704,4 +3704,115 @@ int test_rsa_sha512_256_dupctx(void *data) } #endif /* WP_HAVE_SHA512_256 */ +/* + * Encoding a key that another provider manages goes through the encoder's + * import-object: OpenSSL hands it the encoder context and uses the key object + * it returns. + */ +int test_rsa_encoder_import_object(void *data) +{ + static const char* names[] = { + "RSA", +#ifdef WP_RSA_PSS_ENCODING + "RSA-PSS", +#endif + }; + int err = 0; + EVP_PKEY_CTX* ctx; + EVP_PKEY* pkey; + size_t bits = 2048; + OSSL_PARAM params[2]; + OSSL_PARAM_BLD* bld = NULL; + OSSL_PARAM* pubParams = NULL; + BIGNUM* n = NULL; + BIGNUM* e = NULL; + size_t i; + + (void)data; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits); + params[1] = OSSL_PARAM_construct_end(); + + /* Both key types the encoder context can carry reach wp_rsa_base_new. + * EVP_PKEY_Q_keygen() rejects RSA-PSS before OpenSSL 3.5. */ + for (i = 0; (err == 0) && (i < ARRAY_SIZE(names)); i++) { + ctx = NULL; + pkey = NULL; + + err = (ctx = EVP_PKEY_CTX_new_from_name(osslLibCtx, names[i], NULL)) + == NULL; + if (err == 0) { + err = EVP_PKEY_keygen_init(ctx) != 1; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_params(ctx, params) != 1; + } + if (err == 0) { + err = EVP_PKEY_generate(ctx, &pkey) != 1; + } + if (err) { + PRINT_ERR_MSG("Failed to generate %s key", names[i]); + } + if (err == 0) { + err = test_encoder_import_object(names[i], + "output=pem,structure=SubjectPublicKeyInfo", pkey, + EVP_PKEY_PUBLIC_KEY); + } + if (err == 0) { + err = test_encoder_import_object(names[i], + "output=der,structure=PrivateKeyInfo", pkey, + EVP_PKEY_KEYPAIR); + } + + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + } + + /* wolfProvider imports a modulus of at most 8192 bits. */ + ctx = NULL; + pkey = NULL; + if (err == 0) { + n = BN_new(); + e = BN_new(); + bld = OSSL_PARAM_BLD_new(); + err = (n == NULL) || (e == NULL) || (bld == NULL); + } + if (err == 0) { + err = (BN_set_bit(n, 16383) != 1) || (BN_set_bit(n, 0) != 1) || + (BN_set_word(e, 65537) != 1); + } + if (err == 0) { + err = (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n) != 1) || + (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e) != 1); + } + if (err == 0) { + err = (pubParams = OSSL_PARAM_BLD_to_param(bld)) == NULL; + } + if (err == 0) { + err = (ctx = EVP_PKEY_CTX_new_from_name(osslLibCtx, "RSA", NULL)) + == NULL; + } + if (err == 0) { + err = EVP_PKEY_fromdata_init(ctx) != 1; + } + if (err == 0) { + err = EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, pubParams) + != 1; + } + if (err == 0) { + err = test_encoder_import_object_rejected("RSA", + "output=pem,structure=SubjectPublicKeyInfo", pkey, + EVP_PKEY_PUBLIC_KEY); + } + + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(pubParams); + OSSL_PARAM_BLD_free(bld); + BN_free(e); + BN_free(n); + + return err; +} + #endif /* WP_HAVE_RSA */ diff --git a/test/unit.c b/test/unit.c index 2e708704..13b4c7c8 100644 --- a/test/unit.c +++ b/test/unit.c @@ -381,6 +381,7 @@ TEST_CASE test_case[] = { TEST_DECL(test_dh_weak_group_rejected, NULL), TEST_DECL(test_dh_param_check_q, NULL), TEST_DECL(test_dh_pgen_controls, NULL), + TEST_DECL(test_dh_encoder_import_object, NULL), #ifndef WOLFPROV_QUICKTEST TEST_DECL(test_dh_get_params, NULL), #endif @@ -424,6 +425,7 @@ TEST_CASE test_case[] = { TEST_DECL(test_rsa_pss_mgf1_get_params, NULL), TEST_DECL(test_rsa_kem, NULL), TEST_DECL(test_rsa_key_integrity, NULL), + TEST_DECL(test_rsa_encoder_import_object, NULL), #endif /* WP_HAVE_RSA */ #ifdef WP_HAVE_EC_P192 #ifdef WP_HAVE_ECKEYGEN @@ -552,6 +554,9 @@ TEST_CASE test_case[] = { #ifdef WP_HAVE_ECC TEST_DECL(test_ec_tls_group_p192, NULL), + #ifdef WP_HAVE_EC_P256 + TEST_DECL(test_ecc_encoder_import_object, NULL), + #endif #endif /* WP_HAVE_ECC */ #ifdef WP_HAVE_PBE @@ -584,6 +589,10 @@ TEST_CASE test_case[] = { #if defined(WP_HAVE_X25519) || defined(WP_HAVE_X448) TEST_DECL(test_ecx_x_security_bits, NULL), #endif +#if defined(WP_HAVE_X25519) || defined(WP_HAVE_ED25519) || \ + defined(WP_HAVE_X448) || defined(WP_HAVE_ED448) + TEST_DECL(test_ecx_encoder_import_object, NULL), +#endif TEST_DECL(test_pkcs7_x509_sign_verify, NULL), TEST_DECL(test_x509_cert, NULL), @@ -648,6 +657,7 @@ TEST_CASE test_case[] = { TEST_DECL(test_mldsa_reinit_null_key, NULL), TEST_DECL(test_mldsa_encode_decode, NULL), TEST_DECL(test_mldsa_x509_sign_verify, NULL), + TEST_DECL(test_mldsa_encoder_import_object, NULL), #endif #if defined(WP_HAVE_SLHDSA) && defined(WP_SLHDSA_TEST_SETS) diff --git a/test/unit.h b/test/unit.h index 9d7c1f3b..92c3eca2 100644 --- a/test/unit.h +++ b/test/unit.h @@ -369,6 +369,10 @@ int test_pki_cipher_encrypts(EVP_PKEY* pkey, const char* fmt, const char* encProp, OSSL_LIB_CTX* decLibCtx, int cmpKey); int test_epki_encode_decode(EVP_PKEY* pkey, const char* fmt, const char* encProp, OSSL_LIB_CTX* decLibCtx); +int test_encoder_import_object(const char* algName, const char* encProps, + EVP_PKEY* pkey, int selection); +int test_encoder_import_object_rejected(const char* algName, + const char* encProps, EVP_PKEY* pkey, int selection); #ifdef WP_HAVE_RSA int test_pkey_enc_rsa(EVP_PKEY *pkey, unsigned char *msg, size_t msgLen, @@ -410,6 +414,7 @@ int test_rsa_kem_prefix_match(void* data); int test_rsa_pss_mgf1_get_params(void *data); int test_rsa_kem(void *data); int test_rsa_key_integrity(void* data); +int test_rsa_encoder_import_object(void *data); #endif /* WP_HAVE_RSA */ #ifdef WP_HAVE_DH @@ -423,6 +428,7 @@ int test_dh_encode_epki(void *data); int test_dh_decode(void *data); int test_dh_decode_big_g(void *data); int test_dh_get_params(void *data); +int test_dh_encoder_import_object(void *data); int test_dh_krb5_keygen(void *data); int test_dh_pad(void *data); int test_dh_derive_small_buffer(void *data); @@ -585,6 +591,7 @@ int test_ec_tls_group_p192(void* data); #ifdef WP_HAVE_EC_P256 int test_ec_print_public(void* data); int test_ec_fromdata_oversize(void* data); +int test_ecc_encoder_import_object(void *data); #endif #endif /* WP_HAVE_ECC */ @@ -619,6 +626,11 @@ int test_ecx_shared_key_first_use(void *data); int test_ecx_x_security_bits(void *data); #endif +#if defined(WP_HAVE_X25519) || defined(WP_HAVE_ED25519) || \ + defined(WP_HAVE_X448) || defined(WP_HAVE_ED448) +int test_ecx_encoder_import_object(void *data); +#endif + int test_pkcs7_x509_sign_verify(void *data); int test_x509_cert(void *data); @@ -683,6 +695,7 @@ int test_mldsa_empty_message(void *data); int test_mldsa_reinit_null_key(void *data); int test_mldsa_encode_decode(void *data); int test_mldsa_x509_sign_verify(void *data); +int test_mldsa_encoder_import_object(void *data); #endif #if defined(WP_HAVE_SLHDSA) && defined(WP_SLHDSA_TEST_SETS)