Merge branch 'openssl-providers'
Optionally load the legacy provider in OpenSSL 3 (enabled, by default) to make algorithms like MD4 and DES available, which we require for EAP-MSCHAPv2. Allow explicitly loading the fips provider via existing fips_mode option. The loaded providers, whether influenced by the above options or not, are logged. Closes strongswan/strongswan#759
This commit is contained in:
@@ -3,3 +3,16 @@ charon.plugins.openssl.engine_id = pkcs11
|
|||||||
|
|
||||||
charon.plugins.openssl.fips_mode = 0
|
charon.plugins.openssl.fips_mode = 0
|
||||||
Set OpenSSL FIPS mode: disabled(0), enabled(1), Suite B enabled(2).
|
Set OpenSSL FIPS mode: disabled(0), enabled(1), Suite B enabled(2).
|
||||||
|
|
||||||
|
Set OpenSSL FIPS mode. With OpenSSL before 3.0, the supported values are
|
||||||
|
disabled(0), enabled(1) and Suite B enabled(2). With OpenSSL 3+, any value
|
||||||
|
other than 0 will explicitly load the fips and base providers (_load_legacy_
|
||||||
|
will be ignored). The latter still requires the config in fipsmodule.cnf
|
||||||
|
(e.g. for the module's MAC), but allows explicitly loading the provider if
|
||||||
|
it's not activated in that config.
|
||||||
|
|
||||||
|
charon.plugins.openssl.load_legacy = yes
|
||||||
|
Load the legacy provider in OpenSSL 3+ for algorithms like MD4, DES, or
|
||||||
|
Blowfish (the first two are required for EAP-MSCHAPv2). If disabled, the
|
||||||
|
default provider is loaded, or those configured in the OpenSSL config (e.g.
|
||||||
|
the fips provider).
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
#include <collections/array.h>
|
||||||
#include <threading/thread.h>
|
#include <threading/thread.h>
|
||||||
#include <threading/mutex.h>
|
#include <threading/mutex.h>
|
||||||
#include <threading/thread_value.h>
|
#include <threading/thread_value.h>
|
||||||
@@ -31,6 +32,9 @@
|
|||||||
#ifndef OPENSSL_NO_ECDH
|
#ifndef OPENSSL_NO_ECDH
|
||||||
#include <openssl/ec.h>
|
#include <openssl/ec.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
#include <openssl/provider.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "openssl_plugin.h"
|
#include "openssl_plugin.h"
|
||||||
#include "openssl_util.h"
|
#include "openssl_util.h"
|
||||||
@@ -70,6 +74,13 @@ struct private_openssl_plugin_t {
|
|||||||
* public functions
|
* public functions
|
||||||
*/
|
*/
|
||||||
openssl_plugin_t public;
|
openssl_plugin_t public;
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
/**
|
||||||
|
* Loaded providers
|
||||||
|
*/
|
||||||
|
array_t *providers;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -876,6 +887,15 @@ METHOD(plugin_t, get_features, int,
|
|||||||
METHOD(plugin_t, destroy, void,
|
METHOD(plugin_t, destroy, void,
|
||||||
private_openssl_plugin_t *this)
|
private_openssl_plugin_t *this)
|
||||||
{
|
{
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
OSSL_PROVIDER *provider;
|
||||||
|
while (array_remove(this->providers, ARRAY_TAIL, &provider))
|
||||||
|
{
|
||||||
|
OSSL_PROVIDER_unload(provider);
|
||||||
|
}
|
||||||
|
array_destroy(this->providers);
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
|
||||||
/* OpenSSL 1.1.0 cleans up itself at exit and while OPENSSL_cleanup() exists we
|
/* OpenSSL 1.1.0 cleans up itself at exit and while OPENSSL_cleanup() exists we
|
||||||
* can't call it as we couldn't re-initialize the library (as required by the
|
* can't call it as we couldn't re-initialize the library (as required by the
|
||||||
* unit tests and the Android app) */
|
* unit tests and the Android app) */
|
||||||
@@ -896,6 +916,31 @@ METHOD(plugin_t, destroy, void,
|
|||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
typedef struct {
|
||||||
|
char names[BUF_LEN];
|
||||||
|
int len;
|
||||||
|
} ossl_provider_names_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to produce a list of the names of loaded providers
|
||||||
|
*/
|
||||||
|
static int concat_ossl_providers(OSSL_PROVIDER *provider, void *cbdata)
|
||||||
|
{
|
||||||
|
ossl_provider_names_t *data = cbdata;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = snprintf(&data->names[data->len], sizeof(data->names) - data->len,
|
||||||
|
" %s", OSSL_PROVIDER_get0_name(provider));
|
||||||
|
if (len < (sizeof(data->names) - data->len))
|
||||||
|
{
|
||||||
|
data->len += len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* see header file
|
* see header file
|
||||||
*/
|
*/
|
||||||
@@ -911,15 +956,16 @@ plugin_t *openssl_plugin_create()
|
|||||||
{
|
{
|
||||||
if (FIPS_mode() != fips_mode && !FIPS_mode_set(fips_mode))
|
if (FIPS_mode() != fips_mode && !FIPS_mode_set(fips_mode))
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "unable to set openssl FIPS mode(%d) from (%d)",
|
DBG1(DBG_LIB, "unable to set OpenSSL FIPS mode(%d) from (%d)",
|
||||||
fips_mode, FIPS_mode());
|
fips_mode, FIPS_mode());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
|
/* OpenSSL 3.0+ is handled below */
|
||||||
if (fips_mode)
|
if (fips_mode)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "openssl FIPS mode(%d) unavailable", fips_mode);
|
DBG1(DBG_LIB, "OpenSSL FIPS mode(%d) unavailable", fips_mode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -952,11 +998,43 @@ plugin_t *openssl_plugin_create()
|
|||||||
#endif /* OPENSSL_NO_ENGINE */
|
#endif /* OPENSSL_NO_ENGINE */
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
if (fips_mode)
|
||||||
|
{
|
||||||
|
OSSL_PROVIDER *fips;
|
||||||
|
|
||||||
|
fips = OSSL_PROVIDER_load(NULL, "fips");
|
||||||
|
if (!fips)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "unable to load OpenSSL FIPS provider");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
array_insert_create(&this->providers, ARRAY_TAIL, fips);
|
||||||
|
/* explicitly load the base provider containing encoding functions */
|
||||||
|
array_insert_create(&this->providers, ARRAY_TAIL,
|
||||||
|
OSSL_PROVIDER_load(NULL, "base"));
|
||||||
|
}
|
||||||
|
else if (lib->settings->get_bool(lib->settings, "%s.plugins.openssl.load_legacy",
|
||||||
|
TRUE, lib->ns))
|
||||||
|
{
|
||||||
|
/* load the legacy provider for algorithms like MD4, DES, BF etc. */
|
||||||
|
array_insert_create(&this->providers, ARRAY_TAIL,
|
||||||
|
OSSL_PROVIDER_load(NULL, "legacy"));
|
||||||
|
/* explicitly load the default provider, as mentioned by crypto(7) */
|
||||||
|
array_insert_create(&this->providers, ARRAY_TAIL,
|
||||||
|
OSSL_PROVIDER_load(NULL, "default"));
|
||||||
|
}
|
||||||
|
ossl_provider_names_t data = {};
|
||||||
|
OSSL_PROVIDER_do_all(NULL, concat_ossl_providers, &data);
|
||||||
|
dbg(DBG_LIB, strpfx(lib->ns, "charon") ? 1 : 2,
|
||||||
|
"providers loaded by OpenSSL:%s", data.names);
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
|
||||||
#ifdef OPENSSL_FIPS
|
#ifdef OPENSSL_FIPS
|
||||||
/* we do this here as it may have been enabled via openssl.conf */
|
/* we do this here as it may have been enabled via openssl.conf */
|
||||||
fips_mode = FIPS_mode();
|
fips_mode = FIPS_mode();
|
||||||
dbg(DBG_LIB, strpfx(lib->ns, "charon") ? 1 : 2,
|
dbg(DBG_LIB, strpfx(lib->ns, "charon") ? 1 : 2,
|
||||||
"openssl FIPS mode(%d) - %sabled ", fips_mode, fips_mode ? "en" : "dis");
|
"OpenSSL FIPS mode(%d) - %sabled ", fips_mode, fips_mode ? "en" : "dis");
|
||||||
#endif /* OPENSSL_FIPS */
|
#endif /* OPENSSL_FIPS */
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x1010100fL
|
#if OPENSSL_VERSION_NUMBER < 0x1010100fL
|
||||||
|
|||||||
Reference in New Issue
Block a user