【问题标题】:OpenSSL segfaultOpenSSL 段错误
【发布时间】:2016-11-19 18:29:22
【问题描述】:

我有这个简单的程序:

int main ()
{
        /* INITIALIZING OPENSSL */
        SSL_library_init();          
        SSL_load_error_strings();
        ERR_load_BIO_strings();
        OpenSSL_add_all_algorithms();

        BIO *bio;
        connectServerSSL(bio);
        login(bio);
}

还有这个功能:

void connectServerSSL (BIO *bio)
{
    SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method());
    SSL * ssl;

    if(! SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs"))
    {
        callError(ERR_LOADCERT);
    }

    bio = BIO_new_ssl_connect(ctx);
    BIO_get_ssl(bio, &ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    BIO_set_conn_hostname(bio, hostnamePort);
    if(BIO_do_connect(bio) <= 0)
    {
        callError(ERR_CONNECTION);
    }

    if(SSL_get_verify_result(ssl) != X509_V_OK)
    {
        callError(ERR_VALIDCERT);
    }
}

当我使用这个时:

BIO_write(bio, request.c_str(), request.size())

在函数 connectServerSSL 中它工作正常。

但是当我想在其他功能中使用它时:

void login (BIO *bio)
{
     BIO_write(bio, request.c_str(), request.size());
}

我得到分段错误(核心转储)。

【问题讨论】:

  • 你没有从connectServerSSL返回你的bio
  • 请问我该怎么做?

标签: c++ openssl segmentation-fault


【解决方案1】:

在 C 和 C++ 中,即使是指针也是按值传递的。因此,您需要将 connectServerSSL 的参数更改为 BIO *& 或者以 C 风格重新定义它:

void connectServerSSL (BIO ** bio_ptr)
{
    SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method());
    SSL * ssl;

    if(! SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs"))
    {
        callError(ERR_LOADCERT);
    }

    BIO * bio = BIO_new_ssl_connect(ctx);
    BIO_get_ssl(bio, &ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    BIO_set_conn_hostname(bio, hostnamePort);
    if(BIO_do_connect(bio) <= 0)
    {
        callError(ERR_CONNECTION);
    }

    if(SSL_get_verify_result(ssl) != X509_V_OK)
    {
        callError(ERR_VALIDCERT);
    }
    *bio_ptr = bio;
}

// Example usage:

void example()
{
    BIO * bio;
    connectServerSSL(&bio);
    BIO_write(bio, request.c_str(), request.size());
}

【讨论】:

    【解决方案2】:

    您的connectServerSSL() 函数有一个名为bio 的参数,它只写入这个临时变量,而不写入main() 中未初始化的bio 变量。

    connectServerSSL()的签名改为BIO* connectServerSSL(void),并用bio = connectServerSSL()调用。您还可以使用BIO** newbio 参数调用该函数,使用&amp;bio 调用它,并设置*newbio,这将更新main() 中的bio 变量。

    一些有助于避免此类错误的好习惯:将变量初始化为默认值,使用断言检查输入是否有效,以及在调试器中单步执行。如果您将main() 中的变量初始化为BIO* bio = NULL,或者更好的是BIO* const bio = connectServerSSL(),那么在调试器中很明显它在返回时仍未初始化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2017-06-27
      • 2011-03-16
      • 2015-12-18
      相关资源
      最近更新 更多