summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2021-02-23 22:39:39 +0100
committerRichard Levitte <levitte@openssl.org>2021-02-27 16:14:09 +0100
commit8ab9c4ddc41830a9bd1be36a8e37ee2abc57e886 (patch)
treea5ecac48f22731b8c5a4405749d5a6f483bb5b62 /crypto
parent3d364726606424f760211b5015920410ea9c8f0d (diff)
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 <tomas@openssl.org> Reviewed-by: Ben Kaduk <kaduk@mit.edu> (Merged from https://github.com/openssl/openssl/pull/14291)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asn1/i2d_evp.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/crypto/asn1/i2d_evp.c b/crypto/asn1/i2d_evp.c
index 6e4f7080c7..ffcb34aa20 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: