]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add defaults api to openssl build
authorNeil Horman <nhorman@openssl.org>
Thu, 6 Jun 2024 18:37:37 +0000 (14:37 -0400)
committerNeil Horman <nhorman@openssl.org>
Tue, 9 Jul 2024 08:01:30 +0000 (04:01 -0400)
Build time defaults aren't great for windows, in which various macros
(like OPENSSLDIR) are selected at build time, but may be selected
differently at install time.  Add an internal defaults api to return the
build time constants on unix systems, but instead query registry keys
for the form:
HLKM\SOFTWARE\OpenSSL-{version}-{wininstallcontext}
Such that each built version of openssl may maintain its own set of
registry keys to identify these locations, and be set administratiely as
appropriate at install or run time

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24450)

NOTES-WINDOWS.md
crypto/build.info
crypto/defaults.c [new file with mode: 0644]
include/internal/common.h

index f4573fd4308d871341992d1c8f509abcaf78f81a..e218f28bee7683eb23aea10e02e5df80525aec66 100644 (file)
@@ -125,6 +125,28 @@ Administrator" before running `nmake install`.  The other solution
 is, of course, to choose a different set of directories by using
 `--prefix` and `--openssldir` when configuring.
 
+Note that, on Windows platforms (both 32 and 64 bit), the above build time
+defaults can be overridden by registry keys.  This is done because it is common
+practice for windows based installers to allow users to place the installation
+tree at various locations not defined at build time.  The following keys:
+
+    `\\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\OpenSSL\OPENSSLDIR`
+    `\\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\OpenSSL\ENGINESDIR`
+    `\\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\OpenSSL\MODULESDIR`
+
+Can be administratively set, and openssl will take the paths found there as the
+values for OPENSSLDIR, ENGINESDIR and MODULESDIR respectively.  If unset, the
+build time defaults will be used.
+
+To enable the reading of registry keys from windows builds, add
+`-DWININSTALLCONTEXT=<string>`to the Configure command line.  Without setting
+this, the library defaults back to reporing the build time defaults without
+checking the registry.  Note that if you wish to have a private set of registry
+keys for your application, you should set `OPENSSL_VERSION` to a unique value
+
+Note the installer available at <https://github.com/openssl/installer> will set
+these keys when the installer is run.
+
 Special notes for Universal Windows Platform builds, aka `VC-*-UWP`
 -------------------------------------------------------------------
 
index 90a3b78cda28a8252392b750a37f516fb528e562..881007f8acb171fdcda0a028beb19333944b6631 100644 (file)
@@ -107,7 +107,7 @@ SOURCE[../libcrypto]=$UTIL_COMMON \
         comp_methods.c cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c \
         o_dir.c o_fopen.c getenv.c o_init.c init.c trace.c provider.c \
         provider_child.c punycode.c passphrase.c sleep.c deterministic_nonce.c \
-        quic_vlint.c time.c
+        quic_vlint.c time.c defaults.c
 SOURCE[../providers/libfips.a]=$UTIL_COMMON
 
 SOURCE[../libcrypto]=$UPLINKSRC
