Context initialized incorrectly for digest operation

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

Описание

Этот дефект происходит, когда вы инициализируете 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