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