メインコンテンツ

コンテキストに追加されたデータがありません

空のコンテキストに対するハッシュ演算の実行によってランタイム エラーが発生する可能性がある

説明

この欠陥は、null データでメッセージ ダイジェスト コンテキストの更新のみを行った場合、または更新ステップを実行せずにメッセージ ダイジェスト コンテキストに対する最終ステップを実行した場合に発生します。

メッセージ ダイジェスト関数を使用する場合は、通常、メッセージ ダイジェスト コンテキストを初期化し、1 回以上の更新ステップを実行してコンテキストにデータを追加します。その後で、最終ステップとして、コンテキスト内のデータの署名、検証、または取得を実行します。

チェッカーは、コンテキストに関して利用できる情報がなければ、欠陥を報告しません。そのような例としては、ハッシュ演算を呼び出す関数に引数としてコンテキストが渡された場合や、関数のスコープ外でコンテキストが宣言された場合が挙げられます。たとえば、以下のコード スニペットでは欠陥が報告されません。

void bar(unsigned char* src, int len, EVP_MD_CTX *ctx) {
    //ctx passed as argument of bar()
    EVP_DigestFinal(ctx, out_buf, &out_len); //no defect
}
EVP_MD_CTX glob_ctx;
void foo(unsigned char* src, int len) {
    //glob_ctx declared outside scope of foo()
    EVP_DigestFinal(&glob_ctx, out_buf, &out_len); //no defect
}

リスク

null データを使用してコンテキストに対する更新ステップを実行すると、ランタイム エラーが発生する可能性があります。

データなしでコンテキストに対する最終ステップを実行すると、予期せぬ動作が発生する可能性があります。

修正方法

コンテキスト内のデータの署名、検証、または取得を実行する前に、非 null データを使用したメッセージ ダイジェスト コンテキストに対する更新操作を 1 回以上実行します。

すべて展開する

#include <openssl/evp.h>
#include <stdio.h>

unsigned char out_buf[EVP_MAX_MD_SIZE];
unsigned int out_len;

void func(unsigned char* src, int len)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);


    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, src, len);
    EVP_MD_CTX_init(&ctx);
    EVP_DigestFinal(&ctx, out_buf, &out_len);
}

この例では、メッセージ ダイジェスト コンテキスト ctx が初期化され、コンテキストに src データを追加するための更新操作が実行されます。その後で、コンテキストが再初期化されますが、ctx にデータが追加される前に EVP_DigestFinalctx からデータを取得しようとするため、エラーになります。

修正 — コンテキストの再初期化の前に最終ステップを実行する

1 つの修正方法として、コンテキストを再初期化する前に、コンテキストからデータを取得する最終ステップを実行します。

#include <openssl/evp.h>
#include <stdio.h>

unsigned char out_buf[EVP_MAX_MD_SIZE];
unsigned int out_len;

void func(unsigned char* src, int len)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);


    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, src, len);
    EVP_DigestFinal(&ctx, out_buf, &out_len);
    EVP_MD_CTX_init(&ctx);
} 
#include <openssl/evp.h>
#include <stdio.h>

unsigned char out_buf[EVP_MAX_MD_SIZE];
unsigned int out_len;

void func(unsigned char* src, int len)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);
    size_t cnt = 0;

    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, src, cnt);
    EVP_DigestFinal(&ctx, out_buf, &out_len);
}

この例では、更新操作中にデータのゼロ バイトがメッセージ ダイジェスト コンテキストにハッシュされます。最終ステップでコンテキストからデータを取得すると、予期せぬ動作が発生します。

修正 — 非 Null データをコンテキストに追加する

1 つの修正方法として、コンテキストからデータを取得する前に、更新ステップでコンテキストにデータを追加します。

#include <openssl/evp.h>
#include <stdio.h>

unsigned char out_buf[EVP_MAX_MD_SIZE];
unsigned int out_len;

void func(unsigned char* src, int len)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);

    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, src, len);
    EVP_DigestFinal(&ctx, out_buf, &out_len);
}

結果情報

グループ: 暗号化
言語: C | C++
既定値: オフ
コマンド ライン構文: CRYPTO_MD_NO_DATA
影響度: Medium

バージョン履歴

R2020a で導入