Coverage Report

Created: 2026-10-28 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl34/providers/implementations/encode_decode/encode_key2text.c
Line
Count
Source
1
/*
2
 * Copyright 2020-2024 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
44.1k
{
54
44.1k
    int ret = 0, use_sep = 0;
55
44.1k
    char *hex_str = NULL, *p;
56
44.1k
    const char spaces[] = "    ";
57
44.1k
    const char *post_label_spc = " ";
58
59
44.1k
    const char *neg = "";
60
44.1k
    int bytes;
61
62
44.1k
    if (bn == NULL)
63
345
        return 0;
64
43.7k
    if (label == NULL) {
65
18.1k
        label = "";
66
18.1k
        post_label_spc = "";
67
18.1k
    }
68
69
43.7k
    if (BN_is_zero(bn))
70
6.87k
        return BIO_printf(out, "%s%s0\n", label, post_label_spc);
71
72
36.8k
    if (BN_num_bytes(bn) <= BN_BYTES) {
73
24.9k
        BN_ULONG *words = bn_get_words(bn);
74
75
24.9k
        if (BN_is_negative(bn))
76
87
            neg = "-";
77
78
24.9k
        return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n",
79
24.9k
            label, post_label_spc, neg, words[0], neg, words[0]);
80
24.9k
    }
81
82
11.9k
    hex_str = BN_bn2hex(bn);
83
11.9k
    if (hex_str == NULL)
84
0
        return 0;
85
86
11.9k
    p = hex_str;
87
11.9k
    if (*p == '-') {
88
59
        ++p;
89
59
        neg = " (Negative)";
90
59
    }
91
11.9k
    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
11.9k
    bytes = 0;
96
97
11.9k
    if (BIO_printf(out, "%s", spaces) <= 0)
98
0
        goto err;
99
100
    /* Add a leading 00 if the top bit is set */
101
11.9k
    if (*p >= '8') {
102
5.12k
        if (BIO_printf(out, "%02x", 0) <= 0)
103
0
            goto err;
104
5.12k
        ++bytes;
105
5.12k
        use_sep = 1;
106
5.12k
    }
107
19.1M
    while (*p != '\0') {
108
        /* Do a newline after every 15 hex bytes + add the space indent */
109
19.1M
        if ((bytes % 15) == 0 && bytes > 0) {
110
1.27M
            if (BIO_printf(out, ":\n%s", spaces) <= 0)
111
0
                goto err;
112
1.27M
            use_sep = 0; /* The first byte on the next line doesn't have a : */
113
1.27M
        }
114
19.1M
        if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "",
115
19.1M
                tolower((unsigned char)p[0]),
116
19.1M
                tolower((unsigned char)p[1]))
117
19.1M
            <= 0)
118
0
            goto err;
119
19.1M
        ++bytes;
120
19.1M
        p += 2;
121
19.1M
        use_sep = 1;
122
19.1M
    }
123
11.9k
    if (BIO_printf(out, "\n") <= 0)
124
0
        goto err;
125
11.9k
    ret = 1;
126
11.9k
err:
127
11.9k
    OPENSSL_free(hex_str);
128
11.9k
    return ret;
