Explorar el Código

Cleanup by adding TSetupFileVerification.

Still not tested. Also todo: doc & new clean messages commit.
Martijn Laan hace 3 meses
padre
commit
a73d49d52e

+ 0 - 1
Components/SHA256.pas

@@ -15,7 +15,6 @@ type
   TSHA256Context = record
     hash: THashSHA2;
   end;
-  PSHA256Digest = ^TSHA256Digest;
   TSHA256Digest = array[0..31] of Byte;
 
 procedure SHA256Init(var ctx: TSHA256Context);

+ 3 - 1
Projects/Src/Compiler.Messages.pas

@@ -218,7 +218,7 @@ const
   { Flags }
   SCompilerParamUnknownFlag2 = 'Parameter "%s" includes an unknown flag';
   SCompilerParamErrorBadCombo2 = 'Parameter "%s" cannot have both the "%s" and "%s" flags';
-  SCompilerParamErrorBadCombo3 = 'Parameter "%s" cannot have both the "%s" and "%s" flags on the same source file';
+  SCompilerParamErrorBadCombo2SameSource = 'Parameter "%s" cannot have both the "%s" and "%s" flags on the same source file';
   SCompilerParamUnsupportedFlag = 'Parameter "%s" includes a flag that is not supported in this section';
   SCompilerParamFlagMissing = 'Flag "%s" must be used if flag "%s" is used';
   SCompilerParamFlagMissing2 = 'Flag "%s" must be used if parameter "%s" is used';
@@ -295,6 +295,8 @@ const
     'the "%s" flag is used';
   SCompilerFilesParamFlagConflict = 'Parameter "%s" may not be used when ' +
     'the "%s" flag is used';
+  SCompilerFilesParamFlagConflictSameSource = 'Parameter "%s" may not be used when ' +
+    'the "%s" flag is used on the same source file';
   SCompilerFilesExcludeTooLong = 'Parameter "Excludes" contains a pattern that is too long';
   SCompilerFilesUnsafeFile = 'Unsafe file detected: %s.' + SNewLine2 +
     'See the "Unsafe Files" topic in the help file for more information';

+ 35 - 30
Projects/Src/Compiler.SetupCompiler.pas

@@ -324,10 +324,9 @@ type
   PFileLocationEntryExtraInfo = ^TFileLocationEntryExtraInfo;
   TFileLocationEntryExtraInfo = record
     Flags: set of (floVersionInfoNotValid, floIsUninstExe, floApplyTouchDateTime,
-      floSolidBreak, floHashVerify, floISSigVerify);
+      floSolidBreak);
     Sign: TFileLocationSign;
-    Hash: TSHA256Digest;
-    ISSigAllowedKeys: AnsiString;
+    Verification: TSetupFileVerification;
     ISSigKeyUsedID: String;
   end;
 
@@ -4911,6 +4910,15 @@ type
       Sign := NewSign;
   end;
 
+  procedure ApplyNewVerificationType(var VerificationType: TSetupFileVerificationType;
+    const NewVerificationType: TSetupFileVerificationType; const ErrorMessage: String);
+  begin
+    if not (VerificationType in [fvNone, NewVerificationType]) then
+       AbortCompileFmt(ErrorMessage, ['Hash', 'issigverify'])
+    else
+      VerificationType := NewVerificationType;
+  end;
+
   procedure ProcessFileList(const FileListBaseDir: String; FileList: TList);
   var
     FileListRec: PFileListRec;
@@ -4985,20 +4993,17 @@ type
               to compressing the first one }
             SolidBreak := False;
           end;
-          NewFileLocationEntryExtraInfo^.Hash := NewFileEntry^.Hash;
-          NewFileLocationEntryExtraInfo^.ISSigAllowedKeys := NewFileEntry^.ISSigAllowedKeys;
+          NewFileLocationEntryExtraInfo^.Verification.Hash := NewFileEntry^.Verification.Hash;
+          NewFileLocationEntryExtraInfo^.Verification.ISSigAllowedKeys := NewFileEntry^.Verification.ISSigAllowedKeys;
         end else begin
