メインコンテンツ

X.509 証明書用の秘密鍵が見つかりません

キーが見つからない場合は、ランタイム エラーまたはセキュリティで保護されていない暗号化が発生する可能性がある

説明

この欠陥は、X.509 証明書ファイルを SSL コンテキストに読み込んだが、対応する秘密鍵を読み込まなかった場合またはコンテキストに読み込んだキーが null だった場合に発生します。

通常、TLS/SSL 交換では、サーバーが TLS/SSL ハンドシェイク中にサーバーと公開鍵に関する情報を含む X.509 証明書を送信することによって ID を提供します。証明書を受信したクライアントは、公開鍵を使用して、対応する秘密鍵でしか復号化できないプレマスター シークレットを暗号化して送信します。サーバーは、復号化されたプレマスター シークレットとその他の交換されたメッセージを使用して、通信セッションを暗号化するために使用されるセッション キーを生成します。

チェッカーは以下の場合に欠陥を報告しません。

  • SSL_new を呼び出す関数に引数として SSL コンテキストを渡す。

  • 接続を処理する関数のスコープの外部で SSL コンテキストを宣言する。

リスク

X.509 証明書用の秘密鍵を読み込まなかった場合は、セキュリティで保護されていない暗号化でランタイム エラーが発生する可能性があります。

修正方法

SSL_CTX_use_PrivateKey_file を呼び出すことによって X.509 証明書の秘密鍵を SSL コンテキストに読み込むか、SSL_use_PrivateKey_file を呼び出すことによって秘密鍵を SSL 構造体に読み込みます。

すべて展開する

#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#define SSL_SERVER_CRT "server.pem"

#define fatal_error() exit(-1)

void load_cert(SSL_CTX* ctx, const char* certfile)
{
    int ret = SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;

    /* creation context for the SSL protocol */
    ctx = SSL_CTX_new(SSLv23_server_method());
    if (ctx == NULL) fatal_error();

    /* context configuration */
    load_cert(ctx, SSL_SERVER_CRT);

    /* Handle connection */
    ssl = SSL_new(ctx);
    ret = SSL_accept(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}

この例では、SSL コンテキスト ctx がサーバー役割を使用して開始され、関数 load_cert がサーバー証明書を ctx に読み込みます。その後、サーバーは、クライアントがハンドシェイクを開始するまで待機します。ただし、秘密鍵が SSL 構造体に読み込まれていないため、サーバーはクライアントが送信したプレマスター シークレットを復号化できず、ハンドシェイクが失敗します。

修正 — 秘密鍵を SSL コンテキストに読み込む

1 つの修正方法として、サーバー証明書ファイルを読み込んでから、秘密鍵を SSL コンテキストに読み込みます。

#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#define SSL_SERVER_CRT "server.pem"
#define SSL_SERVER_KEY "server.key"

#define fatal_error() exit(-1)

void load_cert(SSL_CTX* ctx, const char* certfile)
{
    int ret = SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();

    ret = SSL_CTX_use_PrivateKey_file(ctx, SSL_SERVER_KEY, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;

    /* creation context for the SSL protocol */
    ctx = SSL_CTX_new(SSLv23_server_method());
    if (ctx == NULL) fatal_error();

    /* context configuration */
    load_cert(ctx, SSL_SERVER_CRT);

    /* Handle connection */
    ssl = SSL_new(ctx);
    ret = SSL_accept(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}

結果情報

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

バージョン履歴

R2020a で導入