aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2020-12-10 19:39:10 +0100
committerGuilhem Moulin <guilhem@fripost.org>2020-12-11 11:20:41 +0100
commit265f133600e9812726a52ea3067409ed3578e882 (patch)
treea4612e7207515bf090444bb0db78ebf989842283 /tests
parent84d1829fd0f955cf9fb7add54f60fc314b0d42b1 (diff)
libinterimap: make SSL_verify check the hostname as well.
More precisely, ensure that the certificate Subject Alternative Name (SAN) or Subject CommonName (CN) matches the hostname or IP literal specified by the 'host' option. Previously it was only verifying the chain of trust. This bumps the minimum Net::SSLeay version to 1.83 and OpenSSL version 1.0.2.
Diffstat (limited to 'tests')
-rwxr-xr-xtests/certs/generate7
-rwxr-xr-xtests/run2
-rw-r--r--tests/tls-verify-peer/interimap.remote1
-rw-r--r--tests/tls-verify-peer/t61
4 files changed, 60 insertions, 11 deletions
diff --git a/tests/certs/generate b/tests/certs/generate
index 19463d5..6457765 100755
--- a/tests/certs/generate
+++ b/tests/certs/generate
@@ -20,19 +20,22 @@ SERIAL=1
new() {
local key="$1" cn="$2"
openssl req -new -rand /dev/urandom -key "$key" \
- -subj "/OU=$OU/CN=$cn" \
+ -subj "/OU=$OU/CN=$cn" ${3+-addext subjectAltName="$3"} \
-out "$cadir/new.csr"
cat >"$cadir/new-ext.cnf" <<-EOF
basicConstraints = critical, CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = critical, serverAuth
EOF
+ if [ -n "${3+x}" ]; then
+ printf "subjectAltName = %s\\n" "$3" >>"$cadir/new-ext.cnf"
+ fi
openssl x509 -req -in "$cadir/new.csr" -CA ./ca.crt -CAkey "$cadir/ca.key" \
-CAserial "$cadir/ca.srl" -CAcreateserial -extfile "$cadir/new-ext.cnf"
}
openssl genpkey -algorithm RSA -out ./dovecot.rsa.key
-new ./dovecot.rsa.key "localhost" >./dovecot.rsa.crt
+new ./dovecot.rsa.key "localhost" "DNS:localhost,DNS:ip6-localhost,IP:127.0.0.1,IP:::1" >./dovecot.rsa.crt
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out ./dovecot.ecdsa.key
new ./dovecot.ecdsa.key "localhost" >./dovecot.ecdsa.crt
diff --git a/tests/run b/tests/run
index 0305812..d216591 100755
--- a/tests/run
+++ b/tests/run
@@ -93,7 +93,7 @@ prepare() {
mail_location = dbox:~/inbox:LAYOUT=index
mailbox_list_index = yes
ssl = no
- listen = 127.0.0.1, ::1
+ listen = 127.0.0.1, 127.0.1.1, ::1
namespace inbox {
inbox = yes
}
diff --git a/tests/tls-verify-peer/interimap.remote b/tests/tls-verify-peer/interimap.remote
index b02fcd0..263655f 100644
--- a/tests/tls-verify-peer/interimap.remote
+++ b/tests/tls-verify-peer/interimap.remote
@@ -1,2 +1 @@
-host = ::1
port = 10993
diff --git a/tests/tls-verify-peer/t b/tests/tls-verify-peer/t
index 9b676a6..2461a1f 100644
--- a/tests/tls-verify-peer/t
+++ b/tests/tls-verify-peer/t
@@ -1,6 +1,15 @@
+X509_SHA256="$(doveconf -c "$HOME_remote/.dovecot/config" -hx ssl_cert \
+ | openssl x509 -noout -fingerprint -sha256 \
+ | sed -rn "/^.*=\\s*/ {s///p;q}" | tr -d : | tr "[A-Z]" "[a-z]")"
+PKEY_SHA256="$(doveconf -c "$HOME_remote/.dovecot/config" -hx ssl_cert \
+ | openssl x509 -pubkey | openssl pkey -pubin -outform DER \
+ | openssl dgst -sha256 | sed -rn "/^.*=\\s*/ {s///p;q}")"
+
unverified_peer() {
! interimap --debug || error
+ # make sure we aborted the handshake immediately after connecting
+ grep -Fx "remote: Peer certificate fingerprint: sha256\$$X509_SHA256" <"$STDERR" || error
grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error
sed -nr "s/remote: \[[0-9]+\] (preverify=[0-9]+)$/\1/p" <"$STDERR" >"$TMPDIR/preverify"
[ -s "$TMPDIR/preverify" ] || error
@@ -11,12 +20,13 @@ unverified_peer() {
}
verified_peer() {
local i u
- for ((i = 0; i < 32; i++)); do
+ for ((i = 0; i < 4; i++)); do
u="$(shuf -n1 -e "local" "remote")"
sample_message | deliver -u "$u"
done
interimap --debug || error
+ grep -Fx "remote: Peer certificate fingerprint: sha256\$$X509_SHA256" <"$STDERR" || error
sed -nr "s/remote: \[[0-9]+\] (preverify=[0-9]+)$/\1/p" <"$STDERR" >"$TMPDIR/preverify"
[ -s "$TMPDIR/preverify" ] || error
! grep -Fvx "preverify=1" <"$TMPDIR/preverify" || error
@@ -39,9 +49,6 @@ unverified_peer
step_done
step_start "peer verification result honored when pinned pubkey matches"
-PKEY_SHA256="$(doveconf -c "$HOME_remote/.dovecot/config" -hx ssl_cert \
- | openssl x509 -pubkey | openssl pkey -pubin -outform DER \
- | openssl dgst -sha256 | sed -rn "/^.*=\\s*/ {s///p;q}")"
with_remote_config <<-EOF
SSL_fingerprint = sha256\$$PKEY_SHA256
EOF
@@ -50,31 +57,71 @@ grep -Fx "remote: Peer certificate matches pinned SPKI digest sha256\$$PKEY_SHA2
step_done
capath=$(mktemp --tmpdir="$TMPDIR" --directory capath.XXXXXX)
+cp -T -- ~/.dovecot/conf.d/ca.crt "$capath/ca-certificates.crt"
step_start "SSL_CAfile"
if [ -f "/etc/ssl/certs/ca-certificates.crt" ]; then
- # our fake root CA should not be in there
+ # assume our fake root CA is not there
with_remote_config <<<"SSL_CAfile = /etc/ssl/certs/ca-certificates.crt"
unverified_peer
fi
-cp -T -- ~/.dovecot/conf.d/ca.crt "$capath/ca-certificates.crt"
+# default host (localhost) is the CN (and also subjectAltName)
with_remote_config <<<"SSL_CAfile = $capath/ca-certificates.crt"
verified_peer
+
+# 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
+ host = $host
+ SSL_CAfile = $capath/ca-certificates.crt
+ EOF
+ verified_peer
+done
+
+# but not for other IPs or hostnames
+for host in "ip6-loopback" "127.0.1.1"; do
+ with_remote_config <<-EOF
+ host = $host
+ SSL_CAfile = $capath/ca-certificates.crt
+ EOF
+ unverified_peer
+done
+
step_done
step_start "SSL_CApath"
if [ -d "/etc/ssl/certs" ]; then
- # our fake root CA should not be in there
+ # assume our fake root CA is not there
with_remote_config <<<"SSL_CApath = /etc/ssl/certs"
unverified_peer
fi
c_rehash "$capath"
+# default host (localhost) is the CN (and also subjectAltName)
with_remote_config <<<"SSL_CApath = $capath"
verified_peer
+
+# 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
+ host = $host
+ SSL_CApath = $capath
+ EOF
+ verified_peer
+done
+
+# but not for other IPs or hostnames
+for host in "ip6-loopback" "127.0.1.1"; do
+ with_remote_config <<-EOF
+ host = $host
+ SSL_CApath = $capath
+ EOF
+ unverified_peer
+done
+
step_done
# vim: set filetype=sh :