Bug 216790 - mail/postfix: Fix x25519 kex with LibreSSL
Summary: mail/postfix: Fix x25519 kex with LibreSSL
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Only Me
Assignee: Olli Hauer
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-02-04 19:24 UTC by OlivierW
Modified: 2017-05-20 18:49 UTC (History)
3 users (show)

See Also:
bugzilla: maintainer-feedback? (ohauer)


Attachments
Add debug messages to postfix. Not to be released! (856 bytes, patch)
2017-02-04 19:24 UTC, OlivierW
no flags Details | Diff
patch (7.59 KB, patch)
2017-02-05 11:32 UTC, Piotr Kubaj
no flags Details | Diff
patch (7.59 KB, patch)
2017-02-05 12:56 UTC, Piotr Kubaj
no flags Details | Diff
patch (7.01 KB, patch)
2017-02-21 16:54 UTC, Piotr Kubaj
no flags Details | Diff
patch (9.43 KB, patch)
2017-02-22 21:10 UTC, Piotr Kubaj
no flags Details | Diff
patch (8.42 KB, patch)
2017-02-22 21:21 UTC, Piotr Kubaj
no flags Details | Diff
patch (9.54 KB, patch)
2017-03-05 12:09 UTC, Piotr Kubaj
no flags Details | Diff
patch (8.42 KB, patch)
2017-04-23 12:01 UTC, Piotr Kubaj
no flags Details | Diff
svn diff for mail/postfix (2.44 KB, patch)
2017-05-14 09:10 UTC, Bernard Spil
brnrd: maintainer-approval?
Details | Diff
svn diff for mail/postfix-current (3.77 KB, patch)
2017-05-14 09:34 UTC, Bernard Spil
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description OlivierW 2017-02-04 19:24:11 UTC
Created attachment 179608 [details]
Add debug messages to postfix. Not to be released!

Hello,

Sorry, it's long and I'm a bit lost trying to fix the auto selection of EC curves.


Last version of postfix-current has this default values:
"smtpd_tls_eecdh_grade = auto
tls_eecdh_auto_curves = X25519 X448 prime256v1 secp521r1 secp384r1"

LibreSSL 2.5.1 implements SSL_CTX_set1_curves() so this feature should work.


Unfortunaletly, in postfix's log, I'm getting this: "warning: Invalid TLS eecdh grade "auto": EECDH disabled" and when I'm trying to connect to my postfix with:
"/usr/local/bin/openssl s_client -starttls smtp -crlf -connect my-server:25",
I can find: "Server Temp Key: DH, 2048 bits"

In previous postfix version with LibreSSL 2.5.0 (so no EC autodetect feature), I was getting:
"Server Temp Key: ECDH, P-256, 256 bits"
or
"Server Temp Key: ECDH, P-384, 384 bits"

To fix this (EECDH disabled), we can use in postfix's main.cf:
"smtpd_tls_eecdh_grade = ultra" or "smtpd_tls_eecdh_grade = strong" instead of "auto" (will use secp384r1 or prime256v1)


I've also tried to use X25519 with this setup:
"smtpd_tls_eecdh_grade = ultra
tls_eecdh_ultra_curve = X25519",
unfortunately I'm getting this warning:
"warning: unable to use curve "X25519": disabling EECDH support"

If I try a random name for the curve, like "blahblah", I'm getting this different warning:
"warning: unknown curve "blahblah": disabling EECDH support"
Meaning X25519 is recognized but not usable for some reasons.





Then I tried to make "auto" works... and I've been lost in postfix and libressl source code. I have no idea if the problem comes from postfix or libressl (important: autoselection of EC curves does work with nginx-devel + LibreSSL 2.5.1).

So, in this patch https://svnweb.freebsd.org/ports/head/mail/postfix-current/files/patch-src_tls_tls__dh.c?revision=433285&view=markup I changed every "&& !defined(LIBRESSL_VERSION_NUMBER)" to "&& (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x2050100fUL)"

