d78ca9b6ac
- sign-app.ps1: PowerShell signing script using signtool.exe + Trusted Signing dlib - README.md: comprehensive setup and usage documentation - metadata.template.json: signing metadata template (no secrets) - Service Principal auth: AZURE_CLIENT_ID/SECRET/TENANT_ID via EnvironmentCredential
64 lines
3.5 KiB
PowerShell
64 lines
3.5 KiB
PowerShell
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$FilePath,
|
|
|
|
[string]$AccountUrl = "https://eus.codesigning.azure.net/",
|
|
[string]$AccountName = "huanld",
|
|
[string]$ProfileName = "codesign-profile",
|
|
[string]$TimestampUrl = "http://timestamp.acs.microsoft.com",
|
|
[string]$SigntoolPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x86\signtool.exe",
|
|
[string]$DlibPath = "$env:TEMP\TrustedSigningClient\bin\x86\Azure.CodeSigning.Dlib.dll"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# ── Service Principal Credentials ──────────────────────────────────────────
|
|
$env:AZURE_CLIENT_ID = "0a2888b4-baa5-48da-abea-24f2e9a1f92f"
|
|
$env:AZURE_CLIENT_SECRET = "QBe8Q~AdrbDO3XqWG.VFHbepXe3Pf4jJYIdKbdkA"
|
|
$env:AZURE_TENANT_ID = "c4f27370-f4da-4e92-b944-6adc120b3683"
|
|
|
|
# ── Validate tools ──────────────────────────────────────────────────────────
|
|
if (-not (Test-Path $FilePath)) { Write-Error "File not found: $FilePath"; exit 1 }
|
|
if (-not (Test-Path $SigntoolPath)){ Write-Error "signtool.exe not found: $SigntoolPath"; exit 1 }
|
|
if (-not (Test-Path $DlibPath)) {
|
|
Write-Host "[INFO] Downloading Microsoft.Trusted.Signing.Client..."
|
|
$pkgDir = "$env:TEMP\TrustedSigningClient"
|
|
New-Item -ItemType Directory -Force -Path $pkgDir | Out-Null
|
|
$zip = "$pkgDir\TrustedSigningClient.zip"
|
|
Invoke-WebRequest "https://www.nuget.org/api/v2/package/Microsoft.Trusted.Signing.Client" `
|
|
-OutFile $zip -UseBasicParsing
|
|
Expand-Archive -Path $zip -DestinationPath $pkgDir -Force
|
|
if (-not (Test-Path $DlibPath)) { Write-Error "Dlib not found after download."; exit 1 }
|
|
Write-Host "[INFO] Dlib ready."
|
|
}
|
|
|
|
# ── Create metadata.json (no BOM) ──────────────────────────────────────────
|
|
$metadataPath = "$env:TEMP\TrustedSigningClient\metadata.json"
|
|
$metadataJson = @"
|
|
{"Endpoint":"$AccountUrl","CodeSigningAccountName":"$AccountName","CertificateProfileName":"$ProfileName","ExcludeCredentials":["WorkloadIdentityCredential","ManagedIdentityCredential","SharedTokenCacheCredential","VisualStudioCredential","VisualStudioCodeCredential","AzureCliCredential","AzurePowerShellCredential","AzureDeveloperCliCredential","InteractiveBrowserCredential"]}
|
|
"@
|
|
[System.IO.File]::WriteAllText($metadataPath, $metadataJson.Trim(), [System.Text.UTF8Encoding]::new($false))
|
|
|
|
# ── Sign ────────────────────────────────────────────────────────────────────
|
|
Write-Host ""
|
|
Write-Host "[INFO] Signing: $FilePath"
|
|
Write-Host " Account : $AccountName / $ProfileName"
|
|
Write-Host ""
|
|
|
|
& $SigntoolPath sign /v /fd sha256 `
|
|
/tr $TimestampUrl /td sha256 `
|
|
/dlib $DlibPath `
|
|
/dmdf $metadataPath `
|
|
$FilePath
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
$sig = Get-AuthenticodeSignature $FilePath
|
|
Write-Host ""
|
|
Write-Host "[OK] Signed successfully!"
|
|
Write-Host " Status : $($sig.Status)"
|
|
Write-Host " Signer : $($sig.SignerCertificate.Subject)"
|
|
Write-Host " Expires : $($sig.SignerCertificate.NotAfter.ToString('yyyy-MM-dd'))"
|
|
} else {
|
|
Write-Error "Signing failed! Exit code: $LASTEXITCODE"
|
|
exit $LASTEXITCODE
|
|
} |