dlopen.c (3971B)
1 /* 2 * Test dynamic loading of libmbed* 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6 */ 7 8 #include "mbedtls/build_info.h" 9 10 #include "mbedtls/platform.h" 11 12 #if defined(MBEDTLS_X509_CRT_PARSE_C) 13 #include "mbedtls/x509_crt.h" 14 #endif 15 16 #if defined(__APPLE__) 17 #define SO_SUFFIX ".dylib" 18 #else 19 #define SO_SUFFIX ".so" 20 #endif 21 22 #define CRYPTO_SO_FILENAME "libmbedcrypto" SO_SUFFIX 23 #define X509_SO_FILENAME "libmbedx509" SO_SUFFIX 24 #define TLS_SO_FILENAME "libmbedtls" SO_SUFFIX 25 26 #include <dlfcn.h> 27 28 #define CHECK_DLERROR(function, argument) \ 29 do \ 30 { \ 31 char *CHECK_DLERROR_error = dlerror(); \ 32 if (CHECK_DLERROR_error != NULL) \ 33 { \ 34 fprintf(stderr, "Dynamic loading error for %s(%s): %s\n", \ 35 function, argument, CHECK_DLERROR_error); \ 36 mbedtls_exit(MBEDTLS_EXIT_FAILURE); \ 37 } \ 38 } \ 39 while (0) 40 41 int main(void) 42 { 43 #if defined(MBEDTLS_MD_C) || defined(MBEDTLS_SSL_TLS_C) 44 unsigned n; 45 #endif 46 47 #if defined(MBEDTLS_SSL_TLS_C) 48 void *tls_so = dlopen(TLS_SO_FILENAME, RTLD_NOW); 49 CHECK_DLERROR("dlopen", TLS_SO_FILENAME); 50 #pragma GCC diagnostic push 51 /* dlsym() returns an object pointer which is meant to be used as a 52 * function pointer. This has undefined behavior in standard C, so 53 * "gcc -std=c99 -pedantic" complains about it, but it is perfectly 54 * fine on platforms that have dlsym(). */ 55 #pragma GCC diagnostic ignored "-Wpedantic" 56 const int *(*ssl_list_ciphersuites)(void) = 57 dlsym(tls_so, "mbedtls_ssl_list_ciphersuites"); 58 #pragma GCC diagnostic pop 59 CHECK_DLERROR("dlsym", "mbedtls_ssl_list_ciphersuites"); 60 const int *ciphersuites = ssl_list_ciphersuites(); 61 for (n = 0; ciphersuites[n] != 0; n++) {/* nothing to do, we're just counting */ 62 ; 63 } 64 mbedtls_printf("dlopen(%s): %u ciphersuites\n", 65 TLS_SO_FILENAME, n); 66 dlclose(tls_so); 67 CHECK_DLERROR("dlclose", TLS_SO_FILENAME); 68 #endif /* MBEDTLS_SSL_TLS_C */ 69 70 #if defined(MBEDTLS_X509_CRT_PARSE_C) 71 void *x509_so = dlopen(X509_SO_FILENAME, RTLD_NOW); 72 CHECK_DLERROR("dlopen", X509_SO_FILENAME); 73 const mbedtls_x509_crt_profile *profile = 74 dlsym(x509_so, "mbedtls_x509_crt_profile_default"); 75 CHECK_DLERROR("dlsym", "mbedtls_x509_crt_profile_default"); 76 mbedtls_printf("dlopen(%s): Allowed md mask: %08x\n", 77 X509_SO_FILENAME, (unsigned) profile->allowed_mds); 78 dlclose(x509_so); 79 CHECK_DLERROR("dlclose", X509_SO_FILENAME); 80 #endif /* MBEDTLS_X509_CRT_PARSE_C */ 81 82 #if defined(MBEDTLS_MD_C) 83 void *crypto_so = dlopen(CRYPTO_SO_FILENAME, RTLD_NOW); 84 CHECK_DLERROR("dlopen", CRYPTO_SO_FILENAME); 85 #pragma GCC diagnostic push 86 /* dlsym() returns an object pointer which is meant to be used as a 87 * function pointer. This has undefined behavior in standard C, so 88 * "gcc -std=c99 -pedantic" complains about it, but it is perfectly 89 * fine on platforms that have dlsym(). */ 90 #pragma GCC diagnostic ignored "-Wpedantic" 91 const int *(*md_list)(void) = 92 dlsym(crypto_so, "mbedtls_md_list"); 93 #pragma GCC diagnostic pop 94 CHECK_DLERROR("dlsym", "mbedtls_md_list"); 95 const int *mds = md_list(); 96 for (n = 0; mds[n] != 0; n++) {/* nothing to do, we're just counting */ 97 ; 98 } 99 mbedtls_printf("dlopen(%s): %u hashes\n", 100 CRYPTO_SO_FILENAME, n); 101 dlclose(crypto_so); 102 CHECK_DLERROR("dlclose", CRYPTO_SO_FILENAME); 103 #endif /* MBEDTLS_MD_C */ 104 105 return 0; 106 }