1 /* 2 * Copyright 2020-2025 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 <openssl/core.h> 16 #include <openssl/core_dispatch.h> 17 #include <openssl/core_names.h> 18 #include <openssl/bn.h> 19 #include <openssl/err.h> 20 #include <openssl/safestack.h> 21 #include <openssl/proverr.h> 22 #include "crypto/dh.h" /* ossl_dh_get0_params() */ 23 #include "crypto/dsa.h" /* ossl_dsa_get0_params() */ 24 #include "crypto/ec.h" /* ossl_ec_key_get_libctx */ 25 #include "crypto/ecx.h" /* ECX_KEY, etc... */ 26 #include "crypto/ml_kem.h" /* ML_KEM_KEY, etc... */ 27 #include "crypto/rsa.h" /* RSA_PSS_PARAMS_30, etc... */ 28 #include "crypto/ml_dsa.h" 29 #include "crypto/slh_dsa.h" 30 #include "prov/bio.h" 31 #include "prov/implementations.h" 32 #include "internal/encoder.h" 33 #include "endecoder_local.h" 34 #include "ml_dsa_codecs.h" 35 #include "ml_kem_codecs.h" 36 37 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) 38 39 /* ---------------------------------------------------------------------- */ 40 41 #ifndef OPENSSL_NO_DH 42 static int dh_to_text(BIO *out, const void *key, int selection) 43 { 44 const DH *dh = key; 45 const char *type_label = NULL; 46 const BIGNUM *priv_key = NULL, *pub_key = NULL; 47 const FFC_PARAMS *params = NULL; 48 const BIGNUM *p = NULL; 49 long length; 50 51 if (out == NULL || dh == NULL) { 52 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 53 return 0; 54 } 55 56 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 57 type_label = "DH Private-Key"; 58 else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 59 type_label = "DH Public-Key"; 60 else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 61 type_label = "DH Parameters"; 62 63 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 64 priv_key = DH_get0_priv_key(dh); 65 if (priv_key == NULL) { 66 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 67 return 0; 68 } 69 } 70 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 71 pub_key = DH_get0_pub_key(dh); 72 if (pub_key == NULL) { 73 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 74 return 0; 75 } 76 } 77 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 78 params = ossl_dh_get0_params((DH *)dh); 79 if (params == NULL) { 80 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS); 81 return 0; 82 } 83 } 84 85 p = DH_get0_p(dh); 86 if (p == NULL) { 87 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 88 return 0; 89 } 90 91 if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) 92 return 0; 93 if (priv_key != NULL 94 && !ossl_bio_print_labeled_bignum(out, "private-key:", priv_key)) 95 return 0; 96 if (pub_key != NULL 97 && !ossl_bio_print_labeled_bignum(out, "public-key:", pub_key)) 98 return 0; 99 if (params != NULL 100 && !ossl_bio_print_ffc_params(out, params)) 101 return 0; 102 length = DH_get_length(dh); 103 if (length > 0 104 && BIO_printf(out, "recommended-private-length: %ld bits\n", 105 length) 106 <= 0) 107 return 0; 108 109 return 1; 110 } 111 #endif 112 113 /* ---------------------------------------------------------------------- */ 114 115 #ifndef OPENSSL_NO_DSA 116 static int dsa_to_text(BIO *out, const void *key, int selection) 117 { 118 const DSA *dsa = key; 119 const char *type_label = NULL; 120 const BIGNUM *priv_key = NULL, *pub_key = NULL; 121 const FFC_PARAMS *params = NULL; 122 const BIGNUM *p = NULL; 123 124 if (out == NULL || dsa == NULL) { 125 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 126 return 0; 127 } 128 129 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 130 type_label = "Private-Key"; 131 else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 132 type_label = "Public-Key"; 133 else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 134 type_label = "DSA-Parameters"; 135 136 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 137 priv_key = DSA_get0_priv_key(dsa); 138 if (priv_key == NULL) { 139 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 140 return 0; 141 } 142 } 143 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 144 pub_key = DSA_get0_pub_key(dsa); 145 if (pub_key == NULL) { 146 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 147 return 0; 148 } 149 } 150 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 151 params = ossl_dsa_get0_params((DSA *)dsa); 152 if (params == NULL) { 153 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS); 154 return 0; 155 } 156 } 157 158 p = DSA_get0_p(dsa); 159 if (p == NULL) { 160 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 161 return 0; 162 } 163 164 if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) 165 return 0; 166 if (priv_key != NULL 167 && !ossl_bio_print_labeled_bignum(out, "priv:", priv_key)) 168 return 0; 169 if (pub_key != NULL 170 && !ossl_bio_print_labeled_bignum(out, "pub: ", pub_key)) 171 return 0; 172 if (params != NULL 173 && !ossl_bio_print_ffc_params(out, params)) 174 return 0; 175 176 return 1; 177 } 178 #endif 179 180 /* ---------------------------------------------------------------------- */ 181 182 #ifndef OPENSSL_NO_EC 183 static int ec_param_explicit_curve_to_text(BIO *out, const EC_GROUP *group, 184 BN_CTX *ctx) 185 { 186 const char *plabel = "Prime:"; 187 BIGNUM *p = NULL, *a = NULL, *b = NULL; 188 189 p = BN_CTX_get(ctx); 190 a = BN_CTX_get(ctx); 191 b = BN_CTX_get(ctx); 192 if (b == NULL 193 || !EC_GROUP_get_curve(group, p, a, b, ctx)) 194 return 0; 195 196 if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) { 197 int basis_type = EC_GROUP_get_basis_type(group); 198 199 /* print the 'short name' of the base type OID */ 200 if (basis_type == NID_undef 201 || BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0) 202 return 0; 203 plabel = "Polynomial:"; 204 } 205 return ossl_bio_print_labeled_bignum(out, plabel, p) 206 && ossl_bio_print_labeled_bignum(out, "A: ", a) 207 && ossl_bio_print_labeled_bignum(out, "B: ", b); 208 } 209 210 static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group, 211 BN_CTX *ctx) 212 { 213 int ret; 214 size_t buflen; 215 point_conversion_form_t form; 216 const EC_POINT *point = NULL; 217 const char *glabel = NULL; 218 unsigned char *buf = NULL; 219 220 form = EC_GROUP_get_point_conversion_form(group); 221 point = EC_GROUP_get0_generator(group); 222 223 if (point == NULL) 224 return 0; 225 226 switch (form) { 227 case POINT_CONVERSION_COMPRESSED: 228 glabel = "Generator (compressed):"; 229 break; 230 case POINT_CONVERSION_UNCOMPRESSED: 231 glabel = "Generator (uncompressed):"; 232 break; 233 case POINT_CONVERSION_HYBRID: 234 glabel = "Generator (hybrid):"; 235 break; 236 default: 237 return 0; 238 } 239 240 buflen = EC_POINT_point2buf(group, point, form, &buf, ctx); 241 if (buflen == 0) 242 return 0; 243 244 ret = ossl_bio_print_labeled_buf(out, glabel, buf, buflen); 245 OPENSSL_clear_free(buf, buflen); 246 return ret; 247 } 248 249 /* Print explicit parameters */ 250 static int ec_param_explicit_to_text(BIO *out, const EC_GROUP *group, 251 OSSL_LIB_CTX *libctx) 252 { 253 int ret = 0, tmp_nid; 254 BN_CTX *ctx = NULL; 255 const BIGNUM *order = NULL, *cofactor = NULL; 256 const unsigned char *seed; 257 size_t seed_len = 0; 258 259 ctx = BN_CTX_new_ex(libctx); 260 if (ctx == NULL) 261 return 0; 262 BN_CTX_start(ctx); 263 264 tmp_nid = EC_GROUP_get_field_type(group); 265 order = EC_GROUP_get0_order(group); 266 if (order == NULL) 267 goto err; 268 269 seed = EC_GROUP_get0_seed(group); 270 if (seed != NULL) 271 seed_len = EC_GROUP_get_seed_len(group); 272 cofactor = EC_GROUP_get0_cofactor(group); 273 274 /* print the 'short name' of the field type */ 275 if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0 276 || !ec_param_explicit_curve_to_text(out, group, ctx) 277 || !ec_param_explicit_gen_to_text(out, group, ctx) 278 || !ossl_bio_print_labeled_bignum(out, "Order: ", order) 279 || (cofactor != NULL 280 && !ossl_bio_print_labeled_bignum(out, "Cofactor: ", cofactor)) 281 || (seed != NULL 282 && !ossl_bio_print_labeled_buf(out, "Seed:", seed, seed_len))) 283 goto err; 284 ret = 1; 285 err: 286 BN_CTX_end(ctx); 287 BN_CTX_free(ctx); 288 return ret; 289 } 290 291 static int ec_param_to_text(BIO *out, const EC_GROUP *group, 292 OSSL_LIB_CTX *libctx) 293 { 294 if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) { 295 const char *curve_name; 296 int curve_nid = EC_GROUP_get_curve_name(group); 297 298 /* Explicit parameters */ 299 if (curve_nid == NID_undef) 300 return 0; 301 302 if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0) 303 return 0; 304 305 curve_name = EC_curve_nid2nist(curve_nid); 306 return (curve_name == NULL 307 || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0); 308 } else { 309 return ec_param_explicit_to_text(out, group, libctx); 310 } 311 } 312 313 static int ec_to_text(BIO *out, const void *key, int selection) 314 { 315 const EC_KEY *ec = key; 316 const char *type_label = NULL; 317 unsigned char *priv = NULL, *pub = NULL; 318 size_t priv_len = 0, pub_len = 0; 319 const EC_GROUP *group; 320 int ret = 0; 321 322 if (out == NULL || ec == NULL) { 323 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 324 return 0; 325 } 326 327 if ((group = EC_KEY_get0_group(ec)) == NULL) { 328 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 329 return 0; 330 } 331 332 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 333 type_label = "Private-Key"; 334 else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 335 type_label = "Public-Key"; 336 else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 337 if (EC_GROUP_get_curve_name(group) != NID_sm2) 338 type_label = "EC-Parameters"; 339 340 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 341 const BIGNUM *priv_key = EC_KEY_get0_private_key(ec); 342 343 if (priv_key == NULL) { 344 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 345 goto err; 346 } 347 priv_len = EC_KEY_priv2buf(ec, &priv); 348 if (priv_len == 0) 349 goto err; 350 } 351 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 352 const EC_POINT *pub_pt = EC_KEY_get0_public_key(ec); 353 354 if (pub_pt == NULL) { 355 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 356 goto err; 357 } 358 359 pub_len = EC_KEY_key2buf(ec, EC_KEY_get_conv_form(ec), &pub, NULL); 360 if (pub_len == 0) 361 goto err; 362 } 363 364 if (type_label != NULL 365 && BIO_printf(out, "%s: (%d bit)\n", type_label, 366 EC_GROUP_order_bits(group)) 367 <= 0) 368 goto err; 369 if (priv != NULL 370 && !ossl_bio_print_labeled_buf(out, "priv:", priv, priv_len)) 371 goto err; 372 if (pub != NULL 373 && !ossl_bio_print_labeled_buf(out, "pub:", pub, pub_len)) 374 goto err; 375 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 376 ret = ec_param_to_text(out, group, ossl_ec_key_get_libctx(ec)); 377 err: 378 OPENSSL_clear_free(priv, priv_len); 379 OPENSSL_free(pub); 380 return ret; 381 } 382 #endif 383 384 /* ---------------------------------------------------------------------- */ 385 386 #ifndef OPENSSL_NO_ECX 387 static int ecx_to_text(BIO *out, const void *key, int selection) 388 { 389 const ECX_KEY *ecx = key; 390 const char *type_label = NULL; 391 392 if (out == NULL || ecx == NULL) { 393 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 394 return 0; 395 } 396 397 switch (ecx->type) { 398 case ECX_KEY_TYPE_X25519: 399 type_label = "X25519"; 400 break; 401 case ECX_KEY_TYPE_X448: 402 type_label = "X448"; 403 break; 404 case ECX_KEY_TYPE_ED25519: 405 type_label = "ED25519"; 406 break; 407 case ECX_KEY_TYPE_ED448: 408 type_label = "ED448"; 409 break; 410 } 411 412 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 413 if (ecx->privkey == NULL) { 414 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 415 return 0; 416 } 417 418 if (BIO_printf(out, "%s Private-Key:\n", type_label) <= 0) 419 return 0; 420 if (!ossl_bio_print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen)) 421 return 0; 422 } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 423 /* ecx->pubkey is an array, not a pointer... */ 424 if (!ecx->haspubkey) { 425 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 426 return 0; 427 } 428 429 if (BIO_printf(out, "%s Public-Key:\n", type_label) <= 0) 430 return 0; 431 } 432 433 if (!ossl_bio_print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen)) 434 return 0; 435 436 return 1; 437 } 438 #endif 439 440 /* ---------------------------------------------------------------------- */ 441 442 #ifndef OPENSSL_NO_ML_KEM 443 static int ml_kem_to_text(BIO *out, const void *vkey, int selection) 444 { 445 return ossl_ml_kem_key_to_text(out, (ML_KEM_KEY *)vkey, selection); 446 } 447 #endif 448 449 /* ---------------------------------------------------------------------- */ 450 451 #ifndef OPENSSL_NO_SLH_DSA 452 static int slh_dsa_to_text(BIO *out, const void *key, int selection) 453 { 454 return ossl_slh_dsa_key_to_text(out, (SLH_DSA_KEY *)key, selection); 455 } 456 #endif /* OPENSSL_NO_SLH_DSA */ 457 458 static int rsa_to_text(BIO *out, const void *key, int selection) 459 { 460 const RSA *rsa = key; 461 const char *type_label = "RSA key"; 462 const char *modulus_label = NULL; 463 const char *exponent_label = NULL; 464 const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; 465 STACK_OF(BIGNUM_const) *factors = NULL; 466 STACK_OF(BIGNUM_const) *exps = NULL; 467 STACK_OF(BIGNUM_const) *coeffs = NULL; 468 int primes; 469 const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30((RSA *)rsa); 470 int ret = 0; 471 472 if (out == NULL || rsa == NULL) { 473 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 474 goto err; 475 } 476 477 factors = sk_BIGNUM_const_new_null(); 478 exps = sk_BIGNUM_const_new_null(); 479 coeffs = sk_BIGNUM_const_new_null(); 480 481 if (factors == NULL || exps == NULL || coeffs == NULL) { 482 ERR_raise(ERR_LIB_PROV, ERR_R_CRYPTO_LIB); 483 goto err; 484 } 485 486 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 487 type_label = "Private-Key"; 488 modulus_label = "modulus:"; 489 exponent_label = "publicExponent:"; 490 } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 491 type_label = "Public-Key"; 492 modulus_label = "Modulus:"; 493 exponent_label = "Exponent:"; 494 } 495 496 RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); 497 ossl_rsa_get0_all_params((RSA *)rsa, factors, exps, coeffs); 498 primes = sk_BIGNUM_const_num(factors); 499 500 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 501 if (BIO_printf(out, "%s: (%d bit, %d primes)\n", 502 type_label, BN_num_bits(rsa_n), primes) 503 <= 0) 504 goto err; 505 } else { 506 if (BIO_printf(out, "%s: (%d bit)\n", 507 type_label, BN_num_bits(rsa_n)) 508 <= 0) 509 goto err; 510 } 511 512 if (!ossl_bio_print_labeled_bignum(out, modulus_label, rsa_n)) 513 goto err; 514 if (!ossl_bio_print_labeled_bignum(out, exponent_label, rsa_e)) 515 goto err; 516 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 517 int i; 518 519 if (!ossl_bio_print_labeled_bignum(out, "privateExponent:", rsa_d)) 520 goto err; 521 if (!ossl_bio_print_labeled_bignum(out, "prime1:", 522 sk_BIGNUM_const_value(factors, 0))) 523 goto err; 524 if (!ossl_bio_print_labeled_bignum(out, "prime2:", 525 sk_BIGNUM_const_value(factors, 1))) 526 goto err; 527 if (!ossl_bio_print_labeled_bignum(out, "exponent1:", 528 sk_BIGNUM_const_value(exps, 0))) 529 goto err; 530 if (!ossl_bio_print_labeled_bignum(out, "exponent2:", 531 sk_BIGNUM_const_value(exps, 1))) 532 goto err; 533 if (!ossl_bio_print_labeled_bignum(out, "coefficient:", 534 sk_BIGNUM_const_value(coeffs, 0))) 535 goto err; 536 for (i = 2; i < sk_BIGNUM_const_num(factors); i++) { 537 if (BIO_printf(out, "prime%d:", i + 1) <= 0) 538 goto err; 539 if (!ossl_bio_print_labeled_bignum(out, NULL, 540 sk_BIGNUM_const_value(factors, i))) 541 goto err; 542 if (BIO_printf(out, "exponent%d:", i + 1) <= 0) 543 goto err; 544 if (!ossl_bio_print_labeled_bignum(out, NULL, 545 sk_BIGNUM_const_value(exps, i))) 546 goto err; 547 if (BIO_printf(out, "coefficient%d:", i + 1) <= 0) 548 goto err; 549 if (!ossl_bio_print_labeled_bignum(out, NULL, 550 sk_BIGNUM_const_value(coeffs, i - 1))) 551 goto err; 552 } 553 } 554 555 if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) { 556 switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { 557 case RSA_FLAG_TYPE_RSA: 558 if (!ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { 559 if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0) 560 goto err; 561 } 562 break; 563 case RSA_FLAG_TYPE_RSASSAPSS: 564 if (ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { 565 if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0) 566 goto err; 567 } else { 568 int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss_params); 569 int maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(pss_params); 570 int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss_params); 571 int saltlen = ossl_rsa_pss_params_30_saltlen(pss_params); 572 int trailerfield = ossl_rsa_pss_params_30_trailerfield(pss_params); 573 574 if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0) 575 goto err; 576 if (BIO_printf(out, " Hash Algorithm: %s%s\n", 577 ossl_rsa_oaeppss_nid2name(hashalg_nid), 578 (hashalg_nid == NID_sha1 579 ? " (default)" 580 : "")) 581 <= 0) 582 goto err; 583 if (BIO_printf(out, " Mask Algorithm: %s with %s%s\n", 584 ossl_rsa_mgf_nid2name(maskgenalg_nid), 585 ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid), 586 (maskgenalg_nid == NID_mgf1 587 && maskgenhashalg_nid == NID_sha1 588 ? " (default)" 589 : "")) 590 <= 0) 591 goto err; 592 if (BIO_printf(out, " Minimum Salt Length: %d%s\n", 593 saltlen, 594 (saltlen == 20 ? " (default)" : "")) 595 <= 0) 596 goto err; 597 if (BIO_printf(out, " Trailer Field: 0x%x%s\n", 598 trailerfield, 599 (trailerfield == 1 ? " (default)" : "")) 600 <= 0) 601 goto err; 602 } 603 break; 604 } 605 } 606 607 ret = 1; 608 err: 609 sk_BIGNUM_const_free(factors); 610 sk_BIGNUM_const_free(exps); 611 sk_BIGNUM_const_free(coeffs); 612 return ret; 613 } 614 615 /* ---------------------------------------------------------------------- */ 616 617 #ifndef OPENSSL_NO_ML_DSA 618 static int ml_dsa_to_text(BIO *out, const void *key, int selection) 619 { 620 return ossl_ml_dsa_key_to_text(out, (ML_DSA_KEY *)key, selection); 621 } 622 #endif /* OPENSSL_NO_ML_DSA */ 623 /* ---------------------------------------------------------------------- */ 624 625 static void *key2text_newctx(void *provctx) 626 { 627 return provctx; 628 } 629 630 static void key2text_freectx(ossl_unused void *vctx) 631 { 632 } 633 634 static int key2text_encode(void *vctx, const void *key, int selection, 635 OSSL_CORE_BIO *cout, 636 int (*key2text)(BIO *out, const void *key, 637 int selection), 638 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) 639 { 640 BIO *out = ossl_bio_new_from_core_bio(vctx, cout); 641 int ret; 642 643 if (out == NULL) 644 return 0; 645 646 ret = key2text(out, key, selection); 647 BIO_free(out); 648 649 return ret; 650 } 651 652 #define MAKE_TEXT_ENCODER(impl, type) \ 653 static OSSL_FUNC_encoder_import_object_fn \ 654 impl##2text_import_object; \ 655 static OSSL_FUNC_encoder_free_object_fn \ 656 impl##2text_free_object; \ 657 static OSSL_FUNC_encoder_encode_fn impl##2text_encode; \ 658 \ 659 static void *impl##2text_import_object(void *ctx, int selection, \ 660 const OSSL_PARAM params[]) \ 661 { \ 662 return ossl_prov_import_key(ossl_##impl##_keymgmt_functions, \ 663 ctx, selection, params); \ 664 } \ 665 static void impl##2text_free_object(void *key) \ 666 { \ 667 ossl_prov_free_key(ossl_##impl##_keymgmt_functions, key); \ 668 } \ 669 static int impl##2text_encode(void *vctx, OSSL_CORE_BIO *cout, \ 670 const void *key, \ 671 const OSSL_PARAM key_abstract[], \ 672 int selection, \ 673 OSSL_PASSPHRASE_CALLBACK *cb, \ 674 void *cbarg) \ 675 { \ 676 /* We don't deal with abstract objects */ \ 677 if (key_abstract != NULL) { \ 678 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); \ 679 return 0; \ 680 } \ 681 return key2text_encode(vctx, key, selection, cout, \ 682 type##_to_text, cb, cbarg); \ 683 } \ 684 const OSSL_DISPATCH ossl_##impl##_to_text_encoder_functions[] = { \ 685 { OSSL_FUNC_ENCODER_NEWCTX, \ 686 (void (*)(void))key2text_newctx }, \ 687 { OSSL_FUNC_ENCODER_FREECTX, \ 688 (void (*)(void))key2text_freectx }, \ 689 { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \ 690 (void (*)(void))impl##2text_import_object }, \ 691 { OSSL_FUNC_ENCODER_FREE_OBJECT, \ 692 (void (*)(void))impl##2text_free_object }, \ 693 { OSSL_FUNC_ENCODER_ENCODE, \ 694 (void (*)(void))impl##2text_encode }, \ 695 OSSL_DISPATCH_END \ 696 } 697 698 #ifndef OPENSSL_NO_DH 699 MAKE_TEXT_ENCODER(dh, dh); 700 MAKE_TEXT_ENCODER(dhx, dh); 701 #endif 702 #ifndef OPENSSL_NO_DSA 703 MAKE_TEXT_ENCODER(dsa, dsa); 704 #endif 705 #ifndef OPENSSL_NO_EC 706 MAKE_TEXT_ENCODER(ec, ec); 707 #ifndef OPENSSL_NO_SM2 708 MAKE_TEXT_ENCODER(sm2, ec); 709 #endif 710 #ifndef OPENSSL_NO_ECX 711 MAKE_TEXT_ENCODER(ed25519, ecx); 712 MAKE_TEXT_ENCODER(ed448, ecx); 713 MAKE_TEXT_ENCODER(x25519, ecx); 714 MAKE_TEXT_ENCODER(x448, ecx); 715 #endif 716 #endif 717 #ifndef OPENSSL_NO_ML_KEM 718 MAKE_TEXT_ENCODER(ml_kem_512, ml_kem); 719 MAKE_TEXT_ENCODER(ml_kem_768, ml_kem); 720 MAKE_TEXT_ENCODER(ml_kem_1024, ml_kem); 721 #endif 722 MAKE_TEXT_ENCODER(rsa, rsa); 723 MAKE_TEXT_ENCODER(rsapss, rsa); 724 725 #ifndef OPENSSL_NO_ML_DSA 726 MAKE_TEXT_ENCODER(ml_dsa_44, ml_dsa); 727 MAKE_TEXT_ENCODER(ml_dsa_65, ml_dsa); 728 MAKE_TEXT_ENCODER(ml_dsa_87, ml_dsa); 729 #endif 730 731 #ifndef OPENSSL_NO_SLH_DSA 732 MAKE_TEXT_ENCODER(slh_dsa_sha2_128s, slh_dsa); 733 MAKE_TEXT_ENCODER(slh_dsa_sha2_128f, slh_dsa); 734 MAKE_TEXT_ENCODER(slh_dsa_sha2_192s, slh_dsa); 735 MAKE_TEXT_ENCODER(slh_dsa_sha2_192f, slh_dsa); 736 MAKE_TEXT_ENCODER(slh_dsa_sha2_256s, slh_dsa); 737 MAKE_TEXT_ENCODER(slh_dsa_sha2_256f, slh_dsa); 738 MAKE_TEXT_ENCODER(slh_dsa_shake_128s, slh_dsa); 739 MAKE_TEXT_ENCODER(slh_dsa_shake_128f, slh_dsa); 740 MAKE_TEXT_ENCODER(slh_dsa_shake_192s, slh_dsa); 741 MAKE_TEXT_ENCODER(slh_dsa_shake_192f, slh_dsa); 742 MAKE_TEXT_ENCODER(slh_dsa_shake_256s, slh_dsa); 743 MAKE_TEXT_ENCODER(slh_dsa_shake_256f, slh_dsa); 744 #endif 745