add(ci): support core build & signing by cert (#166)
* 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 <[email protected]> Co-authored-by: OpenP2P <[email protected]>
This commit is contained in:
co-authored by
Suyunmeng
OpenP2P
parent
07836fc162
commit
e9e4cd6b3c
@@ -0,0 +1,182 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user