/*
* Copyright 1995-2023 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 <openssl/engine.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)
X509_PUBKEY *ossl_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp,
long len, OSSL_LIB_CTX *libctx,
const char *propq)
{
X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub));
if (xpub == NULL)
return NULL;
return (X509_PUBKEY *)ASN1_item_d2i_ex((ASN1_VALUE **)&xpub, pp, len,
ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL),
libctx, propq);
}
void ossl_X509_PUBKEY_INTERNAL_free(X509_PUBKEY *xpub)
{
ASN1_item_free((ASN1_VALUE *)xpub, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL));
}
static void x509_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
X509_PUBKEY *pubkey;
if (pval != NULL && (pubkey = (X509_PUBKEY *)*pval) != NULL) {
X509_ALGOR_free(pubkey->algor);
ASN1_BIT_STRING_free(pubkey->public_key);
EVP_PKEY_free(pubkey->pkey);
OPENSSL_free(pubkey->propq);
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_ex(ASN1_VALUE **pval, const ASN1_ITEM *it,
OSSL_LIB_CTX *libctx, const char *propq)
{
X509_PUBKEY *ret;
if ((ret = OPENSSL_zalloc(sizeof(*ret