Fix a bunch of gcc warnings in packettest.c
[openssl.git] / test / shlibloadtest.c
1 /*
2  * Copyright 2016-2017 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 <stdlib.h>
13 #include <openssl/opensslv.h>
14 #include <openssl/ssl.h>
15 #include <openssl/ossl_typ.h>
16 #include "testutil.h"
17
18 typedef const SSL_METHOD * (*TLS_method_t)(void);
19 typedef SSL_CTX * (*SSL_CTX_new_t)(const SSL_METHOD *meth);
20 typedef void (*SSL_CTX_free_t)(SSL_CTX *);
21 typedef unsigned long (*ERR_get_error_t)(void);
22 typedef unsigned long (*OpenSSL_version_num_t)(void);
23
24 typedef enum test_types_en {
25     CRYPTO_FIRST,
26     SSL_FIRST,
27     JUST_CRYPTO
28 } TEST_TYPE;
29
30 static TEST_TYPE test_type;
31 static const char *path_crypto;
32 static const char *path_ssl;
33
34 #ifdef DSO_DLFCN
35
36 # include <dlfcn.h>
37
38 # define SHLIB_INIT NULL
39
40 typedef void *SHLIB;
41 typedef void *SHLIB_SYM;
42
43 static int shlib_load(const char *filename, SHLIB *lib)
44 {
45     *lib = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
46     return *lib == NULL ? 0 : 1;
47 }
48
49 static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
50 {
51     *sym = dlsym(lib, symname);
52     return *sym != NULL;
53 }
54
55 # ifdef OPENSSL_USE_NODELETE
56 static int shlib_close(SHLIB lib)
57 {
58     return dlclose(lib) != 0 ? 0 : 1;
59 }
60 # endif
61 #endif
62
63 #ifdef DSO_WIN32
64
65 # include <windows.h>
66
67 # define SHLIB_INIT 0
68
69 typedef HINSTANCE SHLIB;
70 typedef void *SHLIB_SYM;
71
72 static int shlib_load(const char *filename, SHLIB *lib)
73 {
74     *lib = LoadLibraryA(filename);
75     return *lib == NULL ? 0 : 1;
76 }
77
78 static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
79 {
80     *sym = (SHLIB_SYM)GetProcAddress(lib, symname);
81     return *sym != NULL;
82 }
83
84 # ifdef OPENSSL_USE_NODELETE
85 static int shlib_close(SHLIB lib)
86 {
87     return FreeLibrary(lib) == 0 ? 0 : 1;
88 }
89 # endif
90 #endif
91
92
93 #if defined(DSO_DLFCN) || defined(DSO_WIN32)
94
95 static int test_lib(void)
96 {
97     SHLIB ssllib = SHLIB_INIT;
98     SHLIB cryptolib = SHLIB_INIT;
99     SSL_CTX *ctx;
100     union {
101         void (*func)(void);
102         SHLIB_SYM sym;
103     } symbols[3];
104     TLS_method_t myTLS_method;
105     SSL_CTX_new_t mySSL_CTX_new;
106     SSL_CTX_free_t mySSL_CTX_free;
107     ERR_get_error_t myERR_get_error;
108     OpenSSL_version_num_t myOpenSSL_version_num;
109     int result = 0;
110
111     switch (test_type) {
112     case JUST_CRYPTO:
113         if (!TEST_true(shlib_load(path_crypto, &cryptolib)))
114             goto end;
115         break;
116     case CRYPTO_FIRST:
117         if (!TEST_true(shlib_load(path_crypto, &cryptolib))
118                 || !TEST_true(shlib_load(path_ssl, &ssllib)))
119             goto end;
120         break;
121     case SSL_FIRST:
122         if (!TEST_true(shlib_load(path_ssl, &ssllib))
123                 || !TEST_true(shlib_load(path_crypto, &cryptolib)))
124             goto end;
125         break;
126     }
127
128     if (test_type != JUST_CRYPTO) {
129         if (!TEST_true(shlib_sym(ssllib, "TLS_method", &symbols[0].sym))
130                 || !TEST_true(shlib_sym(ssllib, "SSL_CTX_new", &symbols[1].sym))
131                 || !TEST_true(shlib_sym(ssllib, "SSL_CTX_free", &symbols[2].sym)))
132             goto end;
133         myTLS_method = (TLS_method_t)symbols[0].func;
134         mySSL_CTX_new = (SSL_CTX_new_t)symbols[1].func;
135         mySSL_CTX_free = (SSL_CTX_free_t)symbols[2].func;
136         if (!TEST_ptr(ctx = mySSL_CTX_new(myTLS_method())))
137             goto end;
138         mySSL_CTX_free(ctx);
139     }
140
141     if (!TEST_true(shlib_sym(cryptolib, "ERR_get_error", &symbols[0].sym))
142             || !TEST_true(shlib_sym(cryptolib, "OpenSSL_version_num",
143                                     &symbols[1].sym)))
144         goto end;
145     myERR_get_error = (ERR_get_error_t)symbols[0].func;
146     if (!TEST_int_eq(myERR_get_error(), 0))
147         goto end;
148     myOpenSSL_version_num = (OpenSSL_version_num_t)symbols[1].func;
149     if (!TEST_int_eq(myOpenSSL_version_num(), OPENSSL_VERSION_NUMBER))
150         goto end;
151
152 #ifdef OPENSSL_USE_NODELETE
153     switch (test_type) {
154     case JUST_CRYPTO:
155         if (!TEST_true(shlib_close(cryptolib)))
156             goto end;
157         break;
158     case CRYPTO_FIRST:
159         if (!TEST_true(shlib_close(cryptolib))
160                 || !TEST_true(shlib_close(ssllib)))
161             goto end;
162         break;
163     case SSL_FIRST:
164         if (!TEST_true(shlib_close(ssllib))
165                 || !TEST_true(shlib_close(cryptolib)))
166             goto end;
167         break;
168     }
169 #endif
170
171     result = 1;
172 end:
173     return result;
174 }
175 #endif
176
177
178 int setup_tests(void)
179 {
180     const char *p = test_get_argument(0);
181
182     if (strcmp(p, "-crypto_first") == 0) {
183         test_type = CRYPTO_FIRST;
184     } else if (strcmp(p, "-ssl_first") == 0) {
185         test_type = SSL_FIRST;
186     } else if (strcmp(p, "-just_crypto") == 0) {
187         test_type = JUST_CRYPTO;
188     } else {
189         TEST_error("Unrecognised argument");
190         return 0;
191     }
192     if (!TEST_ptr(path_crypto = test_get_argument(1))
193             || !TEST_ptr(path_ssl = test_get_argument(2)))
194         return 0;
195
196 #if defined(DSO_DLFCN) || defined(DSO_WIN32)
197     ADD_TEST(test_lib);
198 #endif
199     return 1;
200 }