Add comments to test_ciphersuite_change()
[openssl.git] / test / shlibloadtest.c
1 /*
2  * Copyright 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 <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     case SSL_FIRST:
121         if (!TEST_true(shlib_load(path_ssl, &ssllib))
122                 || !TEST_true(shlib_load(path_crypto, &cryptolib)))
123             goto end;
124         break;
125     }
126
127     if (test_type != JUST_CRYPTO) {
128         if (!TEST_true(shlib_sym(ssllib, "TLS_method", &symbols[0].sym))
129                 || !TEST_true(shlib_sym(ssllib, "SSL_CTX_new", &symbols[1].sym))
130                 || !TEST_true(shlib_sym(ssllib, "SSL_CTX_free", &symbols[2].sym)))
131             goto end;
132         myTLS_method = (TLS_method_t)symbols[0].func;
133         mySSL_CTX_new = (SSL_CTX_new_t)symbols[1].func;
134         mySSL_CTX_free = (SSL_CTX_free_t)symbols[2].func;
135         if (!TEST_ptr(ctx = mySSL_CTX_new(myTLS_method())))
136             goto end;
137         mySSL_CTX_free(ctx);
138     }
139
140     if (!TEST_true(shlib_sym(cryptolib, "ERR_get_error", &symbols[0].sym))
141             || !TEST_true(shlib_sym(cryptolib, "OpenSSL_version_num",
142                                     &symbols[1].sym)))
143         goto end;
144     myERR_get_error = (ERR_get_error_t)symbols[0].func;
145     if (!TEST_int_eq(myERR_get_error(), 0))
146         goto end;
147     myOpenSSL_version_num = (OpenSSL_version_num_t)symbols[1].func;
148     if (!TEST_int_eq(myOpenSSL_version_num(), OPENSSL_VERSION_NUMBER))
149         goto end;
150
151 #ifdef OPENSSL_USE_NODELETE
152     switch (test_type) {
153     case JUST_CRYPTO:
154         if (!TEST_true(shlib_close(cryptolib)))
155             goto end;
156         break;
157     case CRYPTO_FIRST:
158         if (!TEST_true(shlib_close(cryptolib))
159                 || !TEST_true(shlib_close(ssllib)))
160             goto end;
161     case SSL_FIRST:
162         if (!TEST_true(shlib_close(ssllib))
163                 || !TEST_true(shlib_close(cryptolib)))
164             goto end;
165         break;
166     }
167 #endif
168
169     result = 1;
170 end:
171     return result;
172 }
173 #endif
174
175
176 int test_main(int argc, char **argv)
177 {
178     if (argc != 4) {
179         TEST_error("Unexpected number of arguments");
180         return EXIT_FAILURE;
181     }
182
183     if (strcmp(argv[1], "-crypto_first") == 0) {
184         test_type = CRYPTO_FIRST;
185     } else if (strcmp(argv[1], "-ssl_first") == 0) {
186         test_type = SSL_FIRST;
187     } else if (strcmp(argv[1], "-just_crypto") == 0) {
188         test_type = JUST_CRYPTO;
189     } else {
190         TEST_error("Unrecognised argument");
191         return EXIT_FAILURE;
192     }
193     path_crypto = argv[2];
194     path_ssl = argv[3];
195
196 #if defined(DSO_DLFCN) || defined(DSO_WIN32)
197     ADD_TEST(test_lib);
198 #endif
199     return run_tests(argv[0]);
200 }