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