|
|
|
|
@@ -3,7 +3,7 @@
|
|
|
|
|
// ~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
//
|
|
|
|
|
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
|
|
|
|
// Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
|
|
|
|
// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
|
|
|
|
//
|
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
|
@@ -48,6 +48,7 @@ struct context::evp_pkey_cleanup
|
|
|
|
|
~evp_pkey_cleanup() { if (p) ::EVP_PKEY_free(p); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
|
|
|
|
struct context::rsa_cleanup
|
|
|
|
|
{
|
|
|
|
|
RSA* p;
|
|
|
|
|
@@ -59,6 +60,7 @@ struct context::dh_cleanup
|
|
|
|
|
DH* p;
|
|
|
|
|
~dh_cleanup() { if (p) ::DH_free(p); }
|
|
|
|
|
};
|
|
|
|
|
#endif // (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
|
|
|
|
|
|
|
|
|
context::context(context::method m)
|
|
|
|
|
: handle_(0)
|
|
|
|
|
@@ -358,15 +360,23 @@ context::context(context::method m)
|
|
|
|
|
|
|
|
|
|
if (handle_ == 0)
|
|
|
|
|
{
|
|
|
|
|
boost::system::error_code ec(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
boost::system::error_code ec = translate_error(::ERR_get_error());
|
|
|
|
|
boost::asio::detail::throw_error(ec, "context");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set_options(no_compression);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
context::context(context::native_handle_type native_handle)
|
|
|
|
|
: handle_(native_handle)
|
|
|
|
|
{
|
|
|
|
|
if (!handle_)
|
|
|
|
|
{
|
|
|
|
|
boost::asio::detail::throw_error(
|
|
|
|
|
boost::asio::error::invalid_argument, "context");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
|
|
|
|
context::context(context&& other)
|
|
|
|
|
{
|
|
|
|
|
@@ -387,7 +397,10 @@ context::~context()
|
|
|
|
|
{
|
|
|
|
|
if (handle_)
|
|
|
|
|
{
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
|
|
|
|
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
|
|
|
|
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
|
|
|
|
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
|
|
|
|
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
|
|
|
|
void* cb_userdata = handle_->default_passwd_callback_userdata;
|
|
|
|
|
@@ -398,7 +411,10 @@ context::~context()
|
|
|
|
|
static_cast<detail::password_callback_base*>(
|
|
|
|
|
cb_userdata);
|
|
|
|
|
delete callback;
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
|
|
|
|
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
|
|
|
|
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
|
|
|
|
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
|
|
|
|
::SSL_CTX_set_default_passwd_cb_userdata(handle_, 0);
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
|
|
|
|
handle_->default_passwd_callback_userdata = 0;
|
|
|
|
|
@@ -530,9 +546,7 @@ BOOST_ASIO_SYNC_OP_VOID context::load_verify_file(
|
|
|
|
|
|
|
|
|
|
if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -557,17 +571,23 @@ BOOST_ASIO_SYNC_OP_VOID context::add_certificate_authority(
|
|
|
|
|
{
|
|
|
|
|
if (X509_STORE* store = ::SSL_CTX_get_cert_store(handle_))
|
|
|
|
|
{
|
|
|
|
|
for (;;)
|
|
|
|
|
for (bool added = false;; added = true)
|
|
|
|
|
{
|
|
|
|
|
x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) };
|
|
|
|
|
if (!cert.p)
|
|
|
|
|
break;
|
|
|
|
|
{
|
|
|
|
|
unsigned long err = ::ERR_get_error();
|
|
|
|
|
if (added && ERR_GET_LIB(err) == ERR_LIB_PEM
|
|
|
|
|
&& ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ec = translate_error(err);
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (::X509_STORE_add_cert(store, cert.p) != 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -592,9 +612,7 @@ BOOST_ASIO_SYNC_OP_VOID context::set_default_verify_paths(
|
|
|
|
|
|
|
|
|
|
if (::SSL_CTX_set_default_verify_paths(handle_) != 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -616,9 +634,7 @@ BOOST_ASIO_SYNC_OP_VOID context::add_verify_path(
|
|
|
|
|
|
|
|
|
|
if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -672,9 +688,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate(
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -710,9 +724,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_file(
|
|
|
|
|
|
|
|
|
|
if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -735,7 +747,10 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
|
|
|
|
bio_cleanup bio = { make_buffer_bio(chain) };
|
|
|
|
|
if (bio.p)
|
|
|
|
|
{
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
|
|
|
|
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
|
|
|
|
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
|
|
|
|
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
|
|
|
|
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
|
|
|
|
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
|
|
|
|
@@ -748,21 +763,21 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
|
|
|
|
cb_userdata) };
|
|
|
|
|
if (!cert.p)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(ERR_R_PEM_LIB,
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(ERR_R_PEM_LIB);
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int result = ::SSL_CTX_use_certificate(handle_, cert.p);
|
|
|
|
|
if (result == 0 || ::ERR_peek_error() != 0)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
|
|
|
|
#if ((OPENSSL_VERSION_NUMBER >= 0x10002000L) \
|
|
|
|
|
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| LIBRESSL_VERSION_NUMBER >= 0x2090100fL)) \
|
|
|
|
|
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
|
|
|
|
::SSL_CTX_clear_chain_certs(handle_);
|
|
|
|
|
#else
|
|
|
|
|
if (handle_->extra_certs)
|
|
|
|
|
@@ -778,9 +793,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
|
|
|
|
{
|
|
|
|
|
if (!::SSL_CTX_add_extra_chain_cert(handle_, cacert))
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -795,9 +808,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -815,9 +826,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain_file(
|
|
|
|
|
|
|
|
|
|
if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -839,7 +848,10 @@ BOOST_ASIO_SYNC_OP_VOID context::use_private_key(
|
|
|
|
|
{
|
|
|
|
|
::ERR_clear_error();
|
|
|
|
|
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
|
|
|
|
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
|
|
|
|
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
|
|
|
|
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
|
|
|
|
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
|
|
|
|
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
|
|
|
|
@@ -878,9 +890,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_private_key(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -906,17 +916,55 @@ BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key(
|
|
|
|
|
{
|
|
|
|
|
::ERR_clear_error();
|
|
|
|
|
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
|
|
|
|
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
|
|
|
|
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
|
|
|
|
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
|
|
|
|
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
|
|
|
|
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
|
|
|
|
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
|
|
|
|
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
|
|
|
|
pem_password_cb* callback = handle_->default_passwd_callback;
|
|
|
|
|
void* cb_userdata = handle_->default_passwd_callback_userdata;
|
|
|
|
|
pem_password_cb* callback = handle_->default_passwd_callback;
|
|
|
|
|
void* cb_userdata = handle_->default_passwd_callback_userdata;
|
|
|
|
|
#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
|
|
|
|
|
|
|
|
|
bio_cleanup bio = { make_buffer_bio(private_key) };
|
|
|
|
|
if (bio.p)
|
|
|
|
|
{
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
evp_pkey_cleanup evp_private_key = { 0 };
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
case context_base::asn1:
|
|
|
|
|
evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0);
|
|
|
|
|
break;
|
|
|
|
|
case context_base::pem:
|
|
|
|
|
evp_private_key.p = ::PEM_read_bio_PrivateKey(
|
|
|
|
|
bio.p, 0, callback,
|
|
|
|
|
cb_userdata);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
ec = boost::asio::error::invalid_argument;
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (evp_private_key.p)
|
|
|
|
|
{
|
|
|
|
|
if (::EVP_PKEY_is_a(evp_private_key.p, "RSA") == 0)
|
|
|
|
|
{
|
|
|
|
|
ec = translate_error(
|
|
|
|
|
ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY));
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code();
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
rsa_cleanup rsa_private_key = { 0 };
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
@@ -943,11 +991,10 @@ BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key(
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -975,9 +1022,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_private_key_file(
|
|
|
|
|
|
|
|
|
|
if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -997,6 +1042,53 @@ BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key_file(
|
|
|
|
|
const std::string& filename, context::file_format format,
|
|
|
|
|
boost::system::error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
::ERR_clear_error();
|
|
|
|
|
|
|
|
|
|
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
|
|
|
|
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
|
|
|
|
|
|
|
|
|
bio_cleanup bio = { ::BIO_new_file(filename.c_str(), "r") };
|
|
|
|
|
if (bio.p)
|
|
|
|
|
{
|
|
|
|
|
evp_pkey_cleanup evp_private_key = { 0 };
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
case context_base::asn1:
|
|
|
|
|
evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0);
|
|
|
|
|
break;
|
|
|
|
|
case context_base::pem:
|
|
|
|
|
evp_private_key.p = ::PEM_read_bio_PrivateKey(
|
|
|
|
|
bio.p, 0, callback,
|
|
|
|
|
cb_userdata);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
ec = boost::asio::error::invalid_argument;
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (evp_private_key.p)
|
|
|
|
|
{
|
|
|
|
|
if (::EVP_PKEY_is_a(evp_private_key.p, "RSA") == 0)
|
|
|
|
|
{
|
|
|
|
|
ec = translate_error(
|
|
|
|
|
ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY));
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code();
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
int file_type;
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
@@ -1018,14 +1110,13 @@ BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key_file(
|
|
|
|
|
if (::SSL_CTX_use_RSAPrivateKey_file(
|
|
|
|
|
handle_, filename.c_str(), file_type) != 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec = boost::system::error_code();
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
#endif // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void context::use_tmp_dh(const const_buffer& dh)
|
|
|
|
|
@@ -1046,9 +1137,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_tmp_dh(
|
|
|
|
|
return do_use_tmp_dh(bio.p, ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1070,9 +1159,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_tmp_dh_file(
|
|
|
|
|
return do_use_tmp_dh(bio.p, ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1081,6 +1168,19 @@ BOOST_ASIO_SYNC_OP_VOID context::do_use_tmp_dh(
|
|
|
|
|
{
|
|
|
|
|
::ERR_clear_error();
|
|
|
|
|
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
EVP_PKEY* p = ::PEM_read_bio_Parameters(bio, 0);
|
|
|
|
|
if (p)
|
|
|
|
|
{
|
|
|
|
|
if (::SSL_CTX_set0_tmp_dh_pkey(handle_, p) == 1)
|
|
|
|
|
{
|
|
|
|
|
ec = boost::system::error_code();
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
::EVP_PKEY_free(p);
|
|
|
|
|
}
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
dh_cleanup dh = { ::PEM_read_bio_DHparams(bio, 0, 0, 0) };
|
|
|
|
|
if (dh.p)
|
|
|
|
|
{
|
|
|
|
|
@@ -1090,10 +1190,9 @@ BOOST_ASIO_SYNC_OP_VOID context::do_use_tmp_dh(
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
|
|
|
|
|
ec = boost::system::error_code(
|
|
|
|
|
static_cast<int>(::ERR_get_error()),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
ec = translate_error(::ERR_get_error());
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1145,7 +1244,10 @@ int context::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
|
|
|
|
|
BOOST_ASIO_SYNC_OP_VOID context::do_set_password_callback(
|
|
|
|
|
detail::password_callback_base* callback, boost::system::error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
|
|
|
|
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
|
|
|
|
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
|
|
|
|
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
|
|
|
|
void* old_callback = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
|
|
|
|
::SSL_CTX_set_default_passwd_cb_userdata(handle_, callback);
|
|
|
|
|
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
|
|
|
|
@@ -1197,6 +1299,21 @@ BIO* context::make_buffer_bio(const const_buffer& b)
|
|
|
|
|
static_cast<int>(b.size()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boost::system::error_code context::translate_error(long error)
|
|
|
|
|
{
|
|
|
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
if (ERR_SYSTEM_ERROR(error))
|
|
|
|
|
{
|
|
|
|
|
return boost::system::error_code(
|
|
|
|
|
static_cast<int>(ERR_GET_REASON(error)),
|
|
|
|
|
boost::asio::error::get_system_category());
|
|
|
|
|
}
|
|
|
|
|
#endif // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
|
|
|
|
|
|
|
|
|
return boost::system::error_code(static_cast<int>(error),
|
|
|
|
|
boost::asio::error::get_ssl_category());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace ssl
|
|
|
|
|
} // namespace asio
|
|
|
|
|
} // namespace boost
|
|
|
|
|
|