ssl - 提升 asio SSL stream.shutdown(ec);总是有错误,即 boost::asio::ssl::error::stream_truncated

标签 ssl visual-c++ boost-asio

我尝试使用 Boost Asio 和 Openssl 将一些 json 发布到 SSL 服务器,我的情况是它总是有问题,当我试图关闭 boost::asio::ssl::error::stream_truncated 问题流,现在我试图忽略这个问题,我不知道我是否应该忽略它或者我做错了什么? boost 版本为 1.68.0,Openssl 版本 1.1.1,VS 2017 CE,Windows 7 x64,

这是我的代码

#include "root_certificates.hpp"
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/error.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <cstdlib>
#include <iostream>
#include <string>
#include <time.h>
#include<fstream>
#include <ctime>
#include <istream>

   int postsslserver()
  {
     try
     {
       auto const host ="mydomain.com";
        auto const port = "https";
        auto const target ="/apps/postpage.html" ;
        retcode = 0;



        setlocale(LC_ALL, "");

        pwmd5hashed = "mysecret";

        std::string jsondata ="\"Double\":12.0000001,";

        int version =11;

         // The io_context is required for all I/O
        boost::asio::io_context ioc;

        // The SSL context is required, and holds certificates
        ssl::context ctx{ ssl::context::sslv23_client };

         //20181021
        ctx.set_default_verify_paths();

        // This holds the root certificate used for verification
        //load_root_certificates(ctx);

         // Verify the remote server's certificate
        //ctx.set_verify_mode(ssl::verify_peer);
        ctx.set_verify_mode(ssl::verify_none);

        // These objects perform our I/O
        tcp::resolver resolver{ ioc };
        ssl::stream<tcp::socket> stream{ ioc, ctx };

       // Set SNI Hostname (many hosts need this to handshake successfully)
       if (!SSL_set_tlsext_host_name(stream.native_handle(), host))
       {
            boost::system::error_code ec{ static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category() };
             throw boost::system::system_error{ ec };
        }

        // Look up the domain name
        auto const results = resolver.resolve(host, port);

        // Make the connection on the IP address we get from a lookup
        boost::asio::connect(stream.next_layer(), results.begin(), results.end());

        // Perform the SSL handshake
        stream.handshake(ssl::stream_base::client);// error always occured this line of code,the error hints was "handshake: certificate verify failed"

         // Set up an HTTP POST request message
        http::request<http::string_body> req{ http::verb::post, target, version };
        req.set(http::field::host, host);
        req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
        req.set(http::field::content_type, "application/json");
        req.set(http::field::body, jsondata);

        // Send the HTTP request to the remote host
        http::write(stream, req);

        // This buffer is used for reading and must be persisted
        boost::beast::flat_buffer buffer;

         // Declare a container to hold the response
         http::response<http::dynamic_body> res;

         // Receive the HTTP response
          http::read(stream, buffer, res);

       // Write the message to standard out
       std::cout << res << std::endl;

       // Gracefully close the stream
        boost::system::error_code ec;
        stream.shutdown(ec);// the problem was here! it always get boost::asio::ssl::error::stream_truncated issue
        if (ec == boost::asio::error::eof)
       {
        // Rationale:

            ec.assign(0, ec.category());
        }
         if (ec!= boost::asio::ssl::error::stream_truncated)//then I tried to ignore it
         {
              std::cout << ec.message()<< endl;
              throw boost::system::system_error{ ec };
          }

        // If we get here then the connection is closed gracefully
    }
   catch (std::exception const& e)
   {
    //std::cerr << "Error: " << e.what() << std::endl;
        write_text_to_log_file(e.what());
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

非常感谢

最佳答案

securely shutdown a SSL socket的正确方法不是直接尝试关闭它。

首先,您必须取消任何可能的未完成操作,然后启动关闭,然后关闭套接字。

这是一个有效解决方案的片段:

virtual void OnClose(boost::system::error_code &ec)
{
    //...
    _socket.lowest_layer().cancel(ec);
    _socket.async_shutdown(std::bind(&Socket<T>::ShutdownHandler, this->shared_from_this(), std::placeholders::_1));
    //...
}

void ShutdownHandler(const boost::system::error_code &ec)
{
    //On async_shutdown both parties send and receive a 'close_notify' message.
    //When the shutdown has been negotiated by both parties, the underlying
    //transport may either be reused or closed.
    //The initiator of the shutdown will enter the shutdown-handler with an
    //error value of eof. (Socket was securely shutdown)
    if (ec && ec != boost::asio::error::eof)
    {
        LogError(ec, Error::ErrorLocation(__FUNCTION__, __LINE__));
    }

    boost::system::error_code ec2;
    _socket.lowest_layer().close(ec2);
    if (ec2)
        LogError(ec2, Error::ErrorLocation(__FUNCTION__, __LINE__));
    _shutdownComplete.exchange(true);
}

还有:boost asio ssl async_shutdown always finishes with an error?

关于ssl - 提升 asio SSL stream.shutdown(ec);总是有错误,即 boost::asio::ssl::error::stream_truncated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52990455/

相关文章:

javascript - 谷歌标签管理器给出混合内容错误

http - 为什么有时我网站地址栏中的 https 会出现斜线?

c++ - Boost Windows 程序是否可以移植到其他 Windows 系统?

c++ - 重用 Asio 连接

c# - 如何获取证书支持的算法列表

C#代理客户端证书

c++ - vector : rend() is being invalidated by erase()

c++ - 是否可以实现 __super 宏?

c - 如何将宽字符串文字与 PRId32、PRIu64 等连接起来?

c++ - 如何使用 boost::asio:write 调用发送 ICU UnicodeString?