Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Sign the vendor directory instead of using Squirrel.Windows' signing method. #8855

Merged
merged 25 commits into from
Feb 17, 2025

Conversation

beyondkmp
Copy link
Collaborator

@beyondkmp beyondkmp commented Feb 8, 2025

fix #8854

Root cause

From electron/windows-installer#548 and electron/windows-sign#12 (comment) the windows-installer does not support the hookFunction for signing, which can lead to signing failures.

How to fix

We can first sign Squirrel.exe and StubExecutable.exe in the vendor directory. Then, when Squirrel.Windows uses these files, they are already signed, so there's no need for Squirrel.Windows to sign them again. This approach is the same as the earlier method that didn't use the windows-installer library.

Copy link

changeset-bot bot commented Feb 8, 2025

🦋 Changeset detected

Latest commit: d2e39c9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
electron-builder-squirrel-windows Patch
app-builder-lib Patch
dmg-builder Patch
electron-builder Patch
electron-forge-maker-appimage Patch
electron-forge-maker-nsis-web Patch
electron-forge-maker-nsis Patch
electron-forge-maker-snap Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@beyondkmp beyondkmp marked this pull request as draft February 8, 2025 04:03
@beyondkmp beyondkmp marked this pull request as ready for review February 12, 2025 13:35
@beyondkmp beyondkmp changed the title fix: use csclink firstly fix: Sign the vendor directory instead of using Squirrel.Windows' signing method. Feb 12, 2025
@beyondkmp beyondkmp changed the title fix: Sign the vendor directory instead of using Squirrel.Windows' signing method. fix: Sign the vendor directory instead of using Squirrel.Windows' signing method. Feb 12, 2025
@t3chguy
Copy link
Contributor

t3chguy commented Feb 12, 2025

We can first sign the .exe and .dll files in the vendor directory. Then, when Squirrel.Windows uses these files, they are already signed, so there's no need for Squirrel.Windows to sign them again. This approach is the same as the earlier method that didn't use the windows-installer library.

Signing these could incur fees given signatures using CloudHSMs cost money per signature, we should not be required to sign anything using the paid signing method unless it is being shipped to an end-users device. 7z.dll etc as found in the target vendor directory do not end up in the distributable Electron application so should not require to be signed.

Pre e-b 26 we only saw 3 signatures related to Squirrel + 1 for the unpacked executable + 1 for the msi package we also ship:

image

https://github.com/element-hq/element-desktop/actions/runs/12769577601/job/35592616472

After this patch, this goes up to 25 total, increasing cost per build by 5x

image

https://github.com/element-hq/element-desktop/actions/runs/13290932109/job/37111358677?pr=2132

image

@t3chguy
Copy link
Contributor

t3chguy commented Feb 13, 2025

Preliminary tests with latest commits look good: https://github.com/element-hq/element-desktop/actions/runs/13304132452/job/37151217411?pr=2132

  1. Squirrel setup file has correct name & icon
  2. number of signatures is back down to 5

image

@beyondkmp beyondkmp marked this pull request as draft February 16, 2025 01:54
@beyondkmp beyondkmp marked this pull request as ready for review February 16, 2025 11:11
@beyondkmp beyondkmp requested a review from mmaietta February 16, 2025 11:11
@beyondkmp
Copy link
Collaborator Author

beyondkmp commented Feb 16, 2025

