Gracefully free a NULL HANDSHAKE_RESULT
[openssl.git] / test / enginetest.c
1 /*
2  * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 #include <stdio.h>
11 #include <string.h>
12 #include <openssl/e_os2.h>
13
14 #ifdef OPENSSL_NO_ENGINE
15 int main(int argc, char *argv[])
16 {
17     printf("No ENGINE support\n");
18     return (0);
19 }
20 #else
21 # include <openssl/buffer.h>
22 # include <openssl/crypto.h>
23 # include <openssl/engine.h>
24 # include <openssl/err.h>
25
26 static void display_engine_list(void)
27 {
28     ENGINE *h;
29     int loop;
30
31     h = ENGINE_get_first();
32     loop = 0;
33     printf("listing available engine types\n");
34     while (h) {
35         printf("engine %i, id = \"%s\", name = \"%s\"\n",
36                loop++, ENGINE_get_id(h), ENGINE_get_name(h));
37         h = ENGINE_get_next(h);
38     }
39     printf("end of list\n");
40     /*
41      * ENGINE_get_first() increases the struct_ref counter, so we must call
42      * ENGINE_free() to decrease it again
43      */
44     ENGINE_free(h);
45 }
46
47 int main(int argc, char *argv[])
48 {
49     ENGINE *block[512];
50     char buf[256];
51     const char *id, *name, *p;
52     ENGINE *ptr;
53     int loop;
54     int to_return = 1;
55     ENGINE *new_h1 = NULL;
56     ENGINE *new_h2 = NULL;
57     ENGINE *new_h3 = NULL;
58     ENGINE *new_h4 = NULL;
59
60     p = getenv("OPENSSL_DEBUG_MEMORY");
61     if (p != NULL && strcmp(p, "on") == 0)
62         CRYPTO_set_mem_debug(1);
63
64     memset(block, 0, sizeof(block));
65     if (((new_h1 = ENGINE_new()) == NULL) ||
66         !ENGINE_set_id(new_h1, "test_id0") ||
67         !ENGINE_set_name(new_h1, "First test item") ||
68         ((new_h2 = ENGINE_new()) == NULL) ||
69         !ENGINE_set_id(new_h2, "test_id1") ||
70         !ENGINE_set_name(new_h2, "Second test item") ||
71         ((new_h3 = ENGINE_new()) == NULL) ||
72         !ENGINE_set_id(new_h3, "test_id2") ||
73         !ENGINE_set_name(new_h3, "Third test item") ||
74         ((new_h4 = ENGINE_new()) == NULL) ||
75         !ENGINE_set_id(new_h4, "test_id3") ||
76         !ENGINE_set_name(new_h4, "Fourth test item")) {
77         printf("Couldn't set up test ENGINE structures\n");
78         goto end;
79     }
80     printf("\nenginetest beginning\n\n");
81     display_engine_list();
82     if (!ENGINE_add(new_h1)) {
83         printf("Add failed!\n");
84         goto end;
85     }
86     display_engine_list();
87     ptr = ENGINE_get_first();
88     if (!ENGINE_remove(ptr)) {
89         printf("Remove failed!\n");
90         goto end;
91     }
92     ENGINE_free(ptr);
93     display_engine_list();
94     if (!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) {
95         printf("Add failed!\n");
96         goto end;
97     }
98     display_engine_list();
99     if (!ENGINE_remove(new_h2)) {
100         printf("Remove failed!\n");
101         goto end;
102     }
103     display_engine_list();
104     if (!ENGINE_add(new_h4)) {
105         printf("Add failed!\n");
106         goto end;
107     }
108     display_engine_list();
109     if (ENGINE_add(new_h3)) {
110         printf("Add *should* have failed but didn't!\n");
111         goto end;
112     } else
113         printf("Add that should fail did.\n");
114     ERR_clear_error();
115     if (ENGINE_remove(new_h2)) {
116         printf("Remove *should* have failed but didn't!\n");
117         goto end;
118     } else
119         printf("Remove that should fail did.\n");
120     ERR_clear_error();
121     if (!ENGINE_remove(new_h3)) {
122         printf("Remove failed!\n");
123         goto end;
124     }
125     display_engine_list();
126     if (!ENGINE_remove(new_h4)) {
127         printf("Remove failed!\n");
128         goto end;
129     }
130     display_engine_list();
131     /*
132      * Depending on whether there's any hardware support compiled in, this
133      * remove may be destined to fail.
134      */
135     ptr = ENGINE_get_first();
136     if (ptr)
137         if (!ENGINE_remove(ptr))
138             printf("Remove failed!i - probably no hardware "
139                    "support present.\n");
140     ENGINE_free(ptr);
141     display_engine_list();
142     if (!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) {
143         printf("Couldn't add and remove to an empty list!\n");
144         goto end;
145     } else
146         printf("Successfully added and removed to an empty list!\n");
147     printf("About to beef up the engine-type list\n");
148     for (loop = 0; loop < 512; loop++) {
149         sprintf(buf, "id%i", loop);
150         id = OPENSSL_strdup(buf);
151         sprintf(buf, "Fake engine type %i", loop);
152         name = OPENSSL_strdup(buf);
153         if (((block[loop] = ENGINE_new()) == NULL) ||
154             !ENGINE_set_id(block[loop], id) ||
155             !ENGINE_set_name(block[loop], name)) {
156             printf("Couldn't create block of ENGINE structures.\n"
157                    "I'll probably also core-dump now, damn.\n");
158             goto end;
159         }
160     }
161     for (loop = 0; loop < 512; loop++) {
162         if (!ENGINE_add(block[loop])) {
163             printf("\nAdding stopped at %i, (%s,%s)\n",
164                    loop, ENGINE_get_id(block[loop]),
165                    ENGINE_get_name(block[loop]));
166             goto cleanup_loop;
167         } else
168             printf(".");
169         fflush(stdout);
170     }
171  cleanup_loop:
172     printf("\nAbout to empty the engine-type list\n");
173     while ((ptr = ENGINE_get_first()) != NULL) {
174         if (!ENGINE_remove(ptr)) {
175             printf("\nRemove failed!\n");
176             goto end;
177         }
178         ENGINE_free(ptr);
179         printf(".");
180         fflush(stdout);
181     }
182     for (loop = 0; loop < 512; loop++) {
183         OPENSSL_free((void *)ENGINE_get_id(block[loop]));
184         OPENSSL_free((void *)ENGINE_get_name(block[loop]));
185     }
186     printf("\nTests completed happily\n");
187     to_return = 0;
188  end:
189     if (to_return)
190         ERR_print_errors_fp(stderr);
191     ENGINE_free(new_h1);
192     ENGINE_free(new_h2);
193     ENGINE_free(new_h3);
194     ENGINE_free(new_h4);
195     for (loop = 0; loop < 512; loop++)
196         ENGINE_free(block[loop]);
197
198 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
199     if (CRYPTO_mem_leaks_fp(stderr) <= 0)
200         to_return = 1;
201 #endif
202     return to_return;
203 }
204 #endif