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