在C++中验证OpenSSL客户端证书

6

我有一个可以建立与服务器的SSL连接的应用程序。服务器使用自签名证书,客户端加载证书颁发机构链以告知它可以信任该服务器。客户端使用以下代码实现:

SSL_METHOD* method = TLSv1_client_method();
_ctx = SSL_CTX_new(method);
if ( SSL_CTX_load_verify_locations(_ctx, "ca-all.crt", NULL) != 1 )
{
    return false;
}
_ssl = SSL_new(_ctx);
int val = SSL_set_fd(_ssl, _socket->GetFD());
if ( val != SSL_SUCCESS )
{
    int err = SSL_get_error(_ssl, val);
    return false;
}
val = SSL_connect(_ssl);

在服务器端:

  if ( SSL_CTX_use_certificate_chain_file( g_ctx, "ca-chain1.crt" ) <= 0 ) {
    return 1;
  }
  ppem_file = getenv( "PEM_FILE" );
  if ( ppem_file == NULL ) {
    ppem_file = pem_file;
  }
  if ( SSL_CTX_use_certificate_file( g_ctx, ppem_file,
                                     SSL_FILETYPE_PEM ) <= 0 ) {
    return 1;
  }
  if ( SSL_CTX_use_PrivateKey_file( g_ctx, ppem_file,
                                    SSL_FILETYPE_PEM ) <= 0 ) {
    return 2;
  }

我正在尝试修改这段代码,以便服务器还可以验证客户端的对等证书(自签名,使用与服务器相同的发行者),但遇到了一些困难。我在任何地方都没有找到良好的“概念概述”文档,这似乎是OpenSSL库的典型障碍。
在SSL_CTX_load_verify_locations()调用后,我在客户端添加了以下内容:
if ( SSL_CTX_use_certificate_file(_ctx, "generic_client.pem", SSL_FILETYPE_PEM ) != 1 )
{
    return false;
}

在服务器上,在 SSL_CTX_use_PrivateKey_file() 调用之后,我添加了以下内容:

  STACK_OF(X509_NAME) *list;
  list = SSL_load_client_CA_file( "ca_chain2.crt" );
  if( list == NULL ) {
    return 4;
  }
  SSL_CTX_set_client_CA_list( g_ctx, list );
  SSL_CTX_set_verify( g_ctx, SSL_VERIFY_PEER, NULL );

连接失败是因为证书无法验证。客户端似乎能够正常加载证书,如果我注释掉SSL_CTX_set_verify行,客户端就能够无问题地连接(因为其证书从未经过验证)。
看起来服务器认为客户端的证书颁发机构链不好。我在这里漏了什么?
从命令行中,我可以运行: openssl verify -CAfile ca-chain2.crt generic_client.pem 它通过了,所以我有正确的证书数据可用,只是可能使用方式不对。
2个回答

7
在服务器上,您还必须调用SSL_CTX_load_verify_locations()。该函数告诉服务器要使用哪些证书进行证书验证;SSL_CTX_set_client_CA_list()函数设置了在握手期间发送到客户端的允许CA列表。这两个函数都是必需的。
(在use_certificate_file之后,客户端还需要调用SSL_CTX_use_PrivateKey_file(),但我猜您已经这样做了,只是没有提到它)。

0

SSL_CTX_set_client_CA_list设置CA列表。按定义,CA证书与用户证书不同(例如,它具有CA位设置)。因此,我建议您创建一个适当的CA(其CA证书是自签名的),并使用它来签署客户端和服务器证书。我假设OpenSSL并不期望客户端实际上会将CA证书用于通信。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接