Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read OPENSSLDIR from registry #24450

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

nhorman
Copy link
Contributor

@nhorman nhorman commented May 21, 2024

The windows installer we have allows for targeting arbitrary locations when installing our software. But we have a build time defined default directory OPENSSLDIR which may not match that target, leading to missing configuration files/etc. Enhance openssl to query the registry for the key that our installer creates allowing for an installation to match the run time defaults. Back off to the build time directory only if the key is not defined

@nhorman nhorman self-assigned this May 21, 2024
@nhorman nhorman linked an issue May 21, 2024 that may be closed by this pull request
2 tasks
@mattcaswell mattcaswell added branch: master Merge to master branch approval: review pending This pull request needs review by a committer approval: otc review pending This pull request needs review by an OTC member triaged: feature The issue/pr requests/adds a feature hold: needs tests The PR needs tests to be added to it labels May 21, 2024
Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a test for this.

What about MODULESDIR and ENGINESDIR?

Do we also need some documentation?

crypto/x509/x509_def.c Outdated Show resolved Hide resolved
crypto/x509/x509_def.c Outdated Show resolved Hide resolved
crypto/x509/x509_def.c Outdated Show resolved Hide resolved
crypto/x509/x509_def.c Outdated Show resolved Hide resolved
crypto/x509/x509_def.c Outdated Show resolved Hide resolved
We normally define and use these macros directly, but on windows, thats
undesireable as we don't know the real locations of these macros until
install time.

Add an api set to fetch these values, that just returns the macro for
non-windows platform.  On windows, redirect to some internal functions
to grab the values from the registry (as written by the installer),
backing off to the build time macro values in the event they don't exist
Make use of our new defaults api to get the build time macros from the
windows registry where needed
@nhorman nhorman force-pushed the read-openssldir-from-registry branch from 995c03b to d125bc4 Compare May 23, 2024 19:51
@github-actions github-actions bot added the severity: fips change The pull request changes FIPS provider sources label May 23, 2024
Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some documentation and a test would still be good.

crypto/defaults.c Outdated Show resolved Hide resolved
crypto/defaults.c Show resolved Hide resolved
crypto/defaults.c Outdated Show resolved Hide resolved
crypto/defaults.c Show resolved Hide resolved
crypto/defaults.c Outdated Show resolved Hide resolved
crypto/defaults.c Outdated Show resolved Hide resolved
crypto/defaults.c Outdated Show resolved Hide resolved
crypto/x509/x509_def.c Outdated Show resolved Hide resolved
crypto/x509/x509_def.c Show resolved Hide resolved
Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just some minor nits. Still needs documentation/test

crypto/defaults.c Outdated Show resolved Hide resolved
crypto/defaults.c Outdated Show resolved Hide resolved
crypto/x509/x509_def.c Outdated Show resolved Hide resolved
Since windows builds now try to pull build time defines from the
registry first, lets add a test to setup some dummy registry entries,
and run the version command to see if they get pulled out properly
Added a url without the prorper guards on it
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 run time. The following keys:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean "not defined at build time"?

build time defaults will be used.

Note the installer available at https://github.com/openssl/installer will set
theys keys when the installer is run.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: these

@@ -61,7 +61,7 @@ were given during the build process. You can check the location of the config
file by running this command:

$ openssl version -d
OPENSSLDIR: "/usr/local/ssl"
$ /usr/local/ssl
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it seemed odd when specifying -d for openssl dir to explicitly print OPENSSLDIR on the output. I can reinstate that if you like though

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert that change. People can have scripts that depend on this.

@@ -0,0 +1,42 @@
#! /usr/bin/env perl
# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2024

"Adding ENGINESDIR registry key");

ok(run(cmd(["reg.exe", "add", "HKLM\\SOFTWARE\\WOW6432Node\\OpenSSL", "/t", "REG_EXPAND_SZ", "/v", "MODULESDIR", "/d", "TESTMODULESDIR", "/f"])),
"Adding MODULESDIR registry key");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm.....so this is going to overwrite any existing registry entries?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, do you think we need to restore them afterwards?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly skip the test if they already exist - and if we do run the test, then delete them afterwards

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is bad. Although I understand we want to test it, running make test should not make any system-wide changes. Can we test this in a github CI job instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, sure, its getting tested in CI now. But testing it implies that the registry needs to have the keys set. I suppose the most appropriate solution is to do what @mattcaswell suggests and only preform the test if the keys aren't already set, then delete them afterward. That will have the odd side effect of skipping the test on any windows platform that has run the installer already of course, but perhaps thats ok, as having run the installer implies that their not building from source there anyway

Copy link
Member

@t8m t8m May 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about doing the test passively - i.e. read the registry entries with reg.exe instead of setting them and if they are set then compare the values with the openssl version output? Then, in a CI job definition use the reg.exe to set some values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but in that event the test will be skipped on local systems in which the registry keys aren't already set, I suppose that might be ok though, but its not ideal.

Copy link
Member

@t8m t8m May 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really, the make test is not supposed to mess up with your system. And I assume if you're an unprivileged user trying to run make test, this test would fail because you should not be able to edit the system wide registry as an unprivileged user. Unless there is some kind of local user override for the SOFTWARE keys - I have no idea if there is such thing, not being a Windows developer for a very long time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just going to go with the passive approach. Skip the test if the appropriate keys aren't set, and modify the ci workflow to set the right keys. The local tests for windows will get skipped, but we'll get regular testing in CI that way

char *retval = NULL;

ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Wow6432Node\\OpenSSL"), 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this somehow include the version number in the key? i.e. so that you can have multiple instances of OpenSSL installed?

Copy link
Contributor Author

