in demo_example/asio/asio/ssl/impl/context.ipp [755:833]
ASIO_SYNC_OP_VOID context::use_certificate_chain(
const const_buffer& chain, asio::error_code& ec)
{
::ERR_clear_error();
bio_cleanup bio = { make_buffer_bio(chain) };
if (bio.p)
{
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|| defined(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;
#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
x509_cleanup cert = {
::PEM_read_bio_X509_AUX(bio.p, 0,
callback,
cb_userdata) };
if (!cert.p)
{
ec = asio::error_code(ERR_R_PEM_LIB,
asio::error::get_ssl_category());
ASIO_SYNC_OP_VOID_RETURN(ec);
}
int result = ::SSL_CTX_use_certificate(handle_, cert.p);
if (result == 0 || ::ERR_peek_error() != 0)
{
ec = asio::error_code(
static_cast<int>(::ERR_get_error()),
asio::error::get_ssl_category());
ASIO_SYNC_OP_VOID_RETURN(ec);
}
#if ((OPENSSL_VERSION_NUMBER >= 0x10002000L) \
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|| LIBRESSL_VERSION_NUMBER >= 0x2090100fL)) \
|| defined(ASIO_USE_WOLFSSL)
::SSL_CTX_clear_chain_certs(handle_);
#else
if (handle_->extra_certs)
{
::sk_X509_pop_free(handle_->extra_certs, X509_free);
handle_->extra_certs = 0;
}
#endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L)
while (X509* cacert = ::PEM_read_bio_X509(bio.p, 0,
callback,
cb_userdata))
{
if (!::SSL_CTX_add_extra_chain_cert(handle_, cacert))
{
ec = asio::error_code(
static_cast<int>(::ERR_get_error()),
asio::error::get_ssl_category());
ASIO_SYNC_OP_VOID_RETURN(ec);
}
}
result = ::ERR_peek_last_error();
if ((ERR_GET_LIB(result) == ERR_LIB_PEM)
&& (ERR_GET_REASON(result) == PEM_R_NO_START_LINE))
{
::ERR_clear_error();
ec = asio::error_code();
ASIO_SYNC_OP_VOID_RETURN(ec);
}
}
ec = asio::error_code(
static_cast<int>(::ERR_get_error()),
asio::error::get_ssl_category());
ASIO_SYNC_OP_VOID_RETURN(ec);
}