xref: /src/crypto/openssl/test/endecoder_legacy_test.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
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 
make_key(const char * type,const OSSL_PARAM * gen_template_params)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 
lookup_key(const char * type)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 
test_membio_str_eq(BIO * bio_provided,BIO * bio_legacy)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 
test_protected_PEM(const char * keytype,int evp_type,const void * legacy_key,PEM_write_bio_of_void_protected * pem_write_bio,PEM_read_bio_of_void * pem_read_bio,EVP_PKEY_eq_fn * evp_pkey_eq,EVP_PKEY_print_fn * evp_pkey_print,EVP_PKEY * provided_pkey,int selection,const char * structure)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 
test_unprotected_PEM(const char * keytype,int evp_type,const void * legacy_key,PEM_write_bio_of_void_unprotected * pem_write_bio,PEM_read_bio_of_void * pem_read_bio,EVP_PKEY_eq_fn * evp_pkey_eq,EVP_PKEY_print_fn * evp_pkey_print,EVP_PKEY * provided_pkey,int selection,const char * structure)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 
test_DER(const char * keytype,int evp_type,const void * legacy_key,i2d_of_void * i2d,d2i_of_void * d2i,EVP_PKEY_eq_fn * evp_pkey_eq,EVP_PKEY_print_fn * evp_pkey_print,EVP_PKEY * provided_pkey,int selection,const char * structure)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 
test_key(int idx)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"
OPT_TEST_DECLARE_USAGE(USAGE)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 
cleanup_tests(void)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