Coverage Report

Created: 2025-06-22 06:56

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