diff --git a/crypto/defaults.c b/crypto/defaults.c
new file mode 100644 (file)
index 0000000..792029e
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <openssl/opensslv.h>
+#include "internal/thread_once.h"
+#include "internal/cryptlib.h"
+#include "internal/e_os.h"
+
+#if defined(_WIN32)
+
+# define TOSTR(x) #x
+# define MAKESTR(x) TOSTR(x)
+# define NOQUOTE(x) x
+#if defined(WININSTALLCONTEXT)
+# define REGISTRY_KEY "SOFTWARE\\WOW6432Node\\OpenSSL" ##"-"## NOQUOTE(OPENSSL_VERSION_STR) ##"-"## MAKESTR(WININSTALLCONTEXT)
+#else
+# define REGISTRY_KEY "NONE"
+#endif
+
+/**
+ * @brief The directory where OpenSSL is installed.
+ */
+static char openssldir[MAX_PATH + 1];
+
+/**
+ * @brief The directory where OpenSSL engines are located.
+ */
+
+static char enginesdir[MAX_PATH + 1];
+
+/**
+ * @brief The directory where OpenSSL modules are located.
+ */
+static char modulesdir[MAX_PATH + 1];
+
+/**
+ * @brief Get the list of Windows registry directories.
+ *
+ * This function retrieves a list of Windows registry directories.
+ *
+ * @return A pointer to a char array containing the registry directories.
+ */
+static char *get_windows_regdirs(char *dst, LPCTSTR valuename)
+{
+    DWORD keysize;
+    DWORD ktype;
+    HKEY hkey;
+    LSTATUS ret;
+    DWORD index = 0;
+    LPCTCH tempstr = NULL;
+    char *retval = NULL;
+
+    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                       TEXT(REGISTRY_KEY), KEY_WOW64_32KEY,
+                       KEY_QUERY_VALUE, &hkey);
+    if (ret != ERROR_SUCCESS)
+        goto out;
+
+    ret = RegQueryValueEx(hkey, valuename, NULL, &ktype, NULL,
+                          &keysize);
+    if (ret != ERROR_SUCCESS)
+        goto out;
+    if (ktype != REG_EXPAND_SZ)
+        goto out;
+    if (keysize > MAX_PATH)
+        goto out;
+
+    keysize++;
+    tempstr = OPENSSL_zalloc(keysize * sizeof(TCHAR));
+
+    if (tempstr == NULL)
+        goto out;
+
+    if (RegQueryValueEx(hkey, valuename,
+                        NULL, &ktype, tempstr, &keysize) != ERROR_SUCCESS)
+        goto out;
+
+    if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, keysize,
+                             NULL, NULL)) 
+        goto out;
+
+    retval = dst;
+out:
+    OPENSSL_free(tempstr);
+    RegCloseKey(hkey);
+    return retval;
+}
+
+static CRYPTO_ONCE defaults_setup_init = CRYPTO_ONCE_STATIC_INIT;
+
+/**
+ * @brief Function to setup default values to run once.
+ * Only used in Windows environments.  Does run time initalization
+ * of openssldir/modulesdir/enginesdir from the registry
+ */
+DEFINE_RUN_ONCE_STATIC(do_defaults_setup)
+{
+    char *tmp;
+    tmp = get_windows_regdirs(openssldir, TEXT("OPENSSLDIR"));
+# ifdef OPENSSLDIR
+    if (tmp == NULL)
+        strncpy(openssldir, OPENSSLDIR, MAX_PATH);
+# endif
+    tmp = get_windows_regdirs(enginesdir, TEXT("ENGINESDIR"));
+# ifdef ENGINESDIR
+    if (tmp == NULL)
+        strncpy(enginesdir, ENGINESDIR, MAX_PATH);
+# endif
+    tmp = get_windows_regdirs(modulesdir, TEXT("MODULESDIR"));
+# ifdef MODULESDIR
+    if (tmp == NULL)
+        strncpy(modulesdir, MODULESDIR, MAX_PATH);
+# endif
+        
+    return 1;
+}
+#endif
+
+/**
+ * @brief Get the directory where OpenSSL is installed.
+ *
+ * @return A pointer to a string containing the OpenSSL directory path.
+ */
+const char *ossl_get_openssldir(void)
+{
+#if defined(_WIN32) && defined(WININSTALLCONTEXT)
+    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
+        return NULL;
+    return (const char *)openssldir;
+#else
+# ifdef OPENSSLDIR
+    return OPENSSLDIR;
+# else
+    return "";
+# endif
+#endif
+}
+
+/**
+ * @brief Get the directory where OpenSSL engines are located.
+ *
+ * @return A pointer to a string containing the engines directory path.
+ */
+const char *ossl_get_enginesdir(void)
+{
+#if defined(_WIN32) && defined(WININSTALLCONTEXT)
+    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
+        return NULL;
+    return (const char *)enginesdir;
+#else
+# ifdef OPENSSLDIR
+    return ENGINESDIR;
+# else
+    return "";
+# endif
+#endif
+}
+
+/**
+ * @brief Get the directory where OpenSSL modules are located.
+ *
+ * @return A pointer to a string containing the modules directory path.
+ */
+const char *ossl_get_modulesdir(void)
+{
+#if defined(_WIN32) && defined(WININSTALLCONTEXT)
+    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
+        return NULL;
+    return (const char *)modulesdir;
+#else
+# ifdef OPENSSLDIR
+    return MODULESDIR;
+# else
+    return "";
+# endif
+#endif
+}
+
+/**
+ * @brief Get the build time defined windows installer context
+ *
+ * @return A char pointer to a string representing the windows install context
+ */
+const char *ossl_get_wininstallcontext(void)
+{
+#if defined(_WIN32) && defined (WININSTALLCONTEXT)
+       return MAKESTR(WININSTALLCONTEXT);
+#else
+       return "";
+#endif
+}
index b176a27494ed51ca70fbce23d4013ff4b558c2ea..0c0415b777bd41bfea1f663794a00e757326b95e 100644 (file)
@@ -228,4 +228,9 @@ static ossl_inline int ossl_is_absolute_path(const char *path)
     return path[0] == '/';
 }
 
+const char *ossl_get_openssldir(void);
+const char *ossl_get_enginesdir(void);
+const char *ossl_get_modulesdir(void);
+const char *ossl_get_wininstallcontext(void);
+
 #endif