看起来 boost 只使用了 OpenSSL 接口。我对 boost 了解不多,但我已经为 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
如果您以这种方式设置 verify_mode ,它将根据配置的受信任 CA(使用ctx.load_verify_file
或设置ctx.load_verify_path
)验证证书。
如果您对签署证书的 CA(即您自己的 CA)具有完全控制权,那么您接受该 CA 签署的任何证书可能就足够了。但是,如果您使用的 CA 还签署了您不想接受的证书,就像通常使用公共 CA 的情况一样,您还需要验证证书的内容。具体如何执行此操作取决于您的协议,但对于 HTTP 或 SMTP 等常用 Internet 协议,这涉及检查证书的 commonName 和/或 subjectAltNames。通配符处理等细节因协议而异。
Boost 提供rfc2818_verification来帮助您进行 HTTP 样式的验证,尽管从阅读代码中我认为实现有点错误(接受多个通配符,允许 IDN 通配符 - 参见 RFC6125 的要求)。
我不知道验证客户端证书的任何标准。通常只接受由特定(私有)CA 签署的任何证书。其他时候来自公共 CA 的证书与特定的电子邮件模式匹配。在这种情况下,boost 似乎对您没有多大帮助,因此您可能必须获取 OpenSSLSSL*
句柄,sock.native_handle()
然后使用 OpenSSL 函数来提取证书(SSL_get_peer_certificate
)并检查证书的内容(各种X509_*
函数)。
至少如果涉及公共 CA,您还应该检查证书的吊销状态。看起来 boost 没有提供与 CRL(证书撤销列表)的直接接口,因此您必须使用ctx.native_handle()
适当的 OpenSSL 函数(X509_STORE_add_crl
等)。使用 OCSP(在线状态撤销协议)要复杂得多,而且相关的 OpenSSL 功能大多没有记录,这意味着您必须阅读 OpenSSL 源代码才能使用它们:(