From: Richard Levitte Date: Tue, 23 Feb 2021 21:39:39 +0000 (+0100) Subject: Modify i2d_PublicKey() so it can get an EC public key as a blob X-Git-Tag: openssl-3.0.0-alpha13~147 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8ab9c4ddc41830a9bd1be36a8e37ee2abc57e886;p=thirdparty%2Fopenssl.git Modify i2d_PublicKey() so it can get an EC public key as a blob This introduces the encoder output type "blob", to be used for anything that outputs an unstructured blob of data. Fixes #14258 Reviewed-by: Tomas Mraz Reviewed-by: Ben Kaduk (Merged from https://github.com/openssl/openssl/pull/14291) --- diff --git a/crypto/asn1/i2d_evp.c b/crypto/asn1/i2d_evp.c index 6e4f7080c7b..ffcb34aa207 100644 --- a/crypto/asn1/i2d_evp.c +++ b/crypto/asn1/i2d_evp.c @@ -25,16 +25,21 @@ #include "crypto/asn1.h" #include "crypto/evp.h" +struct type_and_structure_st { + const char *output_type; + const char *output_structure; +}; + static int i2d_provided(const EVP_PKEY *a, int selection, - const char *output_structures[], + const struct type_and_structure_st *output_info, unsigned char **pp) { OSSL_ENCODER_CTX *ctx = NULL; int ret; for (ret = -1; - ret == -1 && *output_structures != NULL; - output_structures++) { + ret == -1 && output_info->output_type != NULL; + output_info++) { /* * The i2d_ calls don't take a boundary length for *pp. However, * OSSL_ENCODER_CTX_get_num_encoders() needs one, so we make one @@ -42,8 +47,10 @@ static int i2d_provided(const EVP_PKEY *a, int selection, */ size_t len = INT_MAX; - ctx = OSSL_ENCODER_CTX_new_for_pkey(a, selection, "DER", - *output_structures, NULL); + ctx = OSSL_ENCODER_CTX_new_for_pkey(a, selection, + output_info->output_type, + output_info->output_structure, + NULL); if (ctx == NULL) return -1; if (OSSL_ENCODER_to_data(ctx, pp, &len)) @@ -60,9 +67,12 @@ static int i2d_provided(const EVP_PKEY *a, int selection, int i2d_KeyParams(const EVP_PKEY *a, unsigned char **pp) { if (evp_pkey_is_provided(a)) { - const char *output_structures[] = { "type-specific", NULL }; + static const struct type_and_structure_st output_info[] = { + { "DER", "type-specific" }, + { NULL, } + }; - return i2d_provided(a, EVP_PKEY_KEY_PARAMETERS, output_structures, pp); + return i2d_provided(a, EVP_PKEY_KEY_PARAMETERS, output_info, pp); } if (a->ameth != NULL && a->ameth->param_encode != NULL) return a->ameth->param_encode(a, pp); @@ -78,9 +88,13 @@ int i2d_KeyParams_bio(BIO *bp, const EVP_PKEY *pkey) int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp) { if (evp_pkey_is_provided(a)) { - const char *output_structures[] = { "type-specific", "pkcs8", NULL }; + static const struct type_and_structure_st output_info[] = { + { "DER", "type-specific" }, + { "DER", "pkcs8" }, + { NULL, } + }; - return i2d_provided(a, EVP_PKEY_KEYPAIR, output_structures, pp); + return i2d_provided(a, EVP_PKEY_KEYPAIR, output_info, pp); } if (a->ameth != NULL && a->ameth->old_priv_encode != NULL) { return a->ameth->old_priv_encode(a, pp); @@ -102,9 +116,13 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp) int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp) { if (evp_pkey_is_provided(a)) { - const char *output_structures[] = { "type-specific", NULL }; + static const struct type_and_structure_st output_info[] = { + { "DER", "type-specific" }, + { "blob", NULL }, /* for EC */ + { NULL, } + }; - return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_structures, pp); + return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_info, pp); } switch (EVP_PKEY_id(a)) { case EVP_PKEY_RSA: