JJ DD JJ DD - 13 days ago 5
C++ Question

OpenSSL segfault

I have this simple program:

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);
}


And this functions:

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);
}
}


When I use this:


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


In function connectServerSSL it works OK.

But when i want to use it in some other function:

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


I get Segmentation fault (core dumped).

Answer

In C and C++, even pointers are passed by value. So you need to either change the parameter of connectServerSSL to a BIO *& or else redefine it in the C-style of things:

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());
}
Comments