diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 2fc4334..361d66e 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -24,7 +24,7 @@ jobs: shell: bash run: | set -euo pipefail - version="0.1.2" + version="0.1.3" dotnet publish src/MrTrustLauncher.csproj \ --configuration Release \ --runtime win-x64 \ @@ -38,7 +38,7 @@ jobs: shell: bash run: | set -euo pipefail - version="0.1.2" + version="0.1.3" package_root="dist/MrTrust-${version}" rm -rf "$package_root" "dist/MrTrust-${version}.zip" mkdir -p "$package_root" @@ -54,8 +54,8 @@ jobs: - name: Upload release artifact uses: actions/upload-artifact@v3 with: - name: MrTrust-0.1.2 - path: dist/MrTrust-0.1.2.zip + name: MrTrust-0.1.3 + path: dist/MrTrust-0.1.3.zip - name: Attach ZIP to Gitea release if: github.ref == 'refs/heads/main' @@ -64,9 +64,35 @@ jobs: GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail - version="0.1.2" + version="0.1.3" api="https://git.wilkensxl.de/api/v1/repos/MrSphay/MrTrust" - release_json="$(curl -fsS -H "Authorization: token ${GITEA_TOKEN}" "${api}/releases/tags/v${version}")" + release_response="$(mktemp)" + status="$(curl -sS -o "$release_response" -w "%{http_code}" -H "Authorization: token ${GITEA_TOKEN}" "${api}/releases/tags/v${version}")" + if [ "$status" = "404" ]; then + release_json="$(python3 - < "$release_response" + elif [ "$status" != "200" ]; then + cat "$release_response" >&2 + exit 1 + fi + release_json="$(cat "$release_response")" release_id="$(printf '%s' "$release_json" | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')" if [ -z "$release_id" ]; then echo "Could not resolve release id for v${version}" >&2 diff --git a/CHANGELOG.md b/CHANGELOG.md index e46d950..6572a20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.1.3 + +- Added Ubuntu-runner signing support through `osslsigncode` and PFX secrets. + ## 0.1.2 - Made `MrTrust.exe` a standalone user-facing release artifact. diff --git a/README.md b/README.md index 988a04a..b75786a 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ MrTrust does not bypass Microsoft Defender or SmartScreen. Windows can still sca - `scripts/Install-MrTrust.ps1` installs the public trust certificate for the current user or the local machine. - `scripts/Uninstall-MrTrust.ps1` removes the MrTrust certificate again. - `scripts/Sign-MrTrustProject.ps1` signs `.exe`, `.msi`, `.ps1`, and other Authenticode-compatible files. +- `scripts/Sign-MrTrustProjectLinux.sh` signs Windows PE/MSI/CAT artifacts on Ubuntu Gitea runners with `osslsigncode`. - `scripts/New-MrTrustRelease.ps1` builds a distributable ZIP package. - `docs/integration-prompt.md` is a prompt you can paste into other Windows projects. - `docs/agent-target-integration.md` is the autonomous target-project integration runbook for agents. @@ -69,7 +70,7 @@ Remove the trust certificate: Build a user-facing ZIP release: ```powershell -.\scripts\New-MrTrustRelease.ps1 -Version 0.1.2 +.\scripts\New-MrTrustRelease.ps1 -Version 0.1.3 ``` The Gitea workflow `.gitea/workflows/build.yml` builds the Windows launcher EXE on an `ubuntu-latest` runner with .NET Windows cross-targeting, then uploads the ZIP as an artifact. diff --git a/docs/agent-target-integration.md b/docs/agent-target-integration.md index 2b164a8..174e068 100644 --- a/docs/agent-target-integration.md +++ b/docs/agent-target-integration.md @@ -43,6 +43,8 @@ Apply every item that fits the target project: - Use the public thumbprint from `mrtrust.integration.json`. - Only run signing where private signing material is securely available. - Do not commit `.pfx`, private keys, passwords, tokens, or signing secrets. + - On the available `ubuntu-latest` Gitea runners, use `osslsigncode` with PFX secrets for `.exe`, `.dll`, `.msi`, and `.cat`. + - PowerShell script signing (`.ps1`, `.psm1`, `.psd1`) still requires a Windows signing environment. If no Windows runner exists, document that limitation instead of blocking PE/MSI signing. 4. Add verification. - Verify the target project still builds. @@ -76,6 +78,12 @@ Check a signature: Get-AuthenticodeSignature .\dist\App.exe | Format-List Status,SignerCertificate,StatusMessage ``` +Sign a release directory on an Ubuntu Gitea runner: + +```bash +bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh ./dist +``` + ## Installer Patterns ### Inno Setup @@ -118,6 +126,45 @@ Document that users should run it once before launching signed MrSphay apps if W ## CI Signing Patterns +### Gitea Actions On Ubuntu Runner + +Use this when only `ubuntu-latest`, `ubuntu-24.04`, or `ubuntu-22.04` runners are available. + +Required Gitea secrets: + +```text +MRTRUST_CODESIGN_PFX_BASE64 +MRTRUST_CODESIGN_PFX_PASSWORD +``` + +Create `MRTRUST_CODESIGN_PFX_BASE64` locally from the private `.pfx`: + +```powershell +[Convert]::ToBase64String([IO.File]::ReadAllBytes(".\private\MrSphay-CodeSigning.pfx")) | Set-Clipboard +``` + +Then paste the clipboard value into the Gitea secret. Do not commit the `.pfx` or the base64 value. + +Ubuntu workflow step: + +```yaml +- name: Install signing tool + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y osslsigncode + +- name: Sign Windows artifacts + shell: bash + env: + MRTRUST_CODESIGN_PFX_BASE64: ${{ secrets.MRTRUST_CODESIGN_PFX_BASE64 }} + MRTRUST_CODESIGN_PFX_PASSWORD: ${{ secrets.MRTRUST_CODESIGN_PFX_PASSWORD }} + run: | + bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh ./dist +``` + +This signs `.exe`, `.dll`, `.msi`, and `.cat` artifacts. It does not sign PowerShell script files. + ### Gitea Actions On Windows Runner ```yaml diff --git a/docs/integration-prompt.md b/docs/integration-prompt.md index 670dd62..710ccd4 100644 --- a/docs/integration-prompt.md +++ b/docs/integration-prompt.md @@ -32,10 +32,12 @@ Implementation requirements: - Only offer LocalMachine installation when the user explicitly chooses an all-users install and the process is elevated. - Add an uninstall path or documentation that opens MrTrust again and tells the user to choose "Remove trust". - Keep the UI wording clear: the user is trusting MrSphay signed software, not bypassing Windows security. -- If this project produces an .exe, .msi, .dll, .ps1, .psm1, .psd1, or .cat release artifact, sign it with: - .\MrTrust\MrTrust.exe sign -Path -CertificateThumbprint A024A89200469F099EC4A172B4F96F6428AFD41B +- If this project produces an .exe, .msi, .dll, or .cat release artifact on an Ubuntu Gitea runner, sign it with: + bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh - Treat the certificate thumbprint as public metadata, but never commit private signing material. -- If the target project needs automated signing, call MrTrust's signing script from CI or a secure local release machine where the private certificate is already installed or supplied through secrets. Do not put private signing material into the target repository or user-facing release ZIP. +- Configure Gitea secrets `MRTRUST_CODESIGN_PFX_BASE64` and `MRTRUST_CODESIGN_PFX_PASSWORD` for Ubuntu runner signing. +- If the target project needs .ps1, .psm1, or .psd1 signing, use a Windows signing environment or document that script signing is not available on the current Ubuntu-only runners. +- Do not put private signing material into the target repository or user-facing release ZIP. Verification: - Confirm the target project's user-facing release contains either a link to the MrTrust release ZIP or a bundled copy of `MrTrust.exe`. diff --git a/mrtrust.integration.json b/mrtrust.integration.json index ee03f86..15e02d9 100644 --- a/mrtrust.integration.json +++ b/mrtrust.integration.json @@ -29,8 +29,35 @@ ".psd1", ".cat" ], - "preferredCommand": ".\\MrTrust\\MrTrust.exe sign -Path -CertificateThumbprint A024A89200469F099EC4A172B4F96F6428AFD41B", - "ciGuidance": "Run signing only on a trusted Windows release runner or secure local release machine where the private certificate is already installed or supplied through secrets.", + "ubuntuRunner": { + "supportedExtensions": [ + ".exe", + ".msi", + ".dll", + ".cat" + ], + "requiredTool": "osslsigncode", + "helperScript": "scripts/Sign-MrTrustProjectLinux.sh", + "requiredSecrets": [ + "MRTRUST_CODESIGN_PFX_BASE64", + "MRTRUST_CODESIGN_PFX_PASSWORD" + ], + "preferredCommand": "bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh " + }, + "windowsRunner": { + "supportedExtensions": [ + ".exe", + ".msi", + ".dll", + ".ps1", + ".psm1", + ".psd1", + ".cat" + ], + "preferredCommand": ".\\MrTrust\\MrTrust.exe sign -Path -CertificateThumbprint A024A89200469F099EC4A172B4F96F6428AFD41B" + }, + "preferredCommand": "bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh ", + "ciGuidance": "On ubuntu-latest runners, sign PE/MSI/CAT artifacts with osslsigncode using a PFX stored in Gitea secrets. Use Windows runners only when signing PowerShell scripts or when Windows certificate store signing is required.", "unsignedBehavior": "Unsigned builds should remain unsigned. MrTrust only makes correctly signed MrSphay artifacts validate after the user has installed trust." }, "targetProjectAgentContract": { diff --git a/scripts/Build-MrTrustExe.ps1 b/scripts/Build-MrTrustExe.ps1 index 380e46a..334de1e 100644 --- a/scripts/Build-MrTrustExe.ps1 +++ b/scripts/Build-MrTrustExe.ps1 @@ -24,6 +24,7 @@ $payloadFiles = @( @{ Path = "scripts\New-MrTrustIcon.ps1"; ResourceName = "MrTrust.Payload.scripts.New-MrTrustIcon.ps1" }, @{ Path = "scripts\New-MrTrustRelease.ps1"; ResourceName = "MrTrust.Payload.scripts.New-MrTrustRelease.ps1" }, @{ Path = "scripts\Sign-MrTrustProject.ps1"; ResourceName = "MrTrust.Payload.scripts.Sign-MrTrustProject.ps1" }, + @{ Path = "scripts\Sign-MrTrustProjectLinux.sh"; ResourceName = "MrTrust.Payload.scripts.Sign-MrTrustProjectLinux.sh" }, @{ Path = "scripts\Start-MrTrustGui.ps1"; ResourceName = "MrTrust.Payload.scripts.Start-MrTrustGui.ps1" }, @{ Path = "scripts\Uninstall-MrTrust.ps1"; ResourceName = "MrTrust.Payload.scripts.Uninstall-MrTrust.ps1" }, @{ Path = "assets\MrTrust.ico"; ResourceName = "MrTrust.Payload.assets.MrTrust.ico" }, diff --git a/src/MrTrustLauncher.cs b/src/MrTrustLauncher.cs index f325fc2..5be5dcd 100644 --- a/src/MrTrustLauncher.cs +++ b/src/MrTrustLauncher.cs @@ -23,6 +23,7 @@ namespace MrTrust new PayloadFile("scripts.New-MrTrustIcon.ps1", Path.Combine("scripts", "New-MrTrustIcon.ps1")), new PayloadFile("scripts.New-MrTrustRelease.ps1", Path.Combine("scripts", "New-MrTrustRelease.ps1")), new PayloadFile("scripts.Sign-MrTrustProject.ps1", Path.Combine("scripts", "Sign-MrTrustProject.ps1")), + new PayloadFile("scripts.Sign-MrTrustProjectLinux.sh", Path.Combine("scripts", "Sign-MrTrustProjectLinux.sh")), new PayloadFile("scripts.Start-MrTrustGui.ps1", Path.Combine("scripts", "Start-MrTrustGui.ps1")), new PayloadFile("scripts.Uninstall-MrTrust.ps1", Path.Combine("scripts", "Uninstall-MrTrust.ps1")), new PayloadFile("assets.MrTrust.ico", Path.Combine("assets", "MrTrust.ico")), diff --git a/src/MrTrustLauncher.csproj b/src/MrTrustLauncher.csproj index 6e0d021..1db12a6 100644 --- a/src/MrTrustLauncher.csproj +++ b/src/MrTrustLauncher.csproj @@ -21,6 +21,7 @@ +