exponenta event banner

Отсутствует закрытый ключ

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

Описание

Этот дефект возникает, когда объект контекста используется для расшифровки, подписи или получения общего секрета, но ранее объект не был связан с закрытым ключом, отличным от NULL.

Например, объект контекста инициализируется с помощью закрытого ключа NULL и используется для расшифровки позже.

ctx = EVP_PKEY_CTX_new(pkey, NULL);
...
ret = EVP_PKEY_decrypt_init(ctx);
...
ret = EVP_PKEY_decrypt(ctx, out, &out_len, in, in_len);

Аналогичная проверка Missing public key проверяет наличие открытого ключа в операциях шифрования и аутентификации. Контролер Missing peer key проверяет наличие однорангового ключа в совместно используемой деривации секрета.

Риск

Без закрытого ключа этап дешифрования, подписи или получения совместно используемого секрета не выполняется. Избыточная операция часто указывает на ошибку кодирования.

Зафиксировать

Проверьте размещение операции (расшифровка, подпись или получение совместно используемого секрета). Если операция предназначена, перед выполнением операции убедитесь, что выполнены следующие действия:

  • Создание закрытого ключа, отличного от NULL.

    Например:

    EVP_PKEY *pkey = NULL;
    kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
    
    EVP_PKEY_keygen_init(kctx);
    EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, RSA_2048BITS);
    EVP_PKEY_keygen(kctx, &pkey);

  • Связывание объекта контекста, отличного от NULL, с закрытым ключом.

    Например:

    ctx = EVP_PKEY_CTX_new(pkey, NULL);
    

    Примечание: Если вы используете EVP_PKEY_CTX_new_id вместо EVP_PKEY_CTX_new, объект контекста не связывается с закрытым ключом.

Примеры

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

#include <stddef.h>
#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf;
size_t out_len;

int func(unsigned char *src, size_t len){
  EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
  if (ctx == NULL) fatal_error();

  ret = EVP_PKEY_decrypt_init(ctx);
  if (ret <= 0) fatal_error();
  return EVP_PKEY_decrypt(ctx, out_buf, &out_len, src, len); 
}

В этом примере объект контекста ctx инициализирован с помощью EVP_PKEY_CTX_new_id вместо EVP_PKEY_CTX_new. Функция EVP_PKEY_CTX_new_id не связывает объект контекста с ключом. Тем не менее, EVP_PKEY_decrypt использует этот объект для расшифровки.

Исправление - связывание закрытого ключа с контекстом во время инициализации

Одной из возможных корректировок является использование EVP_PKEY_CTX_new для инициализации контекста и связывания закрытого ключа с объектом контекста. В следующей корректировке закрытый ключ pkey получается из внешнего источника и проверяется на значение NULL перед использованием.

#include <stddef.h>
#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf;
size_t out_len;

int func(unsigned char *src, size_t len, EVP_PKEY *pkey){
  if (pkey == NULL) fatal_error(); 
  
  EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
  if (ctx == NULL) fatal_error();

  ret = EVP_PKEY_decrypt_init(ctx);
  if (ret <= 0) fatal_error();
  return EVP_PKEY_decrypt(ctx, out_buf, &out_len, src, len); 
}

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

Группа: Криптография
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: CRYPTO_PKEY_NO_PRIVATE_KEY
Воздействие: среднее
CWE ID: 310, 320, 573, 664
Представлен в R2018a