mirror of
https://github.com/stablyai/orca.git
synced 2026-10-17 08:03:14 +00:00
Keep elevate.exe signed through the NSIS rebuild
electron-builder's CopyElevateHelper re-copies a pristine elevate.exe from its download cache on every NSIS pack, which clobbered the round-1 SignPath signature in v1.4.129-rc.4 (caught by the evidence gate). Overwrite the cached copy with the signed one before the rebuild so the clobber becomes a no-op, and make the evidence gate verify resources\elevate.exe in every release regardless of whether staging listed it (the persisted cache can carry an already-signed copy).
This commit is contained in:
@@ -1132,6 +1132,45 @@ jobs:
|
||||
throw "Signed inner artifact did not round-trip cleanly ($($failures.Count) failures)."
|
||||
}
|
||||
|
||||
# Why this step exists: electron-builder's CopyElevateHelper re-copies a
|
||||
# pristine elevate.exe from its download cache over resources\elevate.exe
|
||||
# on EVERY nsis pack — including the --prepackaged rebuild below — which
|
||||
# clobbered the SignPath signature in v1.4.129-rc.4. There is no supported
|
||||
# way to disable just the copy, so we overwrite the cache's copy with our
|
||||
# signed one (identical bytes plus signature) so the clobber becomes a
|
||||
# no-op. Known quirk: the cache persists across releases via actions/cache,
|
||||
# so later runs may see elevate.exe as already signed and skip staging it —
|
||||
# that is fine (the signature is timestamped) and the evidence gate checks
|
||||
# elevate.exe in the shipped installer unconditionally. If this ever causes
|
||||
# trouble, delete this step; the only effect is elevate.exe shipping
|
||||
# unsigned again, which the evidence gate will flag.
|
||||
- name: Replace cached elevate.exe with the signed copy
|
||||
id: sign-elevate-cache
|
||||
if: matrix.platform == 'win' && steps.restore-signed-inner.outcome == 'success'
|
||||
continue-on-error: true
|
||||
shell: pwsh
|
||||
run: |
|
||||
$signed = 'dist/win-unpacked/resources/elevate.exe'
|
||||
if (-not (Test-Path $signed)) {
|
||||
Write-Host '::warning::No elevate.exe in win-unpacked resources; nothing to protect from the rebuild clobber.'
|
||||
exit 0
|
||||
}
|
||||
$signature = Get-AuthenticodeSignature -FilePath $signed
|
||||
$subject = if ($null -eq $signature.SignerCertificate) { '<none>' } else { $signature.SignerCertificate.Subject }
|
||||
if ($signature.Status -ne 'Valid' -or $subject -notlike '*CN=SignPath Foundation*') {
|
||||
Write-Host "::warning::win-unpacked elevate.exe is not SignPath-signed ($($signature.Status), $subject); skipping cache swap."
|
||||
exit 0
|
||||
}
|
||||
$cached = @(Get-ChildItem "$env:LOCALAPPDATA\electron-builder\Cache\nsis" -Recurse -Filter elevate.exe -ErrorAction SilentlyContinue)
|
||||
if ($cached.Count -eq 0) {
|
||||
Write-Host '::warning::No cached elevate.exe found (electron-builder cache layout changed?); the rebuild will pack the unsigned copy and the evidence gate will flag it.'
|
||||
exit 0
|
||||
}
|
||||
foreach ($file in $cached) {
|
||||
Copy-Item -Path $signed -Destination $file.FullName -Force
|
||||
Write-Host "Replaced $($file.FullName) with the SignPath-signed copy."
|
||||
}
|
||||
|
||||
- name: Rebuild NSIS installer from signed unpacked app
|
||||
id: rebuild-nsis-signed
|
||||
if: matrix.platform == 'win' && steps.restore-signed-inner.outcome == 'success'
|
||||
@@ -1325,7 +1364,16 @@ jobs:
|
||||
& $7za x 'dist/orca-windows-setup.exe' '-oinner-evidence-extract' -y | Out-Null
|
||||
|
||||
$root = Resolve-Path 'inner-evidence-extract'
|
||||
foreach ($relative in Get-Content 'inner-signing-list.txt') {
|
||||
# Why elevate.exe is always appended: staging skips already-signed
|
||||
# files, and the persisted electron-builder cache can carry a
|
||||
# previously signed elevate.exe — so it may be absent from the list
|
||||
# in some runs, yet it is the file most at risk of losing its
|
||||
# signature in the NSIS rebuild. Verify it in every release.
|
||||
$targets = @(Get-Content 'inner-signing-list.txt')
|
||||
if ($targets -notcontains 'resources\elevate.exe') {
|
||||
$targets += 'resources\elevate.exe'
|
||||
}
|
||||
foreach ($relative in $targets) {
|
||||
$path = Join-Path $root $relative
|
||||
if (-not (Test-Path $path)) {
|
||||
$failures.Add("missing from installer payload: $relative")
|
||||
@@ -1348,7 +1396,7 @@ jobs:
|
||||
if ($required) { throw $message }
|
||||
Write-Host "::warning::$message Fail-open until ORCA_WINDOWS_INNER_SIGNATURE_REQUIRED is 'true'."
|
||||
} else {
|
||||
Write-Host "All $((Get-Content 'inner-signing-list.txt').Count) inner binaries in the shipped installer are signed by SignPath Foundation."
|
||||
Write-Host "All $($targets.Count) inner binaries in the shipped installer are signed by SignPath Foundation."
|
||||
}
|
||||
} catch {
|
||||
if ($required) { throw }
|
||||
|
||||
@@ -254,6 +254,7 @@ describe('Electron runtime package contract', () => {
|
||||
'Notify Slack that inner-binary signing is waiting for approval',
|
||||
'Download signed inner binaries from SignPath',
|
||||
'Restore signed inner binaries into unpacked app',
|
||||
'Replace cached elevate.exe with the signed copy',
|
||||
'Rebuild NSIS installer from signed unpacked app'
|
||||
]
|
||||
for (const stepName of innerChainStepNames) {
|
||||
|
||||
Reference in New Issue
Block a user