How can I verify SHA-2 signature of PE file? - winapi

I would like to verify SHA-2 authenticode digital signature of PE file on Windows platform.
I tried to verify a SHA-2 signature by using WinVerifyTrustEx().
WinVerifyTrustEx works fine on Windows 7. But WinVerifyTrustEx does not work on Windows Vista.
I used same codes on both Windows 7 and Windows Vista.
How can I verify SHA-2 signature on Window Vista?
[UPDATE]
WinVerifyTrustEx returns TRUST_E_NOSIGNATURE(0x800B0100) on Windows Vista.
WinVerifyTrustEx returns ERROR_SUCCESS on Windows 7.
I used same sample codes and verified the same executable file which is signed.
The signed executable file has SHA-256 signature.
The difference is only OS (vista and 7).
When I tried to verify another executable file which is signed by SHA-1, WinVerifyTrustEx returns ERROR_SUCCESS on both Vista and 7.

Related

Windows MS signed filter driver doesn't load on Win 7 x64 after updating driver to build with VS2019 / WDK 22000

I recently took on a task to update our filter driver from building with Visual Studio 2015 -> 2019. I also moved to the latest SDK + WDK 22000 (Which is the new Windows 11 one).
Everything seemed to work except that on Win 7 x64 (with secure boot) boxes the driver no longer loads.. It get's:
Load failed with error: 0x80070241
Windows cannot verify the digital signature for this file. A recent hardware or
software change might have installed a file that is signed incorrectly or damaged,
or that might be malicious software from an unknown source.
Our driver was/is attestation signed by Microsoft via the MS Hardware portal and so it's joint signed by both our company and Microsoft with a SHA-2 signature each. Windows 7 doesn't support SHA-2 certs out of the box however, it was previously working provided:
Windows6.1-KB3033929-x64
Was installed. Something seems to have changed though and Windows 7 x64 boxes can't load the new driver even with the latest updates. They load the 2015 built driver just fine even though the certificates on both look identical. The new driver loads just fine on Windows 10 machines.
Is anyone aware of any other changes which might make this combination fail to load?
I had a similar issue a few months ago, when we decided to switch our certificate provider. I'll share my knowledge to you, hope that going to help.
A while ago, Microsoft used cross-certificates to validate trusted certificate authorities (CA), so the only thing you needed to sign a driver is a proper certificate bought from a trusted CA. But recently validating process had changed and starting from Windows 10 20H2 you are forced to sign your driver through Microsoft Partner Center and all the cross-certificates was deprecated. However, you still need to use cross sign process for all your drivers prior to Windows 10, actually cross signed driver will work up to Windows 10 20H1 if to be correct.
Now back to the Visual Studio. To properly sign driver, you had to set up production certificate to field Properties -> Driver Signing -> General -> Production Certificate, that causes Visual Studio to use signtool utility to sign driver after the build done. As I presume, Visual Studio 2019 process do not use cross-certificate and looks something like:
signtool sign /v <trusted_certificate> /tr http://timestamp.digicert.com /td sha256 /fd sha256 /a <sys_driver_filepath>
But Visual Studio 2013 actually must use cross-certificate and the command it uses is:
signtool sign /v /ac <microsoft_cross_certificate> /tr http://timestamp.digicert.com /a <sys_driver_filepath>
So what is cross-certificate is? It's a special trusted Microsoft certificate that tied to certified CA. List of all the cross-certificates available can be found here https://learn.microsoft.com/en-us/windows-hardware/drivers/install/cross-certificates-for-kernel-mode-code-signing#cross-certificate-list. To take the correct one you need to check your company certificate first. Take a look into root of certification path of your cert, open View Properties -> Details and find Issuer, that's your CA. Now you need to find exact match on cross-certificate list and download it. Note the thumbprint doesn't need to match (revealed in related issue). After all use a proper signtool command to sign your file.
P.S. If your certificate issuer not present on the list, that means your CA inappropriate and you need to get/buy another certificate.

How to setup signtool with SHA256 on Windows 7?

