The other day a customer of mine was trying to sign a binary with SignTool.exe using the following command line on Windows Server 2008 SP2:
Signtool.exe sign /a /f “c:\mycert.pfx” /p “password” /t “http://timestamp.verisign.com/scripts/timstamp.dll” “c:\temp\myFile.exe”
And SignTool failed with the following error:
SignTool Error: ISignedCode::Sign returned error: 0x80092006 No provider was specified for the store or object.
He got the same error on Windows Vista. Now, the same command worked just fine on Windows 7 and Windows Server 2008 R2. He had the latest Windows SDK installed.
I debugged the issue and saw that on Windows Vista/ Server 2008 RTM/SP1/SP2, SignTool failed because the SignerSignEx API that it calls behind the scenes failed with the same error 80092006:
Now, the API returned that error because it got this other error internally:
0x80090014 Invalid provider type specified
And it got this internal error because when trying to acquire the crypto provider with CryptAcquireCertificatePrivateKey API, it didn’t use CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, and the provider associated to customer’s certificate was a CNG provider (“Microsoft Software Key Storage Provider” in this case).
I also verified that SignerSignEx API ends up calling CryptAcquireCertificatePrivateKey with CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG on Windows 7/Server 2008 R2 RTM/SP1, so it should work with CNG certificates in those environments.
So summing up, we are facing a limitation on Vista/Server 2008 that won’t allow us to use CNG certificates with SignerSignEx API or the APIs, COM objects and tools (e.g. SignTool.exe) that end up calling SignerSignEx behind the scenes.
Here I posted the ways to sign binaries that we support, and all of them end up in a call to SignerSignEx, so they are all affected by this limitation: How to sign EXE files with an Authenticode certificate (part 2)
I hope this helps.
Alex (Alejandro Campos Magencio)