Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WinVerifyTrust is *ALMOST* what I need...

403 views
Skip to first unread message

Chip At Hotmail

unread,
Mar 22, 2002, 2:30:08 AM3/22/02
to
WinVerifyTrust() will verify that a file is signed... by somebody.

I can't have the trust dialog popping up - I need to know that it was signed
by me (I have an SPC). I can simply fail if it's not signed by me.

WinVerifyTrust() has many facilities, but I can only see how to use the file
scheme.

I've seen Daniel Sie recommend WinVerifyTrust() on several occasions, and
I'd love to use it...

Thanks!

-- Phil McDonnell

Daniel Sie [MS]

unread,
Mar 26, 2002, 9:50:52 PM3/26/02
to
The following should do it for you.

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

This code is provided for illustration purpose only.

Linked with Crypt32.lib.

----------------------------------------------------------------------------
*/

#include <stdio.h>
#include <crtdbg.h>
#include <windows.h>
#include <wincrypt.h>

int wmain (int argc, LPWSTR argv[])
{
int nRetCode = 0;
HCERTSTORE hCertStore = NULL;
HCRYPTMSG hCryptMsg = NULL;
DWORD dwContentType = 0;
DWORD dwExpectedType =
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED;
DWORD cbData = 0;
CMSG_SIGNER_INFO * pSignerInfo = NULL;
CERT_INFO CertInfo = {0};
PCCERT_CONTEXT pCertContext = NULL;
LPWSTR pwszSubjectName = NULL;

__try
{
// Check command parameters.
if (2 != argc)
{
nRetCode = E_INVALIDARG;
printf("Usage: %s AuthenticodeSignedFileName\n", argv[0]);
__leave;
}

// Retrieve the signed executable HCRYPTMSG and HCERTSTORE.
if (!CryptQueryObject(CERT_QUERY_OBJECT_FILE,
(LPCVOID) argv[1],
dwExpectedType,
CERT_QUERY_FORMAT_FLAG_BINARY,
0,
NULL,
&dwContentType,
NULL,
&hCertStore,
&hCryptMsg,
NULL))
{
nRetCode = GetLastError();
printf("Error [%#x]: CryptQueryObject() failed.\n", nRetCode);
__leave;
}

// Sanity check.
_ASSERT(CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED == dwContentType);

// Use low level messaging API to retrieve signer's info.
if (!CryptMsgGetParam(hCryptMsg,
CMSG_SIGNER_INFO_PARAM,
0,
NULL,
&cbData))
{
nRetCode = GetLastError();
printf("Error [%#x]: CryptMsgGetParam() failed.\n", nRetCode);
__leave;
}

if (!(pSignerInfo = (CMSG_SIGNER_INFO *) malloc(cbData)))
{
nRetCode = E_OUTOFMEMORY;
printf("Error [%#x]: malloc() failed.\n", nRetCode);
__leave;
}

if (!CryptMsgGetParam(hCryptMsg,
CMSG_SIGNER_INFO_PARAM,
0,
pSignerInfo,
&cbData))
{
nRetCode = GetLastError();
printf("Error [%#x]: CryptMsgGetParam() failed.\n", nRetCode);
__leave;
}

// Find signer's cert in store.
CertInfo.Issuer = pSignerInfo->Issuer;
CertInfo.SerialNumber = pSignerInfo->SerialNumber;

if (!(pCertContext = CertFindCertificateInStore(hCertStore,
X509_ASN_ENCODING |
PKCS_7_ASN_ENCODING,
0,

CERT_FIND_SUBJECT_CERT,
(LPVOID) &CertInfo,
NULL)))
{
nRetCode = GetLastError();
printf("Error [%#x]: CryptMsgGetParam() failed.\n", nRetCode);
__leave;
}

// Retrieve signer's simple name.
if (!(cbData = CertGetNameStringW(pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
NULL,
0)))
{
nRetCode = CRYPT_E_NOT_FOUND;
printf("Error [%#x]: CertGetNameString() failed.\n", nRetCode);
__leave;
}

if (!(pwszSubjectName = (LPWSTR) malloc(cbData)))
{
nRetCode = E_OUTOFMEMORY;
printf("Error [%#x]: malloc() failed.\n", nRetCode);
__leave;
}

if (!(cbData = CertGetNameStringW(pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
pwszSubjectName,
cbData)))
{
nRetCode = CRYPT_E_NOT_FOUND;
printf("Error [%#x]: CertGetNameString() failed.\n", nRetCode);
__leave;
}

// Display signer's simple name.
printf("%ls was signed by %ls.\n", argv[1], pwszSubjectName);
}

__finally
{
// Clean up - left as an exercise for the reader.
}

return nRetCode;
}

--
Daniel Sie [MS]

This posting is provided "AS IS" with no warranties, and confers no rights.


"Chip At Hotmail" <ch...@hotmail.com> wrote in message
news:3c9addfe$0$27998$4c41...@reader1.ash.ops.us.uu.net...

Chip At Hotmail

unread,
Mar 27, 2002, 2:52:15 PM3/27/02
to

"Daniel Sie [MS]" <ds...@online.microsoft.com> wrote in message
news:ut69uoT1BHA.2380@tkmsftngp04...

> The following should do it for you.
>

Hey, this really WORKS!!!

You guys are al-right.

Thanks!! I feel more secure already...

// PMD

Russell G

unread,
Apr 1, 2002, 6:08:34 PM4/1/02
to
Daniel,

The code you included does exactly what I need, but I need to support
all versions of Windows from 95 onwards. When I look at the MSDN
documentation for the functions included, most of them don't seem to
support Win95 and/or 98.

WinVerifyTrust() has the same problem. MSDN says it's only supported
by Windows NT/2000/XP.

Do you have any suggestions for how to do the same thing for older
OSs? I want to take a signed file and verify (programmatically) that
it was signed by me.

Thanks,

Russell

Daniel Sie [MS]

unread,
Apr 8, 2002, 8:07:15 PM4/8/02
to
The doc is wrong. These APIs are available if IE v5.0 is installed (may be
v5.1 can't really remember off the top of my head).

--
Daniel Sie [MS]

This posting is provided "AS IS" with no warranties, and confers no rights.


"Russell G" <myuniq...@yahoo.com> wrote in message
news:2c648112.02040...@posting.google.com...

Russell G

unread,
Apr 10, 2002, 7:36:23 PM4/10/02
to
Thanks for the reply. However, I should have also mentioned that I
need to support IE 4 as well.

So what I need is:

- a way to programmatically verify that a file was signed by me
- a solution that supports IE 4+
- a solution that supports Windows 95+

Any other ideas? Thanks,

Russell

"Daniel Sie [MS]" <ds...@online.microsoft.com> wrote...


>
> The doc is wrong. These APIs are available if IE v5.0 is installed (may be
> v5.1 can't really remember off the top of my head).
>

> "Russell G" <myuniq...@yahoo.com> wrote...

0 new messages