using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
[StandardModule]
public static class VerifyDigiSign
{
private const long ALG_CLASS_HASH = 32768L;
private const long ALG_TYPE_ANY = 0L;
private const long ALG_SID_SHA1 = 4L;
private const long ALG_SID_SHA256 = 12L;
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CryptAcquireContext([Out] ref IntPtr phProv, [MarshalAs(UnmanagedType.LPStr)] string pszContainer, [MarshalAs(UnmanagedType.LPStr)] string pszProvider, int dwProvType, int dwFlags);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CryptReleaseContext(IntPtr hProv, int dwFlags);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CryptCreateHash(IntPtr hProv, long Algid, IntPtr hKey, int dwFlags, [Out] ref IntPtr phHash);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CryptHashData(IntPtr hHash, [MarshalAs(UnmanagedType.LPArray)] byte[] pbData, int dwDataLen, int dwFlags);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CryptDestroyHash(IntPtr hHash);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CryptDecryptMessage([In] ref CRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, [MarshalAs(UnmanagedType.LPArray)] byte[] pbEncryptedBlob, int cbEncryptedBlob, [MarshalAs(UnmanagedType.LPArray)] byte[] pbOutput, [Out] ref int pcbOutput, [Out] IntPtr ppXchgCert);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CryptVerifyMessageSignature([In] ref CRYPT_VERIFY_MESSAGE_PARA pVerifyPara, int dwSignerIndex, [MarshalAs(UnmanagedType.LPArray)] byte[] pbSignedBlob, int cbSignedBlob, [MarshalAs(UnmanagedType.LPArray)] byte[] pbDecoded, [Out] ref int pcbDecoded, [Out] IntPtr ppSignerCert);
private static bool Exec()
{
string subjectName = "MY_CERTIFICATE_SUBJECT_NAME";
bool flag = false;
IntPtr zero = IntPtr.Zero;
if (!CryptAcquireContext(ref zero, null, "Microsoft Enhanced Cryptographic Provider v1.0", 1, 0))
{
Debug.Print("CryptAcquireContext: " + Conversion.Hex(Marshal.GetLastWin32Error()));
return false;
}
IntPtr zero2 = IntPtr.Zero;
if (!CryptCreateHash(zero, 4L, IntPtr.Zero, 0, ref zero2))
{
Debug.Print("CryptCreateHash: " + Conversion.Hex(Marshal.GetLastWin32Error()));
return false;
}
byte[] data = System.Text.Encoding.Unicode.GetBytes("HASH_DATA");
if (!CryptHashData(zero2, data, data.Length, 0))
{
Debug.Print("CryptHashData: " + Conversion.Hex(Marshal.GetLastWin32Error()));
return false;
}
int num = 20;
byte[] array = new byte[num];
if (!CryptGetHashParam(zero2, 2, array, ref num, 0))
{
Debug.Print("CryptGetHashParam: " + Conversion.Hex(Marshal.GetLastWin32Error()));
return false;
}
IntPtr zero3 = IntPtr.Zero;
if (!CryptFindCertificateKeyProvInfo(subjectName, X509FindType.FindBySubjectName, ref zero3))
{
Debug.Print("CryptFindCertificateKeyProvInfo: " + Conversion.Hex(Marshal.GetLastWin32Error()));
return false;
}
X509Certificate2 certificate = new X509Certificate2(zero3);
byte[] signature = certificate.GetSignature();
byte[] b = new byte[signature.Length - 20];
for (int i = 20; i < signature.Length; i++)
{
b[i - 20] = signature[i];
}
byte[] array2 = hmac_sha1(b, array);
if (!string.Equals(BitConverter.ToString(array2).Replace("-", ""), BitConverter.ToString(signature, 0, 20).Replace("-", ""), StringComparison.OrdinalIgnoreCase))
{
Debug.Print("HASH MISMATCH");
return false;
}
flag = true;
if (!CryptDestroyHash(zero2))
{
Debug.Print("CryptDestroyHash: " + Conversion.Hex(Marshal.GetLastWin32Error()));
}
if (!CryptReleaseContext(zero, 0))
{
Debug.Print("CryptReleaseContext: " + Conversion.Hex(Marshal.GetLastWin32Error()));
}
return flag;
}
private static byte[] hmac_sha1(byte[] key, byte[] payload)
{
byte[] result;
using (HMACSHA1 hMACSHA = new HMACSHA1(key))
{
result = hMACSHA.ComputeHash(payload);
}
return result;
}
private static bool CryptFindCertificateKeyProvInfo(string findString, X509FindType findType, ref IntPtr phCryptProv)
{
bool result = false;
int num = 0;
try
{
CRYPT_HASH_FUNCTIONS cRYPT_HASH_FUNCTIONS = default(CRYPT_HASH_FUNCTIONS);
cRYPT_HASH_FUNCTIONS.cbSize = Marshal.SizeOf((object)cRYPT_HASH_FUNCTIONS);
if (!CryptSIPRetrieveSubjectGuid(findString, (int)findType, IntPtr.Zero, ref cRYPT_HASH_FUNCTIONS.gSubject, ref num, IntPtr.Zero))
{
throw new Exception("CryptSIPRetrieveSubjectGuid failed, Error:" + Marshal.GetLastWin32Error());
}
CRYPT_KEY_PROV_INFO cRYPT_KEY_PROV_INFO = default(CRYPT_KEY_PROV_INFO);
cRYPT_KEY_PROV_INFO.cbSize = Marshal.SizeOf((object)cRYPT_KEY_PROV_INFO);
IntPtr zero = IntPtr.Zero;
IntPtr intPtr = IntPtr.Zero;
int num2 = 0;
try
{
num2 = new X509Certificate2(cRYPT_HASH_FUNCTIONS.hFile).Handle.ToInt32();
bool flag = X509Certificate2.GetCertContextProperty(new IntPtr(num2), 2U, IntPtr.Zero, ref zero);
if (!flag)
{
throw new Exception("X509Certificate2.GetCertContextProperty failed, Error:" + Marshal.GetLastWin32Error());
}
if (!CryptFindCertificateKeyProvInfo(ref zero, ref intPtr, 0))
{
throw new Exception("CryptFindCertificateKeyProvInfo failed, Error:" + Marshal.GetLastWin32Error());
}
if (!CryptAcquireContext(ref phCryptProv, cRYPT_KEY_PROV_INFO.pwszContainerName, cRYPT_KEY_PROV_INFO.pwszProvName, cRYPT_KEY_PROV_INFO.dwProvType, cRYPT_KEY_PROV_INFO.dwFlags))
{
throw new Exception("CryptAcquireContext failed, Error:" + Marshal.GetLastWin32Error());
}
result = true;
}
finally
{
if (intPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(intPtr);
}
if (zero != IntPtr.Zero)
{
Marshal.FreeHGlobal(zero);
}
}
}
catch (Exception expr_Pl_113)
{
ProjectData.SetProjectError(expr_Pl_113);
ProjectData.ClearProjectError();
}
return result;
}
private static bool CryptHashData(IntPtr hHash, byte[] pbData, int dwDataLen, int dwFlags)
{
return CryptHashData(hHash, pbData, dwDataLen, dwFlags);
}
private static bool CryptGetHashParam(IntPtr hHash, int dwParam, [MarshalAs(UnmanagedType.LPArray)] byte[] pbData, ref int pdwDataLen, int dwFlags)
{
return CryptGetHashParam(hHash, dwParam, pbData, ref pdwDataLen, dwFlags);
}
}
public struct CRYPT_DECRYPT_MESSAGE_PARA
{
public int cbSize;
public int dwMsgAndCertEncodingType;
public int cCertStore;
public IntPtr rghCertStore;
public int dwFlags;
public int cbDecryptedBlobSize;
public IntPtr pbDecryptedBlob;
public int cPointerArray;
public IntPtr rgpPointerArray;
public int cCertStoreRtn;
public IntPtr rghCertStoreRtn;
public int dwMsgLookupType;
public int dwMsgLookupValue;
}
public struct CRYPT_KEY_PROV_INFO
{
public string pwszContainerName;
public string pwszProvName;
public int dwProvType;
public uint dwFlags;
public uint cProvParam;
public IntPtr rgProvParam;
public int dwKeySpec;
}
public struct CRYPT_HASH_FUNCTIONS
{
public int cbSize;
public IntPtr hFile;
public IntPtr hHash;
public IntPtr hProv;
public Guid gSubject;
}
public struct CRYPT_VERIFY_MESSAGE_PARA
{
public int cbSize;
public int dwMsgAndCertEncodingType;
public IntPtr hCryptProv;
public IntPtr pfnGetSignerCertificate;
public IntPtr pvGetArg;
}