From 02597d3ac42b070c7287d03d2417fb8153998bb0 Mon Sep 17 00:00:00 2001 From: Ben Olden-Cooligan Date: Fri, 4 Oct 2024 15:17:08 -0700 Subject: [PATCH] Tools: Backport windows code signing --- .../Project/Packaging/InnoSetupPackager.cs | 14 +++++++++- .../Project/Packaging/PackageCommand.cs | 6 ++-- .../Project/Packaging/WindowsSigning.cs | 28 +++++++++++++++++++ .../Project/Packaging/WixToolsetPackager.cs | 15 +++++++++- .../Project/Packaging/ZipArchivePackager.cs | 8 +++++- 5 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 NAPS2.Tools/Project/Packaging/WindowsSigning.cs diff --git a/NAPS2.Tools/Project/Packaging/InnoSetupPackager.cs b/NAPS2.Tools/Project/Packaging/InnoSetupPackager.cs index 33febdb9ec..52072eef22 100644 --- a/NAPS2.Tools/Project/Packaging/InnoSetupPackager.cs +++ b/NAPS2.Tools/Project/Packaging/InnoSetupPackager.cs @@ -5,8 +5,14 @@ namespace NAPS2.Tools.Project.Packaging; public static class InnoSetupPackager { - public static void PackageExe(PackageInfo packageInfo) + public static void PackageExe(PackageInfo packageInfo, bool noSign) { + if (!noSign) + { + Output.Verbose("Signing contents"); + WindowsSigning.SignContents(packageInfo); + } + var exePath = packageInfo.GetPath("exe"); Output.Info($"Packaging exe installer: {exePath}"); @@ -16,6 +22,12 @@ public static void PackageExe(PackageInfo packageInfo) var iscc = Environment.ExpandEnvironmentVariables("%PROGRAMFILES(X86)%/Inno Setup 6/iscc.exe"); Cli.Run(iscc, $"\"{innoDefPath}\""); + if (!noSign) + { + Output.Verbose("Signing installer"); + WindowsSigning.SignFile(exePath); + } + Output.OperationEnd($"Packaged exe installer: {exePath}"); } diff --git a/NAPS2.Tools/Project/Packaging/PackageCommand.cs b/NAPS2.Tools/Project/Packaging/PackageCommand.cs index 21f43a089b..a92588ecc6 100644 --- a/NAPS2.Tools/Project/Packaging/PackageCommand.cs +++ b/NAPS2.Tools/Project/Packaging/PackageCommand.cs @@ -30,13 +30,13 @@ public int Run(PackageOptions opts) switch (target.Type) { case PackageType.Exe: - InnoSetupPackager.PackageExe(GetPackageInfoForConfig("Release")); + InnoSetupPackager.PackageExe(GetPackageInfoForConfig("Release"), opts.NoSign); break; case PackageType.Msi: - WixToolsetPackager.PackageMsi(GetPackageInfoForConfig("Release-Msi")); + WixToolsetPackager.PackageMsi(GetPackageInfoForConfig("Release-Msi"), opts.NoSign); break; case PackageType.Zip: - ZipArchivePackager.PackageZip(GetPackageInfoForConfig("Release-Zip")); + ZipArchivePackager.PackageZip(GetPackageInfoForConfig("Release-Zip"), opts.NoSign); break; case PackageType.Deb: DebPackager.PackageDeb(GetPackageInfoForConfig(), opts.NoSign); diff --git a/NAPS2.Tools/Project/Packaging/WindowsSigning.cs b/NAPS2.Tools/Project/Packaging/WindowsSigning.cs new file mode 100644 index 0000000000..fe0da0eb85 --- /dev/null +++ b/NAPS2.Tools/Project/Packaging/WindowsSigning.cs @@ -0,0 +1,28 @@ +namespace NAPS2.Tools.Project.Packaging; + +public static class WindowsSigning +{ + public static void SignContents(PackageInfo packageInfo) + { + // Exclude resource DLLs from signing as that saves 40% time/space and doesn't really provide any value. + // TODO: Maybe reevaluate this + foreach (var batch in packageInfo.Files.Where(file => !file.FileName.EndsWith(".resources.dll")).Chunk(10)) + { + var files = string.Join(" ", + batch + .Where(file => Path.GetExtension(file.FileName) is ".exe" or ".dll") + .Select(file => $"\"{file.SourcePath}\"")); + if (files.Length > 0) + { + Cli.Run("signtool", + $"sign /tr http://timestamp.globalsign.com/tsa/r6advanced1 /td sha256 /fd sha256 /a {files}"); + } + } + } + + public static void SignFile(string path) + { + Cli.Run("signtool", + $"sign /tr http://timestamp.globalsign.com/tsa/r6advanced1 /td sha256 /fd sha256 /a \"{path}\""); + } +} \ No newline at end of file diff --git a/NAPS2.Tools/Project/Packaging/WixToolsetPackager.cs b/NAPS2.Tools/Project/Packaging/WixToolsetPackager.cs index 8d54d5777c..9249e89c47 100644 --- a/NAPS2.Tools/Project/Packaging/WixToolsetPackager.cs +++ b/NAPS2.Tools/Project/Packaging/WixToolsetPackager.cs @@ -6,8 +6,14 @@ namespace NAPS2.Tools.Project.Packaging; public static class WixToolsetPackager { - public static void PackageMsi(PackageInfo pkgInfo) + public static void PackageMsi(PackageInfo pkgInfo, bool noSign) { + if (!noSign) + { + Output.Verbose("Signing contents"); + WindowsSigning.SignContents(pkgInfo); + } + var msiPath = pkgInfo.GetPath("msi"); Output.Info($"Packaging msi installer: {msiPath}"); var wxsPath = GenerateWxs(pkgInfo); @@ -20,6 +26,13 @@ public static void PackageMsi(PackageInfo pkgInfo) var light = Environment.ExpandEnvironmentVariables("%PROGRAMFILES(X86)%/WiX Toolset v3.11/bin/light.exe"); Cli.Run(light, $"\"{wixobjPath}\" -spdb -ext WixUIExtension -o \"{msiPath}\""); + + if (!noSign) + { + Output.Verbose("Signing installer"); + WindowsSigning.SignFile(msiPath); + } + Output.OperationEnd($"Packaged msi installer: {msiPath}"); } diff --git a/NAPS2.Tools/Project/Packaging/ZipArchivePackager.cs b/NAPS2.Tools/Project/Packaging/ZipArchivePackager.cs index ccb5f68c0d..8843512ee8 100644 --- a/NAPS2.Tools/Project/Packaging/ZipArchivePackager.cs +++ b/NAPS2.Tools/Project/Packaging/ZipArchivePackager.cs @@ -4,8 +4,14 @@ namespace NAPS2.Tools.Project.Packaging; public static class ZipArchivePackager { - public static void PackageZip(PackageInfo pkgInfo) + public static void PackageZip(PackageInfo pkgInfo, bool noSign) { + if (!noSign) + { + Output.Verbose("Signing contents"); + WindowsSigning.SignContents(pkgInfo); + } + var zipPath = pkgInfo.GetPath("zip"); Output.Info($"Packaging zip archive: {zipPath}"); if (File.Exists(zipPath))