-          if not CompareMem(@NewFileLocationEntryExtraInfo^.Hash[0], @NewFileEntry^.Hash[0], SizeOf(TSHA256Digest)) then
+          if not CompareMem(@NewFileLocationEntryExtraInfo^.Verification.Hash[0],
+             @NewFileEntry^.Verification.Hash[0], SizeOf(TSHA256Digest)) then
             AbortCompileFmt(SCompilerFilesValueConflict, ['Hash']);
-          if NewFileLocationEntryExtraInfo^.ISSigAllowedKeys <> NewFileEntry^.ISSigAllowedKeys then
+          if NewFileLocationEntryExtraInfo^.Verification.ISSigAllowedKeys <> NewFileEntry^.Verification.ISSigAllowedKeys then
             AbortCompileFmt(SCompilerFilesValueConflict, ['ISSigAllowedKeys']);
         end;
         if Touch then
           Include(NewFileLocationEntryExtraInfo^.Flags, floApplyTouchDateTime);
-        if foHashVerify in NewFileEntry^.Options then
-          Include(NewFileLocationEntryExtraInfo^.Flags, floHashVerify);
-        if foISSigVerify in NewFileEntry^.Options then
-          Include(NewFileLocationEntryExtraInfo^.Flags, floISSigVerify);
         { Note: "nocompression"/"noencryption" on one file makes all merged
           copies uncompressed/unencrypted too }
         if NoCompression then
@@ -5006,7 +5011,10 @@ type
         if NoEncryption then
           Exclude(NewFileLocationEntry^.Flags, floChunkEncrypted);
         if Sign <> fsNoSetting then
-          ApplyNewSign(NewFileLocationEntryExtraInfo.Sign, Sign, SCompilerParamErrorBadCombo3);
+          ApplyNewSign(NewFileLocationEntryExtraInfo.Sign, Sign, SCompilerParamErrorBadCombo2SameSource);
+        if NewFileEntry^.Verification.Typ <> fvNone  then
+          ApplyNewVerificationType(NewFileLocationEntryExtraInfo.Verification.Typ, NewFileEntry^.Verification.Typ,
+            SCompilerFilesParamFlagConflictSameSource);
       end
       else begin
         NewFileEntry^.SourceFilename := SourceFile;
@@ -5273,7 +5281,7 @@ begin
                    38: ApplyNewSign(Sign, fsYes, SCompilerParamErrorBadCombo2);
                    39: ApplyNewSign(Sign, fsOnce, SCompilerParamErrorBadCombo2);
                    40: ApplyNewSign(Sign, fsCheck, SCompilerParamErrorBadCombo2);
-                   41: Include(Options, foISSigVerify);
+                   41: ApplyNewVerificationType(Verification.Typ, fvISSig, SCompilerFilesParamFlagConflict);
                    42: Include(Options, foDownload);
                    43: Include(Options, foExtractArchive);
                  end;
@@ -5375,8 +5383,8 @@ begin
 
                { Hash }
                if Values[paHash].Found then begin
-                 Hash := SHA256DigestFromString(Values[paHash].Data);
-                 Include(Options, foHashVerify);
+                 ApplyNewVerificationType(Verification.Typ, fvHash, SCompilerFilesParamFlagConflict);
+                 Verification.Hash := SHA256DigestFromString(Values[paHash].Data);
                end;
 
                { ISSigAllowedKeys }
@@ -5390,7 +5398,7 @@ begin
                    var ISSigKeyEntryExtraInfo := PISSigKeyEntryExtraInfo(ISSigKeyEntryExtraInfos[KeyIndex]);
                    if SameText(ISSigKeyEntryExtraInfo.Name, KeyNameOrGroupName) or
                       ISSigKeyEntryExtraInfo.HasGroupName(KeyNameOrGroupName) then begin
-                     SetISSigAllowedKey(ISSigAllowedKeys, KeyIndex);
+                     SetISSigAllowedKey(Verification.ISSigAllowedKeys, KeyIndex);
                      FoundKey := True;
                    end;
                  end;
