ASIO_SYNC_OP_VOID context::use_certificate_chain()

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);
}