Hi all,

As reported on 2019-11-08 on IRC, I have issues with ECC certificates in
smtpd_tls_chain_files, which don't happen with the older
smtpd_tls_eccert_file and smtpd_tls_eckey_file.

I use acme.sh [0] to renew my certificates from let's encrypt: crontab extract:
@weekly /usr/local/sbin/acme.sh --renew --dns dns_ovh -d mail.domain.tld 
--keylength ec-256 --cert-file /usr/local/etc/ssl/mail.domain.tld/ecc.crt 
--key-file /usr/local/etc/ssl/mail.domain.tld/ecc.key --ca-file 
/usr/local/etc/ssl/mail.domain.tld/ecc.ca.crt --fullchain-file 
/usr/local/etc/ssl/mail.domain.tld/ecc.fullchain.cer
@weekly /usr/local/sbin/acme.sh --renew --dns dns_ovh -d mail.domain.tld 
--cert-file /usr/local/etc/ssl/mail.domain.tld/rsa.crt --key-file 
/usr/local/etc/ssl/mail.domain.tld/rsa.key --ca-file 
/usr/local/etc/ssl/mail.domain.tld/rsa.ca.crt --fullchain-file 
/usr/local/etc/ssl/mail.domain.tld/rsa.fullchain.cer

This generates/updates the following files:
# ecc.ca.crt / ecc.crt / rsa.ca.crt / rsa.crt look like:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# ecc.fullchain.cer / rsa.fullchain.cer looks like:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# ecc.key is: (note the EC PARAMETERS object)
-----BEGIN EC PARAMETERS-----
...
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
...
-----END EC PRIVATE KEY-----
# rsa.key is:
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

According to the documentation, smtpd_tls_chain_files is the preferred
way of handling TLS files now, so I use:

smtpd_tls_chain_files =
  /usr/local/etc/ssl/mail.domain.tld/rsa.key,
  /usr/local/etc/ssl/mail.domain.tld/rsa.fullchain.cer

which works well:

 % openssl s_client -showcerts -connect mail.domain.tld:465
 ...
 No client certificate CA names sent
 Peer signing digest: SHA256
 Peer signature type: RSA-PSS
 Server Temp Key: X25519, 253 bits
 ...

However, if I add my ECC key and certificate...

smtpd_tls_chain_files =
  /usr/local/etc/ssl/mail.domain.tld/ecc.key,
  /usr/local/etc/ssl/mail.domain.tld/ecc.fullchain.cer,
  /usr/local/etc/ssl/mail.domain.tld/rsa.key,
  /usr/local/etc/ssl/mail.domain.tld/rsa.fullchain.cer

 % openssl s_client -showcerts -connect mail.domain.tld:465
 CONNECTED(00000003)
 write:errno=0
 ---
 no peer certificate available
 ---
 No client certificate CA names sent
 ---
 SSL handshake has read 0 bytes and written 314 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)
 ---

Mail log also has an error:

  Nov  8 21:32:25 mail postfix/smtps/smtpd[3146]: warning: error loading 
/usr/local/etc/ssl/mail.domain.tld/ecc.key: unexpected PEM type: EC PARAMETERS

This lead me to [1] where the author simply removes the EC PARAMETERS to
get a working file. When I then try to remove the EC PARAMETERS object
in ecc.key and use smtpd_tls_chain_files, I get no such issue:

 % openssl s_client -showcerts -connect mail.domain.tld:465
 ...
 No client certificate CA names sent
 Peer signing digest: SHA256
 Peer signature type: ECDSA
 Server Temp Key: X25519, 253 bits
 ...

Which looks like it's working correctly. So the EC PARAMETERS object
breaks an otherwise fine key file for postfix.

However, before reading [1], I tried the "old" method with
smtpd_tls_eccert_file and smtpd_tls_eckey_file and my ecc.key file (with
EC PARAMETERS still in it):

smtpd_tls_eccert_file = /usr/local/etc/ssl/mail.domain.tld/ecc.fullchain.cer
smtpd_tls_eckey_file = /usr/local/etc/ssl/mail.domain.tld/ecc.key

This also works with no issue.

So:
* smtpd_tls_chain_files can't handle the EC PARAMETERS object of the
  ecc.key file
* however previous configuration options could

With my little understanding of C code, I suspect that fixing this bug
should be made around lines 407..418 of src/tls/tls_certkey.c [2], to
silently ignore the EC PARAMETERS object if encountered (though ignoring
those parameters may have consequences I know nothing of).

I could also edit my key file, but as it's valid, it seems weird to do
it. And because the key was generated by a third-party tool ([0]), more
people will encounter the issue if they use it too, same as I did to get
my certificates.

For the time being, I have disabled ECC certificates on my postfix
instance - and keep the knowledge of how to get it to work if it's ever
needed one day...

[0] https://acme.sh
[1] https://gitmemory.com/issue/lukas2511/dehydrated/660/514896977
[2] 
https://github.com/vdukhovni/postfix/blob/v3.4.7/postfix/src/tls/tls_certkey.c#L407-L418

Reply via email to