shlibloadtest.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <openssl/opensslv.h>
  13. /* The test is only currently implemented for DSO_DLFCN and DSO_WIN32 */
  14. #if defined(DSO_DLFCN) || defined(DSO_WIN32)
  15. #define SSL_CTX_NEW "SSL_CTX_new"
  16. #define SSL_CTX_FREE "SSL_CTX_free"
  17. #define TLS_METHOD "TLS_method"
  18. #define ERR_GET_ERROR "ERR_get_error"
  19. #define OPENSSL_VERSION_NUM_FUNC "OpenSSL_version_num"
  20. typedef struct ssl_ctx_st SSL_CTX;
  21. typedef struct ssl_method_st SSL_METHOD;
  22. typedef const SSL_METHOD * (*TLS_method_t)(void);
  23. typedef SSL_CTX * (*SSL_CTX_new_t)(const SSL_METHOD *meth);
  24. typedef void (*SSL_CTX_free_t)(SSL_CTX *);
  25. typedef unsigned long (*ERR_get_error_t)(void);
  26. typedef unsigned long (*OpenSSL_version_num_t)(void);
  27. static TLS_method_t TLS_method;
  28. static SSL_CTX_new_t SSL_CTX_new;
  29. static SSL_CTX_free_t SSL_CTX_free;
  30. static ERR_get_error_t ERR_get_error;
  31. static OpenSSL_version_num_t OpenSSL_version_num;
  32. #ifdef DSO_DLFCN
  33. # include <dlfcn.h>
  34. typedef void * SHLIB;
  35. typedef void * SHLIB_SYM;
  36. # define SHLIB_INIT NULL
  37. static int shlib_load(const char *filename, SHLIB *lib)
  38. {
  39. *lib = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
  40. if (*lib == NULL)
  41. return 0;
  42. return 1;
  43. }
  44. static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
  45. {
  46. *sym = dlsym(lib, symname);
  47. return *sym != NULL;
  48. }
  49. static int shlib_close(SHLIB lib)
  50. {
  51. if (dlclose(lib) != 0)
  52. return 0;
  53. return 1;
  54. }
  55. #elif defined(DSO_WIN32)
  56. # include <windows.h>
  57. typedef HINSTANCE SHLIB;
  58. typedef void * SHLIB_SYM;
  59. # define SHLIB_INIT 0
  60. static int shlib_load(const char *filename, SHLIB *lib)
  61. {
  62. *lib = LoadLibraryA(filename);
  63. if (*lib == NULL)
  64. return 0;
  65. return 1;
  66. }
  67. static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
  68. {
  69. *sym = (SHLIB_SYM)GetProcAddress(lib, symname);
  70. return *sym != NULL;
  71. }
  72. static int shlib_close(SHLIB lib)
  73. {
  74. if (FreeLibrary(lib) == 0)
  75. return 0;
  76. return 1;
  77. }
  78. #endif
  79. # define CRYPTO_FIRST_OPT "-crypto_first"
  80. # define SSL_FIRST_OPT "-ssl_first"
  81. # define JUST_CRYPTO_OPT "-just_crypto"
  82. enum test_types_en {
  83. CRYPTO_FIRST,
  84. SSL_FIRST,
  85. JUST_CRYPTO
  86. };
  87. int main(int argc, char **argv)
  88. {
  89. SHLIB ssllib = SHLIB_INIT, cryptolib = SHLIB_INIT;
  90. SSL_CTX *ctx;
  91. union {
  92. void (*func) (void);
  93. SHLIB_SYM sym;
  94. } tls_method_sym, ssl_ctx_new_sym, ssl_ctx_free_sym, err_get_error_sym,
  95. openssl_version_num_sym;
  96. enum test_types_en test_type;
  97. int i;
  98. if (argc != 4) {
  99. printf("Unexpected number of arguments\n");
  100. return 1;
  101. }
  102. if (strcmp(argv[1], CRYPTO_FIRST_OPT) == 0) {
  103. test_type = CRYPTO_FIRST;
  104. } else if (strcmp(argv[1], SSL_FIRST_OPT) == 0) {
  105. test_type = SSL_FIRST;
  106. } else if (strcmp(argv[1], JUST_CRYPTO_OPT) == 0) {
  107. test_type = JUST_CRYPTO;
  108. } else {
  109. printf("Unrecognised argument\n");
  110. return 1;
  111. }
  112. for (i = 0; i < 2; i++) {
  113. if ((i == 0 && (test_type == CRYPTO_FIRST
  114. || test_type == JUST_CRYPTO))
  115. || (i == 1 && test_type == SSL_FIRST)) {
  116. if (!shlib_load(argv[2], &cryptolib)) {
  117. printf("Unable to load libcrypto\n");
  118. return 1;
  119. }
  120. }
  121. if ((i == 0 && test_type == SSL_FIRST)
  122. || (i == 1 && test_type == CRYPTO_FIRST)) {
  123. if (!shlib_load(argv[3], &ssllib)) {
  124. printf("Unable to load libssl\n");
  125. return 1;
  126. }
  127. }
  128. }
  129. if (test_type != JUST_CRYPTO) {
  130. if (!shlib_sym(ssllib, TLS_METHOD, &tls_method_sym.sym)
  131. || !shlib_sym(ssllib, SSL_CTX_NEW, &ssl_ctx_new_sym.sym)
  132. || !shlib_sym(ssllib, SSL_CTX_FREE, &ssl_ctx_free_sym.sym)) {
  133. printf("Unable to load ssl symbols\n");
  134. return 1;
  135. }
  136. TLS_method = (TLS_method_t)tls_method_sym.func;
  137. SSL_CTX_new = (SSL_CTX_new_t)ssl_ctx_new_sym.func;
  138. SSL_CTX_free = (SSL_CTX_free_t)ssl_ctx_free_sym.func;
  139. ctx = SSL_CTX_new(TLS_method());
  140. if (ctx == NULL) {
  141. printf("Unable to create SSL_CTX\n");
  142. return 1;
  143. }
  144. SSL_CTX_free(ctx);
  145. }
  146. if (!shlib_sym(cryptolib, ERR_GET_ERROR, &err_get_error_sym.sym)
  147. || !shlib_sym(cryptolib, OPENSSL_VERSION_NUM_FUNC,
  148. &openssl_version_num_sym.sym)) {
  149. printf("Unable to load crypto symbols\n");
  150. return 1;
  151. }
  152. ERR_get_error = (ERR_get_error_t)err_get_error_sym.func;
  153. OpenSSL_version_num = (OpenSSL_version_num_t)openssl_version_num_sym.func;
  154. if (ERR_get_error() != 0) {
  155. printf("Unexpected error in error queue\n");
  156. return 1;
  157. }
  158. if (OpenSSL_version_num() != OPENSSL_VERSION_NUMBER) {
  159. printf("Unexpected library version loaded\n");
  160. return 1;
  161. }
  162. for (i = 0; i < 2; i++) {
  163. if ((i == 0 && test_type == CRYPTO_FIRST)
  164. || (i == 1 && test_type == SSL_FIRST)) {
  165. if (!shlib_close(ssllib)) {
  166. printf("Unable to close libssl\n");
  167. return 1;
  168. }
  169. }
  170. if ((i == 0 && (test_type == SSL_FIRST
  171. || test_type == JUST_CRYPTO))
  172. || (i == 1 && test_type == CRYPTO_FIRST)) {
  173. if (!shlib_close(cryptolib)) {
  174. printf("Unable to close libcrypto\n");
  175. return 1;
  176. }
  177. }
  178. }
  179. printf("Success\n");
  180. return 0;
  181. }
  182. #else
  183. int main(void)
  184. {
  185. printf("Test not implemented on this platform\n");
  186. return 0;
  187. }
  188. #endif