/*
 * Copyright 1995-2021 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
 * in the file LICENSE in the source distribution or at
 * 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 <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>
#include <openssl/decoder.h>
#include <openssl/encoder.h>
#include "internal/provider.h"
#include "internal/sizes.h"

struct X509_pubkey_st {
    X509_ALGOR *algor;
    ASN1_BIT_STRING *public_key;

    EVP_PKEY *pkey;

    /* extra data for the callback, used by d2i_PUBKEY_ex */
    OSSL_LIB_CTX *libctx;
    char *propq;

    /* Flag to force legacy keys */
    unsigned int flag_force_legacy : 1;
};

static int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key);

static int x509_pubkey_set0_libctx(X509_PUBKEY *x, OSSL_LIB_CTX *libctx,
                                   const char *propq)
{
    if (x != NULL) {
        x->libctx = libctx;
        OPENSSL_free(x->propq);
        x->propq = NULL;
        if (propq != NULL) {
            x->propq = OPENSSL_strdup(propq);
            if (x->propq == NULL)
                return 0;
        }
    }
    return 1;
}

ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = {
        ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
        ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
} static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL)

static void x509_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;

    X509_ALGOR_free(pubkey->algor);
    ASN1_BIT_STRING_free(pubkey->public_key);
    EVP_PKEY_free(pubkey->pkey);
    OPENSSL_free(pubkey);
    *pval = NULL;
}

static int x509_pubkey_ex_populate(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;

    return (pubkey->algor != NULL
            || (pubkey->algor = X509_ALGOR_new()) != NULL)
        && (pubkey->public_key != NULL
            || (pubkey->public_key = ASN1_BIT_STRING_new()) != NULL);
}

static int x509_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    X509_PUBKEY *ret;

    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL
        || !x509_pubkey_ex_populate((ASN1_VALUE **)&ret, NULL)) {
        x509_pubkey_ex_free((ASN1_VALUE **)&ret, NULL);
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
    } else {
        *pval = (ASN1_VALUE *)ret;
    }

    return ret != NULL;
}

static int x509_pubkey_ex_d2i(ASN1_VALUE **pval,
                              const unsigned char **in, long len,
                              const ASN1_ITEM *it, int tag, int aclass,
                              char opt, ASN1_TLC *ctx)
{
    const unsigned char *in_saved = *in;
    X509_PUBKEY *pubkey;
    int ret;
    OSSL_DECODER_CTX *dctx = NULL;

    if (*pval == NULL && !x509_pubkey_ex_new(pval, it))
        return 0;
    if (!x509_pubkey_ex_populate(pval, NULL)) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    /* This ensures that |*in| advances properly no matter what */
    if ((ret = ASN1_item_ex_d2i(pval, in, len,
                                ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL),
                                tag, aclass, opt, ctx)) <= 0)
        return ret;

    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();

    /*
     * Try to decode with legacy method first.  This ensures that engines
     * aren't overriden by providers.
     */
    if ((ret = x509_pubkey_decode(&pubkey->pkey, pubkey)) == -1) {
        /* -1 indicates a fatal error, like malloc failure */
        ERR_clear_last_mark();
        goto end;
    }

    /* Try to decode it into an EVP_PKEY with OSSL_DECODER */
    if (ret <= 0 && !pubkey->flag_force_legacy) {
        const unsigned char *p = in_saved;
        char txtoidname[OSSL_MAX_NAME_SIZE];

        if (OBJ_obj2txt(txtoidname, sizeof(txtoidname),
                        pubkey->algor->algorithm, 0) <= 0) {
            ERR_clear_last_mark();
            goto end;
        }
        if ((dctx =
             OSSL_DECODER_CTX_new_for_pkey(&pubkey->pkey,
                                           "DER", "SubjectPublicKeyInfo",
                                           txtoidname, EVP_PKEY_PUBLIC_KEY,
                                           pubkey->libctx,
                                           pubkey->propq)) != NULL)
            /*
             * As said higher up, we're being opportunistic.  In other words,
             * we don't care about what the return value signals.
             */
            OSSL_DECODER_from_data(dctx, &p, NULL);
    }

    ERR_pop_to_mark();
    ret = 1;
 end:
    OSSL_DECODER_CTX_free(dctx);
    return ret;
}

static int x509_pubkey_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
                              const ASN1_ITEM *it, int tag, int aclass)
{
    return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL),
                            tag, aclass);
}

static int x509_pubkey_ex_print(BIO *out, const ASN1_VALUE **pval, int indent,
                                const char *fname, const ASN1_PCTX *pctx)
{
    return ASN1_item_print(out, *pval, indent,
                           ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), pctx);
}