I think it's the correct way to detect LibreSSL 2.5.1 without breaking old versions.

This way, I'm not getting anymore the: "warning: Invalid TLS eecdh grade "auto": EECDH disabled" message, but I'm still getting: "Server Temp Key: DH, 2048 bits" while trying to connect to my postfix server with LibreSSL.
So EECDH support is still silently disabled.

I tried to add debug message in "src/tls/tls_dh.c" around line 274, but couldn't find where was the problem. In this piece of code, postfix correctly detect X25519, prime256v1, secp521r1, secp384r1 and ignore X448.

If someone want to dig this problem, I've attached my patch which add 3 debug message.

Maybe it's an easy fix for someone who know postfix and libressl code well. On my side I don't know how to help more.

Best Regards.
Comment 1 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-04 22:07:41 UTC
Heh, I've come here to create a new PR and someone has already done it :)

Just to add my 3 cents: LIBRESSL_VERSION_NUMBER is actually 0x2050100fL, but the behaviour I get from Postfix is exactly the same.
Comment 2 OlivierW 2017-02-04 22:34:21 UTC
Thanks for your comment! :-) I spent quite a few hours on this problem :-/


Yes, I saw the version was "0x2050100fL", but in the "patch-src_tls_tls__dh.c" file, the tests regarding OPENSSL_VERSION_NUMBER compare with "0x1000200fUL".
I thought "UL" meant "unsigned long", but I may be wrong?

I'm not sure why it's defined as long and tested as unsigned long.
In OpenSSL 1.0.2k, it's "# define OPENSSL_VERSION_NUMBER  0x100020bfL".