I have been using SHA1 signing for many years, but from 2016, Windows is forcing developers to use SHA256.
Windows Enforcement of Authenticode Code Signing and Timestamping
By using Windows 7 SDK signtool the functions to sign SHA-256 is "unknown commands", so this signtool is obsolete as a signtool and shouldn't be used any more.
To sign with SHA256 I downloaded the Windows 8.1 SDK to get signtool.exe which got the new functions(/fd and a few others). The BAT file and signtool works on Windows 8 and 10, so I know it works, but crashes on Windows 7 when it tries to timestamp the file.
I use a bat file to sign files, which looks like this(I edited the BAT file so it doesn't show variables, full paths, company name and passwords):
Path\signtool.exe sign /f "Path\Certificate.p12" /fd sha256 /p *password* /du "URL" /tr "timestampServer?td=sha256" /td sha256 /d "Product name" "Filename"
I guess, I don't have the proper SDK to support some of the functions, but I can't find any info on the internet on how to setup this on a Windows 7. I tried to install MS Visual C++ 2015 Redistributable (x64) on my machine without solving the problem.
Seems I'm no good at reading. I'm answering my own question as others could find it hard to find, just like I did.
Windows doesn't support the signtool.exe on Windows 7 any more, so that is why old/obsolete functions like SHA-1 signing is still working, but SHA-256 time stamping is a problem. I found this on MSDN:
Quote from MSDN: Note You can only use SignTool to sign your Windows
Store app packages on Windows 8 and later or Windows Server 2012 and
later. You can't use SignTool to sign app packages on down level
operating systems such as Windows 7 or Windows Server 2008 R2.
If you want to read the whole thing then look here:
How to sign an app package using SignTool

Windows Driver NONPNP Signing

I have tried to run the NONPNP windows driver code. It installs and when I run the nonpnpapp.exe I get a driver signing error.
"windows requires a digitally signed driver"
I am running this on debug mode and release I am test signing it.
Why am I still getting this error?
I do know that x64 machines needs this, I am on windows7 x64.
So we need to do something else.
Visual studio output says that the sys file is successfully signed.
I trace the code. It copies the sys to system32/drivers after it is signed.
Windows device installation uses digital signatures to verify the integrity of driver packages and to verify the identity of the vendor (software publisher) who provides the driver packages. In addition, the kernel-mode code signing policy for 64-bit versions of Windows Vista and later versions of Windows specifies that a kernel-mode driver must be signed for the driver to load.+
Note Windows 10 for desktop editions (Home, Pro, Enterprise, and Education) and Windows Server 2016 kernel-mode drivers must be signed by the Windows Hardware Dev Center Dashboard, which requires an EV certificate. For details, see Driver Signing Changes in Windows 10. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/driver-signing
Two options there;
1) allow test signing
2) disable driver signature enforcement
If you are using a dedicated test machine, I recommend the second option since I think it's more error proof.

Device driver code signing for windows XP 32 bit

I have written a device driver for a device but each time I connect the device in windows XP 32 bit, "found new hardware" wizard appears.
I am signing the driver using a Comodo code signing certificate and not using the cross certificate chain to link to microsoft root authority. Nor is the driver wql certified.
So my question is to disable the found new hardware wizard on windows xp:
i) Does my driver needs to be wql certified?
ii) signed with microsoft root certificate using cross certificate from verisign?
iii) or something i missed out in my code which needs to be changed?
did some research and found the answer:
windows XP does not support authenticode driver signing and there are no plans to add it. Only way is to sign using microsoft certificate by using a cross certificate
As far as I know, the only driver signing recognized by Windows XP is a WHQL signature. Cross-signing has nothing to do with it. (Cross-signing allows the Windows Vista kernel driver loader to recognize Authenticode signatures. It has nothing to do with Windows XP driver loading.)
Authenticode signatures, while they would validate with DIFx / DpInst, would fail to validate later when SetupAPI tries to install your device driver out of the driver store.

Autorun.inf - publisher not specified

I have the following autorun.inf
[Autorun]
action="Blah, Inc."
open=marketing.exe
icon=blah.ico
label="Blah, Inc."
On Vista, the autorun dialog shows "Publisher not specified". How do I specify a publisher?
Bogdan is right: You need to sign your executable.
You can use SignTool from Microsoft for this. Taken from the MSDN:
SignTool tool is a command-line tool that digitally signs files, verifies signatures in files, or time stamps files. (...) The tool is installed in the \Bin folder of the Microsoft Windows Software Development Kit (SDK) installation path.
SignTool is available as part of the Windows SDK, which you can download as part of the Windows SDK for Windows Server 2008 and .NET Framework 3.5.
You specify the publisher by signing your executable file, not by writing it in the autorun.inf file.
How to do it...beats me, I'm a Java developer. Maybe someone else can tell you how.

Resources