Недостающий закрытый ключ

Контекст, используемый для операции криптографии, сопоставлен с закрытым ключом 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 проверяет на равноправный ключ в разделяемой секретной деривации.

Риск

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

Фиксация

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

  • Сгенерируйте непустой закрытый ключ.

    Например:

    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);

  • Сопоставьте непустой объект контекста с закрытым ключом.

    Например:

    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++
Значение по умолчанию: 'off'
Синтаксис командной строки: CRYPTO_PKEY_NO_PRIVATE_KEY
Влияние: носитель
ID CWE: 310, 320, 573, 664

Введенный в R2018a