2011-08-30 19 views
12

Quiero validar certificados de imágenes ejecutables con firma (por validación, me refiero a decir si la firma proviene de MS/Adobe/Oracle etc.). ¿Windows proporciona API para esta tarea? Como debería hacerlo, ni idea. Cualquier ayuda sería apreciada. Estoy usando Windows y C++. Quiero validar las imágenes ejecutables nativas, no los ensamblados .NET ni los archivos jar de Java.Leer y validar el certificado del archivo ejecutable

ACTUALIZACIÓN


Ok, voy a tratar de describir lo que quiero en breve.

1) Valide el certificado PE. Es la firma válida o no Debería funcionar cuando la firma está integrada en PE y cuando la firma está en el catálogo de seguridad. (Encontré esto en el foro sysinternals y funciona bien, así que ya no necesito este).

2) Indique quién es el firmante/editor del archivo. Sé que se puede lograr a través de CryptQueryObject (encontré un ejemplo de trabajo, aunque no funciona con los catálogos de seguridad), pero no sé cómo usarlo con los archivos de catálogo de seguridad.

Respuesta

20

Hay muchas API y enfoques sobre cómo puede obtener y verificar la firma del ejecutable y cómo puede obtener la información adicional que necesita. El problema es qué nivel eliges (nivel alto como WinVerifyTrust)

La primera API más fácil que se puede usar para obtener el contexto criptográfico del archivo CAT o EXE es la función CryptQueryObject. El ejemplo de código del KB323809 podría darle la idea principal de cómo decodificar la información que necesita. la principal diferencia si trabaja con archivos CAT es que debe modificar algunos parámetros de CryptQueryObject. Te recomiendo que acaba de utilizar CERT_QUERY_CONTENT_FLAG_ALL y CERT_QUERY_FORMAT_FLAG_ALL y CryptQueryObject hará todo lo que necesita internamente:

BOOL bIsSuccess; 
DWORD dwEncoding, dwContentType, dwFormatType; 
HCERTSTORE hStore = NULL; 
HCRYPTMSG hMsg = NULL; 
PVOID pvContext = NULL; 

// fill szFileName 
... 

// Get message handle and store handle from the signed file. 
bIsSuccess = CryptQueryObject (CERT_QUERY_OBJECT_FILE, 
           szFileName, 
           CERT_QUERY_CONTENT_FLAG_ALL, 
           CERT_QUERY_FORMAT_FLAG_ALL, 
           0, 
           &dwEncoding, 
           &dwContentType, 
           &dwFormatType, 
           &hStore, 
           &hMsg, 
           &pvContext); 

El valor establecido por el dwContentTypeCryptQueryObject le conseguirá la información de base sobre el tipo del archivo szFileName. El pvContext será PCCERT_CONTEXT para la mayoría de los casos que necesite, pero también puede ser PCCRL_CONTEXT o PCCTL_CONTEXT si utiliza el archivo .ctl o .crl como entrada. Recibirá el hStore rellenado con todos los certificados del archivo szFileName. Entonces con respecto a pvContext y hStore puede examinar el archivo que contiene CryptoAPI. Si prefiere API de masajes de bajo nivel, puede usar hMsg, que se establecerá adicionalmente en el caso de algunos dwContentType (al menos para CERT_QUERY_CONTENT_PKCS7_SIGNED, CERT_QUERY_CONTENT_PKCS7_UNSIGNED, CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED).

para verificar la firma del fichero que recomendaría su uso CertGetCertificateChain y CertVerifyCertificateChainPolicy para verificar no sólo que el certificado es válido en general, sino que (o todas sus padres) es válida para authenticode (szOID_PKIX_KP_CODE_SIGNING). CertGetCertificateChain se puede usar para diferentes escenarios de revocación.Debe hacer dos llamadas por separado con CERT_CHAIN_POLICY_AUTHENTICODE y CERT_CHAIN_POLICY_AUTHENTICODE_TS para verificar que la política de la cadena Authenticode y la política de la cadena del sello de tiempo Authenticode sean válidas.

ACTUALIZADO: He releído su pregunta actual (la parte Actualizada). Su problema actual es cómo obtener el firmante/editor del archivo. Así que solo respondo sobre la pregunta.

Si utiliza the code from sysinternal para la verificación de la firma sólo debe buscar la línea

if (!CryptCATCatalogInfoFromContext(CatalogContext, &InfoStruct, 0)) 

El umbral de la declaración establece los campos de la InfoStruct en caso de que ese archivo es el archivo de las ventanas del sistema, que firma se verifica con respecto de algún archivo .cat. El campo InfoStruct.wszCatalogFile le dará el nombre del archivo .cat.

