Home | History | Annotate | Line # | Download | only in test
endecoder_legacy_test.c revision 1.1.1.1
      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     { "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
    195 static const OSSL_PARAM DH_params[] = { OSSL_PARAM_END };
    196 static const OSSL_PARAM DHX_params[] = { OSSL_PARAM_END };
    197 #endif
    198 #ifndef OPENSSL_NO_DSA
    199 static size_t qbits = 160;  /* PVK only tolerates 160 Q bits */
    200 static size_t pbits = 1024; /* With 160 Q bits, we MUST use 1024 P bits */
    201 static 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
    208 static char groupname[] = "prime256v1";
    209 static const OSSL_PARAM EC_params[] = {
    210     OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1),
    211     OSSL_PARAM_END
    212 };
    213 #endif
    214 
    215 static 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 
    238 static 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 
    275 static 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 
    286 static 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 
    298 static 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 
    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 =
    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 
    433 static 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 
    504 static 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"
    679 OPT_TEST_DECLARE_USAGE(USAGE)
    680 
    681 int 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 
    725 void 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