Opened 3 years ago

Closed 3 years ago

#889 closed Bug / Defect (worksforme)

OpenVPN 2.4.2 fails to build against LibreSSL

Reported by: cardioidi Owned by: Gert Döring
Priority: major Milestone:
Component: Generic / unclassified Version: OpenVPN git master branch (Community Ed)
Severity: Not set (select this one, unless your'e a OpenVPN developer) Keywords:
Cc: David Sommerseth, Steffan Karger

Description

OpenVPN 2.4.2 fails to build against LibreSSL.

Steps to reproduce:

  1. Compile LibreSSL, I did this with:
--prefix=/build/libressl/.openssl
  1. Checkout OpenVPN from Github
  2. Switch to 2.4.2 release branch
  3. Generate configure
autoreconf -vi
  1. Configure
./configure OPENSSL_LIBS="-L/build/libressl/.openssl/lib -lssl -lcrypto" OPENSSL_CFLAGS="-I/build/libressl/.openssl/include" --with-crypto-library=openssl
  1. make
make

Error:

gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include  -I../../include -I../../src/compat   -I/build/libressl/.openssl/include    -DPLUGIN_LIBDIR=\"/usr/local/lib/openvpn/plugins\"  -g -O2 -std=c99 -c -o ssl_openssl.o ssl_openssl.c
In file included from ssl_openssl.c:48:0:
openssl_compat.h: In function ‘SSL_CTX_get_default_passwd_cb_userdata’:
openssl_compat.h:59:21: error: ‘SSL_CTX’ has no member named ‘default_passwd_callback_userdata’
     return ctx ? ctx->default_passwd_callback_userdata : NULL;
                     ^
openssl_compat.h: In function ‘SSL_CTX_get_default_passwd_cb’:
openssl_compat.h:73:21: error: ‘SSL_CTX’ has no member named ‘default_passwd_callback’
     return ctx ? ctx->default_passwd_callback : NULL;
                     ^
openssl_compat.h: In function ‘RSA_meth_free’:
openssl_compat.h:152:14: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier from pointer target type
         free(meth->name);
              ^
In file included from syshead.h:117:0,
                 from ssl_openssl.c:36:
/usr/include/stdlib.h:483:13: note: expected ‘void *’ but argument is of type ‘const char *’
 extern void free (void *__ptr) __THROW;
             ^
In file included from ssl_openssl.h:33:0,
                 from ssl_backend.h:37,
                 from ssl_openssl.c:45:
ssl_openssl.c: In function ‘tls_ctx_client_new’:
/build/libressl/.openssl/include/openssl/ssl.h:606:15: warning: passing argument 1 of ‘SSL_CTX_ctrl’ from incompatible pointer type
  SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
               ^
ssl_openssl.c:119:5: note: in expansion of macro ‘SSL_CTX_set_options’
     SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); // only allow TLSv1.x
     ^
In file included from ssl_openssl.h:33:0,
                 from ssl_backend.h:37,
                 from ssl_openssl.c:45:
/build/libressl/.openssl/include/openssl/ssl.h:1362:6: note: expected ‘struct SSL_CTX *’ but argument is of type ‘struct tls_root_ctx *’
 long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
      ^
ssl_openssl.c: In function ‘rsa_finish’:
ssl_openssl.c:982:19: warning: passing argument 1 of ‘RSA_meth_free’ discards ‘const’ qualifier from pointer target type
     RSA_meth_free(rsa->meth);
                   ^
In file included from ssl_openssl.c:48:0:
openssl_compat.h:148:1: note: expected ‘struct RSA_METHOD *’ but argument is of type ‘const struct RSA_METHOD *’
 RSA_meth_free(RSA_METHOD *meth)
 ^
Makefile:666: recipe for target 'ssl_openssl.o' failed
make[3]: *** [ssl_openssl.o] Error 1
make[3]: Leaving directory '/build/openvpn/src/openvpn'
Makefile:418: recipe for target 'all-recursive' failed
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory '/build/openvpn/src'
Makefile:604: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/build/openvpn'
Makefile:491: recipe for target 'all' failed
make: *** [all] Error 2

