LibreSSL と Boost.ASIO.SSL を組み合わせて使う事になった場合に ::SSL_CTX_get_default_passwd_cb_userdata 等複数箇所で翻訳時エラーが生じてしまう場合の応急対処法
問題
LibreSSL と Boost.ASIO.SSL を組み合わせて使う事になった場合に ::SSL_CTX_get_default_passwd_cb_userdata
等複数箇所で翻訳時エラーが生じてしまう。
発生条件
以下の組み合わせにより発生する。
-
LibreSSL を使用したい
- 執筆時点の最新版は 2.5.0, 2.4.4 、あるいはそれ以降も対応されない可能性あり。
-
Boost.ASIO.SSL を使用したい。
- Boost-1.61以降執筆現在最新1.63まで、あるいはそれ以降も対応されない可能性あり。
現象
翻訳時エラーが発生する。Boost.ASIO.SSL
...include/boost/asio/ssl/impl/context.ipp: In destructor 'boost::asio::ssl::context::~context()':
.../include/boost/asio/ssl/impl/context.ipp:232:25: error: '::SSL_CTX_get_default_passwd_cb_userdata' has not been declared
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
^~
類似のエラーが大量に発生する。
原因
Boost.ASIO.SSL の以下のコミットから asio/ssl/impl/context.hpp
などのソースコード複数について OPENSSL_VERSION_NUMBER
によるプリプロセッサーレベルの分岐処理が導入され、 OpenSSL-1.1 系の API への対応が追加された。
- asio/ssl/impl/context.hpp
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
void* cb_userdata = handle_->default_passwd_callback_userdata;
#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
- asio/ssl/detail/impl/openssl_init.hpp
#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) \
&& (OPENSSL_VERSION_NUMBER < 0x10100000L)
::SSL_COMP_free_compression_methods();
#endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L)
OpenSSL では OPENSSL_VERSION_NUMBER
は 0x10100000L
未満か否かによって OpenSSL-1.1 系の API を使用可能か判別できる。
# define OPENSSL_VERSION_NUMBER 0x10100040L
# ifdef OPENSSL_FIPS
# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.0d-fips-dev xx XXX xxxx"
# else
# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.0d-dev xx XXX xxxx"
# endif
一方、 LibreSSL-2.4/2.5 系では openssl/opensslv.h
で OPENSSL_VERSION_NUMBER
を 0x20000000L
と LibreSSL または互換の OpenSSL の API とは連動せず固定値で定義している。
/* These will never change */
#define OPENSSL_VERSION_NUMBER 0x20000000L
#define OPENSSL_VERSION_TEXT LIBRESSL_VERSION_TEXT
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
また、 LibreSSL-2.4/2.5 は OpenSSL-1.1 系の API に対応していない。
よって、 LibreSSL-2.4/2.5 と Boost-1.61/1.62/1.63.ASIO.SSL を組み合わせると、 Boost.ASIO.SSL のソースコード中から OpenSSL-1.1 系の API を使用するコードがプリプロセッサーレベルで有効となり、 OpenSSL-1.1 系の API に未対応の LibreSSL-2.4/2.5 ではその API が未定義で使用できないため、翻訳時エラーとなる。
余談: LibreSSL のバージョン情報
原因と直接は関係しないが、 LibreSSL のバージョン情報をプリプロセッサーで取得したい場合は、 openssl/opensslv.h
に次の LibreSSL 独自の定義が追加されているのでこちらを使用できる。
#define LIBRESSL_VERSION_NUMBER 0x2030200fL
#define LIBRESSL_VERSION_TEXT "LibreSSL 2.3.2"
応急対処法
Boost.ASIO.SSL のヘッダーインクルード前後で OPENSSL_VERSION_NUMBER
を偽装する事で比較的簡単に応急対処できる。
/// @brief LibreSSL と Boost.ASIO.SSL の OpenSSL-1.1 API 対応判定の偽装処理
/// @ref http://qiita.com/usagi/items/acee410849ca8f4f9c11
/// @{
#if LIBRESSL_VERSION_NUMBER <= 0x2050100fL
#include <openssl/opensslv.h>
#undef OPENSSL_VERSION_NUMBER
#define OPENSSL_VERSION_NUMBER 0x10001fffL
#endif
/// @}
#include <boost/asio/ssl.hpp>
注意
- この記事で紹介する対処方法は「応急」である事を理解して施し、適切な保守を行う必要がある。
Author And Source
この問題について(LibreSSL と Boost.ASIO.SSL を組み合わせて使う事になった場合に ::SSL_CTX_get_default_passwd_cb_userdata 等複数箇所で翻訳時エラーが生じてしまう場合の応急対処法), 我々は、より多くの情報をここで見つけました https://qiita.com/usagi/items/acee410849ca8f4f9c11著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .