Boost Beast Websocket 在连接时多次验证客户端证书

问题描述 投票:0回答:1

我有一个基于 Boost Beast asio 的 websocket 服务器,它(以缩写形式)像这样启动

ssl_context_.set_options(
    boost::asio::ssl::context::default_workarounds |
    boost::asio::ssl::context::no_sslv2            |
    boost::asio::ssl::context::no_sslv3            |
    boost::asio::ssl::context::no_tlsv1            |
    boost::asio::ssl::context::no_tlsv1_1
    );

ssl_context_.use_certificate_file(
    auth->server_cert,
    boost::asio::ssl::context::file_format::pem
    );

ssl_context_.use_private_key_file(
    auth->server_key,
    boost::asio::ssl::context::file_format::pem
    );

ssl_context_.load_verify_file(auth->ca);

ssl_context_.set_verify_mode(
    boost::asio::ssl::verify_peer |
    boost::asio::ssl::verify_fail_if_no_peer_cert
    );

ssl_context_.set_verify_callback(
    std::bind(
      &verify_certificate_cb, std::placeholders::_1, std::placeholders::_2
      )
    );
    
try
{
  const boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::make_address(ip), port);
  acceptor_.open(endpoint.protocol());
  acceptor_.set_option(boost::asio::socket_base::reuse_address(true));
  acceptor_.bind(endpoint);
  acceptor_.listen();
}
catch(const boost::system::system_error &e)
{
  LOG_ERROR("Acceptor error: " << e.what());
  return;
}
 
acceptor_.async_accept(io_context_, boost::beast::bind_front_handler(&server::accept_handler, this));

然后,我有

static bool verify_certificate_cb(bool preverified, boost::asio::ssl::verify_context& ctx)
{
  char subject_name[256];
  X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
  X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
  LOG_INFO("TLS connection verification for: " << subject_name);
  return preverified;
}

void server::accept_handler(const boost::system::error_code& error, boost::asio::ip::tcp::socket socket) noexcept
{
  if (!error)
  {
    // Using Boost's asio paradigm, websocket binds its completion handlers to a shared ptr of this object.
    // This allows the object to extend its lifetime beyond this scope until it's operations are done.
    // Once the all async operations are done, no reference remains, finally ending the lifetime of this object.
    const auto ws(std::make_shared<websocket>(std::move(socket), ssl_context_, auth_));
    
    // Initiate websocket handshake
    ws->handshake();

    // Continue with accepting the next available connection
    acceptor_.async_accept(io_context_, boost::beast::bind_front_handler(&server::accept_handler, this));
  }
  else
  {
    LOG_ERROR("Acceptor error: " << error.message());
  }
}

这对于在初始连接时验证客户端证书非常有用。问题是这个 websocket 服务器期望客户端连接很长时间,可能比客户端证书的有效期更长。换句话说,我需要在初始连接建立后定期重新检查客户端证书。最好的方法是什么?

c++ ssl boost boost-asio boost-beast-websocket
1个回答
0
投票

要在连接上多次验证客户端证书,您可以实现自定义验证回调,在每次握手时检查证书。确保正确处理连接状态以避免出现问题。

© www.soinside.com 2019 - 2024. All rights reserved.