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 dwContentType
CryptQueryObject
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
.
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
@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
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