Problems verifying signed code using CAPICOM 2.1.0.1 from C++

From: J Prendergast (j.prendergast_at_nospam.nospam)
Date: 09/27/05


Date: Tue, 27 Sep 2005 03:49:02 -0700

Hello, I'm new to cryptography and am trying to write a simple application
using C++ and CAPICOM 2.1.0.1 to verify an executable that has been digitally
signed.
(I get the impression that CAPICOM is the way to go - it makes things easier
than using CryptoAPI)

Please bear with me as my problems may be because of a simple thing that
I've overlooked - hopefully, someone will be able to point me in the right
direction.

As a test, I've confirmed that if I use the Platform SDK cryptography tool
Signtool.exe (see:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/cryptography_tools.asp) as follows:

signtool /a /v notepad.exe

... it verifies the signature correctly and gives the full signing
certificate chain (including "Microsoft Root Authority" ... "Thawte
Timestamping CA" ... "Verisign Time Stamping Services CA")

So I've written a simple dialog-based MFC C++ project (with #import
"capicom.dll" in stdafx.h) that uses the SignedCode.Verify method to verify
the executable specified by the CString sFileName (which gets set to the path
of notepad.exe when I browse for it in the app's GUI):

---
		CAPICOM::ISignedCodePtr signedCode(__uuidof(CAPICOM::SignedCode));
		CAPICOM::ICertificates2* certs = NULL;
		BSTR bstrDescription = NULL;
		BSTR bstrDescriptionURL = NULL;
		CAPICOM::ISigner2* signer;
		CAPICOM::ISigner2* timestamper;
		BSTR bstrFileName = sFileName.AllocSysString();
		result = signedCode->put_FileName(bstrFileName);
		::SysFreeString(bstrFileName);
		result = signedCode->Verify(VARIANT_TRUE);
		result = signedCode->get_Certificates(&certs);
		result = signedCode->get_Description(&bstrDescription);
		result = signedCode->get_DescriptionURL(&bstrDescriptionURL);
		result = signedCode->get_Signer(&signer);
		result = signedCode->get_TimeStamper(&timestamper);
		if (bstrDescription != NULL)
		{
			::SysFreeString(bstrDescription);
			bstrDescription = NULL;
		}
		if (bstrDescriptionURL != NULL)
		{
			::SysFreeString(bstrDescriptionURL);
			bstrDescriptionURL = NULL;
		}
---
Since I pass the value VARIANT_TRUE into signedCode->Verify, it prompts with 
a dialog, but in this dialog:
1) The title bar reads "TODO: <File description> - Security Warning"
2) It reads "Publisher: Unknown Publisher"
So my 1st question is - why is the signedCode->Verify call unable to obtain 
this information?
My 2nd question - why does the call to get_Certificates fail with an error 
return value of E_POINTER?
3rdly, if I change the call to Verify so that the value VARIANT_FALSE is 
passed in, the call throws an exception, indicating that the verification 
failed.
On inspection of the CAPICOM samples, the only thing I've wondered about is 
if I need to create a Store object, and open a certificate store.
The SignedCode VB example includes the code:
---
		st.Open(CAPICOM.CAPICOM_STORE_LOCATION.CAPICOM_CURRENT_USER_STORE, 
CAPICOM.Constants.CAPICOM_MY_STORE, 
CAPICOM.CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_READ_ONLY)
		certs = st.Certificates
---
But on the other hand - these 2 variables (st, certs) are never used 
anywhere else in the project!?!
So I tried adding this code into my C++ project:
---
		CAPICOM::IStore2Ptr store(__uuidof(CAPICOM::Store));
		result = store->Open(CAPICOM::CAPICOM_CURRENT_USER_STORE,
							CAPICOM::CAPICOM_MY_STORE,
							CAPICOM::CAPICOM_STORE_OPEN_READ_ONLY);
		CAPICOM::ICertificates* storeCerts = NULL;
		result = store->get_Certificates(&storeCerts);
---
with no change to the behaviour...
Finally, I've just noticed that when I run the SignedCode VB example 
application on my PC, it fails verifying Notepad.exe too!!!
So could my code actually be OK and I have some kind of configuration 
problem on my system?
To install CAPICOM 2.1.0.1, I extracted the contents of the capicom.cab, 
right-clicked on the .inf file and selected install. The capicom.dll appeared 
in my C:\WINDOWS\system32 folder. I even called regsvr32 on it to ensure it's 
registered.
I would appreciate any help or pointers that anyone can offer.
Thankyou and best regards,
JP


Relevant Pages

  • Re: CAPICOM
    ... By decode, you mean verify the signature against content, and verify ... The samples in CAPICOM 2 are rather long. ... Dim SignedData ... > Does anybody know how to decode a message, ...
    (microsoft.public.security)
  • Signature verification with capicom
    ... sign verify reverse the entire buffer. ... capicom says that the hashes don't match. ... Iaik sends ... >with capicom but the hash created from the original file. ...
    (microsoft.public.platformsdk.security)
  • Digital Signatures Verification prblem
    ... i've tried alot to verify PKCS#7 format file using capicom but it alwayz ... generates some exception. ... i've signed some data using CAPICOM, ... try to verify it. ...
    (microsoft.public.platformsdk.security)
  • RE: Are there CAPICOM examples handling Outlook mails?
    ... and verify an Outlook mail items by using CAPICOM or crpyto api ...
    (microsoft.public.platformsdk.security)