@@ -5494,19 +5502,16 @@ begin
         if (foIgnoreVersion in Options) and (foReplaceSameVersionIfContentsDiffer in Options) then
           AbortCompileFmt(SCompilerParamErrorBadCombo2, ['Flags', 'ignoreversion', 'replacesameversion']);
 
-        if (ISSigKeyEntries.Count = 0) and (foISSigVerify in Options) then
+        if (ISSigKeyEntries.Count = 0) and (Verification.Typ = fvISSig) then
           AbortCompile(SCompilerFilesISSigVerifyMissingISSigKeys);
-        if (ISSigAllowedKeys <> '') and not (foISSigVerify in Options) then
+        if (Verification.ISSigAllowedKeys <> '') and (Verification.Typ <> fvISSig) then
           AbortCompile(SCompilerFilesISSigAllowedKeysMissingISSigVerify);
 
-        if (foHashVerify in Options) and (foISSigVerify in Options) then
-          AbortCompileFmt(SCompilerFilesParamRequiresFlag, ['Hash', 'issigverify']);
-
         if Sign in [fsYes, fsOnce] then begin
-          if foHashVerify in Options then
-            AbortCompileFmt(SCompilerParamErrorBadCombo2,
-              [ParamCommonFlags, SignFlags[Sign], 'hashverify']);
-          if foISSigVerify in Options then
+          if Verification.Typ = fvHash then
+            AbortCompileFmt(SCompilerFilesParamFlagConflict,
+              [ParamCommonFlags, 'Hash', SignFlags[Sign]]);
+          if Verification.Typ = fvISSig then
             AbortCompileFmt(SCompilerParamErrorBadCombo2,
               [ParamCommonFlags, SignFlags[Sign], 'issigverify']);
           if SignTools.Count = 0 then
@@ -7171,15 +7176,15 @@ var
           fdOpenExisting, faRead, fsRead);
         try
           var ExpectedFileHash: TSHA256Digest;
