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
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
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...
> The following should do it for you.
>
Hey, this really WORKS!!!
You guys are al-right.
Thanks!! I feel more secure already...
// PMD
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]
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...
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...