Поделиться через


Списки отзыва сертификатов

[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngineи аудио и видеозахват в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать новый код MediaPlayer, IMFMediaEngine и аудио-видеозахват в Media Foundation вместо DirectShowпо возможности. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]

В этом разделе описывается, как проверить список отзыва сертификатов (CRL) для отозванных драйверов при использовании протокола COPP сертифицированной защиты вывода.

CRL содержит дайджесты отозванных сертификатов и может быть предоставлен и подписан только корпорацией Майкрософт. CRL распространяется через лицензии управления цифровыми правами (DRM). CRL может отозвать любой сертификат в цепочке сертификатов драйвера. Если сертификат в цепочке отозван, этот сертификат и все сертификаты под ним в цепочке также отзываются.

Чтобы получить список отзыва сертификатов, приложение должно использовать пакет SDK для формата Windows Media, версию 9 или более позднюю версию и выполнить следующие действия:

  1. Вызовите WMCreateReader, чтобы создать объект средства чтения пакета SDK для формата Windows Media.
  2. Запросите объект чтения для интерфейса IWMDRMReader.
  3. Вызовите IWMDRMReader::GetDRMProperty со значением g_wszWMDRMNet_Revocation, чтобы получить список отзыва сертификатов. Этот метод необходимо вызвать дважды: один раз, чтобы получить размер буфера для выделения, и один раз, чтобы заполнить буфер. Второй вызов возвращает строку, содержащую список отзыва сертификатов. Вся строка закодирована в кодировке Base-64.
  4. Декодирование строки в кодировке Base-64. Для этого можно использовать функцию CryptStringToBinary. Эта функция входит в состав CryptoAPI.

Заметка

Чтобы использовать интерфейс IWMDRMReader, необходимо получить статическую библиотеку DRM от Корпорации Майкрософт и связать приложение с этим файлом библиотеки. Дополнительные сведения см. в разделе "Получение обязательной библиотеки DRM" в документации по пакету SDK для формата Windows Media.

 

Если список отзыва сертификатов отсутствует на компьютере пользователя, метод GetDRMProperty возвращает NS_E_DRM_UNSUPPORTED_PROPERTY. В настоящее время единственным способом получения списка отзыва сертификатов является получение лицензии DRM.

В следующем коде показана функция, которая возвращает список отзыва сертификатов:

////////////////////////////////////////////////////////////////////////
//  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, подписан корневым сертификатом Майкрософт и имеет значение элемента SignCRL равным 1. Кроме того, проверьте подпись списка отзыва сертификатов.

После проверки списка отзыва сертификатов приложение может сохранить его. Необходимо также проверить номер версии CRL перед сохранением, чтобы приложение всегда сохраняло последнюю версию.

Список отзыва сертификатов имеет следующий формат.

Секция Содержание
Заголовок 32-разрядное число записей CRL версии 32
Записи отзыва Несколько 160-разрядных записей отзыва
Сертификат 32-разрядный сертификат lengthVariable-length certificate
Подпись 8-разрядная подпись типа 16-разрядной подписи lengthVariable-length

 

Заметка

Все целые значения не назначены и представлены в нотации big-endian (порядок байтов сети).

 

Описания разделов CRL

Заголовок

Заголовок содержит номер версии списка отзыва и количество записей отзыва в списке отзыва. Список отзыва может содержать ноль или больше записей.

записи отзыва

Каждая запись отзыва — это 160-разрядный дайджест отзыва отозванного сертификата. Сравните этот дайджест с элементом DigestValue в сертификате.

Сертификат

Раздел сертификата содержит 32-разрядное значение, указывающее длину (в байтах) XML-сертификата и его цепочку сертификатов, а также массив байтов, содержащий как XML-сертификат центра сертификации (ЦС), так и цепочку сертификатов, содержащую Корпорацию Майкрософт в качестве корневого. Сертификат должен быть подписан ЦС с центром сертификации, который имеет центр для выдачи списков отзыва сертификатов.

Заметка

Сертификат не должен быть завершен со значением NULL.

 

подпись

Раздел подписи содержит тип и длину подписи, а также сам цифровой подписи. Для 8-разрядного типа задано значение 2, указывающее, что он использует SHA-1 с шифрованием 1024-разрядной RSA. Длина — 16-разрядное значение, содержащее длину цифровой подписи в байтах. Цифровая подпись вычисляется во всех предыдущих разделах списка отзыва сертификатов.

Подпись вычисляется с помощью схемы цифровой подписи RSASSA-PSS, определенной в PKCS #1 (версия 2.1). Хэш-функция — SHA-1, которая определена в федеральном стандарте обработки информации (FIPS) 180-2, а функция создания маски — MGF1, которая определена в разделе B.2.1 в PKCS #1 (версия 2.1). Операции RSASP1 и RSAVP1 используют RSA с 1024-разрядным модулом с экспонентом проверки 65537.

использование сертифицированного протокола защиты выходных данных (COPP)