129
11.9k
}
130
131
/* Number of octets per line */
132
183k
#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
4.42k
{
138
4.42k
    size_t i;
139
140
4.42k
    if (BIO_printf(out, "%s\n", label) <= 0)
141
0
        return 0;
142
143
187k
    for (i = 0; i < buflen; i++) {
144
183k
        if ((i % LABELED_BUF_PRINT_WIDTH) == 0) {
145
14.0k
            if (i > 0 && BIO_printf(out, "\n") <= 0)
146
0
                return 0;
147
14.0k
            if (BIO_printf(out, "    ") <= 0)
148
0
                return 0;
149
14.0k
        }
150
151
183k
        if (BIO_printf(out, "%02x%s", buf[i],
152
183k
                (i == buflen - 1) ? "" : ":")
153
183k
            <= 0)
154
0
            return 0;
155
183k
    }
156
4.42k
    if (BIO_printf(out, "\n") <= 0)
157
0
        return 0;
158
159
4.42k
    return 1;
160
4.42k
}
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
3.95k
{
166
3.95k
    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
3.95k
    if (!print_labeled_bignum(out, "P:   ", ffc->p))
183
0
        goto err;
184
3.95k
    if (ffc->q != NULL) {
185
3.10k
        if (!print_labeled_bignum(out, "Q:   ", ffc->q))
186
0
            goto err;
187
3.10k
    }
188
3.95k
    if (!print_labeled_bignum(out, "G:   ", ffc->g))
189
0
        goto err;
190
3.95k
    if (ffc->j != NULL) {
191
43
        if (!print_labeled_bignum(out, "J:   ", ffc->j))
192
0
            goto err;
193
43
    }
194
3.95k
    if (ffc->seed != NULL) {
195
45
        if (!print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen))
196
0
            goto err;
197
45
    }
198
3.95k
    if (ffc->gindex != -1) {
199
0
        if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0)
200
0
            goto err;
201
0
    }
202
3.95k
    if (ffc->pcounter != -1) {
203
50
        if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0)
204
0
            goto err;
205
50
    }
206
3.95k
    if (ffc->h != 0) {
207
0
        if (BIO_printf(out, "h: %d\n", ffc->h) <= 0)
208
0
            goto err;
209
0
    }
210
3.95k
    return 1;
211
0
err:
212
0
    return 0;
213
3.95k
}
214
#endif
215
216
/* ---------------------------------------------------------------------- */
217
218
#ifndef OPENSSL_NO_DH
219
static int dh_to_text(BIO *out, const void *key, int selection)
220
20.6k
{
221
20.6k
    const DH *dh = key;
222
20.6k
    const char *type_label = NULL;
223
20.6k
    const BIGNUM *priv_key = NULL, *pub_key = NULL;
224
20.6k
    const FFC_PARAMS *params = NULL;
225
20.6k
    const BIGNUM *p = NULL;
226
20.6k
    long length;
227
228
20.6k
    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
20.6k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
234
6.68k
        type_label = "DH Private-Key";
235
13.9k
    else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
236
7.38k
        type_label = "DH Public-Key";
237
6.60k
    else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
238
6.60k
        type_label = "DH Parameters";
239
240
20.6k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
241
6.68k
        priv_key = DH_get0_priv_key(dh);
242
6.68k
        if (priv_key == NULL) {
243
6.55k
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
244
6.55k
            return 0;
245
6.55k
        }
246
6.68k
    }
247
14.1k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
248
7.50k
        pub_key = DH_get0_pub_key(dh);
249
7.50k
        if (pub_key == NULL) {
250
6.19k
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
251
6.19k
            return 0;
252
6.19k
        }
253
7.50k
    }
254
7.91k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
255
7.91k
        params = ossl_dh_get0_params((DH *)dh);
256
7.91k
        if (params == NULL) {
257
0
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS);
258
0
            return 0;
259
0
        }
260
7.91k
    }
261
262
7.91k
    p = DH_get0_p(dh);
263
7.91k
    if (p == NULL) {
264
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
265
0
        return 0;
266
0
    }
267
268
7.91k
    if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0)
269
0
        return 0;
270
7.91k
    if (priv_key != NULL
271
126
        && !print_labeled_bignum(out, "private-key:", priv_key))
272
0
        return 0;
273
7.91k
    if (pub_key != NULL
274
1.31k
        && !print_labeled_bignum(out, "public-key:", pub_key))
275
0
        return 0;
276
7.91k
    if (params != NULL
277
7.91k
        && !ffc_params_to_text(out, params))
278
0
        return 0;
279
7.91k
    length = DH_get_length(dh);
280
7.91k
    if (length > 0
281
299
        && BIO_printf(out, "recommended-private-length: %ld bits\n",
282
299
               length)
283
299
            <= 0)
284
0
        return 0;
285
286
7.91k
    return 1;
