Como verificar se minha orgainização assinou um binário confiável do Windows?

Esta é uma pergunta de seguimento paraquestão 1072540, 'WinVerifyTrust para verificar se há uma assinatura específica?'.

Eu quero escrever uma função C ++ Vamos chamá-loTrustedByUs da forma:

bool TrustedByUs(std::string pathToBinary, std::string pathToPublicKey)

A idéia é que damos a essa função um caminho para um arquivo .dll ou .exe binário que foi assinado com uma assinatura digital. opathToPublicKey string é o caminho para uma chave pública do nosso certificado de assinatura específico.

Usando o código emhttp://support.microsoft.com/kb/323809 é bastante simples para verificar se opathToBinary arquivo é de fato confiável pelo sistema operacional.

Agora eu estou no mesmo lugar que o escritor da questão 1072540, eu sei que o sistema operacional confia no signatário deste binário, mas eu quero saber se a chave RSA da minha organização é a que assinou o binário.

O KB323809 mostra como extrair as seqüências de caracteres do certificado incorporado em nosso arquivo binário. Este exemplo mostra como extrair strings do certificado de assinatura em seuGetProgAndPublisherInfo função, mas eu estou desconfortável usando uma correspondência de seqüência de caracteres para verfiy o certificado.

O que eu gostaria de fazer é extrair a chave pública da assinatura incorporada e compará-la à chave pública que corresponde à chave privada que assinou meu arquivo binário em primeiro lugar.

A documentação paraCryptMsgGetParam diz que oCMSG_SIGNER_CERT_ID_PARAM parâmetro 'Retorna informações em um assinante de mensagem necessário para identificar a chave pública do assinante'. Consegui obter o número de série do certificado com esta chave. Meu código é assim:

// Get message handle and store handle from the signed file.
fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
    L"C:\\Program Files\\MySignedProgram.exe",
    CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
    CERT_QUERY_FORMAT_FLAG_BINARY,
    0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL);

// Get the public key information about the signer
// First get the size
DWORD dwCertIdSize(0);
fResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_ID_PARAM,
    0, NULL, &dwCertIdSize);
BYTE* pCertId = new BYTE(dwCertIdSize);
::ZeroMemory(pCertId,dwCertIdSize);

// Now get the cert info
fResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_ID_PARAM,
    0, (PVOID)pCertId, &dwCertIdSize);

if(fResult)
{      
    CERT_ID* pId = (CERT_ID*)pCertId;  
    pId->HashId;
    pId->dwIdChoice;
    pId->IssuerSerialNumber;  // Valid serial number (reversed)
    pId->KeyId;   
    _tprintf("pid\n");
}

Isso é parecido com o que eu quero, mas realmente gostaria de usar a chave pública do certificado de assinatura para verificar se o arquivo binário assinado de destino foi de fato criado com meu par particular de chave pública / privada.

Usando oCMSG_ENCRYPTED_DIGEST sinalizar este código bem-sucedido:

// Get digest which was encrypted with the private key
DWORD digestSize(0);
fResult = CryptMsgGetParam(hMsg, CMSG_ENCRYPTED_DIGEST, 0, NULL, &digestSize);

BYTE* pDigest = new BYTE[digestSize];

// Next CryptMsgGetParam call succeds,
// pDigest looks valid, can I use this to confirm my public key
// was used to sign MySignedProgram.exe ?
fResult = CryptMsgGetParam(hMsg, CMSG_ENCRYPTED_DIGEST, 0, pDigest, &digestSize);

Questão de fundo: Dada a informação do certificado descoberta porCryptQueryObject, que técnica devo usar para garantir que o arquivo de destino foi de fato assinado usando a chave privada que corresponde à chave pública que está disponível para mim quando o código acima é executado?

questionAnswers(1)

yourAnswerToTheQuestion