Folks, The way we configure OpenSSL and the amount of special stuff we have to do is a bit of a mess. GnuTLS is a bit better, because you can put TLS protocol versions into the Priority String, but with OpenSSL, we're stuck trying to support every last thing and caught when some folks stuck supporting bad clients hold us back from letting everyone else move forward.
Several years ago, I added the openssl_options config knob to Exim, which at least made things a bit better, but we're creaking now. This is a rough proposal, with not a single line of code written to support it, but I'm looking for considered informed feedback as to whether it makes sense to postmasters out there. We've said "we only support versions of OpenSSL supported by the upstream project", so now it's time to take advantage of that. I'm proposing a new configuration section, when built against OpenSSL, which uses an API introduced with OpenSSL 1.0.2, the minimum version still supported upstream. We would use SSL_CONF_cmd(3) and pass settings through from Exim's configure file, straight to OpenSSL. How it would look: ~~~~~~~~~~~~~~~~~~~~~~~~8< hooking: variant 1 >8~~~~~~~~~~~~~~~~~~~~~~~~ # Variant 1: main section config, handled like tls_require_ciphers now: openssl = ${if eq{$received_port}{25}{server_mx}{server_submission}} ~~~~~~~~~~~~~~~~~~~~~~~~8< hooking: variant 1 >8~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~8< hooking: variant 2 >8~~~~~~~~~~~~~~~~~~~~~~~~ # main section: acl_smtp_connect = acl_connect begin acl acl_connect: warn condition = ${if eq{$received_port}{25}} control = openssl/server_mx warn condition = ${if !eq{$received_port}{25}} control = openssl/server_submission ~~~~~~~~~~~~~~~~~~~~~~~~8< hooking: variant 2 >8~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~8< hooking: smtp transport >8~~~~~~~~~~~~~~~~~~~~~~ begin transports: remote_smtp: driver = smtp openssl = ${if dane{client_dane}{client_insecure}} ~~~~~~~~~~~~~~~~~~~~~8< hooking: smtp transport >8~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~8< new config section >8~~~~~~~~~~~~~~~~~~~~~~~~ # This section is ignored if built against GnuTLS # # Warning: no string expansion is performed here (but may be in future). # Macros are allowed. begin openssl server_mx: CipherString DEFAULT:!SSLv2:!LOW:aNULL:!eNULL MinProtocol TLSv1 # requires OpenSSL 1.1.0. Certificate /etc/exim/tls/mx.crt PrivateKey /etc/exim/tlx/mx.key server_submission: Ciphersuites TLS13-CHACHA20-POLY1305-SHA256:... # used for TLS1.3 CipherString ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:HIGH:!MD5:!RC4:!aNULL:!ADH:!DES:!EXP:!NULL MinProtocol TLSv1.2 Groups X25519 Options -SessionTicket Certificate /etc/exim/tls/submission.crt # private CA, perhaps PrivateKey /etc/exim/tls/submission.key client_dane: MinProtocol TLSv1.2 CipherString something modern-ish here # VerifyCAPath irrelevant here, DANE only supports usages 2/3 which # ignores this ... although if the remote server doesn't send a full # chain and uses fingerprint-based pinning, this might unbreak things # enough? client_insecure: MinProtocol TLSv1 VerifyCAPath /etc/ssl/certs # Exim's require/try options still affect this CipherString something broad here # This isn't referenced above, but fancier config options could make it # required for domains in a whitelist, eg to say "use better security # for gmail.com": client_secure: MinProtocol TLSv1.2 CipherString something modern-ish here VerifyCAPath /etc/ssl/certs ~~~~~~~~~~~~~~~~~~~~~~~~8< new config section >8~~~~~~~~~~~~~~~~~~~~~~~~ Some settings come in with newer versions of OpenSSL. We wouldn't have to do anything special to support them, that's _why_ we'd just pass things through. If someone shouts and wants MinProtocol with older OpenSSL, we'd shrug and say "upgrade OpenSSL, we use what they export and are not getting sucked into replicating their work." We simply split on whitespace to a "key" and a "value", where the value can have internal whitespace we don't touch, but we strip off leading and trailing whitespace. Then we pass each key/value down. The openssl main setting, or ACL control, and openssl SMTP transport would all only be valid when built with OpenSSL and be parse errors with GnuTLS. The "begin openssl" could be allowed and ignored with GnuTLS. At daemon startup, before backgrounding, where we do validation right now, we'd go through every defined config block in the openssl section, and for each one we're create an OpenSSL context, call SSL_CONF_cmd() to set each line, and make sure there's no error. If there's an error, that's a fatal configuration error and is passed back. These contexts are all discarded. This would then automatically be visible as an error when running "exim -bV"/"exim --version". Then at runtime, these values are just passed in when configuring the context. For sanity, at first we'd skip string expansion, but would allow macros. If there's an argument to be made for allowing string expansion, we could switch to allowing it but would need to figure out what startup validation looks like in that case. I've introduced a hypothetical expansion condition "dane" for dispatch. Exim settings which would become obsolete for OpenSSL: * tls_require_ciphers * tls_certificate * tls_privatekey * tls_dhparam, tls_dh_max_bits, tls_dh_min_bits * tls_verify_certificates * tls_ocsp_file * openssl_options * smtp transport: tls_require_ciphers * smtp transport: dane_require_tls_ciphers To not break backwards compatibility, we'd allow all of those options to exist and work as long as the "openssl" option is not set. Whether and when to break them is a larger issue. Regards, -Phil
signature.asc
Description: Digital signature
-- ## List details at https://lists.exim.org/mailman/listinfo/exim-users ## Exim details at http://www.exim.org/ ## Please use the Wiki with this list - http://wiki.exim.org/