287
7.91k
}
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
20.2k
{
298
20.2k
    const DSA *dsa = key;
299
20.2k
    const char *type_label = NULL;
300
20.2k
    const BIGNUM *priv_key = NULL, *pub_key = NULL;
301
20.2k
    const FFC_PARAMS *params = NULL;
302
20.2k
    const BIGNUM *p = NULL;
303
304
20.2k
    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
20.2k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
310
8.79k
        type_label = "Private-Key";
311
11.4k
    else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
312
5.75k
        type_label = "Public-Key";
313
5.73k
    else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
314
5.73k
        type_label = "DSA-Parameters";
315
316
20.2k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
317
8.79k
        priv_key = DSA_get0_priv_key(dsa);
318
8.79k
        if (priv_key == NULL) {
319
2.90k
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
320
2.90k
            return 0;
321
2.90k
        }
322
8.79k
    }
323
17.3k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
324
11.6k
        pub_key = DSA_get0_pub_key(dsa);
325
11.6k
        if (pub_key == NULL) {
326
133
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
327
133
            return 0;
328
133
        }
329
11.6k
    }
330
17.2k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
331
17.2k
        params = ossl_dsa_get0_params((DSA *)dsa);
332
17.2k
        if (params == NULL) {
333
0
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS);
334
0
            return 0;
335
0
        }
336
17.2k
    }
337
338
17.2k
    p = DSA_get0_p(dsa);
339
17.2k
    if (p == NULL) {
340
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
341
0
        return 0;
342
0
    }
343
344
17.2k
    if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0)
345
0
        return 0;
346
17.2k
    if (priv_key != NULL
347
5.89k
        && !print_labeled_bignum(out, "priv:", priv_key))
348
0
        return 0;
349
17.2k
    if (pub_key != NULL
350
11.5k
        && !print_labeled_bignum(out, "pub: ", pub_key))
351
0
        return 0;
352
17.2k
    if (params != NULL
353
17.2k
        && !ffc_params_to_text(out, params))
354
0
        return 0;
355
356
17.2k
    return 1;
357
17.2k
}
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.33k
{
368
1.33k
    const char *plabel = "Prime:";
369
1.33k
    BIGNUM *p = NULL, *a = NULL, *b = NULL;
370
371
1.33k
    p = BN_CTX_get(ctx);
372
1.33k
    a = BN_CTX_get(ctx);
373
1.33k
    b = BN_CTX_get(ctx);
374
1.33k
    if (b == NULL
375
1.33k
        || !EC_GROUP_get_curve(group, p, a, b, ctx))
376
0
        return 0;
377
378
1.33k
    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.33k
    return print_labeled_bignum(out, plabel, p)
388
1.33k
        && print_labeled_bignum(out, "A:   ", a)
389
1.33k
        && print_labeled_bignum(out, "B:   ", b);
390
1.33k
}
391
392
static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group,
393
    BN_CTX *ctx)
