X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fx509%2Fx_pubkey.c;h=c240a5f5677f9ea3056eb2c531b6df3778744a54;hp=a583813b5869fdb39987c901003d760a2e82ef59;hb=7674e92324648b59786d86d8e9014bbaed4e6d07;hpb=a076951b71a1837e68eaf6bfd92e6a4d40b0940a diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index a583813b58..c240a5f567 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -24,7 +30,7 @@ struct X509_pubkey_st { EVP_PKEY *pkey; }; -static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key); +static int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key); /* Minor tweak to operation: free up EVP_PKEY */ static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, @@ -85,9 +91,9 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED); goto error; } - } else if (pkey->pkeys[0].keymgmt != NULL) { + } else if (pkey->keymgmt != NULL) { BIO *bmem = BIO_new(BIO_s_mem()); - const char *serprop = "format=der,type=public"; + const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ; OSSL_SERIALIZER_CTX *sctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, serprop); @@ -145,7 +151,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) */ -static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) +static int x509_pubkey_decode(EVP_PKEY **ppkey, const X509_PUBKEY *key) { EVP_PKEY *pkey = EVP_PKEY_new(); @@ -182,7 +188,7 @@ static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) return 0; } -EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key) +EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key) { EVP_PKEY *ret = NULL; @@ -210,11 +216,14 @@ EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key) return NULL; } -EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) +EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key) { EVP_PKEY *ret = X509_PUBKEY_get0(key); - if (ret != NULL) - EVP_PKEY_up_ref(ret); + + if (ret != NULL && !EVP_PKEY_up_ref(ret)) { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_INTERNAL_ERROR); + ret = NULL; + } return ret; } @@ -247,21 +256,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->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; } @@ -413,7 +453,7 @@ int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, X509_PUBKEY *pub) + X509_ALGOR **pa, const X509_PUBKEY *pub) { if (ppkalg) *ppkalg = pub->algor->algorithm;