External (other) Mail clients have started to deny/de-list anonymous ciphersuites. But the TLS support is often spotty. Worse, some clients (mainly Windows, which does not care one whit about your RFC specs or lists of common protocols and does its own thing) have started to refuse to send mail when they cannot get an encrypted connection, preferring instead to silently leave the emails in the mail queue.
If the server admin manually sends out the mailqueue, then these clients will do so, sending the messages in plaintext.
This creates problems where some subset of connections fail with Handshake Failure (40) -> cipher list mismatch
, or: the server is not configured to support any of the ciphers in the list sent by the client in plaintext.
Using Wireshark to extract the actual protocol/messages, An example such list is:
0000 c0 2b c0 2f c0 23 c0 27 c0 13 00 9d 00 9c 00 3d
0010 00 3c 00 35 00 2f 00 0a
Which translates to;
Cipher Suites (12 suites)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
For ECC cipher suites, the client also seems to send a 'supported groups' extension. Which I believe is interpreted by the server; it checks whether its curve is in this set. This client sent only 0x0017
, which is
Supported Group: secp256r1 (0x0017)
But the mail server uses a secp384r1
key for its certificate (because that's the only ECC cert request our provider would sign successfully at the time). Is it true that this can lead to a handshake failure, even if the testssl
output reports this?
Elliptic curves offered: prime256v1 secp384r1 secp521r1 X25519 X448
TLSv1.2: ADH-AES256-GCM-SHA384 ADH-AES256-SHA256 ADH-CAMELLIA256-SHA256 AECDH-AES256-SHA ADH-AES256-SHA ADH-CAMELLIA256-SHA ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-CCM8 ECDHE-ECDSA-AES256-CCM ECDHE-ECDSA-ARIA256-GCM-SHA384 ECDHE-ECDSA-AES256-SHA384 ECDHE-ECDSA-CAMELLIA256-SHA384
ECDHE-ECDSA-AES256-SHA ADH-AES128-GCM-SHA256 ADH-AES128-SHA256 ADH-CAMELLIA128-SHA256 AECDH-AES128-SHA ADH-AES128-SHA ADH-CAMELLIA128-SHA ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES128-CCM8 ECDHE-ECDSA-AES128-CCM ECDHE-ECDSA-ARIA128-GCM-SHA256 ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-CAMELLIA128-SHA256 ECDHE-ECDSA-AES128-SHA
ADH-SEED-SHA
There's also a 'Signature Hash Algorithms' section;
0000 04 01 05 01 02 01 04 03 05 03 02 03 02 02 06 01
0010 06 03
Translating to:
Signature Hash Algorithms (9 algorithms)
Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
Signature Algorithm: rsa_pkcs1_sha1 (0x0201)
Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
Signature Algorithm: ecdsa_sha1 (0x0203)
Signature Algorithm: SHA1 DSA (0x0202)
Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
Signature Algorithm: ecdsa_secp521r1_sha512 (0x0603)
The relevant cert info, pulled with openssl x509 -text -in cert.cer
is (omitting PII details);
Signature : ecdsa-with-SHA256
Signature Algorithm: ecdsa-with-SHA256
Public-Key: (384 bit)
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 Key Usage: critical
Digital Signature
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
One of these could also be the cause of the same problem.
It appears that 'supported group' might not restrict the ECDSA cert. Yet, there's still the problem that this cert does not work. And it's my postfix server/openSSL deciding that it does not, so it's not the fault of some ill-behaved client. Meaning: there's some needle in the haystack here that I'm missing why these clients won't talk; there's some detail in the Client Hello message that causes a handshake failure of
SSL routines:tls_post_process_client_hello:no shared cipher
Dealing with multiple such clients
There's more types/versions of mail clients talking to this mail server. The usual procedure would be to
Be conservative in what you send, be liberal in what you accept
J. Postel
so as to be able to receive encrypted mail from multiple clients, running software that can date from as far back as the early 2000s, supporting various versions of TLS and so on. When anonymous connections are tolerated this isn't a problem. OpenSSL has a huge list of certs it supports, and the server/client tend to auto-negotiate the strongest cipher using the Postfix cipherlist, which is optimized for both compatibility and security (use whatever is strongest that both accept), and can gracefully downgrade*.
But when a client wants one specific type and only supports 'not-anonymous' certs, I.e. ones that have been signed by a CA that it knows, then (for cost purposes) there's only one cert, not one cert per algorithm (since there's many algorithms).
Option A: multiple certificates
One way to solve it is to perhaps add another cert/key for a different algorithm. Postfix supports the smtpd_tls_eccert_file
and smtpd_tls_eckey_file
parameters, so you could add both an ECC and an RSA cert, by using the smtpd_tls_key_file
and smtpd_tls_cert_file
for RSA and the former two for ECDSA. For the sake of argument though, consider what happens when we have two clients that need to speak ECC, but both want a different curve.
I could also add them using the smtpd_tls_chain_files
option, where you can supposedly use a list of keys/certs; [key1, cert1, chain1, key2, cert2, ..., keyN, certN, chainN].
Option B, try it anyway?
Interestingly, the clients in question do seem to reference secp384r1 in their list of 'Signature Hash Algorithms' in the 'signature_algorithms' extension. (see above)
Can I tell postfix to use /send the secp384
cert for this client anyway, instead of aborting when it thinks it can't match because the client sent a malformed request for it, i.e. to ignore supported_groups
in favour of signature_algorithms
if the group in question can be found in the latter?
Option C, modify the client
Can a Microsoft Exchange server be modified so that it will accept an anonymous certificate for outgoing mail, not incoming mail? There's lots of instructions for the former, but none for the latter.
Which option would you recommend / What's a good way to go about this? Needing more and more certificates to deal with all the clients can get cumbersome.
[*] To the extent this is possible; due to mitigations for various downgrade attacks, protocol exploits that could downgrade previous TLS versions.