从源代码构建curl - 对SSL_CTX_set_alpn_protos的未定义引用

时间:2016-04-04 13:44:00

标签: curl build openssl

我对这些工具不是很有经验,所以请耐心等待。我想从源代码构建带有SSL的curl。为此,我还要从源代码编译OpenSSL

在构建和安装OpenSSL之后,将创建存档文件。然后解压缩此tar,并在构建curl时使用。

我这样做的方式是:

OpenSSL的

./config shared -fPIC --prefix="/some/path/install_dir"
make depend
make && make install

rm -rf /some/path/install_dir/lib/pkgconfig
# create tar from $prefix/bin $prefix/include $prefix/lib

pkgconfig被删除了,因为当我把它放在那里时,它包含了openssl-building机器上的库的绝对路径,这可能与curl-building机器不同,我只想使用归档中的库。 我不知道这是否是正确的做法。

卷曲

复制并解压缩上一步中的存档。然后

export LIBS='-ldl'
./configure --prefix="$(pwd)/<install_dir>" --with-ssl="<unpacked-tar>"
make && make install

但是,make会导致:

../lib/.libs/libcurl.so: undefined reference to `SSL_CTX_set_alpn_protos'
../lib/.libs/libcurl.so: undefined reference to `SSL_get0_alpn_selected'

在同一台(测试)机器上构建openssl和curl。

使用openssl-1.0.2gcurl-7.47.1。知道什么可能是错的吗?

curl 的config.log包含如下编译命令:

gcc -o conftest -O2 -Wno-system-headers  -I/home/teamcity/buildAgent/work/10199cb4c61825f3/openssl-1.0.2g/include -I/home/teamcity/buildAgent/work/10199cb4c61825f3/openssl-1.0.2g/include/openssl  -L/home/teamcity/buildAgent/work/10199cb4c61825f3/openssl-1.0.2g/lib conftest.c -lcrypto  -lz -lrt -ldl >&5

-I 文件夹是我想要包含的文件夹,所以我认为不应该使用系统范围的库。

搜索NPNPROT没有产生任何结果,因此未禁用协商。

1 个答案:

答案 0 :(得分:1)

The archive from the previous step is copied and unpacked ... Building both openssl and curl on the same (testing) machine works.

It sounds like OpenSSL on the build machine has Next Protocol Negotiation enabled, but the destination machine's OpenSSL was built without Next Protocol Negotiation. For OpenSSL 1.1.0, I believe that means the build machine was configured with no-nextprotoneg. For OpenSSL 1.0.2 and below, I believe that means it was configured with no-npn.


SSL_CTX_set_alpn_protos is part of OpenSSL 1.1.0. The .pod is important because it means its documented, so its a public function meant to be called by user programs (this is a policy change for 1.1.0):

$ cd openssl-master
$ grep -IR SSL_CTX_set_alpn_protos * | egrep '(ssl.h|.pod)'
doc/ssl/SSL_CTX_set_alpn_select_cb.pod:SSL_CTX_set_alpn_protos, SSL_set_alpn_protos, SSL_CTX_set_alpn_select_cb,
doc/ssl/SSL_CTX_set_alpn_select_cb.pod: int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
doc/ssl/SSL_CTX_set_alpn_select_cb.pod:SSL_CTX_set_alpn_protos() and SSL_set_alpn_protos() are used by the client to
doc/ssl/SSL_CTX_set_alpn_select_cb.pod:SSL_CTX_set_alpn_protos() and SSL_set_alpn_protos() return 0 on success, and
include/openssl/ssl.h:__owur int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,

Its also available in 1.0.2:

$ cd openssl-1.0.2g
$ grep -IR SSL_CTX_set_alpn_protos *
apps/s_client.c:        SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
ssl/ssl.h:int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
ssl/ssl_lib.c: * SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
ssl/ssl_lib.c:int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
ssl/ssltest.c:        SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len);
util/ssleay.num:SSL_CTX_set_alpn_protos                 387 EXIST::FUNCTION:

My guess is that cURL is using a downlevel, distro provided OpenSSL that lacks protocol negotiations (like OpenSSL 0.9.8):

export LIBS='-ldl'
./configure --prefix="$(pwd)/<install_dir>" --with-ssl="<unpacked-tar>"
make && make install

Check the config.log to see what cURL is finding during configuration.


You can disable protocol negotiations in OpenSSL with:

  • OpenSSL 1.0.2 - no-npn
  • OpenSSL 1.1.0 - no-nextprotoneg

It will show up in <openssl/opensslconf.h:

$ cd openssl-master
$ ./config no-nextprotoneg
...

$ find $PWD -name 'opensslconf.h'
.../include/openssl/opensslconf.h
$ cat .../include/openssl/opensslconf.h | grep PROT
#ifndef OPENSSL_NO_NEXTPROTONEG
# define OPENSSL_NO_NEXTPROTONEG

And:

$ cd openssl-1.0.2g
$ ./config no-npn
...

$ cat include/openssl/opensslconf.h | grep NPN
#ifndef OPENSSL_NO_NPN
# define OPENSSL_NO_NPN
# if defined(OPENSSL_NO_NPN) && !defined(NO_NPN)
#  define NO_NPN

So you should also verify it was not disabled at build time.


It looks like cURL is not completely sympathetic to no-npn and no-nextprotoneg:

$ git clone https://github.com/curl/curl.git
$ cd curl/
$ egrep -IR '(OPENSSL_NO_NPN|OPENSSL_NO_NEXTPROTONEG)' *
lib/vtls/openssl.c:    && !defined(OPENSSL_NO_NEXTPROTONEG)

That's also the only hit for SSL_CTX_set_alpn_protos:

$ grep -IR SSL_CTX_set_alpn_protos *
lib/vtls/openssl.c:    SSL_CTX_set_alpn_protos(connssl->ctx, protocols, cur)
相关问题