static const ASN1_EXTERN_FUNCS x509_pubkey_ff = {
    NULL,
    x509_pubkey_ex_new,
    x509_pubkey_ex_free,
    0,                          /* Default clear behaviour is OK */
    x509_pubkey_ex_d2i,
    x509_pubkey_ex_i2d,
    x509_pubkey_ex_print
};

IMPLEMENT_EXTERN_ASN1(X509_PUBKEY, V_ASN1_SEQUENCE, x509_pubkey_ff)
IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)

/*
 * X509_PUBKEY_dup() must be implemented manually, because there is no
 * support for it in ASN1_EXTERN_FUNCS.
 */
X509_PUBKEY *X509_PUBKEY_dup(const X509_PUBKEY *a)
{
    X509_PUBKEY *pubkey = OPENSSL_zalloc(sizeof(*pubkey));

    if (pubkey == NULL
            || !x509_pubkey_set0_libctx(pubkey, a->libctx, a->propq)
            || (pubkey->algor = X509_ALGOR_dup(a->algor)) == NULL
            || (pubkey->public_key = ASN1_BIT_STRING_new()) == NULL
            || !ASN1_BIT_STRING_set(pubkey->public_key,
                                    a->public_key->data, a->public_key->length)
            || (a->pkey != NULL && !EVP_PKEY_up_ref(a->pkey))) {
        x509_pubkey_ex_free((ASN1_VALUE **)&pubkey,
                            ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL));
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    pubkey->pkey = a->pkey;
    return pubkey;
}

/* TODO should better be called X509_PUBKEY_set1 */
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
{
    X509_PUBKEY *pk = NULL;

    if (x == NULL || pkey == NULL) {
        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (pkey->ameth != NULL) {
        if ((pk = X509_PUBKEY_new()) == NULL) {
            ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
            goto error;
        }
        if (pkey->ameth->pub_encode != NULL) {
            if (!pkey->ameth->pub_encode(pk, pkey)) {
                ERR_raise(ERR_LIB_X509, X509_R_PUBLIC_KEY_ENCODE_ERROR);
                goto error;
            }
        } else {
            ERR_raise(ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED);
            goto error;
        }
    } else if (evp_pkey_is_provided(pkey)) {
        unsigned char *der = NULL;
        size_t derlen = 0;
        OSSL_ENCODER_CTX *ectx =
            OSSL_ENCODER_CTX_new_for_pkey(pkey, EVP_PKEY_PUBLIC_KEY,
                                          "DER", "SubjectPublicKeyInfo",
                                          NULL);

        if (OSSL_ENCODER_to_data(ectx, &der, &derlen)) {
            const unsigned char *pder = der;

            pk = d2i_X509_PUBKEY(NULL, &pder, (long)derlen);
        }

        OSSL_ENCODER_CTX_free(ectx);
        OPENSSL_free(der);
    }

    if (pk == NULL) {
        ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM);
        goto error;
    }

    X509_PUBKEY_free(*x);
    if (!EVP_PKEY_up_ref(pkey)) {
        ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR);
        goto error;
    }
    *x = pk;

    /*
     * pk->pkey is NULL when using the legacy routine, but is non-NULL when
     * going through the encoder, and for all intents and purposes, it's
     * a perfect copy of |pkey|, just not the same instance.  In that case,
     * we could simply return early, right here.
     * However, in the interest of being cautious leaning on paranoia, some
     * application might very well depend on the passed |pkey| being used
     * and none other, so we spend a few more cycles throwing away the newly
     * created |pk->pkey| and replace it with |pkey|.
     * TODO(3.0) Investigate if it's safe to change to simply return here
     * if |pk->pkey != NULL|.
     */
    if (pk->pkey != NULL)
        EVP_PKEY_free(pk->pkey);

    pk->pkey = 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.
 *
 * This function is #legacy.
 */
static int x509_pubkey_decode(EVP_PKEY **ppkey, const X509_PUBKEY *key)
{
    EVP_PKEY *pkey = EVP_PKEY_new();

    if (pkey == NULL) {
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
        return -1;
    }

    if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) {
        ERR_raise(ERR_LIB_X509, 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))
            goto error;
    } else {
        ERR_raise(ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED);
        goto error;
    }

    *ppkey = pkey;
    return 1;

 error:
    EVP_PKEY_free(pkey);
    return 0;
}

EVP_PKEY *X509_PUBKEY_get0(const 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) {
        ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR);
        EVP_PKEY_free(ret);
    }

    return NULL;
}

EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key)
{
    EVP_PKEY *ret = X509_PUBKEY_get0(key);

    if (ret != NULL && !EVP_PKEY_up_ref(ret)) {
        ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR);
        ret = NULL;
    }
    return ret;
}

/*
 * Now three pseudo ASN1 routines that take an EVP_PKEY structure and encode
 * or decode as X509_PUBKEY
 */
