Page 1 of 3

Verifty Digital Signatures with PB?

Posted: Fri Jun 13, 2008 2:40 pm
by Karbon
Has anyone done work with PB and the WinTrustVerify API in Windows to verify digital signatures on EXE files?

Several cracks have appeared for some of my software and I would like to add checks inside it to verify the digital signature on its EXE. Supposedly this is possible with the WinTrustVerify API..

http://support.microsoft.com/default.as ... -us;323809

Posted: Fri Jun 13, 2008 4:16 pm
by Karbon
This is the code I have working in C :

Code: Select all

#include <windows.h>

typedef LONGLONG ULONG_PTR, *PULONG_PTR;

#include <winerror.h>
#include <Softpub.h>
#include <wincrypt.h>
#include <wintrust.h>

LONG d_VerifyFile(LPCSTR Filename)
{
	/* Return values:
		0			trusted and verified
		1           wintrust.dll not installed
		2			pre Windows 2000
		0x800B0004  Not trusted (forced to this return code if WinVerifyTrust not found in wintrust.dll
		0x800B0100	Not signed or invalid signature (e.g. file corrupted)
	*/
	typedef LONG (WINAPI *WINVERIFYTRUST)(HWND hwnd, GUID *pgActionID, LPVOID pWVTData);
	WINVERIFYTRUST wvt;
	HINSTANCE hLib;

	WINTRUST_DATA WinTD;
	GUID gAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
	WINTRUST_FILE_INFO wf;
	WCHAR wszPath[512];
	LONG result;
	int	WindowsMajorVersion;

	WindowsMajorVersion = (LOBYTE(LOWORD(GetVersion())));
	if(WindowsMajorVersion < 5) return 2;

	hLib=LoadLibrary("wintrust.dll");
	if(!hLib) return 1;

	MultiByteToWideChar(65001,MB_ERR_INVALID_CHARS,Filename,strlen(Filename)+1,wszPath,sizeof(wszPath));
	memset(&WinTD,0,sizeof(WINTRUST_DATA));
	WinTD.cbStruct = sizeof(WINTRUST_DATA);
	WinTD.dwUIChoice = WTD_UI_NONE;
	WinTD.dwUnionChoice = WTD_CHOICE_FILE;
	WinTD.fdwRevocationChecks = WTD_REVOKE_NONE;
	WinTD.pFile = &wf;
	WinTD.dwStateAction = WTD_STATEACTION_IGNORE;
	WinTD.dwProvFlags = WTD_HASH_ONLY_FLAG | WTD_REVOCATION_CHECK_NONE;
	memset(&wf,0,sizeof(WINTRUST_FILE_INFO));
	wf.cbStruct = sizeof(WINTRUST_FILE_INFO);
	wf.hFile = NULL;
	wf.pcwszFilePath = wszPath;
	wvt = (WINVERIFYTRUST)GetProcAddress(hLib,"WinVerifyTrust");
	if(!wvt)
	{
		FreeLibrary(hLib);
		return 0x800B0004L;
	}
	result = wvt(0,&gAction,&WinTD);
	FreeLibrary(hLib);
	return result;
}

Posted: Thu Jul 10, 2008 5:33 pm
by Karbon
I'm interested in hiring someone to get this working in native PB code. PM/email me if you're interested.

Posted: Fri Jul 11, 2008 8:45 am
by Kukulkan
Hi,

I'm interested in such a solution, too. I like to verify digitally signed documents (for example "MyDoc.doc" with "MyDoc.p7s"). Maybe someone is able to convert this to PureBasic? I think the most important thing is the MultiByteToWideChar() conversion and defining the structures.

Kukulkan

Posted: Fri Jul 11, 2008 2:33 pm
by Karbon
I've had it on my personal to-do list for a month now and can't find the time to get it done.. Hopefully another fellow capitalist will chime in and do it for some cash :-)

Posted: Wed Jul 16, 2008 4:01 am
by dagcrack
Say what?

http://gushh.net/dev/?file=pb/wintrust.pb4i
http://gushh.net/dev/?file=pb/wintrust.pb4
http://gushh.net/dev/?file=pb/wintrust_test.pb4

:)

Too bad I don't have time at the moment, but having the entire headers ported would be ideal.

Posted: Wed Jul 16, 2008 9:20 am
by Kukulkan
Hi dagcrack,

This codes are working fine for Karbons requirements. :D

But to check digital signatures of documents (p7s files), this function does not work. I found this link http://msdn.microsoft.com/en-us/library ... S.85).aspx, but I'm not able to convert this to PureBasic. I'm not good enough in structures and pointers to use this API :-(

Kukulkan

Posted: Wed Jul 16, 2008 4:17 pm
by dagcrack
Yep, I just ported it nothing else.

The real function is a little more complex and it's called VerifyEmbeddedSignature(); used mainly for verifying the signature of PE files.

A full-blown authenticode lib for PB would also be nice :!:

