C++ OpenSSL 忽略自签名证书错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2256950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:45:11  来源:igfitidea点击:

OpenSSL Ignore Self-signed certificate error

c++csslopensslssl-certificate

提问by Ramsey

I'm writing a small program with the OpenSSL library that is suppose to establish a connection with an SSLv3 server. This server dispenses a self-signed certificate, which causes the handshake to fail with this message: "sslv3 alert handshake failure, self signed certificate in certificate chain."

我正在使用 OpenSSL 库编写一个小程序,该程序旨在与 SSLv3 服务器建立连接。此服务器分发自签名证书,这会导致握手失败并显示以下消息:“sslv3 警报握手失败,证书链中的自签名证书。”

Is there a way I can force the connection to proceed? I've tried calling SSL_CTX_set_verify like so:

有没有办法强制连接继续?我试过像这样调用 SSL_CTX_set_verify:

SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);

But it does not seem to change anything.

但这似乎并没有改变任何东西。

Any suggestions?

有什么建议?

采纳答案by jimis

By default OpenSSL walks the certificate chain and tries to verify on each step, SSL_set_verify()does not change that, see tha man page. Quoting it:

默认情况下,OpenSSL 会遍历证书链并尝试在每一步进行验证,SSL_set_verify()不会更改,请参见手册页。引用它:

The actual verification procedure is performed either using the built-in verification procedure or using another application provided verification function set with SSL_CTX_set_cert_verify_callback(3).

实际的验证过程是使用内置验证过程或使用另一个应用程序提供的验证函数集来执行的,该函数集设置为 SSL_CTX_set_cert_verify_callback(3)。

So the solution is to create a simple callback and set that one, so that you override all certificate-chain walking:

因此,解决方案是创建一个简单的回调并设置该回调,以便覆盖所有证书链遍历:

static int always_true_callback(X509_STORE_CTX *ctx, void *arg)
{
    return 1;
}

SSL_CTX_set_cert_verify_callback(CTX, always_true_callback);

回答by Adriano P

Check these OpenSSL Examples: http://www.rtfm.com/openssl-examples/

检查这些 OpenSSL 示例:http: //www.rtfm.com/openssl-examples/

The wclient.cconnects to any https page, for example:

wclient.c连接至任何HTTPS页面,例如:

wclient -h www.yahoo.com -p 443

If you run that with the default installation, you'll get a certificate error (you can use the -i flag to bypass the certificate check though).

如果你使用默认安装运行它,你会得到一个证书错误(你可以使用 -i 标志来绕过证书检查)。

To verify the certificate, you'll need to download the CA certificates (Verisign, Thawte, Equifax, etc), so google this file cacert.pem, download and rename it to root.pemand you'll be able to connect to a web server and validate its certificate.

要验证证书,您需要下载 CA 证书(Verisign、Thawte、Equifax 等),所以在谷歌这个文件cacert.pem,下载并将其重命名为root.pem,您将能够连接到Web 服务器并验证其证书。

回答by ndim

Have you tried giving your app the server's CA certificate so that your app canverify the certificate chain?

您是否尝试为您的应用程序提供服务器的 CA 证书,以便您的应用程序可以验证证书链?

回答by Len Holgate

You could try passing your own callback to SSL_set_verify()and then doing your own verification. It's less than ideal as I think you then need to do all of the verification and then allow the self signed error to be ignored, but you should be able to work out what the standard verify code does from the OpenSSL source and then simply pull it into your own verification callback and allow the specific error code...

您可以尝试将自己的回调传递给SSL_set_verify(),然后进行自己的验证。这不太理想,因为我认为您需要进行所有验证,然后允许忽略自签名错误,但是您应该能够从 OpenSSL 源代码中找出标准验证代码的作用,然后简单地提取它进入您自己的验证回调并允许特定的错误代码...

回答by Xorlev

Have you tried setting SSL_set_verify?

您是否尝试过设置 SSL_set_verify?

SSL_set_verify(s, SSL_VERIFY_NONE, NULL);

回答by bobah

My sample client code (link) works fine with self signed server cert. I have the below code after SSL_connect and have full control over self signed certificates acceptability in my client

我的示例客户端代码(链接)适用于自签名服务器证书。我在 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;
  }
}