394
1.33k
{
395
1.33k
    int ret;
396
1.33k
    size_t buflen;
397
1.33k
    point_conversion_form_t form;
398
1.33k
    const EC_POINT *point = NULL;
399
1.33k
    const char *glabel = NULL;
400
1.33k
    unsigned char *buf = NULL;
401
402
1.33k
    form = EC_GROUP_get_point_conversion_form(group);
403
1.33k
    point = EC_GROUP_get0_generator(group);
404
405
1.33k
    if (point == NULL)
406
0
        return 0;
407
408
1.33k
    switch (form) {
409
1.09k
    case POINT_CONVERSION_COMPRESSED:
410
1.09k
        glabel = "Generator (compressed):";
411
1.09k
        break;
412
175
    case POINT_CONVERSION_UNCOMPRESSED:
413
175
        glabel = "Generator (uncompressed):";
414
175
        break;
415
63
    case POINT_CONVERSION_HYBRID:
416
63
        glabel = "Generator (hybrid):";
417
63
        break;
418
0
    default:
419
0
        return 0;
420
1.33k
    }
421
422
1.33k
    buflen = EC_POINT_point2buf(group, point, form, &buf, ctx);
423
1.33k
    if (buflen == 0)
424
0
        return 0;
425
426
1.33k
    ret = print_labeled_buf(out, glabel, buf, buflen);
427
1.33k
    OPENSSL_clear_free(buf, buflen);
428
1.33k
    return ret;
429
1.33k
}
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.33k
{
435
1.33k
    int ret = 0, tmp_nid;
436
1.33k
    BN_CTX *ctx = NULL;
437
1.33k
    const BIGNUM *order = NULL, *cofactor = NULL;
438
1.33k
    const unsigned char *seed;
439
1.33k
    size_t seed_len = 0;
440
441
1.33k
    ctx = BN_CTX_new_ex(libctx);
442
1.33k
    if (ctx == NULL)
443
0
        return 0;
444
1.33k
    BN_CTX_start(ctx);
445
446
1.33k
    tmp_nid = EC_GROUP_get_field_type(group);
447
1.33k
    order = EC_GROUP_get0_order(group);
448
1.33k
    if (order == NULL)
449
0
        goto err;
450
451
1.33k
    seed = EC_GROUP_get0_seed(group);
452
1.33k
    if (seed != NULL)
453
797
        seed_len = EC_GROUP_get_seed_len(group);
454
1.33k
    cofactor = EC_GROUP_get0_cofactor(group);
455
456
    /* print the 'short name' of the field type */
457
1.33k
    if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0
458
1.33k
        || !ec_param_explicit_curve_to_text(out, group, ctx)
459
1.33k
        || !ec_param_explicit_gen_to_text(out, group, ctx)
460
1.33k
        || !print_labeled_bignum(out, "Order: ", order)
461
1.33k
        || (cofactor != NULL
462
1.33k
            && !print_labeled_bignum(out, "Cofactor: ", cofactor))
463
1.33k
        || (seed != NULL
464
797
            && !print_labeled_buf(out, "Seed:", seed, seed_len)))
465
0
        goto err;
466
1.33k
    ret = 1;
467
1.33k
err:
468
1.33k
    BN_CTX_end(ctx);
469
1.33k
    BN_CTX_free(ctx);
470
1.33k
    return ret;
471
1.33k
}
472
473
static int ec_param_to_text(BIO *out, const EC_GROUP *group,
474
    OSSL_LIB_CTX *libctx)
475
16.7k
{
476
16.7k
    if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) {
477
15.4k
        const char *curve_name;
478
15.4k
        int curve_nid = EC_GROUP_get_curve_name(group);
479
480
        /* Explicit parameters */
481
15.4k
        if (curve_nid == NID_undef)
482
0
            return 0;
483
484
15.4k
        if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
485
0
            return 0;
486
487
15.4k
        curve_name = EC_curve_nid2nist(curve_nid);
488
15.4k
        return (curve_name == NULL
489
8.46k
            || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
490
15.4k
    } else {
491
1.33k
        return ec_param_explicit_to_text(out, group, libctx);
492
1.33k
    }
493
16.7k
}
494
495
static int ec_to_text(BIO *out, const void *key, int selection)
496
21.1k
{
497
21.1k
    const EC_KEY *ec = key;
498
21.1k
    const char *type_label = NULL;
499
21.1k
    unsigned char *priv = NULL, *pub = NULL;
500
21.1k
    size_t priv_len = 0, pub_len = 0;
501
21.1k
    const EC_GROUP *group;
502
21.1k
    int ret = 0;
503
504
21.1k
    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.1k
    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.1k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
515
9.29k
        type_label = "Private-Key";
516
11.8k
    else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
517
6.75k
        type_label = "Public-Key";
518
5.11k
    else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
519
5.11k
        if (EC_GROUP_get_curve_name(group) != NID_sm2)
520
5.05k
            type_label = "EC-Parameters";
521
522
21.1k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
523
9.29k
        const BIGNUM *priv_key = EC_KEY_get0_private_key(ec);
524
525
9.29k
        if (priv_key == NULL) {
526
1.38k
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
527
1.38k
            goto err;
528
1.38k
        }
529
7.91k
        priv_len = EC_KEY_priv2buf(ec, &priv);
530
7.91k
        if (priv_len == 0)
531
2.03k
            goto err;
532
7.91k
    }