@mmaietta @t3chguy It will probably take a long time for the upstream(electron/windows-installer#548) to support hookFunction. In the meantime, we can use the old approach to implement signing. Once upstream adds support, we can replace this solution. Do you have any concerns about this plan?

@t3chguy
Copy link
Contributor

t3chguy commented Feb 16, 2025

@beyondkmp that sounds sane, I will give the latest commits a test tomorrow when I'm back on the clock. Thanks for your work here.

@beyondkmp
Copy link
Collaborator Author

@t3chguy Please help test on both the x64 and arm64 platforms.

@t3chguy
Copy link
Contributor

t3chguy commented Feb 16, 2025

Sure, I will also test ia32 given that was broken with a 7z exe copy which I expect to be fixed with your arch fixes in the area.

@t3chguy
Copy link
Contributor

t3chguy commented Feb 17, 2025

ARM64 build failed with

⨯ Failed with exit code: 4294967295
Output:
System.AggregateException: One or more errors occurred. ---> System.ComponentModel.Win32Exception: The specified executable is not a valid application for this OS platform.
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at Squirrel.Utility.<InvokeProcessAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.Utility.<CreateZipFromDirectory>d__23.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at Squirrel.ReleasePackage.CreateReleasePackage(String outputFile, String packagesRootDir, Func`2 releaseNotesProcessor, Action`1 contentsPostProcessHook)
   at Squirrel.Update.Program.Releasify(String package, String targetDir, String packagesDir, String bootstrapperExe, String backgroundGif, String signingOpts, String baseUrl, String setupIcon, Boolean generateMsi, Boolean packageAs64Bit, String frameworkVersion, Boolean generateDeltas)
   at Squirrel.Update.Program.executeCommandLine(String[] args)
   at Squirrel.Update.Program.main(String[] args)
   at Squirrel.Update.Program.Main(String[] args)
---> (Inner Exception #0) System.ComponentModel.Win32Exception (0x80004005): The specified executable is not a valid application for this OS platform.
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at Squirrel.Utility.<InvokeProcessAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.Utility.<CreateZipFromDirectory>d__23.MoveNext()<---

  failedTask=build stackTrace=Error: Failed with exit code: 429496[729](https://github.com/element-hq/element-desktop/actions/runs/13367208845/job/37327553832?pr=2132#step:13:730)5
Output:
System.AggregateException: One or more errors occurred. ---> System.ComponentModel.Win32Exception: The specified executable is not a valid application for this OS platform.
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at Squirrel.Utility.<InvokeProcessAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.Utility.<CreateZipFromDirectory>d__23.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at Squirrel.ReleasePackage.CreateReleasePackage(String outputFile, String packagesRootDir, Func`2 releaseNotesProcessor, Action`1 contentsPostProcessHook)
   at Squirrel.Update.Program.Releasify(String package, String targetDir, String packagesDir, String bootstrapperExe, String backgroundGif, String signingOpts, String baseUrl, String setupIcon, Boolean generateMsi, Boolean packageAs64Bit, String frameworkVersion, Boolean generateDeltas)
   at Squirrel.Update.Program.executeCommandLine(String[] args)
   at Squirrel.Update.Program.main(String[] args)
   at Squirrel.Update.Program.Main(String[] args)
---> (Inner Exception #0) System.ComponentModel.Win32Exception (0x80004005): The specified executable is not a valid application for this OS platform.
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at Squirrel.Utility.<InvokeProcessAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Squirrel.Utility.<CreateZipFromDirectory>d__23.MoveNext()<---

https://github.com/element-hq/element-desktop/actions/runs/13367208845/job/37327553832?pr=2132

IA32 fails with an error we've seen before:

  ⨯ ENOENT: no such file or directory, copyfile 'C:\Users\RUNNER~1\AppData\Local\Temp\t-0llbqu\squirrel-windows-vendor-3\7z-ia32.exe' -> 'C:\Users\RUNNER~1\AppData\Local\Temp\t-0llbqu\squirrel-windows-vendor-3\7z.exe'  failedTask=build stackTrace=Error: ENOENT: no such file or directory, copyfile 'C:\Users\RUNNER~1\AppData\Local\Temp\t-0llbqu\squirrel-windows-vendor-3\7z-ia32.exe' -> 'C:\Users\RUNNER~1\AppData\Local\Temp\t-0llbqu\squirrel-windows-vendor-3\7z.exe'
    at Object.copyFileSync (node:fs:3086:11)
    at SquirrelWindowsTarget.select7zipArch (D:\a\element-desktop\element-desktop\node_modules\electron-builder-squirrel-windows\out\SquirrelWindowsTarget.js:103:12)
    at SquirrelWindowsTarget.computeEffectiveDistOptions (D:\a\element-desktop\element-desktop\node_modules\electron-builder-squirrel-windows\src\SquirrelWindowsTarget.ts:170:6)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
    at SquirrelWindowsTarget.build (D:\a\element-desktop\element-desktop\node_modules\electron-builder-squirrel-windows\src\SquirrelWindowsTarget.ts:62:19)
    at async Promise.all (index 0)
    at AsyncTaskManager.awaitTasks (D:\a\element-desktop\element-desktop\node_modules\builder-util\src\asyncTaskManager.ts:65:25)
    at Packager.doBuild (D:\a\element-desktop\element-desktop\node_modules\app-builder-lib\src\packager.ts:475:5)
    at executeFinally (D:\a\element-desktop\element-desktop\node_modules\builder-util\src\promise.ts:12:14)
    at Packager.build (D:\a\element-desktop\element-desktop\node_modules\app-builder-lib\src\packager.ts:393:31)
error Command failed with exit code 1.

https://github.com/element-hq/element-desktop/actions/runs/13367489308/job/37328442704?pr=2132

Looks like the issue is https://github.com/electron/windows-installer/tree/main/vendor lacks ia32 executables - electron/windows-installer#386

x64 still appears to work

@beyondkmp
Copy link
Collaborator Author

@t3chguy Thank you for helping with the testing. I have fixed the issues with arm64 and ia32 in the latest commit, and I've added unit tests (UT). So far, no issues have been found. If you have time, please help test it again.
image

@t3chguy
Copy link
Contributor

t3chguy commented Feb 17, 2025

@beyondkmp
Copy link
Collaborator Author

@t3chguy Great. The build seems to have succeeded, but I don't have machines with ia32 or arm64 architectures. Do you have access to ia32 and arm64 machines? If so, could you try installing and running the application on those machines to see if there are any issues?

@t3chguy
Copy link
Contributor

t3chguy commented Feb 17, 2025

Do you have access to ia32 and arm64 machines?

I have a local arm64 Windows VM I could test with but that would need to wait a day or two unfortunately. No access to ia32 at this time.

@beyondkmp
Copy link
Collaborator Author

beyondkmp commented Feb 17, 2025

For ia32, it can be tested on an x64 machine, and I’ve tested it without any issues.

image

image

However, for arm64, it can only be tested on an actual arm64 machine. It seems that @mmaietta has an arm64 Windows VM. @mmaietta , when you have time, could you help test the Windows arm64 build(https://github.com/element-hq/element-desktop/actions/runs/13369135877/artifacts/2602675309)?

@t3chguy
Copy link
Contributor

t3chguy commented Feb 17, 2025

@beyondkmp sorry I misunderstood, thought you wanted the CI running on arm64-native. I can run Element arm64 from the CI build job just fine:

Screen.Recording.2025-02-17.at.16.07.17.mov

@mmaietta
Copy link
Collaborator

Thanks for confirming @t3chguy ! PR approved.

@beyondkmp beyondkmp merged commit bee179b into electron-userland:master Feb 17, 2025
15 checks passed
@github-actions github-actions bot mentioned this pull request Feb 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

>26.0.1 gets stuck on Windows signing the squirrel exe
3 participants