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" 9static void fbsd_ossl_provider_unload(void); 10static void print_dlerror(char *); 11static OSSL_PROVIDER *legacy; 12static OSSL_PROVIDER *deflt; 13static int providers_loaded = 0; 14static OSSL_PROVIDER * (*ossl_provider_load)(OSSL_LIB_CTX *, const char*) = NULL; 15static int (*ossl_provider_unload)(OSSL_PROVIDER *) = NULL; 16static void *crypto_lib_handle = NULL; 17 18static void 19fbsd_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 34static void 35print_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 45int 46fbsd_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