Coverage Report

Created: 2025-12-08 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/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" "-" 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 modules are located.
37
 */
38
static char modulesdir[MAX_PATH + 1];
39
40
/**
41
 * @brief The pointer to the modulesdir buffer
42
 */
43
static char *modulesdirptr = NULL;
44
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
63
    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
64
                       TEXT(REGISTRY_KEY), KEY_WOW64_32KEY,
65
                       KEY_QUERY_VALUE, &hkey);
66
    if (ret != ERROR_SUCCESS)
67
        goto out;
68
69
    /* Always use wide call so we can avoid extra encoding conversions on the output */
70
    ret = RegQueryValueExW(hkey, valuename, NULL, &ktype, NULL,
71
                           &keysizebytes);
72
    if (ret != ERROR_SUCCESS)
73
        goto out;
74
    if (ktype != REG_EXPAND_SZ && ktype != REG_SZ)
75
        goto out;
76
    if (keysizebytes > MAX_PATH * sizeof(WCHAR))
77
        goto out;
78
79
    /*
80
     * RegQueryValueExW does not guarantee the buffer is null terminated,
81
     * so we make space for one in the allocation
82
     */
83
    tempstr = OPENSSL_zalloc(keysizebytes + sizeof(WCHAR));
84
85
    if (tempstr == NULL)
86
        goto out;
87
88
    if (RegQueryValueExW(hkey, valuename,
89
                         NULL, &ktype, (LPBYTE)tempstr, &keysizebytes) != ERROR_SUCCESS)
90
        goto out;
91
92
    if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, dstsizebytes,
93
                             NULL, NULL))
94
        goto out;
95
96
    retval = dst;
97
out:
98
    OPENSSL_free(tempstr);
99
    RegCloseKey(hkey);
100
# endif /* REGISTRY_KEY */
101
    return retval;
102
}
103
104
static CRYPTO_ONCE defaults_setup_init = CRYPTO_ONCE_STATIC_INIT;
105
106
/**
107
 * @brief Function to setup default values to run once.
108
 * Only used in Windows environments.  Does run time initialization
109
 * of openssldir/modulesdir/enginesdir from the registry
110
 */
111
DEFINE_RUN_ONCE_STATIC(do_defaults_setup)
112
{
113
    get_windows_regdirs(openssldir, sizeof(openssldir), L"OPENSSLDIR");
114
    get_windows_regdirs(modulesdir, sizeof(modulesdir), L"MODULESDIR");
115
116
    /*
117
     * Set our pointers only if the directories are fetched properly
118
     */
119
    if (strlen(openssldir) > 0)
120
        openssldirptr = openssldir;
121
122
    if (strlen(modulesdir) > 0)
123
        modulesdirptr = modulesdir;
124
125
    return 1;
126
}
127
#endif /* defined(_WIN32) && defined(OSSL_WINCTX) */
128
129
/**
130
 * @brief Get the directory where OpenSSL is installed.
131
 *
132
 * @return A pointer to a string containing the OpenSSL directory path.
133
 */
134
const char *ossl_get_openssldir(void)
135
0
{
136
#if defined(_WIN32) && defined (OSSL_WINCTX)
137
    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
138
        return NULL;
139
    return (const char *)openssldirptr;
140
# else
141
0
    return OPENSSLDIR;
142
0
#endif
143
0
}
144
145
/**
146
 * @brief Get the directory where OpenSSL modules are located.
147
 *
148
 * @return A pointer to a string containing the modules directory path.
149
 */
150
const char *ossl_get_modulesdir(void)
151
0
{
152
#if defined(_WIN32) && defined(OSSL_WINCTX)
153
    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
154
        return NULL;
155
    return (const char *)modulesdirptr;
156
#else
157
0
    return MODULESDIR;
158
0
#endif
159
0
}
160
161
/**
162
 * @brief Get the build time defined windows installer context
163
 *
164
 * @return A char pointer to a string representing the windows install context
165
 */
166
const char *ossl_get_wininstallcontext(void)
167
0
{
168
#if defined(_WIN32) && defined (OSSL_WINCTX)
169
    return MAKESTR(OSSL_WINCTX);
170
#else
171
0
    return "Undefined";
172
0
#endif
173
0
}