static EVP_PKEY *d2i_PUBKEY_int(EVP_PKEY **a,
                                const unsigned char **pp, long length,
                                OSSL_LIB_CTX *libctx, const char *propq,
                                unsigned int force_legacy,
                                X509_PUBKEY *
                                (*d2i_x509_pubkey)(X509_PUBKEY **a,
                                                   const unsigned char **in,
                                                   long len))
{
    X509_PUBKEY *xpk, *xpk2 = NULL, **pxpk = NULL;
    EVP_PKEY *pktmp = NULL;
    const unsigned char *q;

    q = *pp;

    /*
     * If libctx or propq are non-NULL, we take advantage of the reuse
     * feature.  It's not generally recommended, but is safe enough for
     * newly created structures.
     */
    if (libctx != NULL || propq != NULL || force_legacy) {
        xpk2 = OPENSSL_zalloc(sizeof(*xpk2));
        if (xpk2 == NULL) {
            ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
            return NULL;
        }
        if (!x509_pubkey_set0_libctx(xpk2, libctx, propq))
            goto end;
        xpk2->flag_force_legacy = !!force_legacy;
        pxpk = &xpk2;
    }
    xpk = d2i_x509_pubkey(pxpk, &q, length);
    if (xpk == NULL)
        goto end;
    pktmp = X509_PUBKEY_get(xpk);
    X509_PUBKEY_free(xpk);
    xpk2 = NULL;                 /* We know that xpk == xpk2 */
    if (pktmp == NULL)
        goto end;
    *pp = q;
    if (a != NULL) {
        EVP_PKEY_free(*a);
        *a = pktmp;
    }
 end:
    X509_PUBKEY_free(xpk2);
    return pktmp;
}

/* For the algorithm specific d2i functions further down */
static EVP_PKEY *d2i_PUBKEY_legacy(EVP_PKEY **a,
                                   const unsigned char **pp, long length)
{
    return d2i_PUBKEY_int(a, pp, length, NULL, NULL, 1, d2i_X509_PUBKEY);
}

EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length,
                        OSSL_LIB_CTX *libctx, const char *propq)
{
    return d2i_PUBKEY_int(a, pp, length, libctx, propq, 0, d2i_X509_PUBKEY);
}

EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
{
    return d2i_PUBKEY_ex(a, pp, length, NULL, NULL);
}

int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
{
    int ret = -1;

    if (a == NULL)
        return 0;
    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) {
        OSSL_ENCODER_CTX *ctx =
            OSSL_ENCODER_CTX_new_for_pkey(a, EVP_PKEY_PUBLIC_KEY,
                                          "DER", "SubjectPublicKeyInfo",
                                          NULL);
        BIO *out = BIO_new(BIO_s_mem());
        BUF_MEM *buf = NULL;

        if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0
            && out != NULL
            && OSSL_ENCODER_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_ENCODER_CTX_free(ctx);
    }

    return ret;
}

/*
 * The following are equivalents but which return RSA and DSA keys
 */
RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
{
    EVP_PKEY *pkey;
    RSA *key = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    key = EVP_PKEY_get1_RSA(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        RSA_free(*a);
        *a = key;
    }
    return key;
}

