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

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

Риск

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

Фиксация

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

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

    Например:

    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_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
Влияние: носитель
ID CWE: 310, 320, 573, 664

Введенный в R2018a