2
0
Эх сурвалжийг харах

Use ISSigFunc to check trust. Works while debugging from Delphi as well. Defining TRUSTALL would only be needed while debugging isscint.dll from VS for example.

AllowedPublicKeyText is formatted as a Delphi 12 multiline string literal since I plan to make ISSigTool embed it automatically from issig.bat to avoid complicating the build for others.
Martijn Laan 3 сар өмнө
parent
commit
ec81524172

+ 46 - 27
Components/TrustFunc.pas

@@ -7,9 +7,7 @@ unit TrustFunc;
   For conditions of distribution and use, see LICENSE.TXT.
   For conditions of distribution and use, see LICENSE.TXT.
 }
 }
 
 
-{$IFDEF DEBUG}
-{$DEFINE TRUSTALL}
-{$ENDIF}
+{.$DEFINE TRUSTALL}
 
 
 interface
 interface
 
 
@@ -18,35 +16,56 @@ function TrustedFileExists(const FileName: String): Boolean;
 implementation
 implementation
 
 
 uses
 uses
-  Winapi.Windows {$IFDEF TRUSTALL}, System.SysUtils {$ENDIF};
+  Winapi.Windows, System.SysUtils {$IFNDEF TRUSTALL}, System.Classes, ECDSA, SHA256, ISSigFunc {$ENDIF};
 
 
 function TrustedFileExists(const FileName: String): Boolean;
 function TrustedFileExists(const FileName: String): Boolean;
 begin
 begin
-{$IFNDEF TRUSTALL}
-  var FileInfo: TWinTrustFileInfo;
-  ZeroMemory(@FileInfo, SizeOf(FileInfo));
-  FileInfo.cbStruct := SizeOf(FileInfo);
-  FileInfo.pcwszFilePath := PChar(FileName);
-
-  var WinTrustData: TWinTrustData;
-  ZeroMemory(@WinTrustData, SizeOf(WinTrustData));
-  WinTrustData.cbStruct := SizeOf(WinTrustData);
-  WinTrustData.dwUIChoice := WTD_UI_NONE;
-  WinTrustData.fdwRevocationChecks := WTD_REVOKE_NONE;
-  WinTrustData.dwUnionChoice := WTD_CHOICE_FILE;
-  WinTrustData.pFile := @FileInfo;
-  WinTrustData.dwStateAction := WTD_STATEACTION_VERIFY;
-  WinTrustData.dwProvFlags := WTD_REVOCATION_CHECK_NONE;
-
-  var PolicyGUID := WINTRUST_ACTION_GENERIC_VERIFY_V2;
-
-  Result := WinVerifyTrust(0, PolicyGUID, @WinTrustData) = 0;
-
-  WinTrustData.dwStateAction := WTD_STATEACTION_CLOSE;
-  WinVerifyTrust(0, PolicyGUID, @WinTrustData);
-{$ELSE}
   var Attr := GetFileAttributes(PChar(FileName));
   var Attr := GetFileAttributes(PChar(FileName));
   Result := (Attr <> INVALID_FILE_ATTRIBUTES) and (Attr and faDirectory = 0);
   Result := (Attr <> INVALID_FILE_ATTRIBUTES) and (Attr and faDirectory = 0);
+{$IFNDEF TRUSTALL}
+  if Result then begin
+    try
+      const
+        AllowedPublicKeyText = '''
+format issig-public-key
+key-id c2587f3885b12463bafdadb799f23435f26c03944c1afc1716aabc6a43f2426f
+public-x f9a30c72189077370a8846015ac3ec1e9a1cf425d2996d34dc25bd4f4923dd1b
+public-y f754897b7819da5bbbc5ac568311eee922fbea492578748e07f453dc1289c532
+
+''';
+      const Key = TECDSAKey.Create;
+      try
+        if ISSigImportKeyText(Key, AllowedPublicKeyText, False) <> ikrSuccess then
+          raise Exception.Create('ISSigImportKeyText failed');
+
+        const SigFileName = FileName + '.issig';
+        const SigText = ISSigLoadTextFromFile(SigFileName);
+
+        var ExpectedFileSize: Int64;
+        var ExpectedFileHash: TSHA256Digest;
+        if ISSigVerifySignatureText([Key], SigText, ExpectedFileSize,
+           ExpectedFileHash) <> vsrSuccess then
+          raise Exception.CreateFmt('Signature file "%s" is not valid',
+            [SigFileName]);
+
+        const F = TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
+        try
+          if F.Size <> ExpectedFileSize then
+            raise Exception.CreateFmt('File "%s" is not trusted (incorrect size).',
+              [FileName]);
+          if not SHA256DigestsEqual(ISSigCalcStreamHash(F), ExpectedFileHash) then
+            raise Exception.CreateFmt('File "%s" is not trusted (incorrect hash).',
+              [FileName]);
+        finally
+          F.Free;
+        end;
+      finally
+        Key.Free;
+      end;
+    except
+      Result := False;
+    end;
+  end;
 {$ENDIF}
 {$ENDIF}
 end;
 end;
 
 

+ 4 - 1
Projects/Compil32.dpr

@@ -69,7 +69,10 @@ uses
   SHA256 in '..\Components\SHA256.pas',
   SHA256 in '..\Components\SHA256.pas',
   Shared.DotNetVersion in 'Src\Shared.DotNetVersion.pas',
   Shared.DotNetVersion in 'Src\Shared.DotNetVersion.pas',
   isxclasses_wordlists_generated in '..\ISHelp\isxclasses_wordlists_generated.pas',
   isxclasses_wordlists_generated in '..\ISHelp\isxclasses_wordlists_generated.pas',
