Partager via


Listes de révocation de certificats

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngineet audio/vidéo capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et capture audio/vidéo dans Media Foundation au lieu de directShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Cette rubrique explique comment examiner la liste de révocation de certificats (CRL) pour les pilotes révoqués lors de l’utilisation du protocole COPP (Certified Output Protection Protocol).

La liste de révocation de certificats contient des synthèses de certificats révoqués et peut être fournie et signée uniquement par Microsoft. La liste de révocation de certificats est distribuée par le biais de licences DRM (Digital Rights Management). La liste de révocation de certificats peut révoquer n’importe quel certificat dans la chaîne de certificats du pilote. Si un certificat de la chaîne est révoqué, ce certificat et tous les certificats ci-dessous sont également révoqués.

Pour obtenir la liste de révocation de certificats, l’application doit utiliser le Kit de développement logiciel (SDK) Windows Media Format, version 9 ou ultérieure, et effectuer les étapes suivantes :

  1. Appelez WMCreateReader pour créer l’objet lecteur du Kit de développement logiciel (SDK) Windows Media Format.
  2. Interrogez l’objet lecteur pour l’interface IWMDRMReader.
  3. Appelez IWMDRMReader ::GetDRMProperty avec la valeur g_wszWMDRMNet_Revocation pour obtenir la liste de révocation de certificats. Vous devez appeler cette méthode deux fois : une fois pour obtenir la taille de la mémoire tampon à allouer, et une fois pour remplir la mémoire tampon. Le deuxième appel retourne une chaîne qui contient la liste de révocation de certificats. La chaîne entière est encodée en base 64.
  4. Décodez la chaîne encodée en base 64. Vous pouvez utiliser la fonction CryptStringToBinary pour ce faire. Cette fonction fait partie de CryptoAPI.

Note

Pour utiliser l’interface IWMDRMReader, vous devez obtenir une bibliothèque DRM statique auprès de Microsoft et lier votre application à ce fichier de bibliothèque. Pour plus d’informations, consultez la rubrique « Obtention de la bibliothèque DRM requise » dans la documentation du Kit de développement logiciel (SDK) Windows Media Format.

 

Si la liste de révocation de certificats n’est pas présente sur l’ordinateur de l’utilisateur, la méthode GetDRMProperty retourne NS_E_DRM_UNSUPPORTED_PROPERTY. Actuellement, la seule façon d’obtenir la liste de révocation de certificats consiste à acquérir une licence DRM.

Le code suivant montre une fonction qui retourne la liste de révocation de certificats :

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

Ensuite, l’application doit vérifier que la liste de révocation de certificats est valide. Pour ce faire, vérifiez que le certificat CRL, qui fait partie de la liste de révocation de certificats, est directement signé par le certificat racine Microsoft et que la valeur de l’élément SignCRL est définie sur 1. Vérifiez également la signature de la liste de révocation de certificats.

Une fois la liste de révocation de certificats vérifiée, l’application peut la stocker. Le numéro de version de la liste de révocation de certificats doit également être vérifié avant de stocker afin que l’application stocke toujours la version la plus récente.

La liste de révocation de certificats a le format suivant.

Section Contenu
En-tête Nombre d’entrées de liste de révocation de certificats 32 bits 32 bits 32 bits
Entrées de révocation Plusieurs entrées de révocation 160 bits
Certificat Certificat de longueur de certificat 32 bitsVariable-length
Signature Signature 8 bits type16 bits signature lengthVariable-length

 

Note

Toutes les valeurs entières sont non signées et sont représentées en notation big-endian (ordre d’octet réseau).

 

Descriptions des sections de liste de révocation de certificats

en-tête

L’en-tête contient le numéro de version de la liste de révocation de certificats et le nombre d’entrées de révocation dans la liste de révocation de certificats. Une liste de révocation de certificats peut contenir zéro ou plusieurs entrées.

entrées de révocation de

Chaque entrée de révocation est la synthèse 160 bits d’un certificat révoqué. Comparez cette synthèse avec l’élément DigestValue dans le certificat.

certificat

La section de certificat contient une valeur 32 bits indiquant la longueur (en octets) du certificat XML et sa chaîne de certificats, ainsi qu’un tableau d’octets qui contient à la fois le certificat XML de l’autorité de certification (CA) et la chaîne de certificats qui a Microsoft comme racine. Le certificat doit être signé par une autorité de certification qui dispose de l’autorité de certification pour émettre des listes de révocation de certificats.

Note

Le certificat ne doit pas être arrêté par null.

 

signature

La section signature contient le type et la longueur de la signature, ainsi que la signature numérique elle-même. Le type 8 bits est défini sur 2 pour indiquer qu’il utilise SHA-1 avec chiffrement RSA 1024 bits. La longueur est une valeur 16 bits contenant la longueur de la signature numérique en octets. La signature numérique est calculée sur toutes les sections précédentes de la liste de révocation de certificats.

La signature est calculée à l’aide du schéma de signature numérique RSASSA-PSS défini dans PKCS #1 (version 2.1). La fonction de hachage est SHA-1, qui est définie dans Federal Information Processing Standard (FIPS) 180-2, et la fonction de génération de masque est MGF1, qui est définie dans la section B.2.1 dans PKCS #1 (version 2.1). Les opérations RSASP1 et RSAVP1 utilisent RSA avec un module 1024 bits avec un exposant de vérification de 65537.

à l’aide du protocole COPP (Certified Output Protection Protocol)