mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Migrate WinTrust functions to a common location (#17598)
This commit is contained in:
@@ -7,14 +7,15 @@
|
||||
#if !UNIX
|
||||
using Microsoft.Security.Extensions;
|
||||
#endif
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Security;
|
||||
using System.Management.Automation.Win32Native;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using Dbg = System.Management.Automation;
|
||||
using DWORD = System.UInt32;
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
@@ -52,6 +53,8 @@ namespace System.Management.Automation
|
||||
/// </summary>
|
||||
internal static class SignatureHelper
|
||||
{
|
||||
private static Guid WINTRUST_ACTION_GENERIC_VERIFY_V2 = new Guid("00AAC56B-CD44-11d0-8CC2-00C04FC295EE");
|
||||
|
||||
/// <summary>
|
||||
/// Tracer for SignatureHelper.
|
||||
/// </summary>
|
||||
@@ -103,7 +106,7 @@ namespace System.Management.Automation
|
||||
bool result = false;
|
||||
Signature signature = null;
|
||||
IntPtr pSignInfo = IntPtr.Zero;
|
||||
DWORD error = 0;
|
||||
uint error = 0;
|
||||
string hashOid = null;
|
||||
|
||||
Utils.CheckArgForNullOrEmpty(fileName, "fileName");
|
||||
@@ -190,7 +193,7 @@ namespace System.Management.Automation
|
||||
// able to see that.
|
||||
#pragma warning disable 56523
|
||||
result = NativeMethods.CryptUIWizDigitalSign(
|
||||
(DWORD)NativeMethods.CryptUIFlags.CRYPTUI_WIZ_NO_UI,
|
||||
(uint)NativeMethods.CryptUIFlags.CRYPTUI_WIZ_NO_UI,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero,
|
||||
pSignInfo,
|
||||
@@ -246,7 +249,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
else
|
||||
{
|
||||
signature = new Signature(fileName, (DWORD)error);
|
||||
signature = new Signature(fileName, (uint)error);
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -330,7 +333,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
DWORD error = GetErrorFromSignatureState(fileSigInfo.State);
|
||||
uint error = GetErrorFromSignatureState(fileSigInfo.State);
|
||||
|
||||
if (fileSigInfo.SigningCertificate is null)
|
||||
{
|
||||
@@ -374,7 +377,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
|
||||
#if !UNIX
|
||||
private static DWORD GetErrorFromSignatureState(SignatureState signatureState)
|
||||
private static uint GetErrorFromSignatureState(SignatureState signatureState)
|
||||
{
|
||||
switch (signatureState)
|
||||
{
|
||||
@@ -401,8 +404,8 @@ namespace System.Management.Automation
|
||||
{
|
||||
Signature signature = null;
|
||||
|
||||
NativeMethods.WINTRUST_DATA wtd;
|
||||
DWORD error = Win32Errors.E_FAIL;
|
||||
WinTrustMethods.WINTRUST_DATA wtd;
|
||||
uint error = Win32Errors.E_FAIL;
|
||||
|
||||
if (fileContent == null)
|
||||
{
|
||||
@@ -422,7 +425,10 @@ namespace System.Management.Automation
|
||||
|
||||
signature = GetSignatureFromWintrustData(fileName, error, wtd);
|
||||
|
||||
error = NativeMethods.DestroyWintrustDataStruct(wtd);
|
||||
wtd.dwStateAction = WinTrustAction.WTD_STATEACTION_CLOSE;
|
||||
error = WinTrustMethods.WinVerifyTrust(IntPtr.Zero,
|
||||
ref WINTRUST_ACTION_GENERIC_VERIFY_V2,
|
||||
ref wtd);
|
||||
|
||||
if (error != Win32Errors.NO_ERROR)
|
||||
{
|
||||
@@ -438,89 +444,83 @@ namespace System.Management.Automation
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
private static DWORD GetWinTrustData(string fileName, string fileContent,
|
||||
out NativeMethods.WINTRUST_DATA wtData)
|
||||
private static uint GetWinTrustData(string fileName, string fileContent,
|
||||
out WinTrustMethods.WINTRUST_DATA wtData)
|
||||
{
|
||||
DWORD dwResult = Win32Errors.E_FAIL;
|
||||
IntPtr WINTRUST_ACTION_GENERIC_VERIFY_V2 = IntPtr.Zero;
|
||||
IntPtr wtdBuffer = IntPtr.Zero;
|
||||
|
||||
Guid actionVerify =
|
||||
new Guid("00AAC56B-CD44-11d0-8CC2-00C04FC295EE");
|
||||
|
||||
try
|
||||
wtData = new()
|
||||
{
|
||||
WINTRUST_ACTION_GENERIC_VERIFY_V2 =
|
||||
Marshal.AllocCoTaskMem(Marshal.SizeOf(actionVerify));
|
||||
Marshal.StructureToPtr(actionVerify,
|
||||
WINTRUST_ACTION_GENERIC_VERIFY_V2,
|
||||
false);
|
||||
cbStruct = (uint)Marshal.SizeOf<WinTrustMethods.WINTRUST_DATA>(),
|
||||
dwUIChoice = WinTrustUIChoice.WTD_UI_NONE,
|
||||
dwStateAction = WinTrustAction.WTD_STATEACTION_VERIFY,
|
||||
};
|
||||
|
||||
NativeMethods.WINTRUST_DATA wtd;
|
||||
|
||||
if (fileContent == null)
|
||||
{
|
||||
NativeMethods.WINTRUST_FILE_INFO wfi = NativeMethods.InitWintrustFileInfoStruct(fileName);
|
||||
wtd = NativeMethods.InitWintrustDataStructFromFile(wfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeMethods.WINTRUST_BLOB_INFO wbi = NativeMethods.InitWintrustBlobInfoStruct(fileName, fileContent);
|
||||
wtd = NativeMethods.InitWintrustDataStructFromBlob(wbi);
|
||||
}
|
||||
|
||||
wtdBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(wtd));
|
||||
Marshal.StructureToPtr(wtd, wtdBuffer, false);
|
||||
|
||||
// The result is returned to the caller, and handled generically.
|
||||
// Disable the PreFast check for Win32 error codes, as we don't care.
|
||||
#pragma warning disable 56523
|
||||
dwResult = NativeMethods.WinVerifyTrust(
|
||||
IntPtr.Zero,
|
||||
WINTRUST_ACTION_GENERIC_VERIFY_V2,
|
||||
wtdBuffer);
|
||||
#pragma warning restore 56523
|
||||
|
||||
wtData = Marshal.PtrToStructure<NativeMethods.WINTRUST_DATA>(wtdBuffer);
|
||||
}
|
||||
finally
|
||||
byte[] contentBytes = fileContent == null
|
||||
? Array.Empty<byte>()
|
||||
: System.Text.Encoding.Unicode.GetBytes(fileContent);
|
||||
unsafe
|
||||
{
|
||||
Marshal.DestroyStructure<Guid>(WINTRUST_ACTION_GENERIC_VERIFY_V2);
|
||||
Marshal.FreeCoTaskMem(WINTRUST_ACTION_GENERIC_VERIFY_V2);
|
||||
Marshal.DestroyStructure<NativeMethods.WINTRUST_DATA>(wtdBuffer);
|
||||
Marshal.FreeCoTaskMem(wtdBuffer);
|
||||
}
|
||||
fixed (char* fileNamePtr = fileName)
|
||||
{
|
||||
if (fileContent == null)
|
||||
{
|
||||
WinTrustMethods.WINTRUST_FILE_INFO wfi = new()
|
||||
{
|
||||
cbStruct = (uint)Marshal.SizeOf<WinTrustMethods.WINTRUST_FILE_INFO>(),
|
||||
pcwszFilePath = fileNamePtr,
|
||||
};
|
||||
wtData.dwUnionChoice = WinTrustUnionChoice.WTD_CHOICE_FILE;
|
||||
wtData.pChoice = &wfi;
|
||||
|
||||
return dwResult;
|
||||
return WinTrustMethods.WinVerifyTrust(IntPtr.Zero,
|
||||
ref WINTRUST_ACTION_GENERIC_VERIFY_V2,
|
||||
ref wtData);
|
||||
}
|
||||
|
||||
fixed (byte* contentPtr = contentBytes)
|
||||
{
|
||||
Guid pwshSIP = new("603BCC1F-4B59-4E08-B724-D2C6297EF351");
|
||||
WinTrustMethods.WINTRUST_BLOB_INFO wbi = new()
|
||||
{
|
||||
cbStruct = (uint)Marshal.SizeOf<WinTrustMethods.WINTRUST_BLOB_INFO>(),
|
||||
gSubject = pwshSIP,
|
||||
pcwszDisplayName = fileNamePtr,
|
||||
cbMemObject = (uint)contentBytes.Length,
|
||||
pbMemObject = contentPtr,
|
||||
};
|
||||
wtData.dwUnionChoice = WinTrustUnionChoice.WTD_CHOICE_BLOB;
|
||||
wtData.pChoice = &wbi;
|
||||
|
||||
return WinTrustMethods.WinVerifyTrust(IntPtr.Zero,
|
||||
ref WINTRUST_ACTION_GENERIC_VERIFY_V2,
|
||||
ref wtData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
private static X509Certificate2 GetCertFromChain(IntPtr pSigner)
|
||||
{
|
||||
X509Certificate2 signerCert = null;
|
||||
|
||||
// We don't care about the Win32 error code here, so disable
|
||||
// the PreFast complaint that we're not retrieving it.
|
||||
#pragma warning disable 56523
|
||||
IntPtr pCert =
|
||||
NativeMethods.WTHelperGetProvCertFromChain(pSigner, 0);
|
||||
#pragma warning restore 56523
|
||||
|
||||
if (pCert != IntPtr.Zero)
|
||||
try
|
||||
{
|
||||
IntPtr pCert = WinTrustMethods.WTHelperGetProvCertFromChain(pSigner, 0);
|
||||
NativeMethods.CRYPT_PROVIDER_CERT provCert =
|
||||
Marshal.PtrToStructure<NativeMethods.CRYPT_PROVIDER_CERT>(pCert);
|
||||
signerCert = new X509Certificate2(provCert.pCert);
|
||||
return new X509Certificate2(provCert.pCert);
|
||||
}
|
||||
catch (Win32Exception)
|
||||
{
|
||||
// We don't care about the Win32 error code here, so return
|
||||
// null on a failure and let the caller handle it.
|
||||
return null;
|
||||
}
|
||||
|
||||
return signerCert;
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
private static Signature GetSignatureFromWintrustData(
|
||||
string filePath,
|
||||
DWORD error,
|
||||
NativeMethods.WINTRUST_DATA wtd)
|
||||
uint error,
|
||||
WinTrustMethods.WINTRUST_DATA wtd)
|
||||
{
|
||||
s_tracer.WriteLine("GetSignatureFromWintrustData: error: {0}", error);
|
||||
|
||||
@@ -568,39 +568,36 @@ namespace System.Management.Automation
|
||||
pProvSigner = IntPtr.Zero;
|
||||
timestamperCert = null;
|
||||
|
||||
// The GetLastWin32Error of this is checked, but PreSharp doesn't seem to be
|
||||
// able to see that.
|
||||
#pragma warning disable 56523
|
||||
IntPtr pProvData =
|
||||
NativeMethods.WTHelperProvDataFromStateData(wvtStateData);
|
||||
#pragma warning restore 56523
|
||||
|
||||
if (pProvData != IntPtr.Zero)
|
||||
try
|
||||
{
|
||||
pProvSigner =
|
||||
NativeMethods.WTHelperGetProvSignerFromChain(pProvData, 0, 0, 0);
|
||||
IntPtr pProvData = WinTrustMethods.WTHelperProvDataFromStateData(wvtStateData);
|
||||
|
||||
if (pProvSigner != IntPtr.Zero)
|
||||
pProvSigner = WinTrustMethods.WTHelperGetProvSignerFromChain(
|
||||
pProvData,
|
||||
signerIdx: 0,
|
||||
counterSigner: false,
|
||||
counterSignerIdx: 0);
|
||||
|
||||
NativeMethods.CRYPT_PROVIDER_SGNR provSigner =
|
||||
Marshal.PtrToStructure<NativeMethods.CRYPT_PROVIDER_SGNR>(pProvSigner);
|
||||
if (provSigner.csCounterSigners == 1)
|
||||
{
|
||||
NativeMethods.CRYPT_PROVIDER_SGNR provSigner =
|
||||
Marshal.PtrToStructure<NativeMethods.CRYPT_PROVIDER_SGNR>(pProvSigner);
|
||||
if (provSigner.csCounterSigners == 1)
|
||||
{
|
||||
//
|
||||
// time stamper cert available
|
||||
//
|
||||
timestamperCert = GetCertFromChain(provSigner.pasCounterSigners);
|
||||
}
|
||||
|
||||
return true;
|
||||
//
|
||||
// time stamper cert available
|
||||
//
|
||||
timestamperCert = GetCertFromChain(provSigner.pasCounterSigners);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
catch (Win32Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
private static DWORD GetLastWin32Error()
|
||||
private static uint GetLastWin32Error()
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Security;
|
||||
using System.Management.Automation.Win32Native;
|
||||
using System.Runtime.InteropServices;
|
||||
using DWORD = System.UInt32;
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
@@ -83,12 +84,11 @@ namespace System.Management.Automation
|
||||
/// </summary>
|
||||
/// <param name="catalogHandle">Handle to open catalog file.</param>
|
||||
/// <returns>Version of the catalog.</returns>
|
||||
private static int GetCatalogVersion(IntPtr catalogHandle)
|
||||
private static int GetCatalogVersion(SafeCATHandle catalogHandle)
|
||||
{
|
||||
int catalogVersion = -1;
|
||||
|
||||
IntPtr catalogData = NativeMethods.CryptCATStoreFromHandle(catalogHandle);
|
||||
NativeMethods.CRYPTCATSTORE catalogInfo = Marshal.PtrToStructure<NativeMethods.CRYPTCATSTORE>(catalogData);
|
||||
WinTrustMethods.CRYPTCATSTORE catalogInfo = WinTrustMethods.CryptCATStoreFromHandle(catalogHandle);
|
||||
|
||||
if (catalogInfo.dwPublicVersion == catalogVersion2)
|
||||
{
|
||||
@@ -248,20 +248,32 @@ namespace System.Management.Automation
|
||||
/// <param name="cdfFilePath">Path to the Input .cdf file.</param>
|
||||
internal static void GenerateCatalogFile(string cdfFilePath)
|
||||
{
|
||||
string pwszFilePath = cdfFilePath;
|
||||
NativeMethods.CryptCATCDFOpenCallBack catOpenCallBack = new NativeMethods.CryptCATCDFOpenCallBack(ParseErrorCallback);
|
||||
|
||||
// Open CDF File
|
||||
IntPtr resultCDF = NativeMethods.CryptCATCDFOpen(pwszFilePath, catOpenCallBack);
|
||||
SafeCATCDFHandle resultCDF;
|
||||
try
|
||||
{
|
||||
resultCDF = WinTrustMethods.CryptCATCDFOpen(cdfFilePath, ParseErrorCallback);
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
// If we are not able to open CDF file we can not continue generating catalog
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
new InvalidOperationException(CatalogStrings.UnableToOpenCatalogDefinitionFile, e),
|
||||
"UnableToOpenCatalogDefinitionFile",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
return;
|
||||
}
|
||||
|
||||
// navigate CDF header and files sections
|
||||
if (resultCDF != IntPtr.Zero)
|
||||
using (resultCDF)
|
||||
{
|
||||
// First navigate all catalog level attributes entries first, they represent zero size files
|
||||
IntPtr catalogAttr = IntPtr.Zero;
|
||||
do
|
||||
{
|
||||
catalogAttr = NativeMethods.CryptCATCDFEnumCatAttributes(resultCDF, catalogAttr, catOpenCallBack);
|
||||
catalogAttr = WinTrustMethods.CryptCATCDFEnumCatAttributes(resultCDF, catalogAttr, ParseErrorCallback);
|
||||
|
||||
if (catalogAttr != IntPtr.Zero)
|
||||
{
|
||||
@@ -272,51 +284,38 @@ namespace System.Management.Automation
|
||||
|
||||
// navigate all the files hash entries in the .cdf file
|
||||
IntPtr memberInfo = IntPtr.Zero;
|
||||
try
|
||||
IntPtr memberFile = IntPtr.Zero;
|
||||
string fileName = string.Empty;
|
||||
do
|
||||
{
|
||||
IntPtr memberFile = IntPtr.Zero;
|
||||
NativeMethods.CryptCATCDFEnumMembersByCDFTagExErrorCallBack memberCallBack = new NativeMethods.CryptCATCDFEnumMembersByCDFTagExErrorCallBack(ParseErrorCallback);
|
||||
string fileName = string.Empty;
|
||||
do
|
||||
memberFile = WinTrustMethods.CryptCATCDFEnumMembersByCDFTagEx(resultCDF, memberFile, ParseErrorCallback, ref memberInfo,
|
||||
fContinueOnError: true, pvReserved: IntPtr.Zero);
|
||||
fileName = Marshal.PtrToStringUni(memberFile);
|
||||
|
||||
if (!string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
memberFile = NativeMethods.CryptCATCDFEnumMembersByCDFTagEx(resultCDF, memberFile, memberCallBack, ref memberInfo, true, IntPtr.Zero);
|
||||
fileName = Marshal.PtrToStringUni(memberFile);
|
||||
|
||||
if (!string.IsNullOrEmpty(fileName))
|
||||
IntPtr memberAttr = IntPtr.Zero;
|
||||
string fileRelativePath = string.Empty;
|
||||
do
|
||||
{
|
||||
IntPtr memberAttr = IntPtr.Zero;
|
||||
string fileRelativePath = string.Empty;
|
||||
do
|
||||
{
|
||||
memberAttr = NativeMethods.CryptCATCDFEnumAttributesWithCDFTag(resultCDF, memberFile, memberInfo, memberAttr, memberCallBack);
|
||||
memberAttr = WinTrustMethods.CryptCATCDFEnumAttributesWithCDFTag(resultCDF, memberFile, memberInfo, memberAttr, ParseErrorCallback);
|
||||
|
||||
if (memberAttr != IntPtr.Zero)
|
||||
if (memberAttr != IntPtr.Zero)
|
||||
{
|
||||
fileRelativePath = ProcessFilePathAttributeInCatalog(memberAttr);
|
||||
if (!string.IsNullOrEmpty(fileRelativePath))
|
||||
{
|
||||
fileRelativePath = ProcessFilePathAttributeInCatalog(memberAttr);
|
||||
if (!string.IsNullOrEmpty(fileRelativePath))
|
||||
{
|
||||
// Found the attribute we are looking for
|
||||
// Filename we read from the above API has <Hash> appended to its name as per CDF file tags convention
|
||||
// Truncating that Information from the string.
|
||||
string itemName = fileName.Substring(6);
|
||||
_cmdlet.WriteVerbose(StringUtil.Format(CatalogStrings.AddFileToCatalog, itemName, fileRelativePath));
|
||||
break;
|
||||
}
|
||||
// Found the attribute we are looking for
|
||||
// Filename we read from the above API has <Hash> appended to its name as per CDF file tags convention
|
||||
// Truncating that Information from the string.
|
||||
string itemName = fileName.Substring(6);
|
||||
_cmdlet.WriteVerbose(StringUtil.Format(CatalogStrings.AddFileToCatalog, itemName, fileRelativePath));
|
||||
break;
|
||||
}
|
||||
} while (memberAttr != IntPtr.Zero);
|
||||
}
|
||||
} while (fileName != null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.CryptCATCDFClose(resultCDF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we are not able to open CDF file we can not continue generating catalog
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(CatalogStrings.UnableToOpenCatalogDefinitionFile), "UnableToOpenCatalogDefinitionFile", ErrorCategory.InvalidOperation, null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
} while (memberAttr != IntPtr.Zero);
|
||||
}
|
||||
} while (fileName != null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +373,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
string relativePath = string.Empty;
|
||||
|
||||
NativeMethods.CRYPTCATATTRIBUTE currentMemberAttr = Marshal.PtrToStructure<NativeMethods.CRYPTCATATTRIBUTE>(memberAttrInfo);
|
||||
WinTrustMethods.CRYPTCATATTRIBUTE currentMemberAttr = Marshal.PtrToStructure<WinTrustMethods.CRYPTCATATTRIBUTE>(memberAttrInfo);
|
||||
|
||||
// check if this is the attribute we are looking for
|
||||
// catalog generated other way not using New-FileCatalog can have attributes we don't understand
|
||||
@@ -400,69 +399,65 @@ namespace System.Management.Automation
|
||||
internal static string CalculateFileHash(string filePath, string hashAlgorithm)
|
||||
{
|
||||
string hashValue = string.Empty;
|
||||
IntPtr catAdmin = IntPtr.Zero;
|
||||
|
||||
// To get handle to the hash algorithm to be used to calculate hashes
|
||||
if (!NativeMethods.CryptCATAdminAcquireContext2(ref catAdmin, IntPtr.Zero, hashAlgorithm, IntPtr.Zero, 0))
|
||||
SafeCATAdminHandle catAdmin;
|
||||
try
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToAcquireHashAlgorithmContext, hashAlgorithm)), "UnableToAcquireHashAlgorithmContext", ErrorCategory.InvalidOperation, null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
catAdmin = WinTrustMethods.CryptCATAdminAcquireContext2(hashAlgorithm);
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToAcquireHashAlgorithmContext, hashAlgorithm), e),
|
||||
"UnableToAcquireHashAlgorithmContext",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
|
||||
const DWORD GENERIC_READ = 0x80000000;
|
||||
const DWORD OPEN_EXISTING = 3;
|
||||
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
|
||||
// The method returns an empty string on a failure.
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
// Open the file that is to be hashed for reading and get its handle
|
||||
IntPtr fileHandle = NativeMethods.CreateFile(filePath, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, IntPtr.Zero);
|
||||
if (fileHandle != INVALID_HANDLE_VALUE)
|
||||
FileStream fileStream;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
DWORD hashBufferSize = 0;
|
||||
IntPtr hashBuffer = IntPtr.Zero;
|
||||
|
||||
// Call first time to get the size of expected buffer to hold new hash value
|
||||
if (!NativeMethods.CryptCATAdminCalcHashFromFileHandle2(catAdmin, fileHandle, ref hashBufferSize, hashBuffer, 0))
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToCreateFileHash, filePath)), "UnableToCreateFileHash", ErrorCategory.InvalidOperation, null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
|
||||
int size = (int)hashBufferSize;
|
||||
hashBuffer = Marshal.AllocHGlobal(size);
|
||||
try
|
||||
{
|
||||
// Call second time to actually get the hash value
|
||||
if (!NativeMethods.CryptCATAdminCalcHashFromFileHandle2(catAdmin, fileHandle, ref hashBufferSize, hashBuffer, 0))
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToCreateFileHash, filePath)), "UnableToCreateFileHash", ErrorCategory.InvalidOperation, null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
|
||||
byte[] hashBytes = new byte[size];
|
||||
Marshal.Copy(hashBuffer, hashBytes, 0, size);
|
||||
hashValue = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (hashBuffer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(hashBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.CryptCATAdminReleaseContext(catAdmin, 0);
|
||||
NativeMethods.CloseHandle(fileHandle);
|
||||
}
|
||||
fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
// If we are not able to open file that is to be hashed we can not continue with catalog validation
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToReadFileToHash, filePath)), "UnableToReadFileToHash", ErrorCategory.InvalidOperation, null);
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToReadFileToHash, filePath), e),
|
||||
"UnableToReadFileToHash",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
|
||||
// The method returns an empty string on a failure.
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
using (catAdmin)
|
||||
using (fileStream)
|
||||
{
|
||||
byte[] hashBytes = Array.Empty<byte>();
|
||||
try
|
||||
{
|
||||
hashBytes = WinTrustMethods.CryptCATAdminCalcHashFromFileHandle2(catAdmin, fileStream.SafeFileHandle);
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToCreateFileHash, filePath), e),
|
||||
"UnableToCreateFileHash",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
|
||||
hashValue = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
|
||||
}
|
||||
|
||||
return hashValue;
|
||||
@@ -477,90 +472,92 @@ namespace System.Management.Automation
|
||||
/// <returns>Dictionary mapping files relative paths to HashValues.</returns>
|
||||
internal static Dictionary<string, string> GetHashesFromCatalog(string catalogFilePath, WildcardPattern[] excludedPatterns, out int catalogVersion)
|
||||
{
|
||||
IntPtr resultCatalog = NativeMethods.CryptCATOpen(catalogFilePath, 0, IntPtr.Zero, 1, 0);
|
||||
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
|
||||
Dictionary<string, string> catalogHashes = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
|
||||
catalogVersion = 0;
|
||||
|
||||
if (resultCatalog != INVALID_HANDLE_VALUE)
|
||||
SafeCATHandle resultCatalog;
|
||||
try
|
||||
{
|
||||
try
|
||||
resultCatalog = WinTrustMethods.CryptCATOpen(catalogFilePath, 0, IntPtr.Zero, 1, 0);
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToOpenCatalogFile, catalogFilePath), e),
|
||||
"UnableToOpenCatalogFile",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
return catalogHashes;
|
||||
}
|
||||
|
||||
using (resultCatalog)
|
||||
{
|
||||
IntPtr catAttrInfo = IntPtr.Zero;
|
||||
|
||||
// First traverse all catalog level attributes to get information about zero size file.
|
||||
do
|
||||
{
|
||||
IntPtr catAttrInfo = IntPtr.Zero;
|
||||
catAttrInfo = WinTrustMethods.CryptCATEnumerateCatAttr(resultCatalog, catAttrInfo);
|
||||
|
||||
// First traverse all catalog level attributes to get information about zero size file.
|
||||
do
|
||||
// If we found attribute it is a file information retrieve its relative path
|
||||
// and add it to catalog hash collection if its not in excluded files criteria
|
||||
if (catAttrInfo != IntPtr.Zero)
|
||||
{
|
||||
catAttrInfo = NativeMethods.CryptCATEnumerateCatAttr(resultCatalog, catAttrInfo);
|
||||
|
||||
// If we found attribute it is a file information retrieve its relative path
|
||||
// and add it to catalog hash collection if its not in excluded files criteria
|
||||
if (catAttrInfo != IntPtr.Zero)
|
||||
string relativePath = ProcessFilePathAttributeInCatalog(catAttrInfo);
|
||||
if (!string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
string relativePath = ProcessFilePathAttributeInCatalog(catAttrInfo);
|
||||
if (!string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
ProcessCatalogFile(relativePath, string.Empty, excludedPatterns, ref catalogHashes);
|
||||
}
|
||||
ProcessCatalogFile(relativePath, string.Empty, excludedPatterns, ref catalogHashes);
|
||||
}
|
||||
} while (catAttrInfo != IntPtr.Zero);
|
||||
}
|
||||
} while (catAttrInfo != IntPtr.Zero);
|
||||
|
||||
catalogVersion = GetCatalogVersion(resultCatalog);
|
||||
catalogVersion = GetCatalogVersion(resultCatalog);
|
||||
|
||||
IntPtr memberInfo = IntPtr.Zero;
|
||||
// Next Navigate all members in Catalog files and get their relative paths and hashes
|
||||
do
|
||||
IntPtr memberInfo = IntPtr.Zero;
|
||||
// Next Navigate all members in Catalog files and get their relative paths and hashes
|
||||
do
|
||||
{
|
||||
memberInfo = WinTrustMethods.CryptCATEnumerateMember(resultCatalog, memberInfo);
|
||||
if (memberInfo != IntPtr.Zero)
|
||||
{
|
||||
memberInfo = NativeMethods.CryptCATEnumerateMember(resultCatalog, memberInfo);
|
||||
if (memberInfo != IntPtr.Zero)
|
||||
WinTrustMethods.CRYPTCATMEMBER currentMember = Marshal.PtrToStructure<WinTrustMethods.CRYPTCATMEMBER>(memberInfo);
|
||||
WinTrustMethods.SIP_INDIRECT_DATA pIndirectData = Marshal.PtrToStructure<WinTrustMethods.SIP_INDIRECT_DATA>(currentMember.pIndirectData);
|
||||
|
||||
// For Catalog version 2 CryptoAPI puts hashes of file attributes(relative path in our case) in Catalog as well
|
||||
// We validate those along with file hashes so we are skipping duplicate entries
|
||||
if (!((catalogVersion == 2) && (pIndirectData.DigestAlgorithm.pszObjId.Equals(new Oid("SHA1").Value, StringComparison.OrdinalIgnoreCase))))
|
||||
{
|
||||
NativeMethods.CRYPTCATMEMBER currentMember = Marshal.PtrToStructure<NativeMethods.CRYPTCATMEMBER>(memberInfo);
|
||||
NativeMethods.SIP_INDIRECT_DATA pIndirectData = Marshal.PtrToStructure<NativeMethods.SIP_INDIRECT_DATA>(currentMember.pIndirectData);
|
||||
|
||||
// For Catalog version 2 CryptoAPI puts hashes of file attributes(relative path in our case) in Catalog as well
|
||||
// We validate those along with file hashes so we are skipping duplicate entries
|
||||
if (!((catalogVersion == 2) && (pIndirectData.DigestAlgorithm.pszObjId.Equals(new Oid("SHA1").Value, StringComparison.OrdinalIgnoreCase))))
|
||||
string relativePath = string.Empty;
|
||||
IntPtr memberAttrInfo = IntPtr.Zero;
|
||||
do
|
||||
{
|
||||
string relativePath = string.Empty;
|
||||
IntPtr memberAttrInfo = IntPtr.Zero;
|
||||
do
|
||||
{
|
||||
memberAttrInfo = NativeMethods.CryptCATEnumerateAttr(resultCatalog, memberInfo, memberAttrInfo);
|
||||
memberAttrInfo = WinTrustMethods.CryptCATEnumerateAttr(resultCatalog, memberInfo, memberAttrInfo);
|
||||
|
||||
if (memberAttrInfo != IntPtr.Zero)
|
||||
if (memberAttrInfo != IntPtr.Zero)
|
||||
{
|
||||
relativePath = ProcessFilePathAttributeInCatalog(memberAttrInfo);
|
||||
if (!string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
relativePath = ProcessFilePathAttributeInCatalog(memberAttrInfo);
|
||||
if (!string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (memberAttrInfo != IntPtr.Zero);
|
||||
|
||||
// If we did not find any Relative Path for the item in catalog we should quit
|
||||
// This catalog must not be valid for our use as catalogs generated using New-FileCatalog
|
||||
// always contains relative file Paths
|
||||
if (string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToOpenCatalogFile, catalogFilePath)), "UnableToOpenCatalogFile", ErrorCategory.InvalidOperation, null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
|
||||
ProcessCatalogFile(relativePath, currentMember.pwszReferenceTag, excludedPatterns, ref catalogHashes);
|
||||
}
|
||||
while (memberAttrInfo != IntPtr.Zero);
|
||||
|
||||
// If we did not find any Relative Path for the item in catalog we should quit
|
||||
// This catalog must not be valid for our use as catalogs generated using New-FileCatalog
|
||||
// always contains relative file Paths
|
||||
if (string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToOpenCatalogFile, catalogFilePath)), "UnableToOpenCatalogFile", ErrorCategory.InvalidOperation, null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
|
||||
ProcessCatalogFile(relativePath, currentMember.pwszReferenceTag, excludedPatterns, ref catalogHashes);
|
||||
}
|
||||
} while (memberInfo != IntPtr.Zero);
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.CryptCATClose(resultCatalog);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(StringUtil.Format(CatalogStrings.UnableToOpenCatalogFile, catalogFilePath)), "UnableToOpenCatalogFile", ErrorCategory.InvalidOperation, null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
} while (memberInfo != IntPtr.Zero);
|
||||
}
|
||||
|
||||
return catalogHashes;
|
||||
@@ -785,14 +782,18 @@ namespace System.Management.Automation
|
||||
/// <summary>
|
||||
/// Call back when error is thrown by catalog API's.
|
||||
/// </summary>
|
||||
private static void ParseErrorCallback(DWORD dwErrorArea, DWORD dwLocalError, string pwszLine)
|
||||
private static void ParseErrorCallback(uint dwErrorArea, uint dwLocalError, string pwszLine)
|
||||
{
|
||||
switch (dwErrorArea)
|
||||
{
|
||||
case NativeConstants.CRYPTCAT_E_AREA_HEADER: break;
|
||||
case NativeConstants.CRYPTCAT_E_AREA_MEMBER: break;
|
||||
case NativeConstants.CRYPTCAT_E_AREA_ATTRIBUTE: break;
|
||||
default: break;
|
||||
case NativeConstants.CRYPTCAT_E_AREA_HEADER:
|
||||
break;
|
||||
case NativeConstants.CRYPTCAT_E_AREA_MEMBER:
|
||||
break;
|
||||
case NativeConstants.CRYPTCAT_E_AREA_ATTRIBUTE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dwLocalError)
|
||||
@@ -815,18 +816,24 @@ namespace System.Management.Automation
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
break;
|
||||
}
|
||||
case NativeConstants.CRYPTCAT_E_CDF_BAD_GUID_CONV: break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_ATTR_TYPECOMBO: break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_ATTR_TOOFEWVALUES: break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_UNSUPPORTED: break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_BAD_GUID_CONV:
|
||||
break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_ATTR_TYPECOMBO:
|
||||
break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_ATTR_TOOFEWVALUES:
|
||||
break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_UNSUPPORTED:
|
||||
break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_DUPLICATE:
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(StringUtil.Format(CatalogStrings.FoundDuplicateFileMemberInCatalog, pwszLine)), "FoundDuplicateFileMemberInCatalog", ErrorCategory.InvalidOperation, null);
|
||||
_cmdlet.ThrowTerminatingError(errorRecord);
|
||||
break;
|
||||
}
|
||||
case NativeConstants.CRYPTCAT_E_CDF_TAGNOTFOUND: break;
|
||||
default: break;
|
||||
case NativeConstants.CRYPTCAT_E_CDF_TAGNOTFOUND:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,440 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Management.Automation.Win32Native;
|
||||
|
||||
internal class SafeCATAdminHandle : SafeHandle
|
||||
{
|
||||
internal SafeCATAdminHandle() : base(IntPtr.Zero, true) { }
|
||||
|
||||
public override bool IsInvalid => handle == IntPtr.Zero;
|
||||
|
||||
protected override bool ReleaseHandle() => WinTrustMethods.CryptCATAdminReleaseContext(handle, 0);
|
||||
}
|
||||
|
||||
internal class SafeCATHandle : SafeHandle
|
||||
{
|
||||
internal SafeCATHandle() : base(IntPtr.Zero, true) { }
|
||||
|
||||
public override bool IsInvalid => handle == (IntPtr)(-1);
|
||||
|
||||
protected override bool ReleaseHandle() => WinTrustMethods.CryptCATClose(handle);
|
||||
}
|
||||
|
||||
internal class SafeCATCDFHandle : SafeHandle
|
||||
{
|
||||
internal SafeCATCDFHandle() : base(IntPtr.Zero, true) { }
|
||||
|
||||
public override bool IsInvalid => handle == IntPtr.Zero;
|
||||
|
||||
protected override bool ReleaseHandle() => WinTrustMethods.CryptCATCDFClose(handle);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum WinTrustUIChoice
|
||||
{
|
||||
WTD_UI_ALL = 1,
|
||||
WTD_UI_NONE = 2,
|
||||
WTD_UI_NOBAD = 3,
|
||||
WTD_UI_NOGOOD = 4
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum WinTrustUnionChoice
|
||||
{
|
||||
WTD_CHOICE_FILE = 1,
|
||||
WTD_CHOICE_CATALOG = 2,
|
||||
WTD_CHOICE_BLOB = 3,
|
||||
WTD_CHOICE_SIGNER = 4,
|
||||
WTD_CHOICE_CERT = 5,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum WinTrustAction
|
||||
{
|
||||
WTD_STATEACTION_IGNORE = 0x00000000,
|
||||
WTD_STATEACTION_VERIFY = 0x00000001,
|
||||
WTD_STATEACTION_CLOSE = 0x00000002,
|
||||
WTD_STATEACTION_AUTO_CACHE = 0x00000003,
|
||||
WTD_STATEACTION_AUTO_CACHE_FLUSH = 0x00000004
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum WinTrustProviderFlags
|
||||
{
|
||||
WTD_PROV_FLAGS_MASK = 0x0000FFFF,
|
||||
WTD_USE_IE4_TRUST_FLAG = 0x00000001,
|
||||
WTD_NO_IE4_CHAIN_FLAG = 0x00000002,
|
||||
WTD_NO_POLICY_USAGE_FLAG = 0x00000004,
|
||||
WTD_REVOCATION_CHECK_NONE = 0x00000010,
|
||||
WTD_REVOCATION_CHECK_END_CERT = 0x00000020,
|
||||
WTD_REVOCATION_CHECK_CHAIN = 0x00000040,
|
||||
WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x00000080,
|
||||
WTD_SAFER_FLAG = 0x00000100,
|
||||
WTD_HASH_ONLY_FLAG = 0x00000200,
|
||||
WTD_USE_DEFAULT_OSVER_CHECK = 0x00000400,
|
||||
WTD_LIFETIME_SIGNING_FLAG = 0x00000800,
|
||||
WTD_CACHE_ONLY_URL_RETRIEVAL = 0x00001000
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pinvoke methods from wintrust.dll
|
||||
/// </summary>
|
||||
internal static class WinTrustMethods
|
||||
{
|
||||
private const string WinTrustDll = "wintrust.dll";
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPT_ATTR_BLOB
|
||||
{
|
||||
public uint cbData;
|
||||
public IntPtr pbData;
|
||||
}
|
||||
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)]
|
||||
internal struct CRYPT_ALGORITHM_IDENTIFIER
|
||||
{
|
||||
[MarshalAsAttribute(UnmanagedType.LPStr)] public string pszObjId;
|
||||
public CRYPT_ATTR_BLOB Parameters;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPT_ATTRIBUTE_TYPE_VALUE
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPStr)] public string pszObjId;
|
||||
public CRYPT_ATTR_BLOB Value;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct SIP_INDIRECT_DATA
|
||||
{
|
||||
public CRYPT_ATTRIBUTE_TYPE_VALUE Data;
|
||||
public CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm;
|
||||
public CRYPT_ATTR_BLOB Digest;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPTCATMEMBER
|
||||
{
|
||||
public uint cbStruct;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string pwszReferenceTag;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string pwszFileName;
|
||||
public Guid gSubjectType;
|
||||
public uint fdwMemberFlags;
|
||||
public IntPtr pIndirectData;
|
||||
public uint dwCertVersion;
|
||||
public uint dwReserved;
|
||||
public IntPtr hReserved;
|
||||
public CRYPT_ATTR_BLOB sEncodedIndirectData;
|
||||
public CRYPT_ATTR_BLOB sEncodedMemberInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPTCATATTRIBUTE
|
||||
{
|
||||
public uint cbStruct;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string pwszReferenceTag;
|
||||
public uint dwAttrTypeAndAction;
|
||||
public uint cbValue;
|
||||
public IntPtr pbValue;
|
||||
public uint dwReserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPTCATSTORE
|
||||
{
|
||||
public uint cbStruct;
|
||||
public uint dwPublicVersion;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string pwszP7File;
|
||||
public IntPtr hProv;
|
||||
public uint dwEncodingType;
|
||||
public uint fdwStoreFlags;
|
||||
public IntPtr hReserved;
|
||||
public IntPtr hAttrs;
|
||||
public IntPtr hCryptMsg;
|
||||
public IntPtr hSorted;
|
||||
}
|
||||
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)]
|
||||
internal struct WINTRUST_DATA
|
||||
{
|
||||
public uint cbStruct;
|
||||
public IntPtr pPolicyCallbackData;
|
||||
public IntPtr pSIPClientData;
|
||||
public WinTrustUIChoice dwUIChoice;
|
||||
public uint fdwRevocationChecks;
|
||||
public WinTrustUnionChoice dwUnionChoice;
|
||||
public unsafe void* pChoice;
|
||||
public WinTrustAction dwStateAction;
|
||||
public IntPtr hWVTStateData;
|
||||
public IntPtr pwszURLReference;
|
||||
public WinTrustProviderFlags dwProvFlags;
|
||||
public uint dwUIContext;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct WINTRUST_FILE_INFO
|
||||
{
|
||||
public uint cbStruct;
|
||||
public unsafe char* pcwszFilePath;
|
||||
public IntPtr hFile;
|
||||
public IntPtr pgKnownSubject;
|
||||
}
|
||||
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)]
|
||||
internal struct WINTRUST_BLOB_INFO
|
||||
{
|
||||
public uint cbStruct;
|
||||
public Guid gSubject;
|
||||
public unsafe char* pcwszDisplayName;
|
||||
public uint cbMemObject;
|
||||
public unsafe byte* pbMemObject;
|
||||
public uint cbMemSignedMsg;
|
||||
public IntPtr pbMemSignedMsg;
|
||||
}
|
||||
|
||||
[DllImport(
|
||||
WinTrustDll,
|
||||
CharSet = CharSet.Unicode,
|
||||
EntryPoint = "CryptCATAdminAcquireContext2",
|
||||
SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool NativeCryptCATAdminAcquireContext2(
|
||||
out SafeCATAdminHandle phCatAdmin,
|
||||
IntPtr pgSubsystem,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pwszHashAlgorithm,
|
||||
IntPtr pStrongHashPolicy,
|
||||
uint dwFlags
|
||||
);
|
||||
|
||||
internal static SafeCATAdminHandle CryptCATAdminAcquireContext2(string hashAlgorithm)
|
||||
{
|
||||
if (!NativeCryptCATAdminAcquireContext2(out var adminHandle, IntPtr.Zero, hashAlgorithm, IntPtr.Zero, 0))
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
return adminHandle;
|
||||
}
|
||||
|
||||
[DllImport(
|
||||
WinTrustDll,
|
||||
CharSet = CharSet.Unicode,
|
||||
EntryPoint = "CryptCATAdminCalcHashFromFileHandle2",
|
||||
SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern unsafe bool NativeCryptCATAdminCalcHashFromFileHandle2(
|
||||
SafeCATAdminHandle hCatAdmin,
|
||||
SafeHandle hFile,
|
||||
[In, Out] ref int pcbHash,
|
||||
byte* pbHash,
|
||||
uint dwFlags
|
||||
);
|
||||
|
||||
internal static byte[] CryptCATAdminCalcHashFromFileHandle2(SafeCATAdminHandle catAdmin, SafeHandle file)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
int hashLength = 0;
|
||||
NativeCryptCATAdminCalcHashFromFileHandle2(catAdmin, file, ref hashLength, null, 0);
|
||||
|
||||
byte[] hash = new byte[hashLength];
|
||||
fixed (byte* hashPtr = hash)
|
||||
{
|
||||
if (!NativeCryptCATAdminCalcHashFromFileHandle2(catAdmin, file, ref hashLength, hashPtr, 0))
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CryptCATAdminReleaseContext(
|
||||
IntPtr phCatAdmin,
|
||||
uint dwFlags
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode, EntryPoint = "CryptCATCDFOpen")]
|
||||
private static extern SafeCATCDFHandle NativeCryptCATCDFOpen(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pwszFilePath,
|
||||
CryptCATCDFParseErrorCallBack pfnParseError
|
||||
);
|
||||
|
||||
internal static SafeCATCDFHandle CryptCATCDFOpen(string filePath, CryptCATCDFParseErrorCallBack parseError)
|
||||
{
|
||||
SafeCATCDFHandle handle = NativeCryptCATCDFOpen(filePath, parseError);
|
||||
if (handle.IsInvalid)
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATCDFEnumCatAttributes(
|
||||
SafeCATCDFHandle pCDF,
|
||||
IntPtr pPrevAttr,
|
||||
CryptCATCDFParseErrorCallBack pfnParseError
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CryptCATCDFClose(
|
||||
IntPtr pCDF
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATCDFEnumMembersByCDFTagEx(
|
||||
SafeCATCDFHandle pCDF,
|
||||
IntPtr pwszPrevCDFTag,
|
||||
CryptCATCDFParseErrorCallBack fn,
|
||||
ref IntPtr ppMember,
|
||||
bool fContinueOnError,
|
||||
IntPtr pvReserved
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATCDFEnumAttributesWithCDFTag(
|
||||
SafeCATCDFHandle pCDF,
|
||||
IntPtr pwszMemberTag,
|
||||
IntPtr pMember,
|
||||
IntPtr pPrevAttr,
|
||||
CryptCATCDFParseErrorCallBack fn
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATEnumerateCatAttr(
|
||||
SafeCATHandle hCatalog,
|
||||
IntPtr pPrevAttr
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode, EntryPoint = "CryptCATOpen", SetLastError = true)]
|
||||
internal static extern SafeCATHandle NativeCryptCATOpen(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pwszFilePath,
|
||||
uint fdwOpenFlags,
|
||||
IntPtr hProv,
|
||||
uint dwPublicVersion,
|
||||
uint dwEncodingType
|
||||
);
|
||||
|
||||
internal static SafeCATHandle CryptCATOpen(string filePath, uint openFlags, IntPtr provider, uint publicVersion,
|
||||
uint encodingType)
|
||||
{
|
||||
SafeCATHandle handle = NativeCryptCATOpen(filePath, openFlags, provider, publicVersion, encodingType);
|
||||
if (handle.IsInvalid)
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
[DllImport(WinTrustDll)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CryptCATClose(
|
||||
IntPtr hCatalog
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode, EntryPoint = "CryptCATStoreFromHandle")]
|
||||
private static extern IntPtr NativeCryptCATStoreFromHandle(
|
||||
SafeCATHandle hCatalog
|
||||
);
|
||||
|
||||
internal static CRYPTCATSTORE CryptCATStoreFromHandle(SafeCATHandle catalog)
|
||||
{
|
||||
IntPtr catStore = NativeCryptCATStoreFromHandle(catalog);
|
||||
return Marshal.PtrToStructure<CRYPTCATSTORE>(catStore);
|
||||
}
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATEnumerateMember(
|
||||
SafeCATHandle hCatalog,
|
||||
IntPtr pPrevMember
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATEnumerateAttr(
|
||||
SafeCATHandle hCatalog,
|
||||
IntPtr pCatMember,
|
||||
IntPtr pPrevAttr
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode)]
|
||||
internal static extern uint WinVerifyTrust(
|
||||
IntPtr hWnd,
|
||||
ref Guid pgActionID,
|
||||
ref WINTRUST_DATA pWVTData
|
||||
);
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode, EntryPoint = "WTHelperGetProvCertFromChain")]
|
||||
private static extern IntPtr NativeWTHelperGetProvCertFromChain(
|
||||
IntPtr pSgnr,
|
||||
uint idxCert
|
||||
);
|
||||
|
||||
internal static IntPtr WTHelperGetProvCertFromChain(IntPtr signer, uint certIdx)
|
||||
{
|
||||
IntPtr data = NativeWTHelperGetProvCertFromChain(signer, certIdx);
|
||||
if (data == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception("WTHelperGetProvCertFromChain failed");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode, EntryPoint = "WTHelperGetProvSignerFromChain")]
|
||||
private static extern IntPtr NativeWTHelperGetProvSignerFromChain(
|
||||
IntPtr pProvData,
|
||||
uint idxSigner,
|
||||
bool fCounterSigner,
|
||||
uint idxCounterSigner
|
||||
);
|
||||
|
||||
internal static IntPtr WTHelperGetProvSignerFromChain(IntPtr providerData, uint signerIdx, bool counterSigner,
|
||||
uint counterSignerIdx)
|
||||
{
|
||||
IntPtr data = NativeWTHelperGetProvSignerFromChain(providerData, signerIdx, counterSigner, counterSignerIdx);
|
||||
if (data == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception("WTHelperGetProvSignerFromChain failed");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
[DllImport(WinTrustDll, CharSet = CharSet.Unicode, EntryPoint = "WTHelperProvDataFromStateData")]
|
||||
private static extern IntPtr NativeWTHelperProvDataFromStateData(
|
||||
IntPtr hStateData
|
||||
);
|
||||
|
||||
internal static IntPtr WTHelperProvDataFromStateData(IntPtr stateData)
|
||||
{
|
||||
IntPtr data = NativeWTHelperProvDataFromStateData(stateData);
|
||||
if (data == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception("WTHelperProvDataFromStateData failed");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Signature of call back function used by CryptCATCDFOpen,
|
||||
/// CryptCATCDFEnumCatAttributes, CryptCATCDFEnumAttributesWithCDFTag, and
|
||||
/// and CryptCATCDFEnumMembersByCDFTagEx.
|
||||
/// </summary>
|
||||
internal delegate void CryptCATCDFParseErrorCallBack(
|
||||
uint dwErrorArea,
|
||||
uint dwLocalArea,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pwszLine
|
||||
);
|
||||
}
|
||||
@@ -779,312 +779,6 @@ namespace System.Management.Automation.Security
|
||||
return si;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// wintrust.dll stuff
|
||||
//
|
||||
|
||||
//
|
||||
// WinVerifyTrust() function and associated structures/enums
|
||||
//
|
||||
|
||||
[DllImport("wintrust.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern
|
||||
DWORD WinVerifyTrust(
|
||||
IntPtr hWndNotUsed, // HWND
|
||||
IntPtr pgActionID, // GUID*
|
||||
IntPtr pWinTrustData // WINTRUST_DATA*
|
||||
);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct WINTRUST_FILE_INFO
|
||||
{
|
||||
internal DWORD cbStruct; // = sizeof(WINTRUST_FILE_INFO)
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
internal string pcwszFilePath; // LPCWSTR
|
||||
|
||||
internal IntPtr hFileNotUsed; // optional, HANDLE to pcwszFilePath
|
||||
internal IntPtr pgKnownSubjectNotUsed; // optional: GUID* : fill if the
|
||||
// subject type is known
|
||||
}
|
||||
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)]
|
||||
internal struct WINTRUST_BLOB_INFO
|
||||
{
|
||||
/// DWORD->unsigned int
|
||||
internal uint cbStruct;
|
||||
|
||||
/// GUID->_GUID
|
||||
internal Guid gSubject;
|
||||
|
||||
/// LPCWSTR->WCHAR*
|
||||
[MarshalAsAttribute(UnmanagedType.LPWStr)]
|
||||
internal string pcwszDisplayName;
|
||||
|
||||
/// DWORD->unsigned int
|
||||
internal uint cbMemObject;
|
||||
|
||||
/// BYTE*
|
||||
internal System.IntPtr pbMemObject;
|
||||
|
||||
/// DWORD->unsigned int
|
||||
internal uint cbMemSignedMsg;
|
||||
|
||||
/// BYTE*
|
||||
internal System.IntPtr pbMemSignedMsg;
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
internal static WINTRUST_FILE_INFO InitWintrustFileInfoStruct(string fileName)
|
||||
{
|
||||
WINTRUST_FILE_INFO fi = new WINTRUST_FILE_INFO();
|
||||
|
||||
fi.cbStruct = (DWORD)Marshal.SizeOf(fi);
|
||||
fi.pcwszFilePath = fileName;
|
||||
fi.hFileNotUsed = IntPtr.Zero;
|
||||
fi.pgKnownSubjectNotUsed = IntPtr.Zero;
|
||||
|
||||
return fi;
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
internal static WINTRUST_BLOB_INFO InitWintrustBlobInfoStruct(string fileName, string content)
|
||||
{
|
||||
WINTRUST_BLOB_INFO bi = new WINTRUST_BLOB_INFO();
|
||||
byte[] contentBytes = System.Text.Encoding.Unicode.GetBytes(content);
|
||||
|
||||
// The GUID of the PowerShell SIP
|
||||
bi.gSubject = new Guid(0x603bcc1f, 0x4b59, 0x4e08, new byte[] { 0xb7, 0x24, 0xd2, 0xc6, 0x29, 0x7e, 0xf3, 0x51 });
|
||||
bi.cbStruct = (DWORD)Marshal.SizeOf(bi);
|
||||
bi.pcwszDisplayName = fileName;
|
||||
bi.cbMemObject = (uint)contentBytes.Length;
|
||||
bi.pbMemObject = Marshal.AllocCoTaskMem(contentBytes.Length);
|
||||
Marshal.Copy(contentBytes, 0, bi.pbMemObject, contentBytes.Length);
|
||||
|
||||
return bi;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum WintrustUIChoice
|
||||
{
|
||||
WTD_UI_ALL = 1,
|
||||
WTD_UI_NONE = 2,
|
||||
WTD_UI_NOBAD = 3,
|
||||
WTD_UI_NOGOOD = 4
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum WintrustUnionChoice
|
||||
{
|
||||
WTD_CHOICE_FILE = 1,
|
||||
// WTD_CHOICE_CATALOG = 2,
|
||||
WTD_CHOICE_BLOB = 3,
|
||||
// WTD_CHOICE_SIGNER = 4,
|
||||
// WTD_CHOICE_CERT = 5,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum WintrustProviderFlags
|
||||
{
|
||||
WTD_PROV_FLAGS_MASK = 0x0000FFFF,
|
||||
WTD_USE_IE4_TRUST_FLAG = 0x00000001,
|
||||
WTD_NO_IE4_CHAIN_FLAG = 0x00000002,
|
||||
WTD_NO_POLICY_USAGE_FLAG = 0x00000004,
|
||||
WTD_REVOCATION_CHECK_NONE = 0x00000010,
|
||||
WTD_REVOCATION_CHECK_END_CERT = 0x00000020,
|
||||
WTD_REVOCATION_CHECK_CHAIN = 0x00000040,
|
||||
WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x00000080,
|
||||
WTD_SAFER_FLAG = 0x00000100,
|
||||
WTD_HASH_ONLY_FLAG = 0x00000200,
|
||||
WTD_USE_DEFAULT_OSVER_CHECK = 0x00000400,
|
||||
WTD_LIFETIME_SIGNING_FLAG = 0x00000800,
|
||||
WTD_CACHE_ONLY_URL_RETRIEVAL = 0x00001000
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum WintrustAction
|
||||
{
|
||||
WTD_STATEACTION_IGNORE = 0x00000000,
|
||||
WTD_STATEACTION_VERIFY = 0x00000001,
|
||||
WTD_STATEACTION_CLOSE = 0x00000002,
|
||||
WTD_STATEACTION_AUTO_CACHE = 0x00000003,
|
||||
WTD_STATEACTION_AUTO_CACHE_FLUSH = 0x00000004
|
||||
}
|
||||
|
||||
[StructLayoutAttribute(LayoutKind.Explicit)]
|
||||
internal struct WinTrust_Choice
|
||||
{
|
||||
/// WINTRUST_FILE_INFO_*
|
||||
[FieldOffsetAttribute(0)]
|
||||
internal System.IntPtr pFile;
|
||||
|
||||
/// WINTRUST_CATALOG_INFO_*
|
||||
[FieldOffsetAttribute(0)]
|
||||
internal System.IntPtr pCatalog;
|
||||
|
||||
/// WINTRUST_BLOB_INFO_*
|
||||
[FieldOffsetAttribute(0)]
|
||||
internal System.IntPtr pBlob;
|
||||
|
||||
/// WINTRUST_SGNR_INFO_*
|
||||
[FieldOffsetAttribute(0)]
|
||||
internal System.IntPtr pSgnr;
|
||||
|
||||
/// WINTRUST_CERT_INFO_*
|
||||
[FieldOffsetAttribute(0)]
|
||||
internal System.IntPtr pCert;
|
||||
}
|
||||
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)]
|
||||
internal struct WINTRUST_DATA
|
||||
{
|
||||
/// DWORD->unsigned int
|
||||
internal uint cbStruct;
|
||||
|
||||
/// LPVOID->void*
|
||||
internal System.IntPtr pPolicyCallbackData;
|
||||
|
||||
/// LPVOID->void*
|
||||
internal System.IntPtr pSIPClientData;
|
||||
|
||||
/// DWORD->unsigned int
|
||||
internal uint dwUIChoice;
|
||||
|
||||
/// DWORD->unsigned int
|
||||
internal uint fdwRevocationChecks;
|
||||
|
||||
/// DWORD->unsigned int
|
||||
internal uint dwUnionChoice;
|
||||
|
||||
/// WinTrust_Choice struct
|
||||
internal WinTrust_Choice Choice;
|
||||
|
||||
/// DWORD->unsigned int
|
||||
internal uint dwStateAction;
|
||||
|
||||
/// HANDLE->void*
|
||||
internal System.IntPtr hWVTStateData;
|
||||
|
||||
/// WCHAR*
|
||||
[MarshalAsAttribute(UnmanagedType.LPWStr)]
|
||||
internal string pwszURLReference;
|
||||
|
||||
/// DWORD->unsigned int
|
||||
internal uint dwProvFlags;
|
||||
|
||||
/// DWORD->unsigned int
|
||||
internal uint dwUIContext;
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
internal static WINTRUST_DATA InitWintrustDataStructFromFile(WINTRUST_FILE_INFO wfi)
|
||||
{
|
||||
WINTRUST_DATA wtd = new WINTRUST_DATA();
|
||||
|
||||
wtd.cbStruct = (DWORD)Marshal.SizeOf(wtd);
|
||||
wtd.pPolicyCallbackData = IntPtr.Zero;
|
||||
wtd.pSIPClientData = IntPtr.Zero;
|
||||
wtd.dwUIChoice = (DWORD)WintrustUIChoice.WTD_UI_NONE;
|
||||
wtd.fdwRevocationChecks = 0;
|
||||
wtd.dwUnionChoice = (DWORD)WintrustUnionChoice.WTD_CHOICE_FILE;
|
||||
|
||||
IntPtr pFileBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(wfi));
|
||||
Marshal.StructureToPtr(wfi, pFileBuffer, false);
|
||||
wtd.Choice.pFile = pFileBuffer;
|
||||
|
||||
wtd.dwStateAction = (DWORD)WintrustAction.WTD_STATEACTION_VERIFY;
|
||||
wtd.hWVTStateData = IntPtr.Zero;
|
||||
wtd.pwszURLReference = null;
|
||||
wtd.dwProvFlags = 0;
|
||||
|
||||
return wtd;
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
internal static WINTRUST_DATA InitWintrustDataStructFromBlob(WINTRUST_BLOB_INFO wbi)
|
||||
{
|
||||
WINTRUST_DATA wtd = new WINTRUST_DATA();
|
||||
|
||||
wtd.cbStruct = (DWORD)Marshal.SizeOf(wbi);
|
||||
wtd.pPolicyCallbackData = IntPtr.Zero;
|
||||
wtd.pSIPClientData = IntPtr.Zero;
|
||||
wtd.dwUIChoice = (DWORD)WintrustUIChoice.WTD_UI_NONE;
|
||||
wtd.fdwRevocationChecks = 0;
|
||||
wtd.dwUnionChoice = (DWORD)WintrustUnionChoice.WTD_CHOICE_BLOB;
|
||||
|
||||
IntPtr pBlob = Marshal.AllocCoTaskMem(Marshal.SizeOf(wbi));
|
||||
Marshal.StructureToPtr(wbi, pBlob, false);
|
||||
wtd.Choice.pBlob = pBlob;
|
||||
|
||||
wtd.dwStateAction = (DWORD)WintrustAction.WTD_STATEACTION_VERIFY;
|
||||
wtd.hWVTStateData = IntPtr.Zero;
|
||||
wtd.pwszURLReference = null;
|
||||
wtd.dwProvFlags = 0;
|
||||
|
||||
return wtd;
|
||||
}
|
||||
|
||||
[ArchitectureSensitive]
|
||||
internal static DWORD DestroyWintrustDataStruct(WINTRUST_DATA wtd)
|
||||
{
|
||||
DWORD dwResult = Win32Errors.E_FAIL;
|
||||
IntPtr WINTRUST_ACTION_GENERIC_VERIFY_V2 = IntPtr.Zero;
|
||||
IntPtr wtdBuffer = IntPtr.Zero;
|
||||
|
||||
Guid actionVerify =
|
||||
new Guid("00AAC56B-CD44-11d0-8CC2-00C04FC295EE");
|
||||
|
||||
try
|
||||
{
|
||||
WINTRUST_ACTION_GENERIC_VERIFY_V2 =
|
||||
Marshal.AllocCoTaskMem(Marshal.SizeOf(actionVerify));
|
||||
Marshal.StructureToPtr(actionVerify,
|
||||
WINTRUST_ACTION_GENERIC_VERIFY_V2,
|
||||
false);
|
||||
|
||||
wtd.dwStateAction = (DWORD)WintrustAction.WTD_STATEACTION_CLOSE;
|
||||
wtdBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(wtd));
|
||||
Marshal.StructureToPtr(wtd, wtdBuffer, false);
|
||||
|
||||
// The GetLastWin32Error of this is checked, but PreSharp doesn't seem to be
|
||||
// able to see that.
|
||||
#pragma warning disable 56523
|
||||
dwResult = WinVerifyTrust(
|
||||
IntPtr.Zero,
|
||||
WINTRUST_ACTION_GENERIC_VERIFY_V2,
|
||||
wtdBuffer);
|
||||
#pragma warning restore 56523
|
||||
|
||||
wtd = Marshal.PtrToStructure<WINTRUST_DATA>(wtdBuffer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.DestroyStructure<WINTRUST_DATA>(wtdBuffer);
|
||||
Marshal.FreeCoTaskMem(wtdBuffer);
|
||||
Marshal.DestroyStructure<Guid>(WINTRUST_ACTION_GENERIC_VERIFY_V2);
|
||||
Marshal.FreeCoTaskMem(WINTRUST_ACTION_GENERIC_VERIFY_V2);
|
||||
}
|
||||
|
||||
// Clear the blob or file info, depending on the type of
|
||||
// verification that was done.
|
||||
if (wtd.dwUnionChoice == (DWORD)WintrustUnionChoice.WTD_CHOICE_BLOB)
|
||||
{
|
||||
WINTRUST_BLOB_INFO originalBlob =
|
||||
(WINTRUST_BLOB_INFO)Marshal.PtrToStructure<WINTRUST_BLOB_INFO>(wtd.Choice.pBlob);
|
||||
Marshal.FreeCoTaskMem(originalBlob.pbMemObject);
|
||||
|
||||
Marshal.DestroyStructure<WINTRUST_BLOB_INFO>(wtd.Choice.pBlob);
|
||||
Marshal.FreeCoTaskMem(wtd.Choice.pBlob);
|
||||
}
|
||||
else
|
||||
{
|
||||
Marshal.DestroyStructure<WINTRUST_FILE_INFO>(wtd.Choice.pFile);
|
||||
Marshal.FreeCoTaskMem(wtd.Choice.pFile);
|
||||
}
|
||||
|
||||
return dwResult;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPT_PROVIDER_CERT
|
||||
{
|
||||
@@ -1122,29 +816,6 @@ namespace System.Management.Automation.Security
|
||||
private readonly IntPtr _pChainContext; // PCCERT_CHAIN_CONTEXT
|
||||
}
|
||||
|
||||
[DllImport("wintrust.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern
|
||||
IntPtr // CRYPT_PROVIDER_DATA*
|
||||
WTHelperProvDataFromStateData(IntPtr hStateData);
|
||||
|
||||
[DllImport("wintrust.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern
|
||||
IntPtr // CRYPT_PROVIDER_SGNR*
|
||||
WTHelperGetProvSignerFromChain(
|
||||
IntPtr pProvData, // CRYPT_PROVIDER_DATA*
|
||||
DWORD idxSigner,
|
||||
BOOL fCounterSigner,
|
||||
DWORD idxCounterSigner
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern
|
||||
IntPtr // CRYPT_PROVIDER_CERT*
|
||||
WTHelperGetProvCertFromChain(
|
||||
IntPtr pSgnr, // CRYPT_PROVIDER_SGNR*
|
||||
DWORD idxCert
|
||||
);
|
||||
|
||||
//
|
||||
// stuff required for getting cert extensions
|
||||
//
|
||||
@@ -1799,42 +1470,6 @@ namespace System.Management.Automation.Security
|
||||
internal const uint LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400;
|
||||
internal const uint LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800;
|
||||
internal const uint LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000;
|
||||
|
||||
[DllImport(PinvokeDllNames.LoadLibraryEx, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern IntPtr LoadLibraryExW(
|
||||
string DllName,
|
||||
IntPtr reserved,
|
||||
uint Flags);
|
||||
|
||||
[DllImport(PinvokeDllNames.FreeLibrary, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool FreeLibrary(
|
||||
IntPtr Module);
|
||||
|
||||
internal static bool IsSystem32DllPresent(string DllName)
|
||||
{
|
||||
bool DllExists = false;
|
||||
|
||||
try
|
||||
{
|
||||
IntPtr module = LoadLibraryExW(
|
||||
DllName,
|
||||
IntPtr.Zero,
|
||||
NativeMethods.LOAD_LIBRARY_AS_DATAFILE |
|
||||
NativeMethods.LOAD_LIBRARY_AS_IMAGE_RESOURCE |
|
||||
NativeMethods.LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (module != IntPtr.Zero)
|
||||
{
|
||||
FreeLibrary(module);
|
||||
DllExists = true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
return DllExists;
|
||||
}
|
||||
}
|
||||
|
||||
// Constants needed for Catalog Error Handling
|
||||
@@ -1876,234 +1511,6 @@ namespace System.Management.Automation.Security
|
||||
// CRYPTCAT_E_CDF_ATTR_TYPECOMBO = "0x00020004";
|
||||
public const int CRYPTCAT_E_CDF_ATTR_TYPECOMBO = 131076;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pinvoke methods from wintrust.dll
|
||||
/// These are added to Generate and Validate Window Catalog Files.
|
||||
/// </summary>
|
||||
internal static partial class NativeMethods
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPT_ATTRIBUTE_TYPE_VALUE
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPStr)]
|
||||
internal string pszObjId;
|
||||
|
||||
internal CRYPT_ATTR_BLOB Value;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct SIP_INDIRECT_DATA
|
||||
{
|
||||
internal CRYPT_ATTRIBUTE_TYPE_VALUE Data;
|
||||
internal CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm;
|
||||
internal CRYPT_ATTR_BLOB Digest;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal readonly struct CRYPTCATCDF
|
||||
{
|
||||
private readonly DWORD _cbStruct;
|
||||
private readonly IntPtr _hFile;
|
||||
private readonly DWORD _dwCurFilePos;
|
||||
private readonly DWORD _dwLastMemberOffset;
|
||||
private readonly BOOL _fEOF;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
private readonly string _pwszResultDir;
|
||||
|
||||
private readonly IntPtr _hCATStore;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPTCATMEMBER
|
||||
{
|
||||
internal DWORD cbStruct;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
internal string pwszReferenceTag;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
internal string pwszFileName;
|
||||
|
||||
internal Guid gSubjectType;
|
||||
internal DWORD fdwMemberFlags;
|
||||
internal IntPtr pIndirectData;
|
||||
internal DWORD dwCertVersion;
|
||||
internal DWORD dwReserved;
|
||||
internal IntPtr hReserved;
|
||||
internal CRYPT_ATTR_BLOB sEncodedIndirectData;
|
||||
internal CRYPT_ATTR_BLOB sEncodedMemberInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPTCATATTRIBUTE
|
||||
{
|
||||
private readonly DWORD _cbStruct;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
internal string pwszReferenceTag;
|
||||
|
||||
private readonly DWORD _dwAttrTypeAndAction;
|
||||
internal DWORD cbValue;
|
||||
internal System.IntPtr pbValue;
|
||||
private readonly DWORD _dwReserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CRYPTCATSTORE
|
||||
{
|
||||
private readonly DWORD _cbStruct;
|
||||
internal DWORD dwPublicVersion;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
internal string pwszP7File;
|
||||
|
||||
private readonly IntPtr _hProv;
|
||||
private readonly DWORD _dwEncodingType;
|
||||
private readonly DWORD _fdwStoreFlags;
|
||||
private readonly IntPtr _hReserved;
|
||||
private readonly IntPtr _hAttrs;
|
||||
private readonly IntPtr _hCryptMsg;
|
||||
private readonly IntPtr _hSorted;
|
||||
}
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATCDFOpen(
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
string pwszFilePath,
|
||||
CryptCATCDFOpenCallBack pfnParseError
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CryptCATCDFClose(
|
||||
IntPtr pCDF
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATCDFEnumCatAttributes(
|
||||
IntPtr pCDF,
|
||||
IntPtr pPrevAttr,
|
||||
CryptCATCDFOpenCallBack pfnParseError
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATCDFEnumMembersByCDFTagEx(
|
||||
IntPtr pCDF,
|
||||
IntPtr pwszPrevCDFTag,
|
||||
CryptCATCDFEnumMembersByCDFTagExErrorCallBack fn,
|
||||
ref IntPtr ppMember,
|
||||
bool fContinueOnError,
|
||||
IntPtr pvReserved
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATCDFEnumAttributesWithCDFTag(
|
||||
IntPtr pCDF,
|
||||
IntPtr pwszMemberTag,
|
||||
IntPtr pMember,
|
||||
IntPtr pPrevAttr,
|
||||
CryptCATCDFEnumMembersByCDFTagExErrorCallBack fn
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATOpen(
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
string pwszFilePath,
|
||||
DWORD fdwOpenFlags,
|
||||
IntPtr hProv,
|
||||
DWORD dwPublicVersion,
|
||||
DWORD dwEncodingType
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CryptCATClose(
|
||||
IntPtr hCatalog
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATStoreFromHandle(
|
||||
IntPtr hCatalog
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CryptCATAdminAcquireContext2(
|
||||
ref IntPtr phCatAdmin,
|
||||
IntPtr pgSubsystem,
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
string pwszHashAlgorithm,
|
||||
IntPtr pStrongHashPolicy,
|
||||
DWORD dwFlags
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CryptCATAdminReleaseContext(
|
||||
IntPtr phCatAdmin,
|
||||
DWORD dwFlags
|
||||
);
|
||||
|
||||
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern unsafe IntPtr CreateFile(
|
||||
string lpFileName,
|
||||
DWORD dwDesiredAccess,
|
||||
DWORD dwShareMode,
|
||||
DWORD lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition,
|
||||
DWORD dwFlagsAndAttributes,
|
||||
IntPtr hTemplateFile
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CryptCATAdminCalcHashFromFileHandle2(
|
||||
IntPtr hCatAdmin,
|
||||
IntPtr hFile,
|
||||
[In, Out] ref DWORD pcbHash,
|
||||
IntPtr pbHash,
|
||||
DWORD dwFlags
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATEnumerateCatAttr(
|
||||
IntPtr hCatalog,
|
||||
IntPtr pPrevAttr
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATEnumerateMember(
|
||||
IntPtr hCatalog,
|
||||
IntPtr pPrevMember
|
||||
);
|
||||
|
||||
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr CryptCATEnumerateAttr(
|
||||
IntPtr hCatalog,
|
||||
IntPtr pCatMember,
|
||||
IntPtr pPrevAttr
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Signature of call back function used by CryptCATCDFOpen.
|
||||
/// </summary>
|
||||
internal delegate
|
||||
void CryptCATCDFOpenCallBack(DWORD NotUsedDWORD1,
|
||||
DWORD NotUsedDWORD2,
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
string NotUsedString);
|
||||
|
||||
/// <summary>
|
||||
/// Signature of call back function used by CryptCATCDFEnumMembersByCDFTagEx.
|
||||
/// </summary>
|
||||
internal delegate
|
||||
void CryptCATCDFEnumMembersByCDFTagExErrorCallBack(DWORD NotUsedDWORD1,
|
||||
DWORD NotUsedDWORD2,
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
string NotUsedString);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 56523
|
||||
|
||||
Reference in New Issue
Block a user