aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--COPYING8
-rw-r--r--Changelog16
-rw-r--r--Makefile2
-rwxr-xr-xbenchmark/random_maildir.pl2
-rw-r--r--doc/build.md6
-rw-r--r--doc/development.md14
-rw-r--r--doc/interimap.1.md29
-rw-r--r--doc/pullimap.1.md28
-rwxr-xr-xinterimap4
-rw-r--r--lib/Net/IMAP/InterIMAP.pm27
-rwxr-xr-xpullimap4
-rw-r--r--tests/list1
-rwxr-xr-xtests/run2
-rwxr-xr-xtests/run-all2
-rw-r--r--tests/snippets/dovecot/dovecot.ecdsa.crt11
-rw-r--r--tests/snippets/dovecot/dovecot.ecdsa.key5
-rw-r--r--tests/snippets/dovecot/dovecot.key5
-rw-r--r--tests/snippets/dovecot/dovecot.pem11
-rw-r--r--tests/snippets/dovecot/dovecot.rsa.crt19
-rw-r--r--tests/snippets/dovecot/dovecot.rsa.key28
-rw-r--r--tests/snippets/dovecot/ssl.conf4
-rwxr-xr-xtests/starttls-injection/imapd4
-rw-r--r--tests/starttls/t6
-rw-r--r--tests/tls-pin-fingerprint/t43
l---------tests/tls-rsa+ecdsa/interimap.remote1
-rw-r--r--tests/tls-rsa+ecdsa/remote.conf5
-rw-r--r--tests/tls-rsa+ecdsa/t49
-rw-r--r--tests/tls-verify-peer/t18
-rw-r--r--tests/tls/t6
29 files changed, 273 insertions, 87 deletions
diff --git a/COPYING b/COPYING
index 94a9ed0..e600086 100644
--- a/COPYING
+++ b/COPYING
@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+<https://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/Changelog b/Changelog
index 6ee44fc..4d9b9a4 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,19 @@
+interimap (0.5.3) upstream;
+
+ * libinterimap: SSL_fingerprint now supports a space-separate list of
+ digests to pin, and succeeds if, and only if, the peer certificate
+ SPKI matches one of the pinned digest values. Specifying multiple
+ digest values can key useful in key rollover scenarios and/or when
+ the server supports certificates of different types (for instance
+ RSA+ECDSA).
+ - libinterimap: 'null-stderr' is now ignored when the 'debug' flag is
+ set (the standard error is never sent to /dev/null).
+ - test suite: use a RSA certificate rather than ECDSA.
+ - test suite: new test with a server offering both RSA+ECDSA
+ certificates. This test requires dovecot-imapd 2.2.31 or later.
+
+ -- Guilhem Moulin <guilhem@fripost.org> Wed, 09 Dec 2020 15:32:01 +0100
+
interimap (0.5.2) upstream;
- Makefile: remove 'smart' extension from pandoc call to generate
diff --git a/Makefile b/Makefile
index 9e28dbc..3d60dfb 100644
--- a/Makefile
+++ b/Makefile
@@ -36,7 +36,7 @@ prefix ?= $(DESTDIR)
exec_prefix ?= $(prefix)
bindir ?= $(exec_prefix)/bin
libdir ?= $(exec_prefix)/lib
-datarootdir ?= $(DESTDIR)/share
+datarootdir ?= $(prefix)/share
mandir ?= $(datarootdir)/man
man1dir ?= $(mandir)/man1
diff --git a/benchmark/random_maildir.pl b/benchmark/random_maildir.pl
index 363eb41..d75fa4f 100755
--- a/benchmark/random_maildir.pl
+++ b/benchmark/random_maildir.pl
@@ -15,7 +15,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
use warnings;
diff --git a/doc/build.md b/doc/build.md
index d704f71..4a4f80d 100644
--- a/doc/build.md
+++ b/doc/build.md
@@ -66,9 +66,9 @@ the `CSS` environment variable (the value of which defaults to
For instance, use
- $ CSS="https://guilhem.org/static/css/bootstrap.min.css" \
- HTML_ROOTDIR="$XDG_RUNTIME_DIR/interimap" \
- make html
+ $ env CSS="https://guilhem.org/static/css/bootstrap.min.css" \
+ HTML_ROOTDIR="$XDG_RUNTIME_DIR/interimap" \
+ make html
to generate the HTML documentation under directory `$XDG_RUNTIME_DIR/interimap`
(which needs to exist) using a remote CSS file.
diff --git a/doc/development.md b/doc/development.md
index 708712f..f4578b9 100644
--- a/doc/development.md
+++ b/doc/development.md
@@ -72,7 +72,7 @@ pre-authenticated [IMAP4rev1] in the test environment for username
`testuser`, list mailboxes, and exit, run:
$ env -i PATH="/usr/bin:/bin" USER="testuser" \
- doveadm -c "$BASEDIR/dovecot.conf" exec imap
+ doveadm -c "$BASEDIR/dovecot.conf" exec imap
S: * PREAUTH [CAPABILITY IMAP4rev1 …] Logged in as testuser
C: a LIST "" "*"
S: * LIST (\HasNoChildren) "." INBOX
@@ -88,10 +88,10 @@ the latter to create a mailbox `foo`, add a sample message to it, and
finally mark it as `\Seen`.
$ env -i PATH="/usr/bin:/bin" USER="testuser" \
- doveadm -c "$BASEDIR/dovecot.conf" mailbox create "foo"
+ doveadm -c "$BASEDIR/dovecot.conf" mailbox create "foo"
<!-- -->
$ env -i PATH="/usr/bin:/bin" USER="testuser" HOME="$BASEDIR/testuser" \
- doveadm -c "$BASEDIR/dovecot.conf" exec dovecot-lda -e -m "foo" <<-EOF
+ doveadm -c "$BASEDIR/dovecot.conf" exec dovecot-lda -e -m "foo" <<-EOF
From: <sender@example.net>
To: <recipient@example.net>
Subject: Hello world!
@@ -102,7 +102,7 @@ finally mark it as `\Seen`.
EOF
<!-- -->
$ env -i PATH="/usr/bin:/bin" USER="testuser" \
- doveadm -c "$BASEDIR/dovecot.conf" flags add "\\Seen" mailbox "foo" "*"
+ doveadm -c "$BASEDIR/dovecot.conf" flags add "\\Seen" mailbox "foo" "*"
Normally [`dovecot-lda`(1)][Dovecot LDA] tries to do a userdb lookup in
order to determine the user's home directory. Since we didn't configure
@@ -145,7 +145,7 @@ You can now run [`interimap`(1)] with `--watch` set, here to one second
to observe synchronization steps early.
$ env -i PATH="$PATH" perl -I./lib -T ./interimap --config="$BASEDIR/interimap.conf" \
- --watch=1 --debug
+ --watch=1 --debug
Use instructions from the [previous section][Mail storage access]
(substituting `testuser` with `local` or `remote`) in order to simulate
@@ -169,12 +169,12 @@ Create a [`pullimap`(1)] configuration file with as section `[foo]`.
Run [`pullimap`(1)] without `--idle` in order to create the state file.
$ env -i PATH="$PATH" perl -I./lib -T ./pullimap --config="$BASEDIR/pullimap.conf" \
- --no-delivery foo
+ --no-delivery foo
You can now run [`pullimap`(1)] with `--idle` set.
$ env -i PATH="$PATH" perl -I./lib -T ./pullimap --config="$BASEDIR/pullimap.conf" \
- --no-delivery --idle --debug foo
+ --no-delivery --idle --debug foo
Use instructions from the [previous section][Mail storage access]
in order to simulate activity on the “remote” server (in the relevant
diff --git a/doc/interimap.1.md b/doc/interimap.1.md
index f10ced6..7df0100 100644
--- a/doc/interimap.1.md
+++ b/doc/interimap.1.md
@@ -376,7 +376,8 @@ Valid options are:
*null-stderr*
: Whether to redirect *command*'s standard error to `/dev/null` for
- `type=tunnel`. (Default: `NO`.)
+ `type=tunnel`. This option is ignored when the `--debug` flag is
+ set. (Default: `NO`.)
*SSL_protocols*
@@ -396,25 +397,31 @@ Valid options are:
*SSL_fingerprint*
-: Fingerprint of the server certificate's Subject Public Key Info, in
- the form `[ALGO$]DIGEST_HEX` where `ALGO` is the used algorithm (by
- default `sha256`).
+: Space-separated list of acceptable fingerprints for the server
+ certificate's Subject Public Key Info, in the form
+ `[ALGO$]DIGEST_HEX` where `ALGO` is the digest algorithm (by default
+ `sha256`).
Attempting to connect to a server with a non-matching certificate
SPKI fingerprint causes `interimap` to abort the connection during
the SSL/TLS handshake.
The following command can be used to compute the SHA-256 digest of a
certificate's Subject Public Key Info:
- openssl x509 -in /path/to/server/certificate.pem -pubkey \
- | openssl pkey -pubin -outform DER \
- | openssl dgst -sha256
+ $ openssl x509 -in /path/to/server/certificate.pem -pubkey \
+ | openssl pkey -pubin -outform DER \
+ | openssl dgst -sha256
+
+ Specifying multiple digest values can be useful in key rollover
+ scenarios and/or when the server supports certificates of different
+ types (for instance RSA+ECDSA). In that case the connection is
+ aborted when none of the specified digests matches.
*SSL_verify*
: Whether to verify the server certificate chain.
Note that using *SSL_fingerprint* to specify the fingerprint of the
- server certificate is an orthogonal authentication measure as it
- ignores the CA chain.
+ server certificate provides an independent server authentication
+ measure as it ignores the CA chain.
(Default: `YES`.)
*SSL_CApath*
@@ -427,7 +434,7 @@ Valid options are:
*SSL_CAfile*
: File containing trusted certificates to use during server
- certificate authentication if `SSL_verify=YES`.
+ certificate verification if `SSL_verify=YES`.
Supported extensions {#supported-extensions}
====================
@@ -469,7 +476,7 @@ Known bugs and limitations
* Because the [IMAP protocol][RFC 3501] doesn't provide a way for
clients to determine whether a disappeared mailbox was deleted or
renamed, `interimap` aborts when a known mailbox disappeared from one
- server but not the other. The `--delete` (resp. `rename`) command
+ server but not the other. The `--delete` (resp. `--rename`) command
should be used instead to delete (resp. rename) the mailbox on both
servers as well as within `interimap`'s internal database.
diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md
index 5028a14..98ec2ef 100644
--- a/doc/pullimap.1.md
+++ b/doc/pullimap.1.md
@@ -216,25 +216,31 @@ Valid options are:
*SSL_fingerprint*
-: Fingerprint of the server certificate's Subject Public Key Info, in
- the form `[ALGO$]DIGEST_HEX` where `ALGO` is the used algorithm (by
- default `sha256`).
+: Space-separated list of acceptable fingerprints for the server
+ certificate's Subject Public Key Info, in the form
+ `[ALGO$]DIGEST_HEX` where `ALGO` is the digest algorithm (by default
+ `sha256`).
Attempting to connect to a server with a non-matching certificate
SPKI fingerprint causes `pullimap` to abort the connection during
the SSL/TLS handshake.
The following command can be used to compute the SHA-256 digest of a
certificate's Subject Public Key Info:
- openssl x509 -in /path/to/server/certificate.pem -pubkey \
- | openssl pkey -pubin -outform DER \
- | openssl dgst -sha256
+ $ openssl x509 -in /path/to/server/certificate.pem -pubkey \
+ | openssl pkey -pubin -outform DER \
+ | openssl dgst -sha256
+
+ Specifying multiple digest values can be useful in key rollover
+ scenarios and/or when the server supports certificates of different
+ types (for instance RSA+ECDSA). In that case the connection is
+ aborted when none of the specified digests matches.
*SSL_verify*
: Whether to verify the server certificate chain.
Note that using *SSL_fingerprint* to specify the fingerprint of the
- server certificate is an orthogonal authentication measure as it
- ignores the CA chain.
+ server certificate provides an independent server authentication
+ measure as it ignores the CA chain.
(Default: `YES`.)
*SSL_CApath*
@@ -247,7 +253,7 @@ Valid options are:
*SSL_CAfile*
: File containing trusted certificates to use during server
- certificate authentication if `SSL_verify=YES`.
+ certificate verification if `SSL_verify=YES`.
Control flow {#control-flow}
============
@@ -369,8 +375,8 @@ Standards
[RFC 4731]: https://tools.ietf.org/html/rfc4731
[INI file]: https://en.wikipedia.org/wiki/INI_file
-[`fetchmail`(1)]: http://www.fetchmail.info/
+[`fetchmail`(1)]: https://www.fetchmail.info/
[`getmail`(1)]: http://pyropus.ca/software/getmail/
-[`write`(2)]: http://man7.org/linux/man-pages/man2/write.2.html
+[`write`(2)]: https://man7.org/linux/man-pages/man2/write.2.html
[`ciphers`(1ssl)]: https://www.openssl.org/docs/manmaster/apps/ciphers.html
[`verify`(1ssl)]: https://www.openssl.org/docs/manmaster/apps/verify.html
diff --git a/interimap b/interimap
index 670f746..9dd197b 100755
--- a/interimap
+++ b/interimap
@@ -15,14 +15,14 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
use v5.14.2;
use strict;
use warnings;
-our $VERSION = '0.5.2';
+our $VERSION = '0.5.3';
my $NAME = 'interimap';
my $DATABASE_VERSION = 1;
use Getopt::Long qw/:config posix_default no_ignore_case gnu_compat
diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm
index b01e1a9..1a71f59 100644
--- a/lib/Net/IMAP/InterIMAP.pm
+++ b/lib/Net/IMAP/InterIMAP.pm
@@ -13,7 +13,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
package Net::IMAP::InterIMAP v0.0.5;
@@ -63,7 +63,7 @@ my %OPTIONS = (
'null-stderr' => qr/\A(YES|NO)\z/i,
compress => qr/\A(YES|NO)\z/i,
SSL_protocols => qr/\A(!?$RE_SSL_PROTO(?: !?$RE_SSL_PROTO)*)\z/,
- SSL_fingerprint => qr/\A((?:[A-Za-z0-9]+\$)?\p{AHex}+)\z/,
+ SSL_fingerprint => qr/\A((?:[A-Za-z0-9]+\$)?\p{AHex}+(?: (?:[A-Za-z0-9]+\$)?\p{AHex}+)*)\z/,
SSL_cipherlist => qr/\A(\P{Control}+)\z/,
SSL_verify => qr/\A(YES|NO)\z/i,
SSL_CApath => qr/\A(\P{Control}+)\z/,
@@ -329,7 +329,7 @@ sub new($%) {
open STDOUT, '>&', $s or $self->panic("Can't dup: $!");
my $stderr2;
- if ($self->{'null-stderr'} // 0) {
+ if (($self->{'null-stderr'} // 0) and !($self->{debug} // 0)) {
open $stderr2, '>&', *STDERR;
open STDERR, '>', '/dev/null' or $self->panic("Can't open /dev/null: $!");
}
@@ -1624,15 +1624,22 @@ sub _ssl_verify($$$) {
.$algo.'$'.unpack('H*', Net::SSLeay::X509_digest($cert, $type)));
}
- if (defined (my $fpr = $self->{SSL_fingerprint})) {
- (my $algo, $fpr) = $fpr =~ /^([^\$]+)\$(.*)/ ? ($1, $2) : ('sha256', $fpr);
- my $digest = pack 'H*', ($fpr =~ tr/://rd);
+ if (defined (my $fprs = $self->{SSL_fingerprint})) {
+ my $rv = 0;
+ foreach my $fpr (split /\s+/, $fprs) {
+ (my $algo, $fpr) = $fpr =~ /^([^\$]+)\$(.*)/ ? ($1, $2) : ('sha256', $fpr);
+ my $digest = pack 'H*', ($fpr =~ tr/://rd);
- my $type = Net::SSLeay::EVP_get_digestbyname($algo)
- or $self->_ssl_error("Can't find MD value for name '$algo'");
+ my $type = Net::SSLeay::EVP_get_digestbyname($algo)
+ or $self->_ssl_error("Can't find MD value for name '$algo'");
- my $pkey = Net::SSLeay::X509_get_X509_PUBKEY($cert);
- unless (defined $pkey and Net::SSLeay::EVP_Digest($pkey, $type) eq $digest) {
+ my $pkey = Net::SSLeay::X509_get_X509_PUBKEY($cert);
+ if (defined $pkey and Net::SSLeay::EVP_Digest($pkey, $type) eq $digest) {
+ $rv = 1;
+ last;
+ }
+ }
+ unless ($rv) {
$self->warn("Fingerprint doesn't match! MiTM in action?");
$ok = 0;
}
diff --git a/pullimap b/pullimap
index e4747eb..baee352 100755
--- a/pullimap
+++ b/pullimap
@@ -15,14 +15,14 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
use v5.20.2;
use strict;
use warnings;
-our $VERSION = '0.5.2';
+our $VERSION = '0.5.3';
my $NAME = 'pullimap';
use Errno 'EINTR';
diff --git a/tests/list b/tests/list
index db77f50..0ad86e4 100644
--- a/tests/list
+++ b/tests/list
@@ -51,6 +51,7 @@ split-set Split large sets to avoid extra-long command lines
tls SSL/TLS handshake
... tls-verify-peer
tls-pin-fingerprint pubkey fingerprint pinning
+ tls-rsa+ecdsa pubkey fingerprint pinning for hybrid RSA+ECDSA
tls-protocols force TLS protocol versions
. Live synchronization (60s)
diff --git a/tests/run b/tests/run
index 4aa0685..8164524 100755
--- a/tests/run
+++ b/tests/run
@@ -15,7 +15,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
set -ue
diff --git a/tests/run-all b/tests/run-all
index 1eca50c..d13f689 100755
--- a/tests/run-all
+++ b/tests/run-all
@@ -15,7 +15,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
set -ue
diff --git a/tests/snippets/dovecot/dovecot.ecdsa.crt b/tests/snippets/dovecot/dovecot.ecdsa.crt
new file mode 100644
index 0000000..b928d4d
--- /dev/null
+++ b/tests/snippets/dovecot/dovecot.ecdsa.crt
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBkjCCATmgAwIBAgIUWyEAqMhQ0uRLtagXgm68bUypQa4wCgYIKoZIzj0EAwIw
+HzEdMBsGA1UEAwwUSW50ZXJJTUFQIHRlc3Qgc3VpdGUwHhcNMjAxMjA5MTQwOTUy
+WhcNMzAxMjA3MTQwOTUyWjAfMR0wGwYDVQQDDBRJbnRlcklNQVAgdGVzdCBzdWl0
+ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFP7A0ivFsHK/WuCQzz+WWh2jBLO
+7uqhWSMh+1cc//jmn2q910XNH3xVFNkIRo7ddg6X8twli3OvC66/YIbxiTyjUzBR
+MB0GA1UdDgQWBBS/p0mJpdBjKpNrQ/t+oJMrehS7wzAfBgNVHSMEGDAWgBS/p0mJ
+pdBjKpNrQ/t+oJMrehS7wzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0cA
+MEQCIFMlTb7E92tElIueK8TxbllJ3NOaMb1TMjSScM38N8oOAiAiNI4AkESnimPN
+IOsdnydFYjOkDEhzpXbrBEcP3EgJuQ==
+-----END CERTIFICATE-----
diff --git a/tests/snippets/dovecot/dovecot.ecdsa.key b/tests/snippets/dovecot/dovecot.ecdsa.key
new file mode 100644
index 0000000..dfbd4a7
--- /dev/null
+++ b/tests/snippets/dovecot/dovecot.ecdsa.key
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgleLchaikcJbUnkps
+4ITR6FGkW2S2+S+w2ISJSsvgt0ehRANCAART+wNIrxbByv1rgkM8/llodowSzu7q
+oVkjIftXHP/45p9qvddFzR98VRTZCEaO3XYOl/LcJYtzrwuuv2CG8Yk8
+-----END PRIVATE KEY-----
diff --git a/tests/snippets/dovecot/dovecot.key b/tests/snippets/dovecot/dovecot.key
deleted file mode 100644
index 95c9846..0000000
--- a/tests/snippets/dovecot/dovecot.key
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIGkqkKq69zVeF17S3y2U2HkQWh8z9M/xeblCztkKIfzJoAoGCCqGSM49
-AwEHoUQDQgAE1LLppulKw8KjINrDhOjEd0NTax5iDCds+vpA2PwsvvtGoprNAjQM
-zX+40u30N3CE0r591txqohSBQ/X+nvG2ug==
------END EC PRIVATE KEY-----
diff --git a/tests/snippets/dovecot/dovecot.pem b/tests/snippets/dovecot/dovecot.pem
deleted file mode 100644
index 7e53d90..0000000
--- a/tests/snippets/dovecot/dovecot.pem
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIBkzCCATmgAwIBAgIUQ+3hBMsPJcl59xDDujDDfexurOswCgYIKoZIzj0EAwIw
-HzEdMBsGA1UEAwwUSW50ZXJJTUFQIHRlc3Qgc3VpdGUwHhcNMTkxMTEwMTM1NDAw
-WhcNMjkxMTA3MTM1NDAwWjAfMR0wGwYDVQQDDBRJbnRlcklNQVAgdGVzdCBzdWl0
-ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNSy6abpSsPCoyDaw4ToxHdDU2se
-YgwnbPr6QNj8LL77RqKazQI0DM1/uNLt9DdwhNK+fdbcaqIUgUP1/p7xtrqjUzBR
-MB0GA1UdDgQWBBRlh8nSwyX+VlhwuhV7RKYwvKLyDzAfBgNVHSMEGDAWgBRlh8nS
-wyX+VlhwuhV7RKYwvKLyDzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gA
-MEUCIQDK8xPPHTbYW5JnZ1Siy8ChZ6GOu2sRwQu7OgtGYGZRSQIgFKn1oAhnq2Oi
-aIPqxjvBPMsK/sjrdI/rNsr2XgaulU4=
------END CERTIFICATE-----
diff --git a/tests/snippets/dovecot/dovecot.rsa.crt b/tests/snippets/dovecot/dovecot.rsa.crt
new file mode 100644
index 0000000..d10204b
--- /dev/null
+++ b/tests/snippets/dovecot/dovecot.rsa.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDHzCCAgegAwIBAgIUKSm5of13M/4NiGfhLMspFl/+YmYwDQYJKoZIhvcNAQEL
+BQAwHzEdMBsGA1UEAwwUSW50ZXJJTUFQIHRlc3Qgc3VpdGUwHhcNMjAxMjA5MTM1
+NjI1WhcNMzAxMjA3MTM1NjI1WjAfMR0wGwYDVQQDDBRJbnRlcklNQVAgdGVzdCBz
+dWl0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM1DTaSl/4UtngRG
+bAHmxHlNFZJxQVK9AM4tcYna1PGrY/JbmS5kKVFLSM6znHD5aBvTaOy0HLpF15wY
+Vj+zbaWmgqtlKGYGSGoXcTzNYFNJNB/WNhOv25q5VHNNFePTX/zOgQS8geza7qrK
+MZDiMlbuGKCQSKtZqKiEGiMWIyXtVi8BkkHXcTrvDggOTCQlk/0v8dWbGFZZA9ly
+f7PIdxtfm6tacw6Fxcz4ukWx2uoEjOIyOYhgd4WYdM7L9Jnabrh9OHYknuiGZv38
+b2GUZZ0h0RtkcdP1zOxaz4ZTaewo+gLm6yTFsL3mhnNsK/xxx00/QE6C9OyU0Nip
+gGmpT9ECAwEAAaNTMFEwHQYDVR0OBBYEFHlctzGj8GhUJ8GrlHb0mT7DR/mEMB8G
+A1UdIwQYMBaAFHlctzGj8GhUJ8GrlHb0mT7DR/mEMA8GA1UdEwEB/wQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBAJ/FGOVrBmYujPk2ZzJHJZE/+7+upZndrUA+27l7
+u/bHxhLnl94gfGmOaflU+Zyy/9eqLzllY40wkMT6d/SQmfv4C6d+fqk/dDPfdLdk
+N3ew/q/sPvLuEyoj1QoHamWqc3dfgV6p5j4ek6kjyWtjBPcQbVOZ02Xes1GSLzVJ
+Yo9kfbZxk4Y2mqiBDHCM+erNkG002D7cWErjj/fqhYlnjOxU+v9FEm0gLc3VqAkE
+BRuYZbmyMJUklH00R39G2Fey34kcpaB1VCMOLsymWLkZEhfgrl2qPRwGyh+Wc8N5
+gR/w97oHDOfJ2oZRzjRUB7MIhGoY0ED42Ma44Ub4al57XbY=
+-----END CERTIFICATE-----
diff --git a/tests/snippets/dovecot/dovecot.rsa.key b/tests/snippets/dovecot/dovecot.rsa.key
new file mode 100644
index 0000000..ed77230
--- /dev/null
+++ b/tests/snippets/dovecot/dovecot.rsa.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDNQ02kpf+FLZ4E
+RmwB5sR5TRWScUFSvQDOLXGJ2tTxq2PyW5kuZClRS0jOs5xw+Wgb02jstBy6Rdec
+GFY/s22lpoKrZShmBkhqF3E8zWBTSTQf1jYTr9uauVRzTRXj01/8zoEEvIHs2u6q
+yjGQ4jJW7higkEirWaiohBojFiMl7VYvAZJB13E67w4IDkwkJZP9L/HVmxhWWQPZ
+cn+zyHcbX5urWnMOhcXM+LpFsdrqBIziMjmIYHeFmHTOy/SZ2m64fTh2JJ7ohmb9
+/G9hlGWdIdEbZHHT9czsWs+GU2nsKPoC5uskxbC95oZzbCv8ccdNP0BOgvTslNDY
+qYBpqU/RAgMBAAECggEANzx5VGlnTYttDnF09z4GeS4JNBNOJNm/sbwA5bwBudcJ
+WlrT6ewCQmIkAZvL6Yr0PSiy/5+oa2gIEXVrIFFEnGMmnsDmEi52pjYQvu/1j/QP
+FtIqUznrusNMuopv7ZMgLYPUrFWeEQMJXuRyWi7EpSgFcI/jPlkuTcrezbpTUw0D
+bNAQjgXiDGNzyJDVmx496CWtTJHE94wwKo2QAiFU7zCZcqM7JlNCnRenws4KGqJ1
+qyFeCJJlgORQDMpiqaJLMreF41WPs++Xsu07RzQdmFKaS/sX4Um/5uyhlApmxepR
+cwx3RYvOtGArQKreNONn5j16O012DSbFXIyrUjJgAQKBgQD48iZmm2iiq4oC1u+/
+kYPXMHjUBHeMj8D3lA2mnCh4W/vcEj+ZBFgmR90KyYkK2eDuFslvfwzxZqU3sqJE
+au4OsITsSrxhJHAz4pVWPlJiWUCrz/7ektxY6Jw2+Jk8lR3UvLMgJbKpLWkd5Od+
+h5xKNU5Xzu198yX703k4+v5rgQKBgQDTFEcIJK9BffQ5hqMiM7NujdbMQ4ldxUy+
+ivyHk4MX4Z/kequE1rMJ1Ap8hypPJz10NhXM2naQWa8APnFYkNygwbtwTSZaiyMY
+Tav8rjYoA0CfEsPfIx2AFPtDtrhWGH5o9LZI9sjhH79ud412IDZxSGdZmAho8Xdj
+ky5sQr9MUQKBgByF+jplcg65Yt3CbMPhU17TkfSQ8nWrfuufDhVZ7RUlTO1BNgI9
+SjBQqZXz03zny+rbt4bL4trB7Qo9sHPwYIhUV1aPlZf3yddYDc5M47mbClrlQQmV
+gCO7uzJdN4mGeF2IpWl4iEj0CAhB0vhfZ1vlUa2j6vg0ZNS+vTP3JjGBAoGAQ+gW
+IgyLRWqcE5W5DdvMMhj3radcngpHclWMgKF4X0p7Aipk28umtda9uOpTNjvNjYGI
+6equkioIHu/3zyJrmFw7TRnE6QQyOjNizVvOmHjTZVnIIhVN/FLDszkpfKlMob94
+lWivn51zHLrhi8s5OKCufyhmLDzix+ol2TZwDMECgYEAwjhuZRXZeIgjKkvkG+FT
+8ThPNcxSplNca+YM9fQuWAuKkCbKCtvl8m5HDWYYIDx1jkKGHvDGtUl7vV4TtCgJ
+OeCQPjT5SLYs9ienMqitbzKfvCGRNsIG/1NsUrerD0Lau+V0YmbqYYk1Pptr3R8x
+bLzY7IMbPzdI+aPyhNF9KSg=
+-----END PRIVATE KEY-----
diff --git a/tests/snippets/dovecot/ssl.conf b/tests/snippets/dovecot/ssl.conf
index 240f24b..2d68c80 100644
--- a/tests/snippets/dovecot/ssl.conf
+++ b/tests/snippets/dovecot/ssl.conf
@@ -1,4 +1,4 @@
ssl = required
-ssl_cert = <dovecot.pem
-ssl_key = <dovecot.key
+ssl_cert = <dovecot.rsa.crt
+ssl_key = <dovecot.rsa.key
ssl_dh = <dhparams.pem
diff --git a/tests/starttls-injection/imapd b/tests/starttls-injection/imapd
index 9000c8d..15c53c7 100755
--- a/tests/starttls-injection/imapd
+++ b/tests/starttls-injection/imapd
@@ -26,9 +26,9 @@ Net::SSLeay::CTX_set_mode($CTX,
Net::SSLeay::MODE_ACCEPT_MOVING_WRITE_BUFFER() |
Net::SSLeay::MODE_AUTO_RETRY() | # don't fail SSL_read on renegotiation
Net::SSLeay::MODE_RELEASE_BUFFERS() );
-Net::SSLeay::CTX_use_PrivateKey_file($CTX, "$CONFDIR/dovecot.key", &Net::SSLeay::FILETYPE_PEM)
+Net::SSLeay::CTX_use_PrivateKey_file($CTX, "$CONFDIR/dovecot.rsa.key", &Net::SSLeay::FILETYPE_PEM)
or die_if_ssl_error("Can't load private key: $!");
-Net::SSLeay::CTX_use_certificate_file($CTX, "$CONFDIR/dovecot.pem", &Net::SSLeay::FILETYPE_PEM)
+Net::SSLeay::CTX_use_certificate_file($CTX, "$CONFDIR/dovecot.rsa.crt", &Net::SSLeay::FILETYPE_PEM)
or die_if_ssl_error("Can't load certificate: $!");
while (1) {
diff --git a/tests/starttls/t b/tests/starttls/t
index 99a39c2..5f9bd4f 100644
--- a/tests/starttls/t
+++ b/tests/starttls/t
@@ -1,3 +1,7 @@
+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]")"
+
for ((i = 0; i < 32; i++)); do
u="$(shuf -n1 -e "local" "remote")"
sample_message | deliver -u "$u"
@@ -18,7 +22,7 @@ grep -Fx "remote: C: 000000 STARTTLS" <"$STDERR" || error
grep -Fx "remote: C: 000001 CAPABILITY" <"$STDERR" || error
grep -Fx "remote: Disabling SSL protocols: SSLv3, TLSv1, TLSv1.1" <"$STDERR" || error
-grep -Fx "remote: Peer certificate fingerprint: sha256\$35944e3bd3300d3ac310bb497a32cc1eef6931482a587ddbc95343740cdf1323" <"$STDERR" || error
+grep -Fx "remote: Peer certificate fingerprint: sha256\$$X509_SHA256" <"$STDERR" || error
grep "^remote: SSL protocol: TLSv1\.[23] " <"$STDERR" || error
grep "^remote: SSL cipher: " <"$STDERR" || error
diff --git a/tests/tls-pin-fingerprint/t b/tests/tls-pin-fingerprint/t
index 1b84390..d3830e2 100644
--- a/tests/tls-pin-fingerprint/t
+++ b/tests/tls-pin-fingerprint/t
@@ -1,3 +1,9 @@
+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}")"
+INVALID_FPR="sha256\$deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
+INVALID_FPR2="sha256\$deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbee2"
+
# backup config
install -m0600 "$XDG_CONFIG_HOME/interimap/config" "$XDG_CONFIG_HOME/interimap/config~"
with_remote_config() {
@@ -7,7 +13,7 @@ with_remote_config() {
# pinned valid fingerprint
with_remote_config <<-EOF
- SSL_fingerprint = sha256\$e8fc8d03ffe75e03897136a2f1c5647bf8c36be7136a6883a732a8c4961c1614
+ SSL_fingerprint = sha256\$$PKEY_SHA256
EOF
for ((i = 0; i < 32; i++)); do
@@ -18,9 +24,16 @@ interimap_init
check_mailbox_status "INBOX"
+# with default algorithm (SHA256)
+with_remote_config <<-EOF
+ SSL_fingerprint = $INVALID_FPR $PKEY_SHA256
+EOF
+interimap || error
+
+
# and now an invalid one
with_remote_config <<-EOF
- SSL_fingerprint = sha256\$deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
+ SSL_fingerprint = $INVALID_FPR
EOF
! interimap --debug || error
@@ -30,4 +43,30 @@ grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error
# make sure we didn't send any credentials
! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error
+# two invalid ones
+with_remote_config <<-EOF
+ SSL_fingerprint = $INVALID_FPR $INVALID_FPR2
+EOF
+! interimap --debug || error
+
+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
+! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error
+
+
+# valid + invalid
+with_remote_config <<-EOF
+ SSL_fingerprint = sha256\$$PKEY_SHA256 $INVALID_FPR
+EOF
+interimap || error
+
+
+# invalid + valid
+with_remote_config <<-EOF
+ SSL_fingerprint = $INVALID_FPR sha256\$$PKEY_SHA256
+EOF
+interimap || error
+
# vim: set filetype=sh :
diff --git a/tests/tls-rsa+ecdsa/interimap.remote b/tests/tls-rsa+ecdsa/interimap.remote
new file mode 120000
index 0000000..daf3741
--- /dev/null
+++ b/tests/tls-rsa+ecdsa/interimap.remote
@@ -0,0 +1 @@
+../tls/interimap.remote \ No newline at end of file
diff --git a/tests/tls-rsa+ecdsa/remote.conf b/tests/tls-rsa+ecdsa/remote.conf
new file mode 100644
index 0000000..72ca135
--- /dev/null
+++ b/tests/tls-rsa+ecdsa/remote.conf
@@ -0,0 +1,5 @@
+!include conf.d/imapd.conf
+!include conf.d/ssl.conf
+
+ssl_alt_cert = <conf.d/dovecot.ecdsa.crt
+ssl_alt_key = <conf.d/dovecot.ecdsa.key
diff --git a/tests/tls-rsa+ecdsa/t b/tests/tls-rsa+ecdsa/t
new file mode 100644
index 0000000..29352e9
--- /dev/null
+++ b/tests/tls-rsa+ecdsa/t
@@ -0,0 +1,49 @@
+doveconf_remote() {
+ doveconf -c "$HOME_remote/.dovecot/config" -hx "$1"
+}
+pkey_sha256() {
+ openssl x509 -pubkey | openssl pkey -pubin -outform DER \
+ | openssl dgst -sha256 | sed -rn "/^.*=\\s*/ {s///p;q}"
+}
+x509_sha256() {
+ openssl x509 -noout -fingerprint -sha256 \
+ | sed -rn "/^.*=\\s*/ {s///p;q}" | tr -d : | tr "[A-Z]" "[a-z]"
+}
+
+PKEY_SHA256="$(doveconf_remote ssl_cert | pkey_sha256)"
+X509_SHA256="$(doveconf_remote ssl_cert | x509_sha256)"
+PKEY_ALT_SHA256="$(doveconf_remote ssl_alt_cert | pkey_sha256)"
+X509_ALT_SHA256="$(doveconf_remote ssl_alt_cert | x509_sha256)"
+
+# pinned valid fingerprints
+cat >>"$XDG_CONFIG_HOME/interimap/config" <<-EOF
+ SSL_fingerprint = sha256\$$PKEY_SHA256 sha256\$$PKEY_ALT_SHA256
+EOF
+
+for ((i = 0; i < 32; i++)); do
+ u="$(shuf -n1 -e "local" "remote")"
+ sample_message | deliver -u "$u"
+done
+interimap_init
+check_mailbox_status "INBOX"
+
+interimap --debug || error
+# which peer certificate is used is up to libssl
+grep -Fx -e "remote: Peer certificate fingerprint: sha256\$$X509_SHA256" \
+ -e "remote: Peer certificate fingerprint: sha256\$$X509_ALT_SHA256" \
+ <"$STDERR" || error
+
+# force RSA (XXX do we really have to force TLSv1.2 here?)
+cat >>"$XDG_CONFIG_HOME/interimap/config" <<-EOF
+ SSL_protocols = TLSv1.2
+ SSL_cipherlist = EECDH+AESGCM+aRSA
+EOF
+interimap --debug || error
+grep -Fx "remote: Peer certificate fingerprint: sha256\$$X509_SHA256" <"$STDERR" || error
+
+# force ECDSA
+sed -i "s/^SSL_cipherlist\\s*=.*/SSL_cipherlist = EECDH+AESGCM+aECDSA/" "$XDG_CONFIG_HOME/interimap/config"
+interimap --debug || error
+grep -Fx "remote: Peer certificate fingerprint: sha256\$$X509_ALT_SHA256" <"$STDERR" || error
+
+# vim: set filetype=sh :
diff --git a/tests/tls-verify-peer/t b/tests/tls-verify-peer/t
index d84328a..9e4d9fa 100644
--- a/tests/tls-verify-peer/t
+++ b/tests/tls-verify-peer/t
@@ -1,5 +1,3 @@
-CERT=~/.dovecot/conf.d/dovecot.pem
-
unverified_peer() {
! interimap --debug || error
@@ -41,36 +39,38 @@ unverified_peer
step_done
step_start "peer verification result honored when pinned pubkey matches"
-pkey_sha256="$(openssl x509 -pubkey <"$CERT" | openssl pkey -pubin -outform DER \
+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
+ SSL_fingerprint = sha256\$$PKEY_SHA256
EOF
unverified_peer
! grep -Fx "remote: WARNING: Fingerprint doesn't match! MiTM in action?" <"$STDERR" || error
step_done
+capath=$(mktemp --tmpdir="$TMPDIR" --directory capath.XXXXXX)
step_start "SSL_CAfile"
if [ -f "/etc/ssl/certs/ca-certificates.crt" ]; then
- # the self-signed cert should not be in there
+ # our self-signed test cert should not be in there
with_remote_config <<<"SSL_CAfile = /etc/ssl/certs/ca-certificates.crt"
unverified_peer
fi
-with_remote_config <<<"SSL_CAfile = $CERT"
+
+doveconf -c "$HOME_remote/.dovecot/config" -hx ssl_cert >"$capath/ca-certificates.crt"
+with_remote_config <<<"SSL_CAfile = $capath/ca-certificates.crt"
verified_peer
step_done
step_start "SSL_CApath"
if [ -d "/etc/ssl/certs" ]; then
- # the self-signed cert should not be in there
+ # our self-signed test cert should not be in there
with_remote_config <<<"SSL_CApath = /etc/ssl/certs"
unverified_peer
fi
-capath=$(mktemp --tmpdir="$TMPDIR" --directory capath.XXXXXX)
-cp -t"$capath" "$CERT"
c_rehash "$capath"
with_remote_config <<<"SSL_CApath = $capath"
diff --git a/tests/tls/t b/tests/tls/t
index dd6d955..9fdd399 100644
--- a/tests/tls/t
+++ b/tests/tls/t
@@ -1,3 +1,7 @@
+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]")"
+
for ((i = 0; i < 32; i++)); do
u="$(shuf -n1 -e "local" "remote")"
sample_message | deliver -u "$u"
@@ -5,7 +9,7 @@ done
interimap --debug || error
grep -Fx "remote: Disabling SSL protocols: SSLv3, TLSv1, TLSv1.1" <"$STDERR" || error
-grep -Fx "remote: Peer certificate fingerprint: sha256\$35944e3bd3300d3ac310bb497a32cc1eef6931482a587ddbc95343740cdf1323" <"$STDERR" || error
+grep -Fx "remote: Peer certificate fingerprint: sha256\$$X509_SHA256" <"$STDERR" || error
grep "^remote: SSL protocol: TLSv1\.[23] " <"$STDERR" || error
grep "^remote: SSL cipher: " <"$STDERR" || error