Home | History | Annotate | Line # | Download | only in test
      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 
     61 typedef 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);
     65 typedef int PEM_write_bio_of_void_unprotected(BIO *out, const void *obj);
     66 typedef void *PEM_read_bio_of_void(BIO *out, void **obj,
     67     pem_password_cb *cb, void *u);
     68 typedef int EVP_PKEY_print_fn(BIO *out, const EVP_PKEY *pkey,
     69     int indent, ASN1_PCTX *pctx);
     70 typedef int EVP_PKEY_eq_fn(const EVP_PKEY *a, const EVP_PKEY *b);
     71 
     72 static 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     {
    152         "EC",
    153         { "EC", "type-specific" },
    154         EVP_PKEY_EC,
    155         (i2d_of_void *)i2d_ECPrivateKey,
    156         NULL, /* No i2d_ECPublicKey */
    157         (i2d_of_void *)i2d_ECParameters,
    158         (i2d_of_void *)i2d_EC_PUBKEY,
    159         (PEM_write_bio_of_void_protected *)PEM_write_bio_ECPrivateKey,
    160         NULL, /* No PEM_write_bio_ECPublicKey */
    161         NULL, /* No PEM_write_bio_ECParameters */
    162         (PEM_write_bio_of_void_unprotected *)PEM_write_bio_EC_PUBKEY,
    163         (d2i_of_void *)d2i_ECPrivateKey,
    164         NULL, /* No d2i_ECPublicKey */
    165         (d2i_of_void *)d2i_ECParameters,
    166         (d2i_of_void *)d2i_EC_PUBKEY,
    167         (PEM_read_bio_of_void *)PEM_read_bio_ECPrivateKey,
    168         NULL, /* No PEM_read_bio_ECPublicKey */
    169         NULL, /* No PEM_read_bio_ECParameters */
    170         (PEM_read_bio_of_void *)PEM_read_bio_EC_PUBKEY,
    171     },
    172 #endif
    173     { "RSA", { "RSA", "type-specific" }, EVP_PKEY_RSA,
    174         (i2d_of_void *)i2d_RSAPrivateKey,
    175         (i2d_of_void *)i2d_RSAPublicKey,
    176         NULL, /* No i2d_RSAparams */
    177         (i2d_of_void *)i2d_RSA_PUBKEY,
    178         (PEM_write_bio_of_void_protected *)PEM_write_bio_RSAPrivateKey,
    179         (PEM_write_bio_of_void_unprotected *)PEM_write_bio_RSAPublicKey,
    180         NULL, /* No PEM_write_bio_RSAparams */
    181         (PEM_write_bio_of_void_unprotected *)PEM_write_bio_RSA_PUBKEY,
    182         (d2i_of_void *)d2i_RSAPrivateKey,
    183         (d2i_of_void *)d2i_RSAPublicKey,
    184         NULL, /* No d2i_RSAparams */
    185         (d2i_of_void *)d2i_RSA_PUBKEY,
    186         (PEM_read_bio_of_void *)PEM_read_bio_RSAPrivateKey,
    187         (PEM_read_bio_of_void *)PEM_read_bio_RSAPublicKey,
    188         NULL, /* No PEM_read_bio_RSAparams */
    189         (PEM_read_bio_of_void *)PEM_read_bio_RSA_PUBKEY }
    190 };
    191 
    192 /*
    193  * Keys that we're going to test with.  We initialize this with the intended
    194  * key types, and generate the keys themselves on program setup.
    195  * They must all be downgradable with EVP_PKEY_get0()
    196  */
    197 
    198 #ifndef OPENSSL_NO_DH
    199 static const OSSL_PARAM DH_params[] = { OSSL_PARAM_END };
    200 static const OSSL_PARAM DHX_params[] = { OSSL_PARAM_END };
    201 #endif
    202 #ifndef OPENSSL_NO_DSA
    203 static size_t qbits = 160; /* PVK only tolerates 160 Q bits */
    204 static size_t pbits = 1024; /* With 160 Q bits, we MUST use 1024 P bits */
    205 static const OSSL_PARAM DSA_params[] = {
    206     OSSL_PARAM_size_t("pbits", &pbits),
    207     OSSL_PARAM_size_t("qbits", &qbits),
    208     OSSL_PARAM_END
    209 };
    210 #endif
    211 #ifndef OPENSSL_NO_EC
    212 static char groupname[] = "prime256v1";
    213 static const OSSL_PARAM EC_params[] = {
    214     OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1),
    215     OSSL_PARAM_END
    216 };
    217 #endif
    218 
    219 static struct key_st {
    220     const char *keytype;
    221     int evp_type;
    222     /* non-NULL if a template EVP_PKEY must be generated first */
    223     const OSSL_PARAM *template_params;
    224 
    225     EVP_PKEY *key;
    226 } keys[] = {
    227 #ifndef OPENSSL_NO_DH
    228     { "DH", EVP_PKEY_DH, DH_params, NULL },
    229     { "DHX", EVP_PKEY_DHX, DHX_params, NULL },
    230 #endif
    231 #ifndef OPENSSL_NO_DSA
    232     { "DSA", EVP_PKEY_DSA, DSA_params, NULL },
    233 #endif
    234 #ifndef OPENSSL_NO_EC
    235     { "EC", EVP_PKEY_EC, EC_params, NULL },
    236 #endif
    237 #ifndef OPENSSL_NO_DEPRECATED_3_0
    238     { "RSA", EVP_PKEY_RSA, NULL, NULL },
    239 #endif
    240 };
    241 
    242 static EVP_PKEY *make_key(const char *type,
    243     const OSSL_PARAM *gen_template_params)
    244 {
    245     EVP_PKEY *template = NULL;
    246     EVP_PKEY *pkey = NULL;
    247     EVP_PKEY_CTX *ctx = NULL;
    248     OSSL_PARAM *gen_template_params_noconst = (OSSL_PARAM *)gen_template_params;
    249 
    250     if (gen_template_params != NULL
    251         && ((ctx = EVP_PKEY_CTX_new_from_name(NULL, type, NULL)) == NULL
    252             || EVP_PKEY_paramgen_init(ctx) <= 0
    253             || (gen_template_params[0].key != NULL
    254                 && EVP_PKEY_CTX_set_params(ctx, gen_template_params_noconst) <= 0)
    255             || EVP_PKEY_generate(ctx, &template) <= 0))
    256         goto end;
    257     EVP_PKEY_CTX_free(ctx);
    258 
    259     /*
    260      * No real need to check the errors other than for the cascade
    261      * effect.  |pkey| will simply remain NULL if something goes wrong.
    262      */
    263     ctx = template != NULL
    264         ? EVP_PKEY_CTX_new(template, NULL)
    265         : EVP_PKEY_CTX_new_from_name(NULL, type, NULL);
    266 
    267     (void)(ctx != NULL
    268         && EVP_PKEY_keygen_init(ctx) > 0
    269         && EVP_PKEY_keygen(ctx, &pkey) > 0);
    270 
    271 end:
    272     EVP_PKEY_free(template);
    273     EVP_PKEY_CTX_free(ctx);
    274     return pkey;
    275 }
    276 
    277 static struct key_st *lookup_key(const char *type)
    278 {
    279     size_t i;
    280 
    281     for (i = 0; i < OSSL_NELEM(keys); i++) {
    282         if (strcmp(keys[i].keytype, type) == 0)
    283             return &keys[i];
    284     }
    285     return NULL;
    286 }
    287 
    288 static int test_membio_str_eq(BIO *bio_provided, BIO *bio_legacy)
    289 {
    290     char *str_provided = NULL, *str_legacy = NULL;
    291     long len_provided = BIO_get_mem_data(bio_provided, &str_provided);
    292     long len_legacy = BIO_get_mem_data(bio_legacy, &str_legacy);
    293 
    294     return TEST_long_ge(len_legacy, 0)
    295         && TEST_long_ge(len_provided, 0)
    296         && TEST_strn2_eq(str_provided, len_provided,
    297             str_legacy, len_legacy);
    298 }
    299 
    300 static int test_protected_PEM(const char *keytype, int evp_type,
    301     const void *legacy_key,
    302     PEM_write_bio_of_void_protected *pem_write_bio,
    303     PEM_read_bio_of_void *pem_read_bio,
    304     EVP_PKEY_eq_fn *evp_pkey_eq,
    305     EVP_PKEY_print_fn *evp_pkey_print,
    306     EVP_PKEY *provided_pkey, int selection,
    307     const char *structure)
    308 {
    309     int ok = 0;
    310     BIO *membio_legacy = NULL;
    311     BIO *membio_provided = NULL;
    312     OSSL_ENCODER_CTX *ectx = NULL;
    313     OSSL_DECODER_CTX *dctx = NULL;
    314     void *decoded_legacy_key = NULL;
    315     EVP_PKEY *decoded_legacy_pkey = NULL;
    316     EVP_PKEY *decoded_provided_pkey = NULL;
    317 
    318     /* Set up the BIOs, so we have them */
    319     if (!TEST_ptr(membio_legacy = BIO_new(BIO_s_mem()))
    320         || !TEST_ptr(membio_provided = BIO_new(BIO_s_mem())))
    321         goto end;
    322 
    323     if (!TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(provided_pkey, selection,
    324                       "PEM", structure,
    325                       NULL))
    326         || !TEST_true(OSSL_ENCODER_to_bio(ectx, membio_provided))
    327         || !TEST_true(pem_write_bio(membio_legacy, legacy_key,
    328             NULL, NULL, 0, NULL, NULL))
    329         || !test_membio_str_eq(membio_provided, membio_legacy))
    330         goto end;
    331 
    332     if (pem_read_bio != NULL) {
    333         /* Now try decoding the results and compare the resulting keys */
    334 
    335         if (!TEST_ptr(decoded_legacy_pkey = EVP_PKEY_new())
    336             || !TEST_ptr(dctx = 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 = pem_read_bio(membio_legacy, NULL, NULL, NULL))
    342             || !TEST_true(EVP_PKEY_assign(decoded_legacy_pkey, evp_type,
    343                 decoded_legacy_key)))
    344             goto end;
    345 
    346         if (!TEST_int_gt(evp_pkey_eq(decoded_provided_pkey,
    347                              decoded_legacy_pkey),
    348                 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 
    366 static 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 = OSSL_ENCODER_CTX_new_for_pkey(provided_pkey, selection,
    390                       "PEM", structure,
    391                       NULL))
    392         || !TEST_true(OSSL_ENCODER_to_bio(ectx, membio_provided))
    393         || !TEST_true(pem_write_bio(membio_legacy, legacy_key))
    394         || !test_membio_str_eq(membio_provided, membio_legacy))
    395         goto end;
    396 
    397     if (pem_read_bio != NULL) {
    398         /* Now try decoding the results and compare the resulting keys */
    399 
    400         if (!TEST_ptr(decoded_legacy_pkey = EVP_PKEY_new())
    401             || !TEST_ptr(dctx = OSSL_DECODER_CTX_new_for_pkey(&decoded_provided_pkey,
    402                              "PEM", structure,
    403                              keytype, selection,
    404                              NULL, NULL))
    405             || !TEST_true(OSSL_DECODER_from_bio(dctx, membio_provided))
    406             || !TEST_ptr(decoded_legacy_key = pem_read_bio(membio_legacy, NULL, NULL, NULL))
    407             || !TEST_true(EVP_PKEY_assign(decoded_legacy_pkey, evp_type,
    408                 decoded_legacy_key)))
    409             goto end;
    410 
    411         if (!TEST_int_gt(evp_pkey_eq(decoded_provided_pkey,
    412                              decoded_legacy_pkey),
    413                 0)) {
    414             TEST_info("decoded_provided_pkey:");
    415             evp_pkey_print(bio_out, decoded_provided_pkey, 0, NULL);
    416             TEST_info("decoded_legacy_pkey:");
    417             evp_pkey_print(bio_out, decoded_legacy_pkey, 0, NULL);
    418         }
    419     }
    420     ok = 1;
    421 end:
    422     EVP_PKEY_free(decoded_legacy_pkey);
    423     EVP_PKEY_free(decoded_provided_pkey);
    424     OSSL_ENCODER_CTX_free(ectx);
    425     OSSL_DECODER_CTX_free(dctx);
    426     BIO_free(membio_provided);
    427     BIO_free(membio_legacy);
    428     return ok;
    429 }
    430 
    431 static int test_DER(const char *keytype, int evp_type,
    432     const void *legacy_key, i2d_of_void *i2d, d2i_of_void *d2i,
    433     EVP_PKEY_eq_fn *evp_pkey_eq,
    434     EVP_PKEY_print_fn *evp_pkey_print,
    435     EVP_PKEY *provided_pkey, int selection,
    436     const char *structure)
    437 {
    438     int ok = 0;
    439     unsigned char *der_legacy = NULL;
    440     const unsigned char *pder_legacy = NULL;
    441     size_t der_legacy_len = 0;
    442     unsigned char *der_provided = NULL;
    443     const unsigned char *pder_provided = NULL;
    444     size_t der_provided_len = 0;
    445     size_t tmp_size;
    446     OSSL_ENCODER_CTX *ectx = NULL;
    447     OSSL_DECODER_CTX *dctx = NULL;
    448     void *decoded_legacy_key = NULL;
    449     EVP_PKEY *decoded_legacy_pkey = NULL;
    450     EVP_PKEY *decoded_provided_pkey = NULL;
    451 
    452     if (!TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(provided_pkey, selection,
    453                       "DER", structure,
    454                       NULL))
    455         || !TEST_true(OSSL_ENCODER_to_data(ectx,
    456             &der_provided, &der_provided_len))
    457         || !TEST_size_t_gt(der_legacy_len = i2d(legacy_key, &der_legacy), 0)
    458         || !TEST_mem_eq(der_provided, der_provided_len,
    459             der_legacy, der_legacy_len))
    460         goto end;
    461 
    462     if (d2i != NULL) {
    463         /* Now try decoding the results and compare the resulting keys */
    464 
    465         if (!TEST_ptr(decoded_legacy_pkey = EVP_PKEY_new())
    466             || !TEST_ptr(dctx = OSSL_DECODER_CTX_new_for_pkey(&decoded_provided_pkey,
    467                              "DER", structure,
    468                              keytype, selection,
    469                              NULL, NULL))
    470             || !TEST_true((pder_provided = der_provided,
    471                 tmp_size = der_provided_len,
    472                 OSSL_DECODER_from_data(dctx, &pder_provided,
    473                     &tmp_size)))
    474             || !TEST_ptr((pder_legacy = der_legacy,
    475                 decoded_legacy_key = d2i(NULL, &pder_legacy,
    476                     (long)der_legacy_len)))
    477             || !TEST_true(EVP_PKEY_assign(decoded_legacy_pkey, evp_type,
    478                 decoded_legacy_key)))
    479             goto end;
    480 
    481         if (!TEST_int_gt(evp_pkey_eq(decoded_provided_pkey,
    482                              decoded_legacy_pkey),
    483                 0)) {
    484             TEST_info("decoded_provided_pkey:");
    485             evp_pkey_print(bio_out, decoded_provided_pkey, 0, NULL);
    486             TEST_info("decoded_legacy_pkey:");
    487             evp_pkey_print(bio_out, decoded_legacy_pkey, 0, NULL);
    488         }
    489     }
    490     ok = 1;
    491 end:
    492     EVP_PKEY_free(decoded_legacy_pkey);
    493     EVP_PKEY_free(decoded_provided_pkey);
    494     OSSL_ENCODER_CTX_free(ectx);
    495     OSSL_DECODER_CTX_free(dctx);
    496     OPENSSL_free(der_provided);
    497     OPENSSL_free(der_legacy);
    498     return ok;
    499 }
    500 
    501 static int test_key(int idx)
    502 {
    503     struct test_stanza_st *test_stanza = NULL;
    504     struct key_st *key = NULL;
    505     int ok = 0;
    506     size_t i;
    507     EVP_PKEY *pkey = NULL, *downgraded_pkey = NULL;
    508     const void *legacy_obj = NULL;
    509 
    510     /* Get the test data */
    511     if (!TEST_ptr(test_stanza = &test_stanzas[idx])
    512         || !TEST_ptr(key = lookup_key(test_stanza->keytype)))
    513         goto end;
    514 
    515     /* Set up the keys */
    516     if (!TEST_ptr(pkey = key->key)
    517         || !TEST_true(evp_pkey_copy_downgraded(&downgraded_pkey, pkey))
    518         || !TEST_ptr(downgraded_pkey)
    519         || !TEST_int_eq(EVP_PKEY_get_id(downgraded_pkey), key->evp_type)
    520         || !TEST_ptr(legacy_obj = EVP_PKEY_get0(downgraded_pkey)))
    521         goto end;
    522 
    523     ok = 1;
    524 
    525     /* Test PrivateKey to PEM */
    526     if (test_stanza->pem_write_bio_PrivateKey != NULL) {
    527         int selection = OSSL_KEYMGMT_SELECT_ALL;
    528 
    529         for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
    530             const char *structure = test_stanza->structure[i];
    531 
    532             TEST_info("Test OSSL_ENCODER against PEM_write_bio_{TYPE}PrivateKey for %s, %s",
    533                 test_stanza->keytype, structure);
    534             if (!test_protected_PEM(key->keytype, key->evp_type, legacy_obj,
    535                     test_stanza->pem_write_bio_PrivateKey,
    536                     test_stanza->pem_read_bio_PrivateKey,
    537                     EVP_PKEY_eq, EVP_PKEY_print_private,
    538                     pkey, selection, structure))
    539                 ok = 0;
    540         }
    541     }
    542 
    543     /* Test PublicKey to PEM */
    544     if (test_stanza->pem_write_bio_PublicKey != NULL) {
    545         int selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY
    546             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
    547 
    548         for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
    549             const char *structure = test_stanza->structure[i];
    550 
    551             TEST_info("Test OSSL_ENCODER against PEM_write_bio_{TYPE}PublicKey for %s, %s",
    552                 test_stanza->keytype, structure);
    553             if (!test_unprotected_PEM(key->keytype, key->evp_type, legacy_obj,
    554                     test_stanza->pem_write_bio_PublicKey,
    555                     test_stanza->pem_read_bio_PublicKey,
    556                     EVP_PKEY_eq, EVP_PKEY_print_public,
    557                     pkey, selection, structure))
    558                 ok = 0;
    559         }
    560     }
    561 
    562     /* Test params to PEM */
    563     if (test_stanza->pem_write_bio_params != NULL) {
    564         int selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
    565 
    566         for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
    567             const char *structure = test_stanza->structure[i];
    568 
    569             TEST_info("Test OSSL_ENCODER against PEM_write_bio_{TYPE}params for %s, %s",
    570                 test_stanza->keytype, structure);
    571             if (!test_unprotected_PEM(key->keytype, key->evp_type, legacy_obj,
    572                     test_stanza->pem_write_bio_params,
    573                     test_stanza->pem_read_bio_params,
    574                     EVP_PKEY_parameters_eq,
    575                     EVP_PKEY_print_params,
    576                     pkey, selection, structure))
    577                 ok = 0;
    578         }
    579     }
    580 
    581     /* Test PUBKEY to PEM */
    582     if (test_stanza->pem_write_bio_PUBKEY != NULL) {
    583         int selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY
    584             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
    585         const char *structure = "SubjectPublicKeyInfo";
    586 
    587         TEST_info("Test OSSL_ENCODER against PEM_write_bio_{TYPE}_PUBKEY for %s, %s",
    588             test_stanza->keytype, structure);
    589         if (!test_unprotected_PEM(key->keytype, key->evp_type, legacy_obj,
    590                 test_stanza->pem_write_bio_PUBKEY,
    591                 test_stanza->pem_read_bio_PUBKEY,
    592                 EVP_PKEY_eq, EVP_PKEY_print_public,
    593                 pkey, selection, structure))
    594             ok = 0;
    595     }
    596 
    597     /* Test PrivateKey to DER */
    598     if (test_stanza->i2d_PrivateKey != NULL) {
    599         int selection = OSSL_KEYMGMT_SELECT_ALL;
    600 
    601         for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
    602             const char *structure = test_stanza->structure[i];
    603 
    604             TEST_info("Test OSSL_ENCODER against i2d_{TYPE}PrivateKey for %s, %s",
    605                 test_stanza->keytype, structure);
    606             if (!test_DER(key->keytype, key->evp_type, legacy_obj,
    607                     test_stanza->i2d_PrivateKey,
    608                     test_stanza->d2i_PrivateKey,
    609                     EVP_PKEY_eq, EVP_PKEY_print_private,
    610                     pkey, selection, structure))
    611                 ok = 0;
    612         }
    613     }
    614 
    615     /* Test PublicKey to DER */
    616     if (test_stanza->i2d_PublicKey != NULL) {
    617         int selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY
    618             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
    619 
    620         for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
    621             const char *structure = test_stanza->structure[i];
    622 
    623             TEST_info("Test OSSL_ENCODER against i2d_{TYPE}PublicKey for %s, %s",
    624                 test_stanza->keytype, structure);
    625             if (!test_DER(key->keytype, key->evp_type, legacy_obj,
    626                     test_stanza->i2d_PublicKey,
    627                     test_stanza->d2i_PublicKey,
    628                     EVP_PKEY_eq, EVP_PKEY_print_public,
    629                     pkey, selection, structure))
    630                 ok = 0;
    631         }
    632     }
    633 
    634     /* Test params to DER */
    635     if (test_stanza->i2d_params != NULL) {
    636         int selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
    637 
    638         for (i = 0; i < OSSL_NELEM(test_stanza->structure); i++) {
    639             const char *structure = test_stanza->structure[i];
    640 
    641             TEST_info("Test OSSL_ENCODER against i2d_{TYPE}params for %s, %s",
    642                 test_stanza->keytype, structure);
    643             if (!test_DER(key->keytype, key->evp_type, legacy_obj,
    644                     test_stanza->i2d_params, test_stanza->d2i_params,
    645                     EVP_PKEY_parameters_eq, EVP_PKEY_print_params,
    646                     pkey, selection, structure))
    647                 ok = 0;
    648         }
    649     }
    650 
    651     /* Test PUBKEY to DER */
    652     if (test_stanza->i2d_PUBKEY != NULL) {
    653         int selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY
    654             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
    655         const char *structure = "SubjectPublicKeyInfo";
    656 
    657         TEST_info("Test OSSL_ENCODER against i2d_{TYPE}_PUBKEY for %s, %s",
    658             test_stanza->keytype, structure);
    659         if (!test_DER(key->keytype, key->evp_type, legacy_obj,
    660                 test_stanza->i2d_PUBKEY, test_stanza->d2i_PUBKEY,
    661                 EVP_PKEY_eq, EVP_PKEY_print_public,
    662                 pkey, selection, structure))
    663             ok = 0;
    664     }
    665 end:
    666     EVP_PKEY_free(downgraded_pkey);
    667     return ok;
    668 }
    669 
    670 #define USAGE "rsa-key.pem dh-key.pem\n"
    671 OPT_TEST_DECLARE_USAGE(USAGE)
    672 
    673 int setup_tests(void)
    674 {
    675     size_t i;
    676 
    677     if (!test_skip_common_options()) {
    678         TEST_error("Error parsing test options\n");
    679         return 0;
    680     }
    681     if (test_get_argument_count() != 2) {
    682         TEST_error("usage: endecoder_legacy_test %s", USAGE);
    683         return 0;
    684     }
    685 
    686     TEST_info("Generating keys...");
    687 
    688     for (i = 0; i < OSSL_NELEM(keys); i++) {
    689 #ifndef OPENSSL_NO_DH
    690         if (strcmp(keys[i].keytype, "DH") == 0) {
    691             if (!TEST_ptr(keys[i].key = load_pkey_pem(test_get_argument(1), NULL)))
    692                 return 0;
    693             continue;
    694         }
    695 #endif
    696 #ifndef OPENSSL_NO_DEPRECATED_3_0
    697         if (strcmp(keys[i].keytype, "RSA") == 0) {
    698             if (!TEST_ptr(keys[i].key = load_pkey_pem(test_get_argument(0), NULL)))
    699                 return 0;
    700             continue;
    701         }
    702 #endif
    703         TEST_info("Generating %s key...", keys[i].keytype);
    704         if (!TEST_ptr(keys[i].key = make_key(keys[i].keytype, keys[i].template_params)))
    705             return 0;
    706     }
    707 
    708     TEST_info("Generating keys done");
    709 
    710     ADD_ALL_TESTS(test_key, OSSL_NELEM(test_stanzas));
    711     return 1;
    712 }
    713 
    714 void cleanup_tests(void)
    715 {
    716     size_t i;
    717 
    718     for (i = 0; i < OSSL_NELEM(keys); i++)
    719         EVP_PKEY_free(keys[i].key);
    720 }
    721