/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  | }  |