0

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?

2 Answers 2

2

TLS: Old Mac connects to SMTPS but not IMAPS

Especially with UNIX based systems it is very common that the SSL settings are specific for the service and not global to the machine. Thus SMTP and IMAPS are probably using different SSL configurations with different protocols and ciphers enabled.

But more importantly, for IMAPS specifying tls1_2 gives New, TLSv1.0 (note 1.0 not 1.2) unlike for SMTPS.

The relevant output for IMAPS is:

$ openssl s_client -tls1_2 127.0.0.1:imaps </dev/null
...
New, TLSv1.0, Cipher is ECDHE-RSA-AES256-SHA
...
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-SHA

The protocol version shown in New, TLSv1.0, Cipher is ... is the result from SSL_CIPHER_get_version which "returns string which indicates the SSL/TLS protocol version that first defined the cipher.".

So this is not the protocol version used for the TLS connection, which is instead TLS 1.2 as shown later in Protocol : TLSv1.2. Instead it is the protocol version where ECDHE-RSA-AES256-SHA was defined, i.e. TLS 1.0. With SMTPS instead ECDHE-RSA-AES256-GCM-SHA384 is used which was defined in TLS 1.2 - thus TLS 1.2 is shown as the cipher version there.

See also the output of openssl ciphers -V to get the relation between cipher and protocol version where it was defined.

1
  • +1 - but this turned out to be to do with openssl.cfg and differing use of SSL_CTX_set_min_proto_version meaning the same SSL config was doing different things (sigh). I wrote an answer.
    – abligh
    Mar 25, 2022 at 19:06
1

The problem appears to be that cyrus-imapd uses the default SSL config, whereas postfix overwrites that to a degree, I believe by calling SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_VERSION); or similar.

This can be checked with

nmap --script ssl-cert,ssl-enum-ciphers -p imaps 127.0.0.1

Despite having

tls_versions: tls1_0 tls1_1 tls1_2 tls1_3

in my imapd.conf, only tls1_2 was being offered.

To "fix" that (normally not offering tls1_0 and tls1_1 is a feature not a bug) I applied:

--- /etc/ssl/openssl.cnf        2020-07-01 12:30:10.966775346 +0100
+++ /etc/ssl/openssl.cnf        2020-07-01 12:30:30.714978507 +0100
@@ -11,6 +11,8 @@
 # defined.
 HOME                   = .
 
+openssl_conf = default_conf
+
 # Extra OBJECT IDENTIFIER info:
 #oid_file              = $ENV::HOME/.oid
 oid_section            = new_oids
@@ -349,3 +351,11 @@
 ess_cert_id_alg                = sha1  # algorithm to compute certificate
                                # identifier (optional, default: sha1)
 
+[default_conf]
+ssl_conf = ssl_sect
+
+[ssl_sect]
+system_default = system_default_sect
+
+[system_default_sect]
+CipherString = DEFAULT@SECLEVEL=1

IMHO cyrus-imapd should log some form of warning if you try to enable a TLS protocol that cannot in fact be enabled.

I was led down the garden path by the failure of the to connect using tls1_0 to localhost on either smtps or imaps (despite smtps working from elsewhere), which turned out to the same cause (openssl.cfg).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.