Missing private key for X.509 certificate

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

Описание

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

Обычно при обмене 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++
По умолчанию: Off
Синтаксис командной строки : CRYPTO_SSL_NO_PRIVATE_KEY
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 573
Введенный в R2020a