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

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

Описание

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

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

ret = EVP_PKEY_encrypt_init(ctx);
Однако вы используете контекст для дешифрования, не повторно инициализируя контекст.
ret = EVP_PKEY_decrypt(ctx, out, &out_len, in, in_len);

Средство проверки обнаруживает, если объект контекста, используемый в этих функциях, был инициализирован при помощи соответствующих функций инициализации: EVP_PKEY_paramgen, EVP_PKEY_keygen, EVP_PKEY_encrypt, EVP_PKEY_verify, EVP_PKEY_verify_recover, EVP_PKEY_decrypt, EVP_PKEY_sign, EVP_PKEY_derive и EVP_PKEY_derive_set_peer.

Риск

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

Фиксация

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

  • Для шифрования с EVP_PKEY_encrypt инициализируйте контекст с EVP_PKEY_encrypt_init.

  • Для верификации подписи с EVP_PKEY_verify инициализируйте контекст с EVP_PKEY_verify_init.

  • Для генерации ключей с EVP_PKEY_keygen инициализируйте контекст с EVP_PKEY_keygen_init.

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

Примеры

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

#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf10;
size_t out_len10;
int func(unsigned char *src, size_t len, EVP_PKEY_CTX *ctx){
  if (ctx == NULL) fatal_error(); 

  ret = EVP_PKEY_decrypt_init(ctx); 
  if (ret <= 0) fatal_error();
  return EVP_PKEY_encrypt(ctx, out_buf10, &out_len10, src, len);
}

В этом примере контекст инициализируется для дешифрования, но используется для шифрования.

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

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

#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf10;
size_t out_len10;
int func(unsigned char *src, size_t len, EVP_PKEY_CTX *ctx){
  if (ctx == NULL) fatal_error(); 

  ret = EVP_PKEY_encrypt_init(ctx); 
  if (ret <= 0) fatal_error();
  return EVP_PKEY_encrypt(ctx, out_buf10, &out_len10, src, len);
}

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

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

Введенный в R2018a