次の方法で共有


証明書チェーンの検証

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

このトピックでは、Certified Output Protection Protocol (COPP) を使用するときにドライバーの証明書チェーンを検証する方法について説明します。

グラフィック ドライバーの証明書チェーンは XML ドキュメントです。 証明書チェーンには、3 つの証明書が含まれています。 最初の証明書は リーフ証明書と呼ばれ、ドライバーの COPP 証明書です。 次の証明書は、独立系ハードウェア ベンダー (IHV) の署名証明書です。 最後の証明書は Microsoft の署名証明書です。 グラフィックス ドライバーが正当な COPP デバイスであることを確認するには、アプリケーションでこれらの 3 つの証明書をすべて検証する必要があります。 アプリケーションがチェーン内の証明書を正しく検証しない場合、悪意のあるプログラムによって COPP が機能しなくなる可能性があります。

COPP 証明書チェーンは UTF-8 文字セットを使用します。 証明書のバイナリ データ (RSA 公開キーなど) は、base64 でエンコードされ、ビッグ エンディアン順に格納されます。 (ビッグ エンディアン とは、最も重要なバイトが、最も低いアドレスを持つメモリの場所に格納されることを意味します)。

証明書内の一部の要素には、証明書の機能が存在することを示すブール値が含まれています。 機能が存在する場合、対応する子要素の値は 1 に設定されます。 機能が存在しない場合、その子要素は証明書に存在しません。

XML 要素の定義

証明書スキーマ内の要素の定義を次に示します。

  • CertificateCollection。 XML ドキュメントのルート要素。 これには、チェーン内の証明書ごとに 1 つずつ、Certificate 要素が含まれています。
  • 証明書。 1 つの証明書が含まれています。 この要素には、Data 要素と Signature 要素が含まれています。
  • データ。 証明書に関する情報が含まれます。 特に、証明書の公開キーと型が含まれています。 Data 要素には、次の子要素が含まれています。
    • PublicKey。 証明書の RSA 公開キーが含まれます。 PublicKey 要素には、RSAKeyValue 要素を含む KeyValue 要素が含まれています。 RSAKeyValue 要素には、Modulus と Exponent という 2 つの子要素があり、公開キーを定義します。 Modulus 要素と Exponent 要素は base64 でエンコードされ、ビッグ エンディアン順に格納されます。
    • KeyUsage。 証明書がドライバーの COPP 証明書の場合、この要素には EncryptKey という子要素が含まれている必要があります。 証明書が IHV の署名証明書または Microsoft の署名証明書である場合は、SignCertificate という子要素が含まれている必要があります。 これらの子要素の両方にブール値が含まれています。
    • SecurityLevel。 この要素は無視する必要があります。
    • ManufacturerData。 グラフィックス デバイスの製造元とモデルを指定します。 この要素は情報提供のみを行います。
    • Features。 証明書の使用方法を指定する子要素が含まれます。 COPP に関連する唯一の要素は COPPCertificate 要素です。 その他の子要素が存在する可能性があります。その場合は、無視する必要があります。 COPPCertificate 要素が存在する場合、証明書は COPP 証明書です。 この要素は、有効な COPP 証明書のリーフ ノードに存在する必要があります。 この要素にはブール値が含まれています。
  • 署名。 この証明書の署名が含まれています。 これには、次の子要素が含まれています。
    • SignedInfo。 署名に関する情報が含まれます。 この要素の重要な子要素は DigestValue 要素であり、Data 要素に対する SHA-1 ハッシュの base64 でエンコードされた値が含まれます。 ダイジェスト値は、証明書失効リスト (CRL) に対して証明書を確認するときに使用されます。
    • SignatureValue。 この値は Data 要素で計算され、Public-Key Cryptography Standards (PKCS) #1 (バージョン 2.1) で定義されている RSASSA-PSS デジタル署名スキームに従って計算されます。 PKCS #1 の詳細については、 を参照してください https://www.rsa.com/
    • KeyInfo。 チェーン内の次の証明書の RSA 公開キーが含まれます。 この要素は、Data 要素内のデータが改ざんされていないことを確認するために使用されます。 この要素の形式は PublicKey 要素と同じです。

証明書の検証

証明書チェーンを正しく検証するには、アプリケーションで次の手順を実行する必要があります。 いずれかのステップが失敗した場合、またはこれらのプロシージャで参照されている要素が存在しない場合、検証は失敗します。

証明書収集の検証手順