Change History (12)

comment:1 Changed 3 years ago by David Sommerseth

Resolution: duplicate
Status: newclosed

This looks like the LibreSSL version is the equivalent of OpenSSL v1.1. OpenVPN does currently not support the OpenSSL v1.1 API. This is being tracked in ticket #759. Closing as duplicate.

Feel free to request re-opening if my quick assessment was wrong.

comment:2 Changed 3 years ago by cardioidi

As far as I know LibreSSL does _not_ use a similar API to OpenSSL 1.1.0. I think it is based on the old 1.0.1 stuff. So please reopen.

Last edited 3 years ago by cardioidi (previous) (diff)

comment:3 Changed 3 years ago by Gert Döring

Resolution: duplicate
Status: closedreopened

comment:4 Changed 3 years ago by Gert Döring

Cc: David Sommerseth Steffan Karger added

it *should* build against LibreSSL fine, though that's not a supported crypto library (and generally speaking, LibreSSL has been a bit of an annoyance due to their "we're sort of using the OpenSSL API, but with minor differences" approach).

That said, it should work - one of our buildslaves is OpenBSD 6.0, which uses LibreSSL, and that one is actually running daily builds on everything we commit to master - and there is nothing in release/2.4 that's not in master.

So maybe there is OpenSSL 1.1 on your system in addition to LibreSSL, and due to compiler flags / includes (and possibly configure bugs) we're not using the LibreSSL headers but the OpenSSL headers... looking at the gcc command above, there is no {{{-I/build/...} for LibreSSL, so that bit looks suspicious...

@dazo, @syzzer: what happens if there is a pkg-config for OpenSSL, but we still specify OPENSSL_{LIBS,CFLAGS} with different paths? Will that work?

comment:5 Changed 3 years ago by Steffan Karger

The _LIBS and _CFLAGS should take precedence over pkg-config.

Something fishy is going on here - did LibreSSL change their API perhaps? The following code is in OpenVPN 2.3's ssl_openssl.c:

 602   x = PEM_read_bio_X509 (in, NULL, ctx->ctx->default_passwd_callback,
 603                          ctx->ctx->default_passwd_callback_userdata);

That accesses the same default_passwd_callback member of SSL_CTX, and worked just fine. I too think this smells like 'OpenSSL 1.1 API'.

As cron2 already said, we don't actively support LibreSSL. But if someone feels like digging into this and submit a patch, we might apply it if it doesn't break OpenSSL builds and doesn't clutter our code.

comment:6 in reply to:  5 Changed 3 years ago by Gert Döring

Replying to syzzer:

The _LIBS and _CFLAGS should take precedence over pkg-config.

They certainly should - but if you look at the gcc line in the original post, there's tons of -I<something> but the crucial -I/build/libressl/.openssl/include is not.

Something fishy is going on here - did LibreSSL change their API perhaps?

I tend to blaim this more on the side of "after our openssl/pkg-config configure change, we give precedence to pkg-config-provided openssl and ignore the env vars" - so it picks up openssl 1.1 headers and those are known to break.

As much as I like to blaim LibreSSL, the fact that our OpenBSD 6.0 buildslave has no issue with LibreSSL suggests "it's something else"...

I'll find a system with pkg-config and see if I can produce interesting results :)

comment:7 Changed 3 years ago by Gert Döring

oh, to triangulate :-) - @cardioidi: if you have time, could you do a git checkout of commit 7a1b6a0dd706a8189745 and see if that works or breaks for you? That is the commit before the change to configure.ac which changed the OpenSSL check, having quite a few unintended side effects...

Which OS is this, anyway?

comment:8 Changed 3 years ago by Gert Döring

OK, testing myself...

Test 1:

  • gentoo, pkg-config has openssl 1.0.2k
  • libressl 2.5.3 built from source and installed in /usr/local/libressl/
  • git master, calling configure as follows:
../openvpn.git/configure OPENSSL_LIBS="-L/usr/local/libressl/lib -lssl -lcrypto" OPENSSL_CFLAGS="-I/usr/local/libressl/include" --with-crypto-library=openssl
  • configure prints that it found openssl, and the message itself is "what we do if we have not queried pkg-config", so that's generally good...
