1*b077aed3SPierre Pronchery /* 2*b077aed3SPierre Pronchery * Copyright 2020-2022 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 <ctype.h> 16*b077aed3SPierre Pronchery 17*b077aed3SPierre Pronchery #include <openssl/core.h> 18*b077aed3SPierre Pronchery #include <openssl/core_dispatch.h> 19*b077aed3SPierre Pronchery #include <openssl/core_names.h> 20*b077aed3SPierre Pronchery #include <openssl/bn.h> 21*b077aed3SPierre Pronchery #include <openssl/err.h> 22*b077aed3SPierre Pronchery #include <openssl/safestack.h> 23*b077aed3SPierre Pronchery #include <openssl/proverr.h> 24*b077aed3SPierre Pronchery #include "internal/ffc.h" 25*b077aed3SPierre Pronchery #include "crypto/bn.h" /* bn_get_words() */ 26*b077aed3SPierre Pronchery #include "crypto/dh.h" /* ossl_dh_get0_params() */ 27*b077aed3SPierre Pronchery #include "crypto/dsa.h" /* ossl_dsa_get0_params() */ 28*b077aed3SPierre Pronchery #include "crypto/ec.h" /* ossl_ec_key_get_libctx */ 29*b077aed3SPierre Pronchery #include "crypto/ecx.h" /* ECX_KEY, etc... */ 30*b077aed3SPierre Pronchery #include "crypto/rsa.h" /* RSA_PSS_PARAMS_30, etc... */ 31*b077aed3SPierre Pronchery #include "prov/bio.h" 32*b077aed3SPierre Pronchery #include "prov/implementations.h" 33*b077aed3SPierre Pronchery #include "endecoder_local.h" 34*b077aed3SPierre Pronchery 35*b077aed3SPierre Pronchery DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) 36*b077aed3SPierre Pronchery 37*b077aed3SPierre Pronchery # ifdef SIXTY_FOUR_BIT_LONG 38*b077aed3SPierre Pronchery # define BN_FMTu "%lu" 39*b077aed3SPierre Pronchery # define BN_FMTx "%lx" 40*b077aed3SPierre Pronchery # endif 41*b077aed3SPierre Pronchery 42*b077aed3SPierre Pronchery # ifdef SIXTY_FOUR_BIT 43*b077aed3SPierre Pronchery # define BN_FMTu "%llu" 44*b077aed3SPierre Pronchery # define BN_FMTx "%llx" 45*b077aed3SPierre Pronchery # endif 46*b077aed3SPierre Pronchery 47*b077aed3SPierre Pronchery # ifdef THIRTY_TWO_BIT 48*b077aed3SPierre Pronchery # define BN_FMTu "%u" 49*b077aed3SPierre Pronchery # define BN_FMTx "%x" 50*b077aed3SPierre Pronchery # endif 51*b077aed3SPierre Pronchery 52*b077aed3SPierre Pronchery static int print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn) 53*b077aed3SPierre Pronchery { 54*b077aed3SPierre Pronchery int ret = 0, use_sep = 0; 55*b077aed3SPierre Pronchery char *hex_str = NULL, *p; 56*b077aed3SPierre Pronchery const char spaces[] = " "; 57*b077aed3SPierre Pronchery const char *post_label_spc = " "; 58*b077aed3SPierre Pronchery 59*b077aed3SPierre Pronchery const char *neg = ""; 60*b077aed3SPierre Pronchery int bytes; 61*b077aed3SPierre Pronchery 62*b077aed3SPierre Pronchery if (bn == NULL) 63*b077aed3SPierre Pronchery return 0; 64*b077aed3SPierre Pronchery if (label == NULL) { 65*b077aed3SPierre Pronchery label = ""; 66*b077aed3SPierre Pronchery post_label_spc = ""; 67*b077aed3SPierre Pronchery } 68*b077aed3SPierre Pronchery 69*b077aed3SPierre Pronchery if (BN_is_zero(bn)) 70*b077aed3SPierre Pronchery return BIO_printf(out, "%s%s0\n", label, post_label_spc); 71*b077aed3SPierre Pronchery 72*b077aed3SPierre Pronchery if (BN_num_bytes(bn) <= BN_BYTES) { 73*b077aed3SPierre Pronchery BN_ULONG *words = bn_get_words(bn); 74*b077aed3SPierre Pronchery 75*b077aed3SPierre Pronchery if (BN_is_negative(bn)) 76*b077aed3SPierre Pronchery neg = "-"; 77*b077aed3SPierre Pronchery 78*b077aed3SPierre Pronchery return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n", 79*b077aed3SPierre Pronchery label, post_label_spc, neg, words[0], neg, words[0]); 80*b077aed3SPierre Pronchery } 81*b077aed3SPierre Pronchery 82*b077aed3SPierre Pronchery hex_str = BN_bn2hex(bn); 83*b077aed3SPierre Pronchery if (hex_str == NULL) 84*b077aed3SPierre Pronchery return 0; 85*b077aed3SPierre Pronchery 86*b077aed3SPierre Pronchery p = hex_str; 87*b077aed3SPierre Pronchery if (*p == '-') { 88*b077aed3SPierre Pronchery ++p; 89*b077aed3SPierre Pronchery neg = " (Negative)"; 90*b077aed3SPierre Pronchery } 91*b077aed3SPierre Pronchery if (BIO_printf(out, "%s%s\n", label, neg) <= 0) 92*b077aed3SPierre Pronchery goto err; 93*b077aed3SPierre Pronchery 94*b077aed3SPierre Pronchery /* Keep track of how many bytes we have printed out so far */ 95*b077aed3SPierre Pronchery bytes = 0; 96*b077aed3SPierre Pronchery 97*b077aed3SPierre Pronchery if (BIO_printf(out, "%s", spaces) <= 0) 98*b077aed3SPierre Pronchery goto err; 99*b077aed3SPierre Pronchery 100*b077aed3SPierre Pronchery /* Add a leading 00 if the top bit is set */ 101*b077aed3SPierre Pronchery if (*p >= '8') { 102*b077aed3SPierre Pronchery if (BIO_printf(out, "%02x", 0) <= 0) 103*b077aed3SPierre Pronchery goto err; 104*b077aed3SPierre Pronchery ++bytes; 105*b077aed3SPierre Pronchery use_sep = 1; 106*b077aed3SPierre Pronchery } 107*b077aed3SPierre Pronchery while (*p != '\0') { 108*b077aed3SPierre Pronchery /* Do a newline after every 15 hex bytes + add the space indent */ 109*b077aed3SPierre Pronchery if ((bytes % 15) == 0 && bytes > 0) { 110*b077aed3SPierre Pronchery if (BIO_printf(out, ":\n%s", spaces) <= 0) 111*b077aed3SPierre Pronchery goto err; 112*b077aed3SPierre Pronchery use_sep = 0; /* The first byte on the next line doesnt have a : */ 113*b077aed3SPierre Pronchery } 114*b077aed3SPierre Pronchery if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "", 115*b077aed3SPierre Pronchery tolower(p[0]), tolower(p[1])) <= 0) 116*b077aed3SPierre Pronchery goto err; 117*b077aed3SPierre Pronchery ++bytes; 118*b077aed3SPierre Pronchery p += 2; 119*b077aed3SPierre Pronchery use_sep = 1; 120*b077aed3SPierre Pronchery } 121*b077aed3SPierre Pronchery if (BIO_printf(out, "\n") <= 0) 122*b077aed3SPierre Pronchery goto err; 123*b077aed3SPierre Pronchery ret = 1; 124*b077aed3SPierre Pronchery err: 125*b077aed3SPierre Pronchery OPENSSL_free(hex_str); 126*b077aed3SPierre Pronchery return ret; 127*b077aed3SPierre Pronchery } 128*b077aed3SPierre Pronchery 129*b077aed3SPierre Pronchery /* Number of octets per line */ 130*b077aed3SPierre Pronchery #define LABELED_BUF_PRINT_WIDTH 15 131*b077aed3SPierre Pronchery 132*b077aed3SPierre Pronchery #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) 133*b077aed3SPierre Pronchery static int print_labeled_buf(BIO *out, const char *label, 134*b077aed3SPierre Pronchery const unsigned char *buf, size_t buflen) 135*b077aed3SPierre Pronchery { 136*b077aed3SPierre Pronchery size_t i; 137*b077aed3SPierre Pronchery 138*b077aed3SPierre Pronchery if (BIO_printf(out, "%s\n", label) <= 0) 139*b077aed3SPierre Pronchery return 0; 140*b077aed3SPierre Pronchery 141*b077aed3SPierre Pronchery for (i = 0; i < buflen; i++) { 142*b077aed3SPierre Pronchery if ((i % LABELED_BUF_PRINT_WIDTH) == 0) { 143*b077aed3SPierre Pronchery if (i > 0 && BIO_printf(out, "\n") <= 0) 144*b077aed3SPierre Pronchery return 0; 145*b077aed3SPierre Pronchery if (BIO_printf(out, " ") <= 0) 146*b077aed3SPierre Pronchery return 0; 147*b077aed3SPierre Pronchery } 148*b077aed3SPierre Pronchery 149*b077aed3SPierre Pronchery if (BIO_printf(out, "%02x%s", buf[i], 150*b077aed3SPierre Pronchery (i == buflen - 1) ? "" : ":") <= 0) 151*b077aed3SPierre Pronchery return 0; 152*b077aed3SPierre Pronchery } 153*b077aed3SPierre Pronchery if (BIO_printf(out, "\n") <= 0) 154*b077aed3SPierre Pronchery return 0; 155*b077aed3SPierre Pronchery 156*b077aed3SPierre Pronchery return 1; 157*b077aed3SPierre Pronchery } 158*b077aed3SPierre Pronchery #endif 159*b077aed3SPierre Pronchery 160*b077aed3SPierre Pronchery #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) 161*b077aed3SPierre Pronchery static int ffc_params_to_text(BIO *out, const FFC_PARAMS *ffc) 162*b077aed3SPierre Pronchery { 163*b077aed3SPierre Pronchery if (ffc->nid != NID_undef) { 164*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 165*b077aed3SPierre Pronchery const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); 166*b077aed3SPierre Pronchery const char *name = ossl_ffc_named_group_get_name(group); 167*b077aed3SPierre Pronchery 168*b077aed3SPierre Pronchery if (name == NULL) 169*b077aed3SPierre Pronchery goto err; 170*b077aed3SPierre Pronchery if (BIO_printf(out, "GROUP: %s\n", name) <= 0) 171*b077aed3SPierre Pronchery goto err; 172*b077aed3SPierre Pronchery return 1; 173*b077aed3SPierre Pronchery #else 174*b077aed3SPierre Pronchery /* How could this be? We should not have a nid in a no-dh build. */ 175*b077aed3SPierre Pronchery goto err; 176*b077aed3SPierre Pronchery #endif 177*b077aed3SPierre Pronchery } 178*b077aed3SPierre Pronchery 179*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "P: ", ffc->p)) 180*b077aed3SPierre Pronchery goto err; 181*b077aed3SPierre Pronchery if (ffc->q != NULL) { 182*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "Q: ", ffc->q)) 183*b077aed3SPierre Pronchery goto err; 184*b077aed3SPierre Pronchery } 185*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "G: ", ffc->g)) 186*b077aed3SPierre Pronchery goto err; 187*b077aed3SPierre Pronchery if (ffc->j != NULL) { 188*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "J: ", ffc->j)) 189*b077aed3SPierre Pronchery goto err; 190*b077aed3SPierre Pronchery } 191*b077aed3SPierre Pronchery if (ffc->seed != NULL) { 192*b077aed3SPierre Pronchery if (!print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen)) 193*b077aed3SPierre Pronchery goto err; 194*b077aed3SPierre Pronchery } 195*b077aed3SPierre Pronchery if (ffc->gindex != -1) { 196*b077aed3SPierre Pronchery if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0) 197*b077aed3SPierre Pronchery goto err; 198*b077aed3SPierre Pronchery } 199*b077aed3SPierre Pronchery if (ffc->pcounter != -1) { 200*b077aed3SPierre Pronchery if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0) 201*b077aed3SPierre Pronchery goto err; 202*b077aed3SPierre Pronchery } 203*b077aed3SPierre Pronchery if (ffc->h != 0) { 204*b077aed3SPierre Pronchery if (BIO_printf(out, "h: %d\n", ffc->h) <= 0) 205*b077aed3SPierre Pronchery goto err; 206*b077aed3SPierre Pronchery } 207*b077aed3SPierre Pronchery return 1; 208*b077aed3SPierre Pronchery err: 209*b077aed3SPierre Pronchery return 0; 210*b077aed3SPierre Pronchery } 211*b077aed3SPierre Pronchery #endif 212*b077aed3SPierre Pronchery 213*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 214*b077aed3SPierre Pronchery 215*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 216*b077aed3SPierre Pronchery static int dh_to_text(BIO *out, const void *key, int selection) 217*b077aed3SPierre Pronchery { 218*b077aed3SPierre Pronchery const DH *dh = key; 219*b077aed3SPierre Pronchery const char *type_label = NULL; 220*b077aed3SPierre Pronchery const BIGNUM *priv_key = NULL, *pub_key = NULL; 221*b077aed3SPierre Pronchery const FFC_PARAMS *params = NULL; 222*b077aed3SPierre Pronchery const BIGNUM *p = NULL; 223*b077aed3SPierre Pronchery long length; 224*b077aed3SPierre Pronchery 225*b077aed3SPierre Pronchery if (out == NULL || dh == NULL) { 226*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 227*b077aed3SPierre Pronchery return 0; 228*b077aed3SPierre Pronchery } 229*b077aed3SPierre Pronchery 230*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 231*b077aed3SPierre Pronchery type_label = "DH Private-Key"; 232*b077aed3SPierre Pronchery else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 233*b077aed3SPierre Pronchery type_label = "DH Public-Key"; 234*b077aed3SPierre Pronchery else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 235*b077aed3SPierre Pronchery type_label = "DH Parameters"; 236*b077aed3SPierre Pronchery 237*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 238*b077aed3SPierre Pronchery priv_key = DH_get0_priv_key(dh); 239*b077aed3SPierre Pronchery if (priv_key == NULL) { 240*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 241*b077aed3SPierre Pronchery return 0; 242*b077aed3SPierre Pronchery } 243*b077aed3SPierre Pronchery } 244*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 245*b077aed3SPierre Pronchery pub_key = DH_get0_pub_key(dh); 246*b077aed3SPierre Pronchery if (pub_key == NULL) { 247*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 248*b077aed3SPierre Pronchery return 0; 249*b077aed3SPierre Pronchery } 250*b077aed3SPierre Pronchery } 251*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 252*b077aed3SPierre Pronchery params = ossl_dh_get0_params((DH *)dh); 253*b077aed3SPierre Pronchery if (params == NULL) { 254*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS); 255*b077aed3SPierre Pronchery return 0; 256*b077aed3SPierre Pronchery } 257*b077aed3SPierre Pronchery } 258*b077aed3SPierre Pronchery 259*b077aed3SPierre Pronchery p = DH_get0_p(dh); 260*b077aed3SPierre Pronchery if (p == NULL) { 261*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 262*b077aed3SPierre Pronchery return 0; 263*b077aed3SPierre Pronchery } 264*b077aed3SPierre Pronchery 265*b077aed3SPierre Pronchery if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) 266*b077aed3SPierre Pronchery return 0; 267*b077aed3SPierre Pronchery if (priv_key != NULL 268*b077aed3SPierre Pronchery && !print_labeled_bignum(out, "private-key:", priv_key)) 269*b077aed3SPierre Pronchery return 0; 270*b077aed3SPierre Pronchery if (pub_key != NULL 271*b077aed3SPierre Pronchery && !print_labeled_bignum(out, "public-key:", pub_key)) 272*b077aed3SPierre Pronchery return 0; 273*b077aed3SPierre Pronchery if (params != NULL 274*b077aed3SPierre Pronchery && !ffc_params_to_text(out, params)) 275*b077aed3SPierre Pronchery return 0; 276*b077aed3SPierre Pronchery length = DH_get_length(dh); 277*b077aed3SPierre Pronchery if (length > 0 278*b077aed3SPierre Pronchery && BIO_printf(out, "recommended-private-length: %ld bits\n", 279*b077aed3SPierre Pronchery length) <= 0) 280*b077aed3SPierre Pronchery return 0; 281*b077aed3SPierre Pronchery 282*b077aed3SPierre Pronchery return 1; 283*b077aed3SPierre Pronchery } 284*b077aed3SPierre Pronchery 285*b077aed3SPierre Pronchery # define dh_input_type "DH" 286*b077aed3SPierre Pronchery # define dhx_input_type "DHX" 287*b077aed3SPierre Pronchery #endif 288*b077aed3SPierre Pronchery 289*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 290*b077aed3SPierre Pronchery 291*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DSA 292*b077aed3SPierre Pronchery static int dsa_to_text(BIO *out, const void *key, int selection) 293*b077aed3SPierre Pronchery { 294*b077aed3SPierre Pronchery const DSA *dsa = key; 295*b077aed3SPierre Pronchery const char *type_label = NULL; 296*b077aed3SPierre Pronchery const BIGNUM *priv_key = NULL, *pub_key = NULL; 297*b077aed3SPierre Pronchery const FFC_PARAMS *params = NULL; 298*b077aed3SPierre Pronchery const BIGNUM *p = NULL; 299*b077aed3SPierre Pronchery 300*b077aed3SPierre Pronchery if (out == NULL || dsa == NULL) { 301*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 302*b077aed3SPierre Pronchery return 0; 303*b077aed3SPierre Pronchery } 304*b077aed3SPierre Pronchery 305*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 306*b077aed3SPierre Pronchery type_label = "Private-Key"; 307*b077aed3SPierre Pronchery else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 308*b077aed3SPierre Pronchery type_label = "Public-Key"; 309*b077aed3SPierre Pronchery else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 310*b077aed3SPierre Pronchery type_label = "DSA-Parameters"; 311*b077aed3SPierre Pronchery 312*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 313*b077aed3SPierre Pronchery priv_key = DSA_get0_priv_key(dsa); 314*b077aed3SPierre Pronchery if (priv_key == NULL) { 315*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 316*b077aed3SPierre Pronchery return 0; 317*b077aed3SPierre Pronchery } 318*b077aed3SPierre Pronchery } 319*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 320*b077aed3SPierre Pronchery pub_key = DSA_get0_pub_key(dsa); 321*b077aed3SPierre Pronchery if (pub_key == NULL) { 322*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 323*b077aed3SPierre Pronchery return 0; 324*b077aed3SPierre Pronchery } 325*b077aed3SPierre Pronchery } 326*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 327*b077aed3SPierre Pronchery params = ossl_dsa_get0_params((DSA *)dsa); 328*b077aed3SPierre Pronchery if (params == NULL) { 329*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS); 330*b077aed3SPierre Pronchery return 0; 331*b077aed3SPierre Pronchery } 332*b077aed3SPierre Pronchery } 333*b077aed3SPierre Pronchery 334*b077aed3SPierre Pronchery p = DSA_get0_p(dsa); 335*b077aed3SPierre Pronchery if (p == NULL) { 336*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 337*b077aed3SPierre Pronchery return 0; 338*b077aed3SPierre Pronchery } 339*b077aed3SPierre Pronchery 340*b077aed3SPierre Pronchery if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) 341*b077aed3SPierre Pronchery return 0; 342*b077aed3SPierre Pronchery if (priv_key != NULL 343*b077aed3SPierre Pronchery && !print_labeled_bignum(out, "priv:", priv_key)) 344*b077aed3SPierre Pronchery return 0; 345*b077aed3SPierre Pronchery if (pub_key != NULL 346*b077aed3SPierre Pronchery && !print_labeled_bignum(out, "pub: ", pub_key)) 347*b077aed3SPierre Pronchery return 0; 348*b077aed3SPierre Pronchery if (params != NULL 349*b077aed3SPierre Pronchery && !ffc_params_to_text(out, params)) 350*b077aed3SPierre Pronchery return 0; 351*b077aed3SPierre Pronchery 352*b077aed3SPierre Pronchery return 1; 353*b077aed3SPierre Pronchery } 354*b077aed3SPierre Pronchery 355*b077aed3SPierre Pronchery # define dsa_input_type "DSA" 356*b077aed3SPierre Pronchery #endif 357*b077aed3SPierre Pronchery 358*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 359*b077aed3SPierre Pronchery 360*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 361*b077aed3SPierre Pronchery static int ec_param_explicit_curve_to_text(BIO *out, const EC_GROUP *group, 362*b077aed3SPierre Pronchery BN_CTX *ctx) 363*b077aed3SPierre Pronchery { 364*b077aed3SPierre Pronchery const char *plabel = "Prime:"; 365*b077aed3SPierre Pronchery BIGNUM *p = NULL, *a = NULL, *b = NULL; 366*b077aed3SPierre Pronchery 367*b077aed3SPierre Pronchery p = BN_CTX_get(ctx); 368*b077aed3SPierre Pronchery a = BN_CTX_get(ctx); 369*b077aed3SPierre Pronchery b = BN_CTX_get(ctx); 370*b077aed3SPierre Pronchery if (b == NULL 371*b077aed3SPierre Pronchery || !EC_GROUP_get_curve(group, p, a, b, ctx)) 372*b077aed3SPierre Pronchery return 0; 373*b077aed3SPierre Pronchery 374*b077aed3SPierre Pronchery if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) { 375*b077aed3SPierre Pronchery int basis_type = EC_GROUP_get_basis_type(group); 376*b077aed3SPierre Pronchery 377*b077aed3SPierre Pronchery /* print the 'short name' of the base type OID */ 378*b077aed3SPierre Pronchery if (basis_type == NID_undef 379*b077aed3SPierre Pronchery || BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0) 380*b077aed3SPierre Pronchery return 0; 381*b077aed3SPierre Pronchery plabel = "Polynomial:"; 382*b077aed3SPierre Pronchery } 383*b077aed3SPierre Pronchery return print_labeled_bignum(out, plabel, p) 384*b077aed3SPierre Pronchery && print_labeled_bignum(out, "A: ", a) 385*b077aed3SPierre Pronchery && print_labeled_bignum(out, "B: ", b); 386*b077aed3SPierre Pronchery } 387*b077aed3SPierre Pronchery 388*b077aed3SPierre Pronchery static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group, 389*b077aed3SPierre Pronchery BN_CTX *ctx) 390*b077aed3SPierre Pronchery { 391*b077aed3SPierre Pronchery int ret; 392*b077aed3SPierre Pronchery size_t buflen; 393*b077aed3SPierre Pronchery point_conversion_form_t form; 394*b077aed3SPierre Pronchery const EC_POINT *point = NULL; 395*b077aed3SPierre Pronchery const char *glabel = NULL; 396*b077aed3SPierre Pronchery unsigned char *buf = NULL; 397*b077aed3SPierre Pronchery 398*b077aed3SPierre Pronchery form = EC_GROUP_get_point_conversion_form(group); 399*b077aed3SPierre Pronchery point = EC_GROUP_get0_generator(group); 400*b077aed3SPierre Pronchery 401*b077aed3SPierre Pronchery if (point == NULL) 402*b077aed3SPierre Pronchery return 0; 403*b077aed3SPierre Pronchery 404*b077aed3SPierre Pronchery switch (form) { 405*b077aed3SPierre Pronchery case POINT_CONVERSION_COMPRESSED: 406*b077aed3SPierre Pronchery glabel = "Generator (compressed):"; 407*b077aed3SPierre Pronchery break; 408*b077aed3SPierre Pronchery case POINT_CONVERSION_UNCOMPRESSED: 409*b077aed3SPierre Pronchery glabel = "Generator (uncompressed):"; 410*b077aed3SPierre Pronchery break; 411*b077aed3SPierre Pronchery case POINT_CONVERSION_HYBRID: 412*b077aed3SPierre Pronchery glabel = "Generator (hybrid):"; 413*b077aed3SPierre Pronchery break; 414*b077aed3SPierre Pronchery default: 415*b077aed3SPierre Pronchery return 0; 416*b077aed3SPierre Pronchery } 417*b077aed3SPierre Pronchery 418*b077aed3SPierre Pronchery buflen = EC_POINT_point2buf(group, point, form, &buf, ctx); 419*b077aed3SPierre Pronchery if (buflen == 0) 420*b077aed3SPierre Pronchery return 0; 421*b077aed3SPierre Pronchery 422*b077aed3SPierre Pronchery ret = print_labeled_buf(out, glabel, buf, buflen); 423*b077aed3SPierre Pronchery OPENSSL_clear_free(buf, buflen); 424*b077aed3SPierre Pronchery return ret; 425*b077aed3SPierre Pronchery } 426*b077aed3SPierre Pronchery 427*b077aed3SPierre Pronchery /* Print explicit parameters */ 428*b077aed3SPierre Pronchery static int ec_param_explicit_to_text(BIO *out, const EC_GROUP *group, 429*b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx) 430*b077aed3SPierre Pronchery { 431*b077aed3SPierre Pronchery int ret = 0, tmp_nid; 432*b077aed3SPierre Pronchery BN_CTX *ctx = NULL; 433*b077aed3SPierre Pronchery const BIGNUM *order = NULL, *cofactor = NULL; 434*b077aed3SPierre Pronchery const unsigned char *seed; 435*b077aed3SPierre Pronchery size_t seed_len = 0; 436*b077aed3SPierre Pronchery 437*b077aed3SPierre Pronchery ctx = BN_CTX_new_ex(libctx); 438*b077aed3SPierre Pronchery if (ctx == NULL) 439*b077aed3SPierre Pronchery return 0; 440*b077aed3SPierre Pronchery BN_CTX_start(ctx); 441*b077aed3SPierre Pronchery 442*b077aed3SPierre Pronchery tmp_nid = EC_GROUP_get_field_type(group); 443*b077aed3SPierre Pronchery order = EC_GROUP_get0_order(group); 444*b077aed3SPierre Pronchery if (order == NULL) 445*b077aed3SPierre Pronchery goto err; 446*b077aed3SPierre Pronchery 447*b077aed3SPierre Pronchery seed = EC_GROUP_get0_seed(group); 448*b077aed3SPierre Pronchery if (seed != NULL) 449*b077aed3SPierre Pronchery seed_len = EC_GROUP_get_seed_len(group); 450*b077aed3SPierre Pronchery cofactor = EC_GROUP_get0_cofactor(group); 451*b077aed3SPierre Pronchery 452*b077aed3SPierre Pronchery /* print the 'short name' of the field type */ 453*b077aed3SPierre Pronchery if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0 454*b077aed3SPierre Pronchery || !ec_param_explicit_curve_to_text(out, group, ctx) 455*b077aed3SPierre Pronchery || !ec_param_explicit_gen_to_text(out, group, ctx) 456*b077aed3SPierre Pronchery || !print_labeled_bignum(out, "Order: ", order) 457*b077aed3SPierre Pronchery || (cofactor != NULL 458*b077aed3SPierre Pronchery && !print_labeled_bignum(out, "Cofactor: ", cofactor)) 459*b077aed3SPierre Pronchery || (seed != NULL 460*b077aed3SPierre Pronchery && !print_labeled_buf(out, "Seed:", seed, seed_len))) 461*b077aed3SPierre Pronchery goto err; 462*b077aed3SPierre Pronchery ret = 1; 463*b077aed3SPierre Pronchery err: 464*b077aed3SPierre Pronchery BN_CTX_end(ctx); 465*b077aed3SPierre Pronchery BN_CTX_free(ctx); 466*b077aed3SPierre Pronchery return ret; 467*b077aed3SPierre Pronchery } 468*b077aed3SPierre Pronchery 469*b077aed3SPierre Pronchery static int ec_param_to_text(BIO *out, const EC_GROUP *group, 470*b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx) 471*b077aed3SPierre Pronchery { 472*b077aed3SPierre Pronchery if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) { 473*b077aed3SPierre Pronchery const char *curve_name; 474*b077aed3SPierre Pronchery int curve_nid = EC_GROUP_get_curve_name(group); 475*b077aed3SPierre Pronchery 476*b077aed3SPierre Pronchery /* Explicit parameters */ 477*b077aed3SPierre Pronchery if (curve_nid == NID_undef) 478*b077aed3SPierre Pronchery return 0; 479*b077aed3SPierre Pronchery 480*b077aed3SPierre Pronchery if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0) 481*b077aed3SPierre Pronchery return 0; 482*b077aed3SPierre Pronchery 483*b077aed3SPierre Pronchery curve_name = EC_curve_nid2nist(curve_nid); 484*b077aed3SPierre Pronchery return (curve_name == NULL 485*b077aed3SPierre Pronchery || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0); 486*b077aed3SPierre Pronchery } else { 487*b077aed3SPierre Pronchery return ec_param_explicit_to_text(out, group, libctx); 488*b077aed3SPierre Pronchery } 489*b077aed3SPierre Pronchery } 490*b077aed3SPierre Pronchery 491*b077aed3SPierre Pronchery static int ec_to_text(BIO *out, const void *key, int selection) 492*b077aed3SPierre Pronchery { 493*b077aed3SPierre Pronchery const EC_KEY *ec = key; 494*b077aed3SPierre Pronchery const char *type_label = NULL; 495*b077aed3SPierre Pronchery unsigned char *priv = NULL, *pub = NULL; 496*b077aed3SPierre Pronchery size_t priv_len = 0, pub_len = 0; 497*b077aed3SPierre Pronchery const EC_GROUP *group; 498*b077aed3SPierre Pronchery int ret = 0; 499*b077aed3SPierre Pronchery 500*b077aed3SPierre Pronchery if (out == NULL || ec == NULL) { 501*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 502*b077aed3SPierre Pronchery return 0; 503*b077aed3SPierre Pronchery } 504*b077aed3SPierre Pronchery 505*b077aed3SPierre Pronchery if ((group = EC_KEY_get0_group(ec)) == NULL) { 506*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 507*b077aed3SPierre Pronchery return 0; 508*b077aed3SPierre Pronchery } 509*b077aed3SPierre Pronchery 510*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 511*b077aed3SPierre Pronchery type_label = "Private-Key"; 512*b077aed3SPierre Pronchery else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 513*b077aed3SPierre Pronchery type_label = "Public-Key"; 514*b077aed3SPierre Pronchery else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 515*b077aed3SPierre Pronchery type_label = "EC-Parameters"; 516*b077aed3SPierre Pronchery 517*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 518*b077aed3SPierre Pronchery const BIGNUM *priv_key = EC_KEY_get0_private_key(ec); 519*b077aed3SPierre Pronchery 520*b077aed3SPierre Pronchery if (priv_key == NULL) { 521*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 522*b077aed3SPierre Pronchery goto err; 523*b077aed3SPierre Pronchery } 524*b077aed3SPierre Pronchery priv_len = EC_KEY_priv2buf(ec, &priv); 525*b077aed3SPierre Pronchery if (priv_len == 0) 526*b077aed3SPierre Pronchery goto err; 527*b077aed3SPierre Pronchery } 528*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 529*b077aed3SPierre Pronchery const EC_POINT *pub_pt = EC_KEY_get0_public_key(ec); 530*b077aed3SPierre Pronchery 531*b077aed3SPierre Pronchery if (pub_pt == NULL) { 532*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 533*b077aed3SPierre Pronchery goto err; 534*b077aed3SPierre Pronchery } 535*b077aed3SPierre Pronchery 536*b077aed3SPierre Pronchery pub_len = EC_KEY_key2buf(ec, EC_KEY_get_conv_form(ec), &pub, NULL); 537*b077aed3SPierre Pronchery if (pub_len == 0) 538*b077aed3SPierre Pronchery goto err; 539*b077aed3SPierre Pronchery } 540*b077aed3SPierre Pronchery 541*b077aed3SPierre Pronchery if (BIO_printf(out, "%s: (%d bit)\n", type_label, 542*b077aed3SPierre Pronchery EC_GROUP_order_bits(group)) <= 0) 543*b077aed3SPierre Pronchery goto err; 544*b077aed3SPierre Pronchery if (priv != NULL 545*b077aed3SPierre Pronchery && !print_labeled_buf(out, "priv:", priv, priv_len)) 546*b077aed3SPierre Pronchery goto err; 547*b077aed3SPierre Pronchery if (pub != NULL 548*b077aed3SPierre Pronchery && !print_labeled_buf(out, "pub:", pub, pub_len)) 549*b077aed3SPierre Pronchery goto err; 550*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 551*b077aed3SPierre Pronchery ret = ec_param_to_text(out, group, ossl_ec_key_get_libctx(ec)); 552*b077aed3SPierre Pronchery err: 553*b077aed3SPierre Pronchery OPENSSL_clear_free(priv, priv_len); 554*b077aed3SPierre Pronchery OPENSSL_free(pub); 555*b077aed3SPierre Pronchery return ret; 556*b077aed3SPierre Pronchery } 557*b077aed3SPierre Pronchery 558*b077aed3SPierre Pronchery # define ec_input_type "EC" 559*b077aed3SPierre Pronchery 560*b077aed3SPierre Pronchery # ifndef OPENSSL_NO_SM2 561*b077aed3SPierre Pronchery # define sm2_input_type "SM2" 562*b077aed3SPierre Pronchery # endif 563*b077aed3SPierre Pronchery #endif 564*b077aed3SPierre Pronchery 565*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 566*b077aed3SPierre Pronchery 567*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 568*b077aed3SPierre Pronchery static int ecx_to_text(BIO *out, const void *key, int selection) 569*b077aed3SPierre Pronchery { 570*b077aed3SPierre Pronchery const ECX_KEY *ecx = key; 571*b077aed3SPierre Pronchery const char *type_label = NULL; 572*b077aed3SPierre Pronchery 573*b077aed3SPierre Pronchery if (out == NULL || ecx == NULL) { 574*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 575*b077aed3SPierre Pronchery return 0; 576*b077aed3SPierre Pronchery } 577*b077aed3SPierre Pronchery 578*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 579*b077aed3SPierre Pronchery if (ecx->privkey == NULL) { 580*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 581*b077aed3SPierre Pronchery return 0; 582*b077aed3SPierre Pronchery } 583*b077aed3SPierre Pronchery 584*b077aed3SPierre Pronchery switch (ecx->type) { 585*b077aed3SPierre Pronchery case ECX_KEY_TYPE_X25519: 586*b077aed3SPierre Pronchery type_label = "X25519 Private-Key"; 587*b077aed3SPierre Pronchery break; 588*b077aed3SPierre Pronchery case ECX_KEY_TYPE_X448: 589*b077aed3SPierre Pronchery type_label = "X448 Private-Key"; 590*b077aed3SPierre Pronchery break; 591*b077aed3SPierre Pronchery case ECX_KEY_TYPE_ED25519: 592*b077aed3SPierre Pronchery type_label = "ED25519 Private-Key"; 593*b077aed3SPierre Pronchery break; 594*b077aed3SPierre Pronchery case ECX_KEY_TYPE_ED448: 595*b077aed3SPierre Pronchery type_label = "ED448 Private-Key"; 596*b077aed3SPierre Pronchery break; 597*b077aed3SPierre Pronchery } 598*b077aed3SPierre Pronchery } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 599*b077aed3SPierre Pronchery /* ecx->pubkey is an array, not a pointer... */ 600*b077aed3SPierre Pronchery if (!ecx->haspubkey) { 601*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 602*b077aed3SPierre Pronchery return 0; 603*b077aed3SPierre Pronchery } 604*b077aed3SPierre Pronchery 605*b077aed3SPierre Pronchery switch (ecx->type) { 606*b077aed3SPierre Pronchery case ECX_KEY_TYPE_X25519: 607*b077aed3SPierre Pronchery type_label = "X25519 Public-Key"; 608*b077aed3SPierre Pronchery break; 609*b077aed3SPierre Pronchery case ECX_KEY_TYPE_X448: 610*b077aed3SPierre Pronchery type_label = "X448 Public-Key"; 611*b077aed3SPierre Pronchery break; 612*b077aed3SPierre Pronchery case ECX_KEY_TYPE_ED25519: 613*b077aed3SPierre Pronchery type_label = "ED25519 Public-Key"; 614*b077aed3SPierre Pronchery break; 615*b077aed3SPierre Pronchery case ECX_KEY_TYPE_ED448: 616*b077aed3SPierre Pronchery type_label = "ED448 Public-Key"; 617*b077aed3SPierre Pronchery break; 618*b077aed3SPierre Pronchery } 619*b077aed3SPierre Pronchery } 620*b077aed3SPierre Pronchery 621*b077aed3SPierre Pronchery if (BIO_printf(out, "%s:\n", type_label) <= 0) 622*b077aed3SPierre Pronchery return 0; 623*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 624*b077aed3SPierre Pronchery && !print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen)) 625*b077aed3SPierre Pronchery return 0; 626*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 627*b077aed3SPierre Pronchery && !print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen)) 628*b077aed3SPierre Pronchery return 0; 629*b077aed3SPierre Pronchery 630*b077aed3SPierre Pronchery return 1; 631*b077aed3SPierre Pronchery } 632*b077aed3SPierre Pronchery 633*b077aed3SPierre Pronchery # define ed25519_input_type "ED25519" 634*b077aed3SPierre Pronchery # define ed448_input_type "ED448" 635*b077aed3SPierre Pronchery # define x25519_input_type "X25519" 636*b077aed3SPierre Pronchery # define x448_input_type "X448" 637*b077aed3SPierre Pronchery #endif 638*b077aed3SPierre Pronchery 639*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 640*b077aed3SPierre Pronchery 641*b077aed3SPierre Pronchery static int rsa_to_text(BIO *out, const void *key, int selection) 642*b077aed3SPierre Pronchery { 643*b077aed3SPierre Pronchery const RSA *rsa = key; 644*b077aed3SPierre Pronchery const char *type_label = "RSA key"; 645*b077aed3SPierre Pronchery const char *modulus_label = NULL; 646*b077aed3SPierre Pronchery const char *exponent_label = NULL; 647*b077aed3SPierre Pronchery const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; 648*b077aed3SPierre Pronchery STACK_OF(BIGNUM_const) *factors = NULL; 649*b077aed3SPierre Pronchery STACK_OF(BIGNUM_const) *exps = NULL; 650*b077aed3SPierre Pronchery STACK_OF(BIGNUM_const) *coeffs = NULL; 651*b077aed3SPierre Pronchery int primes; 652*b077aed3SPierre Pronchery const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30((RSA *)rsa); 653*b077aed3SPierre Pronchery int ret = 0; 654*b077aed3SPierre Pronchery 655*b077aed3SPierre Pronchery if (out == NULL || rsa == NULL) { 656*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 657*b077aed3SPierre Pronchery goto err; 658*b077aed3SPierre Pronchery } 659*b077aed3SPierre Pronchery 660*b077aed3SPierre Pronchery factors = sk_BIGNUM_const_new_null(); 661*b077aed3SPierre Pronchery exps = sk_BIGNUM_const_new_null(); 662*b077aed3SPierre Pronchery coeffs = sk_BIGNUM_const_new_null(); 663*b077aed3SPierre Pronchery 664*b077aed3SPierre Pronchery if (factors == NULL || exps == NULL || coeffs == NULL) { 665*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 666*b077aed3SPierre Pronchery goto err; 667*b077aed3SPierre Pronchery } 668*b077aed3SPierre Pronchery 669*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 670*b077aed3SPierre Pronchery type_label = "Private-Key"; 671*b077aed3SPierre Pronchery modulus_label = "modulus:"; 672*b077aed3SPierre Pronchery exponent_label = "publicExponent:"; 673*b077aed3SPierre Pronchery } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 674*b077aed3SPierre Pronchery type_label = "Public-Key"; 675*b077aed3SPierre Pronchery modulus_label = "Modulus:"; 676*b077aed3SPierre Pronchery exponent_label = "Exponent:"; 677*b077aed3SPierre Pronchery } 678*b077aed3SPierre Pronchery 679*b077aed3SPierre Pronchery RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); 680*b077aed3SPierre Pronchery ossl_rsa_get0_all_params((RSA *)rsa, factors, exps, coeffs); 681*b077aed3SPierre Pronchery primes = sk_BIGNUM_const_num(factors); 682*b077aed3SPierre Pronchery 683*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 684*b077aed3SPierre Pronchery if (BIO_printf(out, "%s: (%d bit, %d primes)\n", 685*b077aed3SPierre Pronchery type_label, BN_num_bits(rsa_n), primes) <= 0) 686*b077aed3SPierre Pronchery goto err; 687*b077aed3SPierre Pronchery } else { 688*b077aed3SPierre Pronchery if (BIO_printf(out, "%s: (%d bit)\n", 689*b077aed3SPierre Pronchery type_label, BN_num_bits(rsa_n)) <= 0) 690*b077aed3SPierre Pronchery goto err; 691*b077aed3SPierre Pronchery } 692*b077aed3SPierre Pronchery 693*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, modulus_label, rsa_n)) 694*b077aed3SPierre Pronchery goto err; 695*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, exponent_label, rsa_e)) 696*b077aed3SPierre Pronchery goto err; 697*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 698*b077aed3SPierre Pronchery int i; 699*b077aed3SPierre Pronchery 700*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "privateExponent:", rsa_d)) 701*b077aed3SPierre Pronchery goto err; 702*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "prime1:", 703*b077aed3SPierre Pronchery sk_BIGNUM_const_value(factors, 0))) 704*b077aed3SPierre Pronchery goto err; 705*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "prime2:", 706*b077aed3SPierre Pronchery sk_BIGNUM_const_value(factors, 1))) 707*b077aed3SPierre Pronchery goto err; 708*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "exponent1:", 709*b077aed3SPierre Pronchery sk_BIGNUM_const_value(exps, 0))) 710*b077aed3SPierre Pronchery goto err; 711*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "exponent2:", 712*b077aed3SPierre Pronchery sk_BIGNUM_const_value(exps, 1))) 713*b077aed3SPierre Pronchery goto err; 714*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, "coefficient:", 715*b077aed3SPierre Pronchery sk_BIGNUM_const_value(coeffs, 0))) 716*b077aed3SPierre Pronchery goto err; 717*b077aed3SPierre Pronchery for (i = 2; i < sk_BIGNUM_const_num(factors); i++) { 718*b077aed3SPierre Pronchery if (BIO_printf(out, "prime%d:", i + 1) <= 0) 719*b077aed3SPierre Pronchery goto err; 720*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, NULL, 721*b077aed3SPierre Pronchery sk_BIGNUM_const_value(factors, i))) 722*b077aed3SPierre Pronchery goto err; 723*b077aed3SPierre Pronchery if (BIO_printf(out, "exponent%d:", i + 1) <= 0) 724*b077aed3SPierre Pronchery goto err; 725*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, NULL, 726*b077aed3SPierre Pronchery sk_BIGNUM_const_value(exps, i))) 727*b077aed3SPierre Pronchery goto err; 728*b077aed3SPierre Pronchery if (BIO_printf(out, "coefficient%d:", i + 1) <= 0) 729*b077aed3SPierre Pronchery goto err; 730*b077aed3SPierre Pronchery if (!print_labeled_bignum(out, NULL, 731*b077aed3SPierre Pronchery sk_BIGNUM_const_value(coeffs, i - 1))) 732*b077aed3SPierre Pronchery goto err; 733*b077aed3SPierre Pronchery } 734*b077aed3SPierre Pronchery } 735*b077aed3SPierre Pronchery 736*b077aed3SPierre Pronchery if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) { 737*b077aed3SPierre Pronchery switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { 738*b077aed3SPierre Pronchery case RSA_FLAG_TYPE_RSA: 739*b077aed3SPierre Pronchery if (!ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { 740*b077aed3SPierre Pronchery if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0) 741*b077aed3SPierre Pronchery goto err; 742*b077aed3SPierre Pronchery } 743*b077aed3SPierre Pronchery break; 744*b077aed3SPierre Pronchery case RSA_FLAG_TYPE_RSASSAPSS: 745*b077aed3SPierre Pronchery if (ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { 746*b077aed3SPierre Pronchery if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0) 747*b077aed3SPierre Pronchery goto err; 748*b077aed3SPierre Pronchery } else { 749*b077aed3SPierre Pronchery int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss_params); 750*b077aed3SPierre Pronchery int maskgenalg_nid = 751*b077aed3SPierre Pronchery ossl_rsa_pss_params_30_maskgenalg(pss_params); 752*b077aed3SPierre Pronchery int maskgenhashalg_nid = 753*b077aed3SPierre Pronchery ossl_rsa_pss_params_30_maskgenhashalg(pss_params); 754*b077aed3SPierre Pronchery int saltlen = ossl_rsa_pss_params_30_saltlen(pss_params); 755*b077aed3SPierre Pronchery int trailerfield = 756*b077aed3SPierre Pronchery ossl_rsa_pss_params_30_trailerfield(pss_params); 757*b077aed3SPierre Pronchery 758*b077aed3SPierre Pronchery if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0) 759*b077aed3SPierre Pronchery goto err; 760*b077aed3SPierre Pronchery if (BIO_printf(out, " Hash Algorithm: %s%s\n", 761*b077aed3SPierre Pronchery ossl_rsa_oaeppss_nid2name(hashalg_nid), 762*b077aed3SPierre Pronchery (hashalg_nid == NID_sha1 763*b077aed3SPierre Pronchery ? " (default)" : "")) <= 0) 764*b077aed3SPierre Pronchery goto err; 765*b077aed3SPierre Pronchery if (BIO_printf(out, " Mask Algorithm: %s with %s%s\n", 766*b077aed3SPierre Pronchery ossl_rsa_mgf_nid2name(maskgenalg_nid), 767*b077aed3SPierre Pronchery ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid), 768*b077aed3SPierre Pronchery (maskgenalg_nid == NID_mgf1 769*b077aed3SPierre Pronchery && maskgenhashalg_nid == NID_sha1 770*b077aed3SPierre Pronchery ? " (default)" : "")) <= 0) 771*b077aed3SPierre Pronchery goto err; 772*b077aed3SPierre Pronchery if (BIO_printf(out, " Minimum Salt Length: %d%s\n", 773*b077aed3SPierre Pronchery saltlen, 774*b077aed3SPierre Pronchery (saltlen == 20 ? " (default)" : "")) <= 0) 775*b077aed3SPierre Pronchery goto err; 776*b077aed3SPierre Pronchery if (BIO_printf(out, " Trailer Field: 0x%x%s\n", 777*b077aed3SPierre Pronchery trailerfield, 778*b077aed3SPierre Pronchery (trailerfield == 1 ? " (default)" : "")) <= 0) 779*b077aed3SPierre Pronchery goto err; 780*b077aed3SPierre Pronchery } 781*b077aed3SPierre Pronchery break; 782*b077aed3SPierre Pronchery } 783*b077aed3SPierre Pronchery } 784*b077aed3SPierre Pronchery 785*b077aed3SPierre Pronchery ret = 1; 786*b077aed3SPierre Pronchery err: 787*b077aed3SPierre Pronchery sk_BIGNUM_const_free(factors); 788*b077aed3SPierre Pronchery sk_BIGNUM_const_free(exps); 789*b077aed3SPierre Pronchery sk_BIGNUM_const_free(coeffs); 790*b077aed3SPierre Pronchery return ret; 791*b077aed3SPierre Pronchery } 792*b077aed3SPierre Pronchery 793*b077aed3SPierre Pronchery #define rsa_input_type "RSA" 794*b077aed3SPierre Pronchery #define rsapss_input_type "RSA-PSS" 795*b077aed3SPierre Pronchery 796*b077aed3SPierre Pronchery /* ---------------------------------------------------------------------- */ 797*b077aed3SPierre Pronchery 798*b077aed3SPierre Pronchery static void *key2text_newctx(void *provctx) 799*b077aed3SPierre Pronchery { 800*b077aed3SPierre Pronchery return provctx; 801*b077aed3SPierre Pronchery } 802*b077aed3SPierre Pronchery 803*b077aed3SPierre Pronchery static void key2text_freectx(ossl_unused void *vctx) 804*b077aed3SPierre Pronchery { 805*b077aed3SPierre Pronchery } 806*b077aed3SPierre Pronchery 807*b077aed3SPierre Pronchery static int key2text_encode(void *vctx, const void *key, int selection, 808*b077aed3SPierre Pronchery OSSL_CORE_BIO *cout, 809*b077aed3SPierre Pronchery int (*key2text)(BIO *out, const void *key, 810*b077aed3SPierre Pronchery int selection), 811*b077aed3SPierre Pronchery OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) 812*b077aed3SPierre Pronchery { 813*b077aed3SPierre Pronchery BIO *out = ossl_bio_new_from_core_bio(vctx, cout); 814*b077aed3SPierre Pronchery int ret; 815*b077aed3SPierre Pronchery 816*b077aed3SPierre Pronchery if (out == NULL) 817*b077aed3SPierre Pronchery return 0; 818*b077aed3SPierre Pronchery 819*b077aed3SPierre Pronchery ret = key2text(out, key, selection); 820*b077aed3SPierre Pronchery BIO_free(out); 821*b077aed3SPierre Pronchery 822*b077aed3SPierre Pronchery return ret; 823*b077aed3SPierre Pronchery } 824*b077aed3SPierre Pronchery 825*b077aed3SPierre Pronchery #define MAKE_TEXT_ENCODER(impl, type) \ 826*b077aed3SPierre Pronchery static OSSL_FUNC_encoder_import_object_fn \ 827*b077aed3SPierre Pronchery impl##2text_import_object; \ 828*b077aed3SPierre Pronchery static OSSL_FUNC_encoder_free_object_fn \ 829*b077aed3SPierre Pronchery impl##2text_free_object; \ 830*b077aed3SPierre Pronchery static OSSL_FUNC_encoder_encode_fn impl##2text_encode; \ 831*b077aed3SPierre Pronchery \ 832*b077aed3SPierre Pronchery static void *impl##2text_import_object(void *ctx, int selection, \ 833*b077aed3SPierre Pronchery const OSSL_PARAM params[]) \ 834*b077aed3SPierre Pronchery { \ 835*b077aed3SPierre Pronchery return ossl_prov_import_key(ossl_##impl##_keymgmt_functions, \ 836*b077aed3SPierre Pronchery ctx, selection, params); \ 837*b077aed3SPierre Pronchery } \ 838*b077aed3SPierre Pronchery static void impl##2text_free_object(void *key) \ 839*b077aed3SPierre Pronchery { \ 840*b077aed3SPierre Pronchery ossl_prov_free_key(ossl_##impl##_keymgmt_functions, key); \ 841*b077aed3SPierre Pronchery } \ 842*b077aed3SPierre Pronchery static int impl##2text_encode(void *vctx, OSSL_CORE_BIO *cout, \ 843*b077aed3SPierre Pronchery const void *key, \ 844*b077aed3SPierre Pronchery const OSSL_PARAM key_abstract[], \ 845*b077aed3SPierre Pronchery int selection, \ 846*b077aed3SPierre Pronchery OSSL_PASSPHRASE_CALLBACK *cb, \ 847*b077aed3SPierre Pronchery void *cbarg) \ 848*b077aed3SPierre Pronchery { \ 849*b077aed3SPierre Pronchery /* We don't deal with abstract objects */ \ 850*b077aed3SPierre Pronchery if (key_abstract != NULL) { \ 851*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); \ 852*b077aed3SPierre Pronchery return 0; \ 853*b077aed3SPierre Pronchery } \ 854*b077aed3SPierre Pronchery return key2text_encode(vctx, key, selection, cout, \ 855*b077aed3SPierre Pronchery type##_to_text, cb, cbarg); \ 856*b077aed3SPierre Pronchery } \ 857*b077aed3SPierre Pronchery const OSSL_DISPATCH ossl_##impl##_to_text_encoder_functions[] = { \ 858*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_NEWCTX, \ 859*b077aed3SPierre Pronchery (void (*)(void))key2text_newctx }, \ 860*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_FREECTX, \ 861*b077aed3SPierre Pronchery (void (*)(void))key2text_freectx }, \ 862*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \ 863*b077aed3SPierre Pronchery (void (*)(void))impl##2text_import_object }, \ 864*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_FREE_OBJECT, \ 865*b077aed3SPierre Pronchery (void (*)(void))impl##2text_free_object }, \ 866*b077aed3SPierre Pronchery { OSSL_FUNC_ENCODER_ENCODE, \ 867*b077aed3SPierre Pronchery (void (*)(void))impl##2text_encode }, \ 868*b077aed3SPierre Pronchery { 0, NULL } \ 869*b077aed3SPierre Pronchery } 870*b077aed3SPierre Pronchery 871*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DH 872*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(dh, dh); 873*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(dhx, dh); 874*b077aed3SPierre Pronchery #endif 875*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DSA 876*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(dsa, dsa); 877*b077aed3SPierre Pronchery #endif 878*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_EC 879*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(ec, ec); 880*b077aed3SPierre Pronchery # ifndef OPENSSL_NO_SM2 881*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(sm2, ec); 882*b077aed3SPierre Pronchery # endif 883*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(ed25519, ecx); 884*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(ed448, ecx); 885*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(x25519, ecx); 886*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(x448, ecx); 887*b077aed3SPierre Pronchery #endif 888*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(rsa, rsa); 889*b077aed3SPierre Pronchery MAKE_TEXT_ENCODER(rsapss, rsa); 890