533
17.7k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
534
12.6k
        const EC_POINT *pub_pt = EC_KEY_get0_public_key(ec);
535
536
12.6k
        if (pub_pt == NULL) {
537
628
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
538
628
            goto err;
539
628
        }
540
541
12.0k
        pub_len = EC_KEY_key2buf(ec, EC_KEY_get_conv_form(ec), &pub, NULL);
542
12.0k
        if (pub_len == 0)
543
342
            goto err;
544
12.0k
    }
545
546
16.7k
    if (type_label != NULL
547
16.7k
        && BIO_printf(out, "%s: (%d bit)\n", type_label,
548
16.7k
               EC_GROUP_order_bits(group))
549
16.7k
            <= 0)
550
0
        goto err;
551
16.7k
    if (priv != NULL
552
5.81k
        && !print_labeled_buf(out, "priv:", priv, priv_len))
553
0
        goto err;
554
16.7k
    if (pub != NULL
555
11.6k
        && !print_labeled_buf(out, "pub:", pub, pub_len))
556
0
        goto err;
557
16.7k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
558
16.7k
        ret = ec_param_to_text(out, group, ossl_ec_key_get_libctx(ec));
559
21.1k
err:
560
21.1k
    OPENSSL_clear_free(priv, priv_len);
561
21.1k
    OPENSSL_free(pub);
562
21.1k
    return ret;
563
16.7k
}
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
250
{
577
250
    const ECX_KEY *ecx = key;
578
250
    const char *type_label = NULL;
579
580
250
    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
250
    switch (ecx->type) {
586
81
    case ECX_KEY_TYPE_X25519:
587
81
        type_label = "X25519";
588
81
        break;
589
46
    case ECX_KEY_TYPE_X448:
590
46
        type_label = "X448";
591
46
        break;
592
67
    case ECX_KEY_TYPE_ED25519:
593
67
        type_label = "ED25519";
594
67
        break;
595
56
    case ECX_KEY_TYPE_ED448:
596
56
        type_label = "ED448";
597
56
        break;
598
250
    }
599
600
250
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
601
63
        if (ecx->privkey == NULL) {
602
24
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
603
24
            return 0;
604
24
        }
605
606
39
        if (BIO_printf(out, "%s Private-Key:\n", type_label) <= 0)
607
0
            return 0;
608
39
        if (!print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen))
609
0
            return 0;
610
187
    } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
611
        /* ecx->pubkey is an array, not a pointer... */
612
143
        if (!ecx->haspubkey) {
613
0
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
614
0
            return 0;
615
0
        }
616
617
143
        if (BIO_printf(out, "%s Public-Key:\n", type_label) <= 0)
618
0
            return 0;
619
143
    }
620
621
226
    if (!print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen))
622
0
        return 0;
623
624
226
    return 1;
625
226
}
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
20.2k
{
637
20.2k
    const RSA *rsa = key;
638
20.2k
    const char *type_label = "RSA key";
639
20.2k
    const char *modulus_label = NULL;
640
20.2k
    const char *exponent_label = NULL;
641
20.2k
    const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
642
20.2k
    STACK_OF(BIGNUM_const) *factors = NULL;
643
20.2k
    STACK_OF(BIGNUM_const) *exps = NULL;
644
20.2k
    STACK_OF(BIGNUM_const) *coeffs = NULL;
645
20.2k
    int primes;
646
20.2k
    const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30((RSA *)rsa);
647
20.2k
    int ret = 0;
648
649
20.2k
    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
20.2k
    factors = sk_BIGNUM_const_new_null();
655
20.2k
    exps = sk_BIGNUM_const_new_null();
656
20.2k
    coeffs = sk_BIGNUM_const_new_null();
657
658
20.2k
    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
20.2k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
664
5.34k
        type_label = "Private-Key";
665
5.34k
        modulus_label = "modulus:";
666
5.34k
        exponent_label = "publicExponent:";
667
14.9k
    } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
