RE: Problems verifying signed code using CAPICOM 2.1.0.1 from C++

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


Date: Thu, 29 Sep 2005 09:06:03 -0700

Hi Rhett,

First of all, I've found out that my code was actually working OK all along
(!) -
I was comparing the results of the Platform SDK cryptography tool
Signtool.exe (see:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/cryptography_tools.asp)
(using command line options /a /v) against my application, and because the
results didn't match, I assumed my application wasn't working.

Signtool told me that:
- notepad.exe has a valid digital signature
- WinWord.exe does not have a valid digital signature

My application told me the exact opposite.

However
- the SignedCode VB example application tells me notepad.exe doesn't have a
valid digital signature, but WinWord.exe does
- the csigncode.vbs sample you mentioned tells me the same
- I found out that in Windows Explorer, it's possible to check the digital
signature status of a file in File Properties, and this agrees with the above.
So - my application worked fine all along!

Thank you for the sample code though - it has given me ideas of other things
I may wish to do.

A few more questions that you may be able to help with:
1) To find the identifier that gives the organisation name (e.g. "Microsoft
Corporation") that signed the executable (i.e. we can trust that if the
identifier says "Microsoft Corporation" then we CAN ABSOLUTELY TRUST that it
came from nowhere else), I'm using the approach:
- Get the Certificates collection from the SignedCode object, get the 1st
Certificate item, get the SubjectName property, and parse the string to get
the value of the "CN=" tag.
- The reason I have taken the 1st certificate is because, for certificates
after the 1st one, this tag contains "Microsoft Code Signing PCA", then
"Microsoft Root Authority" then "Verisign Time Stamping Services Signer".
- Is this approach always guaranteed to work, to get the organisation name
for any signed executable? (or do I need to do something a little cleverer
than just automatically always taking the 1st one?)

2) Alternatively - instead of using the Certificates collection from the
SignedCode object, should I be using the one accessed from the
SignedCode->Signer->Chain object (perhaps taking the 1st certificate as I
have done above). In the example given (Winword.exe), this gives me the same
result as my approach in (1), i.e. "Microsoft Corporation".

3) Is such an organisation string enough? Or should I be using another
identifier that uniquely identifies the organisation (I appreciate that
public keys expire so it's not wise to remember this for a company and assume
that this will always be used for all executables it ever signs!)

4) Would the above approach (examining the "CN=" tag) work for any
certificate type that has been used to sign an executable? Or does it only
apply to an X.509 certificate, for example?

5) While implementing the above, I called ICertificate2::Display to display
each certificate as I iterated through the collection. Interestingly, in the
example above where I had 4 certificates in the collection obtained from the
SignedCode object, the 1st and last certificate dialogs included the text
"Windows does not have enough information to verify this certificate." Yet,
this same dialog, when displayed in Windows Explorer, doesn't not show this
text for any of the certificates. The fact that it works in Windows Explorer
suggests to me that I don't need to install anything to get this to work from
my program.
[A random suggestion/idea - maybe my application needs to point at other /
additional certificate stores, which it doesn't access by default?]

6) Finally, in your email, where you recommended trying something like:
signtool sign /f test.pfx /p hello NTService.exe
I appreciate that this is a newbie question - how do I create the .pfx file?
I was thinking that maybe one of the others Platform SDK cryptography tools
would do this for me, but I'm not convinced.

Many thanks for your assistance,

Best regards,
JP

"Rhett Gong [MSFT]" wrote:

> Hello JP,
> Seems you choose a hard part to begin your trip on CAPICOM.
>
> General steps to verify a code are similiar as following :
> //-------------------------------
> ISignedCode* pSignCode = NULL;
> hr = CLSIDFromProgID(L"CAPICOM.SignedCode.1", &signClsid);
> hr = CoCreateInstance(signClsid, NULL,CLSCTX_ALL, __uuidof(ISignedCode), (void**)&pSignCode);
> _bstr_t fname = SysAllocString(L"c:\\test\\ntservice.exe");
> pSignCode->put_FileName( fname );
> pSignCode->Verify(TRUE);
> hr = pSignCode->get_Signer(&pSigner);
> hr = pSigner->get_Chain(&pChain);
> hr = pChain->get_Certificates(&pCCerts);
> pCCerts->get_Count(&cnt);
> //------------------------------
>
> If you just want to verify a signed code, you don't need to add following lines:
> 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);
> these lines are required by sign stage, so putting filename and call verify will be ok.
>
> To make a simple test, you may create a simple exe (eg ntservice.exe in my test) and test with following command:
> C:\test>signtool sign /f test.pfx /p hello NTService.exe
> Done Adding Additional Store
> Successfully signed: NTService.exe
>
> then I used csigncode.vbs sample to verify it and it gives following successful output:
> E:\CAPICOM 2.1.0.1\samples\vbs>cscript csigncode.vbs verify /v c:\test\NTService
> .exe
> Microsoft (R) Windows Script Host Version 5.6
> Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
>
> === Verifying c:\test\NTService.exe ===
>
> Description :
> Description URL:
> Signer : testcert
> Signing chain : 2 certificate(s)
>
> === Certificate 1 of 2 ===
> Subject name : E=no@aa.com, CN=testcert, OU=aa, O=aa, L=aa
>
> Issuer name : CN=001TestCA, DC=microsoft, DC=com
>
> Serial number: 61FC9466000000000006
>
> SHA1 hash : 43070FBBA6733DAEE2DF49ADC8D9E73868B15992
>
> === Certificate 2 of 2 ===
> Subject name : CN=001TestCA, DC=microsoft, DC=com
>
> Issuer name : CN=001TestCA, DC=microsoft, DC=com
>
> Serial number: 24AFA6E12F36BA9440A5C20412FCD09B
>
> SHA1 hash : 3CD4287D8A692DB6F29D5AABFF69084EC34B614B
>
>
> Successful.
> //------------------------------------------------------------
>
> then I use the code on the top of this post and cnt returns 2 as expected.
>
>
> Thanks,
> Rhett Gong [MSFT]
> Microsoft Online Partner Support
> Get Secure! - www.microsoft.com/security
> http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp&SD=msdn
>
> This posting is provided "AS IS" with no warranties and confers no rights.
>
>



Relevant Pages

  • RE: Verifying X509Certificate signature
    ... issue--with that sort of data I know what data to pass to Verify. ... As you said that you want some information about verifying X509 certificate ... Microsoft MSDN Online Support Lead ...
    (microsoft.public.dotnet.framework.aspnet.security)
  • Re: Programmatically Signing DLL
    ... key on it and sign a .DLL before it goes into production. ... > Dim Signer, SignedCode ... What kind of certificate do we need to buy to allow programmatic ... signing and validation of a DLL using VC++. ...
    (microsoft.public.security)
  • Re: Verify file signature programatically
    ... You can either call the WinVerifyTrust API directly or use the SignedCode ... Both will validate the dsig and perform certificate ... "C. Adrian Silasi" wrote in message ... > certificate from the file and know which part of the file to hash. ...
    (microsoft.public.platformsdk.security)
  • RE: receive an SSL Certificate error message when you view public
    ... The certificate received from the remote server does not contain the ... > folder from OWA or outlook 2003? ... > Microsoft CSS Online Newsgroup Support ... > This newsgroup only focuses on SBS technical issues. ...
    (microsoft.public.windows.server.sbs)
  • RE: ssl certificate error on public folders
    ... click the Server Certificate button. ... Microsoft CSS Online Newsgroup Support ... This newsgroup only focuses on SBS technical issues. ... Restart the IIS Admin service in the services mmc. ...
    (microsoft.public.windows.server.sbs)