Coverage Report

Created: 2025-12-10 06:24

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