Listas de Revogação de Certificados

[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

Este tópico descreve como examinar a CRL (lista de revogação de certificados) para drivers revogados ao usar o COPP (Certified Output Protection Protocol).

A CRL contém resumos de certificados revogados e pode ser fornecida e assinada apenas pela Microsoft. A CRL é distribuída por meio de licenças drm (gerenciamento de direitos digitais). A CRL pode revogar qualquer certificado na cadeia de certificados do driver. Se qualquer certificado na cadeia for revogado, esse certificado e todos os certificados abaixo dele na cadeia também serão revogados.

Para obter a CRL, o aplicativo deve usar o SDK de Formato de Mídia do Windows, versão 9 ou posterior e executar as seguintes etapas:

  1. Chame WMCreateReader para criar o objeto de leitor do SDK de Formato de Mídia do Windows.
  2. Consulte o objeto leitor para a interface IWMDRMReader .
  3. Chame IWMDRMReader::GetDRMProperty com um valor de g_wszWMDRMNet_Revocation para obter a CRL. Você deve chamar esse método duas vezes: uma vez para obter o tamanho do buffer a ser alocado e uma vez para preencher o buffer. A segunda chamada retorna uma cadeia de caracteres que contém a CRL. Toda a cadeia de caracteres é codificada em base 64.
  4. Decodificar a cadeia de caracteres codificada em base 64. Você pode usar a função CryptStringToBinary para fazer isso. Essa função faz parte do CryptoAPI.

Observação

Para usar a interface IWMDRMReader , você deve obter uma biblioteca DRM estática da Microsoft e vincular seu aplicativo a esse arquivo de biblioteca. Para obter mais informações, consulte o tópico "Obtendo a biblioteca de DRM necessária" na documentação do SDK de Formato de Mídia do Windows.

 

Se a CRL não estiver presente no computador do usuário, o método GetDRMProperty retornará NS_E_DRM_UNSUPPORTED_PROPERTY. Atualmente, a única maneira de obter a CRL é adquirir uma licença drm.

O código a seguir mostra uma função que retorna a 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;
}

Em seguida, o aplicativo deve verificar se a CRL é válida. Para fazer isso, verifique se o certificado CRL, que faz parte da CRL, é assinado diretamente pelo Certificado Raiz da Microsoft e tem o valor do elemento SignCRL definido como 1. Além disso, verifique a assinatura da CRL.

Depois que a CRL for verificada, o aplicativo poderá armazená-la. O número de versão da CRL também deve ser verificado antes de armazenar para que o aplicativo sempre armazene a versão mais recente.

A CRL tem o seguinte formato.

Seção Sumário
parâmetro Número de entradas de 32 bits crl versão32 bits
Entradas de revogação Várias entradas de revogação de 160 bits
Certificado Certificado de 32 bits lengthVariable-length certificate
Assinatura Assinatura de 8 bits tipo 16 bits assinatura lengthVariable-length signature

 

Observação

Todos os valores inteiros não são assinados e são representados na notação big-endian (ordem de bytes de rede).

 

Descrições da seção CRL

Header

O cabeçalho contém o número de versão da CRL e o número de entradas de revogação na CRL. Uma CRL pode conter zero ou mais entradas.

Entradas de revogação

Cada entrada de revogação é o resumo de 160 bits de um certificado revogado. Compare esse resumo com o elemento DigestValue dentro do certificado.

Certificado

A seção de certificado contém um valor de 32 bits que indica o comprimento (em bytes) do certificado XML e sua cadeia de certificados, juntamente com uma matriz de bytes que contém o certificado XML da AC (Autoridade de Certificação) e a cadeia de certificados que tem a Microsoft como a Raiz. O certificado deve ser assinado por uma AC que tenha autoridade para emitir CRLs.

Observação

O certificado não deve ser encerrado em nulo.

 

Signature

A seção de assinatura contém o tipo de assinatura e o comprimento e a própria assinatura digital. O tipo de 8 bits é definido como 2 para indicar que ele usa SHA-1 com criptografia RSA de 1024 bits. O comprimento é um valor de 16 bits que contém o comprimento da assinatura digital em bytes. A assinatura digital é calculada em todas as seções anteriores da CRL.

A assinatura é calculada usando o esquema de assinatura digital RSASSA-PSS definido no PKCS nº 1 (versão 2.1). A função de hash é SHA-1, que é definida em Padrão de Processamento de Informações Federais (FIPS) 180-2, e a função de geração de máscara é MGF1, que é definida na seção B.2.1 no PKCS nº 1 (versão 2.1). As operações RSASP1 e RSAVP1 usam RSA com um módulo de 1024 bits com um expoente de verificação de 65537.

Usando o COPP (Certified Output Protection Protocol)