2016-11-19 3 views
0

сегментации У меня есть эта простая программа:OpenSSL

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 (био, request.c_str(), request.size())

В f unction connectServerSSL работает нормально.

Но когда я хочу использовать его в какой-либо другой функции:

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

я получаю ошибку сегментации (ядро сбрасывали).

+2

Вы не возвращаем '' bio' из connectServerSSL'. – tkausl

+0

Как я могу это сделать? –

ответ

0

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

Ваш connectServerSSL() функция имеет параметр с именем bio, и он записывает только на эту временную переменную, а не к bio переменной в main(), которая неинициализированным.

Изменить подпись connectServerSSL() на номер BIO* connectServerSSL(void) и позвонить по телефону bio = connectServerSSL(). Вы также можете вызвать функцию с аргументом BIO** newbio, вызвать его с помощью &bio и установить *newbio, который будет обновлять переменную bio в main().

Некоторые хорошие привычки, позволяющие избежать таких ошибок: инициализируйте переменные значениями по умолчанию, используйте утверждения, чтобы проверить, что ваши входы действительны, и один шаг в отладчике. Если бы вы инициализировали переменную в main() до BIO* bio = NULL, или еще лучше, BIO* const bio = connectServerSSL(), тогда в отладчике было бы очевидно, что она по-прежнему не инициализировалась при возврате.

Смежные вопросы