// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include <windows.h>
#include <stdio.h>
#include <wintrust.h>
#include <softpub.h>
#include <mscat.h>
void PrintUsage(_In_ PCWSTR fileName)
{
wprintf(L"%s [-p] <-c | -e> file\n", fileName);
wprintf(L"Flags:\n");
wprintf(L" -p: Use signature policy of the current os (szOID_CERT_STRONG_SIGN_OS_CURRENT)\n");
wprintf(L" -c: Search for the file in system catalogs\n");
wprintf(L" -e: Verify embedded file signature\n");
}
//----------------------------------------------------------------------------
//
// PrintError
// Prints error information to the console
//
//----------------------------------------------------------------------------
void PrintError(_In_ DWORD Status)
{
wprintf(L"Error: 0x%08x (%d)\n", Status, Status);
}
//----------------------------------------------------------------------------
//
// VerifyEmbeddedSignatures
// Verifies all embedded signatures of a file
//
//----------------------------------------------------------------------------
DWORD VerifyEmbeddedSignatures(_In_ PCWSTR FileName,
_In_ HANDLE FileHandle,
_In_ bool UseStrongSigPolicy)
{
DWORD Error = ERROR_SUCCESS;
bool WintrustCalled = false;
GUID GenericActionId = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_DATA WintrustData = {};
WINTRUST_FILE_INFO FileInfo = {};
WINTRUST_SIGNATURE_SETTINGS SignatureSettings = {};
CERT_STRONG_SIGN_PARA StrongSigPolicy = {};
// Setup data structures for calling WinVerifyTrust
WintrustData.cbStruct = sizeof(WINTRUST_DATA);
WintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
WintrustData.dwUIChoice = WTD_UI_NONE;
WintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
WintrustData.dwUnionChoice = WTD_CHOICE_FILE;
FileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO_);
FileInfo.hFile = FileHandle;
FileInfo.pcwszFilePath = FileName;
WintrustData.pFile = &FileInfo;
//
// First verify the primary signature (index 0) to determine how many secondary signatures
// are present. We use WSS_VERIFY_SPECIFIC and dwIndex to do this, also setting
// WSS_GET_SECONDARY_SIG_COUNT to have the number of secondary signatures returned.
//
SignatureSettings.cbStruct = sizeof(WINTRUST_SIGNATURE_SETTINGS);
SignatureSettings.dwFlags = WSS_GET_SECONDARY_SIG_COUNT | WSS_VERIFY_SPECIFIC;
SignatureSettings.dwIndex = 0;
WintrustData.pSignatureSettings = &SignatureSettings;
if (UseStrongSigPolicy != false)
{
StrongSigPolicy.cbSize = sizeof(CERT_STRONG_SIGN_PARA);
StrongSigPolicy.dwInfoChoice = CERT_STRONG_SIGN_OID_INFO_CHOICE;
StrongSigPolicy.pszOID = szOID_CERT_STRONG_SIGN_OS_CURRENT;
WintrustData.pSignatureSettings->pCryptoPolicy = &StrongSigPolicy;
}
wprintf(L"Verifying primary signature... ");
Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
WintrustCalled = true;
if (Error != ERROR_SUCCESS)
{
PrintError(Error);
goto Cleanup;
}
wprintf(L"Success!\n");
wprintf(L"Found %d secondary signatures\n", WintrustData.pSignatureSettings->cSecondarySigs);
// Now attempt to verify all secondary signatures that were found
for(DWORD x = 1; x <= WintrustData.pSignatureSettings->cSecondarySigs; x++)
{
wprintf(L"Verify secondary signature at index %d... ", x);
// Need to clear the previous state data from the last call to WinVerifyTrust
WintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
if (Error != ERROR_SUCCESS)
{
//No need to call WinVerifyTrust again
WintrustCalled = false;
PrintError(Error);
goto Cleanup;
}
WintrustData.hWVTStateData = NULL;
// Caller must reset dwStateAction as it may have been changed during the last call
WintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
WintrustData.pSignatureSettings->dwIndex = x;
Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
if (Error != ERROR_SUCCESS)