Setup.ISSigVerifyFunc.pas 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. unit Setup.ISSigVerifyFunc;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2025 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Installation procedures: DoISSigVerify
  8. }
  9. interface
  10. uses
  11. Classes, SHA256, Shared.FileClass, Shared.SetupTypes, Shared.Struct;
  12. const
  13. VerificationSuccessfulLogMessage = 'Verification successful.';
  14. function NoVerification: TSetupFileVerification;
  15. procedure VerificationError(const AError: TVerificationError;
  16. const ASigFilename: String = '');
  17. procedure DoISSigVerify(const SourceF: TFile; const SourceFS: TFileStream;
  18. const SourceFilename: String; const VerifySourceFilename: Boolean; const ISSigAllowedKeys: AnsiString;
  19. out ExpectedFileHash: TSHA256Digest);
  20. implementation
  21. uses
  22. SysUtils,
  23. ISSigFunc, PathFunc,
  24. SetupLdrAndSetup.Messages,
  25. Shared.CommonFunc, Shared.SetupMessageIDs,
  26. Setup.InstFunc, Setup.LoggingFunc, Setup.MainFunc;
  27. function NoVerification: TSetupFileVerification;
  28. begin
  29. Result := Default(TSetupFileVerification);
  30. Result.Typ := fvNone;
  31. end;
  32. procedure VerificationError(const AError: TVerificationError;
  33. const ASigFilename: String);
  34. const
  35. LogMessages: array[TVerificationError] of String =
  36. ('Signature file does not exist', 'Signature is malformed', 'No matching key found',
  37. 'Signature is bad', 'File name is incorrect', 'File size is incorrect', 'File hash is incorrect');
  38. SetupMessageIDs: array[TVerificationError] of TSetupMessageID =
  39. (msgVerificationSignatureDoesntExist, msgVerificationSignatureInvalid, msgVerificationKeyNotFound,
  40. msgVerificationSignatureInvalid, msgVerificationFileNameIncorrect, msgVerificationFileSizeIncorrect,
  41. msgVerificationFileHashIncorrect);
  42. begin
  43. { Also see Compiler.SetupCompiler for a similar function }
  44. Log('Verification error: ' + AddPeriod(LogMessages[AError]));
  45. raise Exception.Create(FmtSetupMessage1(msgSourceVerificationFailed,
  46. FmtSetupMessage1(SetupMessageIDs[AError], PathExtractName(ASigFilename)))); { Not all messages actually have a %1 parameter but that's OK }
  47. end;
  48. procedure DoISSigVerify(const SourceF: TFile; const SourceFS: TFileStream;
  49. const SourceFilename: String; const VerifySourceFilename: Boolean; const ISSigAllowedKeys: AnsiString;
  50. out ExpectedFileHash: TSHA256Digest);
  51. { Does not disable FS redirection. Either SourceF or SourceFS must be set, which
  52. may be opened for writing instead of reading. }
  53. begin
  54. if ((SourceF = nil) and (SourceFS = nil)) or ((SourceF <> nil) and (SourceFS <> nil)) then
  55. InternalError('DoISSigVerify: Invalid SourceF / SourceFS combination');
  56. var ExpectedFileName: String;
  57. var ExpectedFileSize: Int64;
  58. if not ISSigVerifySignature(SourceFilename,
  59. GetISSigAllowedKeys(ISSigAvailableKeys, ISSigAllowedKeys),
  60. ExpectedFileName, ExpectedFileSize, ExpectedFileHash,
  61. nil,
  62. procedure(const Filename, SigFilename: String)
  63. begin
  64. VerificationError(veSignatureMissing, SigFilename);
  65. end,
  66. procedure(const Filename, SigFilename: String; const VerifyResult: TISSigVerifySignatureResult)
  67. begin
  68. case VerifyResult of
  69. vsrMalformed: VerificationError(veSignatureMalformed, SigFilename);
  70. vsrBad: VerificationError(veSignatureBad, SigFilename);
  71. vsrKeyNotFound: VerificationError(veKeyNotFound, SigFilename);
  72. else
  73. InternalError('Unknown ISSigVerifySignature result');
  74. end;
  75. end
  76. ) then
  77. InternalError('Unexpected ISSigVerifySignature result');
  78. if VerifySourceFilename and (ExpectedFileName <> '') and not PathSame(PathExtractName(SourceFilename), ExpectedFileName) then
  79. VerificationError(veFileNameIncorrect);
  80. var FileSize: Int64;
  81. if SourceF <> nil then
  82. FileSize := SourceF.Size
  83. else
  84. FileSize := SourceFS.Size;
  85. if FileSize <> ExpectedFileSize then
  86. VerificationError(veFileSizeIncorrect);
  87. { Caller must check ExpectedFileHash }
  88. end;
  89. end.