Win32 API 日本語リファレンス
ホーム › Security.Cryptography › NCryptVerifyClaimFn

NCryptVerifyClaimFn

コールバック

シグネチャ

HRESULT NCryptVerifyClaimFn(
    NCRYPT_PROV_HANDLE hProv,
    NCRYPT_KEY_HANDLE hSubjectKey,
    NCRYPT_KEY_HANDLE hAuthorityKey,
    DWORD dwClaimType,
    BCryptBufferDesc* pParameterList,
    BYTE* pbClaimBlob,
    DWORD cbClaimBlob,
    BCryptBufferDesc* pOutput,
    DWORD dwFlags
);

パラメーター

フィールド型説明
hProvNCRYPT_PROV_HANDLE
hSubjectKeyNCRYPT_KEY_HANDLEクレームのサブジェクトキーのハンドルです。
hAuthorityKeyNCRYPT_KEY_HANDLEクレームの検証に使用する機関キーのハンドルです。特定のクレームの種類では機関キーが自己完結しているため、このパラメーターは省略可能です。
dwClaimTypeDWORDクレームの種類です。
pParameterListBCryptBufferDesc*省略可能なパラメーターリストです。
pbClaimBlobBYTE*入力となるクレーム blob です。
cbClaimBlobDWORDpbClaimBlob バッファーのサイズ (バイト単位) です。
pOutputBCryptBufferDesc*出力 blob です。
dwFlagsDWORD

NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG は、VBS が生成したクレームの検証時に設定する新しいフラグです。詳細については解説のセクションを参照してください。

現時点では、ほかにフラグは定義されていません。それ以外の検証の種類では、dwFlags パラメーターに 0 を設定してください。

公式ドキュメント

キー構成証明クレームを検証します。

戻り値

関数の成功または失敗を示すステータスコードを返します。

VBS キー保護の構成証明クレームを検証するときに、検証 API から返される可能性のあるエラーコードの一部を次に示します。

戻り値 意味
NTE_BAD_TYPE クレームの種類の入力パラメーターが、入力クレーム blob の種類と異なります。
STATUS_BAD_DATA 入力クレーム blob が無効です。
STATUS_NO_MEMORY (クレームの検証に必要な) メモリの割り当てに失敗しました。
STATUS_INVALID_PARAMETER 必須の入力パラメーターが不足しているか、いずれかのパラメーターの値が不正です。
STATUS_FAIL_CHECK 入力クレーム blob のチェックに失敗しました。
NTE_BAD_VER クレーム blob のバージョンが検証の実装と一致しません。
NTE_BAD_FLAGS dwFlags に指定されたフラグはサポートされていません。

解説(Remarks)

仮想化ベースのセキュリティ (VBS) を使用した秘密キーの保護と構成証明

メモ

VBS フラグに関する情報は、製品として提供される前に大幅に変更される可能性があるプレリリース製品に関するものです。Microsoft は、ここに記載された情報について、明示または黙示を問わずいかなる保証も行いません。

この API は、VBS キー保護 (VBS を使用して秘密キーを保護し構成証明を行う Windows のモジュール) に基づく、セキュリティキーの高度な構成証明を可能にします。セキュリティキーの構成証明は、そのキーとアンカーとなるキー (構成証明キー) との関連付けを証明します。この機能は、コンテキスト外のキーの使用を制限することで、異なるエンティティ間の通信のセキュリティレベルを高めることができます。

この API は、VBS キー保護の構成証明キーに基づく構成証明クレームの作成と検証をサポートするために、新しいフラグを定義します。

この API に対して定義されている dwClaimType の種類は次のとおりです。

クレームの種類 説明
NCRYPT_CLAIM_VBS_ROOT 生成されたクレームが VBS ルートキーによって作成されたことを示します。
NCRYPT_CLAIM_VBS_IDENTITY 生成されたクレームが VBS の ID/構成証明によって作成されたことを示します。これは、構成証明フラグ NCRYPT_ALLOW_KEY_ATTESTATION_FLAG で昇格された VBS キーによってクレームが作成されたことを意味します (詳細は後述)。

構成証明クレームを検証するときに pParameterList バッファーに設定するバッファーの種類は次のとおりです。

例

この例は、NCryptCreateClaim で生成された構成証明クレームを検証するために、既存の API を使用する方法を示します。

検証 API は、ローカル (クレーム blob を生成したコンピューター上) でもリモートでも呼び出すことができます。検証の手順では、クレームの生成に使用したキーに対応する次の要素が必要です。

検証 API は、入力フラグ NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG が設定されている場合、出力の情報構造体 NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS または NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS のいずれかを生成します。これらの構造体のメモリは、メモリリークを避けるためにコードフローの最後で解放されます。

