1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * DSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <stdio.h> 17e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 18e1051a39Sopenharmony_ci#include <openssl/asn1t.h> 19e1051a39Sopenharmony_ci#include <openssl/x509.h> 20e1051a39Sopenharmony_ci#include <openssl/engine.h> 21e1051a39Sopenharmony_ci#include "crypto/asn1.h" 22e1051a39Sopenharmony_ci#include "crypto/evp.h" 23e1051a39Sopenharmony_ci#include "crypto/x509.h" 24e1051a39Sopenharmony_ci#include <openssl/rsa.h> 25e1051a39Sopenharmony_ci#include <openssl/dsa.h> 26e1051a39Sopenharmony_ci#include <openssl/decoder.h> 27e1051a39Sopenharmony_ci#include <openssl/encoder.h> 28e1051a39Sopenharmony_ci#include "internal/provider.h" 29e1051a39Sopenharmony_ci#include "internal/sizes.h" 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_cistruct X509_pubkey_st { 32e1051a39Sopenharmony_ci X509_ALGOR *algor; 33e1051a39Sopenharmony_ci ASN1_BIT_STRING *public_key; 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_ci EVP_PKEY *pkey; 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_ci /* extra data for the callback, used by d2i_PUBKEY_ex */ 38e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; 39e1051a39Sopenharmony_ci char *propq; 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ci /* Flag to force legacy keys */ 42e1051a39Sopenharmony_ci unsigned int flag_force_legacy : 1; 43e1051a39Sopenharmony_ci}; 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_cistatic int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key); 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_cistatic int x509_pubkey_set0_libctx(X509_PUBKEY *x, OSSL_LIB_CTX *libctx, 48e1051a39Sopenharmony_ci const char *propq) 49e1051a39Sopenharmony_ci{ 50e1051a39Sopenharmony_ci if (x != NULL) { 51e1051a39Sopenharmony_ci x->libctx = libctx; 52e1051a39Sopenharmony_ci OPENSSL_free(x->propq); 53e1051a39Sopenharmony_ci x->propq = NULL; 54e1051a39Sopenharmony_ci if (propq != NULL) { 55e1051a39Sopenharmony_ci x->propq = OPENSSL_strdup(propq); 56e1051a39Sopenharmony_ci if (x->propq == NULL) 57e1051a39Sopenharmony_ci return 0; 58e1051a39Sopenharmony_ci } 59e1051a39Sopenharmony_ci } 60e1051a39Sopenharmony_ci return 1; 61e1051a39Sopenharmony_ci} 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_ciASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = { 64e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), 65e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) 66e1051a39Sopenharmony_ci} static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL) 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ciX509_PUBKEY *ossl_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, 69e1051a39Sopenharmony_ci long len, OSSL_LIB_CTX *libctx) 70e1051a39Sopenharmony_ci{ 71e1051a39Sopenharmony_ci X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub)); 72e1051a39Sopenharmony_ci 73e1051a39Sopenharmony_ci if (xpub == NULL) 74e1051a39Sopenharmony_ci return NULL; 75e1051a39Sopenharmony_ci return (X509_PUBKEY *)ASN1_item_d2i_ex((ASN1_VALUE **)&xpub, pp, len, 76e1051a39Sopenharmony_ci ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), 77e1051a39Sopenharmony_ci libctx, NULL); 78e1051a39Sopenharmony_ci} 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_civoid ossl_X509_PUBKEY_INTERNAL_free(X509_PUBKEY *xpub) 81e1051a39Sopenharmony_ci{ 82e1051a39Sopenharmony_ci ASN1_item_free((ASN1_VALUE *)xpub, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); 83e1051a39Sopenharmony_ci} 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_cistatic void x509_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 86e1051a39Sopenharmony_ci{ 87e1051a39Sopenharmony_ci X509_PUBKEY *pubkey; 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci if (pval != NULL && (pubkey = (X509_PUBKEY *)*pval) != NULL) { 90e1051a39Sopenharmony_ci X509_ALGOR_free(pubkey->algor); 91e1051a39Sopenharmony_ci ASN1_BIT_STRING_free(pubkey->public_key); 92e1051a39Sopenharmony_ci EVP_PKEY_free(pubkey->pkey); 93e1051a39Sopenharmony_ci OPENSSL_free(pubkey->propq); 94e1051a39Sopenharmony_ci OPENSSL_free(pubkey); 95e1051a39Sopenharmony_ci *pval = NULL; 96e1051a39Sopenharmony_ci } 97e1051a39Sopenharmony_ci} 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_cistatic int x509_pubkey_ex_populate(ASN1_VALUE **pval, const ASN1_ITEM *it) 100e1051a39Sopenharmony_ci{ 101e1051a39Sopenharmony_ci X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_ci return (pubkey->algor != NULL 104e1051a39Sopenharmony_ci || (pubkey->algor = X509_ALGOR_new()) != NULL) 105e1051a39Sopenharmony_ci && (pubkey->public_key != NULL 106e1051a39Sopenharmony_ci || (pubkey->public_key = ASN1_BIT_STRING_new()) != NULL); 107e1051a39Sopenharmony_ci} 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_cistatic int x509_pubkey_ex_new_ex(ASN1_VALUE **pval, const ASN1_ITEM *it, 111e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 112e1051a39Sopenharmony_ci{ 113e1051a39Sopenharmony_ci X509_PUBKEY *ret; 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ci if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL 116e1051a39Sopenharmony_ci || !x509_pubkey_ex_populate((ASN1_VALUE **)&ret, NULL) 117e1051a39Sopenharmony_ci || !x509_pubkey_set0_libctx(ret, libctx, propq)) { 118e1051a39Sopenharmony_ci x509_pubkey_ex_free((ASN1_VALUE **)&ret, NULL); 119e1051a39Sopenharmony_ci ret = NULL; 120e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 121e1051a39Sopenharmony_ci } else { 122e1051a39Sopenharmony_ci *pval = (ASN1_VALUE *)ret; 123e1051a39Sopenharmony_ci } 124e1051a39Sopenharmony_ci 125e1051a39Sopenharmony_ci return ret != NULL; 126e1051a39Sopenharmony_ci} 127e1051a39Sopenharmony_ci 128e1051a39Sopenharmony_cistatic int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval, 129e1051a39Sopenharmony_ci const unsigned char **in, long len, 130e1051a39Sopenharmony_ci const ASN1_ITEM *it, int tag, int aclass, 131e1051a39Sopenharmony_ci char opt, ASN1_TLC *ctx, OSSL_LIB_CTX *libctx, 132e1051a39Sopenharmony_ci const char *propq) 133e1051a39Sopenharmony_ci{ 134e1051a39Sopenharmony_ci const unsigned char *in_saved = *in; 135e1051a39Sopenharmony_ci size_t publen; 136e1051a39Sopenharmony_ci X509_PUBKEY *pubkey; 137e1051a39Sopenharmony_ci int ret; 138e1051a39Sopenharmony_ci OSSL_DECODER_CTX *dctx = NULL; 139e1051a39Sopenharmony_ci unsigned char *tmpbuf = NULL; 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci if (*pval == NULL && !x509_pubkey_ex_new_ex(pval, it, libctx, propq)) 142e1051a39Sopenharmony_ci return 0; 143e1051a39Sopenharmony_ci if (!x509_pubkey_ex_populate(pval, NULL)) { 144e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 145e1051a39Sopenharmony_ci return 0; 146e1051a39Sopenharmony_ci } 147e1051a39Sopenharmony_ci 148e1051a39Sopenharmony_ci /* This ensures that |*in| advances properly no matter what */ 149e1051a39Sopenharmony_ci if ((ret = ASN1_item_ex_d2i(pval, in, len, 150e1051a39Sopenharmony_ci ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), 151e1051a39Sopenharmony_ci tag, aclass, opt, ctx)) <= 0) 152e1051a39Sopenharmony_ci return ret; 153e1051a39Sopenharmony_ci 154e1051a39Sopenharmony_ci publen = *in - in_saved; 155e1051a39Sopenharmony_ci if (!ossl_assert(publen > 0)) { 156e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); 157e1051a39Sopenharmony_ci return 0; 158e1051a39Sopenharmony_ci } 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ci pubkey = (X509_PUBKEY *)*pval; 161e1051a39Sopenharmony_ci EVP_PKEY_free(pubkey->pkey); 162e1051a39Sopenharmony_ci pubkey->pkey = NULL; 163e1051a39Sopenharmony_ci 164e1051a39Sopenharmony_ci /* 165e1051a39Sopenharmony_ci * Opportunistically decode the key but remove any non fatal errors 166e1051a39Sopenharmony_ci * from the queue. Subsequent explicit attempts to decode/use the key 167e1051a39Sopenharmony_ci * will return an appropriate error. 168e1051a39Sopenharmony_ci */ 169e1051a39Sopenharmony_ci ERR_set_mark(); 170e1051a39Sopenharmony_ci 171e1051a39Sopenharmony_ci /* 172e1051a39Sopenharmony_ci * Try to decode with legacy method first. This ensures that engines 173e1051a39Sopenharmony_ci * aren't overriden by providers. 174e1051a39Sopenharmony_ci */ 175e1051a39Sopenharmony_ci if ((ret = x509_pubkey_decode(&pubkey->pkey, pubkey)) == -1) { 176e1051a39Sopenharmony_ci /* -1 indicates a fatal error, like malloc failure */ 177e1051a39Sopenharmony_ci ERR_clear_last_mark(); 178e1051a39Sopenharmony_ci goto end; 179e1051a39Sopenharmony_ci } 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ci /* Try to decode it into an EVP_PKEY with OSSL_DECODER */ 182e1051a39Sopenharmony_ci if (ret <= 0 && !pubkey->flag_force_legacy) { 183e1051a39Sopenharmony_ci const unsigned char *p; 184e1051a39Sopenharmony_ci char txtoidname[OSSL_MAX_NAME_SIZE]; 185e1051a39Sopenharmony_ci size_t slen = publen; 186e1051a39Sopenharmony_ci 187e1051a39Sopenharmony_ci /* 188e1051a39Sopenharmony_ci * The decoders don't know how to handle anything other than Universal 189e1051a39Sopenharmony_ci * class so we modify the data accordingly. 190e1051a39Sopenharmony_ci */ 191e1051a39Sopenharmony_ci if (aclass != V_ASN1_UNIVERSAL) { 192e1051a39Sopenharmony_ci tmpbuf = OPENSSL_memdup(in_saved, publen); 193e1051a39Sopenharmony_ci if (tmpbuf == NULL) { 194e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 195e1051a39Sopenharmony_ci return 0; 196e1051a39Sopenharmony_ci } 197e1051a39Sopenharmony_ci in_saved = tmpbuf; 198e1051a39Sopenharmony_ci *tmpbuf = V_ASN1_CONSTRUCTED | V_ASN1_SEQUENCE; 199e1051a39Sopenharmony_ci } 200e1051a39Sopenharmony_ci p = in_saved; 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_ci if (OBJ_obj2txt(txtoidname, sizeof(txtoidname), 203e1051a39Sopenharmony_ci pubkey->algor->algorithm, 0) <= 0) { 204e1051a39Sopenharmony_ci ERR_clear_last_mark(); 205e1051a39Sopenharmony_ci goto end; 206e1051a39Sopenharmony_ci } 207e1051a39Sopenharmony_ci if ((dctx = 208e1051a39Sopenharmony_ci OSSL_DECODER_CTX_new_for_pkey(&pubkey->pkey, 209e1051a39Sopenharmony_ci "DER", "SubjectPublicKeyInfo", 210e1051a39Sopenharmony_ci txtoidname, EVP_PKEY_PUBLIC_KEY, 211e1051a39Sopenharmony_ci pubkey->libctx, 212e1051a39Sopenharmony_ci pubkey->propq)) != NULL) 213e1051a39Sopenharmony_ci /* 214e1051a39Sopenharmony_ci * As said higher up, we're being opportunistic. In other words, 215e1051a39Sopenharmony_ci * we don't care if we fail. 216e1051a39Sopenharmony_ci */ 217e1051a39Sopenharmony_ci if (OSSL_DECODER_from_data(dctx, &p, &slen)) { 218e1051a39Sopenharmony_ci if (slen != 0) { 219e1051a39Sopenharmony_ci /* 220e1051a39Sopenharmony_ci * If we successfully decoded then we *must* consume all the 221e1051a39Sopenharmony_ci * bytes. 222e1051a39Sopenharmony_ci */ 223e1051a39Sopenharmony_ci ERR_clear_last_mark(); 224e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, EVP_R_DECODE_ERROR); 225e1051a39Sopenharmony_ci goto end; 226e1051a39Sopenharmony_ci } 227e1051a39Sopenharmony_ci } 228e1051a39Sopenharmony_ci } 229e1051a39Sopenharmony_ci 230e1051a39Sopenharmony_ci ERR_pop_to_mark(); 231e1051a39Sopenharmony_ci ret = 1; 232e1051a39Sopenharmony_ci end: 233e1051a39Sopenharmony_ci OSSL_DECODER_CTX_free(dctx); 234e1051a39Sopenharmony_ci OPENSSL_free(tmpbuf); 235e1051a39Sopenharmony_ci return ret; 236e1051a39Sopenharmony_ci} 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_cistatic int x509_pubkey_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, 239e1051a39Sopenharmony_ci const ASN1_ITEM *it, int tag, int aclass) 240e1051a39Sopenharmony_ci{ 241e1051a39Sopenharmony_ci return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), 242e1051a39Sopenharmony_ci tag, aclass); 243e1051a39Sopenharmony_ci} 244e1051a39Sopenharmony_ci 245e1051a39Sopenharmony_cistatic int x509_pubkey_ex_print(BIO *out, const ASN1_VALUE **pval, int indent, 246e1051a39Sopenharmony_ci const char *fname, const ASN1_PCTX *pctx) 247e1051a39Sopenharmony_ci{ 248e1051a39Sopenharmony_ci return ASN1_item_print(out, *pval, indent, 249e1051a39Sopenharmony_ci ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), pctx); 250e1051a39Sopenharmony_ci} 251e1051a39Sopenharmony_ci 252e1051a39Sopenharmony_cistatic const ASN1_EXTERN_FUNCS x509_pubkey_ff = { 253e1051a39Sopenharmony_ci NULL, 254e1051a39Sopenharmony_ci NULL, 255e1051a39Sopenharmony_ci x509_pubkey_ex_free, 256e1051a39Sopenharmony_ci 0, /* Default clear behaviour is OK */ 257e1051a39Sopenharmony_ci NULL, 258e1051a39Sopenharmony_ci x509_pubkey_ex_i2d, 259e1051a39Sopenharmony_ci x509_pubkey_ex_print, 260e1051a39Sopenharmony_ci x509_pubkey_ex_new_ex, 261e1051a39Sopenharmony_ci x509_pubkey_ex_d2i_ex, 262e1051a39Sopenharmony_ci}; 263e1051a39Sopenharmony_ci 264e1051a39Sopenharmony_ciIMPLEMENT_EXTERN_ASN1(X509_PUBKEY, V_ASN1_SEQUENCE, x509_pubkey_ff) 265e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) 266e1051a39Sopenharmony_ci 267e1051a39Sopenharmony_ciX509_PUBKEY *X509_PUBKEY_new_ex(OSSL_LIB_CTX *libctx, const char *propq) 268e1051a39Sopenharmony_ci{ 269e1051a39Sopenharmony_ci X509_PUBKEY *pubkey = NULL; 270e1051a39Sopenharmony_ci 271e1051a39Sopenharmony_ci pubkey = (X509_PUBKEY *)ASN1_item_new_ex(X509_PUBKEY_it(), libctx, propq); 272e1051a39Sopenharmony_ci if (!x509_pubkey_set0_libctx(pubkey, libctx, propq)) { 273e1051a39Sopenharmony_ci X509_PUBKEY_free(pubkey); 274e1051a39Sopenharmony_ci pubkey = NULL; 275e1051a39Sopenharmony_ci } 276e1051a39Sopenharmony_ci return pubkey; 277e1051a39Sopenharmony_ci} 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_ci/* 280e1051a39Sopenharmony_ci * X509_PUBKEY_dup() must be implemented manually, because there is no 281e1051a39Sopenharmony_ci * support for it in ASN1_EXTERN_FUNCS. 282e1051a39Sopenharmony_ci */ 283e1051a39Sopenharmony_ciX509_PUBKEY *X509_PUBKEY_dup(const X509_PUBKEY *a) 284e1051a39Sopenharmony_ci{ 285e1051a39Sopenharmony_ci X509_PUBKEY *pubkey = OPENSSL_zalloc(sizeof(*pubkey)); 286e1051a39Sopenharmony_ci 287e1051a39Sopenharmony_ci if (pubkey == NULL 288e1051a39Sopenharmony_ci || !x509_pubkey_set0_libctx(pubkey, a->libctx, a->propq) 289e1051a39Sopenharmony_ci || (pubkey->algor = X509_ALGOR_dup(a->algor)) == NULL 290e1051a39Sopenharmony_ci || (pubkey->public_key = ASN1_BIT_STRING_new()) == NULL 291e1051a39Sopenharmony_ci || !ASN1_BIT_STRING_set(pubkey->public_key, 292e1051a39Sopenharmony_ci a->public_key->data, 293e1051a39Sopenharmony_ci a->public_key->length)) { 294e1051a39Sopenharmony_ci x509_pubkey_ex_free((ASN1_VALUE **)&pubkey, 295e1051a39Sopenharmony_ci ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); 296e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 297e1051a39Sopenharmony_ci return NULL; 298e1051a39Sopenharmony_ci } 299e1051a39Sopenharmony_ci 300e1051a39Sopenharmony_ci if (a->pkey != NULL) { 301e1051a39Sopenharmony_ci ERR_set_mark(); 302e1051a39Sopenharmony_ci pubkey->pkey = EVP_PKEY_dup(a->pkey); 303e1051a39Sopenharmony_ci if (pubkey->pkey == NULL) { 304e1051a39Sopenharmony_ci pubkey->flag_force_legacy = 1; 305e1051a39Sopenharmony_ci if (x509_pubkey_decode(&pubkey->pkey, pubkey) <= 0) { 306e1051a39Sopenharmony_ci x509_pubkey_ex_free((ASN1_VALUE **)&pubkey, 307e1051a39Sopenharmony_ci ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); 308e1051a39Sopenharmony_ci ERR_clear_last_mark(); 309e1051a39Sopenharmony_ci return NULL; 310e1051a39Sopenharmony_ci } 311e1051a39Sopenharmony_ci } 312e1051a39Sopenharmony_ci ERR_pop_to_mark(); 313e1051a39Sopenharmony_ci } 314e1051a39Sopenharmony_ci return pubkey; 315e1051a39Sopenharmony_ci} 316e1051a39Sopenharmony_ci 317e1051a39Sopenharmony_ciint X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) 318e1051a39Sopenharmony_ci{ 319e1051a39Sopenharmony_ci X509_PUBKEY *pk = NULL; 320e1051a39Sopenharmony_ci 321e1051a39Sopenharmony_ci if (x == NULL || pkey == NULL) { 322e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 323e1051a39Sopenharmony_ci return 0; 324e1051a39Sopenharmony_ci } 325e1051a39Sopenharmony_ci 326e1051a39Sopenharmony_ci if (pkey->ameth != NULL) { 327e1051a39Sopenharmony_ci if ((pk = X509_PUBKEY_new()) == NULL) { 328e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 329e1051a39Sopenharmony_ci goto error; 330e1051a39Sopenharmony_ci } 331e1051a39Sopenharmony_ci if (pkey->ameth->pub_encode != NULL) { 332e1051a39Sopenharmony_ci if (!pkey->ameth->pub_encode(pk, pkey)) { 333e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); 334e1051a39Sopenharmony_ci goto error; 335e1051a39Sopenharmony_ci } 336e1051a39Sopenharmony_ci } else { 337e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED); 338e1051a39Sopenharmony_ci goto error; 339e1051a39Sopenharmony_ci } 340e1051a39Sopenharmony_ci } else if (evp_pkey_is_provided(pkey)) { 341e1051a39Sopenharmony_ci unsigned char *der = NULL; 342e1051a39Sopenharmony_ci size_t derlen = 0; 343e1051a39Sopenharmony_ci OSSL_ENCODER_CTX *ectx = 344e1051a39Sopenharmony_ci OSSL_ENCODER_CTX_new_for_pkey(pkey, EVP_PKEY_PUBLIC_KEY, 345e1051a39Sopenharmony_ci "DER", "SubjectPublicKeyInfo", 346e1051a39Sopenharmony_ci NULL); 347e1051a39Sopenharmony_ci 348e1051a39Sopenharmony_ci if (OSSL_ENCODER_to_data(ectx, &der, &derlen)) { 349e1051a39Sopenharmony_ci const unsigned char *pder = der; 350e1051a39Sopenharmony_ci 351e1051a39Sopenharmony_ci pk = d2i_X509_PUBKEY(NULL, &pder, (long)derlen); 352e1051a39Sopenharmony_ci } 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci OSSL_ENCODER_CTX_free(ectx); 355e1051a39Sopenharmony_ci OPENSSL_free(der); 356e1051a39Sopenharmony_ci } 357e1051a39Sopenharmony_ci 358e1051a39Sopenharmony_ci if (pk == NULL) { 359e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM); 360e1051a39Sopenharmony_ci goto error; 361e1051a39Sopenharmony_ci } 362e1051a39Sopenharmony_ci 363e1051a39Sopenharmony_ci X509_PUBKEY_free(*x); 364e1051a39Sopenharmony_ci if (!EVP_PKEY_up_ref(pkey)) { 365e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); 366e1051a39Sopenharmony_ci goto error; 367e1051a39Sopenharmony_ci } 368e1051a39Sopenharmony_ci *x = pk; 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_ci /* 371e1051a39Sopenharmony_ci * pk->pkey is NULL when using the legacy routine, but is non-NULL when 372e1051a39Sopenharmony_ci * going through the encoder, and for all intents and purposes, it's 373e1051a39Sopenharmony_ci * a perfect copy of the public key portions of |pkey|, just not the same 374e1051a39Sopenharmony_ci * instance. If that's all there was to pkey then we could simply return 375e1051a39Sopenharmony_ci * early, right here. However, some application might very well depend on 376e1051a39Sopenharmony_ci * the passed |pkey| being used and none other, so we spend a few more 377e1051a39Sopenharmony_ci * cycles throwing away the newly created |pk->pkey| and replace it with 378e1051a39Sopenharmony_ci * |pkey|. 379e1051a39Sopenharmony_ci */ 380e1051a39Sopenharmony_ci if (pk->pkey != NULL) 381e1051a39Sopenharmony_ci EVP_PKEY_free(pk->pkey); 382e1051a39Sopenharmony_ci 383e1051a39Sopenharmony_ci pk->pkey = pkey; 384e1051a39Sopenharmony_ci return 1; 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_ci error: 387e1051a39Sopenharmony_ci X509_PUBKEY_free(pk); 388e1051a39Sopenharmony_ci return 0; 389e1051a39Sopenharmony_ci} 390e1051a39Sopenharmony_ci 391e1051a39Sopenharmony_ci/* 392e1051a39Sopenharmony_ci * Attempt to decode a public key. 393e1051a39Sopenharmony_ci * Returns 1 on success, 0 for a decode failure and -1 for a fatal 394e1051a39Sopenharmony_ci * error e.g. malloc failure. 395e1051a39Sopenharmony_ci * 396e1051a39Sopenharmony_ci * This function is #legacy. 397e1051a39Sopenharmony_ci */ 398e1051a39Sopenharmony_cistatic int x509_pubkey_decode(EVP_PKEY **ppkey, const X509_PUBKEY *key) 399e1051a39Sopenharmony_ci{ 400e1051a39Sopenharmony_ci EVP_PKEY *pkey; 401e1051a39Sopenharmony_ci int nid; 402e1051a39Sopenharmony_ci 403e1051a39Sopenharmony_ci nid = OBJ_obj2nid(key->algor->algorithm); 404e1051a39Sopenharmony_ci if (!key->flag_force_legacy) { 405e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 406e1051a39Sopenharmony_ci ENGINE *e = NULL; 407e1051a39Sopenharmony_ci 408e1051a39Sopenharmony_ci e = ENGINE_get_pkey_meth_engine(nid); 409e1051a39Sopenharmony_ci if (e == NULL) 410e1051a39Sopenharmony_ci return 0; 411e1051a39Sopenharmony_ci ENGINE_finish(e); 412e1051a39Sopenharmony_ci#else 413e1051a39Sopenharmony_ci return 0; 414e1051a39Sopenharmony_ci#endif 415e1051a39Sopenharmony_ci } 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci pkey = EVP_PKEY_new(); 418e1051a39Sopenharmony_ci if (pkey == NULL) { 419e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 420e1051a39Sopenharmony_ci return -1; 421e1051a39Sopenharmony_ci } 422e1051a39Sopenharmony_ci 423e1051a39Sopenharmony_ci if (!EVP_PKEY_set_type(pkey, nid)) { 424e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM); 425e1051a39Sopenharmony_ci goto error; 426e1051a39Sopenharmony_ci } 427e1051a39Sopenharmony_ci 428e1051a39Sopenharmony_ci if (pkey->ameth->pub_decode) { 429e1051a39Sopenharmony_ci /* 430e1051a39Sopenharmony_ci * Treat any failure of pub_decode as a decode error. In 431e1051a39Sopenharmony_ci * future we could have different return codes for decode 432e1051a39Sopenharmony_ci * errors and fatal errors such as malloc failure. 433e1051a39Sopenharmony_ci */ 434e1051a39Sopenharmony_ci if (!pkey->ameth->pub_decode(pkey, key)) 435e1051a39Sopenharmony_ci goto error; 436e1051a39Sopenharmony_ci } else { 437e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED); 438e1051a39Sopenharmony_ci goto error; 439e1051a39Sopenharmony_ci } 440e1051a39Sopenharmony_ci 441e1051a39Sopenharmony_ci *ppkey = pkey; 442e1051a39Sopenharmony_ci return 1; 443e1051a39Sopenharmony_ci 444e1051a39Sopenharmony_ci error: 445e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 446e1051a39Sopenharmony_ci return 0; 447e1051a39Sopenharmony_ci} 448e1051a39Sopenharmony_ci 449e1051a39Sopenharmony_ciEVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key) 450e1051a39Sopenharmony_ci{ 451e1051a39Sopenharmony_ci if (key == NULL) { 452e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 453e1051a39Sopenharmony_ci return NULL; 454e1051a39Sopenharmony_ci } 455e1051a39Sopenharmony_ci 456e1051a39Sopenharmony_ci if (key->pkey == NULL) { 457e1051a39Sopenharmony_ci /* We failed to decode the key when we loaded it, or it was never set */ 458e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); 459e1051a39Sopenharmony_ci return NULL; 460e1051a39Sopenharmony_ci } 461e1051a39Sopenharmony_ci 462e1051a39Sopenharmony_ci return key->pkey; 463e1051a39Sopenharmony_ci} 464e1051a39Sopenharmony_ci 465e1051a39Sopenharmony_ciEVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key) 466e1051a39Sopenharmony_ci{ 467e1051a39Sopenharmony_ci EVP_PKEY *ret = X509_PUBKEY_get0(key); 468e1051a39Sopenharmony_ci 469e1051a39Sopenharmony_ci if (ret != NULL && !EVP_PKEY_up_ref(ret)) { 470e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); 471e1051a39Sopenharmony_ci ret = NULL; 472e1051a39Sopenharmony_ci } 473e1051a39Sopenharmony_ci return ret; 474e1051a39Sopenharmony_ci} 475e1051a39Sopenharmony_ci 476e1051a39Sopenharmony_ci/* 477e1051a39Sopenharmony_ci * Now three pseudo ASN1 routines that take an EVP_PKEY structure and encode 478e1051a39Sopenharmony_ci * or decode as X509_PUBKEY 479e1051a39Sopenharmony_ci */ 480e1051a39Sopenharmony_cistatic EVP_PKEY *d2i_PUBKEY_int(EVP_PKEY **a, 481e1051a39Sopenharmony_ci const unsigned char **pp, long length, 482e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq, 483e1051a39Sopenharmony_ci unsigned int force_legacy, 484e1051a39Sopenharmony_ci X509_PUBKEY * 485e1051a39Sopenharmony_ci (*d2i_x509_pubkey)(X509_PUBKEY **a, 486e1051a39Sopenharmony_ci const unsigned char **in, 487e1051a39Sopenharmony_ci long len)) 488e1051a39Sopenharmony_ci{ 489e1051a39Sopenharmony_ci X509_PUBKEY *xpk, *xpk2 = NULL, **pxpk = NULL; 490e1051a39Sopenharmony_ci EVP_PKEY *pktmp = NULL; 491e1051a39Sopenharmony_ci const unsigned char *q; 492e1051a39Sopenharmony_ci 493e1051a39Sopenharmony_ci q = *pp; 494e1051a39Sopenharmony_ci 495e1051a39Sopenharmony_ci /* 496e1051a39Sopenharmony_ci * If libctx or propq are non-NULL, we take advantage of the reuse 497e1051a39Sopenharmony_ci * feature. It's not generally recommended, but is safe enough for 498e1051a39Sopenharmony_ci * newly created structures. 499e1051a39Sopenharmony_ci */ 500e1051a39Sopenharmony_ci if (libctx != NULL || propq != NULL || force_legacy) { 501e1051a39Sopenharmony_ci xpk2 = OPENSSL_zalloc(sizeof(*xpk2)); 502e1051a39Sopenharmony_ci if (xpk2 == NULL) { 503e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 504e1051a39Sopenharmony_ci return NULL; 505e1051a39Sopenharmony_ci } 506e1051a39Sopenharmony_ci if (!x509_pubkey_set0_libctx(xpk2, libctx, propq)) 507e1051a39Sopenharmony_ci goto end; 508e1051a39Sopenharmony_ci xpk2->flag_force_legacy = !!force_legacy; 509e1051a39Sopenharmony_ci pxpk = &xpk2; 510e1051a39Sopenharmony_ci } 511e1051a39Sopenharmony_ci xpk = d2i_x509_pubkey(pxpk, &q, length); 512e1051a39Sopenharmony_ci if (xpk == NULL) 513e1051a39Sopenharmony_ci goto end; 514e1051a39Sopenharmony_ci pktmp = X509_PUBKEY_get(xpk); 515e1051a39Sopenharmony_ci X509_PUBKEY_free(xpk); 516e1051a39Sopenharmony_ci xpk2 = NULL; /* We know that xpk == xpk2 */ 517e1051a39Sopenharmony_ci if (pktmp == NULL) 518e1051a39Sopenharmony_ci goto end; 519e1051a39Sopenharmony_ci *pp = q; 520e1051a39Sopenharmony_ci if (a != NULL) { 521e1051a39Sopenharmony_ci EVP_PKEY_free(*a); 522e1051a39Sopenharmony_ci *a = pktmp; 523e1051a39Sopenharmony_ci } 524e1051a39Sopenharmony_ci end: 525e1051a39Sopenharmony_ci X509_PUBKEY_free(xpk2); 526e1051a39Sopenharmony_ci return pktmp; 527e1051a39Sopenharmony_ci} 528e1051a39Sopenharmony_ci 529e1051a39Sopenharmony_ci/* For the algorithm specific d2i functions further down */ 530e1051a39Sopenharmony_ciEVP_PKEY *ossl_d2i_PUBKEY_legacy(EVP_PKEY **a, const unsigned char **pp, 531e1051a39Sopenharmony_ci long length) 532e1051a39Sopenharmony_ci{ 533e1051a39Sopenharmony_ci return d2i_PUBKEY_int(a, pp, length, NULL, NULL, 1, d2i_X509_PUBKEY); 534e1051a39Sopenharmony_ci} 535e1051a39Sopenharmony_ci 536e1051a39Sopenharmony_ciEVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length, 537e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 538e1051a39Sopenharmony_ci{ 539e1051a39Sopenharmony_ci return d2i_PUBKEY_int(a, pp, length, libctx, propq, 0, d2i_X509_PUBKEY); 540e1051a39Sopenharmony_ci} 541e1051a39Sopenharmony_ci 542e1051a39Sopenharmony_ciEVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) 543e1051a39Sopenharmony_ci{ 544e1051a39Sopenharmony_ci return d2i_PUBKEY_ex(a, pp, length, NULL, NULL); 545e1051a39Sopenharmony_ci} 546e1051a39Sopenharmony_ci 547e1051a39Sopenharmony_ciint i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) 548e1051a39Sopenharmony_ci{ 549e1051a39Sopenharmony_ci int ret = -1; 550e1051a39Sopenharmony_ci 551e1051a39Sopenharmony_ci if (a == NULL) 552e1051a39Sopenharmony_ci return 0; 553e1051a39Sopenharmony_ci if (a->ameth != NULL) { 554e1051a39Sopenharmony_ci X509_PUBKEY *xpk = NULL; 555e1051a39Sopenharmony_ci 556e1051a39Sopenharmony_ci if ((xpk = X509_PUBKEY_new()) == NULL) 557e1051a39Sopenharmony_ci return -1; 558e1051a39Sopenharmony_ci 559e1051a39Sopenharmony_ci /* pub_encode() only encode parameters, not the key itself */ 560e1051a39Sopenharmony_ci if (a->ameth->pub_encode != NULL && a->ameth->pub_encode(xpk, a)) { 561e1051a39Sopenharmony_ci xpk->pkey = (EVP_PKEY *)a; 562e1051a39Sopenharmony_ci ret = i2d_X509_PUBKEY(xpk, pp); 563e1051a39Sopenharmony_ci xpk->pkey = NULL; 564e1051a39Sopenharmony_ci } 565e1051a39Sopenharmony_ci X509_PUBKEY_free(xpk); 566e1051a39Sopenharmony_ci } else if (a->keymgmt != NULL) { 567e1051a39Sopenharmony_ci OSSL_ENCODER_CTX *ctx = 568e1051a39Sopenharmony_ci OSSL_ENCODER_CTX_new_for_pkey(a, EVP_PKEY_PUBLIC_KEY, 569e1051a39Sopenharmony_ci "DER", "SubjectPublicKeyInfo", 570e1051a39Sopenharmony_ci NULL); 571e1051a39Sopenharmony_ci BIO *out = BIO_new(BIO_s_mem()); 572e1051a39Sopenharmony_ci BUF_MEM *buf = NULL; 573e1051a39Sopenharmony_ci 574e1051a39Sopenharmony_ci if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0 575e1051a39Sopenharmony_ci && out != NULL 576e1051a39Sopenharmony_ci && OSSL_ENCODER_to_bio(ctx, out) 577e1051a39Sopenharmony_ci && BIO_get_mem_ptr(out, &buf) > 0) { 578e1051a39Sopenharmony_ci ret = buf->length; 579e1051a39Sopenharmony_ci 580e1051a39Sopenharmony_ci if (pp != NULL) { 581e1051a39Sopenharmony_ci if (*pp == NULL) { 582e1051a39Sopenharmony_ci *pp = (unsigned char *)buf->data; 583e1051a39Sopenharmony_ci buf->length = 0; 584e1051a39Sopenharmony_ci buf->data = NULL; 585e1051a39Sopenharmony_ci } else { 586e1051a39Sopenharmony_ci memcpy(*pp, buf->data, ret); 587e1051a39Sopenharmony_ci *pp += ret; 588e1051a39Sopenharmony_ci } 589e1051a39Sopenharmony_ci } 590e1051a39Sopenharmony_ci } 591e1051a39Sopenharmony_ci BIO_free(out); 592e1051a39Sopenharmony_ci OSSL_ENCODER_CTX_free(ctx); 593e1051a39Sopenharmony_ci } 594e1051a39Sopenharmony_ci 595e1051a39Sopenharmony_ci return ret; 596e1051a39Sopenharmony_ci} 597e1051a39Sopenharmony_ci 598e1051a39Sopenharmony_ci/* 599e1051a39Sopenharmony_ci * The following are equivalents but which return RSA and DSA keys 600e1051a39Sopenharmony_ci */ 601e1051a39Sopenharmony_ciRSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) 602e1051a39Sopenharmony_ci{ 603e1051a39Sopenharmony_ci EVP_PKEY *pkey; 604e1051a39Sopenharmony_ci RSA *key = NULL; 605e1051a39Sopenharmony_ci const unsigned char *q; 606e1051a39Sopenharmony_ci 607e1051a39Sopenharmony_ci q = *pp; 608e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 609e1051a39Sopenharmony_ci if (pkey == NULL) 610e1051a39Sopenharmony_ci return NULL; 611e1051a39Sopenharmony_ci key = EVP_PKEY_get1_RSA(pkey); 612e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 613e1051a39Sopenharmony_ci if (key == NULL) 614e1051a39Sopenharmony_ci return NULL; 615e1051a39Sopenharmony_ci *pp = q; 616e1051a39Sopenharmony_ci if (a != NULL) { 617e1051a39Sopenharmony_ci RSA_free(*a); 618e1051a39Sopenharmony_ci *a = key; 619e1051a39Sopenharmony_ci } 620e1051a39Sopenharmony_ci return key; 621e1051a39Sopenharmony_ci} 622e1051a39Sopenharmony_ci 623e1051a39Sopenharmony_ciint i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp) 624e1051a39Sopenharmony_ci{ 625e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 626e1051a39Sopenharmony_ci int ret; 627e1051a39Sopenharmony_ci if (!a) 628e1051a39Sopenharmony_ci return 0; 629e1051a39Sopenharmony_ci pktmp = EVP_PKEY_new(); 630e1051a39Sopenharmony_ci if (pktmp == NULL) { 631e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 632e1051a39Sopenharmony_ci return -1; 633e1051a39Sopenharmony_ci } 634e1051a39Sopenharmony_ci (void)EVP_PKEY_assign_RSA(pktmp, (RSA *)a); 635e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 636e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 637e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 638e1051a39Sopenharmony_ci return ret; 639e1051a39Sopenharmony_ci} 640e1051a39Sopenharmony_ci 641e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DH 642e1051a39Sopenharmony_ciDH *ossl_d2i_DH_PUBKEY(DH **a, const unsigned char **pp, long length) 643e1051a39Sopenharmony_ci{ 644e1051a39Sopenharmony_ci EVP_PKEY *pkey; 645e1051a39Sopenharmony_ci DH *key = NULL; 646e1051a39Sopenharmony_ci const unsigned char *q; 647e1051a39Sopenharmony_ci 648e1051a39Sopenharmony_ci q = *pp; 649e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 650e1051a39Sopenharmony_ci if (pkey == NULL) 651e1051a39Sopenharmony_ci return NULL; 652e1051a39Sopenharmony_ci if (EVP_PKEY_get_id(pkey) == EVP_PKEY_DH) 653e1051a39Sopenharmony_ci key = EVP_PKEY_get1_DH(pkey); 654e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 655e1051a39Sopenharmony_ci if (key == NULL) 656e1051a39Sopenharmony_ci return NULL; 657e1051a39Sopenharmony_ci *pp = q; 658e1051a39Sopenharmony_ci if (a != NULL) { 659e1051a39Sopenharmony_ci DH_free(*a); 660e1051a39Sopenharmony_ci *a = key; 661e1051a39Sopenharmony_ci } 662e1051a39Sopenharmony_ci return key; 663e1051a39Sopenharmony_ci} 664e1051a39Sopenharmony_ci 665e1051a39Sopenharmony_ciint ossl_i2d_DH_PUBKEY(const DH *a, unsigned char **pp) 666e1051a39Sopenharmony_ci{ 667e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 668e1051a39Sopenharmony_ci int ret; 669e1051a39Sopenharmony_ci if (!a) 670e1051a39Sopenharmony_ci return 0; 671e1051a39Sopenharmony_ci pktmp = EVP_PKEY_new(); 672e1051a39Sopenharmony_ci if (pktmp == NULL) { 673e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 674e1051a39Sopenharmony_ci return -1; 675e1051a39Sopenharmony_ci } 676e1051a39Sopenharmony_ci (void)EVP_PKEY_assign_DH(pktmp, (DH *)a); 677e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 678e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 679e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 680e1051a39Sopenharmony_ci return ret; 681e1051a39Sopenharmony_ci} 682e1051a39Sopenharmony_ci 683e1051a39Sopenharmony_ciDH *ossl_d2i_DHx_PUBKEY(DH **a, const unsigned char **pp, long length) 684e1051a39Sopenharmony_ci{ 685e1051a39Sopenharmony_ci EVP_PKEY *pkey; 686e1051a39Sopenharmony_ci DH *key = NULL; 687e1051a39Sopenharmony_ci const unsigned char *q; 688e1051a39Sopenharmony_ci 689e1051a39Sopenharmony_ci q = *pp; 690e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 691e1051a39Sopenharmony_ci if (pkey == NULL) 692e1051a39Sopenharmony_ci return NULL; 693e1051a39Sopenharmony_ci if (EVP_PKEY_get_id(pkey) == EVP_PKEY_DHX) 694e1051a39Sopenharmony_ci key = EVP_PKEY_get1_DH(pkey); 695e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 696e1051a39Sopenharmony_ci if (key == NULL) 697e1051a39Sopenharmony_ci return NULL; 698e1051a39Sopenharmony_ci *pp = q; 699e1051a39Sopenharmony_ci if (a != NULL) { 700e1051a39Sopenharmony_ci DH_free(*a); 701e1051a39Sopenharmony_ci *a = key; 702e1051a39Sopenharmony_ci } 703e1051a39Sopenharmony_ci return key; 704e1051a39Sopenharmony_ci} 705e1051a39Sopenharmony_ci 706e1051a39Sopenharmony_ciint ossl_i2d_DHx_PUBKEY(const DH *a, unsigned char **pp) 707e1051a39Sopenharmony_ci{ 708e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 709e1051a39Sopenharmony_ci int ret; 710e1051a39Sopenharmony_ci if (!a) 711e1051a39Sopenharmony_ci return 0; 712e1051a39Sopenharmony_ci pktmp = EVP_PKEY_new(); 713e1051a39Sopenharmony_ci if (pktmp == NULL) { 714e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 715e1051a39Sopenharmony_ci return -1; 716e1051a39Sopenharmony_ci } 717e1051a39Sopenharmony_ci (void)EVP_PKEY_assign(pktmp, EVP_PKEY_DHX, (DH *)a); 718e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 719e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 720e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 721e1051a39Sopenharmony_ci return ret; 722e1051a39Sopenharmony_ci} 723e1051a39Sopenharmony_ci#endif 724e1051a39Sopenharmony_ci 725e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DSA 726e1051a39Sopenharmony_ciDSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) 727e1051a39Sopenharmony_ci{ 728e1051a39Sopenharmony_ci EVP_PKEY *pkey; 729e1051a39Sopenharmony_ci DSA *key = NULL; 730e1051a39Sopenharmony_ci const unsigned char *q; 731e1051a39Sopenharmony_ci 732e1051a39Sopenharmony_ci q = *pp; 733e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 734e1051a39Sopenharmony_ci if (pkey == NULL) 735e1051a39Sopenharmony_ci return NULL; 736e1051a39Sopenharmony_ci key = EVP_PKEY_get1_DSA(pkey); 737e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 738e1051a39Sopenharmony_ci if (key == NULL) 739e1051a39Sopenharmony_ci return NULL; 740e1051a39Sopenharmony_ci *pp = q; 741e1051a39Sopenharmony_ci if (a != NULL) { 742e1051a39Sopenharmony_ci DSA_free(*a); 743e1051a39Sopenharmony_ci *a = key; 744e1051a39Sopenharmony_ci } 745e1051a39Sopenharmony_ci return key; 746e1051a39Sopenharmony_ci} 747e1051a39Sopenharmony_ci 748e1051a39Sopenharmony_ci/* Called from decoders; disallows provided DSA keys without parameters. */ 749e1051a39Sopenharmony_ciDSA *ossl_d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) 750e1051a39Sopenharmony_ci{ 751e1051a39Sopenharmony_ci DSA *key = NULL; 752e1051a39Sopenharmony_ci const unsigned char *data; 753e1051a39Sopenharmony_ci const BIGNUM *p, *q, *g; 754e1051a39Sopenharmony_ci 755e1051a39Sopenharmony_ci data = *pp; 756e1051a39Sopenharmony_ci key = d2i_DSA_PUBKEY(NULL, &data, length); 757e1051a39Sopenharmony_ci if (key == NULL) 758e1051a39Sopenharmony_ci return NULL; 759e1051a39Sopenharmony_ci DSA_get0_pqg(key, &p, &q, &g); 760e1051a39Sopenharmony_ci if (p == NULL || q == NULL || g == NULL) { 761e1051a39Sopenharmony_ci DSA_free(key); 762e1051a39Sopenharmony_ci return NULL; 763e1051a39Sopenharmony_ci } 764e1051a39Sopenharmony_ci *pp = data; 765e1051a39Sopenharmony_ci if (a != NULL) { 766e1051a39Sopenharmony_ci DSA_free(*a); 767e1051a39Sopenharmony_ci *a = key; 768e1051a39Sopenharmony_ci } 769e1051a39Sopenharmony_ci return key; 770e1051a39Sopenharmony_ci} 771e1051a39Sopenharmony_ci 772e1051a39Sopenharmony_ciint i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp) 773e1051a39Sopenharmony_ci{ 774e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 775e1051a39Sopenharmony_ci int ret; 776e1051a39Sopenharmony_ci if (!a) 777e1051a39Sopenharmony_ci return 0; 778e1051a39Sopenharmony_ci pktmp = EVP_PKEY_new(); 779e1051a39Sopenharmony_ci if (pktmp == NULL) { 780e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 781e1051a39Sopenharmony_ci return -1; 782e1051a39Sopenharmony_ci } 783e1051a39Sopenharmony_ci (void)EVP_PKEY_assign_DSA(pktmp, (DSA *)a); 784e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 785e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 786e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 787e1051a39Sopenharmony_ci return ret; 788e1051a39Sopenharmony_ci} 789e1051a39Sopenharmony_ci#endif 790e1051a39Sopenharmony_ci 791e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC 792e1051a39Sopenharmony_ciEC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) 793e1051a39Sopenharmony_ci{ 794e1051a39Sopenharmony_ci EVP_PKEY *pkey; 795e1051a39Sopenharmony_ci EC_KEY *key = NULL; 796e1051a39Sopenharmony_ci const unsigned char *q; 797e1051a39Sopenharmony_ci int type; 798e1051a39Sopenharmony_ci 799e1051a39Sopenharmony_ci q = *pp; 800e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 801e1051a39Sopenharmony_ci if (pkey == NULL) 802e1051a39Sopenharmony_ci return NULL; 803e1051a39Sopenharmony_ci type = EVP_PKEY_get_id(pkey); 804e1051a39Sopenharmony_ci if (type == EVP_PKEY_EC || type == EVP_PKEY_SM2) 805e1051a39Sopenharmony_ci key = EVP_PKEY_get1_EC_KEY(pkey); 806e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 807e1051a39Sopenharmony_ci if (key == NULL) 808e1051a39Sopenharmony_ci return NULL; 809e1051a39Sopenharmony_ci *pp = q; 810e1051a39Sopenharmony_ci if (a != NULL) { 811e1051a39Sopenharmony_ci EC_KEY_free(*a); 812e1051a39Sopenharmony_ci *a = key; 813e1051a39Sopenharmony_ci } 814e1051a39Sopenharmony_ci return key; 815e1051a39Sopenharmony_ci} 816e1051a39Sopenharmony_ci 817e1051a39Sopenharmony_ciint i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp) 818e1051a39Sopenharmony_ci{ 819e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 820e1051a39Sopenharmony_ci int ret; 821e1051a39Sopenharmony_ci 822e1051a39Sopenharmony_ci if (a == NULL) 823e1051a39Sopenharmony_ci return 0; 824e1051a39Sopenharmony_ci if ((pktmp = EVP_PKEY_new()) == NULL) { 825e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 826e1051a39Sopenharmony_ci return -1; 827e1051a39Sopenharmony_ci } 828e1051a39Sopenharmony_ci (void)EVP_PKEY_assign_EC_KEY(pktmp, (EC_KEY *)a); 829e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 830e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 831e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 832e1051a39Sopenharmony_ci return ret; 833e1051a39Sopenharmony_ci} 834e1051a39Sopenharmony_ci 835e1051a39Sopenharmony_ciECX_KEY *ossl_d2i_ED25519_PUBKEY(ECX_KEY **a, 836e1051a39Sopenharmony_ci const unsigned char **pp, long length) 837e1051a39Sopenharmony_ci{ 838e1051a39Sopenharmony_ci EVP_PKEY *pkey; 839e1051a39Sopenharmony_ci ECX_KEY *key = NULL; 840e1051a39Sopenharmony_ci const unsigned char *q; 841e1051a39Sopenharmony_ci 842e1051a39Sopenharmony_ci q = *pp; 843e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 844e1051a39Sopenharmony_ci if (pkey == NULL) 845e1051a39Sopenharmony_ci return NULL; 846e1051a39Sopenharmony_ci key = ossl_evp_pkey_get1_ED25519(pkey); 847e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 848e1051a39Sopenharmony_ci if (key == NULL) 849e1051a39Sopenharmony_ci return NULL; 850e1051a39Sopenharmony_ci *pp = q; 851e1051a39Sopenharmony_ci if (a != NULL) { 852e1051a39Sopenharmony_ci ossl_ecx_key_free(*a); 853e1051a39Sopenharmony_ci *a = key; 854e1051a39Sopenharmony_ci } 855e1051a39Sopenharmony_ci return key; 856e1051a39Sopenharmony_ci} 857e1051a39Sopenharmony_ci 858e1051a39Sopenharmony_ciint ossl_i2d_ED25519_PUBKEY(const ECX_KEY *a, unsigned char **pp) 859e1051a39Sopenharmony_ci{ 860e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 861e1051a39Sopenharmony_ci int ret; 862e1051a39Sopenharmony_ci 863e1051a39Sopenharmony_ci if (a == NULL) 864e1051a39Sopenharmony_ci return 0; 865e1051a39Sopenharmony_ci if ((pktmp = EVP_PKEY_new()) == NULL) { 866e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 867e1051a39Sopenharmony_ci return -1; 868e1051a39Sopenharmony_ci } 869e1051a39Sopenharmony_ci (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED25519, (ECX_KEY *)a); 870e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 871e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 872e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 873e1051a39Sopenharmony_ci return ret; 874e1051a39Sopenharmony_ci} 875e1051a39Sopenharmony_ci 876e1051a39Sopenharmony_ciECX_KEY *ossl_d2i_ED448_PUBKEY(ECX_KEY **a, 877e1051a39Sopenharmony_ci const unsigned char **pp, long length) 878e1051a39Sopenharmony_ci{ 879e1051a39Sopenharmony_ci EVP_PKEY *pkey; 880e1051a39Sopenharmony_ci ECX_KEY *key = NULL; 881e1051a39Sopenharmony_ci const unsigned char *q; 882e1051a39Sopenharmony_ci 883e1051a39Sopenharmony_ci q = *pp; 884e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 885e1051a39Sopenharmony_ci if (pkey == NULL) 886e1051a39Sopenharmony_ci return NULL; 887e1051a39Sopenharmony_ci if (EVP_PKEY_get_id(pkey) == EVP_PKEY_ED448) 888e1051a39Sopenharmony_ci key = ossl_evp_pkey_get1_ED448(pkey); 889e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 890e1051a39Sopenharmony_ci if (key == NULL) 891e1051a39Sopenharmony_ci return NULL; 892e1051a39Sopenharmony_ci *pp = q; 893e1051a39Sopenharmony_ci if (a != NULL) { 894e1051a39Sopenharmony_ci ossl_ecx_key_free(*a); 895e1051a39Sopenharmony_ci *a = key; 896e1051a39Sopenharmony_ci } 897e1051a39Sopenharmony_ci return key; 898e1051a39Sopenharmony_ci} 899e1051a39Sopenharmony_ci 900e1051a39Sopenharmony_ciint ossl_i2d_ED448_PUBKEY(const ECX_KEY *a, unsigned char **pp) 901e1051a39Sopenharmony_ci{ 902e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 903e1051a39Sopenharmony_ci int ret; 904e1051a39Sopenharmony_ci 905e1051a39Sopenharmony_ci if (a == NULL) 906e1051a39Sopenharmony_ci return 0; 907e1051a39Sopenharmony_ci if ((pktmp = EVP_PKEY_new()) == NULL) { 908e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 909e1051a39Sopenharmony_ci return -1; 910e1051a39Sopenharmony_ci } 911e1051a39Sopenharmony_ci (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED448, (ECX_KEY *)a); 912e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 913e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 914e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 915e1051a39Sopenharmony_ci return ret; 916e1051a39Sopenharmony_ci} 917e1051a39Sopenharmony_ci 918e1051a39Sopenharmony_ciECX_KEY *ossl_d2i_X25519_PUBKEY(ECX_KEY **a, 919e1051a39Sopenharmony_ci const unsigned char **pp, long length) 920e1051a39Sopenharmony_ci{ 921e1051a39Sopenharmony_ci EVP_PKEY *pkey; 922e1051a39Sopenharmony_ci ECX_KEY *key = NULL; 923e1051a39Sopenharmony_ci const unsigned char *q; 924e1051a39Sopenharmony_ci 925e1051a39Sopenharmony_ci q = *pp; 926e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 927e1051a39Sopenharmony_ci if (pkey == NULL) 928e1051a39Sopenharmony_ci return NULL; 929e1051a39Sopenharmony_ci if (EVP_PKEY_get_id(pkey) == EVP_PKEY_X25519) 930e1051a39Sopenharmony_ci key = ossl_evp_pkey_get1_X25519(pkey); 931e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 932e1051a39Sopenharmony_ci if (key == NULL) 933e1051a39Sopenharmony_ci return NULL; 934e1051a39Sopenharmony_ci *pp = q; 935e1051a39Sopenharmony_ci if (a != NULL) { 936e1051a39Sopenharmony_ci ossl_ecx_key_free(*a); 937e1051a39Sopenharmony_ci *a = key; 938e1051a39Sopenharmony_ci } 939e1051a39Sopenharmony_ci return key; 940e1051a39Sopenharmony_ci} 941e1051a39Sopenharmony_ci 942e1051a39Sopenharmony_ciint ossl_i2d_X25519_PUBKEY(const ECX_KEY *a, unsigned char **pp) 943e1051a39Sopenharmony_ci{ 944e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 945e1051a39Sopenharmony_ci int ret; 946e1051a39Sopenharmony_ci 947e1051a39Sopenharmony_ci if (a == NULL) 948e1051a39Sopenharmony_ci return 0; 949e1051a39Sopenharmony_ci if ((pktmp = EVP_PKEY_new()) == NULL) { 950e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 951e1051a39Sopenharmony_ci return -1; 952e1051a39Sopenharmony_ci } 953e1051a39Sopenharmony_ci (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X25519, (ECX_KEY *)a); 954e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 955e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 956e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 957e1051a39Sopenharmony_ci return ret; 958e1051a39Sopenharmony_ci} 959e1051a39Sopenharmony_ci 960e1051a39Sopenharmony_ciECX_KEY *ossl_d2i_X448_PUBKEY(ECX_KEY **a, 961e1051a39Sopenharmony_ci const unsigned char **pp, long length) 962e1051a39Sopenharmony_ci{ 963e1051a39Sopenharmony_ci EVP_PKEY *pkey; 964e1051a39Sopenharmony_ci ECX_KEY *key = NULL; 965e1051a39Sopenharmony_ci const unsigned char *q; 966e1051a39Sopenharmony_ci 967e1051a39Sopenharmony_ci q = *pp; 968e1051a39Sopenharmony_ci pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); 969e1051a39Sopenharmony_ci if (pkey == NULL) 970e1051a39Sopenharmony_ci return NULL; 971e1051a39Sopenharmony_ci if (EVP_PKEY_get_id(pkey) == EVP_PKEY_X448) 972e1051a39Sopenharmony_ci key = ossl_evp_pkey_get1_X448(pkey); 973e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 974e1051a39Sopenharmony_ci if (key == NULL) 975e1051a39Sopenharmony_ci return NULL; 976e1051a39Sopenharmony_ci *pp = q; 977e1051a39Sopenharmony_ci if (a != NULL) { 978e1051a39Sopenharmony_ci ossl_ecx_key_free(*a); 979e1051a39Sopenharmony_ci *a = key; 980e1051a39Sopenharmony_ci } 981e1051a39Sopenharmony_ci return key; 982e1051a39Sopenharmony_ci} 983e1051a39Sopenharmony_ci 984e1051a39Sopenharmony_ciint ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp) 985e1051a39Sopenharmony_ci{ 986e1051a39Sopenharmony_ci EVP_PKEY *pktmp; 987e1051a39Sopenharmony_ci int ret; 988e1051a39Sopenharmony_ci 989e1051a39Sopenharmony_ci if (a == NULL) 990e1051a39Sopenharmony_ci return 0; 991e1051a39Sopenharmony_ci if ((pktmp = EVP_PKEY_new()) == NULL) { 992e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 993e1051a39Sopenharmony_ci return -1; 994e1051a39Sopenharmony_ci } 995e1051a39Sopenharmony_ci (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X448, (ECX_KEY *)a); 996e1051a39Sopenharmony_ci ret = i2d_PUBKEY(pktmp, pp); 997e1051a39Sopenharmony_ci pktmp->pkey.ptr = NULL; 998e1051a39Sopenharmony_ci EVP_PKEY_free(pktmp); 999e1051a39Sopenharmony_ci return ret; 1000e1051a39Sopenharmony_ci} 1001e1051a39Sopenharmony_ci 1002e1051a39Sopenharmony_ci#endif 1003e1051a39Sopenharmony_ci 1004e1051a39Sopenharmony_ciint X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, 1005e1051a39Sopenharmony_ci int ptype, void *pval, 1006e1051a39Sopenharmony_ci unsigned char *penc, int penclen) 1007e1051a39Sopenharmony_ci{ 1008e1051a39Sopenharmony_ci if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) 1009e1051a39Sopenharmony_ci return 0; 1010e1051a39Sopenharmony_ci if (penc) { 1011e1051a39Sopenharmony_ci OPENSSL_free(pub->public_key->data); 1012e1051a39Sopenharmony_ci pub->public_key->data = penc; 1013e1051a39Sopenharmony_ci pub->public_key->length = penclen; 1014e1051a39Sopenharmony_ci /* Set number of unused bits to zero */ 1015e1051a39Sopenharmony_ci pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 1016e1051a39Sopenharmony_ci pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; 1017e1051a39Sopenharmony_ci } 1018e1051a39Sopenharmony_ci return 1; 1019e1051a39Sopenharmony_ci} 1020e1051a39Sopenharmony_ci 1021e1051a39Sopenharmony_ciint X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, 1022e1051a39Sopenharmony_ci const unsigned char **pk, int *ppklen, 1023e1051a39Sopenharmony_ci X509_ALGOR **pa, const X509_PUBKEY *pub) 1024e1051a39Sopenharmony_ci{ 1025e1051a39Sopenharmony_ci if (ppkalg) 1026e1051a39Sopenharmony_ci *ppkalg = pub->algor->algorithm; 1027e1051a39Sopenharmony_ci if (pk) { 1028e1051a39Sopenharmony_ci *pk = pub->public_key->data; 1029e1051a39Sopenharmony_ci *ppklen = pub->public_key->length; 1030e1051a39Sopenharmony_ci } 1031e1051a39Sopenharmony_ci if (pa) 1032e1051a39Sopenharmony_ci *pa = pub->algor; 1033e1051a39Sopenharmony_ci return 1; 1034e1051a39Sopenharmony_ci} 1035e1051a39Sopenharmony_ci 1036e1051a39Sopenharmony_ciASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) 1037e1051a39Sopenharmony_ci{ 1038e1051a39Sopenharmony_ci if (x == NULL) 1039e1051a39Sopenharmony_ci return NULL; 1040e1051a39Sopenharmony_ci return x->cert_info.key->public_key; 1041e1051a39Sopenharmony_ci} 1042e1051a39Sopenharmony_ci 1043e1051a39Sopenharmony_ci/* Returns 1 for equal, 0, for non-equal, < 0 on error */ 1044e1051a39Sopenharmony_ciint X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b) 1045e1051a39Sopenharmony_ci{ 1046e1051a39Sopenharmony_ci X509_ALGOR *algA, *algB; 1047e1051a39Sopenharmony_ci EVP_PKEY *pA, *pB; 1048e1051a39Sopenharmony_ci 1049e1051a39Sopenharmony_ci if (a == b) 1050e1051a39Sopenharmony_ci return 1; 1051e1051a39Sopenharmony_ci if (a == NULL || b == NULL) 1052e1051a39Sopenharmony_ci return 0; 1053e1051a39Sopenharmony_ci if (!X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a) || algA == NULL 1054e1051a39Sopenharmony_ci || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b) || algB == NULL) 1055e1051a39Sopenharmony_ci return -2; 1056e1051a39Sopenharmony_ci if (X509_ALGOR_cmp(algA, algB) != 0) 1057e1051a39Sopenharmony_ci return 0; 1058e1051a39Sopenharmony_ci if ((pA = X509_PUBKEY_get0(a)) == NULL 1059e1051a39Sopenharmony_ci || (pB = X509_PUBKEY_get0(b)) == NULL) 1060e1051a39Sopenharmony_ci return -2; 1061e1051a39Sopenharmony_ci return EVP_PKEY_eq(pA, pB); 1062e1051a39Sopenharmony_ci} 1063e1051a39Sopenharmony_ci 1064e1051a39Sopenharmony_ciint ossl_x509_PUBKEY_get0_libctx(OSSL_LIB_CTX **plibctx, const char **ppropq, 1065e1051a39Sopenharmony_ci const X509_PUBKEY *key) 1066e1051a39Sopenharmony_ci{ 1067e1051a39Sopenharmony_ci if (plibctx) 1068e1051a39Sopenharmony_ci *plibctx = key->libctx; 1069e1051a39Sopenharmony_ci if (ppropq) 1070e1051a39Sopenharmony_ci *ppropq = key->propq; 1071e1051a39Sopenharmony_ci return 1; 1072e1051a39Sopenharmony_ci} 1073