Posted: Wed Oct 29, 2008 11:35 pm
by Karbon
Hey dag! I never saw your reply.

Thank you!

PM me, I'd be happy to pay you for the time you spent on it.

Posted: Tue Dec 16, 2008 5:06 am
by Thunder93
Interesting, dagcrack Wintrust code works beautifully under PB4.30b5 x86;

Trusted -> moviethumb.exe
Trusted -> npPicasa3.dll
Trusted -> Picasa3.exe
Trusted -> PicasaPhotoViewer.exe
Trusted -> PicasaUpdater.exe
Not signed -> qtsupport.dll
Trusted -> setup.exe
Not signed -> Uninstall.exe



Under PB4.30b5 x64;

Provider Unknown -> moviethumb.exe
Provider Unknown -> npPicasa3.dll
Provider Unknown -> Picasa3.exe
Provider Unknown -> PicasaPhotoViewer.exe
Provider Unknown -> PicasaUpdater.exe
Provider Unknown -> qtsupport.dll
Provider Unknown -> setup.exe
Provider Unknown -> Uninstall.exe



The .l all been changed to .i, but something else I'm missing... any ideas?

Posted: Tue Dec 16, 2008 7:01 pm
by Thunder93
Suppose there's an problem with the code or more PB internal in the x64 release?

Posted: Tue Dec 16, 2008 7:57 pm
by Pupil
Thunder93 wrote:Suppose there's an problem with the code or more PB internal in the x64 release?
I would guess the pointers in the structures mess things up a bit..

Posted: Tue Dec 16, 2008 8:02 pm
by freak
> The .l all been changed to .i, but something else I'm missing... any ideas?

You can't just change all .l to .i. Some values may stay long. Also you have to take alignment issues into effect on x64.
What does your structure look like ? (and whats the C definition?)

Posted: Tue Dec 16, 2008 8:15 pm
by Pupil
I think this could be the faulty one:

Code: Select all

typedef struct WINTRUST_FILE_INFO_ {
  DWORD cbStruct;
  LPCWSTR pcwszFilePath;
  HANDLE hFile;
  GUID *pgKnownSubject;
} WINTRUST_FILE_INFO, 
Last item should be set to a pointer, in dagcrack's version its set to a long.

There seem to be some issues with this structure as well:

Code: Select all

typedef struct _WINTRUST_DATA {
  DWORD cbStruct;
  LPVOID pPolicyCallbackData;
  LPVOID pSIPClientData;
  DWORD dwUIChoice;
  DWORD fdwRevocationChecks;
  DWORD dwUnionChoice;
  union {
    struct WINTRUST_FILE_INFO_ *pFile;
    struct WINTRUST_CATALOG_INFO_ *pCatalog;
    struct WINTRUST_BLOB_INFO_ *pBlob;
    struct WINTRUST_SGNR_INFO_ *pSgnr;
    struct WINTRUST_CERT_INFO_ *pCert;
  } ;
  DWORD dwStateAction;
  HANDLE hWVTStateData;
  WCHAR *pwszURLReference;
  DWORD dwProvFlags;
  DWORD dwUIContext;
} WINTRUST_DATA, 
You probably need to change the items starting with LPVOID to pointers or to PB integer type (i.e '.i'). As for the 'hWVTStateData' item i'm not sure if Handles are 64 bit or 32bit?

Posted: Tue Dec 16, 2008 8:54 pm
by Thunder93
Hi,

Currently my structures look like this;

Code: Select all

Structure WINTRUST_DATA
 
	cbStruct.l
	*pPolicyCallbackData.l
	*pSIPClientData.l
	dwUIChoice.l
	fdwRevocationChecks.l
	dwUnionChoice.l
 
	StructureUnion
		*pFile.WINTRUST_FILE_INFO
		*pCatalog.WINTRUST_CATALOG_INFO
		*pBlob.WINTRUST_BLOB_INFO
		*pSgnr.WINTRUST_SGNR_INFO
		*pCert.WINTRUST_CERT_INFO
	EndStructureUnion
 
	dwStateAction.l
	hWVTStateData.l
	*pwszURLReference.l
	dwProvFlags.l
	dwUIContext.l
 
EndStructure
 
Structure WINTRUST_FILE_INFO
  cbStruct.l
  *pcwszFilePath.l
  hFile.l
  *pgKnownSubject.l
EndStructure


PureBasic-x64 v4.30Beta5;
-> moviethumb.exe
-> npPicasa3.dll
-> Picasa3.exe
-> PicasaPhotoViewer.exe
-> PicasaUpdater.exe
-> qtsupport.dll
-> setup.exe
-> Uninstall.exe


PureBasic-x86 v4.30beta5
Trusted -> moviethumb.exe
Trusted -> npPicasa3.dll
Trusted -> Picasa3.exe
Trusted -> PicasaPhotoViewer.exe
Trusted -> PicasaUpdater.exe
Not signed -> qtsupport.dll
Trusted -> setup.exe
Not signed -> Uninstall.exe