-  IDE.ImagesModule in 'Src\IDE.ImagesModule.pas' {ImagesModule: TDataModule};
+  IDE.ImagesModule in 'Src\IDE.ImagesModule.pas' {ImagesModule: TDataModule},
+  ECDSA in '..\Components\ECDSA.pas',
+  ISSigFunc in '..\Components\ISSigFunc.pas',
+  StringScanner in '..\Components\StringScanner.pas';
 
 
 {$SETPEOSVERSION 6.1}
 {$SETPEOSVERSION 6.1}
 {$SETPESUBSYSVERSION 6.1}
 {$SETPESUBSYSVERSION 6.1}

+ 3 - 0
Projects/Compil32.dproj

@@ -155,6 +155,9 @@
             <FormType>dfm</FormType>
             <FormType>dfm</FormType>
             <DesignClass>TDataModule</DesignClass>
             <DesignClass>TDataModule</DesignClass>
         </DCCReference>
         </DCCReference>
+        <DCCReference Include="..\Components\ECDSA.pas"/>
+        <DCCReference Include="..\Components\ISSigFunc.pas"/>
+        <DCCReference Include="..\Components\StringScanner.pas"/>
         <BuildConfiguration Include="Base">
         <BuildConfiguration Include="Base">
             <Key>Base</Key>
             <Key>Base</Key>
         </BuildConfiguration>
         </BuildConfiguration>

+ 5 - 1
Projects/ISCC.dpr

@@ -30,7 +30,11 @@ uses
   Shared.FileClass in 'Src\Shared.FileClass.pas',
   Shared.FileClass in 'Src\Shared.FileClass.pas',
   Shared.ConfigIniFile in 'Src\Shared.ConfigIniFile.pas',
   Shared.ConfigIniFile in 'Src\Shared.ConfigIniFile.pas',
   Shared.SignToolsFunc in 'Src\Shared.SignToolsFunc.pas',
   Shared.SignToolsFunc in 'Src\Shared.SignToolsFunc.pas',
-  Shared.Int64Em in 'Src\Shared.Int64Em.pas';
+  Shared.Int64Em in 'Src\Shared.Int64Em.pas',
+  SHA256 in '..\Components\SHA256.pas',
+  ECDSA in '..\Components\ECDSA.pas',
+  ISSigFunc in '..\Components\ISSigFunc.pas',
+  StringScanner in '..\Components\StringScanner.pas';
 
 
 {$SETPEOSVERSION 6.1}
 {$SETPEOSVERSION 6.1}
 {$SETPESUBSYSVERSION 6.1}
 {$SETPESUBSYSVERSION 6.1}

+ 4 - 0
Projects/ISCC.dproj

@@ -85,6 +85,10 @@
         <DCCReference Include="Src\Shared.ConfigIniFile.pas"/>
         <DCCReference Include="Src\Shared.ConfigIniFile.pas"/>
         <DCCReference Include="Src\Shared.SignToolsFunc.pas"/>
         <DCCReference Include="Src\Shared.SignToolsFunc.pas"/>
         <DCCReference Include="Src\Shared.Int64Em.pas"/>
         <DCCReference Include="Src\Shared.Int64Em.pas"/>
+        <DCCReference Include="..\Components\SHA256.pas"/>
+        <DCCReference Include="..\Components\ECDSA.pas"/>
+        <DCCReference Include="..\Components\ISSigFunc.pas"/>
+        <DCCReference Include="..\Components\StringScanner.pas"/>
         <BuildConfiguration Include="Base">
         <BuildConfiguration Include="Base">
             <Key>Base</Key>
             <Key>Base</Key>
         </BuildConfiguration>
         </BuildConfiguration>

+ 4 - 1
Projects/ISCmplr.dpr

@@ -49,7 +49,10 @@ uses
   Shared.SetupSteps in 'Src\Shared.SetupSteps.pas',
   Shared.SetupSteps in 'Src\Shared.SetupSteps.pas',
   SimpleExpression in '..\Components\SimpleExpression.pas',
   SimpleExpression in '..\Components\SimpleExpression.pas',
   Shared.DotNetVersion in 'Src\Shared.DotNetVersion.pas',
   Shared.DotNetVersion in 'Src\Shared.DotNetVersion.pas',
-  PBKDF2 in '..\Components\PBKDF2.pas';
+  PBKDF2 in '..\Components\PBKDF2.pas',
+  ECDSA in '..\Components\ECDSA.pas',
+  ISSigFunc in '..\Components\ISSigFunc.pas',
+  StringScanner in '..\Components\StringScanner.pas';
 
 
 {$IMAGEBASE $00800000}
 {$IMAGEBASE $00800000}
 {$SETPEOSVERSION 6.1}
 {$SETPEOSVERSION 6.1}

+ 3 - 0
Projects/ISCmplr.dproj

@@ -119,6 +119,9 @@ $(PostBuildEvent)]]></PostBuildEvent>
         <DCCReference Include="..\Components\SimpleExpression.pas"/>
         <DCCReference Include="..\Components\SimpleExpression.pas"/>
         <DCCReference Include="Src\Shared.DotNetVersion.pas"/>
         <DCCReference Include="Src\Shared.DotNetVersion.pas"/>
         <DCCReference Include="..\Components\PBKDF2.pas"/>
         <DCCReference Include="..\Components\PBKDF2.pas"/>
+        <DCCReference Include="..\Components\ECDSA.pas"/>
+        <DCCReference Include="..\Components\ISSigFunc.pas"/>
+        <DCCReference Include="..\Components\StringScanner.pas"/>
         <BuildConfiguration Include="Base">
         <BuildConfiguration Include="Base">
             <Key>Base</Key>
             <Key>Base</Key>
         </BuildConfiguration>
         </BuildConfiguration>