diff --git a/.github/workflows/update-windows-info.yml b/.github/workflows/update-windows-info.yml new file mode 100644 index 0000000..55ee542 --- /dev/null +++ b/.github/workflows/update-windows-info.yml @@ -0,0 +1,104 @@ +name: Updates verify-installers.md after desktop release + +on: + repository_dispatch: + types: [desktop-release] + +defaults: + run: + shell: bash + + +jobs: + create-pr: + name: Create PR to update windows signing cert + runs-on: windows-latest + permissions: + contents: write + env: + DESKTOP_VERSION: ${{ github.event.client_payload.version }} + steps: + - name: Checkout repo + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Create new branch + run: | + git config --global --add safe.directory "$GITHUB_WORKSPACE" + if [[ ! "$DESKTOP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z]+)*$ ]]; then + echo "Invalid version in payload: $DESKTOP_VERSION" >&2 + exit 1; + fi + git checkout -b "feature/desktop-${DESKTOP_VERSION}" + - name: Download MSI + run: | + MSI_URL=$(jq -r '[.[] | select(.name | endswith(".msi"))][0].browser_download_url // "null"' <<< "$ASSETS_JSON") + if [[ "$MSI_URL" == "null" || -z "$MSI_URL" ]]; then + echo "No MSI asset found in repository_dispatch payload." >&2 + exit 1 + fi + curl --silent --fail-with-body --proto "=https" -L -H "Accept: application/vnd.github+json" $MSI_URL --output cryptomator.msi + env: + ASSETS_JSON: ${{ toJson(github.event.client_payload.release.assets ) }} + - name: Update verify-installers.md + shell: pwsh + run: | + $Thumbprint = (Get-AuthenticodeSignature -FilePath 'cryptomator.msi' -ErrorAction Stop).SignerCertificate.Thumbprint + + $DocPath = 'docs/security/verify-installers.md' + $Content = Get-Content -Path $DocPath -Raw + + $CurrentThumbprintRegex = [regex] ([regex]::Escape($env:AUTOMATION_MARKER) + '`[A-F0-9]+`') + $UpdatedContent = $CurrentThumbprintRegex.Replace($Content, ($env:AUTOMATION_MARKER + '`' + $Thumbprint + '`'), 1) + if ($UpdatedContent -eq $Content) { + throw 'Failed to update the current Windows thumbprint in verify-installers.md.' + } + $Content = $UpdatedContent + + $MarkedRow = (Get-Content -Path $DocPath | Where-Object { $_.TrimStart().StartsWith('|') -and $_.Contains($env:AUTOMATION_MARKER) } | Select-Object -First 1) + if ($null -eq $MarkedRow) { + throw 'Failed to find the marked Windows certificate table row in verify-installers.md.' + } + + $PreviousRow = $MarkedRow.Substring(0, $MarkedRow.IndexOf($env:AUTOMATION_MARKER)).TrimEnd() + " |" + $NewRow = "| $env:DESKTOP_VERSION |" + '`' + $Thumbprint + '`' + "$env:AUTOMATION_MARKER |" + $Content = $Content.Replace($MarkedRow, $NewRow + "`r`n" + $PreviousRow) + + Set-Content -Path $DocPath -Value $Content + env: + AUTOMATION_MARKER: '' + - name: Commit and push + id: commit-and-push + run: | + git config user.name "cryptobot" + git config user.email "cryptobot@users.noreply.github.com" + git config push.autoSetupRemote true + git stage docs/security/verify-installers.md + if git diff --cached --quiet; then + echo "No changes to commit" + echo "changed=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + git commit -m "Update Windows section for verifying installers for release ${DESKTOP_VERSION}" + git push + echo "changed=true" >> "$GITHUB_OUTPUT" + - name: Create pull request + id: create-pr + if: steps.commit-and-push.outputs.changed == 'true' + run: | + printf "Created by $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" > pr_body.md + PR_URL=$(gh pr create --title "Desktop release ${DESKTOP_VERSION}" --body-file pr_body.md) + echo "url=$PR_URL" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }} + - name: Slack Notification + if: steps.commit-and-push.outputs.changed == 'true' + uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_CRYPTOMATOR_DESKTOP }} + SLACK_USERNAME: 'Cryptobot' + SLACK_ICON: false + SLACK_ICON_EMOJI: ':bot:' + SLACK_CHANNEL: 'cryptomator-desktop' + SLACK_TITLE: "Docs update PR created for release ${{ github.event.client_payload.version }} ." + SLACK_MESSAGE: "See <${{ steps.create-pr.outputs.url }}|PR> on how to proceed." + SLACK_FOOTER: false + MSG_MINIMAL: true diff --git a/docs/security/verify-installers.md b/docs/security/verify-installers.md index 608067c..9bd86d5 100644 --- a/docs/security/verify-installers.md +++ b/docs/security/verify-installers.md @@ -28,24 +28,53 @@ If shown, you can ignore the following warning: ## Windows (exe, msi) {#windows} -Our Windows installers are signed using a code signing certificate. You can verify the signature in five simple steps: +Our Windows installers are signed using a code signing certificate. You can verify the signature in three simple steps: -How to check the code signing certificate on Windows +1. Open Terminal or PowerShell (found in Windows Start menu). +2. Run either of the following commands to check the signature of the corresponding file: + ```pwsh + Get-AuthenticodeSignature -FilePath "~\Downloads\Cryptomator-*.msi" + Get-AuthenticodeSignature -FilePath "~\Downloads\Cryptomator-*.exe" + ``` +3. Verify that the output includes: + - Column `SignerCertificate` with value `20F30D7C5B1AB3ACAFA4AB27874ACBC4B47B0697`(*) + - Column `Status` with value `Valid` + - no errors + +*for older releases, see [below](#windows-all-versions). + +If the installer is properly signed, you should see output similar to: +```text +SignerCertificate Status StatusMessage Path +----------------- ------ ------------- ---- +BB0E... Valid Signature verified. Cryptomator-1.19.1-x64.msi +``` -1. Right-click on the file and click on Properties. +You can also inspect the certificate manually: +1. Right-click on the cryptomator installer file and click on Properties. 2. Select the Digital Signatures tab: It should show one or more signatures by `Skymatic GmbH` under Embedded Signatures. - For releases since 1.18.0, the `exe` release artifact will have two signatures, and the `msi` release artifact will have one signature. 3. Click on the first signature, and then click Details. -4. Click on View Certificates. -5. Click the Details tab. Different Cryptomator versions are signed with different certificates. The following list shows for each version the certificate serial number: - - Version 1.19.2: `33000890b1b9dff7ee6e525b2d0000000890b1` - - Version 1.19.1: `33000852bd6c3a151ff92180ee0000000852bd` - - Version 1.19.0: `3300083c47651e1daeb99b00eb000000083c47` - - Version 1.18.1: `330007d28ad57305892a81cac600000007d28a` - - Version 1.18.0: `3300052c3561155e2baf361702000000052c35` - - Versions 1.6.11 to 1.17.1: `00d77e4f8b938f56ae265cd08e9193490c` - - Versions 1.4.12 to 1.6.10: `63c45bff1a148d60ed2994d3a2639034` - - Versions up to 1.4.11: `1a360f3933964c71f14e8754d94615d4` +4. Click on View Certificates and select the field `Thumbprint`. + +How to check the code signing certificate on Windows + +### Certificate thumbprints for all Cryptomator versions {#windows-all-versions} + +Every Cryptomator installer is signed with a certificate. A certificate is identified by its thumbprint. The signing certificate changed over time and the following table shows for each version the certificate thumbprint: + +| Version(s) | Certificate Thumbprint | +|---------------------|--------------------------------------------| +| 1.19.2 | `20F30D7C5B1AB3ACAFA4AB27874ACBC4B47B0697` | +| 1.19.1 | `BB0EEBF8E92E4584DF4B6AE4F9577B60BEB5DF4C` | +| 1.19.0 | `14524B1F8A3A1CA8B24B769C7C6DC92851120B22` | +| 1.18.1 | `53FA929F6D50D5E2AE59A7C9A9750D373AFF7D40` | +| 1.18.0 | `4DC9A70B94F731562A9C37B4391C4FD5BEC72C94` | +| 1.6.11 to 1.17.1 | `5FC94CE149E5B511E621F53A060AC67CBD446B3A` | +| 1.4.12 to 1.6.10 | `FF52240075AD7D14AF25629FDF69635357C7D14B` | +| up to 1.4.11 | `6FDEC9DFCFE59E6BAEE64B7ED97F00E120E70D97` | + + ## macOS (app) {#macos}