Hi, On Thu, Nov 11, 2021 at 2:21 PM Arne Schwabe <a...@rfc2549.org> wrote:
> This allows OpenVPN to load non-default providers. This is mainly > useful for loading the legacy provider with --providers legacy default > > Patch v4: use spaces to seperate providers, unload providers. > Patch v5: General cleanup, rename option to --providers, add > option to usage() and add an entry to Changes.rst > > Signed-off-by: Arne Schwabe <a...@rfc2549.org> > --- > Changes.rst | 7 +++++++ > doc/man-sections/generic-options.rst | 12 +++++++++++ > src/openvpn/crypto_backend.h | 15 ++++++++++++++ > src/openvpn/crypto_mbedtls.c | 13 ++++++++++++ > src/openvpn/crypto_mbedtls.h | 3 +++ > src/openvpn/crypto_openssl.c | 30 ++++++++++++++++++++++++++++ > src/openvpn/crypto_openssl.h | 9 +++++++++ > src/openvpn/openvpn.c | 13 ++++++++++++ > src/openvpn/options.c | 8 ++++++++ > src/openvpn/options.h | 9 +++++++++ > 10 files changed, 119 insertions(+) > > diff --git a/Changes.rst b/Changes.rst > index 6f04e59ac..0ce39a839 100644 > --- a/Changes.rst > +++ b/Changes.rst > @@ -50,6 +50,13 @@ Compatibility mode (``--compat-mode``) > with older peers. The options ``--compat-mode`` allows UIs to provide > users > with an easy way to still connect to older servers. > > +OpenSSL 3.0 support > + OpenSSL 3.0 has been added. Most of OpenSSL 3.0 changes are not user > visible but > + improve general compatibility with OpenSSL 3.0. ``--tls-cert-profile > insecure`` > + has been added to allow selecting the lowest OpenSSL security level > (not > + recommended, use only if you must). OpenSSL 3.0 no longer supports > the Blowfish > + (and other deprecated) algorithm by default and the new option > ``--provider`` > + allows loading the legacy provider to renable these algorithms. > > Deprecated features > ------------------- > diff --git a/doc/man-sections/generic-options.rst > b/doc/man-sections/generic-options.rst > index e6c1fe455..a8f049f20 100644 > --- a/doc/man-sections/generic-options.rst > +++ b/doc/man-sections/generic-options.rst > @@ -280,6 +280,18 @@ which mode OpenVPN is configured as. > This option solves the problem by persisting keys across :code:`SIGUSR1` > resets, so they don't need to be re-read. > > +--providers providers > + Load the list of (OpenSSL) providers. This is mainly useful for using an > + external provider for key management like tpm2-openssl or to load the > + legacy provider with > + > + :: > + > + --providers legacy default > + > + Behaviour of changing this option between SIGHUP might not be well > behaving. > + If you need to change/add/remove this option, fully restart OpenVPN. > + > --remap-usr1 signal > Control whether internally or externally generated :code:`SIGUSR1` > signals > are remapped to :code:`SIGHUP` (restart without persisting state) or > diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h > index 5aab3e1b7..c16837619 100644 > --- a/src/openvpn/crypto_backend.h > +++ b/src/openvpn/crypto_backend.h > @@ -78,6 +78,21 @@ void crypto_clear_error(void); > */ > void crypto_init_lib_engine(const char *engine_name); > > + > +/** > + * Load the given (OpenSSL) providers > + * @param provider name of providers to load > + * @return reference to the loaded provider > + */ > +provider_t *crypto_load_provider(const char *provider); > + > +/** > + * Unloads the given (OpenSSL) provider > + * @param provname name of the provider to unload > + * @param provider pointer to the provider to unload > + */ > +void crypto_unload_provider(const char* provname, provider_t *provider); > + > #ifdef DMALLOC > /* > * OpenSSL memory debugging. If dmalloc debugging is enabled, tell > diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c > index 08b9e004f..39dbf38a5 100644 > --- a/src/openvpn/crypto_mbedtls.c > +++ b/src/openvpn/crypto_mbedtls.c > @@ -69,6 +69,19 @@ crypto_init_lib_engine(const char *engine_name) > "available"); > } > > +provider_t *crypto_load_provider(const char *provider) > +{ > + if (provider) > + { > + msg(M_WARN, "Note: mbed TLS provider functionality is not > available"); > + } > + return NULL; > +} > + > +void crypto_unload_provider(const char* provname, provider_t *provider) > +{ > +} > + > /* > * > * Functions related to the core crypto library > diff --git a/src/openvpn/crypto_mbedtls.h b/src/openvpn/crypto_mbedtls.h > index 019de01d1..758ab1b40 100644 > --- a/src/openvpn/crypto_mbedtls.h > +++ b/src/openvpn/crypto_mbedtls.h > @@ -48,6 +48,9 @@ typedef mbedtls_md_context_t md_ctx_t; > /** Generic HMAC %context. */ > typedef mbedtls_md_context_t hmac_ctx_t; > > +/* Use a dummy type for the provider */ > +typedef void provider_t; > + > /** Maximum length of an IV */ > #define OPENVPN_MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH > > diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c > index cc1d62210..c9731adb3 100644 > --- a/src/openvpn/crypto_openssl.c > +++ b/src/openvpn/crypto_openssl.c > @@ -54,6 +54,9 @@ > #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && > !defined(LIBRESSL_VERSION_NUMBER) > #include <openssl/kdf.h> > #endif > +#if OPENSSL_VERSION_NUMBER >= 0x30000000L > +#include <openssl/provider.h> > +#endif > > #if defined(_WIN32) && defined(OPENSSL_NO_EC) > #error Windows build with OPENSSL_NO_EC: disabling EC key is not > supported. > @@ -149,6 +152,33 @@ crypto_init_lib_engine(const char *engine_name) > #endif > } > > +provider_t * > +crypto_load_provider(const char *provider) > +{ > +#if OPENSSL_VERSION_NUMBER >= 0x30000000L > + /* Load providers into the default (NULL) library context */ > + OSSL_PROVIDER* prov = OSSL_PROVIDER_load(NULL, provider); > + if (!prov) > + { > + crypto_msg(M_FATAL, "failed to load provider '%s'", provider); > + } > + return prov; > +#else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ > + msg(M_WARN, "Note: OpenSSL provider functionality is not available"); > + return NULL; > +#endif > +} > + > +void crypto_unload_provider(const char* provname, provider_t *provider) > +{ > +#if OPENSSL_VERSION_NUMBER >= 0x30000000L > + if (!OSSL_PROVIDER_unload(provider)) > + { > + crypto_msg(M_FATAL, "failed to unload provider '%s'", provname); > + } > +#endif > +} > + > /* > * > * Functions related to the core crypto library > diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h > index e540a76b9..446f08508 100644 > --- a/src/openvpn/crypto_openssl.h > +++ b/src/openvpn/crypto_openssl.h > @@ -33,6 +33,10 @@ > #include <openssl/hmac.h> > #include <openssl/md5.h> > #include <openssl/sha.h> > +#if OPENSSL_VERSION_NUMBER >= 0x30000000L > +#include <openssl/provider.h> > +#endif > + > > /** Generic cipher key type %context. */ > typedef EVP_CIPHER cipher_kt_t; > @@ -49,12 +53,17 @@ typedef EVP_MD_CTX md_ctx_t; > /** Generic HMAC %context. */ > #if OPENSSL_VERSION_NUMBER < 0x30000000L > typedef HMAC_CTX hmac_ctx_t; > + > +/* Use a dummy type for the provider */ > +typedef void provider_t; > #else > typedef struct { > OSSL_PARAM params[3]; > uint8_t key[EVP_MAX_KEY_LENGTH]; > EVP_MAC_CTX *ctx; > } hmac_ctx_t; > + > +typedef OSSL_PROVIDER provider_t; > #endif > > /** Maximum length of an IV */ > diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c > index da06f59c2..a18a4dd43 100644 > --- a/src/openvpn/openvpn.c > +++ b/src/openvpn/openvpn.c > @@ -112,10 +112,23 @@ void init_early(struct context *c) > /* init verbosity and mute levels */ > init_verb_mute(c, IVM_LEVEL_1); > > + /* Initialise OpenSSL provider, this needs to be initialised this > + * early since option post-processing and also openssl info > + * printing depends on it */ > + for (int j=1; j < MAX_PARMS && c->options.providers.names[j]; j++) > + { > + c->options.providers.providers[j] = > + crypto_load_provider(c->options.providers.names[j]); > + } > } > > static void uninit_early(struct context *c) > { > + for (int j=1; j < MAX_PARMS && c->options.providers.providers[j]; j++) > + { > + crypto_unload_provider(c->options.providers.names[j], > + c->options.providers.providers[j]); > + } > net_ctx_free(&c->net_ctx); > } > > diff --git a/src/openvpn/options.c b/src/openvpn/options.c > index b5d65d293..b1f9473dc 100644 > --- a/src/openvpn/options.c > +++ b/src/openvpn/options.c > @@ -581,6 +581,7 @@ static const char usage_message[] = > " : Use --show-tls to see a list of supported TLS > ciphers (suites).\n" > "--tls-cert-profile p : Set the allowed certificate crypto algorithm > profile\n" > " (default=legacy).\n" > + "--providers l : A list l of OpenSSL providers to load.\n" > "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" > " if no ACK from remote within n seconds > (default=%d).\n" > "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and > recvd.\n" > @@ -8157,6 +8158,13 @@ add_option(struct options *options, > options->engine = "auto"; > } > } > + else if (streq(p[0], "providers") && p[1]) > + { > + for (size_t j = 1; j < MAX_PARMS && p[j] != NULL;j++) > + { > + options->providers.names[j] = p[j]; > + } > + } > #endif /* ENABLE_CRYPTO_MBEDTLS */ > #ifdef ENABLE_PREDICTION_RESISTANCE > else if (streq(p[0], "use-prediction-resistance") && !p[1]) > diff --git a/src/openvpn/options.h b/src/openvpn/options.h > index 20b34ed4e..d4f41cd71 100644 > --- a/src/openvpn/options.h > +++ b/src/openvpn/options.h > @@ -179,6 +179,14 @@ struct remote_list > struct remote_entry *array[CONNECTION_LIST_SIZE]; > }; > > +struct provider_list > +{ > + /* Names of the providers */ > + const char *names[MAX_PARMS]; > + /* Pointers to the loaded providers to unload them */ > + provider_t *providers[MAX_PARMS]; > +}; > + > enum vlan_acceptable_frames > { > VLAN_ONLY_TAGGED, > @@ -519,6 +527,7 @@ struct options > const char *ncp_ciphers; > const char *authname; > const char *engine; > + struct provider_list providers; > bool replay; > bool mute_replay_warnings; > int replay_window; > -- > 2.33.0 > Acked-by: Selva Nair <selva.n...@gmail.com> Request for nit-fix during commit: In the newly added paragraph in Changes.rst please change ``--provider`` to ``--providers`` Selva
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel