tools/sign-release.ps1
|
# Signs all user-facing Maestro scripts with an Authenticode code-signing # certificate. Requires the certificate to already exist in a cert store # (Cert:\CurrentUser\My or Cert:\LocalMachine\My) with Code Signing EKU. # # Typical usage: # ./tools/sign-release.ps1 -CertThumbprint <thumbprint> # # Rules enforced here: # - Timestamp server is REQUIRED (signatures must outlive cert expiry). # - Every target must end with Status: Valid or the script fails. param( [Parameter(Mandatory)] [string]$CertThumbprint, [string]$TimestampServer = 'http://timestamp.digicert.com', [string]$Root, [switch]$VerifyOnly ) $ErrorActionPreference = 'Stop' if (-not $Root) { $Root = Split-Path -Parent $PSScriptRoot } $targets = @( 'Install-Maestro.ps1', 'tools/install-from-web.ps1', 'tools/validate-bundle.ps1', 'tools/smoke-install.ps1', 'tools/build-module.ps1' ) $cert = Get-ChildItem Cert:\CurrentUser\My, Cert:\LocalMachine\My -ErrorAction SilentlyContinue | Where-Object { $_.Thumbprint -eq $CertThumbprint } | Select-Object -First 1 if (-not $cert) { throw "Certificate $CertThumbprint not found in CurrentUser\My or LocalMachine\My" } if ($cert.NotAfter -lt (Get-Date)) { throw 'Certificate is expired' } if (-not ($cert.EnhancedKeyUsageList | Where-Object FriendlyName -eq 'Code Signing')) { Write-Warning 'Certificate does not advertise Code Signing EKU - signatures may not satisfy AllSigned policy' } Write-Host "Signing with: $($cert.Subject)" Write-Host "Expires: $($cert.NotAfter)" foreach ($rel in $targets) { $path = Join-Path $Root $rel if (-not (Test-Path -LiteralPath $path)) { throw "missing target: $path" } if ($VerifyOnly) { $status = (Get-AuthenticodeSignature -LiteralPath $path).Status Write-Host (" {0,-12} {1}" -f $status, $rel) continue } $result = Set-AuthenticodeSignature -LiteralPath $path -Certificate $cert -TimestampServer $TimestampServer if ($result.Status -ne 'Valid') { throw ("signing failed for {0}: {1} ({2})" -f $rel, $result.Status, $result.StatusMessage) } Write-Host (" signed {0}" -f $rel) -ForegroundColor Green } Write-Host '' Write-Host '=== Verification pass ===' foreach ($rel in $targets) { $sig = Get-AuthenticodeSignature -LiteralPath (Join-Path $Root $rel) Write-Host (" {0,-12} {1}" -f $sig.Status, $rel) if ($sig.Status -ne 'Valid') { throw "post-sign verification failed for $rel" } } Write-Host 'ALL SCRIPTS SIGNED AND VALID' -ForegroundColor Green |