2013-01-22 77 views
1

我想了解如何使用OpenSSL库(总newb),并且在确定如何让客户端连接到具有正确证书的服务器时遇到一些问题,并且如果证书不正确,将会失败。我的用例是建立一个没有中央CA的p2p应用程序,所以我不能依赖CA证书。具体来说,服务器像往常一样拥有证书/密钥,客户端将通过要求其他P2P节点投票来确定服务器的证书。OpenSSL向证书颁发机构颁发服务器证书给客户端?

我有两个具体的问题:

  • 在下面的代码片段,我希望客户端无法连接,如果我 评论如下“密码列表”选择。它仍然有效!我错过了什么,对吧?
  • 有没有办法让客户端使用服务器证书,并有足够的开放连接?即没有钥匙,没有CA?

客户端:

ctx = SSL_CTX_new(DTLSv1_client_method()); 
SSL_CTX_set_cipher_list(ctx, "HIGH:!DSS:[email protected]"); 

// 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:[email protected]"); // 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。

回答

1

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会导致服务器中止连接(请参见documentation)。如果您不使用后一种选项,则可以检查客户是否使用SSL_get_peer_certificate函数发送了证书。