【问题标题】:Failing to validate server certificate with OpenSSL无法使用 OpenSSL 验证服务器证书
【发布时间】:2012-09-02 16:42:00
【问题描述】:

我使用 OpenSSL(在 Ubuntu 12.04 上用 C++ 编写)编写了一个 SOAP 客户端,但它目前无需检查服务器安全证书即可工作。这是我用来建立连接和检查证书的功能

bool bInitialiseSSL(SSL_CTX* &ctx, SSL* &ssl, BIO* &bio)
{
    ctx = SSL_CTX_new(SSLv23_client_method());  
    bio = BIO_new_ssl_connect(ctx);
    if (bio == NULL) {
        ERR_print_errors_fp(stderr);    
        SSL_CTX_free(ctx);
        return false;
    }

    BIO_get_ssl(bio, &ssl);

    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    char target[]  = "api.betfair.com:https";

    BIO_set_conn_hostname(bio, target);
    BIO_set_nbio(bio,1);
    while (1) {
        if (BIO_do_connect(bio) <= 0) {
            if (!BIO_should_retry(bio)) {
                cout << "Connect failed." << endl;
                BIO_free_all(bio);
                SSL_CTX_free(ctx);
                return false;
            }
        } else {
            break;
        }
    }

    if (BIO_do_handshake(bio) <= 0) {
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return false;
    }

    X509 *cert;
    bool bValid  = false;
    cert = SSL_get_peer_certificate(ssl); 
    if ( cert != NULL ) {
        long res = SSL_get_verify_result(ssl);
        if (res == X509_V_OK) {
            bValid = true;
        } else {
            cout << "Error in security validation: " << res << endl;
        }
        X509_free(cert);   
    }
    return bValid;
}

这工作正常,但 SSL_get_verify_result 的返回值为 20,对应于

X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:无法获取本地 颁发者证书

我已经阅读了一些 OpenSSL 文档以了解它们的功能,但它对用户不是特别友好。我查看了许多网络教程,但我看不出我做错了什么。在我尝试实施证书检查之前,我的软件运行良好,但我看不到我需要做什么。我需要在我的机器上配置设置吗?该服务器是必发的,据说非常安全,我很难相信他们没有有效的 SSL 证书。如果有人能告诉我我做错了什么,我将不胜感激。

【问题讨论】:

    标签: c++ soap ssl openssl betfair


    【解决方案1】:

    这取决于服务器的证书。

    • 如果是公共有效证书,您可以将 CA 证书文件包含在 SSL_CTX 中。

    代码:

    ctx = SSL_CTX_new(SSLv23_client_method()); 
    // You can load CA certs into SSL_CTX
    SSL_CTX_load_verify_locations(ctx, cafile, NULL); // cafile: CA PEM certs file
    

    您可以从 cURL 网站CA Certs from mozilla.org 下载公共 CA 证书文件

    • 如果是私有证书,并且你有证书文件,你可以使用SSL_CTX_use_certificate_file而不是SSL_CTX_load_verify_locations

    【讨论】:

    • 感谢您的回答 - 我如何确定它是私有证书还是公共证书?
    • 如果是外部服务器,你应该尝试第一种方案。
    • 如果您使用客户端证书,SSL_CTX_use_PrivateKey_file 用于作为客户端的私钥。这与拥有“私人”证书(在这种情况下实际上没有意义)毫无关系。如果您有一个不在默认 Mozilla 列表(或您选择使用的任何列表)中的单独 CA,只需将其添加到主 CA 列表。
    • 当我从该链接复制 cacert.pem 文件时,这实际上解决了我的问题。我会接受这个答案,但你能告诉我为什么我的机器上没有这个文件吗?我有一个 mozilla 目录,其中包含许多 .crt 文件,但没有 .pem 文件?这是为什么呢?
    • 您总是需要从一个众所周知的公共场所获取受信任的 CA 证书。所有 TLS/SSL 实现都具有受信任的 CA 证书,例如 JRE、Windows、OpenSSL、Firefox。请记住,随着时间的推移,一些根 CA 证书将过期。之后,您需要再次下载最新的 CA 证书,然后申请到您的应用程序中。
    猜你喜欢
    • 2016-01-27
    • 2018-11-29
    • 2015-06-24
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 2014-09-05
    相关资源
    最近更新 更多