116 lines
4.0 KiB
PowerShell
116 lines
4.0 KiB
PowerShell
param(
|
|
[string]$ConfigPath = "src-tauri/tauri.windows-signing.conf.json"
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Read-FirstEnv {
|
|
param([string[]]$Names)
|
|
|
|
foreach ($Name in $Names) {
|
|
$Value = [Environment]::GetEnvironmentVariable($Name)
|
|
if (-not [string]::IsNullOrWhiteSpace($Value)) {
|
|
return $Value.Trim()
|
|
}
|
|
}
|
|
|
|
throw "Set one of these environment variables: $($Names -join ', ')"
|
|
}
|
|
|
|
function Read-OptionalEnv {
|
|
param(
|
|
[string[]]$Names,
|
|
[string]$DefaultValue
|
|
)
|
|
|
|
foreach ($Name in $Names) {
|
|
$Value = [Environment]::GetEnvironmentVariable($Name)
|
|
if (-not [string]::IsNullOrWhiteSpace($Value)) {
|
|
return $Value.Trim()
|
|
}
|
|
}
|
|
|
|
return $DefaultValue
|
|
}
|
|
|
|
function Normalize-Thumbprint {
|
|
param([string]$Thumbprint)
|
|
|
|
return ($Thumbprint -replace "\s", "").ToUpperInvariant()
|
|
}
|
|
|
|
function Convert-CertificateSecretToBytes {
|
|
param([string]$CertificateSecret)
|
|
|
|
$Base64Lines = $CertificateSecret -split "\r?\n" |
|
|
Where-Object { $_ -notmatch "^-+BEGIN " -and $_ -notmatch "^-+END " }
|
|
$CertificateBase64 = ($Base64Lines -join "") -replace "\s", ""
|
|
|
|
try {
|
|
return [Convert]::FromBase64String($CertificateBase64)
|
|
} catch {
|
|
throw "Windows code-signing certificate must be base64-encoded PFX data."
|
|
}
|
|
}
|
|
|
|
$CertificateSecret = Read-FirstEnv @("WINDOWS_CODE_SIGNING_CERTIFICATE", "WINDOWS_CERTIFICATE")
|
|
$CertificatePassword = Read-FirstEnv @("WINDOWS_CODE_SIGNING_CERTIFICATE_PASSWORD", "WINDOWS_CERTIFICATE_PASSWORD")
|
|
$ConfiguredThumbprint = Read-OptionalEnv @("WINDOWS_CODE_SIGNING_CERTIFICATE_THUMBPRINT", "WINDOWS_CERTIFICATE_THUMBPRINT") ""
|
|
$DigestAlgorithm = Read-OptionalEnv @("WINDOWS_CODE_SIGNING_DIGEST_ALGORITHM") "sha256"
|
|
$TimestampUrl = Read-OptionalEnv @("WINDOWS_CODE_SIGNING_TIMESTAMP_URL", "WINDOWS_TIMESTAMP_URL") "http://timestamp.digicert.com"
|
|
|
|
$TempRoot = Join-Path ([IO.Path]::GetTempPath()) "tolaria-windows-signing"
|
|
if (-not [string]::IsNullOrWhiteSpace($env:RUNNER_TEMP)) {
|
|
$TempRoot = Join-Path $env:RUNNER_TEMP "tolaria-windows-signing"
|
|
}
|
|
New-Item -ItemType Directory -Force -Path $TempRoot | Out-Null
|
|
|
|
$PfxPath = Join-Path $TempRoot "certificate.pfx"
|
|
[IO.File]::WriteAllBytes($PfxPath, (Convert-CertificateSecretToBytes $CertificateSecret))
|
|
|
|
$SecurePassword = ConvertTo-SecureString -String $CertificatePassword -Force -AsPlainText
|
|
$ImportedCertificates = @(Import-PfxCertificate -FilePath $PfxPath -CertStoreLocation Cert:\CurrentUser\My -Password $SecurePassword)
|
|
Remove-Item -Force -ErrorAction SilentlyContinue $PfxPath
|
|
|
|
$ImportedCertificate = $ImportedCertificates | Where-Object { $_.HasPrivateKey } | Select-Object -First 1
|
|
if ($null -eq $ImportedCertificate) {
|
|
throw "The imported Windows code-signing certificate does not include a private key."
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ConfiguredThumbprint)) {
|
|
$CertificateThumbprint = Normalize-Thumbprint $ImportedCertificate.Thumbprint
|
|
} else {
|
|
$CertificateThumbprint = Normalize-Thumbprint $ConfiguredThumbprint
|
|
}
|
|
|
|
$StoreCertificate = Get-ChildItem Cert:\CurrentUser\My |
|
|
Where-Object { (Normalize-Thumbprint $_.Thumbprint) -eq $CertificateThumbprint } |
|
|
Select-Object -First 1
|
|
if ($null -eq $StoreCertificate) {
|
|
throw "The requested Windows code-signing certificate thumbprint was not found in Cert:\CurrentUser\My."
|
|
}
|
|
|
|
$Config = @{
|
|
bundle = @{
|
|
windows = @{
|
|
certificateThumbprint = $CertificateThumbprint
|
|
digestAlgorithm = $DigestAlgorithm
|
|
timestampUrl = $TimestampUrl
|
|
}
|
|
}
|
|
}
|
|
|
|
$ResolvedConfigPath = Resolve-Path -Path (Split-Path -Parent $ConfigPath) -ErrorAction SilentlyContinue
|
|
if ($null -eq $ResolvedConfigPath) {
|
|
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $ConfigPath) | Out-Null
|
|
}
|
|
|
|
$Config | ConvertTo-Json -Depth 10 | Set-Content -Path $ConfigPath -Encoding utf8NoBOM
|
|
|
|
if (-not [string]::IsNullOrWhiteSpace($env:GITHUB_ENV)) {
|
|
"WINDOWS_CODE_SIGNING_CERTIFICATE_THUMBPRINT=$CertificateThumbprint" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
}
|
|
|
|
Write-Host "Prepared Windows Authenticode signing config at $ConfigPath."
|