defaults.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include <openssl/opensslv.h>
  11. #include "internal/thread_once.h"
  12. #include "internal/cryptlib.h"
  13. #include "internal/e_os.h"
  14. #if defined(_WIN32) && defined(OSSL_WINCTX)
  15. # define TOSTR(x) #x
  16. # define MAKESTR(x) TOSTR(x)
  17. # define NOQUOTE(x) x
  18. # if defined(OSSL_WINCTX)
  19. # define REGISTRY_KEY "SOFTWARE\\WOW6432Node\\OpenSSL" "-" MAKESTR(OPENSSL_VERSION_MAJOR) "." MAKESTR(OPENSSL_VERSION_MINOR) "-" MAKESTR(OSSL_WINCTX)
  20. # endif
  21. /**
  22. * @brief The directory where OpenSSL is installed.
  23. */
  24. static char openssldir[MAX_PATH + 1];
  25. /**
  26. * @brief The pointer to the openssldir buffer
  27. */
  28. static char *openssldirptr = NULL;
  29. /**
  30. * @brief The directory where OpenSSL engines are located.
  31. */
  32. static char enginesdir[MAX_PATH + 1];
  33. /**
  34. * @brief The pointer to the enginesdir buffer
  35. */
  36. static char *enginesdirptr = NULL;
  37. /**
  38. * @brief The directory where OpenSSL modules are located.
  39. */
  40. static char modulesdir[MAX_PATH + 1];
  41. /**
  42. * @brief The pointer to the modulesdir buffer
  43. */
  44. static char *modulesdirptr = NULL;
  45. /**
  46. * @brief Get the list of Windows registry directories.
  47. *
  48. * This function retrieves a list of Windows registry directories.
  49. *
  50. * @return A pointer to a char array containing the registry directories.
  51. */
  52. static char *get_windows_regdirs(char *dst, DWORD dstsizebytes, LPCWSTR valuename)
  53. {
  54. char *retval = NULL;
  55. # ifdef REGISTRY_KEY
  56. DWORD keysizebytes;
  57. DWORD ktype;
  58. HKEY hkey;
  59. LSTATUS ret;
  60. DWORD index = 0;
  61. LPCWSTR tempstr = NULL;
  62. ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  63. TEXT(REGISTRY_KEY), KEY_WOW64_32KEY,
  64. KEY_QUERY_VALUE, &hkey);
  65. if (ret != ERROR_SUCCESS)
  66. goto out;
  67. /* Always use wide call so we can avoid extra encoding conversions on the output */
  68. ret = RegQueryValueExW(hkey, valuename, NULL, &ktype, NULL,
  69. &keysizebytes);
  70. if (ret != ERROR_SUCCESS)
  71. goto out;
  72. if (ktype != REG_EXPAND_SZ && ktype != REG_SZ)
  73. goto out;
  74. if (keysizebytes > MAX_PATH * sizeof(WCHAR))
  75. goto out;
  76. /*
  77. * RegQueryValueExW does not guarantee the buffer is null terminated,
  78. * so we make space for one in the allocation
  79. */
  80. tempstr = OPENSSL_zalloc(keysizebytes + sizeof(WCHAR));
  81. if (tempstr == NULL)
  82. goto out;
  83. if (RegQueryValueExW(hkey, valuename,
  84. NULL, &ktype, (LPBYTE)tempstr, &keysizebytes) != ERROR_SUCCESS)
  85. goto out;
  86. if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, dstsizebytes,
  87. NULL, NULL))
  88. goto out;
  89. retval = dst;
  90. out:
  91. OPENSSL_free(tempstr);
  92. RegCloseKey(hkey);
  93. # endif /* REGISTRY_KEY */
  94. return retval;
  95. }
  96. static CRYPTO_ONCE defaults_setup_init = CRYPTO_ONCE_STATIC_INIT;
  97. /**
  98. * @brief Function to setup default values to run once.
  99. * Only used in Windows environments. Does run time initialization
  100. * of openssldir/modulesdir/enginesdir from the registry
  101. */
  102. DEFINE_RUN_ONCE_STATIC(do_defaults_setup)
  103. {
  104. get_windows_regdirs(openssldir, sizeof(openssldir), L"OPENSSLDIR");
  105. get_windows_regdirs(enginesdir, sizeof(enginesdir), L"ENGINESDIR");
  106. get_windows_regdirs(modulesdir, sizeof(modulesdir), L"MODULESDIR");
  107. /*
  108. * Set our pointers only if the directories are fetched properly
  109. */
  110. if (strlen(openssldir) > 0)
  111. openssldirptr = openssldir;
  112. if (strlen(enginesdir) > 0)
  113. enginesdirptr = enginesdir;
  114. if (strlen(modulesdir) > 0)
  115. modulesdirptr = modulesdir;
  116. return 1;
  117. }
  118. #endif /* defined(_WIN32) && defined(OSSL_WINCTX) */
  119. /**
  120. * @brief Get the directory where OpenSSL is installed.
  121. *
  122. * @return A pointer to a string containing the OpenSSL directory path.
  123. */
  124. const char *ossl_get_openssldir(void)
  125. {
  126. #if defined(_WIN32) && defined (OSSL_WINCTX)
  127. if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
  128. return NULL;
  129. return (const char *)openssldirptr;
  130. # else
  131. return OPENSSLDIR;
  132. #endif
  133. }
  134. /**
  135. * @brief Get the directory where OpenSSL engines are located.
  136. *
  137. * @return A pointer to a string containing the engines directory path.
  138. */
  139. const char *ossl_get_enginesdir(void)
  140. {
  141. #if defined(_WIN32) && defined (OSSL_WINCTX)
  142. if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
  143. return NULL;
  144. return (const char *)enginesdirptr;
  145. #else
  146. return ENGINESDIR;
  147. #endif
  148. }
  149. /**
  150. * @brief Get the directory where OpenSSL modules are located.
  151. *
  152. * @return A pointer to a string containing the modules directory path.
  153. */
  154. const char *ossl_get_modulesdir(void)
  155. {
  156. #if defined(_WIN32) && defined(OSSL_WINCTX)
  157. if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
  158. return NULL;
  159. return (const char *)modulesdirptr;
  160. #else
  161. return MODULESDIR;
  162. #endif
  163. }
  164. /**
  165. * @brief Get the build time defined windows installer context
  166. *
  167. * @return A char pointer to a string representing the windows install context
  168. */
  169. const char *ossl_get_wininstallcontext(void)
  170. {
  171. #if defined(_WIN32) && defined (OSSL_WINCTX)
  172. return MAKESTR(OSSL_WINCTX);
  173. #else
  174. return "Undefined";
  175. #endif
  176. }