OpenVPN / openvpn

OpenVPN is an open source VPN daemon
http://openvpn.net
Other
10.26k stars 2.92k forks source link

OpenVPN fails when using OpenSSL v3.0.9 configured with the FIPS provider #460

Closed cliffede closed 4 months ago

cliffede commented 7 months ago

IMPORTANT NOTE Bugs about OpenVPN Access Server, OpenVPN Connect or any other product by OpenVPN Inc. should be directly reported to OpenVPN Inc. at https://support.openvpn.net

Describe the bug This line fails when OpenSSL 3.0.x is using the FIPS + BASE providers: https://github.com/OpenVPN/openvpn/blob/v2.6.8/src/openvpn/crypto_openssl.c#L1394 i.e. openSSL call EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_md5_sha1()) fails. MD5 is not provided by the FIPS provider in OpenSSL since MD5 is not an approved FIPS algorithm.

To Reproduce Install v3.0.9 of OpenSSL including the FIPS module. Likely reproducable on any OpenSSL version >= 3.0, but 3.0.8 has a FIPS 140-2 approved module, 3.0.9 has a FIPS module pending approval. For FIPS module installation, see: https://github.com/openssl/openssl/blob/openssl-3.0.9/README-FIPS.md Configure OpenSSL to use the FIPS and BASE providers instead of the DEFAULT provider. See: https://www.openssl.org/docs/manmaster/man7/fips_module.html. Build OpenVPN v2.6.8 against OpenSSL. Now create a VPN connection. Ensure that the OpenVPN configuration does not contain a providers entry.

Expected behavior The openVPN connection can be brought up.

Version information (please complete the following information): Linux 5.4 OpenSSL 3.0.9 OpenVPN 2.6.8

Additional context The platform used was ARMv5 embedded using a buildroot generated rootfs. It is suspected this can be reproduced with a mainline Linux distro running on AMD64.

cron2 commented 7 months ago

My understanding is that MD5 should be fine if used in PRF role - and it does work fine with OpenSSL 1.x on FIPS systems. So maybe something else needs to be adjusted.

@schwabe?

schwabe commented 7 months ago

OpenVPN used to use the TLS 1.0/1.1 PRF which so far was still allowed by the FIPS specification. At least previous FIPS specifcation specificially allowed the TLS 1.0/1.1 PRF to be used (which uses MD5). If FIPS no longer supports TLS 1.0/1.1 and/or the TLS 1.0/1.1 PRF, there is basically nothing we can in these circumstances.

OpenVPN 2.6.0+ (and also OpenVPN 3.x) will already prefer using the TLS export feature to the TLS 1.0/1.1 PRF when the peer also supports it (6dc09d0d4520483716530e12a444b156720cdfcc). What version has the peer that you are connecting to?

It might be that reality now is that if you need FIPS with current guidlines all OpenVPN peers must be modern enough (2.6.0+) to use TLS export or you cannot establish a connection with a modern FIPS implementation.

And yes, I can see that also the current RHEL9 in FIPS seems to be affected as well.

cliffede commented 7 months ago

I am connecting to a peer version 2.5.5, so does not have the TLS export feature. I will try a later version. Thanks for the pointer.

cron2 commented 7 months ago

for completeness, @cliffede , can you provide a log file that shows how it fails (verb 4)? Is there a particular error message, or is it just failing silently?

schwabe commented 7 months ago

We might still be able to get this fixed. Or OpenSSL documentation is broken:

https://www.openssl.org/docs/man3.2/man7/OSSL_PROVIDER-FIPS.html still lists TLS1-PRF, see EVP_KDF-TLS1_PRF(7) but the API changed.

I will look into that.

schwabe commented 7 months ago

So that does not change anything. Using the new API gives the same internal OpenSSL error:

2023-11-21 20:27:04 us=780 styx-secp/192.168.188.77:1194 OpenSSL: error:0308010C:digital envelope routines::unsupported:FIPS internal library context, Algorithm (MD5 : 0), Properties (<null>)
2023-11-21 20:27:04 us=797 styx-secp/192.168.188.77:1194 EVP_KDF_derive failed

So OpenSSL 3.0 just does not like TLS 1.0 PRF anymore.

If you want to try the patch yourself. It is on Gerrit: https://gerrit.openvpn.net/c/openvpn/+/457

cliffede commented 7 months ago

I have tested with peer version 2.6.8 and the problem is resolved in that case, no doubt because generate_key_expansion_tls_export() is called instead of generate_key_expansion_openvpn_prf().

To answer @cron2 OpenVPN v2.6.8 did not fail silently, I had this in the log:

TLS Error: PRF calcuation failed TLS Error: generate_key_expansion failed OPTIONS ERROR: failed to import crypto options

I instrumented the code to call crypto_print_openssl_errors() and when I did that, the log revealed:

OpenSSL: error:0308010C:digital envelope routines::unsupported:FIPS internal library context, Algorithm (MD5 : 0), Properties <null>)

schwabe commented 7 months ago

So yes that is basically the same what I am seeing and is "expected" behaviour.

cliffede commented 7 months ago

@schwabe: By the way, I tried your patch https://gerrit.openvpn.net/c/openvpn/+/457 and got the same result as you.

schwabe commented 7 months ago

@cliffede yeah. I think the conclusion is that OpenVPN 2.6.x when running on modern FIPS is only compatible with other 2.6.x versions. There is also nothing really to fix since we can only add fixes to new versions and new versions already happily work with each other.

The only thing that my patches gives you is that you can now probably load a hacky OpenSSL provider that provides the TLS-1 PRF with MD5+SHA1 again to make this work again but then you also just disable FIPS.

cliffede commented 7 months ago

@schwabe: The patch looks the right way to go, a pity the OpenSSL documentation is misleading in suggesting it is supported by the FIPS module.

I would like to extract this PRF/TLS extract status from the openvpn program when it is running. I could trap the logs but I'm not a fan of doing that as it provides maintenance problems and in any case logging content should never really control program flow...

What I really want to do is to provide a status to the end user when the tunnel fails to up, e.g. Error - the OpenVPN server version may be too old, try v2.6.0 or later...

Do you have any ides on how to do this? Otherwise I will look to patch openvpn locally...

schwabe commented 7 months ago

@cliffede the documentation is not really wrong. It is more a bit misleading. It is more the fine print print that matters. The FIPS module supports TLS1 PRF but only with newer hashes like used in TLS 1.2 e.g. SHA2 based ones but not with SHA1+MD5.

@cliffede here is a patch that should do what you want: https://gerrit.openvpn.net/c/openvpn/+/460

and for the client side improving the error message: https://gerrit.openvpn.net/c/openvpn/+/456/4

flichtenheld commented 4 months ago

This has been released in 2.6.9