Files
mirror-processhacker/trunk/ProcessHacker.Native/Cryptography.cs
T
wj32 c096bdfa33 major refactoring; all Native functions are now in a separate assembly
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1109 21ef857c-d57f-4fe0-8362-d861dc6d29cd
2009-04-21 00:39:15 +00:00

193 lines
6.9 KiB
C#

using System.Runtime.InteropServices;
using System.Text;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
namespace ProcessHacker.Native
{
public enum VerifyResult : int
{
Unknown = 0,
NoSignature,
Trusted,
TrustedInstaller,
Expired,
Revoked,
Distrust,
SecuritySettings
}
public static class Cryptography
{
public static readonly ProcessHacker.Native.Api.Guid GenericCertVerify =
new ProcessHacker.Native.Api.Guid()
{
Data1 = 0x189a3842,
Data2 = 0x3041,
Data3 = 0x11d1,
Data4 = new byte[] { 0x85, 0xe1, 0x00, 0xc0, 0x4f, 0xc2, 0x95, 0xee }
};
public static readonly ProcessHacker.Native.Api.Guid GenericVerifyV2 =
new ProcessHacker.Native.Api.Guid()
{
Data1 = 0xaac56b,
Data2 = 0xcd44,
Data3 = 0x11d0,
Data4 = new byte[] { 0x8c, 0xc2, 0x00, 0xc0, 0x4f, 0xc2, 0x95, 0xee }
};
public static readonly ProcessHacker.Native.Api.Guid GenericChainVerify =
new ProcessHacker.Native.Api.Guid()
{
Data1 = 0xfc451c16,
Data2 = 0xac75,
Data3 = 0x11d1,
Data4 = new byte[] { 0xb4, 0xb8, 0x00, 0xc0, 0x4f, 0xb6, 0x6e, 0xa0 }
};
public static readonly ProcessHacker.Native.Api.Guid DriverVerify =
new ProcessHacker.Native.Api.Guid()
{
Data1 = 0xf750e6c3,
Data2 = 0x38ee,
Data3 = 0x11d1,
Data4 = new byte[] { 0x85, 0xe5, 0x00, 0xc0, 0x4f, 0xc2, 0x95, 0xee }
};
public static VerifyResult StatusToVerifyResult(uint status)
{
if (status == 0)
return VerifyResult.Trusted;
else if (status == 0x800b0100)
return VerifyResult.NoSignature;
else if (status == 0x800b0101)
return VerifyResult.Expired;
else if (status == 0x800b010c)
return VerifyResult.Revoked;
else if (status == 0x800b0111)
return VerifyResult.Distrust;
else if (status == 0x80092026)
return VerifyResult.SecuritySettings;
else
return VerifyResult.SecuritySettings;
}
public static VerifyResult VerifyFile(string filePath)
{
VerifyResult result = VerifyResult.NoSignature;
using (MemoryAlloc strMem = new MemoryAlloc(filePath.Length * 2 + 2))
{
WintrustFileInfo fileInfo = new WintrustFileInfo();
strMem.WriteUnicodeString(0, filePath);
strMem.WriteByte(filePath.Length * 2, 0);
strMem.WriteByte(filePath.Length * 2 + 1, 0);
fileInfo.Size = Marshal.SizeOf(fileInfo);
fileInfo.FilePath = strMem;
WintrustData trustData = new WintrustData();
trustData.Size = 12 * 4;
trustData.UIChoice = 2; // WTD_UI_NONE
trustData.UnionChoice = 1; // WTD_CHOICE_FILE
trustData.ProvFlags = 0x100; // WTD_SAFER_FLAG
using (MemoryAlloc mem = new MemoryAlloc(fileInfo.Size))
{
Marshal.StructureToPtr(fileInfo, mem, false);
trustData.UnionData = mem;
var action = GenericVerifyV2;
uint winTrustResult = Win32.WinVerifyTrust(0, ref action, ref trustData);
result = StatusToVerifyResult(winTrustResult);
}
}
if (result == VerifyResult.NoSignature)
{
FileHandle sourceFile = new FileHandle(filePath, FileAccess.GenericRead, FileShareMode.Read,
FileCreationDisposition.OpenExisting);
byte[] hash = new byte[256];
int hashLength = 256;
if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0))
{
hash = new byte[hashLength];
if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0))
return VerifyResult.NoSignature;
}
StringBuilder memberTag = new StringBuilder(hashLength * 2);
for (int i = 0; i < hashLength; i++)
memberTag.Append(hash[i].ToString("X2"));
int catAdmin;
var action = DriverVerify;
if (!Win32.CryptCATAdminAcquireContext(out catAdmin, ref action, 0))
return VerifyResult.NoSignature;
int catInfo = Win32.CryptCATAdminEnumCatalogFromHash(catAdmin, hash, hashLength, 0, 0);
if (catInfo == 0)
{
Win32.CryptCATAdminReleaseContext(catAdmin, 0);
return VerifyResult.NoSignature;
}
CatalogInfo ci = new CatalogInfo();
if (!Win32.CryptCATCatalogInfoFromContext(catInfo, ref ci, 0))
{
Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0);
Win32.CryptCATAdminReleaseContext(catAdmin, 0);
return VerifyResult.NoSignature;
}
WintrustCatalogInfo wci = new WintrustCatalogInfo();
wci.Size = Marshal.SizeOf(wci);
wci.CatalogFilePath = ci.CatalogFile;
wci.MemberFilePath = filePath;
wci.MemberTag = memberTag.ToString();
WintrustData trustData = new WintrustData();
trustData.Size = 12 * 4;
trustData.UIChoice = 1;
trustData.UnionChoice = 2;
using (MemoryAlloc mem = new MemoryAlloc(wci.Size))
{
Marshal.StructureToPtr(wci, mem, false);
try
{
trustData.UnionData = mem;
var action2 = DriverVerify;
uint winTrustResult = Win32.WinVerifyTrust(0, ref action2, ref trustData);
result = StatusToVerifyResult(winTrustResult);
}
finally
{
Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0);
Win32.CryptCATAdminReleaseContext(catAdmin, 0);
Marshal.DestroyStructure(mem, typeof(WintrustCatalogInfo));
}
}
}
return result;
}
}
}