diff options
| -rw-r--r-- | Changelog | 6 | ||||
| -rw-r--r-- | doc/interimap.1.md | 14 | ||||
| -rw-r--r-- | doc/pullimap.1.md | 14 | ||||
| -rw-r--r-- | interimap.sample | 1 | ||||
| -rw-r--r-- | lib/Net/IMAP/InterIMAP.pm | 10 | ||||
| -rw-r--r-- | pullimap.sample | 1 | ||||
| -rwxr-xr-x | tests/run | 3 | ||||
| -rw-r--r-- | tests/tls-verify-peer/t | 27 | 
8 files changed, 60 insertions, 16 deletions
@@ -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 @@ -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 </dev/null +SSL_CERT_FILE=~/.dovecot/conf.d/ca.crt verified_peer +grep -Fx "remote: Using default locations for trusted CA certificates" <"$STDERR" || error +  # hostnames and IPs included in the subjectAltName should work as well  for host in "ip6-localhost" "127.0.0.1" "::1"; do      with_remote_config <<-EOF @@ -80,7 +96,7 @@ for host in "ip6-localhost" "127.0.0.1" "::1"; do      verified_peer  done -# but not for other IPs or hostnames +# but not for other hostnames or IPs  for host in "ip6-loopback" "127.0.1.1"; do      with_remote_config <<-EOF  		host = $host @@ -92,7 +108,8 @@ done  step_done -step_start "SSL_CApath" +step_start "SSL_CApath/\$SSL_CERT_DIR" +  if [ -d "/etc/ssl/certs" ]; then      # assume our fake root CA is not there      with_remote_config <<<"SSL_CApath = /etc/ssl/certs" @@ -105,6 +122,10 @@ c_rehash "$capath"  with_remote_config <<<"SSL_CApath = $capath"  verified_peer +with_remote_config </dev/null +SSL_CERT_DIR="$capath" verified_peer +grep -Fx "remote: Using default locations for trusted CA certificates" <"$STDERR" || error +  # hostnames and IPs included in the subjectAltName should work as well  for host in "ip6-localhost" "127.0.0.1" "::1"; do      with_remote_config <<-EOF  | 