int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;
    if (!a)
        return 0;
    pktmp = EVP_PKEY_new();
    if (pktmp == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign_RSA(pktmp, (RSA *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    EVP_PKEY_free(pktmp);
    return ret;
}

#ifndef OPENSSL_NO_DH
DH *ossl_d2i_DH_PUBKEY(DH **a, const unsigned char **pp, long length)
{
    EVP_PKEY *pkey;
    DH *key = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    if (EVP_PKEY_id(pkey) == EVP_PKEY_DH)
        key = EVP_PKEY_get1_DH(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        DH_free(*a);
        *a = key;
    }
    return key;
}

int ossl_i2d_DH_PUBKEY(const DH *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;
    if (!a)
        return 0;
    pktmp = EVP_PKEY_new();
    if (pktmp == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign_DH(pktmp, (DH *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    EVP_PKEY_free(pktmp);
    return ret;
}

DH *ossl_d2i_DHx_PUBKEY(DH **a, const unsigned char **pp, long length)
{
    EVP_PKEY *pkey;
    DH *key = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    if (EVP_PKEY_id(pkey) == EVP_PKEY_DHX)
        key = EVP_PKEY_get1_DH(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        DH_free(*a);
        *a = key;
    }
    return key;
}

int ossl_i2d_DHx_PUBKEY(const DH *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;
    if (!a)
        return 0;
    pktmp = EVP_PKEY_new();
    if (pktmp == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign(pktmp, EVP_PKEY_DHX, (DH *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    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 = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    key = EVP_PKEY_get1_DSA(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        DSA_free(*a);
        *a = key;
    }
    return key;
}

int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;
    if (!a)
        return 0;
    pktmp = EVP_PKEY_new();
    if (pktmp == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign_DSA(pktmp, (DSA *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    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 = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    if (EVP_PKEY_id(pkey) == EVP_PKEY_EC)
        key = EVP_PKEY_get1_EC_KEY(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        EC_KEY_free(*a);
        *a = key;
    }
    return key;
}

int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;

    if (a == NULL)
        return 0;
    if ((pktmp = EVP_PKEY_new()) == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign_EC_KEY(pktmp, (EC_KEY *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    EVP_PKEY_free(pktmp);
    return ret;
}

ECX_KEY *ossl_d2i_ED25519_PUBKEY(ECX_KEY **a,
                                 const unsigned char **pp, long length)
{
    EVP_PKEY *pkey;
    ECX_KEY *key = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    key = ossl_evp_pkey_get1_ED25519(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        ossl_ecx_key_free(*a);
        *a = key;
    }
    return key;
}

int ossl_i2d_ED25519_PUBKEY(const ECX_KEY *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;

    if (a == NULL)
        return 0;
    if ((pktmp = EVP_PKEY_new()) == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED25519, (ECX_KEY *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    EVP_PKEY_free(pktmp);
    return ret;
}

ECX_KEY *ossl_d2i_ED448_PUBKEY(ECX_KEY **a,
                               const unsigned char **pp, long length)
{
    EVP_PKEY *pkey;
    ECX_KEY *key = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    if (EVP_PKEY_id(pkey) == EVP_PKEY_ED448)
        key = ossl_evp_pkey_get1_ED448(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        ossl_ecx_key_free(*a);
        *a = key;
    }
    return key;
}

int ossl_i2d_ED448_PUBKEY(const ECX_KEY *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;

    if (a == NULL)
        return 0;
    if ((pktmp = EVP_PKEY_new()) == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED448, (ECX_KEY *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    EVP_PKEY_free(pktmp);
    return ret;
}

ECX_KEY *ossl_d2i_X25519_PUBKEY(ECX_KEY **a,
                                const unsigned char **pp, long length)
{
    EVP_PKEY *pkey;
    ECX_KEY *key = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    if (EVP_PKEY_id(pkey) == EVP_PKEY_X25519)
        key = ossl_evp_pkey_get1_X25519(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        ossl_ecx_key_free(*a);
        *a = key;
    }
    return key;
}

int ossl_i2d_X25519_PUBKEY(const ECX_KEY *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;

    if (a == NULL)
        return 0;
    if ((pktmp = EVP_PKEY_new()) == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X25519, (ECX_KEY *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    EVP_PKEY_free(pktmp);
    return ret;
}

ECX_KEY *ossl_d2i_X448_PUBKEY(ECX_KEY **a,
                              const unsigned char **pp, long length)
{
    EVP_PKEY *pkey;
    ECX_KEY *key = NULL;
    const unsigned char *q;

    q = *pp;
    pkey = d2i_PUBKEY_legacy(NULL, &q, length);
    if (pkey == NULL)
        return NULL;
    if (EVP_PKEY_id(pkey) == EVP_PKEY_X448)
        key = ossl_evp_pkey_get1_X448(pkey);
    EVP_PKEY_free(pkey);
    if (key == NULL)
        return NULL;
    *pp = q;
    if (a != NULL) {
        ossl_ecx_key_free(*a);
        *a = key;
    }
    return key;
}

int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp)
{
    EVP_PKEY *pktmp;
    int ret;

    if (a == NULL)
        return 0;
    if ((pktmp = EVP_PKEY_new()) == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X448, (ECX_KEY *)a);
    ret = i2d_PUBKEY(pktmp, pp);
    pktmp->pkey.ptr = NULL;
    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, const 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;
}

/* Returns 1 for equal, 0, for non-equal, < 0 on error */
int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b)
{
    X509_ALGOR *algA, *algB;
    EVP_PKEY *pA, *pB;

    if (a == b)
        return 1;
    if (a == NULL || b == NULL)
        return 0;
    if (!X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a) || algA == NULL
        || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b) || algB == NULL)
        return -2;
    if (X509_ALGOR_cmp(algA, algB) != 0)
        return 0;
    if ((pA = X509_PUBKEY_get0(a)) == NULL
        || (pB = X509_PUBKEY_get0(b)) == NULL)
        return -2;
    return EVP_PKEY_eq(pA, pB);
}

int ossl_x509_PUBKEY_get0_libctx(OSSL_LIB_CTX **plibctx, const char **ppropq,
                                 const X509_PUBKEY *key)
{
    if (plibctx)
        *plibctx = key->libctx;
    if (ppropq)
        *ppropq = key->propq;
    return 1;
}
