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
);パラメーター
| フィールド | 型 | 説明 |
|---|---|---|
| hProv | NCRYPT_PROV_HANDLE | |
| hSubjectKey | NCRYPT_KEY_HANDLE | クレームのサブジェクトキーのハンドルです。 |
| hAuthorityKey | NCRYPT_KEY_HANDLE | クレームの検証に使用する機関キーのハンドルです。特定のクレームの種類では機関キーが自己完結しているため、このパラメーターは省略可能です。 |
| dwClaimType | DWORD | クレームの種類です。 |
| pParameterList | BCryptBufferDesc* | 省略可能なパラメーターリストです。 |
| pbClaimBlob | BYTE* | 入力となるクレーム blob です。 |
| cbClaimBlob | DWORD | pbClaimBlob バッファーのサイズ (バイト単位) です。 |
| pOutput | BCryptBufferDesc* | 出力 blob です。 |
| dwFlags | DWORD | NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG は、VBS が生成したクレームの検証時に設定する新しいフラグです。詳細については解説のセクションを参照してください。 現時点では、ほかにフラグは定義されていません。それ以外の検証の種類では、dwFlags パラメーターに |
公式ドキュメント
キー構成証明クレームを検証します。
戻り値
関数の成功または失敗を示すステータスコードを返します。
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 バッファーに設定するバッファーの種類は次のとおりです。
NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS
dwClaimType に NCRYPT_CLAIM_VBS_ROOT を指定した NCryptVerifyClaim の出力パラメーター NCryptBufferDesc 内で、種類 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS の NCryptBuffer 項目として設定する新しい構造体です。構造体の定義は次のとおりです。
typedef struct _NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS { ULONG ulKeyFlags; ULONGLONG ullTrustletId; ULONG ulTrustletSecurityVersion; ULONG ulTrustletDebuggable; } NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS, *PNCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS;この構造体には次の項目が含まれます。
- ulKeyFlags – ID キーに対して設定された NCRYPT_VBS_KEY_FLAG_* 値の組み合わせです。
- ullTrustletId – クレームを作成した VBS トラストレットのポリシーメタデータにハードコードされた識別子の整数です。
- ulTrustletSecurityVersion – クレームを作成した VBS トラストレットのセキュリティバージョン番号です。このバージョンは、そのトラストレットに適用されたセキュリティ更新プログラムを反映しており、結果としてそのセキュリティレベルを示します。
- ulTrustletDebuggable – クレームを作成した VBS トラストレットがデバッグ可能かどうかを示します。値
1はトラストレットがデバッグ可能であることを示し、0はデバッグ不可能であることを示します。
将来さらに情報項目が必要になった場合は、新しい構造体と対応する構造体の種類が定義されます。
メモこの出力パラメーターは、参照されなくなった後に解放する必要があります。
NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS
dwClaimType に NCRYPT_CLAIM_VBS_IDENTITY を指定した NCryptVerifyClaim の出力パラメーター NCryptBufferDesc 内で、種類 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS の NCryptBuffer 項目として設定する新しい構造体です。構造体の定義は次のとおりです。
typedef struct _NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS { ULONG ulKeyFlags; LPCWSTR pszSignatureHashAlg; ULONG ulPaddingScheme; LPCWSTR pszPaddingHashAlg; ULONG ulPaddingSalt; } NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS, *PNCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS;この構造体には次の項目が含まれます。
- ulKeyFlags – ID キーに対して設定された NCRYPT_VBS_KEY_FLAG_* 値の組み合わせです。
- pszSignatureHashAlg - クレームの署名ハッシュアルゴリズムを表す Unicode 文字列へのポインターです。
- ulPaddingScheme - クレームの作成時に BCryptSignHash で使用された署名アルゴリズムのパディングスキームです。
- pszPaddingHashAlg - クレームの作成時に BCryptSignHash で使用された、クレームのパディングハッシュアルゴリズムを表す Unicode 文字列へのポインターです。
- ulPaddingSalt - クレームの作成時に BCryptSignHash で使用された署名アルゴリズムのパディングソルトです。
将来さらに情報項目が必要になった場合は、新しい構造体と対応する構造体の種類が定義されます。
メモこの出力パラメーターは、参照されなくなった後に解放する必要があります。このパラメーターを解放するサンプルコードは、後述のコード例に示します。
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS
NCryptVerifyClaim の NCryptBufferDesc 型パラメーター *pOutput 内の NCryptBuffer パラメーターに設定する新しいバッファーの種類です。この種類は、NCryptBuffer にデータ構造体 NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS が含まれることを示します。
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS
NCryptVerifyClaim の NCryptBufferDesc 型パラメーター *pOutput 内の NCryptBuffer パラメーターに設定する新しいバッファーの種類です。この種類は、NCryptBuffer にデータ構造体 NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS が含まれることを示します。
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG
これは、VBS が生成したクレームの検証時に dwFlags 入力パラメーターに設定する新しいフラグです。このフラグが設定されると、NCryptVerifyClaim は内部に NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS または NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS のパラメーターバッファーの種類を持つ出力パラメーター NCryptBufferDesc を生成します。
次の表は、NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG を指定して成功した場合の、入力と出力のデータ構造体の種類の関係を示します。
入力 出力 dwClaimType = NCRYPT_CLAIM_VBS_ROOT内部に情報構造体 NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS を持つ NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS バッファーの種類。 dwClaimType = NCRYPT_CLAIM_VBS_IDENTITY内部に情報構造体 NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS を持つ NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS バッファーの種類。
例
この例は、NCryptCreateClaim で生成された構成証明クレームを検証するために、既存の API を使用する方法を示します。
検証 API は、ローカル (クレーム blob を生成したコンピューター上) でもリモートでも呼び出すことができます。検証の手順では、クレームの生成に使用したキーに対応する次の要素が必要です。
- クレーム blob
- 公開構成証明キーの blob
- 公開トークン (汎用) キーの 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 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)