| /* | |
| * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. | |
| * | |
| * Licensed under the Apache License 2.0 (the "License"). You may not use | |
| * this file except in compliance with the License. You can obtain a copy | |
| * in the file LICENSE in the source distribution or at | |
| * https://www.openssl.org/source/license.html | |
| */ | |
| #include <stdio.h> | |
| #include <openssl/opensslv.h> | |
| #include "internal/thread_once.h" | |
| #include "internal/cryptlib.h" | |
| #include "internal/e_os.h" | |
| #if defined(_WIN32) && defined(OSSL_WINCTX) | |
| #define TOSTR(x) #x | |
| #define MAKESTR(x) TOSTR(x) | |
| #define NOQUOTE(x) x | |
| #if defined(OSSL_WINCTX) | |
| #define REGISTRY_KEY "SOFTWARE\\WOW6432Node\\OpenSSL" \ | |
| "-" MAKESTR(OPENSSL_VERSION_MAJOR) "." MAKESTR(OPENSSL_VERSION_MINOR) "-" MAKESTR(OSSL_WINCTX) | |
| #endif | |
| /** | |
| * @brief The directory where OpenSSL is installed. | |
| */ | |
| static char openssldir[MAX_PATH + 1]; | |
| /** | |
| * @brief The pointer to the openssldir buffer | |
| */ | |
| static char *openssldirptr = NULL; | |
| /** | |
| * @brief The directory where OpenSSL modules are located. | |
| */ | |
| static char modulesdir[MAX_PATH + 1]; | |
| /** | |
| * @brief The pointer to the modulesdir buffer | |
| */ | |
| static char *modulesdirptr = NULL; | |
| /** | |
| * @brief Get the list of Windows registry directories. | |
| * | |
| * This function retrieves a list of Windows registry directories. | |
| * | |
| * @return A pointer to a char array containing the registry directories. | |
| */ | |
| static char *get_windows_regdirs(char *dst, DWORD dstsizebytes, LPCWSTR valuename) | |
| { | |
| char *retval = NULL; | |
| #ifdef REGISTRY_KEY | |
| DWORD keysizebytes; | |
| DWORD ktype; | |
| HKEY hkey; | |
| LSTATUS ret; | |
| DWORD index = 0; | |
| LPCWSTR tempstr = NULL; | |
| ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, | |
| TEXT(REGISTRY_KEY), KEY_WOW64_32KEY, | |
| KEY_QUERY_VALUE, &hkey); | |
| if (ret != ERROR_SUCCESS) | |
| goto out; | |
| /* Always use wide call so we can avoid extra encoding conversions on the output */ | |
| ret = RegQueryValueExW(hkey, valuename, NULL, &ktype, NULL, | |
| &keysizebytes); | |
| if (ret != ERROR_SUCCESS) | |
| goto out; | |
| if (ktype != REG_EXPAND_SZ && ktype != REG_SZ) | |
| goto out; | |
| if (keysizebytes > MAX_PATH * sizeof(WCHAR)) | |
| goto out; | |
| /* | |
| * RegQueryValueExW does not guarantee the buffer is null terminated, | |
| * so we make space for one in the allocation | |
| */ | |
| tempstr = OPENSSL_zalloc(keysizebytes + sizeof(WCHAR)); | |
| if (tempstr == NULL) | |
| goto out; | |
| if (RegQueryValueExW(hkey, valuename, | |
| NULL, &ktype, (LPBYTE)tempstr, &keysizebytes) | |
| != ERROR_SUCCESS) | |
| goto out; | |
| if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, dstsizebytes, | |
| NULL, NULL)) | |
| goto out; | |
| retval = dst; | |
| out: | |
| OPENSSL_free(tempstr); | |
| RegCloseKey(hkey); | |
| #endif /* REGISTRY_KEY */ | |
| return retval; | |
| } | |
| static CRYPTO_ONCE defaults_setup_init = CRYPTO_ONCE_STATIC_INIT; | |
| /** | |
| * @brief Function to setup default values to run once. | |
| * Only used in Windows environments. Does run time initialization | |
| * of openssldir/modulesdir/enginesdir from the registry | |
| */ | |
| DEFINE_RUN_ONCE_STATIC(do_defaults_setup) | |
| { | |
| get_windows_regdirs(openssldir, sizeof(openssldir), L"OPENSSLDIR"); | |
| get_windows_regdirs(modulesdir, sizeof(modulesdir), L"MODULESDIR"); | |
| /* | |
| * Set our pointers only if the directories are fetched properly | |
| */ | |
| if (strlen(openssldir) > 0) | |
| openssldirptr = openssldir; | |
| if (strlen(modulesdir) > 0) | |
| modulesdirptr = modulesdir; | |
| return 1; | |
| } | |
| #endif /* defined(_WIN32) && defined(OSSL_WINCTX) */ | |
| /** | |
| * @brief Get the directory where OpenSSL is installed. | |
| * | |
| * @return A pointer to a string containing the OpenSSL directory path. | |
| */ | |
| const char *ossl_get_openssldir(void) | |
| { | |
| #if defined(_WIN32) && defined(OSSL_WINCTX) | |
| if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup)) | |
| return NULL; | |
| return (const char *)openssldirptr; | |
| #else | |
| return OPENSSLDIR; | |
| #endif | |
| } | |
| /** | |
| * @brief Get the directory where OpenSSL modules are located. | |
| * | |
| * @return A pointer to a string containing the modules directory path. | |
| */ | |
| const char *ossl_get_modulesdir(void) | |
| { | |
| #if defined(_WIN32) && defined(OSSL_WINCTX) | |
| if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup)) | |
| return NULL; | |
| return (const char *)modulesdirptr; | |
| #else | |
| return MODULESDIR; | |
| #endif | |
| } | |
| /** | |
| * @brief Get the build time defined windows installer context | |
| * | |
| * @return A char pointer to a string representing the windows install context | |
| */ | |
| const char *ossl_get_wininstallcontext(void) | |
| { | |
| #if defined(_WIN32) && defined(OSSL_WINCTX) | |
| return MAKESTR(OSSL_WINCTX); | |
| #else | |
| return "Undefined"; | |
| #endif | |
| } |