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