/* * Copyright 1995-2024 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 engines are located. */ static char enginesdir[MAX_PATH + 1]; /** * @brief The pointer to the enginesdir buffer */ static char *enginesdirptr = 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, LPCTSTR valuename) { char *retval = NULL; # ifdef REGISTRY_KEY DWORD keysize; DWORD ktype; HKEY hkey; LSTATUS ret; DWORD index = 0; LPCTCH tempstr = NULL; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(REGISTRY_KEY), KEY_WOW64_32KEY, KEY_QUERY_VALUE, &hkey); if (ret != ERROR_SUCCESS) goto out; ret = RegQueryValueEx(hkey, valuename, NULL, &ktype, NULL, &keysize); if (ret != ERROR_SUCCESS) goto out; if (ktype != REG_EXPAND_SZ) goto out; if (keysize > MAX_PATH) goto out; keysize++; tempstr = OPENSSL_zalloc(keysize * sizeof(TCHAR)); if (tempstr == NULL) goto out; if (RegQueryValueEx(hkey, valuename, NULL, &ktype, tempstr, &keysize) != ERROR_SUCCESS) goto out; if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, keysize, 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, TEXT("OPENSSLDIR")); get_windows_regdirs(enginesdir, TEXT("ENGINESDIR")); get_windows_regdirs(modulesdir, TEXT("MODULESDIR")); /* * Set our pointers only if the directories are fetched properly */ if (strlen(openssldir) > 0) openssldirptr = openssldir; if (strlen(enginesdir) > 0) enginesdirptr = enginesdir; 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 engines are located. * * @return A pointer to a string containing the engines directory path. */ const char *ossl_get_enginesdir(void) { #if defined(_WIN32) && defined (OSSL_WINCTX) if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup)) return NULL; return (const char *)enginesdirptr; #else return ENGINESDIR; #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 }