From ed263d4a380036b654525ee268db615c17d0d216 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Fri, 11 Dec 2020 18:28:32 +0100 Subject: test suite: supply our own OpenSSL configuration file with MinProtocol=None. So we can test TLSv1 as well, not just TLSv1.2 and later. Also, explicitly set ssl_min_protocol=TLSv1 in the Dovecot configuration file (the default as of 2.3.11.3), hence running TLS tests now require Dovecot 2.3 or later. --- tests/tls-verify-peer/t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/tls-verify-peer/t') diff --git a/tests/tls-verify-peer/t b/tests/tls-verify-peer/t index 2461a1f..17018a6 100644 --- a/tests/tls-verify-peer/t +++ b/tests/tls-verify-peer/t @@ -31,7 +31,7 @@ verified_peer() { [ -s "$TMPDIR/preverify" ] || error ! grep -Fvx "preverify=1" <"$TMPDIR/preverify" || error - grep "^remote: SSL protocol: TLSv1\.[23] " <"$STDERR" || error + grep "^remote: SSL protocol: TLSv" <"$STDERR" || error grep "^remote: SSL cipher: " <"$STDERR" || error check_mailbox_status "INBOX" -- cgit v1.2.3 From ba9d8af01141a6d5d5b98a0e249c311814b844a6 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 13 Dec 2020 17:37:32 +0100 Subject: test suite: ensure we haven't started speaking IMAP when the SSL/TLS handshake is aborted. (Unless STARTTLS is used to upgrade the connection.) --- Changelog | 3 +++ tests/tls-pin-fingerprint/t | 6 ++++-- tests/tls-protocols/t | 6 ++++-- tests/tls-verify-peer/t | 3 ++- 4 files changed, 13 insertions(+), 5 deletions(-) (limited to 'tests/tls-verify-peer/t') diff --git a/Changelog b/Changelog index 931e526..9a36e8a 100644 --- a/Changelog +++ b/Changelog @@ -29,6 +29,9 @@ interimap (0.5.5) upstream; - README: suggest ControlPath=$XDG_RUNTIME_DIR/ssh-imap-%C for the SSH transport (note that variable expansion is only available in OpenSSH 8.4 and later). + - test suite: ensure we haven't started speaking IMAP when the SSL/TLS + handshake is aborted (unless STARTTLS is used to upgrade to + connection). -- Guilhem Moulin Fri, 11 Dec 2020 14:55:53 +0100 diff --git a/tests/tls-pin-fingerprint/t b/tests/tls-pin-fingerprint/t index 6716833..883a887 100644 --- a/tests/tls-pin-fingerprint/t +++ b/tests/tls-pin-fingerprint/t @@ -41,8 +41,9 @@ EOF grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error grep -Fx "remote: WARNING: Fingerprint doesn't match! MiTM in action?" <"$STDERR" || error grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error -# make sure we didn't send any credentials +# make sure we didn't send any credentials or started speaking IMAP ! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error +grep -Fx "remote: IMAP traffic (bytes): recv 0 sent 0" <"$STDERR" || error # two invalid ones with_remote_config <<-EOF @@ -53,8 +54,9 @@ EOF grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error grep -Fx "remote: WARNING: Fingerprint doesn't match! MiTM in action?" <"$STDERR" || error grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error -# make sure we didn't send any credentials +# make sure we didn't send any credentials or started speaking IMAP ! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error +grep -Fx "remote: IMAP traffic (bytes): recv 0 sent 0" <"$STDERR" || error # valid + invalid diff --git a/tests/tls-protocols/t b/tests/tls-protocols/t index b65d93c..ecf7e49 100644 --- a/tests/tls-protocols/t +++ b/tests/tls-protocols/t @@ -38,8 +38,9 @@ with_remote_tls_protocols "SSLv2" "SSLv3" ! interimap --debug || error grep -Fx "remote: Disabling SSL protocols: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3" <"$STDERR" || error grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error -# make sure we didn't send any credentials +# make sure we didn't send any credentials or started speaking IMAP ! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error +grep -Fx "remote: IMAP traffic (bytes): recv 0 sent 0" <"$STDERR" || error # new interface: SSL_protocol_{min,max} @@ -88,7 +89,8 @@ with_remote_tls_protocol_min_max "SSLv3" "SSLv3" grep -Fx "remote: Minimum SSL/TLS protocol version: SSLv3" <"$STDERR" || error grep -Fx "remote: Maximum SSL/TLS protocol version: SSLv3" <"$STDERR" || error grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error -# make sure we didn't send any credentials +# make sure we didn't send any credentials or started speaking IMAP ! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error +grep -Fx "remote: IMAP traffic (bytes): recv 0 sent 0" <"$STDERR" || error # vim: set filetype=sh : diff --git a/tests/tls-verify-peer/t b/tests/tls-verify-peer/t index 17018a6..8cc098a 100644 --- a/tests/tls-verify-peer/t +++ b/tests/tls-verify-peer/t @@ -15,8 +15,9 @@ unverified_peer() { [ -s "$TMPDIR/preverify" ] || error ! grep -Fvx "preverify=0" <"$TMPDIR/preverify" || error - # make sure we didn't send any credentials + # make sure we didn't send any credentials or started speaking IMAP ! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error + grep -Fx "remote: IMAP traffic (bytes): recv 0 sent 0" <"$STDERR" || error } verified_peer() { local i u -- cgit v1.2.3 From 8c43ed9baa905d907a6aad77de2282a852ba69a9 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 13 Dec 2020 17:43:52 +0100 Subject: libinterimap: use default locations for trusted CA certificates when neither CAfile nor CApath are set. In particular, OpenSSL's default locations can be overridden by the SSL_CERT_FILE resp. SSL_CERT_DIR environment variables, see SSL_CTX_load_verify_locations(3ssl). This bumps the minimum OpenSSL version to 1.1.0 (when SSL_verify is used). --- Changelog | 6 ++++++ doc/interimap.1.md | 14 ++++++++++---- doc/pullimap.1.md | 14 ++++++++++---- interimap.sample | 1 - lib/Net/IMAP/InterIMAP.pm | 10 +++++++--- pullimap.sample | 1 - tests/run | 3 +++ tests/tls-verify-peer/t | 27 ++++++++++++++++++++++++--- 8 files changed, 60 insertions(+), 16 deletions(-) (limited to 'tests/tls-verify-peer/t') diff --git a/Changelog b/Changelog index 9a36e8a..2fbdf36 100644 --- a/Changelog +++ b/Changelog @@ -10,6 +10,12 @@ interimap (0.5.5) upstream; protocol black/whitelist greatly; this only allows simple min/max bounds, but holes are arguably not very useful here. Using the new settings bumps the required libssl version to 1.1.0. + * libinterimap: use default locations for trusted CA certificates when + neither CAfile nor CApath are set. In particular, OpenSSL's default + locations can be overridden by the SSL_CERT_FILE resp. SSL_CERT_DIR + environment variables, see SSL_CTX_load_verify_locations(3ssl). + This bumps the minimum OpenSSL version to 1.1.0 (when SSL_verify is + used). + `make release`: also bump libinterimap version and pin it in 'use' declarations. + Make error messages more uniform and consistent. diff --git a/doc/interimap.1.md b/doc/interimap.1.md index 2310cb3..63d5ab0 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -439,6 +439,14 @@ Valid options are: measure as it pins directly its key material and ignore its chain of trust. +*SSL_CAfile* + +: File containing trusted certificates to use during server + certificate verification when `SSL_verify=YES`. + + Trusted CA certificates are loaded from the default system locations + unless one (or both) of *SSL_CAfile* or *SSL_CApath* is set. + *SSL_CApath* : Directory to use for server certificate verification when @@ -446,10 +454,8 @@ Valid options are: This directory must be in “hash format”, see [`verify`(1ssl)] for more information. -*SSL_CAfile* - -: File containing trusted certificates to use during server - certificate verification when `SSL_verify=YES`. + Trusted CA certificates are loaded from the default system locations + unless one (or both) of *SSL_CAfile* or *SSL_CApath* is set. *SSL_hostname* diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index cf6ec52..05cbcaf 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -258,6 +258,14 @@ Valid options are: measure as it pins directly its key material and ignore its chain of trust. +*SSL_CAfile* + +: File containing trusted certificates to use during server + certificate verification when `SSL_verify=YES`. + + Trusted CA certificates are loaded from the default system locations + unless one (or both) of *SSL_CAfile* or *SSL_CApath* is set. + *SSL_CApath* : Directory to use for server certificate verification when @@ -265,10 +273,8 @@ Valid options are: This directory must be in “hash format”, see [`verify`(1ssl)] for more information. -*SSL_CAfile* - -: File containing trusted certificates to use during server - certificate verification when `SSL_verify=YES`. + Trusted CA certificates are loaded from the default system locations + unless one (or both) of *SSL_CAfile* or *SSL_CApath* is set. *SSL_hostname* diff --git a/interimap.sample b/interimap.sample index e54c8a0..36eeb2a 100644 --- a/interimap.sample +++ b/interimap.sample @@ -23,7 +23,6 @@ password = xxxxxxxxxxxxxxxx #compress = YES # SSL options -#SSL_CApath = /etc/ssl/certs #SSL_verify = YES #SSL_protocol_min = TLSv1.2 #SSL_fingerprint = sha256$29111aea5d5be7e448bdc5c6e8a9d03bc9221c53c09b1cfbe6f953221e24dda0 diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 5bdd954..89e5cba 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -1776,10 +1776,14 @@ sub _start_ssl($$) { $self->panic("Failed requirement libssl >=1.0.2") if $OPENSSL_VERSION < 0x1000200f; # verify certificate chain - my ($file, $path) = ($self->{SSL_CAfile} // '', $self->{SSL_CApath} // ''); - if ($file ne '' or $path ne '') { + if (defined $self->{SSL_CAfile} or defined $self->{SSL_CApath}) { $self->_ssl_error("SSL_CTX_load_verify_locations()") - unless Net::SSLeay::CTX_load_verify_locations($ctx, $file, $path) == 1; + unless Net::SSLeay::CTX_load_verify_locations($ctx, + $self->{SSL_CAfile} // '', $self->{SSL_CApath} // '') == 1; + } else { + $self->log("Using default locations for trusted CA certificates") if $self->{debug}; + $self->_ssl_error("SSL_CTX_set_default_verify_paths()") + unless Net::SSLeay::CTX_set_default_verify_paths($ctx) == 1; } # verify DNS hostname or IP literal diff --git a/pullimap.sample b/pullimap.sample index d911851..f1a66f9 100644 --- a/pullimap.sample +++ b/pullimap.sample @@ -4,7 +4,6 @@ deliver-method = smtp:[127.0.0.1]:25 purge-after = 90 # SSL options -#SSL_CApath = /etc/ssl/certs #SSL_verify = YES #SSL_protocol_min = TLSv1.2 diff --git a/tests/run b/tests/run index 29384ec..329f3e3 100755 --- a/tests/run +++ b/tests/run @@ -209,6 +209,8 @@ _interimap_cmd() { local script="$1" rv=0 shift environ_set "local" + [ -z "${SSL_CERT_FILE+x}" ] || ENVIRON+=( SSL_CERT_FILE="$SSL_CERT_FILE" ) + [ -z "${SSL_CERT_DIR+x}" ] || ENVIRON+=( SSL_CERT_DIR="$SSL_CERT_DIR" ) env -i "${ENVIRON[@]}" perl -I./lib -T "./$script" "$@" 2>"$STDERR" || rv=$? cat <"$STDERR" >&2 return $rv @@ -445,6 +447,7 @@ passed() { # Run test in a sub-shell declare -a ENVIRON=() environ_set "local" +unset SSL_CERT_FILE SSL_CERT_DIR export TMPDIR TESTDIR STDERR "${ENVIRON[@]}" OPENSSL_CONF export -f environ_set doveadm interimap interimap_init pullimap _interimap_cmd export -f sqlite3 sample_message deliver ptree_abort step_start step_done passed diff --git a/tests/tls-verify-peer/t b/tests/tls-verify-peer/t index 8cc098a..8326521 100644 --- a/tests/tls-verify-peer/t +++ b/tests/tls-verify-peer/t @@ -46,7 +46,9 @@ with_remote_config() { } step_start "peer verification enabled by default" +# assume our fake root CA is not among OpenSSL's default trusted CAs unverified_peer +grep -Fx "remote: Using default locations for trusted CA certificates" <"$STDERR" || error step_done step_start "peer verification result honored when pinned pubkey matches" @@ -54,13 +56,23 @@ with_remote_config <<-EOF SSL_fingerprint = sha256\$$PKEY_SHA256 EOF unverified_peer +grep -Fx "remote: Using default locations for trusted CA certificates" <"$STDERR" || error grep -Fx "remote: Peer certificate matches pinned SPKI digest sha256\$$PKEY_SHA256" <"$STDERR" || error step_done + capath=$(mktemp --tmpdir="$TMPDIR" --directory capath.XXXXXX) cp -T -- ~/.dovecot/conf.d/ca.crt "$capath/ca-certificates.crt" -step_start "SSL_CAfile" +step_start "SSL_CAfile/\$SSL_CERT_FILE" + +# verify that an error is raised when CAfile can't be loaded +# (it's not the case for $SSL_CERT_FILE, cf. SSL_CTX_load_verify_locations(3ssl)) +with_remote_config <<<"SSL_CAfile = /nonexistent" +! interimap --debug || error +grep -Fx "remote: ERROR: SSL_CTX_load_verify_locations()" <"$STDERR" || error +grep -Fx "remote: IMAP traffic (bytes): recv 0 sent 0" <"$STDERR" || error + if [ -f "/etc/ssl/certs/ca-certificates.crt" ]; then # assume our fake root CA is not there with_remote_config <<<"SSL_CAfile = /etc/ssl/certs/ca-certificates.crt" @@ -71,6 +83,10 @@ fi with_remote_config <<<"SSL_CAfile = $capath/ca-certificates.crt" verified_peer +with_remote_config