We have a legacy Windows Workflow process that uses
SignerSign to apply a digital signature to an EXE. We are migrating away from the Windows Workflow process, and so I have been preparing a tool within the context of our new process to perform the same signing operation. I copy/pasted the code signing code from the Workflow Activity to a class in the new project, but I am encountering an error when I try to run it.
The rough outline of what the code does is:
CertOpenStoreis used to open the PFX file containing the private key and certificate.
CertEnumCertificatesInStoreon the resulting certificate store handle.
SignerSignis called with a
SIGNER_SUBJECT_INFOpointing at the target EXE file, a
SIGNER_CERTpointing at the certificate context from the previous step and a
SIGNATURE_SIGNER_INFOspecifying that the SHA-1 algorithm should be used. (I have tried changing the algorithm to SHA-2 512 with no change in the outcome.) The
SignerTimeStampto apply a timestamp to the signature. A comment in the code indicates that if the
SignerSignis used, it returns HRESULT 0x80070020 ("File in use"?)
When I try to run this code on Windows 10 64-bit, whether from a 32-bit or 64-bit process, I get error HRESULT 0x80092006 "No provider was specified for the store or object.". I tried supplying a
pProviderInfo with the provider name set to "Microsoft Strong Cryptographic Provider" (seen in the API Monitor trace output for when SignTool.exe signs the executable -- this works) but it did not affect the outcome.
Does anyone know what exactly this error means and how to fix it?
I have no idea at all why this worked, but by massaging my code so that does the same thing I see SignTool doing in Rohitab's API Monitor, and then paring bits away to what appears to be the minimal working set, this now signs files again:
PFXImportCertStoreis used to open the PFX file and produce an
HCERTSTORE. This requires loading the PFX into memory so that it can be passed in as a
CRYPT_DATA_BLOB-- no big deal.
CertGetCertificateChainis used on the resulting certificate context with an unrestrictive
CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING | CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT. No additional store is specified. When I originally wrote this, based on the API Monitor results, I defined
CERT_CHAIN_PARA_HAS_EXTRA_FIELDSand populated them the same way the API Monitor capture showed, but I continue to get
SignerSignwith the short
CERT_CHAIN_PARAstructure as well.
SignerSignis called as before, except that a dummy collection-type store is passed in as the
SIGNER_CERT_STORE_INFOstruct nested within the
SIGNER_CERT. This dummy collection type store is created by calling
CertOpenStoretwice, once with
CERT_STORE_CREATE_NEW_FLAGand once with
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, and then adding the memory store to the collection store using
If the dummy collection type store is not specified, then
SignerSign complains that it cannot find a path to a trusted root. Note that the certificate I am using in my testing is self-signed, and thus doesn't have a path to a trusted root. Perhaps the dummy collection type store would not be necessary with a code signing certificate that does have a path to a trusted root, I do not presently have the means to test.
In any case, I hope this helps resolve this issue for anybody else who might have bumped into problems with
User contributions licensed under CC BY-SA 3.0