次の方法で共有


証明書の失効リスト

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]

このトピックでは、認定出力保護プロトコル (COPP) を使用する場合に、失効したドライバーの証明書失効リスト (CRL) を調べる方法について説明します。

CRL には失効した証明書のダイジェストが含まれており、Microsoft のみが提供および署名できます。 CRL は、デジタル著作権管理 (DRM) ライセンスを通じて配布されます。 CRL は、ドライバーの証明書チェーン内のすべての証明書を取り消すことができます。 チェーン内の証明書が失効した場合、その証明書とそのチェーン内のその下にあるすべての証明書も取り消されます。

CRL を取得するには、アプリケーションで Windows Media Format SDK バージョン 9 以降を使用し、次の手順を実行する必要があります。

  1. WMCreateReader を呼び出して、Windows Media Format SDK リーダー オブジェクトを作成します。
  2. IWMDRMReader インターフェイスのリーダー オブジェクトに対してクエリを実行します。
  3. 値が g_wszWMDRMNet_Revocation の IWMDRMReader::GetDRMProperty を呼び出して CRL を取得します。 このメソッドを 2 回呼び出す必要があります。割り当てるバッファーのサイズを取得するには 1 回、バッファーを埋めるには 1 回を呼び出します。 2 番目の呼び出しでは、CRL を含む文字列が返されます。 文字列全体が base-64 でエンコードされています。
  4. 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 が使用されます。

認定出力保護プロトコル (COPP) の使用