Missing public key

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

Описание

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

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

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

Блок проверки аналогов Missing private 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_encrypt_init(ctx);
  if (ret <= 0) fatal_error();
  return EVP_PKEY_encrypt(ctx, out_buf, &out_len, src, len); 
}

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

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

Одной из возможных коррекций является использование 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_encrypt_init(ctx);
  if (ret <= 0) fatal_error();
  return EVP_PKEY_encrypt(ctx, out_buf, &out_len, src, len); 
}

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

Группа: Криптография
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки : CRYPTO_PKEY_NO_PUBLIC_KEY
Влияние: Средний
ИДЕНТИФИКАТОР CWE : 310, 320, 573, 664
Введенный в R2018a