exponenta event banner

Не задан метод подключения TLS/SSL

Программа не может определить, следует ли вызывать процедуры клиента или сервера

Описание

Дефект возникает при вызове одной из этих функций без явной установки метода соединения контекста TLS/SSL.

  • SSL_read

  • SSL_write

  • SSL_do_handshake

Связь между сервером и клиентскими объектами, использующими соединение TLS/SSL, начинается с подтверждения. Во время рукопожатия стороны обмениваются информацией и устанавливают алгоритм шифрования и сеансовые ключи, используемые сторонами во время сеанса. Методы соединения для сервера и клиента используют различные процедуры для квитирования.

Проверка не вызывает дефектов, если:

  • Вы используете SSL_connect (клиент) и SSL_accept (серверные) функции. Эти функции автоматически устанавливают правильные процедуры квитирования.

  • Контекст SSL передается в качестве аргумента функции, вызывающей SSL_new.

  • Контекст SSL объявляется вне области действия функции, обрабатывающей соединение.

Риск

Невозможно начать квитирование, если подсистема SSL не знает, какой метод соединения следует вызвать.

Зафиксировать

  • Для выполнения процедур квитирования вызова клиента вызовите SSL_set_connect_state прежде чем начать рукопожатие.

  • Для выполнения процедур квитирования сервера вызовите SSL_set_accept_state прежде чем начать рукопожатие.

Примеры

развернуть все

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>

#define fatal_error() exit(-1)

int len;
unsigned char buf;
volatile int rd;

const SSL_METHOD*  set_method()
{
    return SSLv23_server_method();
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;
    const SSL_METHOD* method =  set_method();
    ctx = SSL_CTX_new(method);
    ssl = SSL_new(ctx);

    switch (rd) {
    case 1:
        ret = SSL_read(ssl, (void*)buf, len);
        if (ret <= 0) fatal_error();
        break;
    case 2:
        ret = SSL_do_handshake(ssl);
        if (ret <= 0) fatal_error();
        break;
    default:
        ret = SSL_write(ssl, (void*)buf, len);
        if (ret <= 0) fatal_error();
        break;
    }
}

В этом примере контекст SSL ctx генерируется с помощью метода соединения с сервером SSLv23_server_method. Однако метод подключения не задан явно для структуры SSL ssl перед попыткой чтения из соединения инициируйте квитирование или выполните запись в соединение.

Исправление - явно задать метод подключения сервера

Одной из возможных корректировок является вызов SSL_set_accept_state установка роли сервера для структуры SSL ssl прежде чем начать рукопожатие.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>

#define fatal_error() exit(-1)

int len;
unsigned char buf;
volatile int rd;

const SSL_METHOD*  set_method()
{
    return SSLv23_server_method();
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;
    const SSL_METHOD* method =  set_method();
    ctx = SSL_CTX_new(method);
    ssl = SSL_new(ctx);
	SSL_set_accept_state(ssl);
	

    switch (rd) {
    case 1:
        ret = SSL_read(ssl, (void*)buf, len);
        if (ret <= 0) fatal_error();
        break;
    case 2:
        ret = SSL_do_handshake(ssl);
        if (ret <= 0) fatal_error();
        break;
    default:
        ret = SSL_write(ssl, (void*)buf, len);
        if (ret <= 0) fatal_error();
        break;
    }
} 

Информация о результатах

Группа: Криптография
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: CRYPTO_SSL_NO_ROLE
Воздействие: среднее
CWE ID: 304, 322, 573
Представлен в R2020a