xref: /freebsd/crypto/openssl/test/endecoder_legacy_test.c (revision 5b56413d04e608379c9a306373554a8e4d321bc0)
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