証明書チェーンを検証するには、次の手順を実行します。

  1. CertificateCollection が整形式の XML であることを確認します。
  2. CertificateCollection が UTF-8 形式でエンコードされていることを確認します。
  3. CertificateCollection 要素の Version 属性が 2.0 以降であることを確認します。
  4. 証明書チェーンに 3 つの Certificate 要素が含まれていることを確認します。
  5. 証明書チェーン内の各 Certificate 要素をループ処理し、以下で説明する証明書の検証手順をそれぞれ実行します。

証明書の検証手順

チェーン内の証明書を検証するには、次の手順を実行します。

  1. Data 要素内の子要素が重複していないかどうかを確認します。 たとえば、PublicKey 要素は 1 つだけ必要です。
  2. Data/PublicKey/KeyValue/RSAKeyValue/Modulus 要素が存在することを確認します。 base64 デコード値は、ルートを除くすべての証明書に対して 256 バイトの長さである必要があります。 ルート証明書では、この要素の長さは 128 バイトである必要があります。
  3. Data/PublicKey/KeyValue/RSAKeyValue/Exponent 要素が存在することを確認します。 base64 デコード値は 4 バイトを超えてはなりません。
  4. この証明書がリーフ証明書の場合は、次のことを確認します。
    • KeyUsage 要素には、値 1 の EncryptKey 要素が含まれています。
    • Features 要素には、値 1 の COPPCertificate 要素が含まれています。
  5. この証明書がリーフ証明書でない場合は、次のことを確認します。
    • Data/PublicKey 要素の剰余と指数は、前の証明書の Signature/KeyInfo 要素の剰余と指数と正確に一致します。
    • KeyUsage 要素には、値 1 の SignCertificate 要素が含まれています。
  6. SHA-1 ハッシュ アルゴリズムを使用して、証明書の Data 要素のすべてのバイトをハッシュします。 Data タグの最初の文字<から終了 </Data>> タグの最後の文字まで、すべてのバイトをハッシュする必要があります。 「証明書失効リスト」で説明されているように、ハッシュ値を使用して証明書を証明書失効リスト (CRL) に対してチェックします
  7. 手順 6 のハッシュ値を、Signature/SignedInfo/Reference/DigestValue 要素の base64 でデコードされた値と比較します。 これらの値は一致している必要があります。
  8. 以下で説明する署名の確認手順を実行します。
  9. この証明書がチェーン内の最終的な証明書でない場合は、ループの次の反復のために Signature/KeyInfo/KeyValue/RSAKeyValue 値を保存します。
  10. この証明書がチェーンの最後の証明書である場合は、Signature/KeyInfo/KeyValue/RSAKeyValue の値が Microsoft の公開キーと一致していることを確認します。 Microsoft 公開キーには、次の base64 でエンコードされた値があります。
    • 係数:

      pjoeWLSTLDonQG8She6QhkYbYott9fPZ8tHdB128ZETcghn5KHoyin7HkJEcPJ0Eg4UdSv a0KDIYDjA3EXd69R3CN2Wp/QyOo0ZPYWYp3NXpJ700tKPgIplzo5wVd/69g7j+j8M66W7V NmDwaNs9mDc1p2+VVMsDhOsV/Au6E+E=

    • 指数: AQAB

署名の確認手順

SignatureValue 要素の値は、PKCS #1 バージョン 2.1 (以下、PKCS と呼ばれます) で定義されている RSASSA-PSS デジタル署名スキームに従って、Data 要素に対して計算されます。 この署名を確認するには、次の手順を実行します。

  1. Signature/KeyInfo/KeyValue/RSAKeyValue 要素の剰余値と指数値をデコードします。 これらの値は、署名証明書の RSA 公開キーを定義します。
  2. Signature/SignatureValue 要素をデコードします。
  3. PKCS のセクション 8.1.2 で定義されている RSASSA-PSS-Verify 操作を計算します。

RSASSA-PSS-Verify 操作の場合は、次の入力を使用します。

  • (n,e) は、手順 1 の公開キーです。
  • M は、Data 要素内のすべてのバイトです。これには、要素を <囲む Data> タグと </Data> タグが含まれます。
  • S は、手順 2 でデコードされた署名値です。

RSASSA-PSS-Verify 操作では、セクション 9.1.1 で定義されている EMSA-PSS-ENCODE 操作を使用します。 PKCS の。 この操作では、COPP は次のオプションを使用します。

  • ハッシュ = SHA-1
  • hLen = 20
  • MGF (マスク生成関数) = MGF1
  • sLen = 0

マスク生成関数 MGF1 は、PKCS の付録 B.2 で定義されています。 この関数では、COPP は次のオプションを使用します。

  • ハッシュ = SHA-1
  • hLen = 20

RSASSA-PSS-Verify 操作の出力は、署名が有効か無効かを示します。

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