xref: /freebsd/crypto/openssl/test/enginetest.c (revision 0d0c8621fd181e507f0fb50ffcca606faf66a8c2)
1e0c4386eSCy Schubert /*
2e0c4386eSCy Schubert  * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
3e0c4386eSCy Schubert  *
4e0c4386eSCy Schubert  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e0c4386eSCy Schubert  * this file except in compliance with the License.  You can obtain a copy
6e0c4386eSCy Schubert  * in the file LICENSE in the source distribution or at
7e0c4386eSCy Schubert  * https://www.openssl.org/source/license.html
8e0c4386eSCy Schubert  */
9e0c4386eSCy Schubert 
10e0c4386eSCy Schubert /* We need to use some deprecated APIs */
11e0c4386eSCy Schubert #define OPENSSL_SUPPRESS_DEPRECATED
12e0c4386eSCy Schubert 
13e0c4386eSCy Schubert #include <stdio.h>
14e0c4386eSCy Schubert #include <string.h>
15e0c4386eSCy Schubert #include <stdlib.h>
16e0c4386eSCy Schubert #include <openssl/e_os2.h>
17e0c4386eSCy Schubert 
18e0c4386eSCy Schubert # include "testutil.h"
19e0c4386eSCy Schubert 
20e0c4386eSCy Schubert #ifndef OPENSSL_NO_ENGINE
21e0c4386eSCy Schubert # include <openssl/buffer.h>
22e0c4386eSCy Schubert # include <openssl/crypto.h>
23e0c4386eSCy Schubert # include <openssl/engine.h>
24e0c4386eSCy Schubert # include <openssl/rsa.h>
25e0c4386eSCy Schubert # include <openssl/err.h>
26e0c4386eSCy Schubert # include <openssl/x509.h>
27e0c4386eSCy Schubert # include <openssl/pem.h>
28e0c4386eSCy Schubert 
display_engine_list(void)29e0c4386eSCy Schubert static void display_engine_list(void)
30e0c4386eSCy Schubert {
31e0c4386eSCy Schubert     ENGINE *h;
32e0c4386eSCy Schubert     int loop;
33e0c4386eSCy Schubert 
34e0c4386eSCy Schubert     loop = 0;
35e0c4386eSCy Schubert     for (h = ENGINE_get_first(); h != NULL; h = ENGINE_get_next(h)) {
36e0c4386eSCy Schubert         TEST_info("#%d: id = \"%s\", name = \"%s\"",
37e0c4386eSCy Schubert                loop++, ENGINE_get_id(h), ENGINE_get_name(h));
38e0c4386eSCy Schubert     }
39e0c4386eSCy Schubert 
40e0c4386eSCy Schubert     /*
41e0c4386eSCy Schubert      * ENGINE_get_first() increases the struct_ref counter, so we must call
42e0c4386eSCy Schubert      * ENGINE_free() to decrease it again
43e0c4386eSCy Schubert      */
44e0c4386eSCy Schubert     ENGINE_free(h);
45e0c4386eSCy Schubert }
46e0c4386eSCy Schubert 
47e0c4386eSCy Schubert #define NUMTOADD 512
48e0c4386eSCy Schubert 
test_engines(void)49e0c4386eSCy Schubert static int test_engines(void)
50e0c4386eSCy Schubert {
51e0c4386eSCy Schubert     ENGINE *block[NUMTOADD];
52e0c4386eSCy Schubert     char *eid[NUMTOADD];
53e0c4386eSCy Schubert     char *ename[NUMTOADD];
54e0c4386eSCy Schubert     char buf[256];
55e0c4386eSCy Schubert     ENGINE *ptr;
56e0c4386eSCy Schubert     int loop;
57e0c4386eSCy Schubert     int to_return = 0;
58e0c4386eSCy Schubert     ENGINE *new_h1 = NULL;
59e0c4386eSCy Schubert     ENGINE *new_h2 = NULL;
60e0c4386eSCy Schubert     ENGINE *new_h3 = NULL;
61e0c4386eSCy Schubert     ENGINE *new_h4 = NULL;
62e0c4386eSCy Schubert 
63e0c4386eSCy Schubert     memset(block, 0, sizeof(block));
64e0c4386eSCy Schubert     if (!TEST_ptr(new_h1 = ENGINE_new())
65e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_id(new_h1, "test_id0"))
66e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_name(new_h1, "First test item"))
67e0c4386eSCy Schubert             || !TEST_ptr(new_h2 = ENGINE_new())
68e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_id(new_h2, "test_id1"))
69e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_name(new_h2, "Second test item"))
70e0c4386eSCy Schubert             || !TEST_ptr(new_h3 = ENGINE_new())
71e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_id(new_h3, "test_id2"))
72e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_name(new_h3, "Third test item"))
73e0c4386eSCy Schubert             || !TEST_ptr(new_h4 = ENGINE_new())
74e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_id(new_h4, "test_id3"))
75e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_name(new_h4, "Fourth test item")))
76e0c4386eSCy Schubert         goto end;
77e0c4386eSCy Schubert     TEST_info("Engines:");
78e0c4386eSCy Schubert     display_engine_list();
79e0c4386eSCy Schubert 
80e0c4386eSCy Schubert     if (!TEST_true(ENGINE_add(new_h1)))
81e0c4386eSCy Schubert         goto end;
82e0c4386eSCy Schubert     TEST_info("Engines:");
83e0c4386eSCy Schubert     display_engine_list();
84e0c4386eSCy Schubert 
85e0c4386eSCy Schubert     ptr = ENGINE_get_first();
86e0c4386eSCy Schubert     if (!TEST_true(ENGINE_remove(ptr)))
87e0c4386eSCy Schubert         goto end;
88e0c4386eSCy Schubert     ENGINE_free(ptr);
89e0c4386eSCy Schubert     TEST_info("Engines:");
90e0c4386eSCy Schubert     display_engine_list();
91e0c4386eSCy Schubert 
92e0c4386eSCy Schubert     if (!TEST_true(ENGINE_add(new_h3))
93e0c4386eSCy Schubert             || !TEST_true(ENGINE_add(new_h2)))
94e0c4386eSCy Schubert         goto end;
95e0c4386eSCy Schubert     TEST_info("Engines:");
96e0c4386eSCy Schubert     display_engine_list();
97e0c4386eSCy Schubert 
98e0c4386eSCy Schubert     if (!TEST_true(ENGINE_remove(new_h2)))
99e0c4386eSCy Schubert         goto end;
100e0c4386eSCy Schubert     TEST_info("Engines:");
101e0c4386eSCy Schubert     display_engine_list();
102e0c4386eSCy Schubert 
103e0c4386eSCy Schubert     if (!TEST_true(ENGINE_add(new_h4)))
104e0c4386eSCy Schubert         goto end;
105e0c4386eSCy Schubert     TEST_info("Engines:");
106e0c4386eSCy Schubert     display_engine_list();
107e0c4386eSCy Schubert 
108e0c4386eSCy Schubert     /* Should fail. */
109e0c4386eSCy Schubert     if (!TEST_false(ENGINE_add(new_h3)))
110e0c4386eSCy Schubert         goto end;
111e0c4386eSCy Schubert     ERR_clear_error();
112e0c4386eSCy Schubert 
113e0c4386eSCy Schubert     /* Should fail. */
114e0c4386eSCy Schubert     if (!TEST_false(ENGINE_remove(new_h2)))
115e0c4386eSCy Schubert         goto end;
116e0c4386eSCy Schubert     ERR_clear_error();
117e0c4386eSCy Schubert 
118e0c4386eSCy Schubert     if (!TEST_true(ENGINE_remove(new_h3)))
119e0c4386eSCy Schubert         goto end;
120e0c4386eSCy Schubert     TEST_info("Engines:");
121e0c4386eSCy Schubert     display_engine_list();
122e0c4386eSCy Schubert 
123e0c4386eSCy Schubert     if (!TEST_true(ENGINE_remove(new_h4)))
124e0c4386eSCy Schubert         goto end;
125e0c4386eSCy Schubert     TEST_info("Engines:");
126e0c4386eSCy Schubert     display_engine_list();
127e0c4386eSCy Schubert 
128e0c4386eSCy Schubert     /*
129e0c4386eSCy Schubert      * At this point, we should have an empty list, unless some hardware
130e0c4386eSCy Schubert      * support engine got added.  However, since we don't allow the config
131e0c4386eSCy Schubert      * file to be loaded and don't otherwise load any built in engines,
132e0c4386eSCy Schubert      * that is unlikely.  Still, we check, if for nothing else, then to
133e0c4386eSCy Schubert      * notify that something is a little off (and might mean that |new_h1|
134e0c4386eSCy Schubert      * wasn't unloaded when it should have)
135e0c4386eSCy Schubert      */
136e0c4386eSCy Schubert     if ((ptr = ENGINE_get_first()) != NULL) {
137e0c4386eSCy Schubert         if (!ENGINE_remove(ptr))
138e0c4386eSCy Schubert             TEST_info("Remove failed - probably no hardware support present");
139e0c4386eSCy Schubert     }
140e0c4386eSCy Schubert     ENGINE_free(ptr);
141e0c4386eSCy Schubert     TEST_info("Engines:");
142e0c4386eSCy Schubert     display_engine_list();
143e0c4386eSCy Schubert 
144e0c4386eSCy Schubert     if (!TEST_true(ENGINE_add(new_h1))
145e0c4386eSCy Schubert             || !TEST_true(ENGINE_remove(new_h1)))
146e0c4386eSCy Schubert         goto end;
147e0c4386eSCy Schubert 
148e0c4386eSCy Schubert     TEST_info("About to beef up the engine-type list");
149e0c4386eSCy Schubert     for (loop = 0; loop < NUMTOADD; loop++) {
150*0d0c8621SEnji Cooper         BIO_snprintf(buf, sizeof(buf), "id%d", loop);
151e0c4386eSCy Schubert         eid[loop] = OPENSSL_strdup(buf);
152*0d0c8621SEnji Cooper         BIO_snprintf(buf, sizeof(buf), "Fake engine type %d", loop);
153e0c4386eSCy Schubert         ename[loop] = OPENSSL_strdup(buf);
154e0c4386eSCy Schubert         if (!TEST_ptr(block[loop] = ENGINE_new())
155e0c4386eSCy Schubert                 || !TEST_true(ENGINE_set_id(block[loop], eid[loop]))
156e0c4386eSCy Schubert                 || !TEST_true(ENGINE_set_name(block[loop], ename[loop])))
157e0c4386eSCy Schubert             goto end;
158e0c4386eSCy Schubert     }
159e0c4386eSCy Schubert     for (loop = 0; loop < NUMTOADD; loop++) {
160e0c4386eSCy Schubert         if (!TEST_true(ENGINE_add(block[loop]))) {
161e0c4386eSCy Schubert             test_note("Adding stopped at %d, (%s,%s)",
162e0c4386eSCy Schubert                       loop, ENGINE_get_id(block[loop]),
163e0c4386eSCy Schubert                       ENGINE_get_name(block[loop]));
164e0c4386eSCy Schubert             goto cleanup_loop;
165e0c4386eSCy Schubert         }
166e0c4386eSCy Schubert     }
167e0c4386eSCy Schubert  cleanup_loop:
168e0c4386eSCy Schubert     TEST_info("About to empty the engine-type list");
169e0c4386eSCy Schubert     while ((ptr = ENGINE_get_first()) != NULL) {
170e0c4386eSCy Schubert         if (!TEST_true(ENGINE_remove(ptr)))
171e0c4386eSCy Schubert             goto end;
172e0c4386eSCy Schubert         ENGINE_free(ptr);
173e0c4386eSCy Schubert     }
174e0c4386eSCy Schubert     for (loop = 0; loop < NUMTOADD; loop++) {
175e0c4386eSCy Schubert         OPENSSL_free(eid[loop]);
176e0c4386eSCy Schubert         OPENSSL_free(ename[loop]);
177e0c4386eSCy Schubert     }
178e0c4386eSCy Schubert     to_return = 1;
179e0c4386eSCy Schubert 
180e0c4386eSCy Schubert  end:
181e0c4386eSCy Schubert     ENGINE_free(new_h1);
182e0c4386eSCy Schubert     ENGINE_free(new_h2);
183e0c4386eSCy Schubert     ENGINE_free(new_h3);
184e0c4386eSCy Schubert     ENGINE_free(new_h4);
185e0c4386eSCy Schubert     for (loop = 0; loop < NUMTOADD; loop++)
186e0c4386eSCy Schubert         ENGINE_free(block[loop]);
187e0c4386eSCy Schubert     return to_return;
188e0c4386eSCy Schubert }
189e0c4386eSCy Schubert 
190e0c4386eSCy Schubert /* Test EVP_PKEY method */
191e0c4386eSCy Schubert static EVP_PKEY_METHOD *test_rsa = NULL;
192e0c4386eSCy Schubert 
193e0c4386eSCy Schubert static int called_encrypt = 0;
194e0c4386eSCy Schubert 
195e0c4386eSCy Schubert /* Test function to check operation has been redirected */
test_encrypt(EVP_PKEY_CTX * ctx,unsigned char * sig,size_t * siglen,const unsigned char * tbs,size_t tbslen)196e0c4386eSCy Schubert static int test_encrypt(EVP_PKEY_CTX *ctx, unsigned char *sig,
197e0c4386eSCy Schubert                         size_t *siglen, const unsigned char *tbs, size_t tbslen)
198e0c4386eSCy Schubert {
199e0c4386eSCy Schubert     called_encrypt = 1;
200e0c4386eSCy Schubert     return 1;
201e0c4386eSCy Schubert }
202e0c4386eSCy Schubert 
test_pkey_meths(ENGINE * e,EVP_PKEY_METHOD ** pmeth,const int ** pnids,int nid)203e0c4386eSCy Schubert static int test_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
204e0c4386eSCy Schubert                            const int **pnids, int nid)
205e0c4386eSCy Schubert {
206e0c4386eSCy Schubert     static const int rnid = EVP_PKEY_RSA;
207e0c4386eSCy Schubert     if (pmeth == NULL) {
208e0c4386eSCy Schubert         *pnids = &rnid;
209e0c4386eSCy Schubert         return 1;
210e0c4386eSCy Schubert     }
211e0c4386eSCy Schubert 
212e0c4386eSCy Schubert     if (nid == EVP_PKEY_RSA) {
213e0c4386eSCy Schubert         *pmeth = test_rsa;
214e0c4386eSCy Schubert         return 1;
215e0c4386eSCy Schubert     }
216e0c4386eSCy Schubert 
217e0c4386eSCy Schubert     *pmeth = NULL;
218e0c4386eSCy Schubert     return 0;
219e0c4386eSCy Schubert }
220e0c4386eSCy Schubert 
221e0c4386eSCy Schubert /* Return a test EVP_PKEY value */
222e0c4386eSCy Schubert 
get_test_pkey(void)223e0c4386eSCy Schubert static EVP_PKEY *get_test_pkey(void)
224e0c4386eSCy Schubert {
225e0c4386eSCy Schubert     static unsigned char n[] =
226e0c4386eSCy Schubert         "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
227e0c4386eSCy Schubert         "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
228e0c4386eSCy Schubert         "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
229e0c4386eSCy Schubert         "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
230e0c4386eSCy Schubert         "\xF5";
231e0c4386eSCy Schubert     static unsigned char e[] = "\x11";
232e0c4386eSCy Schubert 
233e0c4386eSCy Schubert     RSA *rsa = RSA_new();
234e0c4386eSCy Schubert     EVP_PKEY *pk = EVP_PKEY_new();
235e0c4386eSCy Schubert 
236e0c4386eSCy Schubert     if (rsa == NULL || pk == NULL || !EVP_PKEY_assign_RSA(pk, rsa)) {
237e0c4386eSCy Schubert         RSA_free(rsa);
238e0c4386eSCy Schubert         EVP_PKEY_free(pk);
239e0c4386eSCy Schubert         return NULL;
240e0c4386eSCy Schubert     }
241e0c4386eSCy Schubert 
242e0c4386eSCy Schubert     if (!RSA_set0_key(rsa, BN_bin2bn(n, sizeof(n)-1, NULL),
243e0c4386eSCy Schubert                       BN_bin2bn(e, sizeof(e)-1, NULL), NULL)) {
244e0c4386eSCy Schubert         EVP_PKEY_free(pk);
245e0c4386eSCy Schubert         return NULL;
246e0c4386eSCy Schubert     }
247e0c4386eSCy Schubert 
248e0c4386eSCy Schubert     return pk;
249e0c4386eSCy Schubert }
250e0c4386eSCy Schubert 
test_redirect(void)251e0c4386eSCy Schubert static int test_redirect(void)
252e0c4386eSCy Schubert {
253e0c4386eSCy Schubert     const unsigned char pt[] = "Hello World\n";
254e0c4386eSCy Schubert     unsigned char *tmp = NULL;
255e0c4386eSCy Schubert     size_t len;
256e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL;
257e0c4386eSCy Schubert     ENGINE *e = NULL;
258e0c4386eSCy Schubert     EVP_PKEY *pkey = NULL;
259e0c4386eSCy Schubert 
260e0c4386eSCy Schubert     int to_return = 0;
261e0c4386eSCy Schubert 
262e0c4386eSCy Schubert     if (!TEST_ptr(pkey = get_test_pkey()))
263e0c4386eSCy Schubert         goto err;
264e0c4386eSCy Schubert 
265e0c4386eSCy Schubert     len = EVP_PKEY_get_size(pkey);
266e0c4386eSCy Schubert     if (!TEST_ptr(tmp = OPENSSL_malloc(len)))
267e0c4386eSCy Schubert         goto err;
268e0c4386eSCy Schubert 
269e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
270e0c4386eSCy Schubert         goto err;
271e0c4386eSCy Schubert     TEST_info("EVP_PKEY_encrypt test: no redirection");
272e0c4386eSCy Schubert     /* Encrypt some data: should succeed but not be redirected */
273e0c4386eSCy Schubert     if (!TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
274e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
275e0c4386eSCy Schubert             || !TEST_false(called_encrypt))
276e0c4386eSCy Schubert         goto err;
277e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
278e0c4386eSCy Schubert     ctx = NULL;
279e0c4386eSCy Schubert 
280e0c4386eSCy Schubert     /* Create a test ENGINE */
281e0c4386eSCy Schubert     if (!TEST_ptr(e = ENGINE_new())
282e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_id(e, "Test redirect engine"))
283e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_name(e, "Test redirect engine")))
284e0c4386eSCy Schubert         goto err;
285e0c4386eSCy Schubert 
286e0c4386eSCy Schubert     /*
287e0c4386eSCy Schubert      * Try to create a context for this engine and test key.
288e0c4386eSCy Schubert      * Try setting test key engine. Both should fail because the
289e0c4386eSCy Schubert      * engine has no public key methods.
290e0c4386eSCy Schubert      */
291e0c4386eSCy Schubert     if (!TEST_ptr_null(ctx = EVP_PKEY_CTX_new(pkey, e))
292e0c4386eSCy Schubert             || !TEST_int_le(EVP_PKEY_set1_engine(pkey, e), 0))
293e0c4386eSCy Schubert         goto err;
294e0c4386eSCy Schubert 
295e0c4386eSCy Schubert     /* Setup an empty test EVP_PKEY_METHOD and set callback to return it */
296e0c4386eSCy Schubert     if (!TEST_ptr(test_rsa = EVP_PKEY_meth_new(EVP_PKEY_RSA, 0)))
297e0c4386eSCy Schubert         goto err;
298e0c4386eSCy Schubert     ENGINE_set_pkey_meths(e, test_pkey_meths);
299e0c4386eSCy Schubert 
300e0c4386eSCy Schubert     /* Getting a context for test ENGINE should now succeed */
301e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, e)))
302e0c4386eSCy Schubert         goto err;
303e0c4386eSCy Schubert     /* Encrypt should fail because operation is not supported */
304e0c4386eSCy Schubert     if (!TEST_int_le(EVP_PKEY_encrypt_init(ctx), 0))
305e0c4386eSCy Schubert         goto err;
306e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
307e0c4386eSCy Schubert     ctx = NULL;
308e0c4386eSCy Schubert 
309e0c4386eSCy Schubert     /* Add test encrypt operation to method */
310e0c4386eSCy Schubert     EVP_PKEY_meth_set_encrypt(test_rsa, 0, test_encrypt);
311e0c4386eSCy Schubert 
312e0c4386eSCy Schubert     TEST_info("EVP_PKEY_encrypt test: redirection via EVP_PKEY_CTX_new()");
313e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, e)))
314e0c4386eSCy Schubert         goto err;
315e0c4386eSCy Schubert     /* Encrypt some data: should succeed and be redirected */
316e0c4386eSCy Schubert     if (!TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
317e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
318e0c4386eSCy Schubert             || !TEST_true(called_encrypt))
319e0c4386eSCy Schubert         goto err;
320e0c4386eSCy Schubert 
321e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
322e0c4386eSCy Schubert     ctx = NULL;
323e0c4386eSCy Schubert     called_encrypt = 0;
324e0c4386eSCy Schubert 
325e0c4386eSCy Schubert     /* Create context with default engine: should not be redirected */
326e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL))
327e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
328e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
329e0c4386eSCy Schubert             || !TEST_false(called_encrypt))
330e0c4386eSCy Schubert         goto err;
331e0c4386eSCy Schubert 
332e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
333e0c4386eSCy Schubert     ctx = NULL;
334e0c4386eSCy Schubert 
335e0c4386eSCy Schubert     /* Set engine explicitly for test key */
336e0c4386eSCy Schubert     if (!TEST_true(EVP_PKEY_set1_engine(pkey, e)))
337e0c4386eSCy Schubert         goto err;
338e0c4386eSCy Schubert 
339e0c4386eSCy Schubert     TEST_info("EVP_PKEY_encrypt test: redirection via EVP_PKEY_set1_engine()");
340e0c4386eSCy Schubert 
341e0c4386eSCy Schubert     /* Create context with default engine: should be redirected now */
342e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL))
343e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
344e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
345e0c4386eSCy Schubert             || !TEST_true(called_encrypt))
346e0c4386eSCy Schubert         goto err;
347e0c4386eSCy Schubert 
348e0c4386eSCy Schubert     to_return = 1;
349e0c4386eSCy Schubert 
350e0c4386eSCy Schubert  err:
351e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
352e0c4386eSCy Schubert     EVP_PKEY_free(pkey);
353e0c4386eSCy Schubert     ENGINE_free(e);
354e0c4386eSCy Schubert     OPENSSL_free(tmp);
355e0c4386eSCy Schubert     return to_return;
356e0c4386eSCy Schubert }
357e0c4386eSCy Schubert 
test_x509_dup_w_engine(void)358e0c4386eSCy Schubert static int test_x509_dup_w_engine(void)
359e0c4386eSCy Schubert {
360e0c4386eSCy Schubert     ENGINE *e = NULL;
361e0c4386eSCy Schubert     X509 *cert = NULL, *dupcert = NULL;
362e0c4386eSCy Schubert     X509_PUBKEY *pubkey, *duppubkey = NULL;
363e0c4386eSCy Schubert     int ret = 0;
364e0c4386eSCy Schubert     BIO *b = NULL;
365e0c4386eSCy Schubert     RSA_METHOD *rsameth = NULL;
366e0c4386eSCy Schubert 
367e0c4386eSCy Schubert     if (!TEST_ptr(b = BIO_new_file(test_get_argument(0), "r"))
368e0c4386eSCy Schubert         || !TEST_ptr(cert = PEM_read_bio_X509(b, NULL, NULL, NULL)))
369e0c4386eSCy Schubert         goto err;
370e0c4386eSCy Schubert 
371e0c4386eSCy Schubert     /* Dup without an engine */
372e0c4386eSCy Schubert     if (!TEST_ptr(dupcert = X509_dup(cert)))
373e0c4386eSCy Schubert         goto err;
374e0c4386eSCy Schubert     X509_free(dupcert);
375e0c4386eSCy Schubert     dupcert = NULL;
376e0c4386eSCy Schubert 
377e0c4386eSCy Schubert     if (!TEST_ptr(pubkey = X509_get_X509_PUBKEY(cert))
378e0c4386eSCy Schubert         || !TEST_ptr(duppubkey = X509_PUBKEY_dup(pubkey))
379e0c4386eSCy Schubert         || !TEST_ptr_ne(duppubkey, pubkey)
380e0c4386eSCy Schubert         || !TEST_ptr_ne(X509_PUBKEY_get0(duppubkey), X509_PUBKEY_get0(pubkey)))
381e0c4386eSCy Schubert         goto err;
382e0c4386eSCy Schubert 
383e0c4386eSCy Schubert     X509_PUBKEY_free(duppubkey);
384e0c4386eSCy Schubert     duppubkey = NULL;
385e0c4386eSCy Schubert 
386e0c4386eSCy Schubert     X509_free(cert);
387e0c4386eSCy Schubert     cert = NULL;
388e0c4386eSCy Schubert 
389e0c4386eSCy Schubert     /* Create a test ENGINE */
390e0c4386eSCy Schubert     if (!TEST_ptr(e = ENGINE_new())
391e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_id(e, "Test dummy engine"))
392e0c4386eSCy Schubert             || !TEST_true(ENGINE_set_name(e, "Test dummy engine")))
393e0c4386eSCy Schubert         goto err;
394e0c4386eSCy Schubert 
395e0c4386eSCy Schubert     if (!TEST_ptr(rsameth = RSA_meth_dup(RSA_get_default_method())))
396e0c4386eSCy Schubert         goto err;
397e0c4386eSCy Schubert 
398e0c4386eSCy Schubert     ENGINE_set_RSA(e, rsameth);
399e0c4386eSCy Schubert 
400e0c4386eSCy Schubert     if (!TEST_true(ENGINE_set_default_RSA(e)))
401e0c4386eSCy Schubert         goto err;
402e0c4386eSCy Schubert 
403e0c4386eSCy Schubert     if (!TEST_int_ge(BIO_seek(b, 0), 0)
404e0c4386eSCy Schubert         || !TEST_ptr(cert = PEM_read_bio_X509(b, NULL, NULL, NULL)))
405e0c4386eSCy Schubert         goto err;
406e0c4386eSCy Schubert 
407e0c4386eSCy Schubert     /* Dup with an engine set on the key */
408e0c4386eSCy Schubert     if (!TEST_ptr(dupcert = X509_dup(cert)))
409e0c4386eSCy Schubert         goto err;
410e0c4386eSCy Schubert 
411e0c4386eSCy Schubert     if (!TEST_ptr(pubkey = X509_get_X509_PUBKEY(cert))
412e0c4386eSCy Schubert         || !TEST_ptr(duppubkey = X509_PUBKEY_dup(pubkey))
413e0c4386eSCy Schubert         || !TEST_ptr_ne(duppubkey, pubkey)
414e0c4386eSCy Schubert         || !TEST_ptr_ne(X509_PUBKEY_get0(duppubkey), X509_PUBKEY_get0(pubkey)))
415e0c4386eSCy Schubert         goto err;
416e0c4386eSCy Schubert 
417e0c4386eSCy Schubert     ret = 1;
418e0c4386eSCy Schubert 
419e0c4386eSCy Schubert  err:
420e0c4386eSCy Schubert     X509_free(cert);
421e0c4386eSCy Schubert     X509_free(dupcert);
422e0c4386eSCy Schubert     X509_PUBKEY_free(duppubkey);
423e0c4386eSCy Schubert     if (e != NULL) {
424e0c4386eSCy Schubert         ENGINE_unregister_RSA(e);
425e0c4386eSCy Schubert         ENGINE_free(e);
426e0c4386eSCy Schubert     }
427e0c4386eSCy Schubert     RSA_meth_free(rsameth);
428e0c4386eSCy Schubert     BIO_free(b);
429e0c4386eSCy Schubert     return ret;
430e0c4386eSCy Schubert }
431e0c4386eSCy Schubert #endif
432e0c4386eSCy Schubert 
global_init(void)433e0c4386eSCy Schubert int global_init(void)
434e0c4386eSCy Schubert {
435e0c4386eSCy Schubert     /*
436e0c4386eSCy Schubert      * If the config file gets loaded, the dynamic engine will be loaded,
437e0c4386eSCy Schubert      * and that interferes with our test above.
438e0c4386eSCy Schubert      */
439e0c4386eSCy Schubert     return OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL);
440e0c4386eSCy Schubert }
441e0c4386eSCy Schubert 
442e0c4386eSCy Schubert OPT_TEST_DECLARE_USAGE("certfile\n")
443e0c4386eSCy Schubert 
setup_tests(void)444e0c4386eSCy Schubert int setup_tests(void)
445e0c4386eSCy Schubert {
446e0c4386eSCy Schubert #ifdef OPENSSL_NO_ENGINE
447e0c4386eSCy Schubert     TEST_note("No ENGINE support");
448e0c4386eSCy Schubert #else
449e0c4386eSCy Schubert     int n;
450e0c4386eSCy Schubert 
451e0c4386eSCy Schubert     if (!test_skip_common_options()) {
452e0c4386eSCy Schubert         TEST_error("Error parsing test options\n");
453e0c4386eSCy Schubert         return 0;
454e0c4386eSCy Schubert     }
455e0c4386eSCy Schubert 
456e0c4386eSCy Schubert     n = test_get_argument_count();
457e0c4386eSCy Schubert     if (n == 0)
458e0c4386eSCy Schubert         return 0;
459e0c4386eSCy Schubert 
460e0c4386eSCy Schubert     ADD_TEST(test_engines);
461e0c4386eSCy Schubert     ADD_TEST(test_redirect);
462e0c4386eSCy Schubert     ADD_TEST(test_x509_dup_w_engine);
463e0c4386eSCy Schubert #endif
464e0c4386eSCy Schubert     return 1;
465e0c4386eSCy Schubert }
466