668
10.1k
        type_label = "Public-Key";
669
10.1k
        modulus_label = "Modulus:";
670
10.1k
        exponent_label = "Exponent:";
671
10.1k
    }
672
673
20.2k
    RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
674
20.2k
    ossl_rsa_get0_all_params((RSA *)rsa, factors, exps, coeffs);
675
20.2k
    primes = sk_BIGNUM_const_num(factors);
676
677
20.2k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
678
5.34k
        if (BIO_printf(out, "%s: (%d bit, %d primes)\n",
679
5.34k
                type_label, BN_num_bits(rsa_n), primes)
680
5.34k
            <= 0)
681
0
            goto err;
682
14.9k
    } else {
683
14.9k
        if (BIO_printf(out, "%s: (%d bit)\n",
684
14.9k
                type_label, BN_num_bits(rsa_n))
685
14.9k
            <= 0)
686
0
            goto err;
687
14.9k
    }
688
689
20.2k
    if (!print_labeled_bignum(out, modulus_label, rsa_n))
690
0
        goto err;
691
20.2k
    if (!print_labeled_bignum(out, exponent_label, rsa_e))
692
0
        goto err;
693
20.2k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
694
5.34k
        int i;
695
696
5.34k
        if (!print_labeled_bignum(out, "privateExponent:", rsa_d))
697
2.04k
            goto err;
698
3.30k
        if (!print_labeled_bignum(out, "prime1:",
699
3.30k
                sk_BIGNUM_const_value(factors, 0)))
700
0
            goto err;
701
3.30k
        if (!print_labeled_bignum(out, "prime2:",
702
3.30k
                sk_BIGNUM_const_value(factors, 1)))
703
0
            goto err;
704
3.30k
        if (!print_labeled_bignum(out, "exponent1:",
705
3.30k
                sk_BIGNUM_const_value(exps, 0)))
706
0
            goto err;
707
3.30k
        if (!print_labeled_bignum(out, "exponent2:",
708
3.30k
                sk_BIGNUM_const_value(exps, 1)))
709
0
            goto err;
710
3.30k
        if (!print_labeled_bignum(out, "coefficient:",
711
3.30k
                sk_BIGNUM_const_value(coeffs, 0)))
712
0
            goto err;
713
20.3k
        for (i = 2; i < sk_BIGNUM_const_num(factors); i++) {
714
17.0k
            if (BIO_printf(out, "prime%d:", i + 1) <= 0)
715
0
                goto err;
716
17.0k
            if (!print_labeled_bignum(out, NULL,
717
17.0k
                    sk_BIGNUM_const_value(factors, i)))
718
0
                goto err;
719
17.0k
            if (BIO_printf(out, "exponent%d:", i + 1) <= 0)
720
0
                goto err;
721
17.0k
            if (!print_labeled_bignum(out, NULL,
722
17.0k
                    sk_BIGNUM_const_value(exps, i)))
723
0
                goto err;
724
17.0k
            if (BIO_printf(out, "coefficient%d:", i + 1) <= 0)
725
0
                goto err;
726
17.0k
            if (!print_labeled_bignum(out, NULL,
727
17.0k
                    sk_BIGNUM_const_value(coeffs, i - 1)))
728
0
                goto err;
729
17.0k
        }
730
3.30k
    }
731
732
18.2k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) {
733
18.2k
        switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
734
17.9k
        case RSA_FLAG_TYPE_RSA:
735
17.9k
            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
17.9k
            break;
740
17.9k
        case RSA_FLAG_TYPE_RSASSAPSS:
741
221
            if (ossl_rsa_pss_params_30_is_unrestricted(pss_params)) {
742
47
                if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0)
743
0
                    goto err;
744
174
            } else {
745
174
                int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss_params);
746
174
                int maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(pss_params);
747
174
                int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss_params);
748
174
                int saltlen = ossl_rsa_pss_params_30_saltlen(pss_params);
