diff options
author | Richard Levitte <levitte@openssl.org> | 2020-02-12 18:58:15 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2020-02-14 14:17:22 +0100 |
commit | cdb16632636c4a1a439449d110f94cad15d2e9fe (patch) | |
tree | 2f37613d27a46a39a39e9e369c2081fab9c0f1d3 /crypto/x509 | |
parent | 3e686afd04a99e64b70a7c2ef488459ed10ad392 (diff) |
Adapt i2d_PUBKEY for provider only keys
It uses EVP_PKEY serializers to get the desired results.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11078)
Diffstat (limited to 'crypto/x509')
-rw-r--r-- | crypto/x509/x_pubkey.c | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index f74c156652..f79a57cb7d 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -253,21 +253,52 @@ EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) { - X509_PUBKEY *xpk = NULL; int ret = -1; if (a == NULL) return 0; - if ((xpk = X509_PUBKEY_new()) == NULL) - return -1; - if (a->ameth != NULL && a->ameth->pub_encode != NULL - && !a->ameth->pub_encode(xpk, a)) - goto error; - xpk->pkey = (EVP_PKEY *)a; - ret = i2d_X509_PUBKEY(xpk, pp); - xpk->pkey = NULL; - error: - X509_PUBKEY_free(xpk); + if (a->ameth != NULL) { + X509_PUBKEY *xpk = NULL; + + if ((xpk = X509_PUBKEY_new()) == NULL) + return -1; + + /* pub_encode() only encode parameters, not the key itself */ + if (a->ameth->pub_encode != NULL && a->ameth->pub_encode(xpk, a)) { + xpk->pkey = (EVP_PKEY *)a; + ret = i2d_X509_PUBKEY(xpk, pp); + xpk->pkey = NULL; + } + X509_PUBKEY_free(xpk); + } else if (a->pkeys[0].keymgmt != NULL) { + const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ; + OSSL_SERIALIZER_CTX *ctx = + OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop); + BIO *out = BIO_new(BIO_s_mem()); + BUF_MEM *buf = NULL; + + if (ctx != NULL + && out != NULL + && OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL + && OSSL_SERIALIZER_to_bio(ctx, out) + && BIO_get_mem_ptr(out, &buf) > 0) { + ret = buf->length; + + if (pp != NULL) { + if (*pp == NULL) { + *pp = (unsigned char *)buf->data; + buf->length = 0; + buf->data = NULL; + } else { + memcpy(*pp, buf->data, ret); + *pp += ret; + } + } + } + BIO_free(out); + OSSL_SERIALIZER_CTX_free(ctx); + } + return ret; } |