exponenta event banner

Отсутствует закрытый ключ для сертификата X.509

Отсутствие ключа может привести к ошибке во время выполнения или небезопасному шифрованию

Описание

Дефект возникает при загрузке файла сертификата X.509 в контекст SSL, но не при загрузке соответствующего закрытого ключа или при загрузке ключа в контекст.

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

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

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

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

Риск

Загрузка закрытого ключа для сертификата X.509 может привести к ошибке во время выполнения при небезопасном шифровании.

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

Загрузка закрытого ключа сертификата X.509 в контекст SSL путем вызова SSL_CTX_use_PrivateKey_file или загрузить закрытый ключ в структуру SSL путем вызова SSL_use_PrivateKey_file.

Примеры

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

#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#define SSL_SERVER_CRT "server.pem"

#define fatal_error() exit(-1)

void load_cert(SSL_CTX* ctx, const char* certfile)
{
    int ret = SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;

    /* creation context for the SSL protocol */
    ctx = SSL_CTX_new(SSLv23_server_method());
    if (ctx == NULL) fatal_error();

    /* context configuration */
    load_cert(ctx, SSL_SERVER_CRT);

    /* Handle connection */
    ssl = SSL_new(ctx);
    ret = SSL_accept(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}

В этом примере контекст SSL ctx инициируется с помощью роли сервера и функции load_cert загружает сертификат сервера в ctx. Затем сервер ожидает, когда клиент инициирует квитирование. Однако, поскольку закрытый ключ не загружен в структуру SSL, сервер не может расшифровать предварительно главный секрет, который отправляет клиент, и рукопожатие завершается неуспешно.

Исправление - загрузка закрытого ключа в контекст SSL

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

#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#define SSL_SERVER_CRT "server.pem"
#define SSL_SERVER_KEY "server.key"

#define fatal_error() exit(-1)

void load_cert(SSL_CTX* ctx, const char* certfile)
{
    int ret = SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();

    ret = SSL_CTX_use_PrivateKey_file(ctx, SSL_SERVER_KEY, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;

    /* creation context for the SSL protocol */
    ctx = SSL_CTX_new(SSLv23_server_method());
    if (ctx == NULL) fatal_error();

    /* context configuration */
    load_cert(ctx, SSL_SERVER_CRT);

    /* Handle connection */
    ssl = SSL_new(ctx);
    ret = SSL_accept(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}

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

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