c - OpenSSL 向具有证书颁发机构的客户端提供服务器证书



我正在尝试学习如何使用 OpenSSL 库(完全是新手),并且在弄清楚如何让客户端连接到具有正确证书的服务器时遇到了一些麻烦,如果证书不正确,则失败。我的用例是构建一个没有中央 CA 的 p2p 应用程序,所以我不能依赖 CA 证书。具体来说,服务器像往常一样有一个证书/密钥,客户端将通过要求其他 p2p 节点投票来确定服务器的证书。

我有两个具体问题:

  • 在下面的代码片段中,我希望客户端不会连接,如果我注释掉"密码列表"下面的选择。它仍然有效!我错过了什么,对吧?
  • 有没有办法让客户端使用服务器证书,并且足以打开连接?即没有密钥,没有 CA?

客户:

ctx = SSL_CTX_new(DTLSv1_client_method());
SSL_CTX_set_cipher_list(ctx, "HIGH:!DSS:!aNULL@STRENGTH");
// If I comment out below stuff, client still connects happily!?
if (!SSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem", SSL_FILETYPE_PEM))
    printf("nERROR: no certificate found!");
if (!SSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem", SSL_FILETYPE_PEM))
    printf("nERROR: no private key found!");
if (!SSL_CTX_check_private_key (ctx))
    printf("nERROR: invalid private key!");

服务器:

SSL_CTX_set_cipher_list(ctx, "HIGH:!DSS:!aNULL@STRENGTH"); // high strength ciphers
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
if (!SSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem", SSL_FILETYPE_PEM))
    printf("nERROR: no certificate found!");
if (!SSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem", SSL_FILETYPE_PEM))
    printf("nERROR: no private key found!");
if (!SSL_CTX_check_private_key (ctx))
    printf("nERROR: invalid private key!");

我的代码是 https://github.com/a34729t/exp/tree/master/tun2udp/dtls 的;它是由Robin Seggelmann的DTLS示例构建的。具体来说,我正在与server3_oo.c合作。

SSL/TLS 可以在不同的模式下运行。最常见的模式是仅服务器身份验证,其中只有服务器具有证书和密钥。然后是相互身份验证模式,也称为客户端身份验证,其中客户端还具有(客户端)证书和密钥。然后是完全匿名的模式,其中服务器和客户端都不进行身份验证,也不需要证书和密钥。

除非您另行告知 OpenSSL,否则它将在仅服务器身份验证模式下运行。 在此模式下,客户端中的这些行:

if (!SSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem", SSL_FILETYPE_PEM))
    printf("nERROR: no certificate found!");
if (!SSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem", SSL_FILETYPE_PEM))
    printf("nERROR: no private key found!");
将导致客户端加载客户端证书

(顺便说一句,您永远不必在客户端中加载服务器证书和密钥)。 但是,由于服务器不要求客户端提供证书,因此客户端永远不会提供证书。 注释掉这些行会使客户端不加载任何客户端证书,这没有区别,因为它们无论如何都不会被使用。

要使服务器向客户端请求证书,并让服务器拒绝连接(如果未显示任何证书),您必须像这样告诉服务器(省略错误处理):

SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);

SSL_VERIFY_PEER使服务器请求客户端证书,SSL_VERIFY_FAIL_IF_NO_PEER_CERT客户端未提供证书时会导致服务器中止连接(请参阅文档)。 如果不使用后一个选项,则可以自行检查客户端是否使用 SSL_get_peer_certificate 函数发送了证书。

相关内容

最新更新