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

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

Средство проверки повышает дефект если:

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

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

Риск

Без списка CA вы не можете определить, выпущен ли сертификат доверяемым Приблизительно. Сущность, которая представляет сертификат для аутентификации, не может быть сущностью, описанной в сертификате. Ваша связь уязвима для нападений человека в середине (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, нет никакого списка CA, чтобы проверять валидность сертификата сервера.

Коррекция — Прежде, чем Инициировать Квитирование TLS/SSL, Загрузите Список CA в Контекст

Одна возможная коррекция к, прежде чем вы инициализируете структуру 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
Удар: Средняя
ID CWE: 310
Введенный в R2019b