Files
2022-10-26 12:25:11 +08:00

199 lines
4.1 KiB
C++

#include "stdafx.h"
#include <shlwapi.h>
#include <comdef.h>
#include <CRTDBG.H>
#include <atlconv.h>
#include <wchar.h>
#include <strsafe.h>
#include "./SHA256.h"
#include "./OSVersion.h"
#pragma comment(lib,"shlwapi.lib")
namespace Crypt
{
class SHA256_Module
{
public:
SHA256_Module()
:handle_(NULL)
,SHA256_Crypt(NULL)
,SHA256_Compare(NULL)
{
memset(last_error_, 0, _countof(last_error_));
}
~SHA256_Module()
{
if (handle_)
{
FreeLibrary(handle_);
handle_ = NULL;
}
}
bool Load()
{
memset(last_error_, 0, _countof(last_error_));
if (handle_ != NULL)
return true;
bool os_error_flag = false;
Greenmaru::COSVersion osv;
if( osv.IsWindowsXp() && 3 <= osv.ServicePack() )
{
os_error_flag = true;
}
else
{
if( osv.IsWindows2003() || osv.IsWindowsVistaOrLater() )
{
os_error_flag = true;
}
}
if (os_error_flag == false)
{
strcpy(last_error_, "Support OS is XP Service pack 3, VISTA, WINDOWS 7 or later and Server 2003, Server 2008 or later");
return false;
}
#ifdef _X64_VERIFY_
#ifdef _DEBUG
handle_ = LoadLibrary("WZMsgDigest_x64d.dll");
#else
handle_ = LoadLibrary("WZMsgDigest_x64.dll");
#endif
#else
#ifdef _DEBUG
handle_ = LoadLibrary("WZMsgDigest_x86d.dll");
#else
handle_ = LoadLibrary("WZMsgDigest_x86.dll");
#endif
#endif
if (handle_ == NULL)
{
strcpy(last_error_, "Fail to LoadLibrary(WZMsgDigest_XXX.dll)");
return false;
}
SHA256_Crypt = (lpfnDigest)GetProcAddress(handle_, "XP_SHA2_CryptKeyEx");
SHA256_Compare = (lpfnCompare)GetProcAddress(handle_, "XP_SHA2_CompareEx");
if(SHA256_Crypt == NULL || SHA256_Compare == NULL)
{
FreeLibrary(handle_);
handle_ = NULL;
strcpy(last_error_, "Fail to GetProcAddress(XP_SHA2_CryptKeyEx, XP_SHA2_CompareEx)");
return false;
}
return true;
}
const char* GetLastError() const
{
return last_error_;
}
typedef const char* (*lpfnDigest)(BSTR, BSTR);
typedef bool (*lpfnCompare)(BSTR, BSTR, BSTR);
lpfnDigest SHA256_Crypt;
lpfnCompare SHA256_Compare;
private:
HMODULE handle_;
char last_error_[256];
};
SHA256_Module g_sha256_module_;
SHA256::SHA256()
{
}
SHA256::~SHA256()
{
}
const char* SHA256::GetLastError()
{
return g_sha256_module_.GetLastError();
}
const char* SHA256::CreateKey(const char* input1, const char* input2)
{
if (g_sha256_module_.Load() == false)
return NULL;
if (input1 == NULL || input2 == NULL)
return NULL;
if (strlen(input1) == 0 || strlen(input2) == 0)
return NULL;
USES_CONVERSION;
BSTR first_in = ::SysAllocString(A2W(input1));
BSTR second_in = ::SysAllocString(A2W(input2));
bool result_flag = false;
const char* result = g_sha256_module_.SHA256_Crypt(first_in, second_in);
if (result && strlen(result) != 0)
{
strncpy(key_string_, result, 65);
result_flag = true;
}
else
{
memset(key_string_, 0, 65);
}
::SysFreeString(first_in);
::SysFreeString(second_in);
return result_flag ? key_string_ : NULL;
}
bool SHA256::Compare(const char* input1, const char* input2, const char* key_string)
{
if (g_sha256_module_.Load() == false)
return NULL;
if (input1 == NULL || input2 == NULL || key_string == NULL)
return NULL;
if (strlen(input1) == 0 || strlen(input2) == 0 || strlen(key_string) == 0)
return NULL;
USES_CONVERSION;
BSTR first_in = ::SysAllocString(A2W(input1));
BSTR second_in = ::SysAllocString(A2W(input2));
BSTR digest_in = ::SysAllocString(A2W(key_string));
bool result_flag = g_sha256_module_.SHA256_Compare(first_in, digest_in, second_in);
::SysFreeString(first_in);
::SysFreeString(second_in);
::SysFreeString(digest_in);
return result_flag;
}
}