SSL 服务器证书验证在代码中失败,但在 openssl 中没有

Posted

技术标签:

【中文标题】SSL 服务器证书验证在代码中失败,但在 openssl 中没有【英文标题】:SSL server certificate verification fails in code but not with openssl 【发布时间】:2017-10-29 22:52:39 【问题描述】:

我正在尝试在 RHEL 4 系统(openssl 0.9.8b)中编写 Web 服务客户端(升级不是一个选项)。我得到了要使用的 CA 证书文件,有两个证书,一个是自签名根证书。它适用于“openssl s_client”,但不适用于代码。我从 SSL_get_verify_result 收到错误 7(SSL 证书验证失败)。

我做了一个测试程序,下面是基本部分:

SSL_library_init();
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_method());
SSL_CTX_load_verify_locations(ctx, "/etc/pki/mycert/cacert.pem", 0);
ssl = SSL_new(ctx);
sbio = BIO_new_socket(sock, BIO_NOCLOSE); /* The socket is already connected */
SSL_set_bio(ssl, sbio, sbio);
SSL_connect(ssl);
err = SSL_get_verify_result(ssl);

连接正常,服务器发送其证书;我已经用 PEM_write_X509 将其转储出来,并验证它是否被“openssl verify”接受。

我用过

SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);

在回调函数中写出验证的步骤:

static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)

    char    buf[256];
    X509   *err_cert;
    int     err, depth;

    err_cert = X509_STORE_CTX_get_current_cert(ctx);
    err = X509_STORE_CTX_get_error(ctx);
    depth = X509_STORE_CTX_get_error_depth(ctx);

    X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);

if (!preverify_ok)
    printf("verify error:num=%d:%s:depth=%d:%s\n", err,
             X509_verify_cert_error_string(err), depth, buf);
else
    printf("Preverify OK, depth=%d:%s, err=%d\n", depth, buf, err);
...

这个的输出是(一些证书数据被替换为“...”):

Preverify OK, depth=2:/ST=GP/L=JHB/C ... QA Root CA 01, err=0
Preverify OK, depth=1:/C=ZA/DC=za/DC ... QA Issue CA 01, err=0
verify error:num=7:certificate signature failure:depth=0:/C=ZA ...

当将此 CA 证书文件作为“-CAfile”运行“openssl s_client”时,输出开头为:

depth=2 /ST=GP/L=JHB/C ... QA Root CA 01
verify return:1
depth=1 /C=ZA/DC=za/DC ... QA Issue CA 01
verify return:1
depth=0 /C=ZA/ST ...
verify return:1

那么“openssl s_client”在做什么和代码在做什么有什么区别呢?

【问题讨论】:

【参考方案1】:

我通过在代码中添加“OpenSSL_add_all_algorithms()”来让它工作。原来是找不到server cert使用的算法。代码和openssl s_client命令的区别明显就是这个调用。

测试程序中的代码取自 Axis2/C 源代码,因为我的客户端是基于 Axis2/C 的。所以这个电话也不见了。

【讨论】:

以上是关于SSL 服务器证书验证在代码中失败,但在 openssl 中没有的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的SSL证书验证失败

ClientWebsocket SSL 证书验证失败

file_get_contents():SSL 操作失败,代码为 1(证书验证失败)

服务器SSL证书验证失败怎么办

烧瓶 SSL 证书中的 OIDC SSO 验证失败

服务器的SSL证书验证失败问题,怎么解决