Freigeben über


Zertifikatsperrlisten

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]

In diesem Thema wird beschrieben, wie Sie die Zertifikatsperrliste (Certificate Revocation List, CRL) auf gesperrte Treiber untersuchen, wenn Sie das Certified Output Protection Protocol (COPP) verwenden.

Die Zertifikatsperrliste enthält Digests mit widerrufenen Zertifikaten und kann nur von Microsoft bereitgestellt und signiert werden. Die Zertifikatsperrliste wird über DRM-Lizenzen (Digital Rights Management) verteilt. Die Zertifikatsperrliste kann jedes Zertifikat in der Zertifikatkette des Treibers widerrufen. Wenn ein Zertifikat in der Kette widerrufen wird, werden auch dieses Zertifikat und alle darunter liegenden Zertifikate in der Kette widerrufen.

Zum Abrufen der Zertifikatsperrliste muss die Anwendung das Windows Media Format SDK, Version 9 oder höher, verwenden und die folgenden Schritte ausführen:

  1. Rufen Sie WMCreateReader auf, um das Windows Media Format SDK-Readerobjekt zu erstellen.
  2. Fragen Sie das Reader-Objekt für die IWMDRMReader-Schnittstelle ab.
  3. Rufen Sie IWMDRMReader::GetDRMProperty mit dem Wert g_wszWMDRMNet_Revocation auf, um die CRL abzurufen. Sie müssen diese Methode zweimal aufrufen: Einmal, um die Größe des zuzuordnenden Puffers abzurufen, und einmal, um den Puffer aufzufüllen. Der zweite Aufruf gibt eine Zeichenfolge zurück, die die Zertifikatsperrliste enthält. Die gesamte Zeichenfolge ist Base64-codiert.
  4. Decodieren Sie die base64-codierte Zeichenfolge. Dazu können Sie die CryptStringToBinary-Funktion verwenden. Diese Funktion ist Teil von CryptoAPI.

Hinweis

Um die IWMDRMReader-Schnittstelle verwenden zu können, müssen Sie eine statische DRM-Bibliothek von Microsoft abrufen und Ihre Anwendung mit dieser Bibliotheksdatei verknüpfen. Weitere Informationen finden Sie im Thema "Abrufen der erforderlichen DRM-Bibliothek" in der Dokumentation zum Windows Media Format SDK.

 

Wenn die Zertifikatsperrliste nicht auf dem Computer des Benutzers vorhanden ist, gibt die GetDRMProperty-Methode NS_E_DRM_UNSUPPORTED_PROPERTY zurück. Derzeit besteht die einzige Möglichkeit zum Abrufen der Zertifikatsperrliste darin, eine DRM-Lizenz zu erwerben.

Der folgende Code zeigt eine Funktion, die die Zertifikatsperrliste zurückgibt:

////////////////////////////////////////////////////////////////////////
//  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;
}

Als Nächstes muss die Anwendung überprüfen, ob die Zertifikatsperrliste gültig ist. Vergewissern Sie sich hierzu, dass das CRL-Zertifikat, das Teil der Zertifikatsperrliste ist, direkt vom Microsoft-Stammzertifikat signiert ist und der Wert des SignCRL-Elements auf 1 festgelegt ist. Überprüfen Sie auch die Signatur der Zertifikatsperrliste.

Nachdem die Zertifikatsperrliste überprüft wurde, kann sie von der Anwendung gespeichert werden. Die CRL-Versionsnummer sollte auch vor dem Speichern überprüft werden, damit die Anwendung immer die neueste Version speichert.

Die Zertifikatsperrliste hat das folgende Format.

`Section` Contents
Header 32-Bit-CRL Version32-Bit-Anzahl von Einträgen
Sperreinträge Mehrere 160-Bit-Sperreinträge
Zertifikat 32-Bit-ZertifikatlängeVariable-Länge-Zertifikat
Signatur 8-Bit-Signaturtyp16-Bit-SignaturlängeVariable-Length Signature

 

Hinweis

Alle ganzzahligen Werte sind unsigned und werden in der Big-Endian-Notation (Netzwerkbytereihenfolge) dargestellt.

 

CRL-Abschnittsbeschreibungen

Header

Der Header enthält die Versionsnummer der Zertifikatsperrliste und die Anzahl der Sperreinträge in der Zertifikatsperrliste. Eine Zertifikatsperrliste kann null oder mehr Einträge enthalten.

Sperreinträge

Jeder Sperreintrag ist der 160-Bit-Digest eines widerrufenen Zertifikats. Vergleichen Sie diesen Digest mit dem DigestValue-Element innerhalb des Zertifikats.

Zertifikat

Der Zertifikatabschnitt enthält einen 32-Bit-Wert, der die Länge (in Bytes) des XML-Zertifikats und seiner Zertifikatkette angibt, zusammen mit einem Bytearray, das sowohl das XML-Zertifikat der Zertifizierungsstelle (CA) als auch die Zertifikatkette mit Microsoft als Stamm enthält. Das Zertifikat muss von einer Zertifizierungsstelle signiert werden, die über die Berechtigung zum Ausstellen von Zertifikatsperrlisten verfügt.

Hinweis

Das Zertifikat darf nicht null-beendet sein.

 

Signature

Der Signaturabschnitt enthält den Signaturtyp und die Länge sowie die digitale Signatur selbst. Der 8-Bit-Typ ist auf 2 festgelegt, um anzugeben, dass SHA-1 mit 1024-Bit-RSA-Verschlüsselung verwendet wird. Die Länge ist ein 16-Bit-Wert, der die Länge der digitalen Signatur in Bytes enthält. Die digitale Signatur wird über alle vorherigen Abschnitte der Zertifikatsperrliste berechnet.

Die Signatur wird mithilfe des digitalen Signaturschemas RSASSA-PSS berechnet, das in PKCS #1 (Version 2.1) definiert ist. Die Hashfunktion ist SHA-1, die im Federal Information Processing Standard (FIPS) 180-2 definiert ist, und die Maskengenerierungsfunktion ist MGF1, die in Abschnitt B.2.1 in PKCS #1 (Version 2.1) definiert ist. Die Vorgänge RSASP1 und RSAVP1 verwenden RSA mit einem 1024-Bit-Modulus mit einem Überprüfungsexponenten von 65537.

Verwenden des Certified Output Protection Protocol (COPP)