Todo #14677
closedPrevent weak SHA1 certificates from being used with OpenVPN clients and servers
100%
Description
OpenVPN built against OpenSSL 3.0 rejects any certificate (client or server) using SHA1 hash. Surprisingly, a SHA1 CA is OK -- just not a server or client certificate.
We should prevent users from choosing SHA1 certificates, either by removing them from the list or by producing an input validation error on save. Certificate selection options should contain a warning about them as well.
On upgrade, if a server or client is using a SHA1 certificate, it must be disabled and a notice filed informing the user of the change. Otherwise the daemon will start and the user will be left searching the logs for clues.
Errors in the log are similar to the following with some slight variations depending on if it's a client or server role:
Aug 10 15:37:29 openvpn 32827 OpenSSL: error:0A00018E:SSL routines::ca md too weak Aug 10 15:37:29 openvpn 32827 Cannot load certificate file /var/etc/openvpn/server1/cert
Aug 10 16:02:16 openvpn 77691 VERIFY ERROR: depth=0, error=CA signature digest algorithm too weak: CN=test-new-serverold, serial=4060058663703718122 Aug 10 16:02:16 openvpn 77691 OpenSSL: error:0A000086:SSL routines::certificate verify failed Aug 10 16:02:16 openvpn 77691 TLS_ERROR: BIO read tls_read_plaintext error Aug 10 16:02:16 openvpn 77691 TLS Error: TLS object -> incoming plaintext read error Aug 10 16:02:16 openvpn 77691 TLS Error: TLS handshake failed
Note that peers using a SHA1 certificate will also fail but we have no way to know what a peer is using so nothing can be done there. For example if the server is using a proper cert but some remote client has an older SHA1 cert, they will no longer be able to connect. Likewise, even if a client instance has a proper cert, if a remote server has a SHA1 server certificate, the client will fail to connect.
Note that attempting to work around this by loading the OpenSSL legacy provider does not make any difference (e.g. openvpn --providers legacy default [...]
or inline in the config), it fails no matter what.
Similar to #14672 for the GUI but with important differences in behavior, so treat it separately (e.g. do not lump the upgrade code together in a single function)