Enviando solicitações de status copp
[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.]
Para enviar uma solicitação de status do COPP (Certified Output Protection Protocol), preencha uma estrutura AMCOPPStatusInput com os dados de solicitação. Os membros da estrutura são:
- rApp. Um número aleatório de 128 bits, digitado como GUID. O mesmo número é retornado na resposta do driver. Você deve alocar o número aleatório no heap e, em seguida, copiá-lo para a estrutura. Isso protege contra ataques em que o invasor modifica o conteúdo da estrutura AMCOPPStatusInput .
- guidStatusRequestID. Um GUID que identifica a solicitação. Consulte Referência de consulta COPP.
- dwSequence. O status número de sequência. Incremente esse valor após cada solicitação de status. (Na seção Iniciando uma sessão COPP, esse valor é mostrado como uStatusSeq nos exemplos de código.)
- cbSizeData. O tamanho, em bytes, de todos os dados adicionais necessários para a solicitação.
- StatusData. Dados da solicitação de status.
Passe a estrutura AMCOPPStatusInput para o método IAMCertifiedOutputProtection::P rotectionStatus . Por exemplo, o código a seguir envia uma solicitação status que consulta quais mecanismos de proteção estão disponíveis:
AMCOPPStatusInput input;
AMCOPPStatusOutput output;
// Create a 128-bit random number.
GUID *pGuid = new GUID();
if (pGuid == NULL)
{
// Handle out-of-memory condition.
}
CryptGenRandom(hCSP, sizeof(GUID), (BYTE*)pGuid);
// Copy the random number into the command structure.
memcpy(&input.rApp, pGuid, sizeof(GUID));
// Fill in the other data.
input.guidStatusRequestID = DXVA_COPPQueryProtectionType; // Request type.
input.dwSequence = uStatusSeq; // Status sequence number.
input.cbSizeData = 0 // No other data for this query.
// Send the request.
hr = pCOPP->ProtectionStatus(&input, &output);
// Increment the sequence number each time.
++uStatusSeq;
A resposta é gravada no membro COPPStatus da estrutura AMCOPPStatusOutput . O tamanho dos dados válidos na resposta é fornecido no membro cbSizeData . Para garantir a integridade da mensagem, o driver calcula um MAC (código de autenticação de mensagem) usando o algoritmo OMAC 1 e retorna esse valor no membro macKDI da estrutura. O aplicativo deve verificar esse valor da seguinte maneira:
- Calcule a marca OMAC para o bloco de dados que aparece após o membro macKDI da estrutura AMCOPPStatusOutput (em outras palavras, cbSizeData mais COPPStatus).
- Compare essa marca com o valor em macKDI, usando um memcmp reto.
O algoritmo OMAC 1 é descrito em detalhes em https://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html. O COPP usa os seguintes parâmetros OMAC-1:
- E = AES
- t = 128 bits
Os dados retornados da solicitação status sempre começam com dois itens:
- O mesmo valor de rApp que foi passado pelo aplicativo. Você deve verificar se esse valor corresponde ao valor original armazenado no heap.
- Um valor COPP_StatusFlags que indica se a status de proteção de saída foi alterada.
Como a conexão pode ser perdida ou reconfigurada, o aplicativo deve sondar periodicamente o driver para o status atual. Se o sinalizador COPP_RenegotiationRequired estiver definido, o aplicativo deverá tentar redefinir o nível de proteção. Se o sinalizador COPP_LinkLost estiver definido, o aplicativo deverá parar de reproduzir o conteúdo. Por exemplo, o sinalizador COPP_LinkLost pode ser retornado porque o usuário desconectou o conector de saída. O aplicativo deve liberar a instância atual da VMR, criar uma nova instância da VMR e estabelecer uma nova sessão COPP (incluindo troca de chaves e validação de certificado).
Tópicos relacionados