Por ejemplo, en mi Windows 7 si trato de verificar la firma digital del archivo C:\Windows\explorer.exe, el archivo .cat donde se puede encontrar el hash es C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat.

Si desea utilizar el código de KB323809 descrito anteriormente con parámetros de CryptQueryObject va a decodificar el atributo SPC_SP_OPUS_INFO_OBJID ("1.3.6.1.4.1.311.2.1.12") de la C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat (ver la función GetProgAndPublisherInfo) y sabrá

pwszProgramName: "Windows Express Security Catalogs" 
pPublisherInfo: NULL 
pMoreInfo->dwLinkChoice: SPC_URL_LINK_CHOICE 
pMoreInfo->pwszUrl "http://www.microsoft.com" 

Por lo tanto, no se incluye información especial del editor para el archivo. Si examina el firmante del catálogo que se encuentra que:

The signer of the .cat file: "Microsoft Windows" 
The signer signed it with the certificate: 
    Serial Number: 0x6115230F00000000000A 
    Issuer Name: Microsoft Windows Verification PCA 
    Full Issuer Name: 
     CN = Microsoft Windows Verification PCA 
     O = Microsoft Corporation 
     L = Redmond 
     S = Washington 
     C = US 
    Subject Name: Microsoft Windows 
    Full Subject Name: 
     CN = Microsoft Windows 
     OU = MOPR 
     O = Microsoft Corporation 
     L = Redmond 
     S = Washington 
     C = US 
The Date of TimeStamp : 28.02.2011 21:16:36 
TimeStamp Certificate: 
    Serial Number: 0x6103DCF600000000000C 
    Issuer Name: Microsoft Time-Stamp PCA 
    Subject Name: Microsoft Time-Stamp Service 

lo que debe utilizar sólo el firmante del archivo .cat, porque no hay otro firmante de explorer.exe.

+0

muchas gracias y +1, aprecio su tiempo. Aunque todavía tengo algunos problemas, gracias a ustedes, siento que estoy mucho más cerca del objetivo que antes :). Cuando llamo a CryptQueryObject (a explorer.exe), devuelve un código de error 80092009 que significa "No coincide cuando intento encontrar el objeto". Supongo que no encontró el catálogo para explorer.exe (?). Muchas gracias de nuevo por su esfuerzo :) – Davita

+0

@Davita: Si intentara examinar cualquier archivo de texto o cualquier archivo ejecutable sin firmar (como el explorador.exe) con respecto a 'CryptQueryObject' usted recibiría el error [CRYPT_E_NO_MATCH] (http://msdn.microsoft.com/en-us/library/aa909166.aspx). Si examina las propiedades de explorer.exe, no verá la pestaña "Firmas digitales", por lo que el archivo simplemente no está firmado. Si tuviera otros problemas en la implementación, podría preguntarme. Hace algunos años, paso mucho tiempo en código EXE, CAT y así sucesivamente. Entonces probablemente pueda ayudarte rápidamente. – Oleg

+0

Muchas gracias Oleg, realmente aprecio tu esfuerzo. Todavía hay algo de confusión. http://forum.sysinternals.com/howto-verify-the-digital-signature-of-a-file_topic19247.html <- Cuando verifico explorer.exe con este código, WinVerifyTrust dice que la firma es válida. ¿Me falta algo o los archivos de firma y catálogo de PE tienen un propósito diferente? Perdón por esta pregunta tonta, realmente necesito hacer que esto funcione :(Gracias otra vez – Davita

3

La función WinVerifyTrust realiza una acción de verificación de confianza en un objeto especificado. La función pasa la consulta a un proveedor de confianza que admite el identificador de acción, si existe.

Para la verificación de certificados, use las funciones CertGetCertificateChain y CertVerifyCertificateChainPolicy.

+0

Gracias John, probé el ejemplo proporcionado por MSDN y funciona muy bien casi cada vez, excepto cuando se intenta verificar los archivos de las ventanas básicas, tales como explorer.exe. Dice que explorer.exe no está firmado, pero PeExplorer me dice que la firma de explorer.exe está verificada. Estoy confundido de lo que me estoy perdiendo ... – Davita

+1

Los archivos del sistema tienen sus valores almacenados en un archivo de catálogo que está firmado. Vea el código aquí: http://forum.sysinternals.com/howto-verify-the-digital-signature-of-a-file_topic19247.html –

+0

@Bevan Collins, muchas gracias, funcionó bien :) ¿Podría decirnos? ¿Cómo debería recuperar la información del certificado, como quién firmó el certificado? gracias – Davita

1

@Davita Leí a fondo el problema anterior e intenté resolverlo.

Mi sugerencia es tratar de CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED en lugar de CERT_QUERY_CONTENT_FLAG_ALL en el tercer parámetro de CryptQueryObject()

Cuestiones relacionadas