-          if floHashVerify in FLExtraInfo.Flags then
-            ExpectedFileHash := FLExtraInfo.Hash
-          else if floISSigVerify in FLExtraInfo.Flags then begin
+          if FLExtraInfo.Verification.Typ = fvHash then
+            ExpectedFileHash := FLExtraInfo.Verification.Hash
+          else if FLExtraInfo.Verification.Typ = fvISSig then begin
             { See Setup.Install's CopySourceFileToDestFile for similar code }
             if Length(ISSigAvailableKeys) = 0 then { shouldn't fail: flag stripped already }
               AbortCompileFmt(SCompilerCompressInternalError, ['Length(ISSigAvailableKeys) = 0']);
             var ExpectedFileSize: Int64;
             if not ISSigVerifySignature(FileLocationEntryFilenames[I],
-              GetISSigAllowedKeys(ISSigAvailableKeys, FLExtraInfo.ISSigAllowedKeys),
+              GetISSigAllowedKeys(ISSigAvailableKeys, FLExtraInfo.Verification.ISSigAllowedKeys),
               ExpectedFileSize, ExpectedFileHash, FLExtraInfo.ISSigKeyUsedID,
               nil,
               procedure(const Filename, SigFilename: String)
@@ -7250,7 +7255,7 @@ var
           CH.CompressFile(SourceFile, FL.OriginalSize,
             floCallInstructionOptimized in FL.Flags, FL.SHA256Sum);
 
-          if (floHashVerify in FLExtraInfo.Flags) or (floISSigVerify in FLExtraInfo.Flags) then begin
+          if FLExtraInfo.Verification.Typ <> fvNone then begin
             if not SHA256DigestsEqual(FL.SHA256Sum, ExpectedFileHash) then
               VerificationError(veFileHashIncorrect, FileLocationEntryFilenames[I]);
             AddStatus(SCompilerStatusFilesVerified);

+ 38 - 45
Projects/Src/Setup.Install.pas

@@ -12,7 +12,7 @@ unit Setup.Install;
 interface
 
 uses
-  Classes, SHA256, Shared.FileClass, Shared.SetupTypes, Shared.Int64Em;
+  Classes, SHA256, Shared.FileClass, Shared.SetupTypes, Shared.Int64Em, Shared.Struct;
 
 procedure VerificationError(const AError: TVerificationError;
   const ASigFilename: String = '');
@@ -31,13 +31,11 @@ type
 procedure ExtractTemporaryFile(const BaseName: String);
 function ExtractTemporaryFiles(const Pattern: String): Integer;
 function DownloadFile(const Url, CustomUserName, CustomPassword: String;
-  const DestF: TFile; const HashVerify, ISSigVerify: Boolean; const ExpectedHash: PSHA256Digest;
-  const ISSigAllowedKeys: AnsiString; const ISSigSourceFilename: String;
+  const DestF: TFile; [ref] const Verification: TSetupFileVerification; const ISSigSourceFilename: String;
   const OnSimpleDownloadProgress: TOnSimpleDownloadProgress;
   const OnSimpleDownloadProgressParam: Integer64): Int64;
 function DownloadTemporaryFile(const Url, BaseName: String;
-  const HashVerify, ISSigVerify: Boolean; const ExpectedHash: PSHA256Digest;
-  const ISSigAllowedKeys: AnsiString; const OnDownloadProgress: TOnDownloadProgress): Int64;
+  [ref] const Verification: TSetupFileVerification; const OnDownloadProgress: TOnDownloadProgress): Int64;
 function DownloadTemporaryFileSize(const Url: String): Int64;
 function DownloadTemporaryFileDate(const Url: String): String;
 procedure SetDownloadTemporaryFileCredentials(const User, Pass: String);
@@ -46,7 +44,7 @@ function GetISSigUrl(const Url, ISSigUrl: String): String;
 implementation
 
 uses
-  Windows, SysUtils, Messages, Forms, ShlObj, Shared.Struct, Setup.UninstallLog,
+  Windows, SysUtils, Messages, Forms, ShlObj, Setup.UninstallLog,
   SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, Setup.SecurityFunc, SetupLdrAndSetup.Messages,
   Setup.MainFunc, Setup.LoggingFunc, Setup.FileExtractor,
   Compression.Base, PathFunc, ISSigFunc, Shared.CommonFunc.Vcl, Compression.SevenZipDLLDecoder,
@@ -347,8 +345,7 @@ const
   VerificationSuccessfulLogMessage = 'Verification successful.';
 
 procedure CopySourceFileToDestFile(const SourceF, DestF: TFile;
-  const HashVerify, ISSigVerify: Boolean; const HashExpectedHash: PSHA256Digest;
-  const ISSigAllowedKeys: AnsiString; const ISSigSourceFilename: String;
+  [ref] const Verification: TSetupFileVerification; const ISSigSourceFilename: String;
   const AExpectedSize: Integer64);
 { Copies all bytes from SourceF to DestF, incrementing process meter as it
   goes. Assumes file pointers of both are 0. }
@@ -359,11 +356,11 @@ var
   Context: TSHA256Context;
 begin
   var ExpectedFileHash: TSHA256Digest;
-  if HashVerify or ISSigVerify then begin
-    if HashVerify then
-      ExpectedFileHash := HashExpectedHash^
+  if Verification.Typ <> fvNone then begin
+    if Verification.Typ = fvHash then
+      ExpectedFileHash := Verification.Hash
     else
-      DoISSigVerify(SourceF, nil, ISSigSourceFilename, ISSigAllowedKeys, ExpectedFileHash);
+      DoISSigVerify(SourceF, nil, ISSigSourceFilename, Verification.ISSigAllowedKeys, ExpectedFileHash);
     { ExpectedFileHash checked below after copy }
     SHA256Init(Context);
   end;
@@ -389,13 +386,13 @@ begin
     DestF.WriteBuffer(Buf, BufSize);
     Dec64(BytesLeft, BufSize);
 
-    if ISSigVerify then
+    if Verification.Typ <> fvNone then
       SHA256Update(Context, Buf, BufSize);
 
     ExternalProgressProc64(To64(BufSize), MaxProgress);
   end;
 
-  if HashVerify or ISSigVerify then begin
+  if Verification.Typ <> fvNone then begin
     if not SHA256DigestsEqual(SHA256Final(Context), ExpectedFileHash) then
       VerificationError(veFileHashIncorrect);
     Log(VerificationSuccessfulLogMessage);
@@ -1590,18 +1587,18 @@ var
               const DownloadPassword = ExpandConst(CurFile^.DownloadPassword);
               var MaxProgress := CurProgress;
               Inc6464(MaxProgress, AExternalSize);
-              if foISSigVerify in CurFile^.Options then begin
+              if CurFile^.Verification.Typ = fvISSig then begin
                 const ISSigTempFile = TempFile + ISSigExt;
                 const ISSigDestF = TFileRedir.Create(DisableFsRedir, ISSigTempFile, fdCreateAlways, faReadWrite, fsNone);
                 try
                   { Download the .issig file }
                   const ISSigUrl = GetISSigUrl(SourceFile, ExpandConst(CurFile^.DownloadISSigSource));
                   DownloadFile(ISSigUrl, DownloadUserName, DownloadPassword,
-                    ISSigDestF, False, False, nil, '', '', JustProcessEventsProc64, To64(0));
+                    ISSigDestF, Default(TSetupFileVerification), '', JustProcessEventsProc64, To64(0));
                   FreeAndNil(ISSigDestF);
                   { Download and verify the actual file }
                   DownloadFile(SourceFile, DownloadUserName, DownloadPassword,
-                    DestF, False, True, nil, CurFile^.ISSigAllowedKeys, TempFile, ExternalProgressProc64, MaxProgress);
+                    DestF, CurFile^.Verification, TempFile, ExternalProgressProc64, MaxProgress);
                 finally
                   ISSigDestF.Free;
                   { Delete the .issig file }
