From e9acf601b22a3f8c411674bc2fe779351445f9c7 Mon Sep 17 00:00:00 2001 From: Chris O'Neil Date: Mon, 30 Mar 2026 23:16:12 +0100 Subject: [PATCH] chore: sign Windows binary with DigiCert EV certificate Add a sign-windows job to the release workflow that signs ant-node.exe using DigiCert SSM before the post-quantum signing step. The signed binary is repackaged into the release archive. Mirrors the approach used in ant-client. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/release.yml | 132 +++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1284a5c..e40d859 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -187,17 +187,141 @@ jobs: path: ant-node-cli-${{ matrix.friendly_name }}.${{ matrix.archive }} retention-days: 1 + sign-windows: + name: Sign Windows Binary + runs-on: windows-latest + needs: [build] + env: + SM_HOST: ${{ secrets.SM_HOST }} + SM_API_KEY: ${{ secrets.SM_API_KEY }} + SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} + SM_KEYPAIR_ALIAS: ${{ secrets.SM_KEYPAIR_ALIAS }} + SM_LOG_LEVEL: info + SM_LOG_FILE: ${{ github.workspace }}\smctl-signing.log + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + name: cli-windows-x64 + path: artifacts/ + + - name: Extract binary for signing + shell: bash + run: | + cd artifacts + 7z x *.zip + if [ ! -f "ant-node.exe" ]; then + echo "::error::ant-node.exe not found after extraction" + ls -R + exit 1 + fi + + - name: Create client certificate file + id: prepare_cert + shell: pwsh + run: | + $raw = @' + ${{ secrets.SM_CLIENT_CERT_B64 }} + '@ + + $clean = ($raw -replace '\s','') + + if ([string]::IsNullOrWhiteSpace($clean)) { + Write-Error "SM_CLIENT_CERT_B64 is empty after normalization." + exit 1 + } + + try { + $certBytes = [Convert]::FromBase64String($clean) + } catch { + Write-Error "SM_CLIENT_CERT_B64 is not valid Base64." + exit 1 + } + + $certPath = Join-Path $env:RUNNER_TEMP "Certificate.p12" + [System.IO.File]::WriteAllBytes($certPath, $certBytes) + + "SM_CLIENT_CERT_FILE=$certPath" | Out-File -FilePath $env:GITHUB_ENV -Append + Write-Host "::add-mask::$clean" + "sm_client_cert_b64=$clean" | Out-File -FilePath $env:GITHUB_OUTPUT -Append + + - name: Setup DigiCert SSM tools + uses: digicert/ssm-code-signing@v1.2.1 + with: + sm_host: ${{ secrets.SM_HOST }} + sm_api_key: ${{ secrets.SM_API_KEY }} + sm_client_cert_b64: ${{ steps.prepare_cert.outputs.sm_client_cert_b64 }} + sm_client_cert_password: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} + + - name: Verify smctl installation + shell: pwsh + run: | + smctl -v + smctl healthcheck + + - name: Sign ant-node.exe + shell: pwsh + run: | + $file = "artifacts\ant-node.exe" + $result = & smctl sign --keypair-alias "$env:SM_KEYPAIR_ALIAS" --input "$file" 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Error "Signing failed: $result" + exit 1 + } + Write-Host "Successfully signed ant-node.exe" + + - name: Verify signature + shell: pwsh + run: | + $sig = Get-AuthenticodeSignature "artifacts\ant-node.exe" + Write-Host "Status: $($sig.Status)" + Write-Host "Signer: $($sig.SignerCertificate.Subject)" + if ($sig.Status -ne "Valid") { + Write-Error "Signature validation failed" + exit 1 + } + + - name: Repackage signed archive + shell: bash + run: | + staging="ant-node-cli-windows-x64" + rm -rf "$staging" + mkdir "$staging" + cp artifacts/ant-node.exe "$staging/" + cp config/bootstrap_peers.toml "$staging/" + (cd "$staging" && 7z a "../${staging}.zip" ./*) + + + - uses: actions/upload-artifact@v4 + with: + name: signed-windows-x64 + path: ant-node-cli-windows-x64.zip + retention-days: 1 + sign: name: Sign Releases - needs: [build] + needs: [build, sign-windows] runs-on: ubuntu-latest steps: - - name: Download all artifacts + - name: Download build artifacts (excluding signed) uses: actions/download-artifact@v4 with: + pattern: cli-* path: artifacts merge-multiple: true + - name: Download signed Windows artifact + uses: actions/download-artifact@v4 + with: + name: signed-windows-x64 + path: artifacts-signed-win + + - name: Replace Windows archive with signed version + run: | + rm -f artifacts/ant-node-cli-windows-x64.zip + cp artifacts-signed-win/*.zip artifacts/ + - name: List artifacts run: ls -la artifacts/ @@ -322,6 +446,10 @@ jobs: ant-keygen verify --key release-signing-key.pub --input --signature .sig ``` + The Windows binary (`ant-node.exe`) is additionally signed with a DigiCert EV + code-signing certificate. Windows will verify this signature automatically on + download and execution. + SHA256 checksums provided in `SHA256SUMS.txt`. ### Auto-Upgrade