xref: /freebsd/kerberos5/lib/libroken/fbsd_ossl_provider_load.c (revision 9ab31f821ad1c6bad474510447387c50bef2c24c)
1 #include <dlfcn.h>
2 #include <errno.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <openssl/provider.h>
6 
7 #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
8 #define CRYPTO_LIBRARY "/lib/libcrypto.so.35"
9 static void fbsd_ossl_provider_unload(void);
10 static void print_dlerror(char *);
11 static OSSL_PROVIDER *deflt;
12 static int providers_loaded = 0;
13 static OSSL_PROVIDER * (*ossl_provider_load)(OSSL_LIB_CTX *, const char*) = NULL;
14 static int (*ossl_provider_unload)(OSSL_PROVIDER *) = NULL;
15 static void *crypto_lib_handle = NULL;
16 
17 static void
fbsd_ossl_provider_unload(void)18 fbsd_ossl_provider_unload(void)
19 {
20 	if (ossl_provider_unload == NULL) {
21 		if (!(ossl_provider_unload = (int (*)(OSSL_PROVIDER*)) dlsym(crypto_lib_handle, "OSSL_PROVIDER_unload"))) {
22 			print_dlerror("Unable to link OSSL_PROVIDER_unload");
23 			return;
24 		}
25 	}
26 	if (providers_loaded == 1) {
27 		(*ossl_provider_unload)(deflt);
28 		providers_loaded = 0;
29 	}
30 }
31 
32 static void
print_dlerror(char * message)33 print_dlerror(char *message)
34 {
35 	char *errstr;
36 
37 	if ((errstr = dlerror()) != NULL)
38 		fprintf(stderr, "%s: %s\n",
39 			message, errstr);
40 }
41 #endif
42 
43 int
fbsd_ossl_provider_load(void)44 fbsd_ossl_provider_load(void)
45 {
46 #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
47 	if (crypto_lib_handle == NULL) {
48 		if (!(crypto_lib_handle = dlopen(CRYPTO_LIBRARY,
49 		    RTLD_LAZY|RTLD_GLOBAL))) {
50 			print_dlerror("Unable to load libcrypto.so");
51 			return (EINVAL);
52 		}
53 	}
54 	if (ossl_provider_load == NULL) {
55 		if (!(ossl_provider_load = (OSSL_PROVIDER * (*)(OSSL_LIB_CTX*, const char *)) dlsym(crypto_lib_handle, "OSSL_PROVIDER_load"))) {
56 			print_dlerror("Unable to link OSSL_PROVIDER_load");
57 			return(ENOENT);
58 		}
59 	}
60 
61 	if (providers_loaded == 0) {
62 		if ((deflt = (*ossl_provider_load)(NULL, "default")) == NULL) {
63 			return (EINVAL);
64 		}
65 		if (atexit(fbsd_ossl_provider_unload)) {
66 			fbsd_ossl_provider_unload();
67 			return (errno);
68 		}
69 		providers_loaded = 1;
70 	}
71 #endif
72 	return (0);
73 }
74