In LibreSSL 2.5.1, there's:
"#define LIBRESSL_VERSION_NUMBER 0x2050100fL"
and:
"#define OPENSSL_VERSION_NUMBER  0x20000000L"
Comment 3 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-05 08:58:04 UTC
(In reply to OlivierW from comment #2)
LIBRESSL_VERSION_NUMBER doesn't seem to be an issue here. I completely removed the #if #endif blocks mentioning OPENSSL_VERSION_NUMBER >= number of version 1.0.2, making the code in those blocks to be build unconditionally, but ECDHE still doesn't work and there's no message in logs.
Comment 4 Olli Hauer freebsd_committer freebsd_triage 2017-02-05 10:56:52 UTC
Hm, maybe you see the same issue that was reported on the tech@ list
https://marc.info/?t=148596023500003&r=1&w=2
Comment 5 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-05 11:02:28 UTC
(In reply to Olli Hauer from comment #4)
It may be possible. I've also compiled the latest Haproxy 1.8 snapshot with support for "curves" setting which can enable X25519 (using the new OpenSSL auto API). However, after I had set it up, ECDHE silently fails (same symptoms as with Postfix). Using the old API works.

So it may be that the problem isn't with Postfix, but LibreSSL itself.
Comment 6 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-05 11:32:04 UTC
Created attachment 179639 [details]
patch

(In reply to Piotr Kubaj from comment #5)
It seems like OpenBSD guys have found the issue:
https://github.com/openbsd/ports/blob/master/mail/postfix/snapshot/patches/patch-src_tls_tls_dh_c

The patch has to be modified not to break LibreSSL 2.4. I have verified that Postfix does ECDHE with the attached patch.
Comment 7 OlivierW 2017-02-05 11:39:48 UTC
Hello,

Piotr, yes, removing completely the conditionnal directives has the same effect as changing them the way I did when you're using LibreSSL 2.5.1.
I just wanted a "clean" modification to still be compatible with old LibreSSL and OpenSSL (I was hoping it was the only easy fix needed... :-( ).

You're right, the problem may be in LibreSSL. Or in both Postfix and Haproxy? I've no idea.
Can someone test one of this software with OpenSSL 1.0.2? Or I'll try later this week.



Olli, I'm not sure it's the same problem. It looks like Andreas used "x25519" instead of "X25519": https://marc.info/?l=openbsd-tech&m=148628961219628&w=2
I also made this same mistake when first setting up nginx... because all others curves are in lowercase.
But as I said in my first message, it does work with nginx, in the same way stated in this message: https://marc.info/?l=openbsd-tech&m=148627690217342&w=2

Best Regards.
Comment 8 OlivierW 2017-02-05 11:45:41 UTC
(In reply to Piotr Kubaj from comment #6)
Nice find!

If I'm not wrong, replacing:
"+#if OPENSSL_VERSION_NUMBER < 0x10100000UL || defined(LIBRESSL_VERSION_NUMBER)"
with:
"+#if OPENSSL_VERSION_NUMBER < 0x10100000UL || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2050100fUL)"
should work for all version of LibreSSL.
Comment 9 OlivierW 2017-02-05 11:59:01 UTC
(In reply to OlivierW from comment #8)
Well, in fact the patch may not need to be changed: SSL_CTX_set_ecdh_auto() is defined since at least LibreSSL 2.2.2, the same version which also got LIBRESSL_VERSION_NUMBER.

So this patch prevents the use of the new SSL_CTX_set1_curves().
Comment 10 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-05 12:56:17 UTC
Created attachment 179641 [details]
patch

Thanks for the info! In that case, I attach the ready patch.
Comment 11 OlivierW 2017-02-05 14:18:18 UTC
(In reply to Piotr Kubaj from comment #10)
Thanks for your patch! I haven't tried it yet.
I have a question: is it normal your patch touch several files while I think it should only modify "Makefile" and "patch-src_tls_tls__dh.c"? I may be wrong, I'm quite new in the FreeBSD world.


For now I've tried compiling postfix-current with openssl (1.0.2k) and openssl-devel (1.1.0d).
With 1.0.2, I could successfully get
"Server Temp Key: ECDH, P-256, 256 bits" and "Server Temp Key: ECDH, P-384, 384 bits" with this commands:
"/usr/local/bin/openssl s_client -starttls smtp -crlf -connect my-server:25 -groups P-256"
"/usr/local/bin/openssl s_client -starttls smtp -crlf -connect my-server:25 -groups P-384"

With 1.1.0d, I could get the same result as with 1.0.2k and also:
"Server Temp Key: ECDH, X25519, 253 bits" with:
"/usr/local/bin/openssl s_client -starttls smtp -crlf -connect my-server:25 -groups X25519"
Comment 12 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-05 14:58:06 UTC
(In reply to OlivierW from comment #11)
I generated the patch using makepatch, which also regenerated other patches. This is completely harmless and doesn't actually change the code (except for the tls_dh.c file).
Comment 13 OlivierW 2017-02-05 15:34:18 UTC
(In reply to Piotr Kubaj from comment #12)
Ah, ok, thanks!
Comment 14 OlivierW 2017-02-05 17:55:57 UTC
(In reply to Piotr Kubaj from comment #10)
I've just tested your patch and I can confirm now Postfix gives the same results as in comment #11.
And no more warning in its logs.
Comment 15 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-21 16:54:18 UTC
Created attachment 180193 [details]
patch

Updated patch for 3.2-RC1.
Comment 16 Olli Hauer freebsd_committer freebsd_triage 2017-02-22 20:30:10 UTC
Hm, since the patch does only build against libressl-devel it is holding me back at the moment.
The time 3.2.0 or 3.2.1 is released it will eventually replace 3.1.4 in the tree and then it should build also against base openssl or libressl to avoid ssl issues on existing systems.

Perhaps it is possible to get it work as extra patch if libressl-devel is detected
Comment 17 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-22 21:10:46 UTC
Created attachment 180229 [details]
patch

Sure.

Please check the attached patch.

It builds on 10.3-RELEASE with base OpenSSL or LibreSSL 2.5.1.
Comment 18 Piotr Kubaj freebsd_committer freebsd_triage 2017-02-22 21:21:21 UTC
Created attachment 180231 [details]
patch

The corrected patch.
Comment 19 Piotr Kubaj freebsd_committer freebsd_triage 2017-03-05 12:09:06 UTC
Created attachment 180532 [details]
patch

Update to stable 3.2.0.
Regenerate patches.
Fixes build with LibreSSL 2.4.

Test builds done on Poudriere with 10.3-RELEASE and base OpenSSL, LibreSSL 2.4.5 and LibreSSL 2.5.1.
Comment 20 OlivierW 2017-03-27 18:01:44 UTC
(In reply to Piotr Kubaj from comment #19)
Hello,

Sorry for my late answer, I've been quite busy.
Thanks for your new patch, I've just compiled postfix 3.2.0 stable with the new libressl-devel 2.5.2 on FreeBSD 11. It works perfectly!


I think there's a small mistake in your patch. You have:
+.if ${SSL_DEFAULT:Mlibressl}
+EXTRA_PATCHES=	${FILESDIR}/libressl-patch-src_tls_tls__dh.c
+.endif

but there's no "libressl-patch-src_tls_tls__dh.c", only "libressl-devel-patch-src_tls_tls__dh.c"

Best Regards,
Olivier
Comment 21 Piotr Kubaj freebsd_committer freebsd_triage 2017-04-23 12:01:05 UTC
Created attachment 182015 [details]
patch

Updated patch to support only LibreSSL 2.5 (2.4 is not in ports anymore).

Builds fine on Poudriere with 10.3-RELEASE with both base OpenSSL and security/libressl.
Comment 22 Bernard Spil freebsd_committer freebsd_triage 2017-05-14 09:10:07 UTC
Created attachment 182584 [details]
svn diff for mail/postfix

```
mail/postfix: Fix x25519 kex with LibreSSL

 - Add patches for LibreSSL

PR: 216790
Obtained from:   OpenBSD ports
```

Hi Olli,

Please let me know if I should take this.

Cheers, Bernard.
Comment 23 Bernard Spil freebsd_committer freebsd_triage 2017-05-14 09:34:19 UTC
Created attachment 182586 [details]
svn diff for mail/postfix-current

Similar patch but for latest version of postfix-current.
Comment 24 OlivierW 2017-05-14 19:52:45 UTC
(In reply to Bernard Spil from comment #23)
Hello,

Thanks a lot Bernard!
I've just tested your patch on postfix-current 3.3.20170502,5 compiled with libressl-devel 2.5.4 and it does work.

Best Regards.
Comment 25 commit-hook freebsd_committer freebsd_triage 2017-05-20 18:35:08 UTC
A commit references this bug:

Author: brnrd
Date: Sat May 20 18:34:56 UTC 2017
New revision: 441329
URL: https://svnweb.freebsd.org/changeset/ports/441329

Log:
  mail/postfix: Fix x25519 kex with LibreSSL

  PR:		216790
  Obtained from:	OpenBSD ports
  Approved by:	ohauer (maintainer)

Changes:
  head/mail/postfix/files/patch-src_tls_tls.h
  head/mail/postfix/files/patch-src_tls_tls__dh.c
Comment 26 commit-hook freebsd_committer freebsd_triage 2017-05-20 18:49:29 UTC
A commit references this bug:

Author: brnrd
Date: Sat May 20 18:49:11 UTC 2017
New revision: 441330
URL: https://svnweb.freebsd.org/changeset/ports/441330

Log:
  mail/postfix-current: Fix x25519 kex with LibreSSL

   - Add patches for LibreSSL

  PR:		216790
  Obtained from:	OpenBSD ports
  Approved by:	ohauer (maintainer)

Changes:
  head/mail/postfix-current/files/patch-src_tls_tls.h
  head/mail/postfix-current/files/patch-src_tls_tls__dh.c