From 846822e1569f600510be5865ee5e61952fd67a62 Mon Sep 17 00:00:00 2001 From: Bane Stojkovic Date: Fri, 16 Oct 2026 20:28:15 +0200 Subject: [PATCH] signpath --- .github/workflows/sign-windows.yml | 12 +++++- .../deploy/win/signpath/is-signed.py | 39 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 diylc/diylc-swing/deploy/win/signpath/is-signed.py diff --git a/.github/workflows/sign-windows.yml b/.github/workflows/sign-windows.yml index 85463547..5d7bc51f 100644 --- a/.github/workflows/sign-windows.yml +++ b/.github/workflows/sign-windows.yml @@ -17,7 +17,8 @@ on: - release-signing permissions: - actions: read + # write is needed only to delete the unsigned installer once SignPath has fetched it + actions: write contents: read env: @@ -101,6 +102,15 @@ jobs: wait-for-completion: true output-artifact-directory: signed + # SignPath can only fetch the installer from a GitHub artifact, so the unsigned upload cannot + # be skipped; it is deleted as soon as signing is over, whether or not signing succeeded. + - name: Delete unsigned installer artifact + if: always() && steps.upload-unsigned-installer.outputs.artifact-id != '' + env: + GH_TOKEN: ${{ github.token }} + ARTIFACT_ID: ${{ steps.upload-unsigned-installer.outputs.artifact-id }} + run: gh api -X DELETE "repos/${GITHUB_REPOSITORY}/actions/artifacts/${ARTIFACT_ID}" + - name: Verify signed installer run: | python3 diylc/diylc-swing/deploy/win/signpath/is-signed.py signed/diylc-setup.exe diff --git a/diylc/diylc-swing/deploy/win/signpath/is-signed.py b/diylc/diylc-swing/deploy/win/signpath/is-signed.py new file mode 100644 index 00000000..44248ff2 --- /dev/null +++ b/diylc/diylc-swing/deploy/win/signpath/is-signed.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +"""Exits 0 if the given PE file carries an Authenticode signature, 1 if it does not. + +`osslsigncode verify` also fails on an untrusted chain, which is the normal result for the +SignPath test certificate, so it cannot answer this question on its own. This reads the PE +Certificate Table data directory instead, which says whether a signature is present without +making any claim about its validity. +""" + +import struct +import sys + + +def has_signature(path): + with open(path, "rb") as f: + data = f.read() + + pe = struct.unpack_from(" 0 + + +if __name__ == "__main__": + signed = has_signature(sys.argv[1]) + print("signed" if signed else "unsigned") + sys.exit(0 if signed else 1)