]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/serdes_test.c
Rename OSSL_SERIALIZER / OSSL_DESERIALIZER to OSSL_ENCODE / OSSL_DECODE
[thirdparty/openssl.git] / test / serdes_test.c
CommitLineData
5a23d78c
RL
1/*
2 * Copyright 2020 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
3ecbea6a 10#include <string.h>
5a23d78c
RL
11#include <openssl/evp.h>
12#include <openssl/pem.h>
13#include <openssl/rsa.h>
14#include <openssl/x509.h>
7c664b1f 15#include <openssl/params.h>
5a23d78c
RL
16#include <openssl/serializer.h>
17#include <openssl/deserializer.h>
18
a7922e20 19#include "internal/pem.h" /* For PVK and "blob" PEM headers */
e2ac846e
RL
20#include "internal/cryptlib.h" /* ossl_assert */
21
5a23d78c
RL
22#include "testutil.h"
23
e2ac846e
RL
24/*
25 * TODO(3.0) Modify PEM_write_bio_PrivateKey_traditional() to handle
26 * provider side EVP_PKEYs (which don't necessarily have an ameth)
27 *
28 * In the mean time, we use separate "downgraded" EVP_PKEYs to test
29 * serializing/deserializing with "traditional" keys.
30 */
31
7c664b1f
RL
32static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
33{
34 EVP_PKEY *pkey = NULL;
35 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, type, NULL);
36
37 /*
38 * No real need to check the errors other than for the cascade
39 * effect. |pkey| will simply remain NULL if something goes wrong.
40 */
41 (void)(ctx != NULL
42 && EVP_PKEY_paramgen_init(ctx) > 0
43 && (genparams == NULL
44 || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
45 && EVP_PKEY_gen(ctx, &pkey) > 0);
46 EVP_PKEY_CTX_free(ctx);
47
48 return pkey;
49}
5a23d78c 50
7c664b1f
RL
51static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
52 OSSL_PARAM *genparams, int make_legacy)
5a23d78c
RL
53{
54 EVP_PKEY *pkey = NULL;
7c664b1f
RL
55 EVP_PKEY_CTX *ctx =
56 template != NULL
57 ? EVP_PKEY_CTX_new(template, NULL)
58 : EVP_PKEY_CTX_new_from_name(NULL, type, NULL);
5a23d78c
RL
59
60 /*
61 * No real need to check the errors other than for the cascade
7c664b1f 62 * effect. |pkey| will simply remain NULL if something goes wrong.
5a23d78c
RL
63 */
64 (void)(ctx != NULL
65 && EVP_PKEY_keygen_init(ctx) > 0
7c664b1f
RL
66 && (genparams == NULL
67 || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
5a23d78c
RL
68 && EVP_PKEY_keygen(ctx, &pkey) > 0);
69 EVP_PKEY_CTX_free(ctx);
e2ac846e
RL
70 if (make_legacy && EVP_PKEY_get0(pkey) == NULL) {
71 EVP_PKEY_free(pkey);
72 pkey = NULL;
73 }
5a23d78c
RL
74
75 return pkey;
76}
77
7c664b1f 78
5a23d78c
RL
79/* Main test driver */
80
4701f0a9
RL
81/*
82 * TODO(3.0) For better error output, changed the callbacks to take __FILE__
83 * and __LINE__ as first two arguments, and have them use the lower case
84 * functions, such as test_strn_eq(), rather than the uppercase macros
85 * (TEST_strn2_eq(), for example).
86 */
87
5a23d78c 88typedef int (serializer)(void **serialized, long *serialized_len,
4701f0a9 89 void *object, const char *pass, const char *pcipher,
3ecbea6a 90 const char *ser_propq);
5a23d78c 91typedef int (deserializer)(void **object,
3ecbea6a 92 void *serialized, long serialized_len,
4701f0a9 93 const char *pass);
319d0b2b
RL
94typedef int (tester)(const void *data1, size_t data1_len,
95 const void *data2, size_t data2_len);
846f96f8 96typedef int (checker)(const char *type, const void *data, size_t data_len);
5a23d78c
RL
97typedef void (dumper)(const char *label, const void *data, size_t data_len);
98
846f96f8 99static int test_serialize_deserialize(const char *type, EVP_PKEY *pkey,
3ecbea6a 100 const char *pass, const char *pcipher,
5a23d78c
RL
101 serializer *serialize_cb,
102 deserializer *deserialize_cb,
319d0b2b 103 tester *test_cb,
5a23d78c 104 checker *check_cb, dumper *dump_cb,
e2ac846e 105 const char *ser_propq, int make_legacy)
5a23d78c
RL
106{
107 void *serialized = NULL;
108 long serialized_len = 0;
109 EVP_PKEY *pkey2 = NULL;
110 void *serialized2 = NULL;
111 long serialized2_len = 0;
112 int ok = 0;
113
3ecbea6a
RL
114 if (!serialize_cb(&serialized, &serialized_len, pkey,
115 pass, pcipher, ser_propq)
846f96f8 116 || !check_cb(type, serialized, serialized_len)
3ecbea6a 117 || !deserialize_cb((void **)&pkey2, serialized, serialized_len,
4701f0a9 118 pass)
5a23d78c
RL
119 || !TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
120 goto end;
121
e2ac846e
RL
122 /*
123 * TODO(3.0) Remove this when PEM_write_bio_PrivateKey_traditional()
124 * handles provider side keys.
125 */
126 if (make_legacy
127 && !TEST_ptr(EVP_PKEY_get0(pkey2)))
128 goto end;
129
5a23d78c 130 /*
3ecbea6a
RL
131 * Double check the serialization, but only for unprotected keys,
132 * as protected keys have a random component, which makes the output
133 * differ.
5a23d78c 134 */
3ecbea6a
RL
135 if ((pass == NULL && pcipher == NULL)
136 && (!serialize_cb(&serialized2, &serialized2_len, pkey2,
137 pass, pcipher, ser_propq)
319d0b2b
RL
138 || !test_cb(serialized, serialized_len,
139 serialized2, serialized2_len)))
5a23d78c
RL
140 goto end;
141
142 ok = 1;
143 end:
319d0b2b
RL
144 if (!ok) {
145 if (serialized != NULL && serialized_len != 0)
146 dump_cb("serialized result", serialized, serialized_len);
147 if (serialized2 != NULL && serialized2_len != 0)
148 dump_cb("re-serialized result", serialized2, serialized2_len);
149 }
5a23d78c
RL
150
151 OPENSSL_free(serialized);
152 OPENSSL_free(serialized2);
153 EVP_PKEY_free(pkey2);
154 return ok;
155}
156
157/* Serializing and desserializing methods */
158
e2ac846e
RL
159static int serialize_EVP_PKEY_prov(void **serialized, long *serialized_len,
160 void *object,
161 const char *pass, const char *pcipher,
162 const char *ser_propq)
5a23d78c
RL
163{
164 EVP_PKEY *pkey = object;
165 OSSL_SERIALIZER_CTX *sctx = NULL;
166 BIO *mem_ser = NULL;
167 BUF_MEM *mem_buf = NULL;
3ecbea6a 168 const unsigned char *upass = (const unsigned char *)pass;
5a23d78c
RL
169 int ok = 0;
170
171 if (!TEST_ptr(sctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, ser_propq))
3ecbea6a 172 || (pass != NULL
e2ac846e
RL
173 && !TEST_true(OSSL_SERIALIZER_CTX_set_passphrase(sctx, upass,
174 strlen(pass))))
3ecbea6a 175 || (pcipher != NULL
e2ac846e 176 && !TEST_true(OSSL_SERIALIZER_CTX_set_cipher(sctx, pcipher, NULL)))
5a23d78c
RL
177 || !TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
178 || !TEST_true(OSSL_SERIALIZER_to_bio(sctx, mem_ser))
179 || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
180 || !TEST_ptr(*serialized = mem_buf->data)
181 || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
182 goto end;
183
184 /* Detach the serialized output */
185 mem_buf->data = NULL;
186 mem_buf->length = 0;
187 ok = 1;
188 end:
189 BIO_free(mem_ser);
190 OSSL_SERIALIZER_CTX_free(sctx);
191 return ok;
192}
193
e2ac846e
RL
194static int deserialize_EVP_PKEY_prov(void **object,
195 void *serialized, long serialized_len,
4701f0a9 196 const char *pass)
5a23d78c
RL
197{
198 EVP_PKEY *pkey = NULL;
199 OSSL_DESERIALIZER_CTX *dctx = NULL;
200 BIO *mem_deser = NULL;
3ecbea6a 201 const unsigned char *upass = (const unsigned char *)pass;
5a23d78c
RL
202 int ok = 0;
203
204 if (!TEST_ptr(dctx = OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(&pkey, NULL,
205 NULL, NULL))
3ecbea6a
RL
206 || (pass != NULL
207 && !OSSL_DESERIALIZER_CTX_set_passphrase(dctx, upass,
208 strlen(pass)))
5a23d78c
RL
209 || !TEST_ptr(mem_deser = BIO_new_mem_buf(serialized, serialized_len))
210 || !TEST_true(OSSL_DESERIALIZER_from_bio(dctx, mem_deser)))
211 goto end;
212 ok = 1;
213 *object = pkey;
214 end:
215 BIO_free(mem_deser);
216 OSSL_DESERIALIZER_CTX_free(dctx);
217 return ok;
218}
219
e2ac846e
RL
220static int serialize_EVP_PKEY_legacy_PEM(void **serialized,
221 long *serialized_len,
222 void *object,
223 const char *pass, const char *pcipher,
224 ossl_unused const char *ser_propq)
225{
226 EVP_PKEY *pkey = object;
227 EVP_CIPHER *cipher = NULL;
228 BIO *mem_ser = NULL;
229 BUF_MEM *mem_buf = NULL;
230 const unsigned char *upass = (const unsigned char *)pass;
231 size_t passlen = 0;
232 int ok = 0;
233
234 if (pcipher != NULL && pass != NULL) {
235 passlen = strlen(pass);
236 if (!TEST_ptr(cipher = EVP_CIPHER_fetch(NULL, pcipher, NULL)))
237 goto end;
238 }
239 if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
240 || !TEST_true(PEM_write_bio_PrivateKey_traditional(mem_ser, pkey,
241 cipher,
242 upass, passlen,
243 NULL, NULL))
244 || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
245 || !TEST_ptr(*serialized = mem_buf->data)
246 || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
247 goto end;
248
249 /* Detach the serialized output */
250 mem_buf->data = NULL;
251 mem_buf->length = 0;
252 ok = 1;
253 end:
254 BIO_free(mem_ser);
255 EVP_CIPHER_free(cipher);
256 return ok;
257}
258
a7922e20
RL
259#ifndef OPENSSL_NO_DSA
260static int serialize_EVP_PKEY_MSBLOB(void **serialized,
261 long *serialized_len,
262 void *object,
263 ossl_unused const char *pass,
264 ossl_unused const char *pcipher,
265 ossl_unused const char *ser_propq)
266{
267 EVP_PKEY *pkey = object;
268 BIO *mem_ser = NULL;
269 BUF_MEM *mem_buf = NULL;
270 int ok = 0;
271
272 if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
273 || !TEST_int_ge(i2b_PrivateKey_bio(mem_ser, pkey), 0)
274 || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
275 || !TEST_ptr(*serialized = mem_buf->data)
276 || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
277 goto end;
278
279 /* Detach the serialized output */
280 mem_buf->data = NULL;
281 mem_buf->length = 0;
282 ok = 1;
283 end:
284 BIO_free(mem_ser);
285 return ok;
286}
287
288static int serialize_public_EVP_PKEY_MSBLOB(void **serialized,
289 long *serialized_len,
290 void *object,
291 ossl_unused const char *pass,
292 ossl_unused const char *pcipher,
293 ossl_unused const char *ser_propq)
294{
295 EVP_PKEY *pkey = object;
296 BIO *mem_ser = NULL;
297 BUF_MEM *mem_buf = NULL;
298 int ok = 0;
299
300 if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
301 || !TEST_int_ge(i2b_PublicKey_bio(mem_ser, pkey), 0)
302 || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
303 || !TEST_ptr(*serialized = mem_buf->data)
304 || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
305 goto end;
306
307 /* Detach the serialized output */
308 mem_buf->data = NULL;
309 mem_buf->length = 0;
310 ok = 1;
311 end:
312 BIO_free(mem_ser);
313 return ok;
314}
315
316# ifndef OPENSSL_NO_RC4
317static pem_password_cb pass_pw;
318static int pass_pw(char *buf, int size, int rwflag, void *userdata)
319{
320 OPENSSL_strlcpy(buf, userdata, size);
321 return strlen(userdata);
322}
323
324static int serialize_EVP_PKEY_PVK(void **serialized, long *serialized_len,
325 void *object,
326 const char *pass,
327 ossl_unused const char *pcipher,
328 ossl_unused const char *ser_propq)
329{
330 EVP_PKEY *pkey = object;
331 BIO *mem_ser = NULL;
332 BUF_MEM *mem_buf = NULL;
333 int enc = (pass != NULL);
334 int ok = 0;
335
336 if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
337 || !TEST_int_ge(i2b_PVK_bio(mem_ser, pkey, enc,
338 pass_pw, (void *)pass), 0)
339 || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
340 || !TEST_ptr(*serialized = mem_buf->data)
341 || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
342 goto end;
343
344 /* Detach the serialized output */
345 mem_buf->data = NULL;
346 mem_buf->length = 0;
347 ok = 1;
348 end:
349 BIO_free(mem_ser);
350 return ok;
351}
352# endif
353#endif
354
319d0b2b
RL
355static int test_text(const void *data1, size_t data1_len,
356 const void *data2, size_t data2_len)
357{
358 return TEST_strn2_eq(data1, data1_len, data2, data2_len);
359}
360
361static int test_mem(const void *data1, size_t data1_len,
362 const void *data2, size_t data2_len)
363{
364 return TEST_mem_eq(data1, data1_len, data2, data2_len);
365}
366
5a23d78c
RL
367/* Test cases and their dumpers / checkers */
368
369static void dump_der(const char *label, const void *data, size_t data_len)
370{
371 test_output_memory(label, data, data_len);
372}
373
374static void dump_pem(const char *label, const void *data, size_t data_len)
375{
376 test_output_string(label, data, data_len - 1);
377}
378
846f96f8 379static int check_unprotected_PKCS8_DER(const char *type,
3ecbea6a 380 const void *data, size_t data_len)
5a23d78c
RL
381{
382 const unsigned char *datap = data;
383 PKCS8_PRIV_KEY_INFO *p8inf =
384 d2i_PKCS8_PRIV_KEY_INFO(NULL, &datap, data_len);
385 int ok = 0;
386
387 if (TEST_ptr(p8inf)) {
388 EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf);
389
846f96f8 390 ok = (TEST_ptr(pkey) && TEST_true(EVP_PKEY_is_a(pkey, type)));
5a23d78c
RL
391 EVP_PKEY_free(pkey);
392 }
393 PKCS8_PRIV_KEY_INFO_free(p8inf);
394 return ok;
395}
396
7c664b1f 397static int test_unprotected_via_DER(const char *type, EVP_PKEY *key)
846f96f8 398{
7c664b1f 399 return test_serialize_deserialize(type, key, NULL, NULL,
846f96f8
RL
400 serialize_EVP_PKEY_prov,
401 deserialize_EVP_PKEY_prov,
319d0b2b 402 test_mem,
846f96f8
RL
403 check_unprotected_PKCS8_DER, dump_der,
404 OSSL_SERIALIZER_PrivateKey_TO_DER_PQ,
405 0);
406}
407
408static int check_unprotected_PKCS8_PEM(const char *type,
3ecbea6a 409 const void *data, size_t data_len)
5a23d78c
RL
410{
411 static const char pem_header[] = "-----BEGIN " PEM_STRING_PKCS8INF "-----";
412
413 return TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1);
414}
415
7c664b1f 416static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key)
5a23d78c 417{
7c664b1f 418 return test_serialize_deserialize(type, key, NULL, NULL,
e2ac846e
RL
419 serialize_EVP_PKEY_prov,
420 deserialize_EVP_PKEY_prov,
319d0b2b 421 test_text,
3ecbea6a 422 check_unprotected_PKCS8_PEM, dump_pem,
e2ac846e
RL
423 OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ,
424 0);
425}
426
846f96f8 427static int check_unprotected_legacy_PEM(const char *type,
e2ac846e
RL
428 const void *data, size_t data_len)
429{
846f96f8 430 static char pem_header[80];
e2ac846e 431
846f96f8
RL
432 return
433 TEST_int_gt(BIO_snprintf(pem_header, sizeof(pem_header),
434 "-----BEGIN %s PRIVATE KEY-----", type), 0)
435 && TEST_strn_eq(data, pem_header, strlen(pem_header));
e2ac846e
RL
436}
437
7c664b1f 438static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key)
846f96f8 439{
7c664b1f 440 return test_serialize_deserialize(type, key, NULL, NULL,
e2ac846e
RL
441 serialize_EVP_PKEY_legacy_PEM,
442 deserialize_EVP_PKEY_prov,
319d0b2b 443 test_text,
e2ac846e
RL
444 check_unprotected_legacy_PEM, dump_pem,
445 NULL, 1);
3ecbea6a
RL
446}
447
a7922e20
RL
448#ifndef OPENSSL_NO_DSA
449static int check_MSBLOB(const char *type, const void *data, size_t data_len)
450{
451 const unsigned char *datap = data;
452 EVP_PKEY *pkey = b2i_PrivateKey(&datap, data_len);
453 int ok = TEST_ptr(pkey);
454
455 EVP_PKEY_free(pkey);
456 return ok;
457}
458
459static int test_unprotected_via_MSBLOB(const char *type, EVP_PKEY *key)
460{
461 return test_serialize_deserialize(type, key, NULL, NULL,
462 serialize_EVP_PKEY_MSBLOB,
463 deserialize_EVP_PKEY_prov,
464 test_mem,
465 check_MSBLOB, dump_der,
466 NULL, 0);
467}
468
469# ifndef OPENSSL_NO_RC4
470static int check_PVK(const char *type, const void *data, size_t data_len)
471{
472 const unsigned char *in = data;
473 unsigned int saltlen = 0, keylen = 0;
474 int ok = ossl_do_PVK_header(&in, data_len, 0, &saltlen, &keylen);
475
476 return ok;
477}
478
479static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)
480{
481 return test_serialize_deserialize(type, key, NULL, NULL,
482 serialize_EVP_PKEY_PVK,
483 deserialize_EVP_PKEY_prov,
484 test_mem,
485 check_PVK, dump_der,
486 NULL, 0);
487}
488# endif
489#endif
490
3ecbea6a
RL
491static const char *pass_cipher = "AES-256-CBC";
492static const char *pass = "the holy handgrenade of antioch";
493
846f96f8 494static int check_protected_PKCS8_DER(const char *type,
3ecbea6a
RL
495 const void *data, size_t data_len)
496{
497 const unsigned char *datap = data;
498 X509_SIG *p8 = d2i_X509_SIG(NULL, &datap, data_len);
499 int ok = TEST_ptr(p8);
500
501 X509_SIG_free(p8);
502 return ok;
503}
504
7c664b1f 505static int test_protected_via_DER(const char *type, EVP_PKEY *key)
846f96f8 506{
7c664b1f 507 return test_serialize_deserialize(type, key, pass, pass_cipher,
e2ac846e
RL
508 serialize_EVP_PKEY_prov,
509 deserialize_EVP_PKEY_prov,
319d0b2b 510 test_mem,
3ecbea6a 511 check_protected_PKCS8_DER, dump_der,
e2ac846e
RL
512 OSSL_SERIALIZER_PrivateKey_TO_DER_PQ,
513 0);
3ecbea6a
RL
514}
515
846f96f8 516static int check_protected_PKCS8_PEM(const char *type,
3ecbea6a
RL
517 const void *data, size_t data_len)
518{
519 static const char pem_header[] = "-----BEGIN " PEM_STRING_PKCS8 "-----";
520
521 return TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1);
522}
523
7c664b1f 524static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
3ecbea6a 525{
7c664b1f 526 return test_serialize_deserialize(type, key, pass, pass_cipher,
e2ac846e
RL
527 serialize_EVP_PKEY_prov,
528 deserialize_EVP_PKEY_prov,
319d0b2b 529 test_text,
3ecbea6a 530 check_protected_PKCS8_PEM, dump_pem,
e2ac846e
RL
531 OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ,
532 0);
533}
534
846f96f8 535static int check_protected_legacy_PEM(const char *type,
e2ac846e
RL
536 const void *data, size_t data_len)
537{
846f96f8 538 static char pem_header[80];
e2ac846e
RL
539
540 return
846f96f8
RL
541 TEST_int_gt(BIO_snprintf(pem_header, sizeof(pem_header),
542 "-----BEGIN %s PRIVATE KEY-----", type), 0)
543 && TEST_strn_eq(data, pem_header, strlen(pem_header))
e2ac846e
RL
544 && TEST_ptr(strstr(data, "\nDEK-Info: "));
545}
546
7c664b1f 547static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
e2ac846e 548{
7c664b1f 549 return test_serialize_deserialize(type, key, pass, pass_cipher,
846f96f8
RL
550 serialize_EVP_PKEY_legacy_PEM,
551 deserialize_EVP_PKEY_prov,
319d0b2b 552 test_text,
846f96f8
RL
553 check_protected_legacy_PEM, dump_pem,
554 NULL, 1);
555}
556
a7922e20
RL
557#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
558static int test_protected_via_PVK(const char *type, EVP_PKEY *key)
559{
560 return test_serialize_deserialize(type, key, pass, NULL,
561 serialize_EVP_PKEY_PVK,
562 deserialize_EVP_PKEY_prov,
563 test_mem,
564 check_PVK, dump_der,
565 NULL, 0);
566}
567#endif
568
7c664b1f 569static int check_public_DER(const char *type, const void *data, size_t data_len)
3ff8159a
RL
570{
571 const unsigned char *datap = data;
572 EVP_PKEY *pkey = d2i_PUBKEY(NULL, &datap, data_len);
7c664b1f 573 int ok = (TEST_ptr(pkey) && TEST_true(EVP_PKEY_is_a(pkey, type)));
3ff8159a
RL
574
575 EVP_PKEY_free(pkey);
576 return ok;
577}
578
7c664b1f 579static int test_public_via_DER(const char *type, EVP_PKEY *key)
3ff8159a 580{
7c664b1f 581 return test_serialize_deserialize(type, key, NULL, NULL,
3ff8159a
RL
582 serialize_EVP_PKEY_prov,
583 deserialize_EVP_PKEY_prov,
319d0b2b 584 test_mem,
3ff8159a
RL
585 check_public_DER, dump_der,
586 OSSL_SERIALIZER_PUBKEY_TO_DER_PQ,
587 0);
588}
589
7c664b1f 590static int check_public_PEM(const char *type, const void *data, size_t data_len)
3ff8159a
RL
591{
592 static const char pem_header[] = "-----BEGIN " PEM_STRING_PUBLIC "-----";
593
594 return
595 TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1);
596}
597
7c664b1f 598static int test_public_via_PEM(const char *type, EVP_PKEY *key)
3ff8159a 599{
7c664b1f 600 return test_serialize_deserialize(type, key, NULL, NULL,
3ff8159a
RL
601 serialize_EVP_PKEY_prov,
602 deserialize_EVP_PKEY_prov,
319d0b2b 603 test_text,
3ff8159a
RL
604 check_public_PEM, dump_pem,
605 OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ,
606 0);
607}
608
a7922e20
RL
609#ifndef OPENSSL_NO_DSA
610static int check_public_MSBLOB(const char *type,
611 const void *data, size_t data_len)
612{
613 const unsigned char *datap = data;
614 EVP_PKEY *pkey = b2i_PublicKey(&datap, data_len);
615 int ok = TEST_ptr(pkey);
616
617 EVP_PKEY_free(pkey);
618 return ok;
619}
620
621static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
622{
623 return test_serialize_deserialize(type, key, NULL, NULL,
624 serialize_public_EVP_PKEY_MSBLOB,
625 deserialize_EVP_PKEY_prov,
626 test_mem,
627 check_public_MSBLOB, dump_der,
628 NULL, 0);
629}
630#endif
631
7c664b1f
RL
632#define KEYS(KEYTYPE) \
633 static EVP_PKEY *key_##KEYTYPE = NULL; \
634 static EVP_PKEY *legacy_key_##KEYTYPE = NULL
635#define MAKE_KEYS(KEYTYPE, KEYTYPEstr, params) \
636 ok = ok \
637 && TEST_ptr(key_##KEYTYPE = \
638 make_key(KEYTYPEstr, NULL, params, 0)) \
639 && TEST_ptr(legacy_key_##KEYTYPE = \
640 make_key(KEYTYPEstr, NULL, params, 1))
641#define FREE_KEYS(KEYTYPE) \
642 EVP_PKEY_free(key_##KEYTYPE); \
643 EVP_PKEY_free(legacy_key_##KEYTYPE)
644
645#define DOMAIN_KEYS(KEYTYPE) \
646 static EVP_PKEY *template_##KEYTYPE = NULL; \
647 static EVP_PKEY *key_##KEYTYPE = NULL; \
648 static EVP_PKEY *legacy_key_##KEYTYPE = NULL
649#define MAKE_DOMAIN_KEYS(KEYTYPE, KEYTYPEstr, params) \
650 ok = ok \
651 && TEST_ptr(template_##KEYTYPE = \
652 make_template(KEYTYPEstr, params)) \
653 && TEST_ptr(key_##KEYTYPE = \
654 make_key(KEYTYPEstr, template_##KEYTYPE, NULL, 0)) \
655 && TEST_ptr(legacy_key_##KEYTYPE = \
656 make_key(KEYTYPEstr, template_##KEYTYPE, NULL, 1))
657#define FREE_DOMAIN_KEYS(KEYTYPE) \
658 EVP_PKEY_free(template_##KEYTYPE); \
659 EVP_PKEY_free(key_##KEYTYPE); \
660 EVP_PKEY_free(legacy_key_##KEYTYPE)
661
662#define IMPLEMENT_TEST_SUITE(KEYTYPE, KEYTYPEstr) \
663 static int test_unprotected_##KEYTYPE##_via_DER(void) \
664 { \
665 return test_unprotected_via_DER(KEYTYPEstr, key_##KEYTYPE); \
666 } \
667 static int test_unprotected_##KEYTYPE##_via_PEM(void) \
668 { \
669 return test_unprotected_via_PEM(KEYTYPEstr, key_##KEYTYPE); \
670 } \
671 static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void) \
672 { \
673 return test_unprotected_via_legacy_PEM(KEYTYPEstr, \
674 legacy_key_##KEYTYPE); \
675 } \
676 static int test_protected_##KEYTYPE##_via_DER(void) \
677 { \
678 return test_protected_via_DER(KEYTYPEstr, key_##KEYTYPE); \
679 } \
680 static int test_protected_##KEYTYPE##_via_PEM(void) \
681 { \
682 return test_protected_via_PEM(KEYTYPEstr, key_##KEYTYPE); \
683 } \
684 static int test_protected_##KEYTYPE##_via_legacy_PEM(void) \
685 { \
686 return test_protected_via_legacy_PEM(KEYTYPEstr, \
687 legacy_key_##KEYTYPE); \
688 } \
689 static int test_public_##KEYTYPE##_via_DER(void) \
690 { \
691 return test_public_via_DER(KEYTYPEstr, key_##KEYTYPE); \
692 } \
693 static int test_public_##KEYTYPE##_via_PEM(void) \
694 { \
695 return test_public_via_PEM(KEYTYPEstr, key_##KEYTYPE); \
696 }
697
698#define ADD_TEST_SUITE(KEYTYPE) \
699 ADD_TEST(test_unprotected_##KEYTYPE##_via_DER); \
700 ADD_TEST(test_unprotected_##KEYTYPE##_via_PEM); \
701 ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM); \
702 ADD_TEST(test_protected_##KEYTYPE##_via_DER); \
703 ADD_TEST(test_protected_##KEYTYPE##_via_PEM); \
704 ADD_TEST(test_protected_##KEYTYPE##_via_legacy_PEM); \
705 ADD_TEST(test_public_##KEYTYPE##_via_DER); \
706 ADD_TEST(test_public_##KEYTYPE##_via_PEM)
707
a7922e20
RL
708#ifndef OPENSSL_NO_DSA
709# define IMPLEMENT_TEST_SUITE_MSBLOB(KEYTYPE, KEYTYPEstr) \
710 static int test_unprotected_##KEYTYPE##_via_MSBLOB(void) \
711 { \
712 return test_unprotected_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE); \
713 } \
714 static int test_public_##KEYTYPE##_via_MSBLOB(void) \
715 { \
716 return test_public_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE); \
717 }
718
719# define ADD_TEST_SUITE_MSBLOB(KEYTYPE) \
720 ADD_TEST(test_unprotected_##KEYTYPE##_via_MSBLOB); \
721 ADD_TEST(test_public_##KEYTYPE##_via_MSBLOB)
722
723# ifndef OPENSSL_NO_RC4
724# define IMPLEMENT_TEST_SUITE_PVK(KEYTYPE, KEYTYPEstr) \
725 static int test_unprotected_##KEYTYPE##_via_PVK(void) \
726 { \
727 return test_unprotected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \
728 } \
729 static int test_protected_##KEYTYPE##_via_PVK(void) \
730 { \
731 return test_protected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \
732 }
733
734# define ADD_TEST_SUITE_PVK(KEYTYPE) \
735 ADD_TEST(test_unprotected_##KEYTYPE##_via_PVK); \
736 ADD_TEST(test_protected_##KEYTYPE##_via_PVK)
737# endif
738#endif
739
7c664b1f
RL
740#ifndef OPENSSL_NO_DH
741DOMAIN_KEYS(DH);
742IMPLEMENT_TEST_SUITE(DH, "DH")
31d2daec
SL
743DOMAIN_KEYS(DHX);
744IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH")
7c664b1f
RL
745#endif
746#ifndef OPENSSL_NO_DSA
747DOMAIN_KEYS(DSA);
748IMPLEMENT_TEST_SUITE(DSA, "DSA")
a7922e20
RL
749IMPLEMENT_TEST_SUITE_MSBLOB(DSA, "DSA")
750# ifndef OPENSSL_NO_RC4
751IMPLEMENT_TEST_SUITE_PVK(DSA, "DSA")
752# endif
7c664b1f
RL
753#endif
754#ifndef OPENSSL_NO_EC
755DOMAIN_KEYS(EC);
756IMPLEMENT_TEST_SUITE(EC, "EC")
757KEYS(ED25519);
758IMPLEMENT_TEST_SUITE(ED25519, "ED25519")
759KEYS(ED448);
760IMPLEMENT_TEST_SUITE(ED448, "ED448")
761KEYS(X25519);
762IMPLEMENT_TEST_SUITE(X25519, "X25519")
763KEYS(X448);
764IMPLEMENT_TEST_SUITE(X448, "X448")
765#endif
766KEYS(RSA);
767IMPLEMENT_TEST_SUITE(RSA, "RSA")
768KEYS(RSA_PSS);
769IMPLEMENT_TEST_SUITE(RSA_PSS, "RSA-PSS")
a7922e20
RL
770#ifndef OPENSSL_NO_DSA
771IMPLEMENT_TEST_SUITE_MSBLOB(RSA, "RSA")
772# ifndef OPENSSL_NO_RC4
773IMPLEMENT_TEST_SUITE_PVK(RSA, "RSA")
774# endif
775#endif
3ff8159a 776
5a23d78c
RL
777int setup_tests(void)
778{
7c664b1f
RL
779 int ok = 1;
780
a7922e20
RL
781#ifndef OPENSSL_NO_DSA
782 static size_t qbits = 160; /* PVK only tolerates 160 Q bits */
783 static size_t pbits = 1024; /* With 160 Q bits, we MUST use 1024 P bits */
784 OSSL_PARAM DSA_params[] = {
785 OSSL_PARAM_size_t("pbits", &pbits),
786 OSSL_PARAM_size_t("qbits", &qbits),
787 OSSL_PARAM_END
788 };
789#endif
790
7c664b1f
RL
791#ifndef OPENSSL_NO_EC
792 static char groupname[] = "prime256v1";
793 OSSL_PARAM EC_params[] = {
794 OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1),
795 OSSL_PARAM_END
796 };
797#endif
798
799 /* 7 is the default magic number */
800 static unsigned int rsapss_min_saltlen = 7;
801 OSSL_PARAM RSA_PSS_params[] = {
802 OSSL_PARAM_uint("saltlen", &rsapss_min_saltlen),
803 OSSL_PARAM_END
804 };
805
e2ac846e 806 TEST_info("Generating keys...");
7c664b1f
RL
807#ifndef OPENSSL_NO_DH
808 MAKE_DOMAIN_KEYS(DH, "DH", NULL);
31d2daec 809 MAKE_DOMAIN_KEYS(DHX, "X9.42 DH", NULL);
7c664b1f
RL
810#endif
811#ifndef OPENSSL_NO_DSA
a7922e20 812 MAKE_DOMAIN_KEYS(DSA, "DSA", DSA_params);
7c664b1f
RL
813#endif
814#ifndef OPENSSL_NO_EC
815 MAKE_DOMAIN_KEYS(EC, "EC", EC_params);
816 MAKE_KEYS(ED25519, "ED25519", NULL);
817 MAKE_KEYS(ED448, "ED448", NULL);
818 MAKE_KEYS(X25519, "X25519", NULL);
819 MAKE_KEYS(X448, "X448", NULL);
820#endif
821 MAKE_KEYS(RSA, "RSA", NULL);
822 MAKE_KEYS(RSA_PSS, "RSA-PSS", RSA_PSS_params);
5a23d78c
RL
823 TEST_info("Generating key... done");
824
7c664b1f
RL
825 if (ok) {
826#ifndef OPENSSL_NO_DH
827 ADD_TEST_SUITE(DH);
31d2daec 828 ADD_TEST_SUITE(DHX);
7c664b1f
RL
829#endif
830#ifndef OPENSSL_NO_DSA
831 ADD_TEST_SUITE(DSA);
a7922e20
RL
832 ADD_TEST_SUITE_MSBLOB(DSA);
833# ifndef OPENSSL_NO_RC4
834 ADD_TEST_SUITE_PVK(DSA);
835# endif
7c664b1f
RL
836#endif
837#ifndef OPENSSL_NO_EC
838 ADD_TEST_SUITE(EC);
839 ADD_TEST_SUITE(ED25519);
840 ADD_TEST_SUITE(ED448);
841 ADD_TEST_SUITE(X25519);
842 ADD_TEST_SUITE(X448);
843#endif
844 ADD_TEST_SUITE(RSA);
845 ADD_TEST_SUITE(RSA_PSS);
a7922e20
RL
846#ifndef OPENSSL_NO_DSA
847 ADD_TEST_SUITE_MSBLOB(RSA);
848# ifndef OPENSSL_NO_RC4
849 ADD_TEST_SUITE_PVK(RSA);
850# endif
851#endif
7c664b1f 852 }
5a23d78c
RL
853
854 return 1;
855}
7c664b1f
RL
856
857void cleanup_tests(void)
858{
859#ifndef OPENSSL_NO_DH
860 FREE_DOMAIN_KEYS(DH);
31d2daec 861 FREE_DOMAIN_KEYS(DHX);
7c664b1f
RL
862#endif
863#ifndef OPENSSL_NO_DSA
864 FREE_DOMAIN_KEYS(DSA);
865#endif
866#ifndef OPENSSL_NO_EC
867 FREE_DOMAIN_KEYS(EC);
868 FREE_KEYS(ED25519);
869 FREE_KEYS(ED448);
870 FREE_KEYS(X25519);
871 FREE_KEYS(X448);
872#endif
873 FREE_KEYS(RSA);
874 FREE_KEYS(RSA_PSS);
875}