Coverage Report

Created: 2025-12-31 06:58

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