From 78043fe898f4dac862a515f9a1b1bbe6dda22951 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 30 Mar 2021 17:41:03 +0200 Subject: Add "save-parameters" encoder parameter The parameter makes the dsa key encoder to skip saving the DSA key parameters similarly to what the legacy dsa key encoder did. Fixes #14362 Reviewed-by: Richard Levitte Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/14746) --- crypto/encode_decode/encoder_pkey.c | 8 +++ doc/man7/provider-encoder.pod | 5 ++ include/openssl/core_names.h | 1 + .../implementations/encode_decode/encode_key2any.c | 60 +++++++++++----------- 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c index 713aa44131..0c2207f54d 100644 --- a/crypto/encode_decode/encoder_pkey.c +++ b/crypto/encode_decode/encoder_pkey.c @@ -327,6 +327,14 @@ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_for_pkey(const EVP_PKEY *pkey, && OSSL_ENCODER_CTX_set_selection(ctx, selection) && ossl_encoder_ctx_setup_for_pkey(ctx, pkey, selection, propquery) && OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int save_parameters = pkey->save_parameters; + + params[0] = OSSL_PARAM_construct_int(OSSL_ENCODER_PARAM_SAVE_PARAMETERS, + &save_parameters); + /* ignoring error as this is only auxiliary parameter */ + (void)OSSL_ENCODER_CTX_set_params(ctx, params); + OSSL_TRACE_BEGIN(ENCODER) { BIO_printf(trc_out, "(ctx %p) Got %d encoders\n", (void *)ctx, OSSL_ENCODER_CTX_get_num_encoders(ctx)); diff --git a/doc/man7/provider-encoder.pod b/doc/man7/provider-encoder.pod index 5e34b7a394..7911289cfe 100644 --- a/doc/man7/provider-encoder.pod +++ b/doc/man7/provider-encoder.pod @@ -303,6 +303,11 @@ However, it is recommended that implementations that do not handle property strings return an error on receiving this parameter unless its value NULL or the empty string. +=item "save-parameters" (B) + +If set to 0 disables saving of key domain parameters. Default is 1. +It currently has an effect only on DSA keys. + =back Parameters currently recognised by the built-in pass phrase callback: diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index ab669cfd3f..7c00109621 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -473,6 +473,7 @@ extern "C" { #define OSSL_ENCODER_PARAM_OUTPUT_STRUCTURE "output-structure" /* Currently PVK only, but reusable for others as needed */ #define OSSL_ENCODER_PARAM_ENCRYPT_LEVEL "encrypt-level" +#define OSSL_ENCODER_PARAM_SAVE_PARAMETERS "save-parameters" /* integer */ #define OSSL_DECODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES #define OSSL_DECODER_PARAM_INPUT_TYPE "input-type" diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index 1647b9fdb5..93f725d906 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -43,6 +43,9 @@ struct key2any_ctx_st { PROV_CTX *provctx; + /* Set to 0 if parameters should not be saved (dsa only) */ + int save_parameters; + /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */ int cipher_intent; @@ -52,7 +55,7 @@ struct key2any_ctx_st { }; typedef int check_key_type_fn(const void *key, int nid); -typedef int key_to_paramstring_fn(const void *key, int nid, +typedef int key_to_paramstring_fn(const void *key, int nid, int save, void **str, int *strtype); typedef int key_to_der_fn(BIO *out, const void *key, int key_nid, const char *pemname, @@ -174,7 +177,8 @@ static int key_to_pkcs8_der_priv_bio(BIO *out, const void *key, void *str = NULL; int strtype = V_ASN1_UNDEF; - if (p2s != NULL && !p2s(key, key_nid, &str, &strtype)) + if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, + &str, &strtype)) return 0; if (ctx->cipher_intent) { @@ -210,7 +214,8 @@ static int key_to_pkcs8_pem_priv_bio(BIO *out, const void *key, void *str = NULL; int strtype = V_ASN1_UNDEF; - if (p2s != NULL && !p2s(key, key_nid, &str, &strtype)) + if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, + &str, &strtype)) return 0; if (ctx->cipher_intent) { @@ -247,7 +252,8 @@ static int key_to_spki_der_pub_bio(BIO *out, const void *key, int strtype = V_ASN1_UNDEF; X509_PUBKEY *xpk = NULL; - if (p2s != NULL && !p2s(key, key_nid, &str, &strtype)) + if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, + &str, &strtype)) return 0; xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); @@ -272,7 +278,8 @@ static int key_to_spki_pem_pub_bio(BIO *out, const void *key, int strtype = V_ASN1_UNDEF; X509_PUBKEY *xpk = NULL; - if (p2s != NULL && !p2s(key, key_nid, &str, &strtype)) + if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, + &str, &strtype)) return 0; xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); @@ -374,7 +381,7 @@ static int key_to_type_specific_pem_param_bio(BIO *out, const void *key, /* ---------------------------------------------------------------------- */ #ifndef OPENSSL_NO_DH -static int prepare_dh_params(const void *dh, int nid, +static int prepare_dh_params(const void *dh, int nid, int save, void **pstr, int *pstrtype) { ASN1_STRING *params = ASN1_STRING_new(); @@ -476,8 +483,8 @@ static int dh_check_key_type(const void *dh, int expected_type) /* ---------------------------------------------------------------------- */ #ifndef OPENSSL_NO_DSA -static int prepare_some_dsa_params(const void *dsa, int nid, - void **pstr, int *pstrtype) +static int encode_dsa_params(const void *dsa, int nid, + void **pstr, int *pstrtype) { ASN1_STRING *params = ASN1_STRING_new(); @@ -499,35 +506,21 @@ static int prepare_some_dsa_params(const void *dsa, int nid, return 1; } -static int prepare_all_dsa_params(const void *dsa, int nid, - void **pstr, int *pstrtype) +static int prepare_dsa_params(const void *dsa, int nid, int save, + void **pstr, int *pstrtype) { const BIGNUM *p = DSA_get0_p(dsa); const BIGNUM *q = DSA_get0_q(dsa); const BIGNUM *g = DSA_get0_g(dsa); - if (p != NULL && q != NULL && g != NULL) - return prepare_some_dsa_params(dsa, nid, pstr, pstrtype); + if (save && p != NULL && q != NULL && g != NULL) + return encode_dsa_params(dsa, nid, pstr, pstrtype); *pstr = NULL; *pstrtype = V_ASN1_UNDEF; return 1; } -static int prepare_dsa_params(const void *dsa, int nid, - void **pstr, int *pstrtype) -{ - /* - * TODO(v3.0) implement setting save_parameters, see dsa_pub_encode() - * in crypto/dsa/dsa_ameth.c - */ - int save_parameters = 1; - - return save_parameters - ? prepare_all_dsa_params(dsa, nid, pstr, pstrtype) - : prepare_some_dsa_params(dsa, nid, pstr, pstrtype); -} - static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder) { const BIGNUM *bn = NULL; @@ -610,7 +603,7 @@ static int prepare_ec_explicit_params(const void *eckey, * is a curve name (curve nid) to be found or not. See RFC 3279 for details. * TODO: shouldn't we use i2d_ECPKParameters()? */ -static int prepare_ec_params(const void *eckey, int nid, +static int prepare_ec_params(const void *eckey, int nid, int save, void **pstr, int *pstrtype) { int curve_nid; @@ -763,7 +756,7 @@ static int ecx_pkcs8_priv_to_der(const void *vecxkey, unsigned char **pder) * functionality doesn't allow that. */ -static int prepare_rsa_params(const void *rsa, int nid, +static int prepare_rsa_params(const void *rsa, int nid, int save, void **pstr, int *pstrtype) { const RSA_PSS_PARAMS_30 *pss = ossl_rsa_get0_pss_params_30((RSA *)rsa); @@ -871,8 +864,10 @@ static void *key2any_newctx(void *provctx) { struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx != NULL) + if (ctx != NULL) { ctx->provctx = provctx; + ctx->save_parameters = 1; + } return ctx; } @@ -946,6 +941,8 @@ static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[]) OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER); const OSSL_PARAM *propsp = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES); + const OSSL_PARAM *save_paramsp = + OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_SAVE_PARAMETERS); if (cipherp != NULL) { const char *ciphername = NULL; @@ -964,6 +961,11 @@ static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[]) EVP_CIPHER_fetch(libctx, ciphername, props)) == NULL)) return 0; } + + if (save_paramsp != NULL) { + if (!OSSL_PARAM_get_int(save_paramsp, &ctx->save_parameters)) + return 0; + } return 1; } -- cgit v1.2.3