go my file uploader
This commit is contained in:
207
tools/CustomSignTool/CustomSignTool.vcxproj
Normal file
207
tools/CustomSignTool/CustomSignTool.vcxproj
Normal file
@@ -0,0 +1,207 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{E8CD0A41-1537-4EA6-98AC-E80CD59C478E}</ProjectGuid>
|
||||
<RootNamespace>CustomSignTool</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)bin\$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)bin\$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\phnt\include;..\..\phlib\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_PHLIB_;_WINDOWS;WIN32;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>phlib.lib;ntdll.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\phlib\bin\$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalManifestDependencies>
|
||||
</AdditionalManifestDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\phnt\include;..\..\phlib\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_PHLIB_;_WINDOWS;WIN64;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>phlib.lib;ntdll.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\phlib\bin\$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalManifestDependencies>
|
||||
</AdditionalManifestDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..\phnt\include;..\..\phlib\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_PHLIB_;_WINDOWS;WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>phlib.lib;ntdll.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\phlib\bin\$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalManifestDependencies>
|
||||
</AdditionalManifestDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<SetChecksum>true</SetChecksum>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..\phnt\include;..\..\phlib\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_PHLIB_;_WINDOWS;WIN64;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>phlib.lib;ntdll.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\phlib\bin\$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalManifestDependencies>
|
||||
</AdditionalManifestDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<SetChecksum>true</SetChecksum>
|
||||
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\phlib\phlib.vcxproj">
|
||||
<Project>{477d0215-f252-41a1-874b-f27e3ea1ed17}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
22
tools/CustomSignTool/CustomSignTool.vcxproj.filters
Normal file
22
tools/CustomSignTool/CustomSignTool.vcxproj.filters
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
BIN
tools/CustomSignTool/bin/Release32/CustomSignTool.exe
Normal file
BIN
tools/CustomSignTool/bin/Release32/CustomSignTool.exe
Normal file
Binary file not shown.
BIN
tools/CustomSignTool/bin/Release64/CustomSignTool.exe
Normal file
BIN
tools/CustomSignTool/bin/Release64/CustomSignTool.exe
Normal file
Binary file not shown.
362
tools/CustomSignTool/main.c
Normal file
362
tools/CustomSignTool/main.c
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Process Hacker -
|
||||
* Custom data signing tool
|
||||
*
|
||||
* Copyright (C) 2016 wj32
|
||||
*
|
||||
* This file is part of Process Hacker.
|
||||
*
|
||||
* Process Hacker is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Process Hacker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ph.h>
|
||||
#include <bcrypt.h>
|
||||
|
||||
#define CST_SIGN_ALGORITHM BCRYPT_ECDSA_P256_ALGORITHM
|
||||
#define CST_SIGN_ALGORITHM_BITS 256
|
||||
#define CST_HASH_ALGORITHM BCRYPT_SHA256_ALGORITHM
|
||||
#define CST_BLOB_PRIVATE BCRYPT_ECCPRIVATE_BLOB
|
||||
#define CST_BLOB_PUBLIC BCRYPT_ECCPUBLIC_BLOB
|
||||
|
||||
#define FILE_BUFFER_SIZE PAGE_SIZE
|
||||
|
||||
#define ARG_KEY 1
|
||||
#define ARG_SIG 2
|
||||
|
||||
PPH_STRING CstCommand = NULL;
|
||||
PPH_STRING CstArgument1 = NULL;
|
||||
PPH_STRING CstArgument2 = NULL;
|
||||
PPH_STRING CstKeyFileName = NULL;
|
||||
PPH_STRING CstSigFileName = NULL;
|
||||
|
||||
PWSTR CstHelpMessage =
|
||||
L"Usage: CustomSignTool.exe command ...\n"
|
||||
L"Commands:\n"
|
||||
L"createkeypair\tprivatekeyfile publickeyfile\n"
|
||||
L"sign\t\t-k privatekeyfile -s outputsigfile inputfile\n"
|
||||
L"verify\t\t-k publickeyfile -s inputsigfile inputfile\n"
|
||||
;
|
||||
|
||||
static BOOLEAN NTAPI CstCommandLineCallback(
|
||||
_In_opt_ PPH_COMMAND_LINE_OPTION Option,
|
||||
_In_opt_ PPH_STRING Value,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
if (Option)
|
||||
{
|
||||
switch (Option->Id)
|
||||
{
|
||||
case ARG_KEY:
|
||||
PhSwapReference(&CstKeyFileName, Value);
|
||||
break;
|
||||
case ARG_SIG:
|
||||
PhSwapReference(&CstSigFileName, Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CstCommand)
|
||||
PhSwapReference(&CstCommand, Value);
|
||||
else if (!CstArgument1)
|
||||
PhSwapReference(&CstArgument1, Value);
|
||||
else if (!CstArgument2)
|
||||
PhSwapReference(&CstArgument2, Value);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DECLSPEC_NORETURN
|
||||
static VOID CstFailWith(
|
||||
_In_ PWSTR Message
|
||||
)
|
||||
{
|
||||
wprintf(L"%s\n", Message);
|
||||
RtlExitUserProcess(1);
|
||||
}
|
||||
|
||||
DECLSPEC_NORETURN
|
||||
static VOID CstFailWithStatus(
|
||||
_In_ PWSTR Message,
|
||||
_In_ NTSTATUS Status,
|
||||
_In_opt_ ULONG Win32Result
|
||||
)
|
||||
{
|
||||
wprintf(L"%s: %s\n", Message, PhGetStatusMessage(Status, Win32Result)->Buffer);
|
||||
RtlExitUserProcess(1);
|
||||
}
|
||||
|
||||
static VOID CstExportKey(
|
||||
_In_ BCRYPT_KEY_HANDLE KeyHandle,
|
||||
_In_ PWSTR BlobType,
|
||||
_In_ PWSTR FileName,
|
||||
_In_ PWSTR Description
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG blobSize;
|
||||
PVOID blob;
|
||||
HANDLE fileHandle;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
|
||||
if (!NT_SUCCESS(status = BCryptExportKey(KeyHandle, NULL, BlobType, NULL, 0, &blobSize, 0)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to export %s: Unable to get blob size", Description)->Buffer, status, 0);
|
||||
blob = PhAllocate(blobSize);
|
||||
if (!NT_SUCCESS(status = BCryptExportKey(KeyHandle, NULL, BlobType, blob, blobSize, &blobSize, 0)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to export %s: Unable to get blob data", Description)->Buffer, status, 0);
|
||||
|
||||
if (!NT_SUCCESS(status = PhCreateFileWin32(&fileHandle, FileName, FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to create '%s'", FileName)->Buffer, status, 0);
|
||||
if (!NT_SUCCESS(status = NtWriteFile(fileHandle, NULL, NULL, NULL, &iosb, blob, blobSize, NULL, NULL)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to write blob to '%s'", FileName)->Buffer, status, 0);
|
||||
NtClose(fileHandle);
|
||||
|
||||
RtlSecureZeroMemory(blob, blobSize);
|
||||
PhFree(blob);
|
||||
}
|
||||
|
||||
static PVOID CstReadFile(
|
||||
_In_ PWSTR FileName,
|
||||
_In_ ULONG FileSizeLimit,
|
||||
_Out_ PULONG FileSize
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
HANDLE fileHandle;
|
||||
LARGE_INTEGER fileSize;
|
||||
PVOID buffer;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
|
||||
if (!NT_SUCCESS(status = PhCreateFileWin32(&fileHandle, FileName, FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to open '%s'", FileName)->Buffer, status, 0);
|
||||
if (!NT_SUCCESS(status = PhGetFileSize(fileHandle, &fileSize)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to get the size of '%s'", FileName)->Buffer, status, 0);
|
||||
if (fileSize.QuadPart > FileSizeLimit)
|
||||
CstFailWith(PhFormatString(L"The file '%s' is too large", FileName)->Buffer);
|
||||
buffer = PhAllocate((ULONG)fileSize.QuadPart);
|
||||
if (!NT_SUCCESS(status = NtReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, (ULONG)fileSize.QuadPart, NULL, NULL)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to read '%s'", FileName)->Buffer, status, 0);
|
||||
NtClose(fileHandle);
|
||||
|
||||
*FileSize = (ULONG)fileSize.QuadPart;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static PVOID CstHashFile(
|
||||
_In_ PWSTR FileName,
|
||||
_Out_ PULONG HashSize
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
HANDLE fileHandle;
|
||||
PVOID buffer;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
BCRYPT_ALG_HANDLE hashAlgHandle;
|
||||
ULONG querySize;
|
||||
ULONG hashObjectSize;
|
||||
ULONG hashSize;
|
||||
PVOID hashObject;
|
||||
BCRYPT_HASH_HANDLE hashHandle;
|
||||
PVOID hash;
|
||||
|
||||
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hashAlgHandle, CST_HASH_ALGORITHM, NULL, 0)))
|
||||
CstFailWithStatus(L"Unable to open the hashing algorithm provider", status, 0);
|
||||
if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hashObjectSize, sizeof(ULONG), &querySize, 0)))
|
||||
CstFailWithStatus(L"Unable to query hash object size", status, 0);
|
||||
if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_HASH_LENGTH, (PUCHAR)&hashSize, sizeof(ULONG), &querySize, 0)))
|
||||
CstFailWithStatus(L"Unable to query hash size", status, 0);
|
||||
hashObject = PhAllocate(hashObjectSize);
|
||||
if (!NT_SUCCESS(status = BCryptCreateHash(hashAlgHandle, &hashHandle, hashObject, hashObjectSize, NULL, 0, 0)))
|
||||
CstFailWithStatus(L"Unable to get hash handle", status, 0);
|
||||
|
||||
if (!NT_SUCCESS(status = PhCreateFileWin32(&fileHandle, FileName, FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to open '%s'", FileName)->Buffer, status, 0);
|
||||
|
||||
buffer = PhAllocatePage(FILE_BUFFER_SIZE, NULL);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (!NT_SUCCESS(status = NtReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, FILE_BUFFER_SIZE, NULL, NULL)))
|
||||
{
|
||||
if (status == STATUS_END_OF_FILE)
|
||||
break;
|
||||
|
||||
CstFailWithStatus(PhFormatString(L"Unable to read '%s'", FileName)->Buffer, status, 0);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status = BCryptHashData(hashHandle, buffer, (ULONG)iosb.Information, 0)))
|
||||
CstFailWithStatus(L"Unable to hash file", status, 0);
|
||||
}
|
||||
|
||||
PhFreePage(buffer);
|
||||
NtClose(fileHandle);
|
||||
|
||||
hash = PhAllocate(hashSize);
|
||||
if (!NT_SUCCESS(status = BCryptFinishHash(hashHandle, hash, hashSize, 0)))
|
||||
CstFailWithStatus(L"Unable to complete the hash", status, 0);
|
||||
PhFree(hashObject);
|
||||
BCryptDestroyHash(hashHandle);
|
||||
BCryptCloseAlgorithmProvider(hashAlgHandle, 0);
|
||||
|
||||
*HashSize = hashSize;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int __cdecl wmain(int argc, wchar_t *argv[])
|
||||
{
|
||||
static PH_COMMAND_LINE_OPTION options[] =
|
||||
{
|
||||
{ ARG_KEY, L"k", MandatoryArgumentType },
|
||||
{ ARG_SIG, L"s", MandatoryArgumentType }
|
||||
};
|
||||
|
||||
NTSTATUS status;
|
||||
PH_STRINGREF commandLine;
|
||||
|
||||
if (!NT_SUCCESS(PhInitializePhLibEx(0, 0, 0)))
|
||||
return 1;
|
||||
|
||||
PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine);
|
||||
PhParseCommandLine(
|
||||
&commandLine,
|
||||
options,
|
||||
sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
|
||||
PH_COMMAND_LINE_IGNORE_FIRST_PART,
|
||||
CstCommandLineCallback,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (!CstCommand)
|
||||
CstFailWith(CstHelpMessage);
|
||||
|
||||
if (PhEqualString2(CstCommand, L"createkeypair", TRUE))
|
||||
{
|
||||
BCRYPT_ALG_HANDLE signAlgHandle;
|
||||
BCRYPT_KEY_HANDLE keyHandle;
|
||||
|
||||
if (!CstArgument1 || !CstArgument2)
|
||||
CstFailWith(CstHelpMessage);
|
||||
|
||||
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&signAlgHandle, CST_SIGN_ALGORITHM, NULL, 0)))
|
||||
CstFailWithStatus(L"Unable to open the signing algorithm provider", status, 0);
|
||||
if (!NT_SUCCESS(status = BCryptGenerateKeyPair(signAlgHandle, &keyHandle, CST_SIGN_ALGORITHM_BITS, 0)))
|
||||
CstFailWithStatus(L"Unable to create the key", status, 0);
|
||||
if (!NT_SUCCESS(status = BCryptFinalizeKeyPair(keyHandle, 0)))
|
||||
CstFailWithStatus(L"Unable to finalize the key", status, 0);
|
||||
|
||||
CstExportKey(keyHandle, CST_BLOB_PRIVATE, CstArgument1->Buffer, L"private key");
|
||||
CstExportKey(keyHandle, CST_BLOB_PUBLIC, CstArgument2->Buffer, L"public key");
|
||||
|
||||
BCryptDestroyKey(keyHandle);
|
||||
BCryptCloseAlgorithmProvider(signAlgHandle, 0);
|
||||
}
|
||||
else if (PhEqualString2(CstCommand, L"sign", TRUE))
|
||||
{
|
||||
BCRYPT_ALG_HANDLE signAlgHandle;
|
||||
HANDLE fileHandle;
|
||||
ULONG bufferSize;
|
||||
PVOID buffer;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
BCRYPT_KEY_HANDLE keyHandle;
|
||||
ULONG hashSize;
|
||||
PVOID hash;
|
||||
ULONG signatureSize;
|
||||
PVOID signature;
|
||||
|
||||
if (!CstArgument1 || !CstKeyFileName || !CstSigFileName)
|
||||
CstFailWith(CstHelpMessage);
|
||||
|
||||
// Import the key.
|
||||
|
||||
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&signAlgHandle, CST_SIGN_ALGORITHM, NULL, 0)))
|
||||
CstFailWithStatus(L"Unable to open the signing algorithm provider", status, 0);
|
||||
buffer = CstReadFile(CstKeyFileName->Buffer, 1024 * 1024, &bufferSize);
|
||||
if (!NT_SUCCESS(status = BCryptImportKeyPair(signAlgHandle, NULL, CST_BLOB_PRIVATE, &keyHandle, buffer, bufferSize, 0)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to import the private key", CstKeyFileName->Buffer)->Buffer, status, 0);
|
||||
PhFree(buffer);
|
||||
|
||||
// Hash the file.
|
||||
|
||||
hash = CstHashFile(CstArgument1->Buffer, &hashSize);
|
||||
|
||||
// Sign the hash.
|
||||
|
||||
if (!NT_SUCCESS(status = BCryptSignHash(keyHandle, NULL, hash, hashSize, NULL, 0, &signatureSize, 0)))
|
||||
CstFailWithStatus(L"Unable to get the signature size", status, 0);
|
||||
signature = PhAllocate(signatureSize);
|
||||
if (!NT_SUCCESS(status = BCryptSignHash(keyHandle, NULL, hash, hashSize, signature, signatureSize, &signatureSize, 0)))
|
||||
CstFailWithStatus(L"Unable to create the signature", status, 0);
|
||||
PhFree(hash);
|
||||
BCryptDestroyKey(keyHandle);
|
||||
BCryptCloseAlgorithmProvider(signAlgHandle, 0);
|
||||
|
||||
// Write the signature to the output file.
|
||||
|
||||
if (!NT_SUCCESS(status = PhCreateFileWin32(&fileHandle, CstSigFileName->Buffer, FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to create '%s'", CstSigFileName->Buffer)->Buffer, status, 0);
|
||||
if (!NT_SUCCESS(status = NtWriteFile(fileHandle, NULL, NULL, NULL, &iosb, signature, signatureSize, NULL, NULL)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to write signature to '%s'", CstSigFileName->Buffer)->Buffer, status, 0);
|
||||
NtClose(fileHandle);
|
||||
PhFree(signature);
|
||||
}
|
||||
else if (PhEqualString2(CstCommand, L"verify", TRUE))
|
||||
{
|
||||
BCRYPT_ALG_HANDLE signAlgHandle;
|
||||
ULONG bufferSize;
|
||||
PVOID buffer;
|
||||
BCRYPT_KEY_HANDLE keyHandle;
|
||||
ULONG hashSize;
|
||||
PVOID hash;
|
||||
ULONG signatureSize;
|
||||
PVOID signature;
|
||||
|
||||
if (!CstArgument1 || !CstKeyFileName || !CstSigFileName)
|
||||
CstFailWith(CstHelpMessage);
|
||||
|
||||
if (!CstArgument1 || !CstKeyFileName || !CstSigFileName)
|
||||
CstFailWith(CstHelpMessage);
|
||||
|
||||
// Import the key.
|
||||
|
||||
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&signAlgHandle, CST_SIGN_ALGORITHM, NULL, 0)))
|
||||
CstFailWithStatus(L"Unable to open the signing algorithm provider", status, 0);
|
||||
buffer = CstReadFile(CstKeyFileName->Buffer, 1024 * 1024, &bufferSize);
|
||||
if (!NT_SUCCESS(status = BCryptImportKeyPair(signAlgHandle, NULL, CST_BLOB_PUBLIC, &keyHandle, buffer, bufferSize, 0)))
|
||||
CstFailWithStatus(PhFormatString(L"Unable to import the public key", CstKeyFileName->Buffer)->Buffer, status, 0);
|
||||
PhFree(buffer);
|
||||
|
||||
// Read the signature.
|
||||
|
||||
signature = CstReadFile(CstSigFileName->Buffer, 1024 * 1024, &signatureSize);
|
||||
|
||||
// Hash the file.
|
||||
|
||||
hash = CstHashFile(CstArgument1->Buffer, &hashSize);
|
||||
|
||||
// Verify the hash.
|
||||
|
||||
if (!NT_SUCCESS(status = BCryptVerifySignature(keyHandle, NULL, hash, hashSize, signature, signatureSize, 0)))
|
||||
CstFailWithStatus(PhFormatString(L"Signature verification failed", CstKeyFileName->Buffer)->Buffer, status, 0);
|
||||
PhFree(signature);
|
||||
PhFree(hash);
|
||||
|
||||
wprintf(L"The signature is valid.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user