Openssl 调用SSL\u connect时发生SSL\u错误\u SSL

Openssl 调用SSL\u connect时发生SSL\u错误\u SSL,openssl,Openssl,我用openssl编写了代码来连接tls下的服务器。如果我从pem文件加载证书,它将正常工作。但若我从pfx文件加载证书,调用SSL\U connect时会出现SSL\U错误\U SSL。我不知道加载pfx文件的过程是否错误。过程如下 FILE* fp = fopen("cert.pfx", "rb"); PKCS12* p12 = d2i_PKCS12_fp(fp, NULL); PKCS12_parse(p12, NULL, &private_key, &certificat

我用openssl编写了代码来连接tls下的服务器。如果我从pem文件加载证书,它将正常工作。但若我从pfx文件加载证书,调用SSL\U connect时会出现SSL\U错误\U SSL。我不知道加载pfx文件的过程是否错误。过程如下

FILE* fp = fopen("cert.pfx", "rb");
PKCS12* p12 = d2i_PKCS12_fp(fp, NULL);
PKCS12_parse(p12, NULL, &private_key, &certificate, &ca_certificates);
SSL_CTX_use_certificate(ctx, certificate);
SSL_CTX_use_PrivateKey(ctx, private_key);
SSL_CTX_check_private_key(ctx);
SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(ca_certificates, i);
SSL_CTX_add_client_CA(ctx, sk_X509_value(ca_certificates, i);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
...
SSL* ssl = SSL_new(ssl_context);
SSL_set_fd(ssl, sockfd);
SSL_connect(ssl);
...
我已经与其他客户测试了pfx文件。它工作得很好。所以问题不在于pfx文件。是否有任何openssl选项会导致连接失败?或者我没有正确设置CA证书?pfx文件包含我自己签名的CA。但它与其他客户机协同工作

SSL\u connect()失败后,我调用了ERR\u get\u error()。并且获取证书验证失败。因此,我认为在上面加载pfx文件的过程中出现了一些错误。可能我没有正确添加CA证书。谁能告诉我加载pfx的正确过程吗


请帮忙

您的
i
变量是大小为
sk_num(ca_证书)
的计数器吗?如果是,请尝试删除我认为不适合客户端的行
SSL\u CTX\u add\u client\u CA
(不确定,很难)

此外,在错误处理中,请输入以下行以查找原因:

SSL_load_error_strings(); // just once
char msg[1024];
ERR_error_string_n(ERR_get_error(), err_msg, sizeof(err_msg));
printf("%s\n", msg);`
或者,您也可以尝试直接获取SSL错误:

int ssl_error = SSL_get_verify_result(ssl);

我发现,使用SSL\u CTX\u add\u extra\u chain\u cert添加证书的顺序确实很重要。PKCS12_解析添加证书的顺序必须已从libssl 0.9.8更改为libssl1.0。 这就是为什么我使用下面的代码将它们添加到证书存储中

X509_STORE * certStore = SSL_CTX_get_cert_store(ctx);
for(int i = 0; i < sk_X509_num(ca) ; i++)
{
    if (X509_STORE_add_cert(certStore, sk_X509_value(ca_certificates, i))==0)
    {
        ERR_print_errors_fp (stderr);
    }
}
X509\u STORE*certStore=SSL\u CTX\u get\u cert\u STORE(CTX);
对于(int i=0;i
我找到了解决方案。此代码供客户端使用。我研究了SSL\u CTX\u load\u verify\u locations()函数的源代码。它通过X509_store_add_cert()函数将ca证书添加到SSL上下文的证书存储中。我也做了同样的工作。谢谢你的帮助。