66 lines
2.7 KiB
PowerShell
66 lines
2.7 KiB
PowerShell
# Sign the given files with the release certificate from the repository secrets.
|
|
#
|
|
# msime-installer's Sign-PackageBinaries-Local.ps1 mints a self-signed certificate for local
|
|
# testing and must never run in CI, so this is a separate path using the real certificate. Used
|
|
# for the uiAccess Server binary and the finished installer.
|
|
#
|
|
# Requires CERTIFICATE_BASE64, CERTIFICATE_PASSWORD, TIMESTAMP_URL.
|
|
param(
|
|
[Parameter(Mandatory)][string[]]$Path,
|
|
[switch]$Recurse
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$targets = if ($Recurse) {
|
|
Get-ChildItem -Recurse -File -Include '*.exe', '*.dll' -Path $Path
|
|
}
|
|
else {
|
|
Get-Item -Path $Path
|
|
}
|
|
|
|
# A package can contain the same payload through multiple input paths. Sign each
|
|
# physical file at most once; certificate usage is per signed file, not per
|
|
# signtool invocation.
|
|
$targets = @($targets | Sort-Object FullName -Unique)
|
|
|
|
if (-not $targets) {
|
|
throw "Nothing to sign under: $($Path -join ', ')"
|
|
}
|
|
|
|
Write-Host "Signing $($targets.Count) unique file(s):"
|
|
$targets | ForEach-Object { Write-Host " - $($_.FullName)" }
|
|
|
|
$signtool = Get-ChildItem 'C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe' |
|
|
Sort-Object FullName -Descending | Select-Object -First 1
|
|
if (-not $signtool) { throw 'signtool.exe not found in the Windows SDK.' }
|
|
|
|
if ($env:CERTIFICATE_THUMBPRINT) {
|
|
$thumbprint = $env:CERTIFICATE_THUMBPRINT -replace '\s', ''
|
|
$cert = Get-ChildItem Cert:\CurrentUser\My\$thumbprint -ErrorAction SilentlyContinue
|
|
if ($cert -and $cert.HasPrivateKey) {
|
|
& $signtool.FullName sign /sha1 $thumbprint /fd sha256 /tr $env:TIMESTAMP_URL /td sha256 /v @($targets.FullName)
|
|
if ($LASTEXITCODE -ne 0) { throw "signtool failed with exit code $LASTEXITCODE" }
|
|
Write-Host "Signed using certificate store thumbprint $thumbprint."
|
|
return
|
|
}
|
|
if (-not ($env:CERTIFICATE_BASE64 -and $env:CERTIFICATE_PASSWORD)) {
|
|
throw "Certificate with thumbprint $thumbprint is not available with a private key, and no PFX fallback is configured."
|
|
}
|
|
Write-Warning "Certificate thumbprint $thumbprint is unavailable; falling back to the PFX secret."
|
|
}
|
|
|
|
if ($env:CERTIFICATE_BASE64 -and $env:CERTIFICATE_PASSWORD) {
|
|
$pfx = Join-Path $env:RUNNER_TEMP 'metasequoia-signing.pfx'
|
|
[IO.File]::WriteAllBytes($pfx, [Convert]::FromBase64String($env:CERTIFICATE_BASE64))
|
|
try {
|
|
& $signtool.FullName sign /f $pfx /p $env:CERTIFICATE_PASSWORD /fd sha256 /tr $env:TIMESTAMP_URL /td sha256 /v @($targets.FullName)
|
|
if ($LASTEXITCODE -ne 0) { throw "signtool failed with exit code $LASTEXITCODE" }
|
|
} finally { Remove-Item $pfx -Force -ErrorAction SilentlyContinue }
|
|
}
|
|
else {
|
|
throw 'No usable signing certificate is configured.'
|
|
}
|
|
|
|
Write-Host "Signed $($targets.Count) file(s)."
|