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