Missing certification authority list

Не удается доверять сертификату для проверки подлинности

Описание

Этот дефект возникает, когда вы используете контекст для обработки соединений TLS/SSL с этими функциями, но вы не загружаете список сертифицирующего органа (CA) в контекст.

  • SSL_connect

  • SSL_accept

  • SSL_do_handshake

  • SSL_write

  • SSL_read

  • BIO_do_connect

  • BIO_do_accept

  • BIO_do_handshake

ЦС является доверенной третьей сущностью, которая выдает цифровые сертификаты другим сущностям. Сертификат содержит информацию о его владельце. Сервер или клиенты используют эти сведения для проверки подлинности подключений к владельцу сертификата.

Шашка поднимает дефект, если:

  • Для проверки подлинности сервера у клиента нет списка ЦС, чтобы определить, получен ли сертификат сервера от доверенного источника.

  • Для проверки подлинности клиента сервер не имеет списка ЦС, чтобы определить, получен ли сертификат клиента от доверенного источника.

Риск

Без списка ЦС невозможно определить, выдан ли сертификат доверенным ЦС. Сущность, которая представляет сертификат для проверки подлинности, возможно, не является сущностью, описанной в сертификате. Ваше соединение уязвимо для атак «человек посередине» (MITM).

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

Загрузите список сертифицирующего органа в контекст, созданный для обработки подключений TLS/SSL.

Примеры

расширить все

#include <openssl/ssl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/err.h>

unsigned char* buf;

int OpenConnection(char* hostname, int port)
{
    /* Open the connection */
}

SSL_CTX* InitCTX(void)
{
    SSL_CTX* ctx;
    OpenSSL_add_all_algorithms();
    ctx = SSL_CTX_new(TLSv1_2_client_method());
    if (ctx == NULL) {
        /*handle errors */
    }
    return ctx;
}

void func()
{
    SSL_CTX* ctx;
    int server;
    SSL* ssl;
    char buf[1024];
    int bytes;
    char* hostname, *portnum;
    int ret;

    SSL_library_init();
    hostname = "localhost";
    portnum = "4433";

    ctx = InitCTX();
    server = OpenConnection(hostname, atoi(portnum));
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, server);
    ret = SSL_connect(ssl);
    if (SSL_get_error(ssl, ret) <= 0) {
        char* msg = "Hello???";
        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
        SSL_write(ssl, msg, strlen(msg));
        bytes = SSL_read(ssl, buf, sizeof(buf));
        buf[bytes] = 0;
        printf("Received: \"%s\"\n", buf);
        SSL_free(ssl);
    } else
        ERR_print_errors_fp(stderr);
    close(server);
    SSL_CTX_free(ctx);
}

В этом примере контекстное ctx инициализируется для обработки соединений TLS/SSL. Когда SSL_connect инициализирует квитирование TLS/SSL с сервером с помощью структуры SSL ssl создан из ctxСписок ЦС, позволяющий проверить валидность сертификата сервера, отсутствует.

Коррекция - перед инициированием рукопожатия TLS/SSL загрузите список ЦС в контекст

Одна из возможных коррекций состоит в том, чтобы, прежде чем вы инициализируете структуру SSL, задать список сертификатов CA для контекста ctx, для образца с SSL_CTX_load_verify_locations.

#include <openssl/ssl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/err.h>

unsigned char* buf;

int OpenConnection(char* hostname, int port)
{
    /* Open the connection */
}

SSL_CTX* InitCTX(void)
{
    SSL_CTX* ctx;
    OpenSSL_add_all_algorithms();
    ctx = SSL_CTX_new(TLSv1_2_client_method());
    if (ctx == NULL) {
        /*handle errors */
    }
    return ctx;
}

void LoadCA(SSL_CTX* ctx, char* CertFile, char* CertPath)
{
    if (SSL_CTX_load_verify_locations(ctx, CertFile, CertPath) <= 0) {
        /* handle errors */
    }
}

void func()
{
    SSL_CTX* ctx;
    int server;
    SSL* ssl;
    char buf[1024];
    int bytes;
    char* hostname, *portnum;
    int ret;

    SSL_library_init();
    hostname = "localhost";
    portnum = "4433";

    ctx = InitCTX();
    LoadCA(ctx, "cacert.pem", "ca/");
    server = OpenConnection(hostname, atoi(portnum));
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, server);
    ret = SSL_connect(ssl);
    if (SSL_get_error(ssl, ret) <= 0) {
        char* msg = "Hello???";
        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
        SSL_write(ssl, msg, strlen(msg));
        bytes = SSL_read(ssl, buf, sizeof(buf));
        buf[bytes] = 0;
        printf("Received: \"%s\"\n", buf);
        SSL_free(ssl);
    } else
        ERR_print_errors_fp(stderr);
    close(server);
    SSL_CTX_free(ctx);
}

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

Группа: Криптография
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки : CRYPTO_SSL_NO_CA
Влияние: Средний
ИДЕНТИФИКАТОР CWE : 310
Введенный в R2019b