Missing private key

Контекст, используемый для операции криптографии, связан с закрытым ключом 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++
По умолчанию: Off
Синтаксис командной строки : CRYPTO_PKEY_NO_PRIVATE_KEY
Влияние: Средний
ИДЕНТИФИКАТОР CWE : 310, 320, 573, 664
Введенный в R2018a