我有一个可以与服务器建立 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 它通过了,所以我有正确的证书数据可用,我一定只是以某种方式错误地使用它。