メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

公開鍵が見つかりません

暗号化操作に使用されるコンテキストが、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);

対応するチェッカー [秘密鍵が見つかりません] は、復号化操作と署名操作で秘密鍵をチェックします。

リスク

公開鍵がないと、暗号化または署名認証ステップが発生しません。冗長な操作は多くの場合、コーディング エラーを示します。

修正方法

操作 (暗号化または署名認証) の配置をチェックします。操作の発生が意図されている場合、操作の前に次のステップを完了するようにします。

  • 非 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 の代わりに EVP_PKEY_CTX_new_id を使用する場合、コンテキスト オブジェクトと公開鍵を関連付けません。

すべて展開する

#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 の代わりに EVP_PKEY_CTX_new_id を使用して初期化されています。関数 EVP_PKEY_CTX_new_id では、コンテキスト オブジェクトをキーに関連付けていません。しかし、関数 EVP_PKEY_encrypt は復号化にこのオブジェクトを使用しています。

修正 — 初期化中に公開鍵をコンテキストと関連付け

1 つの修正方法として、コンテキストの初期化に関数 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++
既定値: オフ
コマンド ライン構文: CRYPTO_PKEY_NO_PUBLIC_KEY
影響度: Medium

バージョン履歴

R2018a で導入