1/*
2 * Copyright 2020-2021 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 * This program tests the following known key type specific function against
12 * the corresponding OSSL_ENCODER implementation:
13 *
14 * - i2d_{TYPE}PrivateKey()
15 * - i2d_{TYPE}PublicKey(),
16 * - i2d_{TYPE}params(),
17 * - i2d_{TYPE}_PUBKEY(),
18 * - PEM_write_bio_{TYPE}PrivateKey()
19 * - PEM_write_bio_{TYPE}PublicKey()
20 * - PEM_write_bio_{TYPE}params()
21 * - PEM_write_bio_{TYPE}_PUBKEY()
22 *
23 * as well as the following functions against the corresponding OSSL_DECODER
24 * implementation.
25 *
26 * - d2i_{TYPE}PrivateKey()
27 * - d2i_{TYPE}PublicKey(),
28 * - d2i_{TYPE}params(),
29 * - d2i_{TYPE}_PUBKEY(),
30 * - PEM_read_bio_{TYPE}PrivateKey()
31 * - PEM_read_bio_{TYPE}PublicKey()
32 * - PEM_read_bio_{TYPE}params()
33 * - PEM_read_bio_{TYPE}_PUBKEY()
34 */
35
36#include <stdlib.h>
37#include <string.h>
38
39/*
40 * We test deprecated functions, so we need to suppress deprecation warnings.
41 */
42#define OPENSSL_SUPPRESS_DEPRECATED
43
44#include <openssl/bio.h>
45#include <openssl/evp.h>
46#include <openssl/asn1.h>
47#include <openssl/pem.h>
48#include <openssl/params.h>
49#include <openssl/encoder.h>
50#include <openssl/decoder.h>
51#include <openssl/dh.h>
52#include <openssl/dsa.h>
53#ifndef OPENSSL_NO_DEPRECATED_3_0
54# include <openssl/rsa.h>
55#endif
56#include "internal/nelem.h"
57#include "crypto/evp.h"
58
59#include "testutil.h"
60
61typedef int PEM_write_bio_of_void_protected(BIO *out, const void *obj,
62                                            const EVP_CIPHER *enc,
63                                            unsigned char *kstr, int klen,
64                                            pem_password_cb *cb, void *u);
65typedef int PEM_write_bio_of_void_unprotected(BIO *out, const void *obj);
66typedef void *PEM_read_bio_of_void(BIO *out, void **obj,
67                                   pem_password_cb *cb, void *u);
68typedef int EVP_PKEY_print_fn(BIO *out, const EVP_PKEY *pkey,
69                              int indent, ASN1_PCTX *pctx);
70typedef int EVP_PKEY_eq_fn(const EVP_PKEY *a, const EVP_PKEY *b);
71
72static struct test_stanza_st {
73    const char *keytype;
74    const char *structure[2];
75    int evp_type;
76
77    i2d_of_void *i2d_PrivateKey;
78    i2d_of_void *i2d_PublicKey;
79    i2d_of_void *i2d_params;
80    i2d_of_void *i2d_PUBKEY;
81    PEM_write_bio_of_void_protected *pem_write_bio_PrivateKey;
82    PEM_write_bio_of_void_unprotected *pem_write_bio_PublicKey;
83    PEM_write_bio_of_void_unprotected *pem_write_bio_params;
84    PEM_write_bio_of_void_unprotected *pem_write_bio_PUBKEY;
85
86    d2i_of_void *d2i_PrivateKey;
87    d2i_of_void *d2i_PublicKey;
88    d2i_of_void *d2i_params;
89    d2i_of_void *d2i_PUBKEY;
90    PEM_read_bio_of_void *pem_read_bio_PrivateKey;
91    PEM_read_bio_of_void *pem_read_bio_PublicKey;
92    PEM_read_bio_of_void *pem_read_bio_params;
93    PEM_read_bio_of_void *pem_read_bio_PUBKEY;
94} test_stanzas[] = {
95#ifndef OPENSSL_NO_DH
96    { "DH", { "DH", "type-specific" }, EVP_PKEY_DH,
97      NULL,                      /* No i2d_DHPrivateKey */
98      NULL,                      /* No i2d_DHPublicKey */
99      (i2d_of_void *)i2d_DHparams,
100      NULL,                      /* No i2d_DH_PUBKEY */
101      NULL,                      /* No PEM_write_bio_DHPrivateKey */
102      NULL,                      /* No PEM_write_bio_DHPublicKey */
103      (PEM_write_bio_of_void_unprotected *)PEM_write_bio_DHparams,
104      NULL,                      /* No PEM_write_bio_DH_PUBKEY */
105      NULL,                      /* No d2i_DHPrivateKey */
106      NULL,                      /* No d2i_DHPublicKey */
107      (d2i_of_void *)d2i_DHparams,
108      NULL,                      /* No d2i_DH_PUBKEY */
109      NULL,                      /* No PEM_read_bio_DHPrivateKey */
110      NULL,                      /* No PEM_read_bio_DHPublicKey */
111      (PEM_read_bio_of_void *)PEM_read_bio_DHparams,
112      NULL },                    /* No PEM_read_bio_DH_PUBKEY */
113    { "DHX", { "DHX", "type-specific" }, EVP_PKEY_DHX,
114      NULL,                      /* No i2d_DHxPrivateKey */
115      NULL,                      /* No i2d_DHxPublicKey */
116      (i2d_of_void *)i2d_DHxparams,
117      NULL,                      /* No i2d_DHx_PUBKEY */
118      NULL,                      /* No PEM_write_bio_DHxPrivateKey */
119      NULL,                      /* No PEM_write_bio_DHxPublicKey */
120      (PEM_write_bio_of_void_unprotected *)PEM_write_bio_DHxparams,
121      NULL,                      /* No PEM_write_bio_DHx_PUBKEY */
122      NULL,                      /* No d2i_DHxPrivateKey */
123      NULL,                      /* No d2i_DHxPublicKey */
124      (d2i_of_void *)d2i_DHxparams,
125      NULL,                      /* No d2i_DHx_PUBKEY */
126      NULL,                      /* No PEM_read_bio_DHxPrivateKey */
127      NULL,                      /* No PEM_read_bio_DHxPublicKey */
128      NULL,                      /* No PEM_read_bio_DHxparams */
129      NULL },                    /* No PEM_read_bio_DHx_PUBKEY */
130#endif
131#ifndef OPENSSL_NO_DSA
132    { "DSA", { "DSA", "type-specific" }, EVP_PKEY_DSA,
133      (i2d_of_void *)i2d_DSAPrivateKey,
134      (i2d_of_void *)i2d_DSAPublicKey,
135      (i2d_of_void *)i2d_DSAparams,
136      (i2d_of_void *)i2d_DSA_PUBKEY,
137      (PEM_write_bio_of_void_protected *)PEM_write_bio_DSAPrivateKey,
138      NULL,                      /* No PEM_write_bio_DSAPublicKey */
139      (PEM_write_bio_of_void_unprotected *)PEM_write_bio_DSAparams,
140      (PEM_write_bio_of_void_unprotected *)PEM_write_bio_DSA_PUBKEY,
141      (d2i_of_void *)d2i_DSAPrivateKey,
142      (d2i_of_void *)d2i_DSAPublicKey,
143      (d2i_of_void *)d2i_DSAparams,
144      (d2i_of_void *)d2i_DSA_PUBKEY,
145      (PEM_read_bio_of_void *)PEM_read_bio_DSAPrivateKey,
146      NULL,                      /* No PEM_write_bio_DSAPublicKey */
147      (PEM_read_bio_of_void *)PEM_read_bio_DSAparams,
148      (PEM_read_bio_of_void *)PEM_read_bio_DSA_PUBKEY },
149#endif
150#ifndef OPENSSL_NO_EC
151    { "EC", { "EC", "type-specific" }, EVP_PKEY_EC,
152      (i2d_of_void *)i2d_ECPrivateKey,
153      NULL,                      /* No i2d_ECPublicKey */
154      (i2d_of_void *)i2d_ECParameters,
155      (i2d_of_void *)i2d_EC_PUBKEY,
156      (PEM_write_bio_of_void_protected *)PEM_write_bio_ECPrivateKey,
157      NULL,                      /* No PEM_write_bio_ECPublicKey */
158      NULL,                      /* No PEM_write_bio_ECParameters */
159      (PEM_write_bio_of_void_unprotected *)PEM_write_bio_EC_PUBKEY,
160      (d2i_of_void *)d2i_ECPrivateKey,
161      NULL,                      /* No d2i_ECPublicKey */
162      (d2i_of_void *)d2i_ECParameters,
163      (d2i_of_void *)d2i_EC_PUBKEY,
164      (PEM_read_bio_of_void *)PEM_read_bio_ECPrivateKey,
165      NULL,                      /* No PEM_read_bio_ECPublicKey */
166      NULL,                      /* No PEM_read_bio_ECParameters */
167      (PEM_read_bio_of_void *)PEM_read_bio_EC_PUBKEY, },
168#endif
169    { "RSA", { "RSA", "type-specific" }, EVP_PKEY_RSA,
170      (i2d_of_void *)i2d_RSAPrivateKey,
171      (i2d_of_void *)i2d_RSAPublicKey,
172      NULL,                      /* No i2d_RSAparams */
173      (i2d_of_void *)i2d_RSA_PUBKEY,
174      (PEM_write_bio_of_void_protected *)PEM_write_bio_RSAPrivateKey,
175      (PEM_write_bio_of_void_unprotected *)PEM_write_bio_RSAPublicKey,
176      NULL,                      /* No PEM_write_bio_RSAparams */
177      (PEM_write_bio_of_void_unprotected *)PEM_write_bio_RSA_PUBKEY,
178      (d2i_of_void *)d2i_RSAPrivateKey,
179      (d2i_of_void *)d2i_RSAPublicKey,
180      NULL,                      /* No d2i_RSAparams */
181      (d2i_of_void *)d2i_RSA_PUBKEY,
182      (PEM_read_bio_of_void *)PEM_read_bio_RSAPrivateKey,
183      (PEM_read_bio_of_void *)PEM_read_bio_RSAPublicKey,
184      NULL,                      /* No PEM_read_bio_RSAparams */
185      (PEM_read_bio_of_void *)PEM_read_bio_RSA_PUBKEY }
186};
187
188/*
189 * Keys that we're going to test with.  We initialize this with the intended
190 * key types, and generate the keys themselves on program setup.
191 * They must all be downgradable with EVP_PKEY_get0()
192 */
193
194#ifndef OPENSSL_NO_DH
195static const OSSL_PARAM DH_params[] = { OSSL_PARAM_END };
196static const OSSL_PARAM DHX_params[] = { OSSL_PARAM_END };
197#endif
198#ifndef OPENSSL_NO_DSA
199static size_t qbits = 160;  /* PVK only tolerates 160 Q bits */
200static size_t pbits = 1024; /* With 160 Q bits, we MUST use 1024 P bits */
201static const OSSL_PARAM DSA_params[] = {
202    OSSL_PARAM_size_t("pbits", &pbits),
203    OSSL_PARAM_size_t("qbits", &qbits),
204    OSSL_PARAM_END
205};
206#endif
207#ifndef OPENSSL_NO_EC
208static char groupname[] = "prime256v1";
209static const OSSL_PARAM EC_params[] = {
210    OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1),
211    OSSL_PARAM_END
212};
213#endif
214
215static struct key_st {
216    const char *keytype;
217    int evp_type;
218    /* non-NULL if a template EVP_PKEY must be generated first */
219    const OSSL_PARAM *template_params;
220
221    EVP_PKEY *key;
222} keys[] = {
223#ifndef OPENSSL_NO_DH
224    { "DH", EVP_PKEY_DH, DH_params, NULL },
225    { "DHX", EVP_PKEY_DHX, DHX_params, NULL },
226#endif
227#ifndef OPENSSL_NO_DSA
228    { "DSA", EVP_PKEY_DSA, DSA_params, NULL },
229#endif
230#ifndef OPENSSL_NO_EC
231    { "EC", EVP_PKEY_EC, EC_params, NULL },
232#endif
233#ifndef OPENSSL_NO_DEPRECATED_3_0
234    { "RSA", EVP_PKEY_RSA, NULL, NULL },
235#endif
236};
237
238static EVP_PKEY *make_key(const char *type,
239                          const OSSL_PARAM *gen_template_params)
240{
241    EVP_PKEY *template = NULL;
242    EVP_PKEY *pkey = NULL;
243    EVP_PKEY_CTX *ctx = NULL;
244    OSSL_PARAM *gen_template_params_noconst =
245        (OSSL_PARAM *)gen_template_params;
246
247    if (gen_template_params != NULL
248        && ((ctx = EVP_PKEY_CTX_new_from_name(NULL, type, NULL)) == NULL
249            || EVP_PKEY_paramgen_init(ctx) <= 0
250            || (gen_template_params[0].key != NULL
251                && EVP_PKEY_CTX_set_params(ctx, gen_template_params_noconst) <= 0)
252            || EVP_PKEY_generate(ctx, &template) <= 0))
253        goto end;
254    EVP_PKEY_CTX_free(ctx);
255
256    /*
257     * No real need to check the errors other than for the cascade
258     * effect.  |pkey| will simply remain NULL if something goes wrong.
259     */
260    ctx =
261        template != NULL
262        ? EVP_PKEY_CTX_new(template, NULL)
263        : EVP_PKEY_CTX_new_from_name(NULL, type, NULL);
264
265    (void)(ctx != NULL
266           && EVP_PKEY_keygen_init(ctx) > 0
267           && EVP_PKEY_keygen(ctx, &pkey) > 0);
268
269 end:
270    EVP_PKEY_free(template);
271    EVP_PKEY_CTX_free(ctx);
272    return pkey;
273}
274
275static struct key_st *lookup_key(const char *type)
276{
277    size_t i;
278
279    for (i = 0; i < OSSL_NELEM(keys); i++) {
280        if (strcmp(keys[i].keytype, type) == 0)
281            return &keys[i];
282    }
283    return NULL;
284}
285
286static int test_membio_str_eq(BIO *bio_provided, BIO *bio_legacy)
287{
288    char *str_provided = NULL, *str_legacy = NULL;
289    long len_provided = BIO_get_mem_data(bio_provided, &str_provided);
290    long len_legacy = BIO_get_mem_data(bio_legacy, &str_legacy);
291
292    return TEST_long_ge(len_legacy, 0)
293           && TEST_long_ge(len_provided, 0)
294           && TEST_strn2_eq(str_provided, len_provided,
295                            str_legacy, len_legacy);
296}
297
298static int test_protected_PEM(const char *keytype, int evp_type,
299                              const void *legacy_key,
300                              PEM_write_bio_of_void_protected *pem_write_bio,
301                              PEM_read_bio_of_void *pem_read_bio,
302                              EVP_PKEY_eq_fn *evp_pkey_eq,
303                              EVP_PKEY_print_fn *evp_pkey_print,
304                              EVP_PKEY *provided_pkey, int selection,
305                              const char *structure)
306{
307    int ok = 0;
308    BIO *membio_legacy = NULL;
309    BIO *membio_provided = NULL;
310    OSSL_ENCODER_CTX *ectx = NULL;
311    OSSL_DECODER_CTX *dctx = NULL;
312    void *decoded_legacy_key = NULL;
313    EVP_PKEY *decoded_legacy_pkey = NULL;
314    EVP_PKEY *decoded_provided_pkey = NULL;
315
316    /* Set up the BIOs, so we have them */
317    if (!TEST_ptr(membio_legacy = BIO_new(BIO_s_mem()))
318        || !TEST_ptr(membio_provided = BIO_new(BIO_s_mem())))
319        goto end;
320
321    if (!TEST_ptr(ectx =
322                  OSSL_ENCODER_CTX_new_for_pkey(provided_pkey, selection,
323                                                "PEM", structure,
324                                                NULL))
325        || !TEST_true(OSSL_ENCODER_to_bio(ectx, membio_provided))
326        || !TEST_true(pem_write_bio(membio_legacy, legacy_key,
327                                   NULL, NULL, 0, NULL, NULL))
328        || !test_membio_str_eq(membio_provided, membio_legacy))
329        goto end;
330
331    if (pem_read_bio != NULL) {
332        /* Now try decoding the results and compare the resulting keys */
333
334        if (!TEST_ptr(decoded_legacy_pkey = EVP_PKEY_new())
335            || !TEST_ptr(dctx =
336                         OSSL_DECODER_CTX_new_for_pkey(&decoded_provided_pkey,
337                                                       "PEM", structure,
338                                                       keytype, selection,
339                                                       NULL, NULL))
340            || !TEST_true(OSSL_DECODER_from_bio(dctx, membio_provided))
341            || !TEST_ptr(decoded_legacy_key =
342                         pem_read_bio(membio_legacy, NULL, NULL, NULL))
343            || !TEST_true(EVP_PKEY_assign(decoded_legacy_pkey, evp_type,
344                                          decoded_legacy_key)))
345            goto end;
346
347        if (!TEST_int_gt(evp_pkey_eq(decoded_provided_pkey,
348                                     decoded_legacy_pkey), 0)) {
349            TEST_info("decoded_provided_pkey:");
350            evp_pkey_print(bio_out, decoded_provided_pkey, 0, NULL);
351            TEST_info("decoded_legacy_pkey:");
352            evp_pkey_print(bio_out, decoded_legacy_pkey, 0, NULL);
353        }
354    }
355    ok = 1;
356 end:
357    EVP_PKEY_free(decoded_legacy_pkey);
358    EVP_PKEY_free(decoded_provided_pkey);
359    OSSL_ENCODER_CTX_free(ectx);
360    OSSL_DECODER_CTX_free(dctx);
361    BIO_free(membio_provided);
362    BIO_free(membio_legacy);
363    return ok;
364}
365
366static int test_unprotected_PEM(const char *keytype, int evp_type,
367                                const void *legacy_key,
368                                PEM_write_bio_of_void_unprotected *pem_write_bio,
369                                PEM_read_bio_of_void *pem_read_bio,
370                                EVP_PKEY_eq_fn *evp_pkey_eq,
371                                EVP_PKEY_print_fn *evp_pkey_print,
372                                EVP_PKEY *provided_pkey, int selection,
373                                const char *structure)
374{
375    int ok = 0;
376    BIO *membio_legacy = NULL;
377    BIO *membio_provided = NULL;
378    OSSL_ENCODER_CTX *ectx = NULL;
379    OSSL_DECODER_CTX *dctx = NULL;
380    void *decoded_legacy_key = NULL;
381    EVP_PKEY *decoded_legacy_pkey = NULL;
382    EVP_PKEY *decoded_provided_pkey = NULL;
383
384    /* Set up the BIOs, so we have them */
385    if (!TEST_ptr(membio_legacy = BIO_new(BIO_s_mem()))
386        || !TEST_ptr(membio_provided = BIO_new(BIO_s_mem())))
387        goto end;
388
389    if (!TEST_ptr(ectx =
390                  OSSL_ENCODER_CTX_new_for_pkey(provided_pkey, selection,
391                                                "PEM", structure,
392                                                NULL))
393        || !TEST_true(OSSL_ENCODER_to_bio(ectx, membio_provided))
394        || !TEST_true(pem_write_bio(membio_legacy, legacy_key))
395        || !test_membio_str_eq(membio_provided, membio_legacy))
396        goto end;
397
398    if (pem_read_bio != NULL) {
399        /* Now try decoding the results and compare the resulting keys */
400
401        if (!TEST_ptr(decoded_legacy_pkey = EVP_PKEY_new())
402            || !TEST_ptr(dctx =
403                         OSSL_DECODER_CTX_new_for_pkey(&decoded_provided_pkey,
404                                                       "PEM", structure,
405                                                       keytype, selection,
406                                                       NULL, NULL))
407            || !TEST_true(OSSL_DECODER_from_bio(dctx, membio_provided))
408            || !TEST_ptr(decoded_legacy_key =
409                         pem_read_bio(membio_legacy, NULL, NULL, NULL))
410            || !TEST_true(EVP_PKEY_assign(decoded_legacy_pkey, evp_type,
411                                          decoded_legacy_key)))
412            goto end;
413
414        if (!TEST_int_gt(evp_pkey_eq(decoded_provided_pkey,
415                                     decoded_legacy_pkey), 0)) {
416            TEST_info("decoded_provided_pkey:");
417            evp_pkey_print(bio_out, decoded_provided_pkey, 0, NULL);
418            TEST_info("decoded_legacy_pkey:");
419            evp_pkey_print(bio_out, decoded_legacy_pkey, 0, NULL);
420        }
421    }
422    ok = 1;
423 end:
424    EVP_PKEY_free(decoded_legacy_pkey);
425    EVP_PKEY_free(decoded_provided_pkey);
426    OSSL_ENCODER_CTX_free(ectx);
427    OSSL_DECODER_CTX_free(dctx);
428    BIO_free(membio_provided);
429    BIO_free(membio_legacy);
430    return ok;
431}
432
433static int test_DER(const char *keytype, int evp_type,
434                    const void *legacy_key, i2d_of_void *i2d, d2i_of_void *d2i,
435                    EVP_PKEY_eq_fn *evp_pkey_eq,
436                    EVP_PKEY_print_fn *evp_pkey_print,
437                    EVP_PKEY *provided_pkey, int selection,
438                    const char *structure)
439{
440    int ok = 0;
441    unsigned char *der_legacy = NULL;
442    const unsigned char *pder_legacy = NULL;
443    size_t der_legacy_len = 0;
444    unsigned char *der_provided = NULL;
445    const unsigned char *pder_provided = NULL;
446    size_t der_provided_len = 0;
447    size_t tmp_size;
448    OSSL_ENCODER_CTX *ectx = NULL;
449    OSSL_DECODER_CTX *dctx = NULL;
450    void *decoded_legacy_key = NULL;
451    EVP_PKEY *decoded_legacy_pkey = NULL;
452    EVP_PKEY *decoded_provided_pkey = NULL;
453
454    if (!TEST_ptr(ectx =
455                 OSSL_ENCODER_CTX_new_for_pkey(provided_pkey, selection,
456                                               "DER", structure,
457                                               NULL))
458        || !TEST_true(OSSL_ENCODER_to_data(ectx,
459                                          &der_provided, &der_provided_len))
460        || !TEST_size_t_gt(der_legacy_len = i2d(legacy_key, &der_legacy), 0)
461        || !TEST_mem_eq(der_provided, der_provided_len,
462                        der_legacy, der_legacy_len))
463        goto end;
464
465    if (d2i != NULL) {
466        /* Now try decoding the results and compare the resulting keys */
467
468        if (!TEST_ptr(decoded_legacy_pkey = EVP_PKEY_new())
469            || !TEST_ptr(dctx =
470                         OSSL_DECODER_CTX_new_for_pkey(&decoded_provided_pkey,
471                                                       "DER", structure,
472                                                       keytype, selection,
473                                                       NULL, NULL))
474            || !TEST_true((pder_provided = der_provided,
475                           tmp_size = der_provided_len,
476                           OSSL_DECODER_from_data(dctx, &pder_provided,
477                                                  &tmp_size)))
478            || !TEST_ptr((pder_legacy = der_legacy,
479                          decoded_legacy_key = d2i(NULL, &pder_legacy,
480                                                   (long)der_legacy_len)))
481            || !TEST_true(EVP_PKEY_assign(decoded_legacy_pkey, evp_type,
482                                          decoded_legacy_key)))
483            goto end;
484
485        if (!TEST_int_gt(evp_pkey_eq(decoded_provided_pkey,
486                                     decoded_legacy_pkey), 0)) {
487            TEST_info("decoded_provided_pkey:");
488            evp_pkey_print(bio_out, decoded_provided_pkey, 0, NULL);
489            TEST_info("decoded_legacy_pkey:");
490            evp_pkey_print(bio_out, decoded_legacy_pkey, 0, NULL);
491        }
492    }
493    ok = 1;
494 end:
495    EVP_PKEY_free(decoded_legacy_pkey);
496    EVP_PKEY_free(decoded_provided_pkey);
497    OSSL_ENCODER_CTX_free(ectx);
498    OSSL_DECODER_CTX_free(dctx);
499    OPENSSL_free(der_provided);
500    OPENSSL_free(der_legacy);
501    return ok;
502}
503
504static int test_key(int idx)
505{
506    struct test_stanza_st *test_stanza = NULL;
507    struct key_st *key = NULL;
508    int ok = 0;
509    size_t i;
510    EVP_PKEY *pkey = NULL, *downgraded_pkey = NULL;
511    const void *legacy_obj = NULL;
512
513    /* Get the test data */
514    if (!TEST_ptr(test_stanza = &test_stanzas[idx])
515        || !TEST_ptr(key = lookup_key(test_stanza->keytype)))
516        goto end;
517
518    /* Set up the keys */
519    if (!TEST_ptr(pkey = key->key)
520        || !TEST_true(evp_pkey_copy_downgraded(&downgraded_pkey, pkey))
521        || !TEST_ptr(downgraded_pkey)
522        || !TEST_int_eq(EVP_PKEY_get_id(downgraded_pkey), key->evp_type)
523        || !TEST_ptr(legacy_obj = EVP_PKEY_get0(downgraded_pkey)))
524        goto end;
525
526    ok = 1;
527
528    /* Test PrivateKey to PEM */
529    if (test_stanza->pem_write_bio_PrivateKey != NULL) {
530        int selection = OSSL_KEYMGMT_SELECT_ALL;
531
532        for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
533            const char *structure = test_stanza->structure[i];
534
535            TEST_info("Test OSSL_ENCODER against PEM_write_bio_{TYPE}PrivateKey for %s, %s",
536                      test_stanza->keytype, structure);
537            if (!test_protected_PEM(key->keytype, key->evp_type, legacy_obj,
538                                    test_stanza->pem_write_bio_PrivateKey,
539                                    test_stanza->pem_read_bio_PrivateKey,
540                                    EVP_PKEY_eq, EVP_PKEY_print_private,
541                                    pkey, selection, structure))
542                ok = 0;
543        }
544    }
545
546    /* Test PublicKey to PEM */
547    if (test_stanza->pem_write_bio_PublicKey != NULL) {
548        int selection =
549            OSSL_KEYMGMT_SELECT_PUBLIC_KEY
550            | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
551
552        for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
553            const char *structure = test_stanza->structure[i];
554
555            TEST_info("Test OSSL_ENCODER against PEM_write_bio_{TYPE}PublicKey for %s, %s",
556                      test_stanza->keytype, structure);
557            if (!test_unprotected_PEM(key->keytype, key->evp_type, legacy_obj,
558                                      test_stanza->pem_write_bio_PublicKey,
559                                      test_stanza->pem_read_bio_PublicKey,
560                                      EVP_PKEY_eq, EVP_PKEY_print_public,
561                                      pkey, selection, structure))
562                ok = 0;
563        }
564    }
565
566    /* Test params to PEM */
567    if (test_stanza->pem_write_bio_params != NULL) {
568        int selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
569
570        for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
571            const char *structure = test_stanza->structure[i];
572
573            TEST_info("Test OSSL_ENCODER against PEM_write_bio_{TYPE}params for %s, %s",
574                      test_stanza->keytype, structure);
575            if (!test_unprotected_PEM(key->keytype, key->evp_type, legacy_obj,
576                                      test_stanza->pem_write_bio_params,
577                                      test_stanza->pem_read_bio_params,
578                                      EVP_PKEY_parameters_eq,
579                                      EVP_PKEY_print_params,
580                                      pkey, selection, structure))
581                ok = 0;
582        }
583    }
584
585    /* Test PUBKEY to PEM */
586    if (test_stanza->pem_write_bio_PUBKEY != NULL) {
587        int selection =
588            OSSL_KEYMGMT_SELECT_PUBLIC_KEY
589            | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
590        const char *structure = "SubjectPublicKeyInfo";
591
592        TEST_info("Test OSSL_ENCODER against PEM_write_bio_{TYPE}_PUBKEY for %s, %s",
593                  test_stanza->keytype, structure);
594        if (!test_unprotected_PEM(key->keytype, key->evp_type, legacy_obj,
595                                  test_stanza->pem_write_bio_PUBKEY,
596                                  test_stanza->pem_read_bio_PUBKEY,
597                                  EVP_PKEY_eq, EVP_PKEY_print_public,
598                                  pkey, selection, structure))
599            ok = 0;
600    }
601
602
603    /* Test PrivateKey to DER */
604    if (test_stanza->i2d_PrivateKey != NULL) {
605        int selection = OSSL_KEYMGMT_SELECT_ALL;
606
607        for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
608            const char *structure = test_stanza->structure[i];
609
610            TEST_info("Test OSSL_ENCODER against i2d_{TYPE}PrivateKey for %s, %s",
611                      test_stanza->keytype, structure);
612            if (!test_DER(key->keytype, key->evp_type, legacy_obj,
613                          test_stanza->i2d_PrivateKey,
614                          test_stanza->d2i_PrivateKey,
615                          EVP_PKEY_eq, EVP_PKEY_print_private,
616                          pkey, selection, structure))
617                ok = 0;
618        }
619    }
620
621    /* Test PublicKey to DER */
622    if (test_stanza->i2d_PublicKey != NULL) {
623        int selection =
624            OSSL_KEYMGMT_SELECT_PUBLIC_KEY
625            | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
626
627        for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
628            const char *structure = test_stanza->structure[i];
629
630            TEST_info("Test OSSL_ENCODER against i2d_{TYPE}PublicKey for %s, %s",
631                      test_stanza->keytype, structure);
632            if (!test_DER(key->keytype, key->evp_type, legacy_obj,
633                          test_stanza->i2d_PublicKey,
634                          test_stanza->d2i_PublicKey,
635                          EVP_PKEY_eq, EVP_PKEY_print_public,
636                          pkey, selection, structure))
637                ok = 0;
638        }
639    }
640
641    /* Test params to DER */
642    if (test_stanza->i2d_params != NULL) {
643        int selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
644
645        for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
646            const char *structure = test_stanza->structure[i];
647
648            TEST_info("Test OSSL_ENCODER against i2d_{TYPE}params for %s, %s",
649                      test_stanza->keytype, structure);
650            if (!test_DER(key->keytype, key->evp_type, legacy_obj,
651                          test_stanza->i2d_params, test_stanza->d2i_params,
652                          EVP_PKEY_parameters_eq, EVP_PKEY_print_params,
653                          pkey, selection, structure))
654                ok = 0;
655        }
656    }
657
658    /* Test PUBKEY to DER */
659    if (test_stanza->i2d_PUBKEY != NULL) {
660        int selection =
661            OSSL_KEYMGMT_SELECT_PUBLIC_KEY
662            | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
663        const char *structure = "SubjectPublicKeyInfo";
664
665        TEST_info("Test OSSL_ENCODER against i2d_{TYPE}_PUBKEY for %s, %s",
666                  test_stanza->keytype, structure);
667        if (!test_DER(key->keytype, key->evp_type, legacy_obj,
668                      test_stanza->i2d_PUBKEY, test_stanza->d2i_PUBKEY,
669                      EVP_PKEY_eq, EVP_PKEY_print_public,
670                      pkey, selection, structure))
671            ok = 0;
672    }
673 end:
674    EVP_PKEY_free(downgraded_pkey);
675    return ok;
676}
677
678#define USAGE "rsa-key.pem dh-key.pem\n"
679OPT_TEST_DECLARE_USAGE(USAGE)
680
681int setup_tests(void)
682{
683    size_t i;
684
685    if (!test_skip_common_options()) {
686        TEST_error("Error parsing test options\n");
687        return 0;
688    }
689    if (test_get_argument_count() != 2) {
690        TEST_error("usage: endecoder_legacy_test %s", USAGE);
691        return 0;
692    }
693
694    TEST_info("Generating keys...");
695
696    for (i = 0; i < OSSL_NELEM(keys); i++) {
697#ifndef OPENSSL_NO_DH
698        if (strcmp(keys[i].keytype, "DH") == 0) {
699            if (!TEST_ptr(keys[i].key =
700                          load_pkey_pem(test_get_argument(1), NULL)))
701                return  0;
702            continue;
703        }
704#endif
705#ifndef OPENSSL_NO_DEPRECATED_3_0
706        if (strcmp(keys[i].keytype, "RSA") == 0) {
707            if (!TEST_ptr(keys[i].key =
708                          load_pkey_pem(test_get_argument(0), NULL)))
709                return  0;
710            continue;
711        }
712#endif
713        TEST_info("Generating %s key...", keys[i].keytype);
714        if (!TEST_ptr(keys[i].key =
715                      make_key(keys[i].keytype, keys[i].template_params)))
716            return 0;
717    }
718
719    TEST_info("Generating keys done");
720
721    ADD_ALL_TESTS(test_key, OSSL_NELEM(test_stanzas));
722    return 1;
723}
724
725void cleanup_tests(void)
726{
727    size_t i;
728
729    for (i = 0; i < OSSL_NELEM(keys); i++)
730        EVP_PKEY_free(keys[i].key);
731}
732