提升asio SSL双向认证

use*_*577 2 c++ ssl boost boost-asio mutual-authentication

我需要一段代码,用于我正在编写的程序Boost Asio SSL.我有一个由两个客户组成的系统,它们相互连接.我要求他们进行相互身份验证,因此,在handshake()命令结束时,两个客户端都可以确定其他客户端具有其提供的证书的私钥.两个客户端有一个context对象,让我们打电话给他们ctx1,并ctx2和每个客户端有一个公共的证书和私钥.

是否可以设置上下文对象,当我调用socket.handshake()客户端时将执行双向身份验证.如果没有,那么实现目标的正确方法是什么?

Ste*_*ich 9

看起来boost只使用OpenSSL接口.我不太了解提升但我已经为Perl实现了许多OpenSSL内部结构,并在阅读了boost源代码的相关部分后得出以下结论:

要与OpenSSL进行相互身份验证,您必须SSL_VERIFY_PEER在客户端和SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT服务器端使用.如果仅SSL_VERIFY_PEER在服务器端使用它,它只会将证书请求发送到客户端,但如果客户端不发送任何证书,则静默接受.

有了提升,这可能是:

ctx.set_verify_mode(ssl::verify_peer); // client side
ctx.set_verify_mode(ssl::verify_peer|ssl::verify_fail_if_no_peer_cert); // server side
Run Code Online (Sandbox Code Playgroud)

如果以这种方式设置verify_mode,它将根据配置的可信CA(使用ctx.load_verify_file或设置ctx.load_verify_path)验证证书.

如果您完全控制签署证书的CA(即其自己的CA),则可能足以接受此CA签署的任何证书.但是,如果您使用的CA也签署了您不想接受的证书(例如公共CA的情况),则还需要验证证书的内容.详细说明如何执行此操作取决于您的协议,但对于通常的Internet协议(如HTTP或SMTP),这涉及检查证书的commonName和/或subjectAltNames.诸如通配符处理之类的细节因协议而异.

Boost提供rfc2818_verification来帮助您进行HTTP样式验证,尽管从阅读代码我认为实现略有错误(接受多个通配符,允许IDN通配符 - 请参阅RFC6125以了解要求).

我不知道验证客户证书的任何标准.通常只接受由特定(私人)CA签署的任何证书.其他时候来自公共CA的证书与特定电子邮件模式匹配.在这种情况下看起来boost对你没什么帮助,所以你可能必须得到OpenSSL SSL*句柄sock.native_handle()然后使用OpenSSL函数来提取certificate(SSL_get_peer_certificate)并检查证书的内容(各种X509_*函数).

至少如果涉及公共CA,您还应检查证书的撤销状态.看起来boost不提供CRL(证书撤销列表)的直接接口,因此您必须使用ctx.native_handle()适当的OpenSSL函数(X509_STORE_add_crl等).使用OCSP(在线状态撤销协议)是更复杂和相关的OpenSSL功能大多数未记录,这意味着你必须阅读OpenSSL源代码使用它们:(