TLDR Mac OS_X 10.11 / openssl 0.9.8zh connects successfully using TLS1.0 to a modern server's SMTPS port, but not its IMAPS port, despite the use of the same SSL library on both server and client. Any idea what this could be?
Debugging detail:
Having recently upgraded my Ubuntu mail server, one old client (Mac OS-X 10.11.6 Mail.app) successfully connects on the IMAPS port but not the SSL port; newer clients connect to both services. Normally this problem is related to LetsEncrypt certificate chains and out of date OS-X roots of trust (which I have fixed), but I am pretty convinced this is not the case as openssl s_connect
indicates that the certificates presented on IMAPS and SSL are the same (byte for byte). Unfortunately Mail.app gives little to no information on where the connection problem is (connection doctor shows a red dot, logs seem to indicate a very early TLS failure). So I tried to see what if anything is different in the way cyrus-imapd and postfix handle their TLS connections, and have come up with something very peculiar re TLS version management.
The server is running an up-to-date Ubuntu 20.04. Both imapd
and postfix are using libcrypto.so.1.1 (OPENSSL_1_1_0)
.
The non-working client is linked to /usr/lib/libcrypto.0.9.8.dylib
.
TLS 1.2 is meant to be supported from Mac OS_X 10.11 (ie this version - though it doesn't seem to be - see below), however TLS 1.3 is not supported in 10.11 I believe.
Here's what happens when I used openssl s_client
(0.9.8zh, linked the same library as Mail.app).
$ openssl s_client -tls1 example.com:smtps </dev/null
CONNECTED(00000003)
...
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
$ openssl s_client -tls1 example.com:imaps </dev/null
33344:error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.2/src/ssl/s3_pkt.c:1145:SSL alert number 70
33344:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.2/src/ssl/s3_pkt.c:566:
CONNECTED(00000003)
(Note -tls1_2
and -tls1_1
are unrecognised by this client)
This suggests there is a problem with the SSL version handling of the connection to imaps
but not smtps
. So what is the server offering?
Using a reasonably recent version of OpenSSL (1.1.1f) connecting to loopback on the server itself, this is what I see connecting to SMTPS:
$ openssl s_client -tls1_3 127.0.0.1:smtps </dev/null
CONNECTED(00000003)
...
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
...
$ openssl s_client -tls1_2 127.0.0.1:smtps </dev/null
CONNECTED(00000003)
...
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
...
$ openssl s_client -tls1_1 127.0.0.1:smtps </dev/null
CONNECTED(00000003)
140019230856512:error:141E70BF:SSL routines:tls_construct_client_hello:no protocols available:../ssl/statem/statem_clnt.c:1112:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 7 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
$ openssl s_client -tls1 127.0.0.1:smtps </dev/null
CONNECTED(00000003)
139839107994944:error:141E70BF:SSL routines:tls_construct_client_hello:no protocols available:../ssl/statem/statem_clnt.c:1112:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 7 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
This is mostly what I would expect.
However, with IMAPS:
$ openssl s_client -tls1_3 127.0.0.1:imaps </dev/null
CONNECTED(00000003)
...
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
DONE
$ openssl s_client -tls1_2 127.0.0.1:imaps </dev/null
CONNECTED(00000003)
...
New, TLSv1.0, Cipher is ECDHE-RSA-AES256-SHA
Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-SHA
...
$ openssl s_client -tls1_1 127.0.0.1:imaps </dev/null
CONNECTED(00000003)
140418999268672:error:141E70BF:SSL routines:tls_construct_client_hello:no protocols available:../ssl/statem/statem_clnt.c:1112:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 7 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
$ openssl s_client -tls1 127.0.0.1:imaps </dev/null
CONNECTED(00000003)
139756429100352:error:141E70BF:SSL routines:tls_construct_client_hello:no protocols available:../ssl/statem/statem_clnt.c:1112:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 7 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
There are two bits of weirdness here. Specifying tls1_3
causes substantially less output; I think this is a timing issue as it's fixed if I remove the </dev/null
. But more importantly, for IMAPS specifying tls1_2
gives New, TLSv1.0
(note 1.0 not 1.2) unlike for SMTPS. But connecting with tls1_0
does not work (for either IMAPS or SMTPS).
Any idea what is happening here?