Home | History | Annotate | Line # | Download | only in test
shlibloadtest.c revision 1.1
      1  1.1  christos /*
      2  1.1  christos  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
      3  1.1  christos  *
      4  1.1  christos  * Licensed under the OpenSSL license (the "License").  You may not use
      5  1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6  1.1  christos  * in the file LICENSE in the source distribution or at
      7  1.1  christos  * https://www.openssl.org/source/license.html
      8  1.1  christos  */
      9  1.1  christos 
     10  1.1  christos #include <stdio.h>
     11  1.1  christos #include <string.h>
     12  1.1  christos #include <stdlib.h>
     13  1.1  christos #include <openssl/opensslv.h>
     14  1.1  christos 
     15  1.1  christos /* The test is only currently implemented for DSO_DLFCN and DSO_WIN32 */
     16  1.1  christos #if defined(DSO_DLFCN) || defined(DSO_WIN32)
     17  1.1  christos 
     18  1.1  christos #define SSL_CTX_NEW "SSL_CTX_new"
     19  1.1  christos #define SSL_CTX_FREE "SSL_CTX_free"
     20  1.1  christos #define TLS_METHOD "TLS_method"
     21  1.1  christos 
     22  1.1  christos #define ERR_GET_ERROR "ERR_get_error"
     23  1.1  christos #define OPENSSL_VERSION_NUM_FUNC "OpenSSL_version_num"
     24  1.1  christos 
     25  1.1  christos typedef struct ssl_ctx_st SSL_CTX;
     26  1.1  christos typedef struct ssl_method_st SSL_METHOD;
     27  1.1  christos typedef const SSL_METHOD * (*TLS_method_t)(void);
     28  1.1  christos typedef SSL_CTX * (*SSL_CTX_new_t)(const SSL_METHOD *meth);
     29  1.1  christos typedef void (*SSL_CTX_free_t)(SSL_CTX *);
     30  1.1  christos 
     31  1.1  christos typedef unsigned long (*ERR_get_error_t)(void);
     32  1.1  christos typedef unsigned long (*OpenSSL_version_num_t)(void);
     33  1.1  christos 
     34  1.1  christos static TLS_method_t TLS_method;
     35  1.1  christos static SSL_CTX_new_t SSL_CTX_new;
     36  1.1  christos static SSL_CTX_free_t SSL_CTX_free;
     37  1.1  christos 
     38  1.1  christos static ERR_get_error_t ERR_get_error;
     39  1.1  christos static OpenSSL_version_num_t OpenSSL_version_num;
     40  1.1  christos 
     41  1.1  christos #ifdef DSO_DLFCN
     42  1.1  christos 
     43  1.1  christos # include <dlfcn.h>
     44  1.1  christos 
     45  1.1  christos typedef void * SHLIB;
     46  1.1  christos typedef void * SHLIB_SYM;
     47  1.1  christos # define SHLIB_INIT NULL
     48  1.1  christos 
     49  1.1  christos static int shlib_load(const char *filename, SHLIB *lib)
     50  1.1  christos {
     51  1.1  christos     *lib = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
     52  1.1  christos 
     53  1.1  christos     if (*lib == NULL)
     54  1.1  christos         return 0;
     55  1.1  christos 
     56  1.1  christos     return 1;
     57  1.1  christos }
     58  1.1  christos 
     59  1.1  christos static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
     60  1.1  christos {
     61  1.1  christos     *sym = dlsym(lib, symname);
     62  1.1  christos 
     63  1.1  christos     return *sym != NULL;
     64  1.1  christos }
     65  1.1  christos 
     66  1.1  christos static int shlib_close(SHLIB lib)
     67  1.1  christos {
     68  1.1  christos     if (dlclose(lib) != 0)
     69  1.1  christos         return 0;
     70  1.1  christos 
     71  1.1  christos     return 1;
     72  1.1  christos }
     73  1.1  christos 
     74  1.1  christos #elif defined(DSO_WIN32)
     75  1.1  christos 
     76  1.1  christos # include <windows.h>
     77  1.1  christos 
     78  1.1  christos typedef HINSTANCE SHLIB;
     79  1.1  christos typedef void * SHLIB_SYM;
     80  1.1  christos # define SHLIB_INIT 0
     81  1.1  christos 
     82  1.1  christos static int shlib_load(const char *filename, SHLIB *lib)
     83  1.1  christos {
     84  1.1  christos     *lib = LoadLibraryA(filename);
     85  1.1  christos     if (*lib == NULL)
     86  1.1  christos         return 0;
     87  1.1  christos 
     88  1.1  christos     return 1;
     89  1.1  christos }
     90  1.1  christos 
     91  1.1  christos static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
     92  1.1  christos {
     93  1.1  christos     *sym = (SHLIB_SYM)GetProcAddress(lib, symname);
     94  1.1  christos 
     95  1.1  christos     return *sym != NULL;
     96  1.1  christos }
     97  1.1  christos 
     98  1.1  christos static int shlib_close(SHLIB lib)
     99  1.1  christos {
    100  1.1  christos     if (FreeLibrary(lib) == 0)
    101  1.1  christos         return 0;
    102  1.1  christos 
    103  1.1  christos     return 1;
    104  1.1  christos }
    105  1.1  christos 
    106  1.1  christos #endif
    107  1.1  christos 
    108  1.1  christos # define CRYPTO_FIRST_OPT    "-crypto_first"
    109  1.1  christos # define SSL_FIRST_OPT       "-ssl_first"
    110  1.1  christos # define JUST_CRYPTO_OPT     "-just_crypto"
    111  1.1  christos 
    112  1.1  christos enum test_types_en {
    113  1.1  christos     CRYPTO_FIRST,
    114  1.1  christos     SSL_FIRST,
    115  1.1  christos     JUST_CRYPTO
    116  1.1  christos };
    117  1.1  christos 
    118  1.1  christos int main(int argc, char **argv)
    119  1.1  christos {
    120  1.1  christos     SHLIB ssllib = SHLIB_INIT, cryptolib = SHLIB_INIT;
    121  1.1  christos     SSL_CTX *ctx;
    122  1.1  christos     union {
    123  1.1  christos         void (*func) (void);
    124  1.1  christos         SHLIB_SYM sym;
    125  1.1  christos     } tls_method_sym, ssl_ctx_new_sym, ssl_ctx_free_sym, err_get_error_sym,
    126  1.1  christos     openssl_version_num_sym;
    127  1.1  christos     enum test_types_en test_type;
    128  1.1  christos     int i;
    129  1.1  christos 
    130  1.1  christos     if (argc != 4) {
    131  1.1  christos         printf("Unexpected number of arguments\n");
    132  1.1  christos         return 1;
    133  1.1  christos     }
    134  1.1  christos 
    135  1.1  christos     if (strcmp(argv[1], CRYPTO_FIRST_OPT) == 0) {
    136  1.1  christos         test_type = CRYPTO_FIRST;
    137  1.1  christos     } else if (strcmp(argv[1], SSL_FIRST_OPT) == 0) {
    138  1.1  christos             test_type = SSL_FIRST;
    139  1.1  christos     } else if (strcmp(argv[1], JUST_CRYPTO_OPT) == 0) {
    140  1.1  christos             test_type = JUST_CRYPTO;
    141  1.1  christos     } else {
    142  1.1  christos         printf("Unrecognised argument\n");
    143  1.1  christos         return 1;
    144  1.1  christos     }
    145  1.1  christos 
    146  1.1  christos     for (i = 0; i < 2; i++) {
    147  1.1  christos         if ((i == 0 && (test_type == CRYPTO_FIRST
    148  1.1  christos                        || test_type == JUST_CRYPTO))
    149  1.1  christos                || (i == 1 && test_type == SSL_FIRST)) {
    150  1.1  christos             if (!shlib_load(argv[2], &cryptolib)) {
    151  1.1  christos                 printf("Unable to load libcrypto\n");
    152  1.1  christos                 return 1;
    153  1.1  christos             }
    154  1.1  christos         }
    155  1.1  christos         if ((i == 0 && test_type == SSL_FIRST)
    156  1.1  christos                 || (i == 1 && test_type == CRYPTO_FIRST)) {
    157  1.1  christos             if (!shlib_load(argv[3], &ssllib)) {
    158  1.1  christos                 printf("Unable to load libssl\n");
    159  1.1  christos                 return 1;
    160  1.1  christos             }
    161  1.1  christos         }
    162  1.1  christos     }
    163  1.1  christos 
    164  1.1  christos     if (test_type != JUST_CRYPTO) {
    165  1.1  christos         if (!shlib_sym(ssllib, TLS_METHOD, &tls_method_sym.sym)
    166  1.1  christos                 || !shlib_sym(ssllib, SSL_CTX_NEW, &ssl_ctx_new_sym.sym)
    167  1.1  christos                 || !shlib_sym(ssllib, SSL_CTX_FREE, &ssl_ctx_free_sym.sym)) {
    168  1.1  christos             printf("Unable to load ssl symbols\n");
    169  1.1  christos             return 1;
    170  1.1  christos         }
    171  1.1  christos 
    172  1.1  christos         TLS_method = (TLS_method_t)tls_method_sym.func;
    173  1.1  christos         SSL_CTX_new = (SSL_CTX_new_t)ssl_ctx_new_sym.func;
    174  1.1  christos         SSL_CTX_free = (SSL_CTX_free_t)ssl_ctx_free_sym.func;
    175  1.1  christos 
    176  1.1  christos         ctx = SSL_CTX_new(TLS_method());
    177  1.1  christos         if (ctx == NULL) {
    178  1.1  christos             printf("Unable to create SSL_CTX\n");
    179  1.1  christos             return 1;
    180  1.1  christos         }
    181  1.1  christos         SSL_CTX_free(ctx);
    182  1.1  christos     }
    183  1.1  christos 
    184  1.1  christos     if (!shlib_sym(cryptolib, ERR_GET_ERROR, &err_get_error_sym.sym)
    185  1.1  christos             || !shlib_sym(cryptolib, OPENSSL_VERSION_NUM_FUNC,
    186  1.1  christos                           &openssl_version_num_sym.sym)) {
    187  1.1  christos         printf("Unable to load crypto symbols\n");
    188  1.1  christos         return 1;
    189  1.1  christos     }
    190  1.1  christos 
    191  1.1  christos     ERR_get_error = (ERR_get_error_t)err_get_error_sym.func;
    192  1.1  christos     OpenSSL_version_num = (OpenSSL_version_num_t)openssl_version_num_sym.func;
    193  1.1  christos 
    194  1.1  christos     if (ERR_get_error() != 0) {
    195  1.1  christos         printf("Unexpected error in error queue\n");
    196  1.1  christos         return 1;
    197  1.1  christos     }
    198  1.1  christos 
    199  1.1  christos     if (OpenSSL_version_num() != OPENSSL_VERSION_NUMBER) {
    200  1.1  christos         printf("Unexpected library version loaded\n");
    201  1.1  christos         return 1;
    202  1.1  christos     }
    203  1.1  christos 
    204  1.1  christos     for (i = 0; i < 2; i++) {
    205  1.1  christos         if ((i == 0 && test_type == CRYPTO_FIRST)
    206  1.1  christos                 || (i == 1 && test_type == SSL_FIRST)) {
    207  1.1  christos             if (!shlib_close(ssllib)) {
    208  1.1  christos                 printf("Unable to close libssl\n");
    209  1.1  christos                 return 1;
    210  1.1  christos             }
    211  1.1  christos         }
    212  1.1  christos         if ((i == 0 && (test_type == SSL_FIRST
    213  1.1  christos                        || test_type == JUST_CRYPTO))
    214  1.1  christos                 || (i == 1 && test_type == CRYPTO_FIRST)) {
    215  1.1  christos             if (!shlib_close(cryptolib)) {
    216  1.1  christos                 printf("Unable to close libcrypto\n");
    217  1.1  christos                 return 1;
    218  1.1  christos             }
    219  1.1  christos         }
    220  1.1  christos     }
    221  1.1  christos 
    222  1.1  christos     printf("Success\n");
    223  1.1  christos     return 0;
    224  1.1  christos }
    225  1.1  christos #else
    226  1.1  christos int main(void)
    227  1.1  christos {
    228  1.1  christos     printf("Test not implemented on this platform\n");
    229  1.1  christos     return 0;
    230  1.1  christos }
    231  1.1  christos #endif
    232