From afe8fbf1cd6d6cd0923e311907b614e1c11b253f Mon Sep 17 00:00:00 2001 From: Violet Hansen Date: Sun, 1 Dec 2024 06:52:04 +0200 Subject: [PATCH] Implementing LibraryImports instead of DllImports for improved performance (#433) Fixed CA1838 in the CryptoAPI class. Changed theCertGetNameStringW to use LibraryImport. Changed CryptDecodeObject in Opus class to use LibraryImport. Changed WinVerifyTrust in WinTrust class to use LibraryImport. No DllImport exists in the code anymore. --- .../Logic/AllCertificatesGrabber.cs | 4 +- AppControl Manager/Logic/Crypt32CertCN.cs | 80 +++++++++++-------- AppControl Manager/Logic/GetOpusData.cs | 29 +++---- .../Logic/Types And Definitions/WinTrust.cs | 12 +-- 4 files changed, 65 insertions(+), 60 deletions(-) diff --git a/AppControl Manager/Logic/AllCertificatesGrabber.cs b/AppControl Manager/Logic/AllCertificatesGrabber.cs index 04dd76ff6..a9001c30b 100644 --- a/AppControl Manager/Logic/AllCertificatesGrabber.cs +++ b/AppControl Manager/Logic/AllCertificatesGrabber.cs @@ -207,7 +207,7 @@ public static List GetAllFileSigners(string FilePath) // Call WinVerifyTrust to verify trust on the file WinTrust.WinVerifyTrustResult verifyTrustResult = WinTrust.WinVerifyTrust( IntPtr.Zero, - WinTrust.GenericWinTrustVerifyActionGuid, + ref WinTrust.GenericWinTrustVerifyActionGuid, winTrustDataPointer ); @@ -314,7 +314,7 @@ public static List GetAllFileSigners(string FilePath) // Convert TrustedData back to pointer and call WinVerifyTrust to close the structure Marshal.StructureToPtr(TrustedData, winTrustDataPointer, false); - _ = WinTrust.WinVerifyTrust(IntPtr.Zero, WinTrust.GenericWinTrustVerifyActionGuid, winTrustDataPointer); + _ = WinTrust.WinVerifyTrust(IntPtr.Zero, ref WinTrust.GenericWinTrustVerifyActionGuid, winTrustDataPointer); } // Free memory allocated to winTrustDataPointer diff --git a/AppControl Manager/Logic/Crypt32CertCN.cs b/AppControl Manager/Logic/Crypt32CertCN.cs index d786824ef..3e1cd80d3 100644 --- a/AppControl Manager/Logic/Crypt32CertCN.cs +++ b/AppControl Manager/Logic/Crypt32CertCN.cs @@ -1,22 +1,18 @@ using System; using System.Runtime.InteropServices; -using System.Text; - -#pragma warning disable CA1838 // Avoid 'StringBuilder' parameters for P/Invoke methods namespace WDACConfig { - public static class CryptoAPI + public static partial class CryptoAPI { - // Importing function from crypt32.dll to access certificate information - // https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetnamestringa - [DllImport("crypt32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern bool CertGetNameString( - IntPtr pCertContext, // the handle property of the certificate object + // https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetnamestringw + [LibraryImport("crypt32.dll", EntryPoint = "CertGetNameStringW", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] + private static partial int CertGetNameString( + IntPtr pCertContext, // The handle property of the certificate object int dwType, int dwFlags, IntPtr pvTypePara, - StringBuilder pszNameString, + [Out] char[] pszNameString, int cchNameString ); @@ -25,42 +21,58 @@ int cchNameString public const int CERT_NAME_ATTR_TYPE = 3; // Display type for attributes public const int CERT_NAME_ISSUER_FLAG = 0x1; // Flag indicating that the issuer name should be retrieved - // Define a helper method to get the name string + /// + /// The main method of the class to get the name string + /// + /// + /// + /// + /// + /// public static string GetNameString(IntPtr pCertContext, int dwType, string? pvTypePara, bool isIssuer) { - // Allocate a buffer for the name string, setting it big to handle longer names if needed + // Allocate a buffer for the name string const int bufferSize = 1024; - StringBuilder nameString = new(bufferSize); + char[] nameBuffer = new char[bufferSize]; // Convert the pvTypePara to a pointer if needed IntPtr pvTypeParaPtr = IntPtr.Zero; - if (!string.IsNullOrEmpty(pvTypePara)) + + try { - // Using Unicode encoding for better compatibility - pvTypeParaPtr = Marshal.StringToHGlobalUni(pvTypePara); - } - // Set flags to retrieve issuer name if needed - int flags = isIssuer ? CERT_NAME_ISSUER_FLAG : 0; + if (!string.IsNullOrEmpty(pvTypePara)) + { + // Using Unicode encoding for better compatibility + pvTypeParaPtr = Marshal.StringToHGlobalUni(pvTypePara); + } - // Call the CertGetNameString function to get the name string - bool result = CertGetNameString( - pCertContext, - dwType, - flags, - pvTypeParaPtr, - nameString, - nameString.Capacity - ); + // Set flags to retrieve issuer name if needed + int flags = isIssuer ? CERT_NAME_ISSUER_FLAG : 0; + + // Call the CertGetNameString function to get the name string + int result = CertGetNameString( + pCertContext, + dwType, + flags, + pvTypeParaPtr, + nameBuffer, + nameBuffer.Length + ); + + // Return the name string or an empty string if failed + return result > 0 ? new string(nameBuffer, 0, result - 1) : string.Empty; // Exclude null terminator - // Free the pointer if allocated - if (pvTypeParaPtr != IntPtr.Zero) - { - Marshal.FreeHGlobal(pvTypeParaPtr); } + finally + { + // Free the pointer if allocated + if (pvTypeParaPtr != IntPtr.Zero) + { + Marshal.FreeHGlobal(pvTypeParaPtr); + } - // Return the name string or an empty string if failed - return result ? nameString.ToString() : string.Empty; + } } } } diff --git a/AppControl Manager/Logic/GetOpusData.cs b/AppControl Manager/Logic/GetOpusData.cs index f1b954100..d17a9b955 100644 --- a/AppControl Manager/Logic/GetOpusData.cs +++ b/AppControl Manager/Logic/GetOpusData.cs @@ -4,28 +4,25 @@ using System.Security.Cryptography; using System.Security.Cryptography.Pkcs; -#pragma warning disable SYSLIB1054 - namespace WDACConfig { - public static class Opus + public static partial class Opus { - internal static class Crypt32 + internal static partial class Crypt32 { // More info: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecodeobject - [DllImport("crypt32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern bool CryptDecodeObject( - uint dwCertEncodingType, // Specifies the encoding type used in the encoded message - IntPtr lpszStructType, // Pointer to a null-terminated ANSI string that identifies the type of the structure to be decoded - [In] byte[] pbEncoded, // Pointer to a buffer that contains the encoded structure - uint cbEncoded, // Size, in bytes, of the pbEncoded buffer - uint dwFlags, // Flags that modify the behavior of the function - [Out] IntPtr pvStructInto, // Pointer to a buffer that receives the decoded structure - ref uint pcbStructInfo // Pointer to a variable that specifies the size, in bytes, of the pvStructInfo buffer - ); - - + [LibraryImport("crypt32.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static partial bool CryptDecodeObject( + uint dwCertEncodingType, // Specifies the encoding type used in the encoded message + IntPtr lpszStructType, // Pointer to a null-terminated ANSI string that identifies the type of the structure to be decoded + [In] byte[] pbEncoded, // Pointer to a buffer that contains the encoded structure + uint cbEncoded, // Size, in bytes, of the pbEncoded buffer + uint dwFlags, // Flags that modify the behavior of the function + IntPtr pvStructInto, // Pointer to a buffer that receives the decoded structure + ref uint pcbStructInfo // Pointer to a variable that specifies the size, in bytes, of the pvStructInfo buffer + ); } // More info about this at the end of the code diff --git a/AppControl Manager/Logic/Types And Definitions/WinTrust.cs b/AppControl Manager/Logic/Types And Definitions/WinTrust.cs index 1e497f125..8a13cf81f 100644 --- a/AppControl Manager/Logic/Types And Definitions/WinTrust.cs +++ b/AppControl Manager/Logic/Types And Definitions/WinTrust.cs @@ -1,8 +1,6 @@ using System; using System.Runtime.InteropServices; -#pragma warning disable SYSLIB1054 - namespace WDACConfig { // This class contains all of the WinTrust related functions and codes @@ -113,17 +111,15 @@ public enum WinVerifyTrustResult : uint // Constants related to WinTrust internal const uint StateActionVerify = 1; internal const uint StateActionClose = 2; - internal static readonly Guid GenericWinTrustVerifyActionGuid = new("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}"); - + internal static Guid GenericWinTrustVerifyActionGuid = new("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}"); - // External method declarations for WinVerifyTrust and WTHelperProvDataFromStateData - [DllImport("wintrust.dll", CharSet = CharSet.Unicode)] // https://learn.microsoft.com/en-us/windows/win32/api/wintrust/nf-wintrust-winverifytrust + [LibraryImport("wintrust.dll", EntryPoint = "WinVerifyTrust")] // Set to return a WinVerifyTrustResult enum - internal static extern WinVerifyTrustResult WinVerifyTrust( + internal static partial WinVerifyTrustResult WinVerifyTrust( IntPtr hwnd, - [MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID, + ref Guid pgActionID, IntPtr pWVTData); // https://learn.microsoft.com/en-us/windows/win32/api/wintrust/nf-wintrust-wthelperprovdatafromstatedata