1*b077aed3SPierre Pronchery /* 2*b077aed3SPierre Pronchery * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. 3*b077aed3SPierre Pronchery * 4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use 5*b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy 6*b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at 7*b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html 8*b077aed3SPierre Pronchery */ 9*b077aed3SPierre Pronchery 10*b077aed3SPierre Pronchery /* 11*b077aed3SPierre Pronchery * Low level APIs are deprecated for public use, but still ok for internal use. 12*b077aed3SPierre Pronchery */ 13*b077aed3SPierre Pronchery #include "internal/deprecated.h" 14*b077aed3SPierre Pronchery 15*b077aed3SPierre Pronchery #include <openssl/core.h> 16*b077aed3SPierre Pronchery #include <openssl/core_dispatch.h> 17*b077aed3SPierre Pronchery #include <openssl/core_names.h> 18*b077aed3SPierre Pronchery #include <openssl/crypto.h> 19*b077aed3SPierre Pronchery #include <openssl/params.h> 20*b077aed3SPierre Pronchery #include <openssl/asn1.h> 21*b077aed3SPierre Pronchery #include <openssl/err.h> 22*b077aed3SPierre Pronchery #include <openssl/pem.h> 23*b077aed3SPierre Pronchery #include <openssl/x509.h> 24*b077aed3SPierre Pronchery #include <openssl/pkcs12.h> /* PKCS8_encrypt() */ 25*b077aed3SPierre Pronchery #include <openssl/dh.h> 26*b077aed3SPierre Pronchery #include <openssl/dsa.h> 27*b077aed3SPierre Pronchery #include <openssl/ec.h> 28*b077aed3SPierre Pronchery #include <openssl/proverr.h> 29*b077aed3SPierre Pronchery #include "internal/passphrase.h" 30*b077aed3SPierre Pronchery #include "internal/cryptlib.h" 31*b077aed3SPierre Pronchery #include "crypto/ecx.h" 32*b077aed3SPierre Pronchery #include "crypto/rsa.h" 33*b077aed3SPierre Pronchery #include "prov/implementations.h" 34*b077aed3SPierre Pronchery #include "prov/bio.h" 35*b077aed3SPierre Pronchery #include "prov/provider_ctx.h" 36*b077aed3SPierre Pronchery #include "prov/der_rsa.h" 37*b077aed3SPierre Pronchery #include "endecoder_local.h" 38*b077aed3SPierre Pronchery 39*b077aed3SPierre Pronchery #if defined(OPENSSL_NO_DH) && defined(OPENSSL_NO_DSA) && defined(OPENSSL_NO_EC) 40*b077aed3SPierre Pronchery # define OPENSSL_NO_KEYPARAMS 41*b077aed3SPierre Pronchery #endif 42*b077aed3SPierre Pronchery 43*b077aed3SPierre Pronchery struct key2any_ctx_st { 44*b077aed3SPierre Pronchery PROV_CTX *provctx; 45*b077aed3SPierre Pronchery 46*b077aed3SPierre Pronchery /* Set to 0 if parameters should not be saved (dsa only) */ 47*b077aed3SPierre Pronchery int save_parameters; 48*b077aed3SPierre Pronchery 49*b077aed3SPierre Pronchery /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */ 50*b077aed3SPierre Pronchery int cipher_intent; 51*b077aed3SPierre Pronchery 52*b077aed3SPierre Pronchery EVP_CIPHER *cipher; 53*b077aed3SPierre Pronchery 54*b077aed3SPierre Pronchery struct ossl_passphrase_data_st pwdata; 55*b077aed3SPierre Pronchery }; 56*b077aed3SPierre Pronchery 57*b077aed3SPierre Pronchery typedef int check_key_type_fn(const void *key, int nid); 58*b077aed3SPierre Pronchery typedef int key_to_paramstring_fn(const void *key, int nid, int save, 59*b077aed3SPierre Pronchery void **str, int *strtype); 60*b077aed3SPierre Pronchery typedef int key_to_der_fn(BIO *out, const void *key, 61*b077aed3SPierre Pronchery int key_nid, const char *pemname, 62*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, i2d_of_void *k2d, 63*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx); 64*b077aed3SPierre Pronchery typedef int write_bio_of_void_fn(BIO *bp, const void *x); 65*b077aed3SPierre Pronchery 66*b077aed3SPierre Pronchery 67*b077aed3SPierre Pronchery /* Free the blob allocated during key_to_paramstring_fn */ 68*b077aed3SPierre Pronchery static void free_asn1_data(int type, void *data) 69*b077aed3SPierre Pronchery { 70*b077aed3SPierre Pronchery switch(type) { 71*b077aed3SPierre Pronchery case V_ASN1_OBJECT: 72*b077aed3SPierre Pronchery ASN1_OBJECT_free(data); 73*b077aed3SPierre Pronchery break; 74*b077aed3SPierre Pronchery case V_ASN1_SEQUENCE: 75*b077aed3SPierre Pronchery ASN1_STRING_free(data); 76*b077aed3SPierre Pronchery break; 77*b077aed3SPierre Pronchery } 78*b077aed3SPierre Pronchery } 79*b077aed3SPierre Pronchery 80*b077aed3SPierre Pronchery static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, 81*b077aed3SPierre Pronchery void *params, int params_type, 82*b077aed3SPierre Pronchery i2d_of_void *k2d) 83*b077aed3SPierre Pronchery { 84*b077aed3SPierre Pronchery /* der, derlen store the key DER output and its length */ 85*b077aed3SPierre Pronchery unsigned char *der = NULL; 86*b077aed3SPierre Pronchery int derlen; 87*b077aed3SPierre Pronchery /* The final PKCS#8 info */ 88*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO *p8info = NULL; 89*b077aed3SPierre Pronchery 90*b077aed3SPierre Pronchery if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL 91*b077aed3SPierre Pronchery || (derlen = k2d(key, &der)) <= 0 92*b077aed3SPierre Pronchery || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0, 93*b077aed3SPierre Pronchery params_type, params, der, derlen)) { 94*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 95*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO_free(p8info); 96*b077aed3SPierre Pronchery OPENSSL_free(der); 97*b077aed3SPierre Pronchery p8info = NULL; 98*b077aed3SPierre Pronchery } 99*b077aed3SPierre Pronchery 100*b077aed3SPierre Pronchery return p8info; 101*b077aed3SPierre Pronchery } 102*b077aed3SPierre Pronchery 103*b077aed3SPierre Pronchery static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info, 104*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 105*b077aed3SPierre Pronchery { 106*b077aed3SPierre Pronchery X509_SIG *p8 = NULL; 107*b077aed3SPierre Pronchery char kstr[PEM_BUFSIZE]; 108*b077aed3SPierre Pronchery size_t klen = 0; 109*b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); 110*b077aed3SPierre Pronchery 111*b077aed3SPierre Pronchery if (ctx->cipher == NULL) 112*b077aed3SPierre Pronchery return NULL; 113*b077aed3SPierre Pronchery 114*b077aed3SPierre Pronchery if (!ossl_pw_get_passphrase(kstr, sizeof(kstr), &klen, NULL, 1, 115*b077aed3SPierre Pronchery &ctx->pwdata)) { 116*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE); 117*b077aed3SPierre Pronchery return NULL; 118*b077aed3SPierre Pronchery } 119*b077aed3SPierre Pronchery /* First argument == -1 means "standard" */ 120*b077aed3SPierre Pronchery p8 = PKCS8_encrypt_ex(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info, libctx, NULL); 121*b077aed3SPierre Pronchery OPENSSL_cleanse(kstr, klen); 122*b077aed3SPierre Pronchery return p8; 123*b077aed3SPierre Pronchery } 124*b077aed3SPierre Pronchery 125*b077aed3SPierre Pronchery static X509_SIG *key_to_encp8(const void *key, int key_nid, 126*b077aed3SPierre Pronchery void *params, int params_type, 127*b077aed3SPierre Pronchery i2d_of_void *k2d, struct key2any_ctx_st *ctx) 128*b077aed3SPierre Pronchery { 129*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO *p8info = 130*b077aed3SPierre Pronchery key_to_p8info(key, key_nid, params, params_type, k2d); 131*b077aed3SPierre Pronchery X509_SIG *p8 = NULL; 132*b077aed3SPierre Pronchery 133*b077aed3SPierre Pronchery if (p8info == NULL) { 134*b077aed3SPierre Pronchery free_asn1_data(params_type, params); 135*b077aed3SPierre Pronchery } else { 136*b077aed3SPierre Pronchery p8 = p8info_to_encp8(p8info, ctx); 137*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO_free(p8info); 138*b077aed3SPierre Pronchery } 139*b077aed3SPierre Pronchery return p8; 140*b077aed3SPierre Pronchery } 141*b077aed3SPierre Pronchery 142*b077aed3SPierre Pronchery static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, 143*b077aed3SPierre Pronchery void *params, int params_type, 144*b077aed3SPierre Pronchery i2d_of_void k2d) 145*b077aed3SPierre Pronchery { 146*b077aed3SPierre Pronchery /* der, derlen store the key DER output and its length */ 147*b077aed3SPierre Pronchery unsigned char *der = NULL; 148*b077aed3SPierre Pronchery int derlen; 149*b077aed3SPierre Pronchery /* The final X509_PUBKEY */ 150*b077aed3SPierre Pronchery X509_PUBKEY *xpk = NULL; 151*b077aed3SPierre Pronchery 152*b077aed3SPierre Pronchery 153*b077aed3SPierre Pronchery if ((xpk = X509_PUBKEY_new()) == NULL 154*b077aed3SPierre Pronchery || (derlen = k2d(key, &der)) <= 0 155*b077aed3SPierre Pronchery || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid), 156*b077aed3SPierre Pronchery params_type, params, der, derlen)) { 157*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 158*b077aed3SPierre Pronchery X509_PUBKEY_free(xpk); 159*b077aed3SPierre Pronchery OPENSSL_free(der); 160*b077aed3SPierre Pronchery xpk = NULL; 161*b077aed3SPierre Pronchery } 162*b077aed3SPierre Pronchery 163*b077aed3SPierre Pronchery return xpk; 164*b077aed3SPierre Pronchery } 165*b077aed3SPierre Pronchery 166*b077aed3SPierre Pronchery /* 167*b077aed3SPierre Pronchery * key_to_epki_* produce encoded output with the private key data in a 168*b077aed3SPierre Pronchery * EncryptedPrivateKeyInfo structure (defined by PKCS#8). They require 169*b077aed3SPierre Pronchery * that there's an intent to encrypt, anything else is an error. 170*b077aed3SPierre Pronchery * 171*b077aed3SPierre Pronchery * key_to_pki_* primarly produce encoded output with the private key data 172*b077aed3SPierre Pronchery * in a PrivateKeyInfo structure (also defined by PKCS#8). However, if 173*b077aed3SPierre Pronchery * there is an intent to encrypt the data, the corresponding key_to_epki_* 174*b077aed3SPierre Pronchery * function is used instead. 175*b077aed3SPierre Pronchery * 176*b077aed3SPierre Pronchery * key_to_spki_* produce encoded output with the public key data in an 177*b077aed3SPierre Pronchery * X.509 SubjectPublicKeyInfo. 178*b077aed3SPierre Pronchery * 179*b077aed3SPierre Pronchery * Key parameters don't have any defined envelopment of this kind, but are 180*b077aed3SPierre Pronchery * included in some manner in the output from the functions described above, 181*b077aed3SPierre Pronchery * either in the AlgorithmIdentifier's parameter field, or as part of the 182*b077aed3SPierre Pronchery * key data itself. 183*b077aed3SPierre Pronchery */ 184*b077aed3SPierre Pronchery 185*b077aed3SPierre Pronchery static int key_to_epki_der_priv_bio(BIO *out, const void *key, 186*b077aed3SPierre Pronchery int key_nid, 187*b077aed3SPierre Pronchery ossl_unused const char *pemname, 188*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 189*b077aed3SPierre Pronchery i2d_of_void *k2d, 190*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 191*b077aed3SPierre Pronchery { 192*b077aed3SPierre Pronchery int ret = 0; 193*b077aed3SPierre Pronchery void *str = NULL; 194*b077aed3SPierre Pronchery int strtype = V_ASN1_UNDEF; 195*b077aed3SPierre Pronchery X509_SIG *p8; 196*b077aed3SPierre Pronchery 197*b077aed3SPierre Pronchery if (!ctx->cipher_intent) 198*b077aed3SPierre Pronchery return 0; 199*b077aed3SPierre Pronchery 200*b077aed3SPierre Pronchery if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, 201*b077aed3SPierre Pronchery &str, &strtype)) 202*b077aed3SPierre Pronchery return 0; 203*b077aed3SPierre Pronchery 204*b077aed3SPierre Pronchery p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx); 205*b077aed3SPierre Pronchery if (p8 != NULL) 206*b077aed3SPierre Pronchery ret = i2d_PKCS8_bio(out, p8); 207*b077aed3SPierre Pronchery 208*b077aed3SPierre Pronchery X509_SIG_free(p8); 209*b077aed3SPierre Pronchery 210*b077aed3SPierre Pronchery return ret; 211*b077aed3SPierre Pronchery } 212*b077aed3SPierre Pronchery 213*b077aed3SPierre Pronchery static int key_to_epki_pem_priv_bio(BIO *out, const void *key, 214*b077aed3SPierre Pronchery int key_nid, 215*b077aed3SPierre Pronchery ossl_unused const char *pemname, 216*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 217*b077aed3SPierre Pronchery i2d_of_void *k2d, 218*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 219*b077aed3SPierre Pronchery { 220*b077aed3SPierre Pronchery int ret = 0; 221*b077aed3SPierre Pronchery void *str = NULL; 222*b077aed3SPierre Pronchery int strtype = V_ASN1_UNDEF; 223*b077aed3SPierre Pronchery X509_SIG *p8; 224*b077aed3SPierre Pronchery 225*b077aed3SPierre Pronchery if (!ctx->cipher_intent) 226*b077aed3SPierre Pronchery return 0; 227*b077aed3SPierre Pronchery 228*b077aed3SPierre Pronchery if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, 229*b077aed3SPierre Pronchery &str, &strtype)) 230*b077aed3SPierre Pronchery return 0; 231*b077aed3SPierre Pronchery 232*b077aed3SPierre Pronchery p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx); 233*b077aed3SPierre Pronchery if (p8 != NULL) 234*b077aed3SPierre Pronchery ret = PEM_write_bio_PKCS8(out, p8); 235*b077aed3SPierre Pronchery 236*b077aed3SPierre Pronchery X509_SIG_free(p8); 237*b077aed3SPierre Pronchery 238*b077aed3SPierre Pronchery return ret; 239*b077aed3SPierre Pronchery } 240*b077aed3SPierre Pronchery 241*b077aed3SPierre Pronchery static int key_to_pki_der_priv_bio(BIO *out, const void *key, 242*b077aed3SPierre Pronchery int key_nid, 243*b077aed3SPierre Pronchery ossl_unused const char *pemname, 244*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 245*b077aed3SPierre Pronchery i2d_of_void *k2d, 246*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 247*b077aed3SPierre Pronchery { 248*b077aed3SPierre Pronchery int ret = 0; 249*b077aed3SPierre Pronchery void *str = NULL; 250*b077aed3SPierre Pronchery int strtype = V_ASN1_UNDEF; 251*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO *p8info; 252*b077aed3SPierre Pronchery 253*b077aed3SPierre Pronchery if (ctx->cipher_intent) 254*b077aed3SPierre Pronchery return key_to_epki_der_priv_bio(out, key, key_nid, pemname, 255*b077aed3SPierre Pronchery p2s, k2d, ctx); 256*b077aed3SPierre Pronchery 257*b077aed3SPierre Pronchery if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, 258*b077aed3SPierre Pronchery &str, &strtype)) 259*b077aed3SPierre Pronchery return 0; 260*b077aed3SPierre Pronchery 261*b077aed3SPierre Pronchery p8info = key_to_p8info(key, key_nid, str, strtype, k2d); 262*b077aed3SPierre Pronchery 263*b077aed3SPierre Pronchery if (p8info != NULL) 264*b077aed3SPierre Pronchery ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info); 265*b077aed3SPierre Pronchery else 266*b077aed3SPierre Pronchery free_asn1_data(strtype, str); 267*b077aed3SPierre Pronchery 268*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO_free(p8info); 269*b077aed3SPierre Pronchery 270*b077aed3SPierre Pronchery return ret; 271*b077aed3SPierre Pronchery } 272*b077aed3SPierre Pronchery 273*b077aed3SPierre Pronchery static int key_to_pki_pem_priv_bio(BIO *out, const void *key, 274*b077aed3SPierre Pronchery int key_nid, 275*b077aed3SPierre Pronchery ossl_unused const char *pemname, 276*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 277*b077aed3SPierre Pronchery i2d_of_void *k2d, 278*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 279*b077aed3SPierre Pronchery { 280*b077aed3SPierre Pronchery int ret = 0; 281*b077aed3SPierre Pronchery void *str = NULL; 282*b077aed3SPierre Pronchery int strtype = V_ASN1_UNDEF; 283*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO *p8info; 284*b077aed3SPierre Pronchery 285*b077aed3SPierre Pronchery if (ctx->cipher_intent) 286*b077aed3SPierre Pronchery return key_to_epki_pem_priv_bio(out, key, key_nid, pemname, 287*b077aed3SPierre Pronchery p2s, k2d, ctx); 288*b077aed3SPierre Pronchery 289*b077aed3SPierre Pronchery if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, 290*b077aed3SPierre Pronchery &str, &strtype)) 291*b077aed3SPierre Pronchery return 0; 292*b077aed3SPierre Pronchery 293*b077aed3SPierre Pronchery p8info = key_to_p8info(key, key_nid, str, strtype, k2d); 294*b077aed3SPierre Pronchery 295*b077aed3SPierre Pronchery if (p8info != NULL) 296*b077aed3SPierre Pronchery ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); 297*b077aed3SPierre Pronchery else 298*b077aed3SPierre Pronchery free_asn1_data(strtype, str); 299*b077aed3SPierre Pronchery 300*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO_free(p8info); 301*b077aed3SPierre Pronchery 302*b077aed3SPierre Pronchery return ret; 303*b077aed3SPierre Pronchery } 304*b077aed3SPierre Pronchery 305*b077aed3SPierre Pronchery static int key_to_spki_der_pub_bio(BIO *out, const void *key, 306*b077aed3SPierre Pronchery int key_nid, 307*b077aed3SPierre Pronchery ossl_unused const char *pemname, 308*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 309*b077aed3SPierre Pronchery i2d_of_void *k2d, 310*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 311*b077aed3SPierre Pronchery { 312*b077aed3SPierre Pronchery int ret = 0; 313*b077aed3SPierre Pronchery void *str = NULL; 314*b077aed3SPierre Pronchery int strtype = V_ASN1_UNDEF; 315*b077aed3SPierre Pronchery X509_PUBKEY *xpk = NULL; 316*b077aed3SPierre Pronchery 317*b077aed3SPierre Pronchery if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, 318*b077aed3SPierre Pronchery &str, &strtype)) 319*b077aed3SPierre Pronchery return 0; 320*b077aed3SPierre Pronchery 321*b077aed3SPierre Pronchery xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); 322*b077aed3SPierre Pronchery 323*b077aed3SPierre Pronchery if (xpk != NULL) 324*b077aed3SPierre Pronchery ret = i2d_X509_PUBKEY_bio(out, xpk); 325*b077aed3SPierre Pronchery 326*b077aed3SPierre Pronchery /* Also frees |str| */ 327*b077aed3SPierre Pronchery X509_PUBKEY_free(xpk); 328*b077aed3SPierre Pronchery return ret; 329*b077aed3SPierre Pronchery } 330*b077aed3SPierre Pronchery 331*b077aed3SPierre Pronchery static int key_to_spki_pem_pub_bio(BIO *out, const void *key, 332*b077aed3SPierre Pronchery int key_nid, 333*b077aed3SPierre Pronchery ossl_unused const char *pemname, 334*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 335*b077aed3SPierre Pronchery i2d_of_void *k2d, 336*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 337*b077aed3SPierre Pronchery { 338*b077aed3SPierre Pronchery int ret = 0; 339*b077aed3SPierre Pronchery void *str = NULL; 340*b077aed3SPierre Pronchery int strtype = V_ASN1_UNDEF; 341*b077aed3SPierre Pronchery X509_PUBKEY *xpk = NULL; 342*b077aed3SPierre Pronchery 343*b077aed3SPierre Pronchery if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, 344*b077aed3SPierre Pronchery &str, &strtype)) 345*b077aed3SPierre Pronchery return 0; 346*b077aed3SPierre Pronchery 347*b077aed3SPierre Pronchery xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); 348*b077aed3SPierre Pronchery 349*b077aed3SPierre Pronchery if (xpk != NULL) 350*b077aed3SPierre Pronchery ret = PEM_write_bio_X509_PUBKEY(out, xpk); 351*b077aed3SPierre Pronchery else 352*b077aed3SPierre Pronchery free_asn1_data(strtype, str); 353*b077aed3SPierre Pronchery 354*b077aed3SPierre Pronchery /* Also frees |str| */ 355*b077aed3SPierre Pronchery X509_PUBKEY_free(xpk); 356*b077aed3SPierre Pronchery return ret; 357*b077aed3SPierre Pronchery } 358*b077aed3SPierre Pronchery 359*b077aed3SPierre Pronchery /* 360*b077aed3SPierre Pronchery * key_to_type_specific_* produce encoded output with type specific key data, 361*b077aed3SPierre Pronchery * no envelopment; the same kind of output as the type specific i2d_ and 362*b077aed3SPierre Pronchery * PEM_write_ functions, which is often a simple SEQUENCE of INTEGER. 363*b077aed3SPierre Pronchery * 364*b077aed3SPierre Pronchery * OpenSSL tries to discourage production of new keys in this form, because 365*b077aed3SPierre Pronchery * of the ambiguity when trying to recognise them, but can't deny that PKCS#1 366*b077aed3SPierre Pronchery * et al still are live standards. 367*b077aed3SPierre Pronchery * 368*b077aed3SPierre Pronchery * Note that these functions completely ignore p2s, and rather rely entirely 369*b077aed3SPierre Pronchery * on k2d to do the complete work. 370*b077aed3SPierre Pronchery */ 371*b077aed3SPierre Pronchery static int key_to_type_specific_der_bio(BIO *out, const void *key, 372*b077aed3SPierre Pronchery int key_nid, 373*b077aed3SPierre Pronchery ossl_unused const char *pemname, 374*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 375*b077aed3SPierre Pronchery i2d_of_void *k2d, 376*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 377*b077aed3SPierre Pronchery { 378*b077aed3SPierre Pronchery unsigned char *der = NULL; 379*b077aed3SPierre Pronchery int derlen; 380*b077aed3SPierre Pronchery int ret; 381*b077aed3SPierre Pronchery 382*b077aed3SPierre Pronchery if ((derlen = k2d(key, &der)) <= 0) { 383*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 384*b077aed3SPierre Pronchery return 0; 385*b077aed3SPierre Pronchery } 386*b077aed3SPierre Pronchery 387*b077aed3SPierre Pronchery ret = BIO_write(out, der, derlen); 388*b077aed3SPierre Pronchery OPENSSL_free(der); 389*b077aed3SPierre Pronchery return ret > 0; 390*b077aed3SPierre Pronchery } 391*b077aed3SPierre Pronchery #define key_to_type_specific_der_priv_bio key_to_type_specific_der_bio 392*b077aed3SPierre Pronchery #define key_to_type_specific_der_pub_bio key_to_type_specific_der_bio 393*b077aed3SPierre Pronchery #define key_to_type_specific_der_param_bio key_to_type_specific_der_bio 394*b077aed3SPierre Pronchery 395*b077aed3SPierre Pronchery static int key_to_type_specific_pem_bio_cb(BIO *out, const void *key, 396*b077aed3SPierre Pronchery int key_nid, const char *pemname, 397*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 398*b077aed3SPierre Pronchery i2d_of_void *k2d, 399*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx, 400*b077aed3SPierre Pronchery pem_password_cb *cb, void *cbarg) 401*b077aed3SPierre Pronchery { 402*b077aed3SPierre Pronchery return 403*b077aed3SPierre Pronchery PEM_ASN1_write_bio(k2d, pemname, out, key, ctx->cipher, 404*b077aed3SPierre Pronchery NULL, 0, cb, cbarg) > 0; 405*b077aed3SPierre Pronchery } 406*b077aed3SPierre Pronchery 407*b077aed3SPierre Pronchery static int key_to_type_specific_pem_priv_bio(BIO *out, const void *key, 408*b077aed3SPierre Pronchery int key_nid, const char *pemname, 409*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 410*b077aed3SPierre Pronchery i2d_of_void *k2d, 411*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 412*b077aed3SPierre Pronchery { 413*b077aed3SPierre Pronchery return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, 414*b077aed3SPierre Pronchery p2s, k2d, ctx, 415*b077aed3SPierre Pronchery ossl_pw_pem_password, &ctx->pwdata); 416*b077aed3SPierre Pronchery } 417*b077aed3SPierre Pronchery 418*b077aed3SPierre Pronchery static int key_to_type_specific_pem_pub_bio(BIO *out, const void *key, 419*b077aed3SPierre Pronchery int key_nid, const char *pemname, 420*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 421*b077aed3SPierre Pronchery i2d_of_void *k2d, 422*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 423*b077aed3SPierre Pronchery { 424*b077aed3SPierre Pronchery return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, 425*b077aed3SPierre Pronchery p2s, k2d, ctx, NULL, NULL); 426*b077aed3SPierre Pronchery } 427*b077aed3SPierre Pronchery 428*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_KEYPARAMS 429*b077aed3SPierre Pronchery static int key_to_type_specific_pem_param_bio(BIO *out, const void *key, 430*b077aed3SPierre Pronchery int key_nid, const char *pemname, 431*b077aed3SPierre Pronchery key_to_paramstring_fn *p2s, 432*b077aed3SPierre Pronchery i2d_of_void *k2d, 433*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx) 434*b077aed3SPierre Pronchery { 435*b077aed3SPierre Pronchery return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, 436*b077aed3SPierre Pronchery p2s, k2d, ctx, NULL, NULL); 437*b077aed3SPierre Pronchery } 438*b077aed3SPierre Pronchery #endif 439*b077aed3SPierre Pronchery 440*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 441*b077aed3SPierre Pronchery 442*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 443*b077aed3SPierre Pronchery static int prepare_dh_params(const void *dh, int nid, int save, 444*b077aed3SPierre Pronchery void **pstr, int *pstrtype) 445*b077aed3SPierre Pronchery { 446*b077aed3SPierre Pronchery ASN1_STRING *params = ASN1_STRING_new(); 447*b077aed3SPierre Pronchery 448*b077aed3SPierre Pronchery if (params == NULL) { 449*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 450*b077aed3SPierre Pronchery return 0; 451*b077aed3SPierre Pronchery } 452*b077aed3SPierre Pronchery 453*b077aed3SPierre Pronchery if (nid == EVP_PKEY_DHX) 454*b077aed3SPierre Pronchery params->length = i2d_DHxparams(dh, ¶ms->data); 455*b077aed3SPierre Pronchery else 456*b077aed3SPierre Pronchery params->length = i2d_DHparams(dh, ¶ms->data); 457*b077aed3SPierre Pronchery 458*b077aed3SPierre Pronchery if (params->length <= 0) { 459*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 460*b077aed3SPierre Pronchery ASN1_STRING_free(params); 461*b077aed3SPierre Pronchery return 0; 462*b077aed3SPierre Pronchery } 463*b077aed3SPierre Pronchery params->type = V_ASN1_SEQUENCE; 464*b077aed3SPierre Pronchery 465*b077aed3SPierre Pronchery *pstr = params; 466*b077aed3SPierre Pronchery *pstrtype = V_ASN1_SEQUENCE; 467*b077aed3SPierre Pronchery return 1; 468*b077aed3SPierre Pronchery } 469*b077aed3SPierre Pronchery 470*b077aed3SPierre Pronchery static int dh_spki_pub_to_der(const void *dh, unsigned char **pder) 471*b077aed3SPierre Pronchery { 472*b077aed3SPierre Pronchery const BIGNUM *bn = NULL; 473*b077aed3SPierre Pronchery ASN1_INTEGER *pub_key = NULL; 474*b077aed3SPierre Pronchery int ret; 475*b077aed3SPierre Pronchery 476*b077aed3SPierre Pronchery if ((bn = DH_get0_pub_key(dh)) == NULL) { 477*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 478*b077aed3SPierre Pronchery return 0; 479*b077aed3SPierre Pronchery } 480*b077aed3SPierre Pronchery if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { 481*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); 482*b077aed3SPierre Pronchery return 0; 483*b077aed3SPierre Pronchery } 484*b077aed3SPierre Pronchery 485*b077aed3SPierre Pronchery ret = i2d_ASN1_INTEGER(pub_key, pder); 486*b077aed3SPierre Pronchery 487*b077aed3SPierre Pronchery ASN1_STRING_clear_free(pub_key); 488*b077aed3SPierre Pronchery return ret; 489*b077aed3SPierre Pronchery } 490*b077aed3SPierre Pronchery 491*b077aed3SPierre Pronchery static int dh_pki_priv_to_der(const void *dh, unsigned char **pder) 492*b077aed3SPierre Pronchery { 493*b077aed3SPierre Pronchery const BIGNUM *bn = NULL; 494*b077aed3SPierre Pronchery ASN1_INTEGER *priv_key = NULL; 495*b077aed3SPierre Pronchery int ret; 496*b077aed3SPierre Pronchery 497*b077aed3SPierre Pronchery if ((bn = DH_get0_priv_key(dh)) == NULL) { 498*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 499*b077aed3SPierre Pronchery return 0; 500*b077aed3SPierre Pronchery } 501*b077aed3SPierre Pronchery if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { 502*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); 503*b077aed3SPierre Pronchery return 0; 504*b077aed3SPierre Pronchery } 505*b077aed3SPierre Pronchery 506*b077aed3SPierre Pronchery ret = i2d_ASN1_INTEGER(priv_key, pder); 507*b077aed3SPierre Pronchery 508*b077aed3SPierre Pronchery ASN1_STRING_clear_free(priv_key); 509*b077aed3SPierre Pronchery return ret; 510*b077aed3SPierre Pronchery } 511*b077aed3SPierre Pronchery 512*b077aed3SPierre Pronchery # define dh_epki_priv_to_der dh_pki_priv_to_der 513*b077aed3SPierre Pronchery 514*b077aed3SPierre Pronchery static int dh_type_specific_params_to_der(const void *dh, unsigned char **pder) 515*b077aed3SPierre Pronchery { 516*b077aed3SPierre Pronchery if (DH_test_flags(dh, DH_FLAG_TYPE_DHX)) 517*b077aed3SPierre Pronchery return i2d_DHxparams(dh, pder); 518*b077aed3SPierre Pronchery return i2d_DHparams(dh, pder); 519*b077aed3SPierre Pronchery } 520*b077aed3SPierre Pronchery 521*b077aed3SPierre Pronchery /* 522*b077aed3SPierre Pronchery * DH doesn't have i2d_DHPrivateKey or i2d_DHPublicKey, so we can't make 523*b077aed3SPierre Pronchery * corresponding functions here. 524*b077aed3SPierre Pronchery */ 525*b077aed3SPierre Pronchery # define dh_type_specific_priv_to_der NULL 526*b077aed3SPierre Pronchery # define dh_type_specific_pub_to_der NULL 527*b077aed3SPierre Pronchery 528*b077aed3SPierre Pronchery static int dh_check_key_type(const void *dh, int expected_type) 529*b077aed3SPierre Pronchery { 530*b077aed3SPierre Pronchery int type = 531*b077aed3SPierre Pronchery DH_test_flags(dh, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH; 532*b077aed3SPierre Pronchery 533*b077aed3SPierre Pronchery return type == expected_type; 534*b077aed3SPierre Pronchery } 535*b077aed3SPierre Pronchery 536*b077aed3SPierre Pronchery # define dh_evp_type EVP_PKEY_DH 537*b077aed3SPierre Pronchery # define dhx_evp_type EVP_PKEY_DHX 538*b077aed3SPierre Pronchery # define dh_input_type "DH" 539*b077aed3SPierre Pronchery # define dhx_input_type "DHX" 540*b077aed3SPierre Pronchery # define dh_pem_type "DH" 541*b077aed3SPierre Pronchery # define dhx_pem_type "X9.42 DH" 542*b077aed3SPierre Pronchery #endif 543*b077aed3SPierre Pronchery 544*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 545*b077aed3SPierre Pronchery 546*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DSA 547*b077aed3SPierre Pronchery static int encode_dsa_params(const void *dsa, int nid, 548*b077aed3SPierre Pronchery void **pstr, int *pstrtype) 549*b077aed3SPierre Pronchery { 550*b077aed3SPierre Pronchery ASN1_STRING *params = ASN1_STRING_new(); 551*b077aed3SPierre Pronchery 552*b077aed3SPierre Pronchery if (params == NULL) { 553*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 554*b077aed3SPierre Pronchery return 0; 555*b077aed3SPierre Pronchery } 556*b077aed3SPierre Pronchery 557*b077aed3SPierre Pronchery params->length = i2d_DSAparams(dsa, ¶ms->data); 558*b077aed3SPierre Pronchery 559*b077aed3SPierre Pronchery if (params->length <= 0) { 560*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 561*b077aed3SPierre Pronchery ASN1_STRING_free(params); 562*b077aed3SPierre Pronchery return 0; 563*b077aed3SPierre Pronchery } 564*b077aed3SPierre Pronchery 565*b077aed3SPierre Pronchery *pstrtype = V_ASN1_SEQUENCE; 566*b077aed3SPierre Pronchery *pstr = params; 567*b077aed3SPierre Pronchery return 1; 568*b077aed3SPierre Pronchery } 569*b077aed3SPierre Pronchery 570*b077aed3SPierre Pronchery static int prepare_dsa_params(const void *dsa, int nid, int save, 571*b077aed3SPierre Pronchery void **pstr, int *pstrtype) 572*b077aed3SPierre Pronchery { 573*b077aed3SPierre Pronchery const BIGNUM *p = DSA_get0_p(dsa); 574*b077aed3SPierre Pronchery const BIGNUM *q = DSA_get0_q(dsa); 575*b077aed3SPierre Pronchery const BIGNUM *g = DSA_get0_g(dsa); 576*b077aed3SPierre Pronchery 577*b077aed3SPierre Pronchery if (save && p != NULL && q != NULL && g != NULL) 578*b077aed3SPierre Pronchery return encode_dsa_params(dsa, nid, pstr, pstrtype); 579*b077aed3SPierre Pronchery 580*b077aed3SPierre Pronchery *pstr = NULL; 581*b077aed3SPierre Pronchery *pstrtype = V_ASN1_UNDEF; 582*b077aed3SPierre Pronchery return 1; 583*b077aed3SPierre Pronchery } 584*b077aed3SPierre Pronchery 585*b077aed3SPierre Pronchery static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder) 586*b077aed3SPierre Pronchery { 587*b077aed3SPierre Pronchery const BIGNUM *bn = NULL; 588*b077aed3SPierre Pronchery ASN1_INTEGER *pub_key = NULL; 589*b077aed3SPierre Pronchery int ret; 590*b077aed3SPierre Pronchery 591*b077aed3SPierre Pronchery if ((bn = DSA_get0_pub_key(dsa)) == NULL) { 592*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 593*b077aed3SPierre Pronchery return 0; 594*b077aed3SPierre Pronchery } 595*b077aed3SPierre Pronchery if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { 596*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); 597*b077aed3SPierre Pronchery return 0; 598*b077aed3SPierre Pronchery } 599*b077aed3SPierre Pronchery 600*b077aed3SPierre Pronchery ret = i2d_ASN1_INTEGER(pub_key, pder); 601*b077aed3SPierre Pronchery 602*b077aed3SPierre Pronchery ASN1_STRING_clear_free(pub_key); 603*b077aed3SPierre Pronchery return ret; 604*b077aed3SPierre Pronchery } 605*b077aed3SPierre Pronchery 606*b077aed3SPierre Pronchery static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder) 607*b077aed3SPierre Pronchery { 608*b077aed3SPierre Pronchery const BIGNUM *bn = NULL; 609*b077aed3SPierre Pronchery ASN1_INTEGER *priv_key = NULL; 610*b077aed3SPierre Pronchery int ret; 611*b077aed3SPierre Pronchery 612*b077aed3SPierre Pronchery if ((bn = DSA_get0_priv_key(dsa)) == NULL) { 613*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 614*b077aed3SPierre Pronchery return 0; 615*b077aed3SPierre Pronchery } 616*b077aed3SPierre Pronchery if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { 617*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); 618*b077aed3SPierre Pronchery return 0; 619*b077aed3SPierre Pronchery } 620*b077aed3SPierre Pronchery 621*b077aed3SPierre Pronchery ret = i2d_ASN1_INTEGER(priv_key, pder); 622*b077aed3SPierre Pronchery 623*b077aed3SPierre Pronchery ASN1_STRING_clear_free(priv_key); 624*b077aed3SPierre Pronchery return ret; 625*b077aed3SPierre Pronchery } 626*b077aed3SPierre Pronchery 627*b077aed3SPierre Pronchery # define dsa_epki_priv_to_der dsa_pki_priv_to_der 628*b077aed3SPierre Pronchery 629*b077aed3SPierre Pronchery # define dsa_type_specific_priv_to_der (i2d_of_void *)i2d_DSAPrivateKey 630*b077aed3SPierre Pronchery # define dsa_type_specific_pub_to_der (i2d_of_void *)i2d_DSAPublicKey 631*b077aed3SPierre Pronchery # define dsa_type_specific_params_to_der (i2d_of_void *)i2d_DSAparams 632*b077aed3SPierre Pronchery 633*b077aed3SPierre Pronchery # define dsa_check_key_type NULL 634*b077aed3SPierre Pronchery # define dsa_evp_type EVP_PKEY_DSA 635*b077aed3SPierre Pronchery # define dsa_input_type "DSA" 636*b077aed3SPierre Pronchery # define dsa_pem_type "DSA" 637*b077aed3SPierre Pronchery #endif 638*b077aed3SPierre Pronchery 639*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 640*b077aed3SPierre Pronchery 641*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 642*b077aed3SPierre Pronchery static int prepare_ec_explicit_params(const void *eckey, 643*b077aed3SPierre Pronchery void **pstr, int *pstrtype) 644*b077aed3SPierre Pronchery { 645*b077aed3SPierre Pronchery ASN1_STRING *params = ASN1_STRING_new(); 646*b077aed3SPierre Pronchery 647*b077aed3SPierre Pronchery if (params == NULL) { 648*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 649*b077aed3SPierre Pronchery return 0; 650*b077aed3SPierre Pronchery } 651*b077aed3SPierre Pronchery 652*b077aed3SPierre Pronchery params->length = i2d_ECParameters(eckey, ¶ms->data); 653*b077aed3SPierre Pronchery if (params->length <= 0) { 654*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 655*b077aed3SPierre Pronchery ASN1_STRING_free(params); 656*b077aed3SPierre Pronchery return 0; 657*b077aed3SPierre Pronchery } 658*b077aed3SPierre Pronchery 659*b077aed3SPierre Pronchery *pstrtype = V_ASN1_SEQUENCE; 660*b077aed3SPierre Pronchery *pstr = params; 661*b077aed3SPierre Pronchery return 1; 662*b077aed3SPierre Pronchery } 663*b077aed3SPierre Pronchery 664*b077aed3SPierre Pronchery /* 665*b077aed3SPierre Pronchery * This implements EcpkParameters, where the CHOICE is based on whether there 666*b077aed3SPierre Pronchery * is a curve name (curve nid) to be found or not. See RFC 3279 for details. 667*b077aed3SPierre Pronchery */ 668*b077aed3SPierre Pronchery static int prepare_ec_params(const void *eckey, int nid, int save, 669*b077aed3SPierre Pronchery void **pstr, int *pstrtype) 670*b077aed3SPierre Pronchery { 671*b077aed3SPierre Pronchery int curve_nid; 672*b077aed3SPierre Pronchery const EC_GROUP *group = EC_KEY_get0_group(eckey); 673*b077aed3SPierre Pronchery ASN1_OBJECT *params = NULL; 674*b077aed3SPierre Pronchery 675*b077aed3SPierre Pronchery if (group == NULL) 676*b077aed3SPierre Pronchery return 0; 677*b077aed3SPierre Pronchery curve_nid = EC_GROUP_get_curve_name(group); 678*b077aed3SPierre Pronchery if (curve_nid != NID_undef) { 679*b077aed3SPierre Pronchery params = OBJ_nid2obj(curve_nid); 680*b077aed3SPierre Pronchery if (params == NULL) 681*b077aed3SPierre Pronchery return 0; 682*b077aed3SPierre Pronchery } 683*b077aed3SPierre Pronchery 684*b077aed3SPierre Pronchery if (curve_nid != NID_undef 685*b077aed3SPierre Pronchery && (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE)) { 686*b077aed3SPierre Pronchery /* The CHOICE came to namedCurve */ 687*b077aed3SPierre Pronchery if (OBJ_length(params) == 0) { 688*b077aed3SPierre Pronchery /* Some curves might not have an associated OID */ 689*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID); 690*b077aed3SPierre Pronchery ASN1_OBJECT_free(params); 691*b077aed3SPierre Pronchery return 0; 692*b077aed3SPierre Pronchery } 693*b077aed3SPierre Pronchery *pstr = params; 694*b077aed3SPierre Pronchery *pstrtype = V_ASN1_OBJECT; 695*b077aed3SPierre Pronchery return 1; 696*b077aed3SPierre Pronchery } else { 697*b077aed3SPierre Pronchery /* The CHOICE came to ecParameters */ 698*b077aed3SPierre Pronchery return prepare_ec_explicit_params(eckey, pstr, pstrtype); 699*b077aed3SPierre Pronchery } 700*b077aed3SPierre Pronchery } 701*b077aed3SPierre Pronchery 702*b077aed3SPierre Pronchery static int ec_spki_pub_to_der(const void *eckey, unsigned char **pder) 703*b077aed3SPierre Pronchery { 704*b077aed3SPierre Pronchery if (EC_KEY_get0_public_key(eckey) == NULL) { 705*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 706*b077aed3SPierre Pronchery return 0; 707*b077aed3SPierre Pronchery } 708*b077aed3SPierre Pronchery return i2o_ECPublicKey(eckey, pder); 709*b077aed3SPierre Pronchery } 710*b077aed3SPierre Pronchery 711*b077aed3SPierre Pronchery static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder) 712*b077aed3SPierre Pronchery { 713*b077aed3SPierre Pronchery EC_KEY *eckey = (EC_KEY *)veckey; 714*b077aed3SPierre Pronchery unsigned int old_flags; 715*b077aed3SPierre Pronchery int ret = 0; 716*b077aed3SPierre Pronchery 717*b077aed3SPierre Pronchery /* 718*b077aed3SPierre Pronchery * For PKCS8 the curve name appears in the PKCS8_PRIV_KEY_INFO object 719*b077aed3SPierre Pronchery * as the pkeyalg->parameter field. (For a named curve this is an OID) 720*b077aed3SPierre Pronchery * The pkey field is an octet string that holds the encoded 721*b077aed3SPierre Pronchery * ECPrivateKey SEQUENCE with the optional parameters field omitted. 722*b077aed3SPierre Pronchery * We omit this by setting the EC_PKEY_NO_PARAMETERS flag. 723*b077aed3SPierre Pronchery */ 724*b077aed3SPierre Pronchery old_flags = EC_KEY_get_enc_flags(eckey); /* save old flags */ 725*b077aed3SPierre Pronchery EC_KEY_set_enc_flags(eckey, old_flags | EC_PKEY_NO_PARAMETERS); 726*b077aed3SPierre Pronchery ret = i2d_ECPrivateKey(eckey, pder); 727*b077aed3SPierre Pronchery EC_KEY_set_enc_flags(eckey, old_flags); /* restore old flags */ 728*b077aed3SPierre Pronchery return ret; /* return the length of the der encoded data */ 729*b077aed3SPierre Pronchery } 730*b077aed3SPierre Pronchery 731*b077aed3SPierre Pronchery # define ec_epki_priv_to_der ec_pki_priv_to_der 732*b077aed3SPierre Pronchery 733*b077aed3SPierre Pronchery # define ec_type_specific_params_to_der (i2d_of_void *)i2d_ECParameters 734*b077aed3SPierre Pronchery /* No ec_type_specific_pub_to_der, there simply is no such thing */ 735*b077aed3SPierre Pronchery # define ec_type_specific_priv_to_der (i2d_of_void *)i2d_ECPrivateKey 736*b077aed3SPierre Pronchery 737*b077aed3SPierre Pronchery # define ec_check_key_type NULL 738*b077aed3SPierre Pronchery # define ec_evp_type EVP_PKEY_EC 739*b077aed3SPierre Pronchery # define ec_input_type "EC" 740*b077aed3SPierre Pronchery # define ec_pem_type "EC" 741*b077aed3SPierre Pronchery 742*b077aed3SPierre Pronchery # ifndef OPENSSL_NO_SM2 743*b077aed3SPierre Pronchery # define sm2_evp_type EVP_PKEY_SM2 744*b077aed3SPierre Pronchery # define sm2_input_type "SM2" 745*b077aed3SPierre Pronchery # define sm2_pem_type "SM2" 746*b077aed3SPierre Pronchery # endif 747*b077aed3SPierre Pronchery #endif 748*b077aed3SPierre Pronchery 749*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 750*b077aed3SPierre Pronchery 751*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 752*b077aed3SPierre Pronchery # define prepare_ecx_params NULL 753*b077aed3SPierre Pronchery 754*b077aed3SPierre Pronchery static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder) 755*b077aed3SPierre Pronchery { 756*b077aed3SPierre Pronchery const ECX_KEY *ecxkey = vecxkey; 757*b077aed3SPierre Pronchery unsigned char *keyblob; 758*b077aed3SPierre Pronchery 759*b077aed3SPierre Pronchery if (ecxkey == NULL) { 760*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 761*b077aed3SPierre Pronchery return 0; 762*b077aed3SPierre Pronchery } 763*b077aed3SPierre Pronchery 764*b077aed3SPierre Pronchery keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen); 765*b077aed3SPierre Pronchery if (keyblob == NULL) { 766*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 767*b077aed3SPierre Pronchery return 0; 768*b077aed3SPierre Pronchery } 769*b077aed3SPierre Pronchery 770*b077aed3SPierre Pronchery *pder = keyblob; 771*b077aed3SPierre Pronchery return ecxkey->keylen; 772*b077aed3SPierre Pronchery } 773*b077aed3SPierre Pronchery 774*b077aed3SPierre Pronchery static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder) 775*b077aed3SPierre Pronchery { 776*b077aed3SPierre Pronchery const ECX_KEY *ecxkey = vecxkey; 777*b077aed3SPierre Pronchery ASN1_OCTET_STRING oct; 778*b077aed3SPierre Pronchery int keybloblen; 779*b077aed3SPierre Pronchery 780*b077aed3SPierre Pronchery if (ecxkey == NULL || ecxkey->privkey == NULL) { 781*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 782*b077aed3SPierre Pronchery return 0; 783*b077aed3SPierre Pronchery } 784*b077aed3SPierre Pronchery 785*b077aed3SPierre Pronchery oct.data = ecxkey->privkey; 786*b077aed3SPierre Pronchery oct.length = ecxkey->keylen; 787*b077aed3SPierre Pronchery oct.flags = 0; 788*b077aed3SPierre Pronchery 789*b077aed3SPierre Pronchery keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder); 790*b077aed3SPierre Pronchery if (keybloblen < 0) { 791*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 792*b077aed3SPierre Pronchery return 0; 793*b077aed3SPierre Pronchery } 794*b077aed3SPierre Pronchery 795*b077aed3SPierre Pronchery return keybloblen; 796*b077aed3SPierre Pronchery } 797*b077aed3SPierre Pronchery 798*b077aed3SPierre Pronchery # define ecx_epki_priv_to_der ecx_pki_priv_to_der 799*b077aed3SPierre Pronchery 800*b077aed3SPierre Pronchery /* 801*b077aed3SPierre Pronchery * ED25519, ED448, X25519 and X448 only has PKCS#8 / SubjectPublicKeyInfo 802*b077aed3SPierre Pronchery * representation, so we don't define ecx_type_specific_[priv,pub,params]_to_der. 803*b077aed3SPierre Pronchery */ 804*b077aed3SPierre Pronchery 805*b077aed3SPierre Pronchery # define ecx_check_key_type NULL 806*b077aed3SPierre Pronchery 807*b077aed3SPierre Pronchery # define ed25519_evp_type EVP_PKEY_ED25519 808*b077aed3SPierre Pronchery # define ed448_evp_type EVP_PKEY_ED448 809*b077aed3SPierre Pronchery # define x25519_evp_type EVP_PKEY_X25519 810*b077aed3SPierre Pronchery # define x448_evp_type EVP_PKEY_X448 811*b077aed3SPierre Pronchery # define ed25519_input_type "ED25519" 812*b077aed3SPierre Pronchery # define ed448_input_type "ED448" 813*b077aed3SPierre Pronchery # define x25519_input_type "X25519" 814*b077aed3SPierre Pronchery # define x448_input_type "X448" 815*b077aed3SPierre Pronchery # define ed25519_pem_type "ED25519" 816*b077aed3SPierre Pronchery # define ed448_pem_type "ED448" 817*b077aed3SPierre Pronchery # define x25519_pem_type "X25519" 818*b077aed3SPierre Pronchery # define x448_pem_type "X448" 819*b077aed3SPierre Pronchery #endif 820*b077aed3SPierre Pronchery 821*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 822*b077aed3SPierre Pronchery 823*b077aed3SPierre Pronchery /* 824*b077aed3SPierre Pronchery * Helper functions to prepare RSA-PSS params for encoding. We would 825*b077aed3SPierre Pronchery * have simply written the whole AlgorithmIdentifier, but existing libcrypto 826*b077aed3SPierre Pronchery * functionality doesn't allow that. 827*b077aed3SPierre Pronchery */ 828*b077aed3SPierre Pronchery 829*b077aed3SPierre Pronchery static int prepare_rsa_params(const void *rsa, int nid, int save, 830*b077aed3SPierre Pronchery void **pstr, int *pstrtype) 831*b077aed3SPierre Pronchery { 832*b077aed3SPierre Pronchery const RSA_PSS_PARAMS_30 *pss = ossl_rsa_get0_pss_params_30((RSA *)rsa); 833*b077aed3SPierre Pronchery 834*b077aed3SPierre Pronchery *pstr = NULL; 835*b077aed3SPierre Pronchery 836*b077aed3SPierre Pronchery switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { 837*b077aed3SPierre Pronchery case RSA_FLAG_TYPE_RSA: 838*b077aed3SPierre Pronchery /* If plain RSA, the parameters shall be NULL */ 839*b077aed3SPierre Pronchery *pstrtype = V_ASN1_NULL; 840*b077aed3SPierre Pronchery return 1; 841*b077aed3SPierre Pronchery case RSA_FLAG_TYPE_RSASSAPSS: 842*b077aed3SPierre Pronchery if (ossl_rsa_pss_params_30_is_unrestricted(pss)) { 843*b077aed3SPierre Pronchery *pstrtype = V_ASN1_UNDEF; 844*b077aed3SPierre Pronchery return 1; 845*b077aed3SPierre Pronchery } else { 846*b077aed3SPierre Pronchery ASN1_STRING *astr = NULL; 847*b077aed3SPierre Pronchery WPACKET pkt; 848*b077aed3SPierre Pronchery unsigned char *str = NULL; 849*b077aed3SPierre Pronchery size_t str_sz = 0; 850*b077aed3SPierre Pronchery int i; 851*b077aed3SPierre Pronchery 852*b077aed3SPierre Pronchery for (i = 0; i < 2; i++) { 853*b077aed3SPierre Pronchery switch (i) { 854*b077aed3SPierre Pronchery case 0: 855*b077aed3SPierre Pronchery if (!WPACKET_init_null_der(&pkt)) 856*b077aed3SPierre Pronchery goto err; 857*b077aed3SPierre Pronchery break; 858*b077aed3SPierre Pronchery case 1: 859*b077aed3SPierre Pronchery if ((str = OPENSSL_malloc(str_sz)) == NULL 860*b077aed3SPierre Pronchery || !WPACKET_init_der(&pkt, str, str_sz)) { 861*b077aed3SPierre Pronchery goto err; 862*b077aed3SPierre Pronchery } 863*b077aed3SPierre Pronchery break; 864*b077aed3SPierre Pronchery } 865*b077aed3SPierre Pronchery if (!ossl_DER_w_RSASSA_PSS_params(&pkt, -1, pss) 866*b077aed3SPierre Pronchery || !WPACKET_finish(&pkt) 867*b077aed3SPierre Pronchery || !WPACKET_get_total_written(&pkt, &str_sz)) 868*b077aed3SPierre Pronchery goto err; 869*b077aed3SPierre Pronchery WPACKET_cleanup(&pkt); 870*b077aed3SPierre Pronchery 871*b077aed3SPierre Pronchery /* 872*b077aed3SPierre Pronchery * If no PSS parameters are going to be written, there's no 873*b077aed3SPierre Pronchery * point going for another iteration. 874*b077aed3SPierre Pronchery * This saves us from getting |str| allocated just to have it 875*b077aed3SPierre Pronchery * immediately de-allocated. 876*b077aed3SPierre Pronchery */ 877*b077aed3SPierre Pronchery if (str_sz == 0) 878*b077aed3SPierre Pronchery break; 879*b077aed3SPierre Pronchery } 880*b077aed3SPierre Pronchery 881*b077aed3SPierre Pronchery if ((astr = ASN1_STRING_new()) == NULL) 882*b077aed3SPierre Pronchery goto err; 883*b077aed3SPierre Pronchery *pstrtype = V_ASN1_SEQUENCE; 884*b077aed3SPierre Pronchery ASN1_STRING_set0(astr, str, (int)str_sz); 885*b077aed3SPierre Pronchery *pstr = astr; 886*b077aed3SPierre Pronchery 887*b077aed3SPierre Pronchery return 1; 888*b077aed3SPierre Pronchery err: 889*b077aed3SPierre Pronchery OPENSSL_free(str); 890*b077aed3SPierre Pronchery return 0; 891*b077aed3SPierre Pronchery } 892*b077aed3SPierre Pronchery } 893*b077aed3SPierre Pronchery 894*b077aed3SPierre Pronchery /* Currently unsupported RSA key type */ 895*b077aed3SPierre Pronchery return 0; 896*b077aed3SPierre Pronchery } 897*b077aed3SPierre Pronchery 898*b077aed3SPierre Pronchery /* 899*b077aed3SPierre Pronchery * RSA is extremely simple, as PKCS#1 is used for the PKCS#8 |privateKey| 900*b077aed3SPierre Pronchery * field as well as the SubjectPublicKeyInfo |subjectPublicKey| field. 901*b077aed3SPierre Pronchery */ 902*b077aed3SPierre Pronchery #define rsa_pki_priv_to_der rsa_type_specific_priv_to_der 903*b077aed3SPierre Pronchery #define rsa_epki_priv_to_der rsa_type_specific_priv_to_der 904*b077aed3SPierre Pronchery #define rsa_spki_pub_to_der rsa_type_specific_pub_to_der 905*b077aed3SPierre Pronchery #define rsa_type_specific_priv_to_der (i2d_of_void *)i2d_RSAPrivateKey 906*b077aed3SPierre Pronchery #define rsa_type_specific_pub_to_der (i2d_of_void *)i2d_RSAPublicKey 907*b077aed3SPierre Pronchery #define rsa_type_specific_params_to_der NULL 908*b077aed3SPierre Pronchery 909*b077aed3SPierre Pronchery static int rsa_check_key_type(const void *rsa, int expected_type) 910*b077aed3SPierre Pronchery { 911*b077aed3SPierre Pronchery switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { 912*b077aed3SPierre Pronchery case RSA_FLAG_TYPE_RSA: 913*b077aed3SPierre Pronchery return expected_type == EVP_PKEY_RSA; 914*b077aed3SPierre Pronchery case RSA_FLAG_TYPE_RSASSAPSS: 915*b077aed3SPierre Pronchery return expected_type == EVP_PKEY_RSA_PSS; 916*b077aed3SPierre Pronchery } 917*b077aed3SPierre Pronchery 918*b077aed3SPierre Pronchery /* Currently unsupported RSA key type */ 919*b077aed3SPierre Pronchery return EVP_PKEY_NONE; 920*b077aed3SPierre Pronchery } 921*b077aed3SPierre Pronchery 922*b077aed3SPierre Pronchery #define rsa_evp_type EVP_PKEY_RSA 923*b077aed3SPierre Pronchery #define rsapss_evp_type EVP_PKEY_RSA_PSS 924*b077aed3SPierre Pronchery #define rsa_input_type "RSA" 925*b077aed3SPierre Pronchery #define rsapss_input_type "RSA-PSS" 926*b077aed3SPierre Pronchery #define rsa_pem_type "RSA" 927*b077aed3SPierre Pronchery #define rsapss_pem_type "RSA-PSS" 928*b077aed3SPierre Pronchery 929*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 930*b077aed3SPierre Pronchery 931*b077aed3SPierre Pronchery static OSSL_FUNC_decoder_newctx_fn key2any_newctx; 932*b077aed3SPierre Pronchery static OSSL_FUNC_decoder_freectx_fn key2any_freectx; 933*b077aed3SPierre Pronchery 934*b077aed3SPierre Pronchery static void *key2any_newctx(void *provctx) 935*b077aed3SPierre Pronchery { 936*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); 937*b077aed3SPierre Pronchery 938*b077aed3SPierre Pronchery if (ctx != NULL) { 939*b077aed3SPierre Pronchery ctx->provctx = provctx; 940*b077aed3SPierre Pronchery ctx->save_parameters = 1; 941*b077aed3SPierre Pronchery } 942*b077aed3SPierre Pronchery 943*b077aed3SPierre Pronchery return ctx; 944*b077aed3SPierre Pronchery } 945*b077aed3SPierre Pronchery 946*b077aed3SPierre Pronchery static void key2any_freectx(void *vctx) 947*b077aed3SPierre Pronchery { 948*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx = vctx; 949*b077aed3SPierre Pronchery 950*b077aed3SPierre Pronchery ossl_pw_clear_passphrase_data(&ctx->pwdata); 951*b077aed3SPierre Pronchery EVP_CIPHER_free(ctx->cipher); 952*b077aed3SPierre Pronchery OPENSSL_free(ctx); 953*b077aed3SPierre Pronchery } 954*b077aed3SPierre Pronchery 955*b077aed3SPierre Pronchery static const OSSL_PARAM *key2any_settable_ctx_params(ossl_unused void *provctx) 956*b077aed3SPierre Pronchery { 957*b077aed3SPierre Pronchery static const OSSL_PARAM settables[] = { 958*b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0), 959*b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, NULL, 0), 960*b077aed3SPierre Pronchery OSSL_PARAM_END, 961*b077aed3SPierre Pronchery }; 962*b077aed3SPierre Pronchery 963*b077aed3SPierre Pronchery return settables; 964*b077aed3SPierre Pronchery } 965*b077aed3SPierre Pronchery 966*b077aed3SPierre Pronchery static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 967*b077aed3SPierre Pronchery { 968*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx = vctx; 969*b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx); 970*b077aed3SPierre Pronchery const OSSL_PARAM *cipherp = 971*b077aed3SPierre Pronchery OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER); 972*b077aed3SPierre Pronchery const OSSL_PARAM *propsp = 973*b077aed3SPierre Pronchery OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES); 974*b077aed3SPierre Pronchery const OSSL_PARAM *save_paramsp = 975*b077aed3SPierre Pronchery OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_SAVE_PARAMETERS); 976*b077aed3SPierre Pronchery 977*b077aed3SPierre Pronchery if (cipherp != NULL) { 978*b077aed3SPierre Pronchery const char *ciphername = NULL; 979*b077aed3SPierre Pronchery const char *props = NULL; 980*b077aed3SPierre Pronchery 981*b077aed3SPierre Pronchery if (!OSSL_PARAM_get_utf8_string_ptr(cipherp, &ciphername)) 982*b077aed3SPierre Pronchery return 0; 983*b077aed3SPierre Pronchery if (propsp != NULL && !OSSL_PARAM_get_utf8_string_ptr(propsp, &props)) 984*b077aed3SPierre Pronchery return 0; 985*b077aed3SPierre Pronchery 986*b077aed3SPierre Pronchery EVP_CIPHER_free(ctx->cipher); 987*b077aed3SPierre Pronchery ctx->cipher = NULL; 988*b077aed3SPierre Pronchery ctx->cipher_intent = ciphername != NULL; 989*b077aed3SPierre Pronchery if (ciphername != NULL 990*b077aed3SPierre Pronchery && ((ctx->cipher = 991*b077aed3SPierre Pronchery EVP_CIPHER_fetch(libctx, ciphername, props)) == NULL)) 992*b077aed3SPierre Pronchery return 0; 993*b077aed3SPierre Pronchery } 994*b077aed3SPierre Pronchery 995*b077aed3SPierre Pronchery if (save_paramsp != NULL) { 996*b077aed3SPierre Pronchery if (!OSSL_PARAM_get_int(save_paramsp, &ctx->save_parameters)) 997*b077aed3SPierre Pronchery return 0; 998*b077aed3SPierre Pronchery } 999*b077aed3SPierre Pronchery return 1; 1000*b077aed3SPierre Pronchery } 1001*b077aed3SPierre Pronchery 1002*b077aed3SPierre Pronchery static int key2any_check_selection(int selection, int selection_mask) 1003*b077aed3SPierre Pronchery { 1004*b077aed3SPierre Pronchery /* 1005*b077aed3SPierre Pronchery * The selections are kinda sorta "levels", i.e. each selection given 1006*b077aed3SPierre Pronchery * here is assumed to include those following. 1007*b077aed3SPierre Pronchery */ 1008*b077aed3SPierre Pronchery int checks[] = { 1009*b077aed3SPierre Pronchery OSSL_KEYMGMT_SELECT_PRIVATE_KEY, 1010*b077aed3SPierre Pronchery OSSL_KEYMGMT_SELECT_PUBLIC_KEY, 1011*b077aed3SPierre Pronchery OSSL_KEYMGMT_SELECT_ALL_PARAMETERS 1012*b077aed3SPierre Pronchery }; 1013*b077aed3SPierre Pronchery size_t i; 1014*b077aed3SPierre Pronchery 1015*b077aed3SPierre Pronchery /* The decoder implementations made here support guessing */ 1016*b077aed3SPierre Pronchery if (selection == 0) 1017*b077aed3SPierre Pronchery return 1; 1018*b077aed3SPierre Pronchery 1019*b077aed3SPierre Pronchery for (i = 0; i < OSSL_NELEM(checks); i++) { 1020*b077aed3SPierre Pronchery int check1 = (selection & checks[i]) != 0; 1021*b077aed3SPierre Pronchery int check2 = (selection_mask & checks[i]) != 0; 1022*b077aed3SPierre Pronchery 1023*b077aed3SPierre Pronchery /* 1024*b077aed3SPierre Pronchery * If the caller asked for the currently checked bit(s), return 1025*b077aed3SPierre Pronchery * whether the decoder description says it's supported. 1026*b077aed3SPierre Pronchery */ 1027*b077aed3SPierre Pronchery if (check1) 1028*b077aed3SPierre Pronchery return check2; 1029*b077aed3SPierre Pronchery } 1030*b077aed3SPierre Pronchery 1031*b077aed3SPierre Pronchery /* This should be dead code, but just to be safe... */ 1032*b077aed3SPierre Pronchery return 0; 1033*b077aed3SPierre Pronchery } 1034*b077aed3SPierre Pronchery 1035*b077aed3SPierre Pronchery static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, 1036*b077aed3SPierre Pronchery const void *key, int type, const char *pemname, 1037*b077aed3SPierre Pronchery check_key_type_fn *checker, 1038*b077aed3SPierre Pronchery key_to_der_fn *writer, 1039*b077aed3SPierre Pronchery OSSL_PASSPHRASE_CALLBACK *pwcb, void *pwcbarg, 1040*b077aed3SPierre Pronchery key_to_paramstring_fn *key2paramstring, 1041*b077aed3SPierre Pronchery i2d_of_void *key2der) 1042*b077aed3SPierre Pronchery { 1043*b077aed3SPierre Pronchery int ret = 0; 1044*b077aed3SPierre Pronchery 1045*b077aed3SPierre Pronchery if (key == NULL) { 1046*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 1047*b077aed3SPierre Pronchery } else if (writer != NULL 1048*b077aed3SPierre Pronchery && (checker == NULL || checker(key, type))) { 1049*b077aed3SPierre Pronchery BIO *out = ossl_bio_new_from_core_bio(ctx->provctx, cout); 1050*b077aed3SPierre Pronchery 1051*b077aed3SPierre Pronchery if (out != NULL 1052*b077aed3SPierre Pronchery && (pwcb == NULL 1053*b077aed3SPierre Pronchery || ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, pwcb, pwcbarg))) 1054*b077aed3SPierre Pronchery ret = 1055*b077aed3SPierre Pronchery writer(out, key, type, pemname, key2paramstring, key2der, ctx); 1056*b077aed3SPierre Pronchery 1057*b077aed3SPierre Pronchery BIO_free(out); 1058*b077aed3SPierre Pronchery } else { 1059*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); 1060*b077aed3SPierre Pronchery } 1061*b077aed3SPierre Pronchery return ret; 1062*b077aed3SPierre Pronchery } 1063*b077aed3SPierre Pronchery 1064*b077aed3SPierre Pronchery #define DO_PRIVATE_KEY_selection_mask OSSL_KEYMGMT_SELECT_PRIVATE_KEY 1065*b077aed3SPierre Pronchery #define DO_PRIVATE_KEY(impl, type, kind, output) \ 1066*b077aed3SPierre Pronchery if ((selection & DO_PRIVATE_KEY_selection_mask) != 0) \ 1067*b077aed3SPierre Pronchery return key2any_encode(ctx, cout, key, impl##_evp_type, \ 1068*b077aed3SPierre Pronchery impl##_pem_type " PRIVATE KEY", \ 1069*b077aed3SPierre Pronchery type##_check_key_type, \ 1070*b077aed3SPierre Pronchery key_to_##kind##_##output##_priv_bio, \ 1071*b077aed3SPierre Pronchery cb, cbarg, prepare_##type##_params, \ 1072*b077aed3SPierre Pronchery type##_##kind##_priv_to_der); 1073*b077aed3SPierre Pronchery 1074*b077aed3SPierre Pronchery #define DO_PUBLIC_KEY_selection_mask OSSL_KEYMGMT_SELECT_PUBLIC_KEY 1075*b077aed3SPierre Pronchery #define DO_PUBLIC_KEY(impl, type, kind, output) \ 1076*b077aed3SPierre Pronchery if ((selection & DO_PUBLIC_KEY_selection_mask) != 0) \ 1077*b077aed3SPierre Pronchery return key2any_encode(ctx, cout, key, impl##_evp_type, \ 1078*b077aed3SPierre Pronchery impl##_pem_type " PUBLIC KEY", \ 1079*b077aed3SPierre Pronchery type##_check_key_type, \ 1080*b077aed3SPierre Pronchery key_to_##kind##_##output##_pub_bio, \ 1081*b077aed3SPierre Pronchery cb, cbarg, prepare_##type##_params, \ 1082*b077aed3SPierre Pronchery type##_##kind##_pub_to_der); 1083*b077aed3SPierre Pronchery 1084*b077aed3SPierre Pronchery #define DO_PARAMETERS_selection_mask OSSL_KEYMGMT_SELECT_ALL_PARAMETERS 1085*b077aed3SPierre Pronchery #define DO_PARAMETERS(impl, type, kind, output) \ 1086*b077aed3SPierre Pronchery if ((selection & DO_PARAMETERS_selection_mask) != 0) \ 1087*b077aed3SPierre Pronchery return key2any_encode(ctx, cout, key, impl##_evp_type, \ 1088*b077aed3SPierre Pronchery impl##_pem_type " PARAMETERS", \ 1089*b077aed3SPierre Pronchery type##_check_key_type, \ 1090*b077aed3SPierre Pronchery key_to_##kind##_##output##_param_bio, \ 1091*b077aed3SPierre Pronchery NULL, NULL, NULL, \ 1092*b077aed3SPierre Pronchery type##_##kind##_params_to_der); 1093*b077aed3SPierre Pronchery 1094*b077aed3SPierre Pronchery /*- 1095*b077aed3SPierre Pronchery * Implement the kinds of output structure that can be produced. They are 1096*b077aed3SPierre Pronchery * referred to by name, and for each name, the following macros are defined 1097*b077aed3SPierre Pronchery * (braces not included): 1098*b077aed3SPierre Pronchery * 1099*b077aed3SPierre Pronchery * DO_{kind}_selection_mask 1100*b077aed3SPierre Pronchery * 1101*b077aed3SPierre Pronchery * A mask of selection bits that must not be zero. This is used as a 1102*b077aed3SPierre Pronchery * selection criterion for each implementation. 1103*b077aed3SPierre Pronchery * This mask must never be zero. 1104*b077aed3SPierre Pronchery * 1105*b077aed3SPierre Pronchery * DO_{kind} 1106*b077aed3SPierre Pronchery * 1107*b077aed3SPierre Pronchery * The performing macro. It must use the DO_ macros defined above, 1108*b077aed3SPierre Pronchery * always in this order: 1109*b077aed3SPierre Pronchery * 1110*b077aed3SPierre Pronchery * - DO_PRIVATE_KEY 1111*b077aed3SPierre Pronchery * - DO_PUBLIC_KEY 1112*b077aed3SPierre Pronchery * - DO_PARAMETERS 1113*b077aed3SPierre Pronchery * 1114*b077aed3SPierre Pronchery * Any of those may be omitted, but the relative order must still be 1115*b077aed3SPierre Pronchery * the same. 1116*b077aed3SPierre Pronchery */ 1117*b077aed3SPierre Pronchery 1118*b077aed3SPierre Pronchery /* 1119*b077aed3SPierre Pronchery * PKCS#8 defines two structures for private keys only: 1120*b077aed3SPierre Pronchery * - PrivateKeyInfo (raw unencrypted form) 1121*b077aed3SPierre Pronchery * - EncryptedPrivateKeyInfo (encrypted wrapping) 1122*b077aed3SPierre Pronchery * 1123*b077aed3SPierre Pronchery * To allow a certain amount of flexibility, we allow the routines 1124*b077aed3SPierre Pronchery * for PrivateKeyInfo to also produce EncryptedPrivateKeyInfo if a 1125*b077aed3SPierre Pronchery * passphrase callback has been passed to them. 1126*b077aed3SPierre Pronchery */ 1127*b077aed3SPierre Pronchery #define DO_PrivateKeyInfo_selection_mask DO_PRIVATE_KEY_selection_mask 1128*b077aed3SPierre Pronchery #define DO_PrivateKeyInfo(impl, type, output) \ 1129*b077aed3SPierre Pronchery DO_PRIVATE_KEY(impl, type, pki, output) 1130*b077aed3SPierre Pronchery 1131*b077aed3SPierre Pronchery #define DO_EncryptedPrivateKeyInfo_selection_mask DO_PRIVATE_KEY_selection_mask 1132*b077aed3SPierre Pronchery #define DO_EncryptedPrivateKeyInfo(impl, type, output) \ 1133*b077aed3SPierre Pronchery DO_PRIVATE_KEY(impl, type, epki, output) 1134*b077aed3SPierre Pronchery 1135*b077aed3SPierre Pronchery /* SubjectPublicKeyInfo is a structure for public keys only */ 1136*b077aed3SPierre Pronchery #define DO_SubjectPublicKeyInfo_selection_mask DO_PUBLIC_KEY_selection_mask 1137*b077aed3SPierre Pronchery #define DO_SubjectPublicKeyInfo(impl, type, output) \ 1138*b077aed3SPierre Pronchery DO_PUBLIC_KEY(impl, type, spki, output) 1139*b077aed3SPierre Pronchery 1140*b077aed3SPierre Pronchery /* 1141*b077aed3SPierre Pronchery * "type-specific" is a uniform name for key type specific output for private 1142*b077aed3SPierre Pronchery * and public keys as well as key parameters. This is used internally in 1143*b077aed3SPierre Pronchery * libcrypto so it doesn't have to have special knowledge about select key 1144*b077aed3SPierre Pronchery * types, but also when no better name has been found. If there are more 1145*b077aed3SPierre Pronchery * expressive DO_ names above, those are preferred. 1146*b077aed3SPierre Pronchery * 1147*b077aed3SPierre Pronchery * Three forms exist: 1148*b077aed3SPierre Pronchery * 1149*b077aed3SPierre Pronchery * - type_specific_keypair Only supports private and public key 1150*b077aed3SPierre Pronchery * - type_specific_params Only supports parameters 1151*b077aed3SPierre Pronchery * - type_specific Supports all parts of an EVP_PKEY 1152*b077aed3SPierre Pronchery * - type_specific_no_pub Supports all parts of an EVP_PKEY 1153*b077aed3SPierre Pronchery * except public key 1154*b077aed3SPierre Pronchery */ 1155*b077aed3SPierre Pronchery #define DO_type_specific_params_selection_mask DO_PARAMETERS_selection_mask 1156*b077aed3SPierre Pronchery #define DO_type_specific_params(impl, type, output) \ 1157*b077aed3SPierre Pronchery DO_PARAMETERS(impl, type, type_specific, output) 1158*b077aed3SPierre Pronchery #define DO_type_specific_keypair_selection_mask \ 1159*b077aed3SPierre Pronchery ( DO_PRIVATE_KEY_selection_mask | DO_PUBLIC_KEY_selection_mask ) 1160*b077aed3SPierre Pronchery #define DO_type_specific_keypair(impl, type, output) \ 1161*b077aed3SPierre Pronchery DO_PRIVATE_KEY(impl, type, type_specific, output) \ 1162*b077aed3SPierre Pronchery DO_PUBLIC_KEY(impl, type, type_specific, output) 1163*b077aed3SPierre Pronchery #define DO_type_specific_selection_mask \ 1164*b077aed3SPierre Pronchery ( DO_type_specific_keypair_selection_mask \ 1165*b077aed3SPierre Pronchery | DO_type_specific_params_selection_mask ) 1166*b077aed3SPierre Pronchery #define DO_type_specific(impl, type, output) \ 1167*b077aed3SPierre Pronchery DO_type_specific_keypair(impl, type, output) \ 1168*b077aed3SPierre Pronchery DO_type_specific_params(impl, type, output) 1169*b077aed3SPierre Pronchery #define DO_type_specific_no_pub_selection_mask \ 1170*b077aed3SPierre Pronchery ( DO_PRIVATE_KEY_selection_mask | DO_PARAMETERS_selection_mask) 1171*b077aed3SPierre Pronchery #define DO_type_specific_no_pub(impl, type, output) \ 1172*b077aed3SPierre Pronchery DO_PRIVATE_KEY(impl, type, type_specific, output) \ 1173*b077aed3SPierre Pronchery DO_type_specific_params(impl, type, output) 1174*b077aed3SPierre Pronchery 1175*b077aed3SPierre Pronchery /* 1176*b077aed3SPierre Pronchery * Type specific aliases for the cases where we need to refer to them by 1177*b077aed3SPierre Pronchery * type name. 1178*b077aed3SPierre Pronchery * This only covers key types that are represented with i2d_{TYPE}PrivateKey, 1179*b077aed3SPierre Pronchery * i2d_{TYPE}PublicKey and i2d_{TYPE}params / i2d_{TYPE}Parameters. 1180*b077aed3SPierre Pronchery */ 1181*b077aed3SPierre Pronchery #define DO_RSA_selection_mask DO_type_specific_keypair_selection_mask 1182*b077aed3SPierre Pronchery #define DO_RSA(impl, type, output) DO_type_specific_keypair(impl, type, output) 1183*b077aed3SPierre Pronchery 1184*b077aed3SPierre Pronchery #define DO_DH_selection_mask DO_type_specific_params_selection_mask 1185*b077aed3SPierre Pronchery #define DO_DH(impl, type, output) DO_type_specific_params(impl, type, output) 1186*b077aed3SPierre Pronchery 1187*b077aed3SPierre Pronchery #define DO_DHX_selection_mask DO_type_specific_params_selection_mask 1188*b077aed3SPierre Pronchery #define DO_DHX(impl, type, output) DO_type_specific_params(impl, type, output) 1189*b077aed3SPierre Pronchery 1190*b077aed3SPierre Pronchery #define DO_DSA_selection_mask DO_type_specific_selection_mask 1191*b077aed3SPierre Pronchery #define DO_DSA(impl, type, output) DO_type_specific(impl, type, output) 1192*b077aed3SPierre Pronchery 1193*b077aed3SPierre Pronchery #define DO_EC_selection_mask DO_type_specific_no_pub_selection_mask 1194*b077aed3SPierre Pronchery #define DO_EC(impl, type, output) DO_type_specific_no_pub(impl, type, output) 1195*b077aed3SPierre Pronchery 1196*b077aed3SPierre Pronchery #define DO_SM2_selection_mask DO_type_specific_no_pub_selection_mask 1197*b077aed3SPierre Pronchery #define DO_SM2(impl, type, output) DO_type_specific_no_pub(impl, type, output) 1198*b077aed3SPierre Pronchery 1199*b077aed3SPierre Pronchery /* PKCS#1 defines a structure for RSA private and public keys */ 1200*b077aed3SPierre Pronchery #define DO_PKCS1_selection_mask DO_RSA_selection_mask 1201*b077aed3SPierre Pronchery #define DO_PKCS1(impl, type, output) DO_RSA(impl, type, output) 1202*b077aed3SPierre Pronchery 1203*b077aed3SPierre Pronchery /* PKCS#3 defines a structure for DH parameters */ 1204*b077aed3SPierre Pronchery #define DO_PKCS3_selection_mask DO_DH_selection_mask 1205*b077aed3SPierre Pronchery #define DO_PKCS3(impl, type, output) DO_DH(impl, type, output) 1206*b077aed3SPierre Pronchery /* X9.42 defines a structure for DHx parameters */ 1207*b077aed3SPierre Pronchery #define DO_X9_42_selection_mask DO_DHX_selection_mask 1208*b077aed3SPierre Pronchery #define DO_X9_42(impl, type, output) DO_DHX(impl, type, output) 1209*b077aed3SPierre Pronchery 1210*b077aed3SPierre Pronchery /* X9.62 defines a structure for EC keys and parameters */ 1211*b077aed3SPierre Pronchery #define DO_X9_62_selection_mask DO_EC_selection_mask 1212*b077aed3SPierre Pronchery #define DO_X9_62(impl, type, output) DO_EC(impl, type, output) 1213*b077aed3SPierre Pronchery 1214*b077aed3SPierre Pronchery /* 1215*b077aed3SPierre Pronchery * MAKE_ENCODER is the single driver for creating OSSL_DISPATCH tables. 1216*b077aed3SPierre Pronchery * It takes the following arguments: 1217*b077aed3SPierre Pronchery * 1218*b077aed3SPierre Pronchery * impl This is the key type name that's being implemented. 1219*b077aed3SPierre Pronchery * type This is the type name for the set of functions that implement 1220*b077aed3SPierre Pronchery * the key type. For example, ed25519, ed448, x25519 and x448 1221*b077aed3SPierre Pronchery * are all implemented with the exact same set of functions. 1222*b077aed3SPierre Pronchery * evp_type The corresponding EVP_PKEY_xxx type macro for each key. 1223*b077aed3SPierre Pronchery * Necessary because we currently use EVP_PKEY with legacy 1224*b077aed3SPierre Pronchery * native keys internally. This will need to be refactored 1225*b077aed3SPierre Pronchery * when that legacy support goes away. 1226*b077aed3SPierre Pronchery * kind What kind of support to implement. These translate into 1227*b077aed3SPierre Pronchery * the DO_##kind macros above. 1228*b077aed3SPierre Pronchery * output The output type to implement. may be der or pem. 1229*b077aed3SPierre Pronchery * 1230*b077aed3SPierre Pronchery * The resulting OSSL_DISPATCH array gets the following name (expressed in 1231*b077aed3SPierre Pronchery * C preprocessor terms) from those arguments: 1232*b077aed3SPierre Pronchery * 1233*b077aed3SPierre Pronchery * ossl_##impl##_to_##kind##_##output##_encoder_functions 1234*b077aed3SPierre Pronchery */ 1235*b077aed3SPierre Pronchery #define MAKE_ENCODER(impl, type, evp_type, kind, output) \ 1236*b077aed3SPierre Pronchery static OSSL_FUNC_encoder_import_object_fn \ 1237*b077aed3SPierre Pronchery impl##_to_##kind##_##output##_import_object; \ 1238*b077aed3SPierre Pronchery static OSSL_FUNC_encoder_free_object_fn \ 1239*b077aed3SPierre Pronchery impl##_to_##kind##_##output##_free_object; \ 1240*b077aed3SPierre Pronchery static OSSL_FUNC_encoder_encode_fn \ 1241*b077aed3SPierre Pronchery impl##_to_##kind##_##output##_encode; \ 1242*b077aed3SPierre Pronchery \ 1243*b077aed3SPierre Pronchery static void * \ 1244*b077aed3SPierre Pronchery impl##_to_##kind##_##output##_import_object(void *vctx, int selection, \ 1245*b077aed3SPierre Pronchery const OSSL_PARAM params[]) \ 1246*b077aed3SPierre Pronchery { \ 1247*b077aed3SPierre Pronchery struct key2any_ctx_st *ctx = vctx; \ 1248*b077aed3SPierre Pronchery \ 1249*b077aed3SPierre Pronchery return ossl_prov_import_key(ossl_##impl##_keymgmt_functions, \ 1250*b077aed3SPierre Pronchery ctx->provctx, selection, params); \ 1251*b077aed3SPierre Pronchery } \ 1252*b077aed3SPierre Pronchery static void impl##_to_##kind##_##output##_free_object(void *key) \ 1253*b077aed3SPierre Pronchery { \ 1254*b077aed3SPierre Pronchery ossl_prov_free_key(ossl_##impl##_keymgmt_functions, key); \ 1255*b077aed3SPierre Pronchery } \ 1256*b077aed3SPierre Pronchery static int impl##_to_##kind##_##output##_does_selection(void *ctx, \ 1257*b077aed3SPierre Pronchery int selection) \ 1258*b077aed3SPierre Pronchery { \ 1259*b077aed3SPierre Pronchery return key2any_check_selection(selection, \ 1260*b077aed3SPierre Pronchery DO_##kind##_selection_mask); \ 1261*b077aed3SPierre Pronchery } \ 1262*b077aed3SPierre Pronchery static int \ 1263*b077aed3SPierre Pronchery impl##_to_##kind##_##output##_encode(void *ctx, OSSL_CORE_BIO *cout, \ 1264*b077aed3SPierre Pronchery const void *key, \ 1265*b077aed3SPierre Pronchery const OSSL_PARAM key_abstract[], \ 1266*b077aed3SPierre Pronchery int selection, \ 1267*b077aed3SPierre Pronchery OSSL_PASSPHRASE_CALLBACK *cb, \ 1268*b077aed3SPierre Pronchery void *cbarg) \ 1269*b077aed3SPierre Pronchery { \ 1270*b077aed3SPierre Pronchery /* We don't deal with abstract objects */ \ 1271*b077aed3SPierre Pronchery if (key_abstract != NULL) { \ 1272*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); \ 1273*b077aed3SPierre Pronchery return 0; \ 1274*b077aed3SPierre Pronchery } \ 1275*b077aed3SPierre Pronchery DO_##kind(impl, type, output) \ 1276*b077aed3SPierre Pronchery \ 1277*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); \ 1278*b077aed3SPierre Pronchery return 0; \ 1279*b077aed3SPierre Pronchery } \ 1280*b077aed3SPierre Pronchery const OSSL_DISPATCH \ 1281*b077aed3SPierre Pronchery ossl_##impl##_to_##kind##_##output##_encoder_functions[] = { \ 1282*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_NEWCTX, \ 1283*b077aed3SPierre Pronchery (void (*)(void))key2any_newctx }, \ 1284*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_FREECTX, \ 1285*b077aed3SPierre Pronchery (void (*)(void))key2any_freectx }, \ 1286*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS, \ 1287*b077aed3SPierre Pronchery (void (*)(void))key2any_settable_ctx_params }, \ 1288*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, \ 1289*b077aed3SPierre Pronchery (void (*)(void))key2any_set_ctx_params }, \ 1290*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_DOES_SELECTION, \ 1291*b077aed3SPierre Pronchery (void (*)(void))impl##_to_##kind##_##output##_does_selection }, \ 1292*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \ 1293*b077aed3SPierre Pronchery (void (*)(void))impl##_to_##kind##_##output##_import_object }, \ 1294*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_FREE_OBJECT, \ 1295*b077aed3SPierre Pronchery (void (*)(void))impl##_to_##kind##_##output##_free_object }, \ 1296*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_ENCODE, \ 1297*b077aed3SPierre Pronchery (void (*)(void))impl##_to_##kind##_##output##_encode }, \ 1298*b077aed3SPierre Pronchery { 0, NULL } \ 1299*b077aed3SPierre Pronchery } 1300*b077aed3SPierre Pronchery 1301*b077aed3SPierre Pronchery /* 1302*b077aed3SPierre Pronchery * Replacements for i2d_{TYPE}PrivateKey, i2d_{TYPE}PublicKey, 1303*b077aed3SPierre Pronchery * i2d_{TYPE}params, as they exist. 1304*b077aed3SPierre Pronchery */ 1305*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, type_specific_keypair, der); 1306*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 1307*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, type_specific_params, der); 1308*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, type_specific_params, der); 1309*b077aed3SPierre Pronchery #endif 1310*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DSA 1311*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, type_specific, der); 1312*b077aed3SPierre Pronchery #endif 1313*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 1314*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, type_specific_no_pub, der); 1315*b077aed3SPierre Pronchery # ifndef OPENSSL_NO_SM2 1316*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, der); 1317*b077aed3SPierre Pronchery # endif 1318*b077aed3SPierre Pronchery #endif 1319*b077aed3SPierre Pronchery 1320*b077aed3SPierre Pronchery /* 1321*b077aed3SPierre Pronchery * Replacements for PEM_write_bio_{TYPE}PrivateKey, 1322*b077aed3SPierre Pronchery * PEM_write_bio_{TYPE}PublicKey, PEM_write_bio_{TYPE}params, as they exist. 1323*b077aed3SPierre Pronchery */ 1324*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, type_specific_keypair, pem); 1325*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 1326*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, type_specific_params, pem); 1327*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, type_specific_params, pem); 1328*b077aed3SPierre Pronchery #endif 1329*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DSA 1330*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, type_specific, pem); 1331*b077aed3SPierre Pronchery #endif 1332*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 1333*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, type_specific_no_pub, pem); 1334*b077aed3SPierre Pronchery # ifndef OPENSSL_NO_SM2 1335*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, pem); 1336*b077aed3SPierre Pronchery # endif 1337*b077aed3SPierre Pronchery #endif 1338*b077aed3SPierre Pronchery 1339*b077aed3SPierre Pronchery /* 1340*b077aed3SPierre Pronchery * PKCS#8 and SubjectPublicKeyInfo support. This may duplicate some of the 1341*b077aed3SPierre Pronchery * implementations specified above, but are more specific. 1342*b077aed3SPierre Pronchery * The SubjectPublicKeyInfo implementations also replace the 1343*b077aed3SPierre Pronchery * PEM_write_bio_{TYPE}_PUBKEY functions. 1344*b077aed3SPierre Pronchery * For PEM, these are expected to be used by PEM_write_bio_PrivateKey(), 1345*b077aed3SPierre Pronchery * PEM_write_bio_PUBKEY() and PEM_write_bio_Parameters(). 1346*b077aed3SPierre Pronchery */ 1347*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, EncryptedPrivateKeyInfo, der); 1348*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, EncryptedPrivateKeyInfo, pem); 1349*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PrivateKeyInfo, der); 1350*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PrivateKeyInfo, pem); 1351*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, SubjectPublicKeyInfo, der); 1352*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, SubjectPublicKeyInfo, pem); 1353*b077aed3SPierre Pronchery MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, EncryptedPrivateKeyInfo, der); 1354*b077aed3SPierre Pronchery MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, EncryptedPrivateKeyInfo, pem); 1355*b077aed3SPierre Pronchery MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PrivateKeyInfo, der); 1356*b077aed3SPierre Pronchery MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PrivateKeyInfo, pem); 1357*b077aed3SPierre Pronchery MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, SubjectPublicKeyInfo, der); 1358*b077aed3SPierre Pronchery MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, SubjectPublicKeyInfo, pem); 1359*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 1360*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, EncryptedPrivateKeyInfo, der); 1361*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, EncryptedPrivateKeyInfo, pem); 1362*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PrivateKeyInfo, der); 1363*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PrivateKeyInfo, pem); 1364*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, SubjectPublicKeyInfo, der); 1365*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, SubjectPublicKeyInfo, pem); 1366*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, EncryptedPrivateKeyInfo, der); 1367*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, EncryptedPrivateKeyInfo, pem); 1368*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PrivateKeyInfo, der); 1369*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PrivateKeyInfo, pem); 1370*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, SubjectPublicKeyInfo, der); 1371*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, SubjectPublicKeyInfo, pem); 1372*b077aed3SPierre Pronchery #endif 1373*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DSA 1374*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, EncryptedPrivateKeyInfo, der); 1375*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, EncryptedPrivateKeyInfo, pem); 1376*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PrivateKeyInfo, der); 1377*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PrivateKeyInfo, pem); 1378*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, SubjectPublicKeyInfo, der); 1379*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, SubjectPublicKeyInfo, pem); 1380*b077aed3SPierre Pronchery #endif 1381*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 1382*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, der); 1383*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, pem); 1384*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PrivateKeyInfo, der); 1385*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PrivateKeyInfo, pem); 1386*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der); 1387*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem); 1388*b077aed3SPierre Pronchery # ifndef OPENSSL_NO_SM2 1389*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, der); 1390*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, pem); 1391*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, der); 1392*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, pem); 1393*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der); 1394*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem); 1395*b077aed3SPierre Pronchery # endif 1396*b077aed3SPierre Pronchery MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, EncryptedPrivateKeyInfo, der); 1397*b077aed3SPierre Pronchery MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, EncryptedPrivateKeyInfo, pem); 1398*b077aed3SPierre Pronchery MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, der); 1399*b077aed3SPierre Pronchery MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, pem); 1400*b077aed3SPierre Pronchery MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, der); 1401*b077aed3SPierre Pronchery MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, pem); 1402*b077aed3SPierre Pronchery MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, der); 1403*b077aed3SPierre Pronchery MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, pem); 1404*b077aed3SPierre Pronchery MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der); 1405*b077aed3SPierre Pronchery MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem); 1406*b077aed3SPierre Pronchery MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der); 1407*b077aed3SPierre Pronchery MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem); 1408*b077aed3SPierre Pronchery MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, EncryptedPrivateKeyInfo, der); 1409*b077aed3SPierre Pronchery MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, EncryptedPrivateKeyInfo, pem); 1410*b077aed3SPierre Pronchery MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PrivateKeyInfo, der); 1411*b077aed3SPierre Pronchery MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PrivateKeyInfo, pem); 1412*b077aed3SPierre Pronchery MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, SubjectPublicKeyInfo, der); 1413*b077aed3SPierre Pronchery MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, SubjectPublicKeyInfo, pem); 1414*b077aed3SPierre Pronchery MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, der); 1415*b077aed3SPierre Pronchery MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, pem); 1416*b077aed3SPierre Pronchery MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der); 1417*b077aed3SPierre Pronchery MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem); 1418*b077aed3SPierre Pronchery MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der); 1419*b077aed3SPierre Pronchery MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem); 1420*b077aed3SPierre Pronchery #endif 1421*b077aed3SPierre Pronchery 1422*b077aed3SPierre Pronchery /* 1423*b077aed3SPierre Pronchery * Support for key type specific output formats. Not all key types have 1424*b077aed3SPierre Pronchery * this, we only aim to duplicate what is available in 1.1.1 as 1425*b077aed3SPierre Pronchery * i2d_TYPEPrivateKey(), i2d_TYPEPublicKey() and i2d_TYPEparams(). 1426*b077aed3SPierre Pronchery * For example, there are no publicly available i2d_ function for 1427*b077aed3SPierre Pronchery * ED25519, ED448, X25519 or X448, and they therefore only have PKCS#8 1428*b077aed3SPierre Pronchery * and SubjectPublicKeyInfo implementations as implemented above. 1429*b077aed3SPierre Pronchery */ 1430*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, RSA, der); 1431*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, RSA, pem); 1432*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 1433*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, DH, der); 1434*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, DH, pem); 1435*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, DHX, der); 1436*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, DHX, pem); 1437*b077aed3SPierre Pronchery #endif 1438*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DSA 1439*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, DSA, der); 1440*b077aed3SPierre Pronchery MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, DSA, pem); 1441*b077aed3SPierre Pronchery #endif 1442*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 1443*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EC, der); 1444*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EC, pem); 1445*b077aed3SPierre Pronchery # ifndef OPENSSL_NO_SM2 1446*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SM2, der); 1447*b077aed3SPierre Pronchery MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SM2, pem); 1448*b077aed3SPierre Pronchery # endif 1449*b077aed3SPierre Pronchery #endif 1450*b077aed3SPierre Pronchery 1451*b077aed3SPierre Pronchery /* Convenience structure names */ 1452*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PKCS1, der); 1453*b077aed3SPierre Pronchery MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PKCS1, pem); 1454*b077aed3SPierre Pronchery MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PKCS1, der); 1455*b077aed3SPierre Pronchery MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PKCS1, pem); 1456*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 1457*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PKCS3, der); /* parameters only */ 1458*b077aed3SPierre Pronchery MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PKCS3, pem); /* parameters only */ 1459*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, X9_42, der); /* parameters only */ 1460*b077aed3SPierre Pronchery MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, X9_42, pem); /* parameters only */ 1461*b077aed3SPierre Pronchery #endif 1462*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 1463*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, X9_62, der); 1464*b077aed3SPierre Pronchery MAKE_ENCODER(ec, ec, EVP_PKEY_EC, X9_62, pem); 1465*b077aed3SPierre Pronchery #endif 1466