Контекст, инициализированный неправильно для операции обзора

Контекст, используемый для операции обзора, инициализируется для различной операции обзора

Описание

Контекст, инициализированный неправильно для операции обзора, происходит, когда вы инициализируете объект контекста EVP_MD_CTX для определенной операции обзора, но используете контекст для различной операции.

Например, вы инициализируете контекст для создания дайджеста сообщения только.

ret = EVP_DigestInit(ctx, EVP_sha256())
Однако вы выполняете последний шаг для подписания:
ret = EVP_SignFinal(&ctx, out, &out_len, pkey);
Ошибку показывают, только если последний шаг не сопоставим с инициализацией контекста. Если промежуточные шаги обновления противоречивы, это не инициировало ошибку, потому что промежуточные шаги не зависят от природы операции. Например, EVP_DigestUpdate работает тождественно к EVP_SignUpdate.

Риск

Спутывание различных операций на том же контексте может вести, чтобы затенить код. Трудно определить сразу, используется ли текущий объект для создания дайджеста сообщения, подписания или верификации. Путаница может также привести к отказу в операции или неожиданном дайджесте сообщения.

Фиксация

После того, как вы настроите контекст для определенного семейства операций, используйте контекст только для того семейства операций. Например, используйте эти пары функций для инициализации и последних шагов.

  • EVP_DigestInit: EVP_DigestFinal

  • EVP_DigestInit_ex: EVP_DigestFinal_ex

  • EVP_DigestSignInit: EVP_DigestSignFinal

Если вы хотите снова использовать существующий объект контекста для различного семейства операций, повторно инициализируйте контекст.

Примеры

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

#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf16;
unsigned int out_len16;

void func(unsigned char *src, size_t len){
  EVP_MD_CTX* ctx = EVP_MD_CTX_create();

  ret = EVP_SignInit_ex(ctx, EVP_sha256(), NULL);
  if (ret != 1) fatal_error();

  ret = EVP_SignUpdate(ctx, src, len);
  if (ret != 1) fatal_error();

  ret = EVP_DigestSignFinal(ctx, out_buf16, (size_t*) out_len16);

  if (ret != 1) fatal_error();
}

В этом примере объект контекста инициализируется для подписания только с EVP_SignInit, но последний шаг пытается создать обзор со знаком с EVP_DigestSignFinal.

Исправление — использует одно семейство операций

Одно возможное исправление должно использовать объект контекста для подписания только. Измените последний шаг на EVP_SignFinal в соответствии с шагом инициализации.

#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf16;
unsigned int out_len16;

void corrected_cryptomdbadfunction(unsigned char *src, size_t len, EVP_PKEY* pkey){
  EVP_MD_CTX* ctx = EVP_MD_CTX_create();

  ret = EVP_SignInit_ex(ctx, EVP_sha256(), NULL); 
  if (ret != 1) fatal_error();

  ret = EVP_SignUpdate(ctx, src, len);
  if (ret != 1) fatal_error();

  ret = EVP_SignFinal(ctx, out_buf16, &out_len16, pkey); 
  if (ret != 1) fatal_error();
}

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

Группа: криптография
Язык: C | C++
Значение по умолчанию: 'off'
Синтаксис командной строки: CRYPTO_MD_BAD_FUNCTION
Влияние: носитель
ID CWE: 310, 353, 354, 372, 573, 664

Введенный в R2018a