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