提升Asio SSL客户端握手问题

时间:2014-05-08 13:59:31

标签: ssl boost boost-asio handshake

我一直在尝试实施一个非常基本的Boost SSL实现来尝试和学习基础知识。我想要与之通信的服务器已经以纯文本形式向我提供了他们的公钥。我已经在其中放了很多其他代码(异步连接,握手等)。

我首先尝试使用Boost SSL流的以下设置实现SSL而不验证其证书:

boost::asio::ssl::context ctxt(boost::asio::ssl::context::sslv23);
ctxt.set_verify_mode(boost::asio::ssl::verify_none);

此实现工作正常,我能够与服务器连接。但是,当我尝试实施对等证书的验证时,握手失败。我尝试使用以下代码:

boost::asio::ssl::context ctxt(boost::asio::ssl::context::sslv23);
ctxt.set_verify_mode(boost::asio::ssl::verify_peer);
ctxt.load_verify_file("peer.crt");

我把包含公钥的“peer.crt”(连同----- BEGIN CERTIFICATE -----和----- END CERTIFICATE -----标签)放在目录中我在运行我的可执行文件。无论出于何种原因,握手现在都失败,错误代码为336134278:证书验证失败。我也尝试将验证文件的完整路径放在那里,但没有运气。

我的问题如下:

  1. 我应该在load_verify_file中指定验证文件的文件名?它只是在我运行可执行文件的目录中吗?
  2. 我没有正确设置对等验证的握手过程吗?我没有自己的验证回调,因为我认为如果我这样指定对等验证会自动发生。
  3. 我应该通过安装或类似的方式以某种方式处理证书吗?
  4. 有没有更好的方法来调试此功能?我正在使用VS10并且只能访问ipp,因此我实际上无法查看正在进行的验证。
  5. 感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:2)

  1. 您应该可以使用相对路径或绝对路径。
  2. 您对set_verify_mode()load_verify_file()的使用看起来很不错。我在自己的代码中完成了这个。如果未指定,则使用默认验证回调。
  3. 您不需要"安装"证书。
  4. 我不知道调试boost::asio SSL连接的简单方法,但您可以使用OpenSSL命令行工具(例如s_client)来测试连接。 boost::asio使用OpenSSL。
  5. 我怀疑您的文件中没有完整的证书证书链。您可以使用服务器和端口替换www.google.com:443从服务器中提取它们:

    openssl s_client -connect www.google.com:443 -showcerts
    

    如果您只想查看部分证书,例如只有叶证书,你可以使用自己的验证回调。自定义回调的示例以及验证模式和选项的说明位于this page

答案 1 :(得分:0)

一个好的起点是asio examples中的HTTP客户端。

您是否使用回调函数调用套接字上的set_verify_callback来验证证书? E.g:

bool verify_certificate(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);
  return preverified;
}