I want to validate certificates of signed executable images (by validation, I mean to tell if the signature comes from MS/Adobe/Oracle etc.). Does windows provides api for this task? How should I do that, no idea. Any help would be appreciated.
I’m using Windows and C++. I want to validate native executable images, not .NET assemblies or Java jar files.
UPDATE
Ok, I’ll try to describe what I want shortly.
1) Validate PE certificate. Is the signature valid or not. It should work when signature is embedded in PE and when the signature is in security catalog. (I found this on sysinternals forum and works fine, so I don’t need this one anymore).
2) Tell who’s the signer/publisher of the file. I know it can be achieved through CryptQueryObject (I found a working example, though it doesn’t work with security catalogs), but don’t know how to use it with security catalog files.
There are many API and approaches how you can get and verify the signature of the executable and how you can get other additional information which you need. The problem is which level you choose (high level like
WinVerifyTrust)The easiest first API which can be used to get cryptography context from the CAT or EXE file is CryptQueryObject function. The code example from the KB323809 could get you the main idea how to decode information what you need. the main difference if you work with CAT files is that you should modify the some parameters of CryptQueryObject. I recommend you just to use
CERT_QUERY_CONTENT_FLAG_ALLandCERT_QUERY_FORMAT_FLAG_ALLandCryptQueryObjectwill do all what you needs internally:The value
dwContentTypeset by theCryptQueryObjectwill get you the base information about the type of the fileszFileName. ThepvContextwill bePCCERT_CONTEXTfor the most cases which you need, but it can be alsoPCCRL_CONTEXTorPCCTL_CONTEXTif you use .ctl or .crl file as the input. You will receive thehStorefilled with all certificates from the fileszFileName. So with respect ofpvContextandhStoreyou can examine the file contain with CryptoAPI. If you do preferlow-level massages API you can use
hMsgwhich will be additionally set in case of somedwContentType(at least for forCERT_QUERY_CONTENT_PKCS7_SIGNED,CERT_QUERY_CONTENT_PKCS7_UNSIGNED,CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED).To verify the signature of the file I would recommend you to use CertGetCertificateChain and CertVerifyCertificateChainPolicy to verify not only that the certificate is valid in general, but that it (or all its parents) is valid for authenticode (
szOID_PKIX_KP_CODE_SIGNING). CertGetCertificateChain can be used for different revocation scenarios. You should do two separate calls withCERT_CHAIN_POLICY_AUTHENTICODEandCERT_CHAIN_POLICY_AUTHENTICODE_TSto verify that both Authenticode chain policy and Authenticode Time Stamp chain policy are valid.UPDATED: I reread your current question (the Updated part). Your current problem is how to get the signer/publisher of the file. So I answer only on the question.
If you use the code from sysinternal for the signature verification you should just search for the line
The statement sill set the fields of the
InfoStructin case that that file is system windows file which signature is verified with respect of some .cat file. The field InfoStruct.wszCatalogFile will get you the name of the .cat file.For example on my Windows 7 if I try to verify the digital signature of the
C:\Windows\explorer.exefile, the .cat where its hash could be found isC:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat.If you would use code from KB323809 with described above parameters of
CryptQueryObjectyou will decode theSPC_SP_OPUS_INFO_OBJID(“1.3.6.1.4.1.311.2.1.12”) attribute of theC:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat(see the functionGetProgAndPublisherInfo) and you will knowSo no special publisher information are included for the file. If you examine the signer of the the catalog you will find out that:
So you should use just the signer of the .cat file, because there are no other signer of
explorer.exe.