我正在用OpenSSL库编写一个小程序,假设它与SSLv3服务器建立连接。此服务器分发自签名证书,导致握手失败并显示以下消息:“sslv3警报握手失败,证书链中的自签名证书。”
有没有办法可以强制连接继续进行?我试过这样调用SSL_CTX_set_verify:
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
但它似乎没有改变任何东西。
有什么建议吗?
答案 0 :(得分:4)
默认情况下,OpenSSL遍历证书链并尝试验证每一步,SSL_set_verify()
不会更改,请参阅手册页。引用它:
实际验证程序使用 内置验证程序或使用提供的其他应用程序 使用SSL_CTX_set_cert_verify_callback(3)设置的验证功能。
所以解决方案是创建一个简单的回调并设置一个回调,以便覆盖所有证书链步行:
static int always_true_callback(X509_STORE_CTX *ctx, void *arg)
{
return 1;
}
SSL_CTX_set_cert_verify_callback(CTX, always_true_callback);
答案 1 :(得分:2)
您是否尝试过为应用提供服务器的CA证书,以便您的应用可以验证证书链?
答案 2 :(得分:2)
检查这些OpenSSL示例:http://www.rtfm.com/openssl-examples/
wclient.c 连接到任何https页面,例如:
wclient -h www.yahoo.com -p 443
如果使用默认安装运行它,您将收到证书错误(您可以使用-i标志绕过证书检查)。
要验证证书,您需要下载CA证书(Verisign,Thawte,Equifax等),以便谷歌此文件 cacert.pem ,下载并重命名为 root.pem ,您将能够连接到Web服务器并验证其证书。
答案 3 :(得分:0)
您是否尝试过设置SSL_set_verify?
SSL_set_verify(s, SSL_VERIFY_NONE, NULL);
答案 4 :(得分:0)
您可以尝试将自己的回调传递给SSL_set_verify()
,然后进行自己的验证。它不太理想,因为我认为你需要进行所有验证,然后允许忽略自签名错误,但是你应该能够从OpenSSL源中找出标准验证代码的作用,然后简单地将它拉出来进入您自己的验证回调并允许特定的错误代码...
答案 5 :(得分:0)
我的示例客户端代码(link)可以使用自签名服务器证书。我在SSL_connect之后有以下代码,并且可以完全控制我的客户端中的自签名证书可接受性
SSL_CTX* ctx = SSL_CTX_new(SSLv3_method());
// TCP connection and SSL handshake ...
/* Check the certificate */
rc = SSL_get_verify_result(ssl);
if(rc != X509_V_OK) {
if (rc == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || rc == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
fprintf(stderr, "self signed certificate\n");
}
else {
fprintf(stderr, "Certificate verification error: %ld\n", SSL_get_verify_result(ssl));
SSL_CTX_free(ctx);
return 0;
}
}