Missing X.509 certificate

Сервер или клиент не могут аутентифицироваться

Описание

Этот дефект происходит, когда вы используете контекст, чтобы обработать связи TLS/SSL с этими функциями, но вы не загружаете сертификат X.509 в контекст.

  • SSL_accept

  • SSL_connect

  • SSL_do_handshake

  • SSL_write

  • SSL_read

  • BIO_do_accept

  • BIO_do_connect

  • BIO_do_handshake

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

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

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

  • Для аутентификации клиента клиент пытается связать с сервером во второй раз после получения SSL_ERROR_WANT_X509_LOOKUP ошибка на первой попытке подключения.

Риск

Когда вы не загружаете сертификат X.509 в контекст, чтобы обработать связи TLS/SSL, связь не безопасна и уязвима для нападений человека в середине (MITM).

Фиксация

Загрузите сертификат X.509 в контекст, который вы создаете, чтобы обработать связи TLS/SSL.

Примеры

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

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

unsigned char* buf;
int len;

SSL_CTX* InitServerCTX(void)
{
    SSL_CTX* ctx;
    OpenSSL_add_all_algorithms();
    ctx = SSL_CTX_new(SSLv23_server_method());
    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
    if (ctx == NULL) {
        /*handle errors */
    }
    return ctx;
}

int OpenListener(int port)
{
    /* Create server socket */
}

void func()
{
    SSL_CTX* ctx;
    int server, port;
    int ret;
    SSL_library_init();

    ctx = InitServerCTX();
    server = OpenListener(port);
    while (1) {
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);
        SSL* ssl;

        int client = accept(server, (struct sockaddr*)&addr, &len);
        printf("Connection: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, client);
        ret = SSL_accept(ssl);
        if (SSL_get_error(ssl, ret) <= 0)
            /* Serve connection */;
        else
            SSL_free(ssl);
    }
    close(server);
    SSL_CTX_free(ctx);
}

В этом примере, InitServerCTX() инициализирует контекст ctx для связей TLS/SSL, но никакого сертификата загружается в ctx. Когда SSL_accept проверяет квитирование TLS/SLL на структуру SSL, созданную из ctx, нет никакого сертификата, доступного, чтобы аутентифицировать сервер.

Коррекция — прежде, чем создать структуру SSL, сертификат загрузки в контекст

Одна возможная коррекция к, прежде чем вы создадите структуру SSL, загрузите сертификат в контекст, который вы создаете для связей TLS/SSL, например, с SSL_CTX_use_certificate_file.

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

unsigned char* buf;
int len;

SSL_CTX* InitServerCTX(void)
{
    SSL_CTX* ctx;
    OpenSSL_add_all_algorithms();
    ctx = SSL_CTX_new(SSLv23_server_method());
    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
    if (ctx == NULL) {
        /*handle errors */
    }
    return ctx;
}

void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
    if (SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0) {
        /* Handle errors */
    }
}

int OpenListener(int port)
{
    /* Create server socket */
}

void func()
{
    SSL_CTX* ctx;
    int server, port;
    int ret;
    SSL_library_init();

    ctx = InitServerCTX();
    LoadCertificates(ctx, "mycert.pem", "mycert.pem");
    server = OpenListener(port);
    while (1) {
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);
        SSL* ssl;

        int client = accept(server, (struct sockaddr*)&addr, &len);
        printf("Connection: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, client);
        ret = SSL_accept(ssl);
        if (SSL_get_error(ssl, ret) <= 0)
            /* Serve connection */;
        else
            SSL_free(ssl);
    }
    close(server);
    SSL_CTX_free(ctx);
}

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

Группа: криптография
Язык: C | C++
Значение по умолчанию: Off
Синтаксис командной строки: CRYPTO_SSL_NO_CERTIFICATE
Удар: носитель
ID CWE: 310
Введенный в R2019b