HRESULT VerifyClaim(
       BCRYPT_RSAKEY_BLOB *pAttestPublicKeyBlob,
       BCRYPT_RSAKEY_BLOB *pTokenPublicKeyBlob,
       PBYTE pRootClaim,
       DWORD rootClaimSize,
       PBYTE pIdentityClaim,
       DWORD identityClaimSize)
{

    HRESULT hr = S_OK;
    DWORD bytesWritten = 0;

    NCRYPT_PROV_HANDLE provider = NULL;

    if (FAILED(hr = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0)))
    {
        wprintf(L"Error opening storage provider in NCryptOpenStorageProvider: 0x%X\n", hr);
        goto cleanup;
    }

    NCRYPT_KEY_HANDLE attestPublicKey = NULL;

    if (FAILED(hr = NCryptImportKey(
                       provider,
                       NULL,
                       BCRYPT_RSAPUBLIC_BLOB,
                       NULL,
                       &attestPublicKey,
                       (PBYTE)pAttestPublicKeyBlob,
                       GetRsaPublicKeyBlobSize(pAttestPublicKeyBlob),
                       0)))
    {
        wprintf(L"Unable to create a key handle for attestation public key blob with NCryptImportKey(): 0x%X\n", hr);
        goto cleanup;
    }

    NCRYPT_KEY_HANDLE tokenPublicKey = NULL;

    if (FAILED(hr = NCryptImportKey(
                       provider,
                       NULL,
                       BCRYPT_RSAPUBLIC_BLOB,
                       NULL,
                       &tokenPublicKey,
                       (PBYTE)pTokenPublicKeyBlob,
                       GetRsaPublicKeyBlobSize(pTokenPublicKeyBlob),
                       0)))
    {
        wprintf(L"Unable to create a key handle for token public key blob with NCryptImportKey(): 0x%X\n", hr);
        goto cleanup;
    }

    NCryptBufferDesc rootOutput{};

    // Verify the VBS root claim using the attestation/identity public key
    if (FAILED(hr = NCryptVerifyClaim(
                       attestPublicKey,
                       NULL,
                       NCRYPT_CLAIM_VBS_ROOT, // Created claim by IDKS (VBS root signing key)
                       NULL, // parameters
                       pRootClaim,
                       rootClaimSize,
                       &rootOutput,
                       NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG /*dwFlags*/)))
    {
        switch (hr)
        {
            case STATUS_OBJECT_TYPE_MISMATCH:
                wprintf(L"The dwClaimType parameter’s value is different than the claim’s type.\n-----\n", hr);
                break;
            case STATUS_BAD_DATA:
                wprintf(L"Something wrong in one of the data structures. E.g. Magic value mismatch\n-----\n", hr);
                break;
            case STATUS_NO_MEMORY:
                wprintf(L"Memory allocation failed\n-----\n", hr);
                break;
            case STATUS_INVALID_PARAMETER:
                wprintf(L"Missing mandatory parameter or one of the parameters has a bad value.\n-----\n", hr);
                break;
            case STATUS_FAIL_CHECK:
                wprintf(L"One of the claim checks has failed.\n-----\n", hr);
                break;
            default:
                wprintf(L"Unable to verify VBS root claim from NCryptVerifyClaim(): 0x%X\n-----\n", hr);
        }
        goto cleanup;
    }

    PNCryptBuffer pRootOutBuffer;
    DWORD count;

    // Look into the retrieved VBS root claim details
    for (count = 0; count < rootOutput.cBuffers; ++count)
    {
        pRootOutBuffer = rootOutput.pBuffers[count];
        if (pRootOutBuffer->BufferType == NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS)
        {
            PNCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS pDetails =
            (PNCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS) pRootOutBuffer->pvBuffer;
            wprintf(L"The claim trustlet id is: %lu\n-----\n", pDetails->ullTrustletId);
            wprintf(L"The claim trustlet Security Version number is: %llu\n-----\n", pDetails->ulTrustletSecurityVersion);
        }
    }

    NCryptBufferDesc identityOutput{};

    // Verify the identity claim using the attestation/identity and token public keys
    if (FAILED(hr = NCryptVerifyClaim(
                        tokenPublicKey,
                        attestPublicKey,
                        NCRYPT_CLAIM_VBS_IDENTITY, // Claim created by an attestation/identity key
                        NULL, // parameters
                        pIdentityClaim,
                        identityClaimSize,
                        &identityOutput,
                        NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG /*dwFlags*/)))
    {
        wprintf(L"Unable to verify identity claim from NCryptVerifyClaim(): 0x%X\n-----\n", hr);
        goto cleanup;
    }

    PNCryptBuffer pIdentityOutBuffer;

    // Look into the retrieved identity claim details
    for (count = 0; count < identityOutput.cBuffers; ++count)
    {
        pIdentityOutBuffer = identityOutput.pBuffers[count];
        if (pIdentityOutBuffer->BufferType == NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS)
        {
            PNCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS pDetails =
            (PNCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS) pIdentityOutBuffer->pvBuffer;
            wprintf(L"The claim hash algorithm is: %S\n-----\n", pDetails-> pszSignatureHashAlg);
            wprintf(L"The claim padding scheme is: %lu\n-----\n", pDetails->ulPaddingScheme);
        }
    }

    wprintf(L"Verify claim for root and identity types passed successfully\n");

    cleanup:

    if (provider != NULL)
    {
        NCryptFreeObject(provider);
    }
    if (attestPublicKey != NULL)
    {
        CryptDestroyKey(attestPublicKey);
    }
    if (tokenPub != NULL)
    {
        CryptDestroyKey(tokenPublicKey);
    }
    if (rootOutput.pBuffers != NULL)
    {
        for (count = 0; count < rootOutput.cBuffers; ++count)
        {
            NCryptFreeBuffer(rootOutput.pBuffers[count].pvBuffer);
        }
        NCryptFreeBuffer(rootOutput.pBuffers);
    }

    if (identityOutput.pBuffers != NULL)
    {
        for (count = 0; count < identityOutput.cBuffers; ++count)
        {
            NCryptFreeBuffer(identityOutput.pBuffers[count].pvBuffer);
        }
        NCryptFreeBuffer(identityOutput.pBuffers);
    }

    return hr;
}

DWORD GetRsaPublicKeyBlobSize(BCRYPT_RSAKEY_BLOB* publicKeyBlob)
{
    return sizeof(BCRYPT_RSAKEY_BLOB) +
                publicKeyBlob->cbModulus +
                publicKeyBlob->cbPublicExp;
}
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)