1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery *
4*e7be843bSPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5*e7be843bSPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6*e7be843bSPierre Pronchery * in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery */
9*e7be843bSPierre Pronchery
10*e7be843bSPierre Pronchery #include "testutil.h"
11*e7be843bSPierre Pronchery
12*e7be843bSPierre Pronchery #include <openssl/bio.h>
13*e7be843bSPierre Pronchery #include <openssl/pem.h>
14*e7be843bSPierre Pronchery
15*e7be843bSPierre Pronchery /* dummy data that needs to be passed to the callback */
16*e7be843bSPierre Pronchery typedef struct CallbackData {
17*e7be843bSPierre Pronchery char magic;
18*e7be843bSPierre Pronchery int result;
19*e7be843bSPierre Pronchery } CALLBACK_DATA;
20*e7be843bSPierre Pronchery
21*e7be843bSPierre Pronchery /* constants */
22*e7be843bSPierre Pronchery static const char weak_password[] = "weak_password";
23*e7be843bSPierre Pronchery static const char a0a_password[] = "aaaaaaaa\0aaaaaaaa";
24*e7be843bSPierre Pronchery static const char a0b_password[] = "aaaaaaaa\0bbbbbbbb";
25*e7be843bSPierre Pronchery static const char cb_magic = 'p';
26*e7be843bSPierre Pronchery
27*e7be843bSPierre Pronchery /* shared working data for all tests */
28*e7be843bSPierre Pronchery static char *key_file = NULL;
29*e7be843bSPierre Pronchery static EVP_PKEY *original_pkey = NULL;
30*e7be843bSPierre Pronchery
31*e7be843bSPierre Pronchery /* the test performed by the callback */
32*e7be843bSPierre Pronchery typedef enum CallbackTest {
33*e7be843bSPierre Pronchery CB_TEST_NEGATIVE = 0,
34*e7be843bSPierre Pronchery CB_TEST_ZERO_LENGTH,
35*e7be843bSPierre Pronchery CB_TEST_WEAK,
36*e7be843bSPierre Pronchery CB_TEST_16ZERO,
37*e7be843bSPierre Pronchery CB_TEST_A0A,
38*e7be843bSPierre Pronchery CB_TEST_A0B,
39*e7be843bSPierre Pronchery CB_TEST_MATCH_SIZE,
40*e7be843bSPierre Pronchery CB_TEST_EXCEED_SIZE
41*e7be843bSPierre Pronchery } CALLBACK_TEST;
42*e7be843bSPierre Pronchery static CALLBACK_TEST callback_test = CB_TEST_NEGATIVE;
43*e7be843bSPierre Pronchery
44*e7be843bSPierre Pronchery typedef enum KeyEncoding {
45*e7be843bSPierre Pronchery KE_PEM = 0,
46*e7be843bSPierre Pronchery KE_PKCS8
47*e7be843bSPierre Pronchery } KEY_ENCODING;
48*e7be843bSPierre Pronchery
49*e7be843bSPierre Pronchery typedef enum ExpectedResult {
50*e7be843bSPierre Pronchery ER_FAILURE = 0,
51*e7be843bSPierre Pronchery ER_SUCCESS
52*e7be843bSPierre Pronchery } EXPECTED_RESULT;
53*e7be843bSPierre Pronchery
54*e7be843bSPierre Pronchery typedef enum OPTION_choice {
55*e7be843bSPierre Pronchery OPT_ERR = -1,
56*e7be843bSPierre Pronchery OPT_EOF = 0,
57*e7be843bSPierre Pronchery OPT_KEY_FILE,
58*e7be843bSPierre Pronchery OPT_TEST_ENUM
59*e7be843bSPierre Pronchery } OPTION_CHOICE;
60*e7be843bSPierre Pronchery
test_get_options(void)61*e7be843bSPierre Pronchery const OPTIONS *test_get_options(void)
62*e7be843bSPierre Pronchery {
63*e7be843bSPierre Pronchery static const OPTIONS test_options[] = {
64*e7be843bSPierre Pronchery OPT_TEST_OPTIONS_DEFAULT_USAGE,
65*e7be843bSPierre Pronchery { "keyfile", OPT_KEY_FILE, '<',
66*e7be843bSPierre Pronchery "The PEM file with the encrypted key to load" },
67*e7be843bSPierre Pronchery { NULL }
68*e7be843bSPierre Pronchery };
69*e7be843bSPierre Pronchery return test_options;
70*e7be843bSPierre Pronchery }
71*e7be843bSPierre Pronchery
callback_copy_password(char * buf,int size)72*e7be843bSPierre Pronchery static int callback_copy_password(char *buf, int size)
73*e7be843bSPierre Pronchery {
74*e7be843bSPierre Pronchery int ret = -1;
75*e7be843bSPierre Pronchery
76*e7be843bSPierre Pronchery switch (callback_test) {
77*e7be843bSPierre Pronchery case CB_TEST_NEGATIVE:
78*e7be843bSPierre Pronchery break;
79*e7be843bSPierre Pronchery case CB_TEST_ZERO_LENGTH:
80*e7be843bSPierre Pronchery ret = 0;
81*e7be843bSPierre Pronchery break;
82*e7be843bSPierre Pronchery case CB_TEST_WEAK:
83*e7be843bSPierre Pronchery ret = sizeof(weak_password) - 1;
84*e7be843bSPierre Pronchery memcpy(buf, weak_password, ret);
85*e7be843bSPierre Pronchery break;
86*e7be843bSPierre Pronchery case CB_TEST_16ZERO:
87*e7be843bSPierre Pronchery memset(buf, 0, 16);
88*e7be843bSPierre Pronchery ret = 16;
89*e7be843bSPierre Pronchery break;
90*e7be843bSPierre Pronchery case CB_TEST_A0A:
91*e7be843bSPierre Pronchery ret = sizeof(a0a_password) - 1;
92*e7be843bSPierre Pronchery memcpy(buf, a0a_password, ret);
93*e7be843bSPierre Pronchery break;
94*e7be843bSPierre Pronchery case CB_TEST_A0B:
95*e7be843bSPierre Pronchery ret = sizeof(a0b_password) - 1;
96*e7be843bSPierre Pronchery memcpy(buf, a0b_password, ret);
97*e7be843bSPierre Pronchery break;
98*e7be843bSPierre Pronchery case CB_TEST_MATCH_SIZE:
99*e7be843bSPierre Pronchery memset(buf, 'e', size);
100*e7be843bSPierre Pronchery ret = size;
101*e7be843bSPierre Pronchery break;
102*e7be843bSPierre Pronchery case CB_TEST_EXCEED_SIZE:
103*e7be843bSPierre Pronchery memset(buf, 'e', size);
104*e7be843bSPierre Pronchery ret = 1000000;
105*e7be843bSPierre Pronchery break;
106*e7be843bSPierre Pronchery }
107*e7be843bSPierre Pronchery return ret;
108*e7be843bSPierre Pronchery }
109*e7be843bSPierre Pronchery
read_callback(char * buf,int size,int rwflag,void * u)110*e7be843bSPierre Pronchery static int read_callback(char *buf, int size, int rwflag, void *u)
111*e7be843bSPierre Pronchery {
112*e7be843bSPierre Pronchery CALLBACK_DATA *cb_data = (CALLBACK_DATA *)u;
113*e7be843bSPierre Pronchery int ret = -1;
114*e7be843bSPierre Pronchery
115*e7be843bSPierre Pronchery /* basic verification of the received data */
116*e7be843bSPierre Pronchery if (!TEST_ptr(cb_data))
117*e7be843bSPierre Pronchery goto err;
118*e7be843bSPierre Pronchery if (!TEST_char_eq(cb_data->magic, cb_magic))
119*e7be843bSPierre Pronchery goto err;
120*e7be843bSPierre Pronchery if (!TEST_ptr(buf))
121*e7be843bSPierre Pronchery goto err;
122*e7be843bSPierre Pronchery if (!TEST_int_gt(size, 0))
123*e7be843bSPierre Pronchery goto err;
124*e7be843bSPierre Pronchery if (!TEST_int_eq(rwflag, 0))
125*e7be843bSPierre Pronchery goto err;
126*e7be843bSPierre Pronchery ret = callback_copy_password(buf, size);
127*e7be843bSPierre Pronchery cb_data->result = 1;
128*e7be843bSPierre Pronchery err:
129*e7be843bSPierre Pronchery return ret;
130*e7be843bSPierre Pronchery }
131*e7be843bSPierre Pronchery
write_callback(char * buf,int size,int rwflag,void * u)132*e7be843bSPierre Pronchery static int write_callback(char *buf, int size, int rwflag, void *u)
133*e7be843bSPierre Pronchery {
134*e7be843bSPierre Pronchery CALLBACK_DATA *cb_data = (CALLBACK_DATA *)u;
135*e7be843bSPierre Pronchery int ret = -1;
136*e7be843bSPierre Pronchery
137*e7be843bSPierre Pronchery /* basic verification of the received data */
138*e7be843bSPierre Pronchery if (!TEST_ptr(cb_data))
139*e7be843bSPierre Pronchery goto err;
140*e7be843bSPierre Pronchery if (!TEST_char_eq(cb_data->magic, cb_magic))
141*e7be843bSPierre Pronchery goto err;
142*e7be843bSPierre Pronchery if (!TEST_ptr(buf))
143*e7be843bSPierre Pronchery goto err;
144*e7be843bSPierre Pronchery if (!TEST_int_gt(size, 0))
145*e7be843bSPierre Pronchery goto err;
146*e7be843bSPierre Pronchery if (!TEST_int_eq(rwflag, 1))
147*e7be843bSPierre Pronchery goto err;
148*e7be843bSPierre Pronchery ret = callback_copy_password(buf, size);
149*e7be843bSPierre Pronchery cb_data->result = 1;
150*e7be843bSPierre Pronchery err:
151*e7be843bSPierre Pronchery return ret;
152*e7be843bSPierre Pronchery }
153*e7be843bSPierre Pronchery
re_encrypt_key(char ** enc_data,int * enc_data_size,KEY_ENCODING key_encoding)154*e7be843bSPierre Pronchery static int re_encrypt_key(char **enc_data, int *enc_data_size,
155*e7be843bSPierre Pronchery KEY_ENCODING key_encoding)
156*e7be843bSPierre Pronchery {
157*e7be843bSPierre Pronchery CALLBACK_DATA cb_data;
158*e7be843bSPierre Pronchery int w_ret = 0;
159*e7be843bSPierre Pronchery BUF_MEM *bptr = NULL;
160*e7be843bSPierre Pronchery BIO *bio = NULL;
161*e7be843bSPierre Pronchery int ret = 0;
162*e7be843bSPierre Pronchery
163*e7be843bSPierre Pronchery if (!TEST_ptr(enc_data))
164*e7be843bSPierre Pronchery goto err;
165*e7be843bSPierre Pronchery if (!TEST_ptr(enc_data_size))
166*e7be843bSPierre Pronchery goto err;
167*e7be843bSPierre Pronchery if (!TEST_ptr(bio = BIO_new(BIO_s_mem())))
168*e7be843bSPierre Pronchery goto err;
169*e7be843bSPierre Pronchery cb_data.magic = cb_magic;
170*e7be843bSPierre Pronchery cb_data.result = 0;
171*e7be843bSPierre Pronchery switch (key_encoding) {
172*e7be843bSPierre Pronchery case KE_PEM:
173*e7be843bSPierre Pronchery w_ret = PEM_write_bio_PrivateKey(bio, original_pkey, EVP_aes_256_cbc(),
174*e7be843bSPierre Pronchery NULL, 0, write_callback, &cb_data);
175*e7be843bSPierre Pronchery break;
176*e7be843bSPierre Pronchery case KE_PKCS8:
177*e7be843bSPierre Pronchery w_ret = i2d_PKCS8PrivateKey_bio(bio, original_pkey, EVP_aes_256_cbc(),
178*e7be843bSPierre Pronchery NULL, 0, write_callback, &cb_data);
179*e7be843bSPierre Pronchery break;
180*e7be843bSPierre Pronchery }
181*e7be843bSPierre Pronchery if (!TEST_int_ne(w_ret, 0))
182*e7be843bSPierre Pronchery goto err;
183*e7be843bSPierre Pronchery if (!TEST_char_eq(cb_data.magic, cb_magic))
184*e7be843bSPierre Pronchery goto err;
185*e7be843bSPierre Pronchery if (!TEST_int_eq(cb_data.result, 1))
186*e7be843bSPierre Pronchery goto err;
187*e7be843bSPierre Pronchery *enc_data_size = BIO_get_mem_data(bio, enc_data);
188*e7be843bSPierre Pronchery BIO_get_mem_ptr(bio, &bptr);
189*e7be843bSPierre Pronchery if (!BIO_set_close(bio, BIO_NOCLOSE))
190*e7be843bSPierre Pronchery goto err;
191*e7be843bSPierre Pronchery bptr->data = NULL;
192*e7be843bSPierre Pronchery ret = 1;
193*e7be843bSPierre Pronchery err:
194*e7be843bSPierre Pronchery BUF_MEM_free(bptr);
195*e7be843bSPierre Pronchery BIO_free(bio);
196*e7be843bSPierre Pronchery return ret;
197*e7be843bSPierre Pronchery }
198*e7be843bSPierre Pronchery
decrypt_key(char * enc_data,int enc_data_size,KEY_ENCODING key_encoding,EXPECTED_RESULT expected_result)199*e7be843bSPierre Pronchery static int decrypt_key(char *enc_data, int enc_data_size,
200*e7be843bSPierre Pronchery KEY_ENCODING key_encoding,
201*e7be843bSPierre Pronchery EXPECTED_RESULT expected_result)
202*e7be843bSPierre Pronchery {
203*e7be843bSPierre Pronchery CALLBACK_DATA cb_data;
204*e7be843bSPierre Pronchery EVP_PKEY *r_ret = NULL;
205*e7be843bSPierre Pronchery BIO *bio = NULL;
206*e7be843bSPierre Pronchery EVP_PKEY *pkey = NULL;
207*e7be843bSPierre Pronchery int ret = 0;
208*e7be843bSPierre Pronchery
209*e7be843bSPierre Pronchery if (!TEST_ptr(bio = BIO_new_mem_buf(enc_data, enc_data_size)))
210*e7be843bSPierre Pronchery goto err;
211*e7be843bSPierre Pronchery cb_data.magic = cb_magic;
212*e7be843bSPierre Pronchery cb_data.result = 0;
213*e7be843bSPierre Pronchery switch (key_encoding) {
214*e7be843bSPierre Pronchery case KE_PEM:
215*e7be843bSPierre Pronchery r_ret = PEM_read_bio_PrivateKey(bio, &pkey, read_callback, &cb_data);
216*e7be843bSPierre Pronchery break;
217*e7be843bSPierre Pronchery case KE_PKCS8:
218*e7be843bSPierre Pronchery r_ret = d2i_PKCS8PrivateKey_bio(bio, &pkey, read_callback, &cb_data);
219*e7be843bSPierre Pronchery break;
220*e7be843bSPierre Pronchery }
221*e7be843bSPierre Pronchery if (expected_result == ER_SUCCESS) {
222*e7be843bSPierre Pronchery if (!TEST_ptr(r_ret))
223*e7be843bSPierre Pronchery goto err;
224*e7be843bSPierre Pronchery } else {
225*e7be843bSPierre Pronchery if (!TEST_ptr_null(r_ret))
226*e7be843bSPierre Pronchery goto err;
227*e7be843bSPierre Pronchery }
228*e7be843bSPierre Pronchery if (!TEST_char_eq(cb_data.magic, cb_magic))
229*e7be843bSPierre Pronchery goto err;
230*e7be843bSPierre Pronchery if (!TEST_int_eq(cb_data.result, 1))
231*e7be843bSPierre Pronchery goto err;
232*e7be843bSPierre Pronchery ret = 1;
233*e7be843bSPierre Pronchery err:
234*e7be843bSPierre Pronchery EVP_PKEY_free(pkey);
235*e7be843bSPierre Pronchery BIO_free(bio);
236*e7be843bSPierre Pronchery return ret;
237*e7be843bSPierre Pronchery }
238*e7be843bSPierre Pronchery
full_cycle_test(KEY_ENCODING key_encoding,CALLBACK_TEST write_test,CALLBACK_TEST read_test,EXPECTED_RESULT expected_read_result)239*e7be843bSPierre Pronchery static int full_cycle_test(KEY_ENCODING key_encoding, CALLBACK_TEST write_test,
240*e7be843bSPierre Pronchery CALLBACK_TEST read_test,
241*e7be843bSPierre Pronchery EXPECTED_RESULT expected_read_result)
242*e7be843bSPierre Pronchery {
243*e7be843bSPierre Pronchery char *enc_data = NULL;
244*e7be843bSPierre Pronchery int enc_data_size = 0;
245*e7be843bSPierre Pronchery int ret = 0;
246*e7be843bSPierre Pronchery
247*e7be843bSPierre Pronchery callback_test = write_test;
248*e7be843bSPierre Pronchery if (!re_encrypt_key(&enc_data, &enc_data_size, key_encoding))
249*e7be843bSPierre Pronchery goto err;
250*e7be843bSPierre Pronchery callback_test = read_test;
251*e7be843bSPierre Pronchery if (!decrypt_key(enc_data, enc_data_size, key_encoding,
252*e7be843bSPierre Pronchery expected_read_result))
253*e7be843bSPierre Pronchery goto err;
254*e7be843bSPierre Pronchery ret = 1;
255*e7be843bSPierre Pronchery err:
256*e7be843bSPierre Pronchery OPENSSL_free(enc_data);
257*e7be843bSPierre Pronchery return ret;
258*e7be843bSPierre Pronchery }
259*e7be843bSPierre Pronchery
test_pem_negative(void)260*e7be843bSPierre Pronchery static int test_pem_negative(void)
261*e7be843bSPierre Pronchery {
262*e7be843bSPierre Pronchery return full_cycle_test(KE_PEM, CB_TEST_WEAK, CB_TEST_NEGATIVE, ER_FAILURE);
263*e7be843bSPierre Pronchery }
264*e7be843bSPierre Pronchery
test_pem_zero_length(void)265*e7be843bSPierre Pronchery static int test_pem_zero_length(void)
266*e7be843bSPierre Pronchery {
267*e7be843bSPierre Pronchery return full_cycle_test(KE_PEM, CB_TEST_ZERO_LENGTH, CB_TEST_ZERO_LENGTH,
268*e7be843bSPierre Pronchery ER_SUCCESS);
269*e7be843bSPierre Pronchery }
270*e7be843bSPierre Pronchery
test_pem_weak(void)271*e7be843bSPierre Pronchery static int test_pem_weak(void)
272*e7be843bSPierre Pronchery {
273*e7be843bSPierre Pronchery return full_cycle_test(KE_PEM, CB_TEST_WEAK, CB_TEST_WEAK, ER_SUCCESS);
274*e7be843bSPierre Pronchery }
275*e7be843bSPierre Pronchery
test_pem_16zero(void)276*e7be843bSPierre Pronchery static int test_pem_16zero(void)
277*e7be843bSPierre Pronchery {
278*e7be843bSPierre Pronchery return full_cycle_test(KE_PEM, CB_TEST_16ZERO, CB_TEST_16ZERO, ER_SUCCESS);
279*e7be843bSPierre Pronchery }
280*e7be843bSPierre Pronchery
test_pem_a0a(void)281*e7be843bSPierre Pronchery static int test_pem_a0a(void)
282*e7be843bSPierre Pronchery {
283*e7be843bSPierre Pronchery return full_cycle_test(KE_PEM, CB_TEST_A0A, CB_TEST_A0A, ER_SUCCESS);
284*e7be843bSPierre Pronchery }
285*e7be843bSPierre Pronchery
test_pem_a0a_a0b(void)286*e7be843bSPierre Pronchery static int test_pem_a0a_a0b(void)
287*e7be843bSPierre Pronchery {
288*e7be843bSPierre Pronchery return full_cycle_test(KE_PEM, CB_TEST_A0A, CB_TEST_A0B, ER_FAILURE);
289*e7be843bSPierre Pronchery }
290*e7be843bSPierre Pronchery
test_pem_match_size(void)291*e7be843bSPierre Pronchery static int test_pem_match_size(void)
292*e7be843bSPierre Pronchery {
293*e7be843bSPierre Pronchery return full_cycle_test(KE_PEM, CB_TEST_MATCH_SIZE, CB_TEST_MATCH_SIZE,
294*e7be843bSPierre Pronchery ER_SUCCESS);
295*e7be843bSPierre Pronchery }
296*e7be843bSPierre Pronchery
test_pem_exceed_size(void)297*e7be843bSPierre Pronchery static int test_pem_exceed_size(void)
298*e7be843bSPierre Pronchery {
299*e7be843bSPierre Pronchery return full_cycle_test(KE_PEM, CB_TEST_MATCH_SIZE, CB_TEST_EXCEED_SIZE,
300*e7be843bSPierre Pronchery ER_FAILURE);
301*e7be843bSPierre Pronchery }
302*e7be843bSPierre Pronchery
test_pkcs8_negative(void)303*e7be843bSPierre Pronchery static int test_pkcs8_negative(void)
304*e7be843bSPierre Pronchery {
305*e7be843bSPierre Pronchery return full_cycle_test(KE_PKCS8, CB_TEST_WEAK, CB_TEST_NEGATIVE, ER_FAILURE);
306*e7be843bSPierre Pronchery }
307*e7be843bSPierre Pronchery
test_pkcs8_zero_length(void)308*e7be843bSPierre Pronchery static int test_pkcs8_zero_length(void)
309*e7be843bSPierre Pronchery {
310*e7be843bSPierre Pronchery return full_cycle_test(KE_PKCS8, CB_TEST_ZERO_LENGTH, CB_TEST_ZERO_LENGTH,
311*e7be843bSPierre Pronchery ER_SUCCESS);
312*e7be843bSPierre Pronchery }
313*e7be843bSPierre Pronchery
test_pkcs8_weak(void)314*e7be843bSPierre Pronchery static int test_pkcs8_weak(void)
315*e7be843bSPierre Pronchery {
316*e7be843bSPierre Pronchery return full_cycle_test(KE_PKCS8, CB_TEST_WEAK, CB_TEST_WEAK, ER_SUCCESS);
317*e7be843bSPierre Pronchery }
318*e7be843bSPierre Pronchery
test_pkcs8_16zero(void)319*e7be843bSPierre Pronchery static int test_pkcs8_16zero(void)
320*e7be843bSPierre Pronchery {
321*e7be843bSPierre Pronchery return full_cycle_test(KE_PKCS8, CB_TEST_16ZERO, CB_TEST_16ZERO,
322*e7be843bSPierre Pronchery ER_SUCCESS);
323*e7be843bSPierre Pronchery }
324*e7be843bSPierre Pronchery
test_pkcs8_a0a(void)325*e7be843bSPierre Pronchery static int test_pkcs8_a0a(void)
326*e7be843bSPierre Pronchery {
327*e7be843bSPierre Pronchery return full_cycle_test(KE_PKCS8, CB_TEST_A0A, CB_TEST_A0A, ER_SUCCESS);
328*e7be843bSPierre Pronchery }
329*e7be843bSPierre Pronchery
test_pkcs8_a0a_a0b(void)330*e7be843bSPierre Pronchery static int test_pkcs8_a0a_a0b(void)
331*e7be843bSPierre Pronchery {
332*e7be843bSPierre Pronchery return full_cycle_test(KE_PKCS8, CB_TEST_A0A, CB_TEST_A0B, ER_FAILURE);
333*e7be843bSPierre Pronchery }
334*e7be843bSPierre Pronchery
test_pkcs8_match_size(void)335*e7be843bSPierre Pronchery static int test_pkcs8_match_size(void)
336*e7be843bSPierre Pronchery {
337*e7be843bSPierre Pronchery return full_cycle_test(KE_PKCS8, CB_TEST_MATCH_SIZE, CB_TEST_MATCH_SIZE,
338*e7be843bSPierre Pronchery ER_SUCCESS);
339*e7be843bSPierre Pronchery }
340*e7be843bSPierre Pronchery
test_pkcs8_exceed_size(void)341*e7be843bSPierre Pronchery static int test_pkcs8_exceed_size(void)
342*e7be843bSPierre Pronchery {
343*e7be843bSPierre Pronchery return full_cycle_test(KE_PKCS8, CB_TEST_MATCH_SIZE, CB_TEST_EXCEED_SIZE,
344*e7be843bSPierre Pronchery ER_FAILURE);
345*e7be843bSPierre Pronchery }
346*e7be843bSPierre Pronchery
callback_original_pw(char * buf,int size,int rwflag,void * u)347*e7be843bSPierre Pronchery static int callback_original_pw(char *buf, int size, int rwflag, void *u)
348*e7be843bSPierre Pronchery {
349*e7be843bSPierre Pronchery memcpy(buf, weak_password, sizeof(weak_password) - 1);
350*e7be843bSPierre Pronchery return sizeof(weak_password) - 1;
351*e7be843bSPierre Pronchery }
352*e7be843bSPierre Pronchery
setup_tests(void)353*e7be843bSPierre Pronchery int setup_tests(void)
354*e7be843bSPierre Pronchery {
355*e7be843bSPierre Pronchery OPTION_CHOICE o;
356*e7be843bSPierre Pronchery BIO *bio = NULL;
357*e7be843bSPierre Pronchery
358*e7be843bSPierre Pronchery while ((o = opt_next()) != OPT_EOF) {
359*e7be843bSPierre Pronchery switch (o) {
360*e7be843bSPierre Pronchery case OPT_KEY_FILE:
361*e7be843bSPierre Pronchery key_file = opt_arg();
362*e7be843bSPierre Pronchery break;
363*e7be843bSPierre Pronchery case OPT_TEST_CASES:
364*e7be843bSPierre Pronchery break;
365*e7be843bSPierre Pronchery default:
366*e7be843bSPierre Pronchery case OPT_ERR:
367*e7be843bSPierre Pronchery return 0;
368*e7be843bSPierre Pronchery }
369*e7be843bSPierre Pronchery }
370*e7be843bSPierre Pronchery
371*e7be843bSPierre Pronchery /* read the original key */
372*e7be843bSPierre Pronchery if (!TEST_ptr(bio = BIO_new_file(key_file, "r")))
373*e7be843bSPierre Pronchery return 0;
374*e7be843bSPierre Pronchery if (!TEST_ptr(PEM_read_bio_PrivateKey(bio, &original_pkey,
375*e7be843bSPierre Pronchery callback_original_pw, NULL)))
376*e7be843bSPierre Pronchery return 0;
377*e7be843bSPierre Pronchery BIO_free(bio);
378*e7be843bSPierre Pronchery
379*e7be843bSPierre Pronchery /* add all tests */
380*e7be843bSPierre Pronchery ADD_TEST(test_pem_negative);
381*e7be843bSPierre Pronchery ADD_TEST(test_pem_zero_length);
382*e7be843bSPierre Pronchery ADD_TEST(test_pem_weak);
383*e7be843bSPierre Pronchery ADD_TEST(test_pem_16zero);
384*e7be843bSPierre Pronchery ADD_TEST(test_pem_a0a);
385*e7be843bSPierre Pronchery ADD_TEST(test_pem_a0a_a0b);
386*e7be843bSPierre Pronchery ADD_TEST(test_pem_match_size);
387*e7be843bSPierre Pronchery ADD_TEST(test_pem_exceed_size);
388*e7be843bSPierre Pronchery ADD_TEST(test_pkcs8_negative);
389*e7be843bSPierre Pronchery ADD_TEST(test_pkcs8_zero_length);
390*e7be843bSPierre Pronchery ADD_TEST(test_pkcs8_weak);
391*e7be843bSPierre Pronchery ADD_TEST(test_pkcs8_16zero);
392*e7be843bSPierre Pronchery ADD_TEST(test_pkcs8_a0a);
393*e7be843bSPierre Pronchery ADD_TEST(test_pkcs8_a0a_a0b);
394*e7be843bSPierre Pronchery ADD_TEST(test_pkcs8_match_size);
395*e7be843bSPierre Pronchery ADD_TEST(test_pkcs8_exceed_size);
396*e7be843bSPierre Pronchery return 1;
397*e7be843bSPierre Pronchery }
398*e7be843bSPierre Pronchery
cleanup_tests(void)399*e7be843bSPierre Pronchery void cleanup_tests(void)
400*e7be843bSPierre Pronchery {
401*e7be843bSPierre Pronchery EVP_PKEY_free(original_pkey);
402*e7be843bSPierre Pronchery }
403