749
174
                int trailerfield = ossl_rsa_pss_params_30_trailerfield(pss_params);
750
751
174
                if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0)
752
0
                    goto err;
753
174
                if (BIO_printf(out, "  Hash Algorithm: %s%s\n",
754
174
                        ossl_rsa_oaeppss_nid2name(hashalg_nid),
755
174
                        (hashalg_nid == NID_sha1
756
174
                                ? " (default)"
757
174
                                : ""))
758
174
                    <= 0)
759
0
                    goto err;
760
174
                if (BIO_printf(out, "  Mask Algorithm: %s with %s%s\n",
761
174
                        ossl_rsa_mgf_nid2name(maskgenalg_nid),
762
174
                        ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid),
763
174
                        (maskgenalg_nid == NID_mgf1
764
174
                                    && maskgenhashalg_nid == NID_sha1
765
174
                                ? " (default)"
766
174
                                : ""))
767
174
                    <= 0)
768
0
                    goto err;
769
174
                if (BIO_printf(out, "  Minimum Salt Length: %d%s\n",
770
174
                        saltlen,
771
174
                        (saltlen == 20 ? " (default)" : ""))
772
174
                    <= 0)
773
0
                    goto err;
774
174
                if (BIO_printf(out, "  Trailer Field: 0x%x%s\n",
775
174
                        trailerfield,
776
174
                        (trailerfield == 1 ? " (default)" : ""))
777
174
                    <= 0)
778
0
                    goto err;
779
174
            }
780
221
            break;
781
18.2k
        }
782
18.2k
    }
783
784
18.2k
    ret = 1;
785
20.2k
err:
786
20.2k
    sk_BIGNUM_const_free(factors);
787
20.2k
    sk_BIGNUM_const_free(exps);
788
20.2k
    sk_BIGNUM_const_free(coeffs);
789
20.2k
    return ret;
790
18.2k
}
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
93.2k
{
799
93.2k
    return provctx;
800
93.2k
}
801
802
static void key2text_freectx(ossl_unused void *vctx)
803
93.2k
{
804
93.2k
}
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
83.6k
{
812
83.6k
    BIO *out = ossl_bio_new_from_core_bio(vctx, cout);
813
83.6k
    int ret;
814
815
83.6k
    if (out == NULL)
816
0
        return 0;
817
818
83.6k
    ret = key2text(out, key, selection);
819
83.6k
    BIO_free(out);
820
821
83.6k
    return ret;
822
83.6k
}
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
82.6k
    {                                                                 \
848
82.6k
        /* We don't deal with abstract objects */                     \
849
82.6k
        if (key_abstract != NULL) {                                   \
850
0
            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);   \
851
0
            return 0;                                                 \
852
0
        }                                                             \
853
82.6k
        return key2text_encode(vctx, key, selection, cout,            \
854
82.6k
            type##_to_text, cb, cbarg);                               \
855
82.6k
    }                                                                 \
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
8.70k
MAKE_TEXT_ENCODER(dh, dh);
872
11.9k
MAKE_TEXT_ENCODER(dhx, dh);
873
#endif
874
#ifndef OPENSSL_NO_DSA
875
20.2k
MAKE_TEXT_ENCODER(dsa, dsa);
876
#endif
877
#ifndef OPENSSL_NO_EC
878
20.9k
MAKE_TEXT_ENCODER(ec, ec);
879
#ifndef OPENSSL_NO_SM2
880
250
MAKE_TEXT_ENCODER(sm2, ec);
881
#endif
882
#ifndef OPENSSL_NO_ECX
883
67
MAKE_TEXT_ENCODER(ed25519, ecx);
884
56
MAKE_TEXT_ENCODER(ed448, ecx);
885
81
MAKE_TEXT_ENCODER(x25519, ecx);
886
46
MAKE_TEXT_ENCODER(x448, ecx);
887
#endif
888
#endif
889
20.0k
MAKE_TEXT_ENCODER(rsa, rsa);
890
MAKE_TEXT_ENCODER(rsapss, rsa);