@nhorman nhorman May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to decide on that, we could certainly do that, but it creates another level of indirection, given that these can already be overriden by the OPENSSL_CONF, OPENSSL_MODULES, and OPENSSL_ENGINES environment variable. It also means that we have to co-ordinate the version string built into the binary with the version string used to create the installer. which is feasible, but needs to be done over in the installer repo

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is very likely that people will want multiple installations and to keep them separate. I also think the installer should be aware of what version it is installing. So I think it would be a really good idea to do this. I probably would not keep different patch versions distinct, but IMO different minor/major versions definitely should be.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested read order :

  • HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\OpenSSL\3.2
  • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\OpenSSL\3.2
  • HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\OpenSSL
  • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\OpenSSL

where :

  • 3.2 should be replaced by compiled version no.
  • Wow6432Node should be removed on WIN64 define presence.

Writing into HKEY_LOCAL_MACHINE implies "admin rights" for actual user and current running shell also.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the multi-tiered fallback? Individual users can already override specific default values with OPENSSL_CONF / OPENSSL_ENGINES / OPENSSL_MODULES in the environment. This seems like unneeded complication

@mattcaswell
Copy link
Member

Also this needs a rebase

@mattcaswell
Copy link
Member

I'm wondering whether the registry key look up should be a compile time option. Consider the example where someone installs OpenSSL on their machine using the installer. But they also have an application which has statically linked OpenSSL (or maybe just bundled its own version of OpenSSL). Suddenly that application will start getting its locations from the registry and maybe break.

@mattcaswell
Copy link
Member

I'm wondering whether the registry key look up should be a compile time option. Consider the example where someone installs OpenSSL on their machine using the installer. But they also have an application which has statically linked OpenSSL (or maybe just bundled its own version of OpenSSL). Suddenly that application will start getting its locations from the registry and maybe break.

Maybe the compile time option could be set by setting an installer "context" define "-DINSTALLCONTEXT=blah", which could be included in the registry key and stop different builds of OpenSSL (maybe produced by different people) from interfering with each other.

Copy link
Contributor

@FdaSilvaYY FdaSilvaYY left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few comments about Unicode possible issues.

*
* @return A pointer to a char array containing the registry directories.
*/
static char *get_windows_regdirs(char *dst, LPCWSTR valuename)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be LPCTSTR to be coherent with TCHAR declaration and TEXT macro usage.

/**
* @brief The directory where OpenSSL is installed.
*/
static char openssldir[MAX_PATH];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I advise you to declare its size as [MAX_PATH + 1] here, IMHO.
This will spare some MAX.. - 1 arithmetic thereafter.

DWORD ktype;
HKEY hkey;
LSTATUS ret;
LPCWCH tempstr = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LPCTCH, if it exist or any T equivalent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LPTSTR tempstr = NULL

crypto/defaults.c Show resolved Hide resolved

/**
* @brief Function to setup default values to run once.
* Only used in WIN32 environments. Does run time initalization
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIN32 -> Windows?

@@ -61,7 +61,7 @@ were given during the build process. You can check the location of the config
file by running this command:

$ openssl version -d
OPENSSLDIR: "/usr/local/ssl"
$ /usr/local/ssl
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert that change. People can have scripts that depend on this.

@nhorman
Copy link
Contributor Author

nhorman commented May 29, 2024

@mattcaswell I think adding a version prefix to the key would be the less confusing way to go, then each installation would just use their respective key. Ostensibly if someone has release installed via the installer, then builds openssl manually the version string should have been bumped, and there will be no conflict. the corner case there is if someone builds from an old tag against an already installed version, but at that point they have the environment variables to allow redirection. Presumably, it also seems unlikely that someone interested in using the windows installer will also be building locally that often, given that the installer is being created so that users don't have to build openssl themselves

@mattcaswell
Copy link
Member

@mattcaswell I think adding a version prefix to the key would be the less confusing way to go, then each installation would just use their respective key. Ostensibly if someone has release installed via the installer, then builds openssl manually the version string should have been bumped, and there will be no conflict. the corner case there is if someone builds from an old tag against an already installed version, but at that point they have the environment variables to allow redirection. Presumably, it also seems unlikely that someone interested in using the windows installer will also be building locally that often, given that the installer is being created so that users don't have to build openssl themselves

I disagree. I think it is very likely that people will end up a directly installed version of OpenSSL and a version of OpenSSL coming from somewhere else - quite possible of the same version (e.g. the static linking case where OpenSSL is being used in an application and maybe the end user is not even aware of it - plus a directly installed version). I think there is potential for huge confusion here and opportunity for things to be messed up. This is why I think having the registry keys thing being a build time option (off by default) is going to be essential. Having an installer specific context as an element in the key name in addition to the version would be a good thing too IMO to further reduce the possibility of problems.

Copy link
Contributor

@FdaSilvaYY FdaSilvaYY left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 small comments

&keysize);
if (ret != ERROR_SUCCESS)
goto out;
if (ktype != REG_EXPAND_SZ)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REG_EXPAND_SZ means that registry value can contains some enviroment variables (like %PATH%), who will be expand and returned.
You need to accept REG_SZ key type too.

static char x509_cert_dir[MAX_PATH];
static char x509_cert_file[MAX_PATH];

static void get_windows_default_path(char *pathname, char *suffix)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const char *suffix ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approval: otc review pending This pull request needs review by an OTC member approval: review pending This pull request needs review by a committer branch: master Merge to master branch hold: needs tests The PR needs tests to be added to it severity: fips change The pull request changes FIPS provider sources triaged: feature The issue/pr requests/adds a feature
Projects
Status: In progress
Development

Successfully merging this pull request may close these issues.

Implement relocatable binaries for windows installer
5 participants