@@ -1609,8 +1606,7 @@ var
                 end;
               end else
                 DownloadFile(SourceFile, DownloadUserName, DownloadPassword,
-                  DestF, foHashVerify in CurFile^.Options, False, @CurFile^.Hash[0],
-                    '', '', ExternalProgressProc64, MaxProgress);
+                  DestF, CurFile^.Verification, '', ExternalProgressProc64, MaxProgress);
             end
             else begin
               { Copy a duplicated non-external file, or an external file }
@@ -1618,11 +1614,10 @@ var
               try
                 LastOperation := SetupMessages[msgErrorCopying];
                 if Assigned(CurFileLocation) then
-                  CopySourceFileToDestFile(SourceF, DestF, False, False, nil,
-                    '', '', CurFileLocation^.OriginalSize)
+                  CopySourceFileToDestFile(SourceF, DestF, Default(TSetupFileVerification),
+                    '', CurFileLocation^.OriginalSize)
                 else
-                  CopySourceFileToDestFile(SourceF, DestF, foHashVerify in CurFile^.Options,
-                    foISSigVerify in CurFile^.Options, @CurFile^.Hash[0], CurFile^.ISSigAllowedKeys,
+                  CopySourceFileToDestFile(SourceF, DestF, CurFile^.Verification,
                     SourceFile, AExternalSize);
               finally
                 SourceF.Free;
@@ -2037,14 +2032,14 @@ var
         var Failed: String;
         repeat
           try
-            if  (foHashVerify in CurFile^.Options) or (foISSigVerify in CurFile^.Options) then begin
+            if CurFile^.Verification.Typ <> fvNone then begin
               var ExpectedFileHash: TSHA256Digest;
-              if foHashVerify in CurFile^.Options then
-                ExpectedFileHash := CurFile^.Hash
+              if CurFile^.Verification.Typ = fvHash then
+                ExpectedFileHash := CurFile^.Verification.Hash
               else begin
                 if ISSigVerifySourceF = nil then
                   ISSigVerifySourceF := TFileRedir.Create(DisableFsRedir, ArchiveFilename, fdOpenExisting, faRead, fsRead);
-                DoISSigVerify(ISSigVerifySourceF, nil, ArchiveFilename, CurFile^.ISSigAllowedKeys,
+                DoISSigVerify(ISSigVerifySourceF, nil, ArchiveFilename, CurFile^.Verification.ISSigAllowedKeys,
                 ExpectedFileHash);
               end;
               { Can't get the SHA-256 while extracting so need to get and check it now }
@@ -3810,8 +3805,7 @@ begin
 end;
 
 function DownloadFile(const Url, CustomUserName, CustomPassword: String;
-  const DestF: TFile; const HashVerify, ISSigVerify: Boolean; const ExpectedHash: PSHA256Digest;
-  const ISSigAllowedKeys: AnsiString; const ISSigSourceFilename: String;
+  const DestF: TFile; [ref] const Verification: TSetupFileVerification; const ISSigSourceFilename: String;
   const OnSimpleDownloadProgress: TOnSimpleDownloadProgress;
   const OnSimpleDownloadProgressParam: Integer64): Int64;
 var
@@ -3866,13 +3860,13 @@ begin
       Result := HandleStream.Size;
       FreeAndNil(HandleStream);
 
-      { Check .issig if specified, otherwise check everything else we can check }
-      if HashVerify or ISSigVerify then begin
+      { Check verification if specified, otherwise check everything else we can check }
+      if Verification.Typ <> fvNone then begin
         var ExpectedFileHash: TSHA256Digest;
-        if HashVerify then
-          ExpectedFileHash := ExpectedHash^
+        if Verification.Typ = fvHash then
+          ExpectedFileHash := Verification.Hash
         else
-          DoISSigVerify(DestF, nil, ISSigSourceFilename, ISSigAllowedKeys, ExpectedFileHash);
+          DoISSigVerify(DestF, nil, ISSigSourceFilename, Verification.ISSigAllowedKeys, ExpectedFileHash);
         const FileHash = GetSHA256OfFile(DestF);
         if not SHA256DigestsEqual(FileHash, ExpectedFileHash) then
           VerificationError(veFileHashIncorrect);
@@ -3894,8 +3888,7 @@ begin
 end;
 
 function DownloadTemporaryFile(const Url, BaseName: String;
-  const HashVerify, ISSigVerify: Boolean; const ExpectedHash: PSHA256Digest;
-  const ISSigAllowedKeys: AnsiString; const OnDownloadProgress: TOnDownloadProgress): Int64;
+  [ref] const Verification: TSetupFileVerification; const OnDownloadProgress: TOnDownloadProgress): Int64;
 var
   DestFile, TempFile: String;
   TempF: TFile;
@@ -3922,16 +3915,16 @@ begin
 
   { Prepare directory }
   if NewFileExists(DestFile) then begin
-    if HashVerify then begin
-      if SHA256DigestsEqual(GetSHA256OfFile(False, DestFile), ExpectedHash^) then begin
+    if Verification.Typ = fvHash then begin
+      if SHA256DigestsEqual(GetSHA256OfFile(False, DestFile), Verification.Hash) then begin
         Log('  File already downloaded.');
         Result := 0;
         Exit;
       end;
-    end else if ISSigVerify then begin
+    end else if Verification.Typ = fvISSig then begin
       var ExistingFileSize: Int64;
       var ExistingFileHash: TSHA256Digest;
-      if ISSigVerifySignature(DestFile, GetISSigAllowedKeys(ISSigAvailableKeys, ISSigAllowedKeys),
+      if ISSigVerifySignature(DestFile, GetISSigAllowedKeys(ISSigAvailableKeys, Verification.ISSigAllowedKeys),
            ExistingFileSize, ExistingFileHash, nil, nil, nil) then begin
         const DestF = TFile.Create(DestFile, fdOpenExisting, faRead, fsReadWrite);
         try
@@ -4005,13 +3998,13 @@ begin
       Result := HandleStream.Size;
       FreeAndNil(HandleStream);
 
-      { Check hash or .issig if specified, otherwise check everything else we can check }
-      if HashVerify or ISSigVerify then begin
+      { Check verification if specified, otherwise check everything else we can check }
+      if Verification.Typ = fvNone then begin
         var ExpectedFileHash: TSHA256Digest;
-        if HashVerify then
-          ExpectedFileHash := ExpectedHash^
+        if Verification.Typ = fvHash then
+          ExpectedFileHash := Verification.Hash
         else
-          DoISSigVerify(TempF, nil, DestFile, ISSigAllowedKeys, ExpectedFileHash);
+          DoISSigVerify(TempF, nil, DestFile, Verification.ISSigAllowedKeys, ExpectedFileHash);
         FreeAndNil(TempF);
         const FileHash = GetSHA256OfFile(False, TempFile);
         if not SHA256DigestsEqual(FileHash, ExpectedFileHash) then

+ 13 - 15
Projects/Src/Setup.ScriptDlg.pas

@@ -13,7 +13,7 @@ interface
 
 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls, Contnrs, Generics.Collections,
-  SHA256, Setup.WizardForm, Setup.Install, Compression.SevenZipDecoder,
+  Shared.Struct, Setup.WizardForm, Setup.Install, Compression.SevenZipDecoder,
   NewCheckListBox, NewStaticText, NewProgressBar, PasswordEdit, RichEditViewer,
   BidiCtrls, TaskbarProgressFunc;
 
@@ -174,9 +174,7 @@ type
 
   TDownloadFile = class
     Url, BaseName, UserName, Password: String;
-    HashVerify, ISSigVerify: Boolean;
-    Hash: TSHA256Digest;
-    ISSigAllowedKeys: AnsiString;
+    Verification: TSetupFileVerification;
   end;
   TDownloadFiles = TObjectList<TDownloadFile>;
 
@@ -250,8 +248,8 @@ function ConvertAllowedKeysRuntimeIDsToISSigAllowedKeys(const AllowedKeysRuntime
 implementation
 
 uses
-  StrUtils, ISSigFunc,
-  Shared.Struct, Shared.SetupTypes, Setup.MainFunc, Setup.SelectFolderForm,
+  StrUtils, ISSigFunc, SHA256,
+  Shared.SetupTypes, Setup.MainFunc, Setup.SelectFolderForm,
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, PathFunc, Shared.CommonFunc.Vcl,
   Shared.CommonFunc, BrowseFunc, Setup.LoggingFunc, Setup.InstFunc,
   Compression.SevenZipDLLDecoder;
@@ -1066,13 +1064,14 @@ begin
   F.BaseName := BaseName;
   F.UserName := UserName;
   F.Password := Password;
-  F.HashVerify := RequiredSHA256OfFile <> '';
-  if F.HashVerify then
-    F.Hash := SHA256DigestFromString(RequiredSHA256OfFile)
-  else
-    ZeroMemory(@F.Hash[0], SizeOf(F.Hash)); { not really necessary }
-  F.ISSigVerify := ISSigVerify;
-  F.ISSigAllowedKeys := ISSigAllowedKeys;
+  F.Verification := Default(TSetupFileVerification);
+  if RequiredSHA256OfFile <> '' then begin
+    F.Verification.Typ := fvHash;
+    F.Verification.Hash := SHA256DigestFromString(RequiredSHA256OfFile)
+  end else if ISSigVerify then begin
+    F.Verification.Typ := fvISSig;
+    F.Verification.ISSigAllowedKeys := ISSigAllowedKeys
+  end;
   Result := FFiles.Add(F);
 end;
 
@@ -1137,8 +1136,7 @@ begin
   for var F in FFiles do begin
     { Don't need to set DownloadTemporaryFileOrExtractArchiveProcessMessages before downloading since we already process messages ourselves }
     SetDownloadTemporaryFileCredentials(F.UserName, F.Password);
-    Result := Result + DownloadTemporaryFile(F.Url, F.BaseName, F.HashVerify, F.ISSigVerify,
-      @F.Hash[0], F.ISSigAllowedKeys, InternalOnDownloadProgress);
+    Result := Result + DownloadTemporaryFile(F.Url, F.BaseName, F.Verification, InternalOnDownloadProgress);
   end;
   SetDownloadTemporaryFileCredentials('', '');
 end;

+ 10 - 8
Projects/Src/Setup.ScriptFunc.pas

@@ -822,17 +822,19 @@ var
         OnDownloadProgress := TOnDownloadProgress(Stack.GetProc(PStart-4, Caller));
       end;
 
-      const HashVerify = RequiredSHA256OfFile <> '';
-      var Hash: TSHA256Digest;
-      if HashVerify then
-        Hash := SHA256DigestFromString(RequiredSHA256OfFile)
-      else
-        ZeroMemory(@Hash[0], SizeOf(Hash)); { not really necessary }
+      var Verification := Default(TSetupFileVerification);
+      if RequiredSHA256OfFile <> '' then begin
+        Verification.Typ := fvHash;
+        Verification.Hash := SHA256DigestFromString(RequiredSHA256OfFile)
+      end else if ISSigVerify then begin
+        Verification.Typ := fvISSig;
+        Verification.ISSigAllowedKeys := ISSigAllowedKeys
+      end;
 
       { Also see Setup.ScriptDlg TDownloadWizardPage.AddExWithISSigVerify }
       if ISSigVerify then
-        DownloadTemporaryFile(GetISSigUrl(Url, ISSigUrl), BaseName + ISSigExt, False, False, nil, '', OnDownloadProgress);
-      Stack.SetInt64(PStart, DownloadTemporaryFile(Url, BaseName, HashVerify, ISSigVerify, @Hash[0], ISSigAllowedKeys, OnDownloadProgress));
+        DownloadTemporaryFile(GetISSigUrl(Url, ISSigUrl), BaseName + ISSigExt, Default(TSetupFileVerification), OnDownloadProgress);
+      Stack.SetInt64(PStart, DownloadTemporaryFile(Url, BaseName, Verification, OnDownloadProgress));
     end);
     RegisterScriptFunc('DownloadTemporaryFileSize', sfNoUninstall, procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
     begin

+ 8 - 3
Projects/Src/Shared.Struct.pas

@@ -231,12 +231,17 @@ const
   SetupFileEntryAnsiStrings = 1;
 type
   PSetupFileEntry = ^TSetupFileEntry;
+  TSetupFileVerificationType = (fvNone, fvHash, fvISSig); { fvNone must be first }
+  TSetupFileVerification = packed record
+    ISSigAllowedKeys: AnsiString; { Must be first }
+    Hash: TSHA256Digest;
+    Typ: TSetupFileVerificationType;
+  end;
   TSetupFileEntry = packed record
     SourceFilename, DestName, InstallFontName, StrongAssemblyName, Components,
     Tasks, Languages, Check, AfterInstall, BeforeInstall, Excludes,
     DownloadISSigSource, DownloadUserName, DownloadPassword, ExtractArchivePassword: String;
-    ISSigAllowedKeys: AnsiString;
-    Hash: TSHA256Digest;
+    Verification: TSetupFileVerification; { Must be first after strings }
     MinVersion, OnlyBelowVersion: TSetupVersionData;
     LocationEntry: Integer;
     Attribs: Integer;
@@ -252,7 +257,7 @@ type
       foRecurseSubDirsExternal, foReplaceSameVersionIfContentsDiffer,
       foDontVerifyChecksum, foUninsNoSharedFilePrompt, foCreateAllSubDirs,
       fo32Bit, fo64Bit, foExternalSizePreset, foSetNTFSCompression,
-      foUnsetNTFSCompression, foGacInstall, foHashVerify, foISSigVerify, foDownload,
+      foUnsetNTFSCompression, foGacInstall, foDownload,
       foExtractArchive);
     FileType: (ftUserFile, ftUninstExe);
   end;