OpenSSL Bio_gets в клиенте - PullRequest
       3

OpenSSL Bio_gets в клиенте

0 голосов
/ 14 января 2019

Я пытаюсь реализовать простой клиент SSL с OpenSSL, но я хочу прочитать только одну строку с BIO_gets(). Я получил рабочую тестовую программу на примере клиента здесь:
https://linux.die.net/man/3/bio_new_ssl_connect. Но в этом коде используется функция BIO.read(). Я попробовал это, просто заменив BIO.read на BIO_gets, но в этом случае возвращается -2 и согласно документации эта операция не реализована в конкретном типе BIO. Я знаю, что BIO в этом примере является SSL BIO, а в примере с сервером (который использует BIO_gets) буферизирующий BIO находится поверх SSL BIO:

bbio = BIO_new(BIO_f_buffer());
sbio = BIO_push(bbio, sbio);

Я попытался вставить две вышеупомянутые строки в мой клиентский код, но затем программа зависла. Поэтому мой вопрос: как я могу использовать BIO_gets в моей клиентской программе для чтения по одной строке за раз?

Полный код:

    SSL_load_error_strings();
    ERR_load_BIO_strings();
    SSL_library_init();

    context = SSL_CTX_new(SSLv23_client_method());

    if(SSL_CTX_set_default_verify_paths(context) == 0){
        fprintf(stderr, "Error: Error: Can't load default verify paths!\n");
        printf("Reason: %s\n", ERR_reason_error_string(ERR_get_error()));
        return -1;
    }

    bio = BIO_new_ssl_connect(context);
    BIO_get_ssl(bio, &ssl);

    if(!ssl){
        fprintf(stderr, "Error: Can't locate SSL pointer\n");
        return -1;
    }

    //Don't want any retries
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);


    BIO_set_conn_hostname(bio, connection);

    if(BIO_do_connect(bio) <= 0){
        fprintf(stderr, "Error: Error: Can't load default verify paths!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }

    if(SSL_get_verify_result(ssl) != X509_V_OK)
    {
        fprintf(stderr, "No valid certificate!\n");
        return -1;
    }

    static char recv_buffer[1024]; 

    // Read line
    int len = BIO_gets(bio, recv_buffer, 1024);
    printf("Received: %d, %s", len, recv_buffer);

    return 0;

1 Ответ

0 голосов
/ 14 января 2019

Вам нужно сделать это следующим образом:

Это создает новый буферизованный BIO

BIO *bbio = BIO_new(BIO_f_buffer());

Теперь вам нужно привязать его к существующему SSL BIO

BIO_push(bbio, bio);

и тогда вы можете позвонить BIO_gets() по этому

int len = BIO_gets(bbio, recv_buffer, 1024);

, которая читает одну строку с завершающей новой строкой, аналогичную fgets(), из потока файлов.

Это должно работать так, как вы ожидаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...