对于ssl,openssl BIO_do_connect返回0

时间:2014-02-03 17:31:37

标签: ssl openssl libssl libcrypto

这是我尝试连接到google.com:443的简单openssl客户端测试用例。

根据手册,BIO_do_connect应返回1,0或-1。 谷歌没有找到任何人为它返回0,这对我来说是这样。

#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

int main()
{
    SSL_load_error_strings();
    SSL_library_init();
    ERR_load_BIO_strings();
    OpenSSL_add_all_algorithms();

    SSL_CTX *p_ssl_ctx = NULL;
    SSL     *p_ssl     = NULL;
    BIO     * bio      = NULL;
    int r = 0;

    // init ssl context
    p_ssl_ctx = SSL_CTX_new(SSLv2_client_method());   /* Create new context */
    if (p_ssl_ctx == NULL)
    {
        ERR_print_errors_fp(stderr);
        return 3;
    }

    const char *store_path = "/etc/ssl/certs/ca-certificates.crt";
    r = SSL_CTX_load_verify_locations(p_ssl_ctx, store_path, NULL);
    if (r == 0) {
        fprintf(stderr, "Unable to load the trust store from %s.\n", store_path);
        return 4;
    }

    bio = BIO_new_ssl_connect(p_ssl_ctx);
    if (!bio) {
        fprintf(stderr, "no bio \n");
        return 5;
    }

    BIO_get_ssl(bio, &p_ssl);
    if (!(p_ssl)) {
        fprintf(stderr, "no ssl\n");
        return 6;
    }

    SSL_set_mode(p_ssl, SSL_MODE_AUTO_RETRY);
    BIO_set_conn_hostname(bio, "www.google.com:443");

    r  = BIO_do_connect(bio);
    if (r < 1) {
        fprintf(stderr, "BIO_new_ssl_connect failed: %lu (0x%lx)\n", r, r);
        fprintf(stderr, "Error: %s\n", ERR_reason_error_string(ERR_get_error()));
        fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
        ERR_print_errors_fp(stderr);
        perror("bio");
        return 7;
    }

    if (SSL_get_verify_result(p_ssl) != X509_V_OK) {
        fprintf(stderr, "Unable to verify connection result.\n");
        return 8;
    }

    return 0;
}

返回:

BIO_new_ssl_connect failed: 0 (0x0)
Error: (null)
error:00000000:lib(0):func(0):reason(0)
bio: Success

那么如何从中获得实际错误?

1 个答案:

答案 0 :(得分:0)

要在代码中获取SSL连接的最后状态,您可以添加fprintf(stderr,"p_ssl state: %s\n",SSL_state_string_long(p_ssl));之类的内容。

更一般地,我建议您添加如下信息回调:http://www.openssl.org/docs/ssl/SSL_CTX_set_info_callback.html

对于您的情况,您必须用TLSv1_client_method()替换SSLv2_client_method()。