From cfe0f467310c0a4f590ee839ee6f248f40a6686c Mon Sep 17 00:00:00 2001 From: Le-Syl21 Date: Fri, 10 Jul 2026 15:05:21 +0200 Subject: [PATCH] CI: sign Windows with ssign instead of the SimplySign container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the standalone SimplySign-Desktop-2.9.10 + PKCS#11 container workflow with a gated `sign-windows` job in ci.yml: the Linux runner installs ssign and Authenticode-signs pinready.exe via Certum (no Windows, no container). Gated by the `signing` environment (owner approval); `release` now needs it, so a tag is build → approve → signed release. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_0138mtPxwfXPetBypyjp6KwU --- .github/workflows/ci.yml | 44 ++++++++- .github/workflows/sign-windows.yml | 143 ----------------------------- target-bookworm/.rustc_info.json | 1 + target-bookworm/CACHEDIR.TAG | 3 + 4 files changed, 47 insertions(+), 144 deletions(-) delete mode 100644 .github/workflows/sign-windows.yml create mode 100644 target-bookworm/.rustc_info.json create mode 100644 target-bookworm/CACHEDIR.TAG diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed59d914..6bbc6add 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -233,9 +233,51 @@ jobs: name: pinready-${{ matrix.label }} path: pinready-${{ matrix.label }}.* - release: + # Authenticode-sign the Windows binary with ssign (the Linux runner signs the + # .exe — no Windows, no vendor stack). Gated by the `signing` environment + # (owner approval); the release below waits for it, so a tag becomes + # build → approve → signed release. + sign-windows: needs: build if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + environment: signing + steps: + - uses: dtolnay/rust-toolchain@stable + + - name: Install ssign + run: cargo install ssign + + - name: Download the Windows artifact + uses: actions/download-artifact@v8 + with: + name: pinready-windows-x86_64 + path: dl + + - name: Sign pinready.exe with ssign (via Certum) + env: + CERTUM_EMAIL: ${{ secrets.CERTUM_EMAIL }} + CERTUM_OTP: ${{ secrets.CERTUM_OTP }} + run: | + unzip -o dl/pinready-windows-x86_64.zip -d dl + ssign --verbose \ + -n "PinReady" -u "https://github.com/${{ github.repository }}" \ + dl/pinready.exe + sudo apt-get update -qq && sudo apt-get install -y osslsigncode + osslsigncode verify dl/pinready.exe 2>&1 | tee verify.txt || true + grep -q "Calculated message digest" verify.txt + (cd dl && rm -f pinready-windows-x86_64.zip && zip -j pinready-windows-x86_64.zip pinready.exe) + + - name: Re-upload the signed Windows artifact + uses: actions/upload-artifact@v7 + with: + name: pinready-windows-x86_64 + path: dl/pinready-windows-x86_64.zip + overwrite: true + + release: + needs: [build, sign-windows] + if: startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-24.04 permissions: contents: write diff --git a/.github/workflows/sign-windows.yml b/.github/workflows/sign-windows.yml deleted file mode 100644 index 9d08f3ac..00000000 --- a/.github/workflows/sign-windows.yml +++ /dev/null @@ -1,143 +0,0 @@ -# Windows code-signing via Certum SimplySign (cloud HSM) — STANDALONE TEST. -# -# This is intentionally a manual (`workflow_dispatch`) workflow, gated by the -# protected `signing` environment, so we can iterate on the (fiddly) Certum -# SimplySign-on-Linux login WITHOUT risking the real release pipeline. -# -# It downloads the pinready.exe from an existing GitHub Release, signs it, and -# uploads the signed binary as an artifact for inspection. Once this proves -# reliable, the `sign` job gets folded into ci.yml between `build` and `release`. -# -# Secrets required on the `signing` environment: -# - CERTUM_USERID : SimplySign account e-mail -# - CERTUM_TOTP_SECRET : Base32 TOTP seed from the activation QR (otpauth secret=) -# - CERTUM_CARD_PIN : (optional) card PIN, if SimplySign prompts for one -# -# The mobile phone is NOT needed: the 6-digit code is generated from the TOTP -# secret with `oathtool`. The only human step is approving the `signing` -# environment (GitHub notifies you; approve from the mobile GitHub app). - -name: Sign Windows (Certum SimplySign — test) - -on: - workflow_dispatch: - inputs: - release_tag: - description: "Release tag whose pinready-windows-x86_64.zip to sign (e.g. v0.16.0)" - required: true - type: string - -# SimplySign Desktop 2.9.10 (Linux RedHat build) + its PKCS#11 module. -env: - SSD_BIN: SimplySignDesktop-2.9.10-9.2.14.0-x86_64-prod-centos.bin - SSD_SHA256: 1bb72568f27ceb46aaa2906d3347dd49c72ea4795eded79f7b3ecb18b6379947 - SSD_URL: https://files.certum.eu/software/SimplySignDesktop/Linux-RedHat/2.9.10-9.2.14.0/SimplySignDesktop-2.9.10-9.2.14.0-x86_64-prod-centos.bin - PKCS11_MODULE: /opt/SimplySignDesktop/SimplySignPKCS_64-MS-1.0.20.so - -jobs: - sign: - runs-on: ubuntu-latest - # ── The approval gate. This job pauses until you approve the `signing` - # environment; only then are its secrets exposed to the runner. ── - environment: signing - # Fedora matches the SimplySign Linux build (the container image ships the - # RedHat .bin + /usr/lib64 p11-kit layout). - container: - image: fedora:42 - - steps: - - name: Install SimplySign Desktop + signing tools - run: | - set -euxo pipefail - dnf -y install --setopt=install_weak_deps=False \ - libX11 libXext libXcomposite libXi libICE libSM libXrender libxcb libXau \ - pcsc-lite-libs libglvnd-glx xorg-x11-server-Xvfb xdotool \ - p11-kit-server osslsigncode oathtool procps-ng curl unzip ImageMagick - curl -sSLO "$SSD_URL" - echo "$SSD_SHA256 $SSD_BIN" | sha256sum -c - yes yes | sh "$SSD_BIN" --target /tmp/certum - mv /tmp/certum/SSD-2.9.10-dist /opt/SimplySignDesktop - test -f "$PKCS11_MODULE" - - - name: Download pinready.exe from the release - run: | - set -euxo pipefail - dnf -y install gh jq - gh release download "${{ inputs.release_tag }}" \ - --repo "$GITHUB_REPOSITORY" \ - --pattern 'pinready-windows-x86_64.zip' --dir /tmp/dl - unzip -o /tmp/dl/pinready-windows-x86_64.zip -d /tmp/dl - test -f /tmp/dl/pinready.exe - env: - GH_TOKEN: ${{ github.token }} - - - name: Start SimplySign Desktop and log in (headless, auto-TOTP) - env: - CERTUM_USERID: ${{ secrets.CERTUM_USERID }} - CERTUM_TOTP_SECRET: ${{ secrets.CERTUM_TOTP_SECRET }} - run: | - set -uxo pipefail - export DISPLAY=:99 - Xvfb :99 -screen 0 1280x1024x24 & - sleep 3 - # Launch the desktop app (it draws the login dialog). - ( /opt/SimplySignDesktop/SimplySignDesktop >/tmp/ssd.log 2>&1 & ) - sleep 12 - - # ┌── FRAGILE: GUI login automation. This is the part that needs - # │ iterating on — window title / field order / button labels can - # │ differ by version. We type the e-mail, tab to the OTP field, - # │ type the freshly-generated TOTP, and submit. A screenshot is - # │ saved for debugging. - OTP="$(oathtool --totp -b "$CERTUM_TOTP_SECRET")" - WIN_ID="$(xdotool search --sync --name 'SimplySign' | head -1 || true)" - echo "SimplySign window id: ${WIN_ID:-}" - if [ -n "${WIN_ID:-}" ]; then - xdotool windowactivate --sync "$WIN_ID" || true - fi - xdotool type --delay 60 "$CERTUM_USERID" - xdotool key Tab - xdotool type --delay 60 "$OTP" - xdotool key Return - sleep 8 - # Some versions show a confirmation dialog that MUST be closed before - # the token is usable — press Enter/Escape/close to be safe. - xdotool key Return || true - # └── end fragile block. Screenshot for debugging failed logins: - import -window root /tmp/ssd-login.png 2>/dev/null || true - - - name: Sign pinready.exe via the cloud token - run: | - set -euxo pipefail - # Expose the authenticated SimplySign token as a p11-kit socket. - mkdir -p /run/p11-kit - p11-kit server --provider "$PKCS11_MODULE" -f 'pkcs11:' >/tmp/p11.log 2>&1 & - sleep 3 - export P11_KIT_SERVER_ADDRESS="$(grep -oE 'unix:path=[^;]+' /tmp/p11.log | head -1)" - echo "P11_KIT_SERVER_ADDRESS=$P11_KIT_SERVER_ADDRESS" - - osslsigncode sign \ - -pkcs11module /usr/lib64/pkcs11/p11-kit-client.so \ - -pkcs11cert 'pkcs11:model=SimplySign%20C' \ - -key 'pkcs11:model=SimplySign%20C' \ - -h sha256 \ - -t http://time.certum.pl/ \ - -n "PinReady" \ - -i "https://github.com/Le-Syl21/PinReady" \ - -in /tmp/dl/pinready.exe \ - -out /tmp/dl/pinready-signed.exe - - - name: Verify the signature - run: | - set -euxo pipefail - osslsigncode verify -in /tmp/dl/pinready-signed.exe - - - name: Upload signed binary - if: always() - uses: actions/upload-artifact@v7 - with: - name: pinready-windows-x86_64-signed - path: | - /tmp/dl/pinready-signed.exe - /tmp/ssd-login.png - if-no-files-found: warn diff --git a/target-bookworm/.rustc_info.json b/target-bookworm/.rustc_info.json new file mode 100644 index 00000000..59163aa4 --- /dev/null +++ b/target-bookworm/.rustc_info.json @@ -0,0 +1 @@ +{"rustc_fingerprint":16876993080210027489,"outputs":{"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/usr/local/rustup/toolchains/1.96.1-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"14077377089280841642":{"success":true,"status":"","code":0,"stdout":"rustc 1.96.1 (31fca3adb 2026-06-26)\nbinary: rustc\ncommit-hash: 31fca3adb283cc9dfd56b49cdee9a96eb9c96ffd\ncommit-date: 2026-06-26\nhost: x86_64-unknown-linux-gnu\nrelease: 1.96.1\nLLVM version: 22.1.2\n","stderr":""}},"successes":{}} \ No newline at end of file diff --git a/target-bookworm/CACHEDIR.TAG b/target-bookworm/CACHEDIR.TAG new file mode 100644 index 00000000..20d7c319 --- /dev/null +++ b/target-bookworm/CACHEDIR.TAG @@ -0,0 +1,3 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by cargo. +# For information about cache directory tags see https://bford.info/cachedir/