checking additionally if OpenSSL is available and version >= 1.0.1... ok
  • ... but the build itself is having the right flags set:
gcc -DHAVE_CONFIG_H -I. -I../../../openvpn.git/src/openvpn -I../.. -I../../include  -I../../../openvpn.git/include -I../../../openvpn.git/src/compat   -I/usr/local/libressl/include    -DPLUGIN_LIBDIR=\"/usr/local/lib/openvpn/plugins\"  -g -O2 -std=c99 -MT ssl.o -MD -MP -MF .deps/ssl.Tpo -c -o ssl.o ../../../openvpn.git/src/openvpn/ssl.c
  • and the resulting binary a) works and b) claims "LibreSSL":
$ src/openvpn/openvpn --version
library versions: LibreSSL 2.5.3, LZO 2.09
...
$ ldd src/openvpn/openvpn
        libssl.so.43 => /usr/local/libressl/lib/libssl.so.43 (0x00007fcfae2e3000)
        libcrypto.so.41 => /usr/local/libressl/lib/libcrypto.so.41 (0x00007fcfadf0c000)

Test 2:

  • moving openssl.pc, libssl.pc, libcrypto.pc out of the way (= pkg-config claims there is no openssl installed)
  • doing the same configure call
  • leading to the same results -> libressl-using binary, which works

Test 3:

  • calling configure with no LIBS/CFLAGS options actually has a remarkable difference in output:
checking for OPENSSL... no
checking additionally if OpenSSL is available and version >= 1.0.1... ok

the "checking for OPENSSL..." line is only printed if there are no LIBS/CFLAGS set on the command line (and the "no" bit is "no pkg-config").

Test 4:

  • just to be sure it's not a 2.4.2 weirdness, I repeated test 1 with release 2.4.2 - and the output is indeed a bit different...
../openvpn.git/configure OPENSSL_LIBS="-L/usr/local/libressl/lib -lssl -lcrypto" OPENSSL_CFLAGS="-I/usr/local/libressl/include" --with-crypto-library=openssl
...
checking for pam_start in -lpam... yes
checking for PKCS11_HELPER... no
checking for SSL_CTX_new... yes
checking for EVP_CIPHER_CTX_set_key_length... yes
  • ... note the notable absence of "checking additionally..." here... but building has all the -I there:
gcc -DHAVE_CONFIG_H -I. -I../../../openvpn.git/src/openvpn -I../.. -I../../include  -I../../../openvpn.git/include -I../../../openvpn.git/src/compat   -I/usr/local/libressl/include    -DPLUGIN_LIBDIR=\"/usr/local/lib/openvpn/plugins\"  -g -O2 -std=c99 -MT ssl.o -MD -MP -MF .deps/ssl.Tpo -c -o ssl.o ../../../openvpn.git/src/openvpn/ssl.c
  • and the resulting binary is linked against LibreSSL just fine, again.

So with all these tests, I take back my assumption that "something in our configure is giving precedence to pkg-config vs. OPENSSL_LIBS/OPENSSL_CFLAGS, and assume that something in the original configure call was not exactly like stated above, causing the loss of the specified -I/build/... setting.

The ball is now back at @cardioidi, I think - please double check your configure line, and if that isn't leading anywhere, please attach config.log to this ticket.

comment:9 Changed 3 years ago by Gert Döring

@syzzer: sorry, I was confused about 2.4 vs. master - 2.4 does not have the problematic configure.ac changes, so "nothing new in there" - the issue must indeed come from elsewhere.

comment:10 Changed 3 years ago by Gert Döring

@cardioidi: we'll have to close this ticket unless you can come up with a few answers for us - like "what operating system", "which LibreSSL version" and a copy of config.log

I've done my best to reproduce this, and can't - everything behaves exactly as expected.

comment:11 Changed 3 years ago by Gert Döring

Owner: set to Gert Döring
Status: reopenedaccepted

comment:12 Changed 3 years ago by Gert Döring

Resolution: worksforme
Status: acceptedclosed
Note: See TracTickets for help on using tickets.