encode_key2text.c 25 KB

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