aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/openssl/crypto/x509/x_pubkey.c
diff options
context:
space:
mode:
authordeshevoy <deshevoy@yandex-team.ru>2022-02-10 16:46:57 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:46:57 +0300
commit28148f76dbfcc644d96427d41c92f36cbf2fdc6e (patch)
treeb83306b6e37edeea782e9eed673d89286c4fef35 /contrib/libs/openssl/crypto/x509/x_pubkey.c
parente988f30484abe5fdeedcc7a5d3c226c01a21800c (diff)
downloadydb-28148f76dbfcc644d96427d41c92f36cbf2fdc6e.tar.gz
Restoring authorship annotation for <deshevoy@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/openssl/crypto/x509/x_pubkey.c')
-rw-r--r--contrib/libs/openssl/crypto/x509/x_pubkey.c738
1 files changed, 369 insertions, 369 deletions
diff --git a/contrib/libs/openssl/crypto/x509/x_pubkey.c b/contrib/libs/openssl/crypto/x509/x_pubkey.c
index e1af863664..9be7e92865 100644
--- a/contrib/libs/openssl/crypto/x509/x_pubkey.c
+++ b/contrib/libs/openssl/crypto/x509/x_pubkey.c
@@ -1,378 +1,378 @@
-/*
+/*
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include "internal/cryptlib.h"
-#include <openssl/asn1t.h>
-#include <openssl/x509.h>
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
#include "crypto/asn1.h"
#include "crypto/evp.h"
#include "crypto/x509.h"
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-
-struct X509_pubkey_st {
- X509_ALGOR *algor;
- ASN1_BIT_STRING *public_key;
- EVP_PKEY *pkey;
-};
-
-static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key);
-
-/* Minor tweak to operation: free up EVP_PKEY */
-static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg)
-{
- if (operation == ASN1_OP_FREE_POST) {
- X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
- EVP_PKEY_free(pubkey->pkey);
- } else if (operation == ASN1_OP_D2I_POST) {
- /* Attempt to decode public key and cache in pubkey structure. */
- X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
- EVP_PKEY_free(pubkey->pkey);
- pubkey->pkey = NULL;
- /*
- * Opportunistically decode the key but remove any non fatal errors
- * from the queue. Subsequent explicit attempts to decode/use the key
- * will return an appropriate error.
- */
- ERR_set_mark();
- if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1)
- return 0;
- ERR_pop_to_mark();
- }
- return 1;
-}
-
-ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
- ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
- ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
-} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
-
-IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
-
-int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
-{
- X509_PUBKEY *pk = NULL;
-
- if (x == NULL)
- return 0;
-
- if ((pk = X509_PUBKEY_new()) == NULL)
- goto error;
-
- if (pkey->ameth) {
- if (pkey->ameth->pub_encode) {
- if (!pkey->ameth->pub_encode(pk, pkey)) {
- X509err(X509_F_X509_PUBKEY_SET,
- X509_R_PUBLIC_KEY_ENCODE_ERROR);
- goto error;
- }
- } else {
- X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
- goto error;
- }
- } else {
- X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
- goto error;
- }
-
- X509_PUBKEY_free(*x);
- *x = pk;
- pk->pkey = pkey;
- EVP_PKEY_up_ref(pkey);
- return 1;
-
- error:
- X509_PUBKEY_free(pk);
- return 0;
-}
-
-/*
- * Attempt to decode a public key.
- * Returns 1 on success, 0 for a decode failure and -1 for a fatal
- * error e.g. malloc failure.
- */
-
-
-static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key)
-{
- EVP_PKEY *pkey = EVP_PKEY_new();
-
- if (pkey == NULL) {
- X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE);
- return -1;
- }
-
- if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) {
- X509err(X509_F_X509_PUBKEY_DECODE, X509_R_UNSUPPORTED_ALGORITHM);
- goto error;
- }
-
- if (pkey->ameth->pub_decode) {
- /*
- * Treat any failure of pub_decode as a decode error. In
- * future we could have different return codes for decode
- * errors and fatal errors such as malloc failure.
- */
- if (!pkey->ameth->pub_decode(pkey, key)) {
- X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR);
- goto error;
- }
- } else {
- X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED);
- goto error;
- }
-
- *ppkey = pkey;
- return 1;
-
- error:
- EVP_PKEY_free(pkey);
- return 0;
-}
-
-EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key)
-{
- EVP_PKEY *ret = NULL;
-
- if (key == NULL || key->public_key == NULL)
- return NULL;
-
- if (key->pkey != NULL)
- return key->pkey;
-
- /*
- * When the key ASN.1 is initially parsed an attempt is made to
- * decode the public key and cache the EVP_PKEY structure. If this
- * operation fails the cached value will be NULL. Parsing continues
- * to allow parsing of unknown key types or unsupported forms.
- * We repeat the decode operation so the appropriate errors are left
- * in the queue.
- */
- x509_pubkey_decode(&ret, key);
- /* If decode doesn't fail something bad happened */
- if (ret != NULL) {
- X509err(X509_F_X509_PUBKEY_GET0, ERR_R_INTERNAL_ERROR);
- EVP_PKEY_free(ret);
- }
-
- return NULL;
-}
-
-EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
-{
- EVP_PKEY *ret = X509_PUBKEY_get0(key);
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+struct X509_pubkey_st {
+ X509_ALGOR *algor;
+ ASN1_BIT_STRING *public_key;
+ EVP_PKEY *pkey;
+};
+
+static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key);
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ if (operation == ASN1_OP_FREE_POST) {
+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+ EVP_PKEY_free(pubkey->pkey);
+ } else if (operation == ASN1_OP_D2I_POST) {
+ /* Attempt to decode public key and cache in pubkey structure. */
+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+ EVP_PKEY_free(pubkey->pkey);
+ pubkey->pkey = NULL;
+ /*
+ * Opportunistically decode the key but remove any non fatal errors
+ * from the queue. Subsequent explicit attempts to decode/use the key
+ * will return an appropriate error.
+ */
+ ERR_set_mark();
+ if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1)
+ return 0;
+ ERR_pop_to_mark();
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
+ ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
+{
+ X509_PUBKEY *pk = NULL;
+
+ if (x == NULL)
+ return 0;
+
+ if ((pk = X509_PUBKEY_new()) == NULL)
+ goto error;
+
+ if (pkey->ameth) {
+ if (pkey->ameth->pub_encode) {
+ if (!pkey->ameth->pub_encode(pk, pkey)) {
+ X509err(X509_F_X509_PUBKEY_SET,
+ X509_R_PUBLIC_KEY_ENCODE_ERROR);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
+ goto error;
+ }
+
+ X509_PUBKEY_free(*x);
+ *x = pk;
+ pk->pkey = pkey;
+ EVP_PKEY_up_ref(pkey);
+ return 1;
+
+ error:
+ X509_PUBKEY_free(pk);
+ return 0;
+}
+
+/*
+ * Attempt to decode a public key.
+ * Returns 1 on success, 0 for a decode failure and -1 for a fatal
+ * error e.g. malloc failure.
+ */
+
+
+static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key)
+{
+ EVP_PKEY *pkey = EVP_PKEY_new();
+
+ if (pkey == NULL) {
+ X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) {
+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_UNSUPPORTED_ALGORITHM);
+ goto error;
+ }
+
+ if (pkey->ameth->pub_decode) {
+ /*
+ * Treat any failure of pub_decode as a decode error. In
+ * future we could have different return codes for decode
+ * errors and fatal errors such as malloc failure.
+ */
+ if (!pkey->ameth->pub_decode(pkey, key)) {
+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+
+ *ppkey = pkey;
+ return 1;
+
+ error:
+ EVP_PKEY_free(pkey);
+ return 0;
+}
+
+EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key)
+{
+ EVP_PKEY *ret = NULL;
+
+ if (key == NULL || key->public_key == NULL)
+ return NULL;
+
+ if (key->pkey != NULL)
+ return key->pkey;
+
+ /*
+ * When the key ASN.1 is initially parsed an attempt is made to
+ * decode the public key and cache the EVP_PKEY structure. If this
+ * operation fails the cached value will be NULL. Parsing continues
+ * to allow parsing of unknown key types or unsupported forms.
+ * We repeat the decode operation so the appropriate errors are left
+ * in the queue.
+ */
+ x509_pubkey_decode(&ret, key);
+ /* If decode doesn't fail something bad happened */
+ if (ret != NULL) {
+ X509err(X509_F_X509_PUBKEY_GET0, ERR_R_INTERNAL_ERROR);
+ EVP_PKEY_free(ret);
+ }
+
+ return NULL;
+}
+
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
+{
+ EVP_PKEY *ret = X509_PUBKEY_get0(key);
if (ret != NULL && !EVP_PKEY_up_ref(ret)) {
X509err(X509_F_X509_PUBKEY_GET, ERR_R_INTERNAL_ERROR);
ret = NULL;
}
- return ret;
-}
-
-/*
- * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
- * decode as X509_PUBKEY
- */
-
-EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
-{
- X509_PUBKEY *xpk;
- EVP_PKEY *pktmp;
- const unsigned char *q;
- q = *pp;
- xpk = d2i_X509_PUBKEY(NULL, &q, length);
- if (!xpk)
- return NULL;
- pktmp = X509_PUBKEY_get(xpk);
- X509_PUBKEY_free(xpk);
- if (!pktmp)
- return NULL;
- *pp = q;
- if (a) {
- EVP_PKEY_free(*a);
- *a = pktmp;
- }
- return pktmp;
-}
-
-int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
-{
- X509_PUBKEY *xpk = NULL;
- int ret;
- if (!a)
- return 0;
- if (!X509_PUBKEY_set(&xpk, a))
- return -1;
- ret = i2d_X509_PUBKEY(xpk, pp);
- X509_PUBKEY_free(xpk);
- return ret;
-}
-
-/*
- * The following are equivalents but which return RSA and DSA keys
- */
-#ifndef OPENSSL_NO_RSA
-RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
-{
- EVP_PKEY *pkey;
- RSA *key;
- const unsigned char *q;
- q = *pp;
- pkey = d2i_PUBKEY(NULL, &q, length);
- if (!pkey)
- return NULL;
- key = EVP_PKEY_get1_RSA(pkey);
- EVP_PKEY_free(pkey);
- if (!key)
- return NULL;
- *pp = q;
- if (a) {
- RSA_free(*a);
- *a = key;
- }
- return key;
-}
-
-int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
-{
- EVP_PKEY *pktmp;
- int ret;
- if (!a)
- return 0;
- pktmp = EVP_PKEY_new();
- if (pktmp == NULL) {
- ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- EVP_PKEY_set1_RSA(pktmp, a);
- ret = i2d_PUBKEY(pktmp, pp);
- EVP_PKEY_free(pktmp);
- return ret;
-}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
-{
- EVP_PKEY *pkey;
- DSA *key;
- const unsigned char *q;
- q = *pp;
- pkey = d2i_PUBKEY(NULL, &q, length);
- if (!pkey)
- return NULL;
- key = EVP_PKEY_get1_DSA(pkey);
- EVP_PKEY_free(pkey);
- if (!key)
- return NULL;
- *pp = q;
- if (a) {
- DSA_free(*a);
- *a = key;
- }
- return key;
-}
-
-int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
-{
- EVP_PKEY *pktmp;
- int ret;
- if (!a)
- return 0;
- pktmp = EVP_PKEY_new();
- if (pktmp == NULL) {
- ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- EVP_PKEY_set1_DSA(pktmp, a);
- ret = i2d_PUBKEY(pktmp, pp);
- EVP_PKEY_free(pktmp);
- return ret;
-}
-#endif
-
-#ifndef OPENSSL_NO_EC
-EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
-{
- EVP_PKEY *pkey;
- EC_KEY *key;
- const unsigned char *q;
- q = *pp;
- pkey = d2i_PUBKEY(NULL, &q, length);
- if (!pkey)
- return NULL;
- key = EVP_PKEY_get1_EC_KEY(pkey);
- EVP_PKEY_free(pkey);
- if (!key)
- return NULL;
- *pp = q;
- if (a) {
- EC_KEY_free(*a);
- *a = key;
- }
- return key;
-}
-
-int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
-{
- EVP_PKEY *pktmp;
- int ret;
- if (!a)
- return 0;
- if ((pktmp = EVP_PKEY_new()) == NULL) {
- ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- EVP_PKEY_set1_EC_KEY(pktmp, a);
- ret = i2d_PUBKEY(pktmp, pp);
- EVP_PKEY_free(pktmp);
- return ret;
-}
-#endif
-
-int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
- int ptype, void *pval,
- unsigned char *penc, int penclen)
-{
- if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
- return 0;
- if (penc) {
- OPENSSL_free(pub->public_key->data);
- pub->public_key->data = penc;
- pub->public_key->length = penclen;
- /* Set number of unused bits to zero */
- pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
- pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
- }
- return 1;
-}
-
-int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
- const unsigned char **pk, int *ppklen,
- X509_ALGOR **pa, X509_PUBKEY *pub)
-{
- if (ppkalg)
- *ppkalg = pub->algor->algorithm;
- if (pk) {
- *pk = pub->public_key->data;
- *ppklen = pub->public_key->length;
- }
- if (pa)
- *pa = pub->algor;
- return 1;
-}
-
-ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
-{
- if (x == NULL)
- return NULL;
- return x->cert_info.key->public_key;
-}
+ return ret;
+}
+
+/*
+ * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
+ * decode as X509_PUBKEY
+ */
+
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
+{
+ X509_PUBKEY *xpk;
+ EVP_PKEY *pktmp;
+ const unsigned char *q;
+ q = *pp;
+ xpk = d2i_X509_PUBKEY(NULL, &q, length);
+ if (!xpk)
+ return NULL;
+ pktmp = X509_PUBKEY_get(xpk);
+ X509_PUBKEY_free(xpk);
+ if (!pktmp)
+ return NULL;
+ *pp = q;
+ if (a) {
+ EVP_PKEY_free(*a);
+ *a = pktmp;
+ }
+ return pktmp;
+}
+
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
+{
+ X509_PUBKEY *xpk = NULL;
+ int ret;
+ if (!a)
+ return 0;
+ if (!X509_PUBKEY_set(&xpk, a))
+ return -1;
+ ret = i2d_X509_PUBKEY(xpk, pp);
+ X509_PUBKEY_free(xpk);
+ return ret;
+}
+
+/*
+ * The following are equivalents but which return RSA and DSA keys
+ */
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ RSA *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ RSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ pktmp = EVP_PKEY_new();
+ if (pktmp == NULL) {
+ ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ EVP_PKEY_set1_RSA(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ DSA *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_DSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ DSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ pktmp = EVP_PKEY_new();
+ if (pktmp == NULL) {
+ ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ EVP_PKEY_set1_DSA(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ EC_KEY *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_EC_KEY(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ EC_KEY_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ if ((pktmp = EVP_PKEY_new()) == NULL) {
+ ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ EVP_PKEY_set1_EC_KEY(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+ int ptype, void *pval,
+ unsigned char *penc, int penclen)
+{
+ if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+ return 0;
+ if (penc) {
+ OPENSSL_free(pub->public_key->data);
+ pub->public_key->data = penc;
+ pub->public_key->length = penclen;
+ /* Set number of unused bits to zero */
+ pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ }
+ return 1;
+}
+
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+ const unsigned char **pk, int *ppklen,
+ X509_ALGOR **pa, X509_PUBKEY *pub)
+{
+ if (ppkalg)
+ *ppkalg = pub->algor->algorithm;
+ if (pk) {
+ *pk = pub->public_key->data;
+ *ppklen = pub->public_key->length;
+ }
+ if (pa)
+ *pa = pub->algor;
+ return 1;
+}
+
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
+{
+ if (x == NULL)
+ return NULL;
+ return x->cert_info.key->public_key;
+}