Coverage Report

Created: 2025-12-31 06:58

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