証明書の失効リスト
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]
このトピックでは、認定出力保護プロトコル (COPP) を使用する場合に、失効したドライバーの証明書失効リスト (CRL) を調べる方法について説明します。
CRL には失効した証明書のダイジェストが含まれており、Microsoft のみが提供および署名できます。 CRL は、デジタル著作権管理 (DRM) ライセンスを通じて配布されます。 CRL は、ドライバーの証明書チェーン内のすべての証明書を取り消すことができます。 チェーン内の証明書が失効した場合、その証明書とそのチェーン内のその下にあるすべての証明書も取り消されます。
CRL を取得するには、アプリケーションで Windows Media Format SDK バージョン 9 以降を使用し、次の手順を実行する必要があります。
- WMCreateReader を呼び出して、Windows Media Format SDK リーダー オブジェクトを作成します。
- IWMDRMReader インターフェイスのリーダー オブジェクトに対してクエリを実行します。
- 値が g_wszWMDRMNet_Revocation の IWMDRMReader::GetDRMProperty を呼び出して CRL を取得します。 このメソッドを 2 回呼び出す必要があります。割り当てるバッファーのサイズを取得するには 1 回、バッファーを埋めるには 1 回を呼び出します。 2 番目の呼び出しでは、CRL を含む文字列が返されます。 文字列全体が base-64 でエンコードされています。
- base-64 でエンコードされた文字列をデコードします。 これを行うには、 CryptStringToBinary 関数を使用できます。 この関数は CryptoAPI の一部です。
注意
IWMDRMReader インターフェイスを使用するには、Microsoft から静的 DRM ライブラリを取得し、アプリケーションをこのライブラリ ファイルにリンクする必要があります。 詳細については、Windows Media Format SDK ドキュメントの「必要な DRM ライブラリの取得」を参照してください。
CRL がユーザーのコンピューターに存在しない場合、 GetDRMProperty メソッドはNS_E_DRM_UNSUPPORTED_PROPERTYを返します。 現在、CRL を取得する唯一の方法は、DRM ライセンスを取得することです。
次のコードは、CRL を返す関数を示しています。
////////////////////////////////////////////////////////////////////////
// Name: GetCRL
// Description: Gets the certificate revocation list (CRL).
//
// ppBuffer: Receives a pointer to the buffer that contains the CRL.
// pcbBuffer: Receives the size of the buffer returned in ppBuffer.
//
// The caller must free the returned buffer by calling CoTaskMemFree.
////////////////////////////////////////////////////////////////////////
HRESULT GetCRL(BYTE **ppBuffer, DWORD *pcbBuffer)
{
IWMReader *pReader = NULL;
IWMDRMReader *pDrmReader = NULL;
HRESULT hr = S_OK;
// DRM attribute data.
WORD cbAttributeLength = 0;
BYTE *pDataBase64 = NULL;
WMT_ATTR_DATATYPE type;
// Buffer for base-64 decoded CRL.
BYTE *pCRL = NULL;
DWORD cbCRL = 0;
// Create the WMReader object.
hr = WMCreateReader(NULL, 0, &pReader);
// Query for the IWMDRMReader interface.
if (SUCCEEDED(hr))
{
hr = pReader->QueryInterface(
IID_IWMDRMReader, (void**)&pDrmReader);
}
// Call GetDRMProperty once to find the size of the buffer.
if (SUCCEEDED(hr))
{
hr = pDrmReader->GetDRMProperty(
g_wszWMDRMNET_Revocation,
&type,
NULL,
&cbAttributeLength
);
}
// Allocate a buffer.
if (SUCCEEDED(hr))
{
pDataBase64 = (BYTE*)CoTaskMemAlloc(cbAttributeLength);
if (pDataBase64 == NULL)
{
hr = E_OUTOFMEMORY;
}
}
// Call GetDRMProperty again to get the property.
if (SUCCEEDED(hr))
{
hr = pDrmReader->GetDRMProperty(
g_wszWMDRMNET_Revocation,
&type,
pDataBase64,
&cbAttributeLength
);
}
// Find the size of the buffer for the base-64 decoding.
if (SUCCEEDED(hr))
{
BOOL bResult = CryptStringToBinary(
(WCHAR*)pDataBase64, // Base-64 encoded string.
0, // Null-terminated.
CRYPT_STRING_BASE64,
NULL, // Buffer (NULL).
&cbCRL, // Receives the size of the buffer.
NULL, NULL // Optional.
);
if (!bResult)
{
hr = __HRESULT_FROM_WIN32(GetLastError());
}
}
// Allocate a buffer for the CRL.
if (SUCCEEDED(hr))
{
pCRL = (BYTE*)CoTaskMemAlloc(cbCRL);
if (pCRL == NULL)
{
hr = E_OUTOFMEMORY;
}
}
// Base-64 decode to get the CRL.
if (SUCCEEDED(hr))
{
BOOL bResult = CryptStringToBinary(
(WCHAR*)pDataBase64, // Base-64 encoded string.
0, // Null-terminated.
CRYPT_STRING_BASE64,
pCRL, // Buffer.
&cbCRL, // Receives the size of the buffer.
NULL, NULL // Optional.
);
if (!bResult)
{
hr = __HRESULT_FROM_WIN32(GetLastError());
}
}
// Return the buffer to the caller. Caller must free the buffer.
if (SUCCEEDED(hr))
{
*ppBuffer = pCRL;
*pcbBuffer = cbCRL;
}
else
{
CoTaskMemFree(pCRL);
}
CoTaskMemFree(pDataBase64);
SAFE_RELEASE(pReader);
SAFE_RELEASE(pDrmReader);
return hr;
}
次に、アプリケーションは CRL が有効であることを確認する必要があります。 これを行うには、CRL の一部である CRL 証明書が Microsoft ルート証明書によって直接署名され、SignCRL 要素の値が 1 に設定されていることを確認します。 また、CRL の署名を確認します。
CRL が検証されると、アプリケーションはそれを格納できます。 CRL のバージョン番号も、保存する前に確認して、アプリケーションが常に最新バージョンを格納するようにする必要があります。
CRL の形式は次のとおりです。
Section | 内容 |
---|---|
ヘッダー | 32 ビット CRL バージョン 32 ビットのエントリ数 |
失効エントリ | 複数の 160 ビット失効エントリ |
Certificate | 32 ビット証明書の長さバリアント長証明書 |
署名 | 8 ビット署名の種類 16 ビット署名の長さVariable-length signature |
注意
すべての整数値は符号なしであり、ビッグ エンディアン (ネットワーク バイト順) 表記で表されます。
CRL セクションの説明
-
ヘッダー
-
ヘッダーには、CRL のバージョン番号と CRL 内の失効エントリの数が含まれています。 CRL には、0 個以上のエントリを含めることができます。
-
失効エントリ
-
各失効エントリは、失効した証明書の 160 ビット ダイジェストです。 このダイジェストを証明書内の DigestValue 要素と比較します。
-
証明 書
-
証明書セクションには、XML 証明書とその証明書チェーンの長さ (バイト単位) を示す 32 ビット値と、証明機関 (CA) の XML 証明書と、ルートとして Microsoft を持つ証明書チェーンの両方を含むバイト配列が含まれています。 証明書は、CRL を発行する権限を持つ CA によって署名されている必要があります。
注意
証明書を null で終了させてはいけません。
-
Signature
-
署名セクションには、署名の種類と長さ、およびデジタル署名自体が含まれています。 8 ビット型は 2 に設定され、SHA-1 と 1024 ビット RSA 暗号化が使用されていることを示します。 長さは、デジタル署名の長さをバイト単位で含む 16 ビット値です。 デジタル署名は、CRL の以前のすべてのセクションで計算されます。
署名は、PKCS #1 (バージョン 2.1) で定義されている RSASSA-PSS デジタル署名スキームを使用して計算されます。 ハッシュ関数は SHA-1 で、連邦情報処理標準 (FIPS) 180-2 で定義され、マスク生成関数は MGF1 です。これは、PKCS #1 (バージョン 2.1) のセクション B.2.1 で定義されています。 RSASP1 および RSAVP1 操作では、検証指数が 65537 の 1024 ビットの剰余を持つ RSA が使用されます。
関連トピック