blob: bb7fba88aff3f2717c8ff9f7a6bcdfa27f1b8622 [file] [log] [blame]
Gilles Peskinea7c247e2021-11-04 12:45:19 +01001/*
2 * Test dynamic loading of libmbed*
3 *
4 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Gilles Peskinea7c247e2021-11-04 12:45:19 +01006 */
7
Felix Conway998760a2025-03-24 11:37:33 +00008#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
9
Gilles Peskinea7c247e2021-11-04 12:45:19 +010010#include "mbedtls/build_info.h"
11
12#include "mbedtls/platform.h"
Gilles Peskinea7c247e2021-11-04 12:45:19 +010013
14#if defined(MBEDTLS_X509_CRT_PARSE_C)
15#include "mbedtls/x509_crt.h"
16#endif
17
Gilles Peskine834d2292021-11-12 14:30:22 +010018#if defined(__APPLE__)
19#define SO_SUFFIX ".dylib"
20#else
21#define SO_SUFFIX ".so"
22#endif
23
Ronald Cron8126a682024-10-25 17:34:23 +020024#define MBEDCRYPTO_SO_FILENAME "libmbedcrypto" SO_SUFFIX
25#define TFPSACRYPTO_SO_FILENAME "libtfpsacrypto" SO_SUFFIX
Gilles Peskine834d2292021-11-12 14:30:22 +010026#define X509_SO_FILENAME "libmbedx509" SO_SUFFIX
27#define TLS_SO_FILENAME "libmbedtls" SO_SUFFIX
Gilles Peskinea7c247e2021-11-04 12:45:19 +010028
29#include <dlfcn.h>
30
Gilles Peskine449bd832023-01-11 14:50:10 +010031#define CHECK_DLERROR(function, argument) \
Gilles Peskinea7c247e2021-11-04 12:45:19 +010032 do \
33 { \
Gilles Peskine449bd832023-01-11 14:50:10 +010034 char *CHECK_DLERROR_error = dlerror(); \
35 if (CHECK_DLERROR_error != NULL) \
Gilles Peskinea7c247e2021-11-04 12:45:19 +010036 { \
Gilles Peskine449bd832023-01-11 14:50:10 +010037 fprintf(stderr, "Dynamic loading error for %s(%s): %s\n", \
38 function, argument, CHECK_DLERROR_error); \
39 mbedtls_exit(MBEDTLS_EXIT_FAILURE); \
Gilles Peskinea7c247e2021-11-04 12:45:19 +010040 } \
41 } \
Gilles Peskine449bd832023-01-11 14:50:10 +010042 while (0)
Gilles Peskinea7c247e2021-11-04 12:45:19 +010043
Gilles Peskine449bd832023-01-11 14:50:10 +010044int main(void)
Gilles Peskinea7c247e2021-11-04 12:45:19 +010045{
Gilles Peskineb6a02992021-11-10 19:11:32 +010046#if defined(MBEDTLS_MD_C) || defined(MBEDTLS_SSL_TLS_C)
Gilles Peskinea7c247e2021-11-04 12:45:19 +010047 unsigned n;
Gilles Peskineb6a02992021-11-10 19:11:32 +010048#endif
Gilles Peskinea7c247e2021-11-04 12:45:19 +010049
50#if defined(MBEDTLS_SSL_TLS_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010051 void *tls_so = dlopen(TLS_SO_FILENAME, RTLD_NOW);
52 CHECK_DLERROR("dlopen", TLS_SO_FILENAME);
Gilles Peskine06af4172025-01-08 17:26:01 +010053#pragma GCC diagnostic push
54 /* dlsym() returns an object pointer which is meant to be used as a
55 * function pointer. This has undefined behavior in standard C, so
56 * "gcc -std=c99 -pedantic" complains about it, but it is perfectly
57 * fine on platforms that have dlsym(). */
58#pragma GCC diagnostic ignored "-Wpedantic"
Gilles Peskine449bd832023-01-11 14:50:10 +010059 const int *(*ssl_list_ciphersuites)(void) =
60 dlsym(tls_so, "mbedtls_ssl_list_ciphersuites");
Gilles Peskine06af4172025-01-08 17:26:01 +010061#pragma GCC diagnostic pop
Gilles Peskine449bd832023-01-11 14:50:10 +010062 CHECK_DLERROR("dlsym", "mbedtls_ssl_list_ciphersuites");
63 const int *ciphersuites = ssl_list_ciphersuites();
64 for (n = 0; ciphersuites[n] != 0; n++) {/* nothing to do, we're just counting */
65 ;
66 }
67 mbedtls_printf("dlopen(%s): %u ciphersuites\n",
68 TLS_SO_FILENAME, n);
69 dlclose(tls_so);
70 CHECK_DLERROR("dlclose", TLS_SO_FILENAME);
Gilles Peskinea7c247e2021-11-04 12:45:19 +010071#endif /* MBEDTLS_SSL_TLS_C */
72
73#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010074 void *x509_so = dlopen(X509_SO_FILENAME, RTLD_NOW);
75 CHECK_DLERROR("dlopen", X509_SO_FILENAME);
Gilles Peskinea7c247e2021-11-04 12:45:19 +010076 const mbedtls_x509_crt_profile *profile =
Gilles Peskine449bd832023-01-11 14:50:10 +010077 dlsym(x509_so, "mbedtls_x509_crt_profile_default");
78 CHECK_DLERROR("dlsym", "mbedtls_x509_crt_profile_default");
79 mbedtls_printf("dlopen(%s): Allowed md mask: %08x\n",
80 X509_SO_FILENAME, (unsigned) profile->allowed_mds);
81 dlclose(x509_so);
82 CHECK_DLERROR("dlclose", X509_SO_FILENAME);
Gilles Peskinea7c247e2021-11-04 12:45:19 +010083#endif /* MBEDTLS_X509_CRT_PARSE_C */
84
85#if defined(MBEDTLS_MD_C)
Ronald Cron8126a682024-10-25 17:34:23 +020086 const char *crypto_so_filename = NULL;
87 void *crypto_so = dlopen(MBEDCRYPTO_SO_FILENAME, RTLD_NOW);
88 if (dlerror() == NULL) {
89 crypto_so_filename = MBEDCRYPTO_SO_FILENAME;
90 } else {
91 crypto_so = dlopen(TFPSACRYPTO_SO_FILENAME, RTLD_NOW);
92 CHECK_DLERROR("dlopen", TFPSACRYPTO_SO_FILENAME);
93 crypto_so_filename = TFPSACRYPTO_SO_FILENAME;
94 }
Gilles Peskine06af4172025-01-08 17:26:01 +010095#pragma GCC diagnostic push
96 /* dlsym() returns an object pointer which is meant to be used as a
97 * function pointer. This has undefined behavior in standard C, so
98 * "gcc -std=c99 -pedantic" complains about it, but it is perfectly
99 * fine on platforms that have dlsym(). */
100#pragma GCC diagnostic ignored "-Wpedantic"
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 const int *(*md_list)(void) =
102 dlsym(crypto_so, "mbedtls_md_list");
Gilles Peskine06af4172025-01-08 17:26:01 +0100103#pragma GCC diagnostic pop
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 CHECK_DLERROR("dlsym", "mbedtls_md_list");
105 const int *mds = md_list();
106 for (n = 0; mds[n] != 0; n++) {/* nothing to do, we're just counting */
107 ;
108 }
109 mbedtls_printf("dlopen(%s): %u hashes\n",
Ronald Cron8126a682024-10-25 17:34:23 +0200110 crypto_so_filename, n);
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 dlclose(crypto_so);
Ronald Cron8126a682024-10-25 17:34:23 +0200112 CHECK_DLERROR("dlclose", crypto_so_filename);
Gilles Peskinea7c247e2021-11-04 12:45:19 +0100113#endif /* MBEDTLS_MD_C */
114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 return 0;
Gilles Peskinea7c247e2021-11-04 12:45:19 +0100116}