mirror of
https://github.com/openp2p-cn/openp2p.git
synced 2026-07-02 18:27:03 +08:00
* add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * add(ci): github action & signing * chore: update signature CI * fix(ci): sign windows binaries with direct CERTUM SHA1 * fix(ci): replace cert-store wait with simplysign readiness check * feat(ci): refactor certum signing flow for release * fix(ci): fail certum auth when session not ready * fix(ci): retry certum auth and fail critical steps * fix(ci): add cert preflight checks before signtool * fix(install): update SimplySign Desktop MSI download link to version 9.4.3.90 * fix(ci): mask totp and certificate identifiers in scripts * fix(ci): remove certificate inventory logs from release * add(ci): CHANGE beta release * feat(ci): resolve certum msi url dynamically from download page * add(ci): github action & signing * add(ci): github action & signing * revert(ci): app/app/build.gradle for build * add(ci): github action & signing * add(ci): github action & signing * Update default URLs for binary file downloads --------- Co-authored-by: Suyunmeng <Susus0175@proton.me> Co-authored-by: OpenP2P <89245779+TenderIronh@users.noreply.github.com>
182 lines
6.6 KiB
PowerShell
182 lines
6.6 KiB
PowerShell
# Sign-Windows.ps1
|
|
# Signs Windows EasyTier executables and libraries with a Certum SimplySign cloud certificate.
|
|
|
|
param(
|
|
[string]$TargetDirectory = "sign_binaries",
|
|
[string]$CertificateSHA1 = $env:CERTUM_CERTIFICATE_SHA1,
|
|
[string]$TimestampServer = "http://time.certum.pl"
|
|
)
|
|
|
|
function Get-LatestSignToolPath {
|
|
$windowsKitsBin = Join-Path ${env:ProgramFiles(x86)} "Windows Kits\10\bin"
|
|
if (Test-Path $windowsKitsBin) {
|
|
$candidate = (
|
|
Get-ChildItem -Path $windowsKitsBin -Recurse -File -Filter "signtool.exe" -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.FullName -match "\\x64\\signtool\.exe$" } |
|
|
ForEach-Object {
|
|
$version = [version]"0.0"
|
|
if ($_.FullName -match "\\bin\\([^\\]+)\\x64\\signtool\.exe$") {
|
|
try {
|
|
$version = [version]$matches[1]
|
|
} catch {
|
|
$version = [version]"0.0"
|
|
}
|
|
}
|
|
[PSCustomObject]@{
|
|
Path = $_.FullName
|
|
Version = $version
|
|
}
|
|
} |
|
|
Sort-Object -Property Version -Descending |
|
|
Select-Object -First 1
|
|
)
|
|
|
|
if ($candidate) {
|
|
return $candidate.Path
|
|
}
|
|
}
|
|
|
|
$cmd = Get-Command "signtool.exe" -ErrorAction SilentlyContinue
|
|
if ($cmd) {
|
|
return $cmd.Source
|
|
}
|
|
|
|
return $null
|
|
}
|
|
|
|
function Find-TargetCertificate {
|
|
param([string]$Thumbprint)
|
|
|
|
$all = Get-ChildItem -Path "Cert:\CurrentUser\My", "Cert:\LocalMachine\My" -ErrorAction SilentlyContinue
|
|
# 对证书库中的 Thumbprint 同样做规范化(去除不可见字符、统一大写),避免 BOM 或格式差异导致匹配失败
|
|
return @($all | Where-Object {
|
|
$normalizedStoreThumprint = ($_.Thumbprint -replace "[^a-fA-F0-9]", "").ToUpperInvariant()
|
|
$normalizedStoreThumprint -eq $Thumbprint
|
|
})
|
|
}
|
|
|
|
function Show-PrivateKeyCertificateHints {
|
|
$candidates = Get-ChildItem -Path "Cert:\CurrentUser\My", "Cert:\LocalMachine\My" -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.HasPrivateKey }
|
|
|
|
if (($null -eq $candidates) -or ($candidates.Count -eq 0)) {
|
|
Write-Host "No certificates with private keys were found in Personal stores"
|
|
return
|
|
}
|
|
|
|
Write-Host "Certificates with private keys are present in Personal stores, but details are hidden for security"
|
|
}
|
|
|
|
Write-Host "=== WINDOWS BINARY SIGNING (CERTUM SIMPLYSIGN) ==="
|
|
Write-Host "Target directory: $TargetDirectory"
|
|
|
|
if (-not (Test-Path $TargetDirectory)) {
|
|
Write-Host "ERROR: Target directory not found: $TargetDirectory"
|
|
exit 1
|
|
}
|
|
|
|
if (-not $CertificateSHA1) {
|
|
Write-Host "ERROR: CERTUM_CERTIFICATE_SHA1 environment variable not provided"
|
|
exit 1
|
|
}
|
|
|
|
$normalizedSha1 = ($CertificateSHA1 -replace "[^a-fA-F0-9]", "").ToUpperInvariant()
|
|
if ($normalizedSha1.Length -ne 40) {
|
|
Write-Host "ERROR: CERTUM_CERTIFICATE_SHA1 is invalid after normalization"
|
|
Write-Host "Raw length: $($CertificateSHA1.Length), normalized length: $($normalizedSha1.Length)"
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Expected signing certificate thumbprint has been received (masked)"
|
|
|
|
$targetCerts = Find-TargetCertificate -Thumbprint $normalizedSha1
|
|
if (($null -eq $targetCerts) -or ($targetCerts.Count -eq 0)) {
|
|
Write-Host "ERROR: Target certificate not found in Cert:\CurrentUser\My or Cert:\LocalMachine\My"
|
|
Write-Host "Authentication likely failed or CERTUM_CERTIFICATE_SHA1 is incorrect"
|
|
Show-PrivateKeyCertificateHints
|
|
exit 1
|
|
}
|
|
|
|
$targetWithPrivateKey = @($targetCerts | Where-Object { $_.HasPrivateKey })
|
|
if (($null -eq $targetWithPrivateKey) -or ($targetWithPrivateKey.Count -eq 0)) {
|
|
Write-Host "ERROR: Target certificate exists but has no available private key"
|
|
Write-Host "Signing cannot continue without private key access"
|
|
Show-PrivateKeyCertificateHints
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Locating signtool..."
|
|
$signTool = Get-LatestSignToolPath
|
|
if (-not $signTool) {
|
|
Write-Host "ERROR: signtool.exe not found"
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Found signtool: $signTool"
|
|
|
|
Write-Host "Scanning for Windows binaries to sign (.exe, .dll)..."
|
|
$filesToSign = Get-ChildItem -Path $TargetDirectory -Recurse -File |
|
|
Where-Object { $_.Extension -iin @(".exe", ".dll") }
|
|
|
|
if (($null -eq $filesToSign) -or ($filesToSign.Count -eq 0)) {
|
|
Write-Host "WARNING: No signable files (.exe, .dll) found to sign"
|
|
exit 0
|
|
}
|
|
|
|
Write-Host "Found $($filesToSign.Count) files to sign"
|
|
$signedCount = 0
|
|
$failedCount = 0
|
|
|
|
foreach ($file in $filesToSign) {
|
|
Write-Host "=== Signing: $($file.Name) ==="
|
|
Write-Host "Path: $($file.FullName)"
|
|
|
|
$attempts = @(
|
|
@{ Name = "SHA1 thumbprint + /td SHA256"; Args = @("sign", "/sha1", $normalizedSha1, "/tr", $TimestampServer, "/td", "SHA256", "/fd", "SHA256", "/v", $file.FullName) },
|
|
@{ Name = "SHA1 thumbprint in CurrentUser\\My"; Args = @("sign", "/sha1", $normalizedSha1, "/s", "My", "/tr", $TimestampServer, "/td", "SHA256", "/fd", "SHA256", "/v", $file.FullName) },
|
|
@{ Name = "SHA1 thumbprint in LocalMachine\\My"; Args = @("sign", "/sha1", $normalizedSha1, "/sm", "/s", "My", "/tr", $TimestampServer, "/td", "SHA256", "/fd", "SHA256", "/v", $file.FullName) },
|
|
@{ Name = "Auto-select cert (fallback)"; Args = @("sign", "/a", "/tr", $TimestampServer, "/td", "SHA256", "/fd", "SHA256", "/v", $file.FullName) }
|
|
)
|
|
|
|
$signed = $false
|
|
foreach ($attempt in $attempts) {
|
|
Write-Host "Attempt: $($attempt.Name)"
|
|
$signOutput = & $signTool @($attempt.Args) 2>&1
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host "SUCCESS: $($attempt.Name)"
|
|
$signed = $true
|
|
break
|
|
}
|
|
|
|
Write-Host "FAILED: $($attempt.Name)"
|
|
Write-Host "signtool returned a non-zero exit code; detailed output is hidden for security"
|
|
}
|
|
|
|
if ($signed) {
|
|
$signedCount++
|
|
$verifyOutput = & $signTool verify /pa /v $file.FullName 2>&1
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host "VERIFIED: Signature verification successful"
|
|
} else {
|
|
Write-Host "WARNING: Signature verification failed"
|
|
Write-Host "Detailed verification output is hidden for security"
|
|
}
|
|
} else {
|
|
$failedCount++
|
|
}
|
|
|
|
Write-Host ""
|
|
}
|
|
|
|
Write-Host "=== SIGNING SUMMARY ==="
|
|
Write-Host "Total files: $($filesToSign.Count)"
|
|
Write-Host "Successfully signed: $signedCount"
|
|
Write-Host "Failed to sign: $failedCount"
|
|
|
|
if ($failedCount -eq 0) {
|
|
Write-Host "ALL WINDOWS BINARIES SIGNED SUCCESSFULLY"
|
|
exit 0
|
|
}
|
|
|
|
Write-Host "SOME WINDOWS BINARIES FAILED TO SIGN"
|
|
exit 1 |