Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/desktop-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,6 @@ jobs:
cat desktop-windows-artifacts.sha256

- name: Attest Windows release artifacts
# Keep uploads/verifiers running if GitHub token policy rejects artifact attestation.
continue-on-error: true
uses: actions/attest@281a49d4cbb0a72c9575a50d18f6deb515a11deb # was v4
with:
subject-checksums: desktop-windows-artifacts.sha256
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,6 @@ jobs:
cat windows-release-artifacts.sha256

- name: Attest Windows release artifacts
# Keep release uploads running if GitHub token policy rejects artifact attestation.
continue-on-error: true
uses: actions/attest@281a49d4cbb0a72c9575a50d18f6deb515a11deb # was v4
with:
subject-checksums: windows-release-artifacts.sha256
Expand Down
4 changes: 2 additions & 2 deletions scripts/ci/_common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3670,9 +3670,9 @@ verify_windows_authenticode_signatures() {
$issuer = $signature.SignerCertificate.Issuer
}
if ($subject -ne $expectedSubject) {
throw "Authenticode signer subject mismatch for $file. Expected=$expectedSubject Actual=$subject Issuer=$issuer"
throw "Authenticode signer subject mismatch for $file. Actual=$subject Issuer=$issuer"
}
Write-Host ("verified-windows-authenticode {0} subject={1} issuer={2}" -f $file, $subject, $issuer)
Write-Host ("verified-windows-authenticode {0} thumbprint={1}" -f $file, $signature.SignerCertificate.Thumbprint)
}
' "${ps_args[@]}"
}
Expand Down
10 changes: 10 additions & 0 deletions scripts/ci/attestation-manifest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,14 @@ if [ "${#proof_files[@]}" -gt 0 ]; then
done >> "${out}"
fi

# actions/attest@v4 splits checksum files on the runner platform EOL.
# Windows runners need CRLF here even when Git Bash generated the file.
case "$(host_os)" in
mingw* | msys* | cygwin*)
tmp="$(mktemp)"
awk '{ sub(/\r$/, ""); printf "%s\r\n", $0 }' "${out}" > "${tmp}"
mv "${tmp}" "${out}"
;;
esac

cat "${out}"
61 changes: 60 additions & 1 deletion scripts/ci/verify-release-artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,65 @@ verify_file_manifest() {
done < "${manifest}"
}

verify_windows_runtime_manifest() {
local manifest="$1"
local digest label path expected_path
local count=0
local expected_paths=(
"frontend/src-tauri/resources/windows/MSVCP140.dll"
"frontend/src-tauri/resources/windows/MSVCP140_1.dll"
"frontend/src-tauri/resources/windows/onnxruntime.dll"
"frontend/src-tauri/resources/windows/VCRUNTIME140.dll"
"frontend/src-tauri/resources/windows/VCRUNTIME140_1.dll"
)
declare -A seen=()

for expected_path in "${expected_paths[@]}"; do
seen["${expected_path}"]=0
done

while read -r digest label _; do
[ -n "${digest:-}" ] || continue

if ! [[ "${digest}" =~ ^[0-9a-fA-F]{64}$ ]]; then
echo "Invalid Windows runtime manifest line in ${manifest}: ${digest} ${label:-}" >&2
return 1
fi

if [ -z "${label:-}" ]; then
echo "Missing Windows runtime manifest label in ${manifest}." >&2
return 1
fi

path="$(manifest_label_path "${label}")"
if [ -z "${seen[${path}]+x}" ]; then
echo "Unexpected Windows runtime DLL proof in ${manifest}: ${path}" >&2
return 1
fi

if [ "${seen[${path}]}" = "1" ]; then
echo "Duplicate Windows runtime DLL proof in ${manifest}: ${path}" >&2
return 1
fi

seen["${path}"]=1
count=$((count + 1))
printf 'verified-windows-runtime-dll-proof %s %s\n' "${digest}" "${label}"
done < "${manifest}"

for expected_path in "${expected_paths[@]}"; do
if [ "${seen[${expected_path}]}" != "1" ]; then
echo "Missing Windows runtime DLL proof in ${manifest}: ${expected_path}" >&2
return 1
fi
done

if [ "${count}" -ne "${#expected_paths[@]}" ]; then
echo "Unexpected Windows runtime DLL proof count in ${manifest}: ${count}" >&2
return 1
fi
}
Comment on lines +128 to +185

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Runtime manifest verification no longer checks actual file hashes

The old code called verify_file_manifest on the runtime DLLs manifest (verify-release-artifacts.sh:432), which attempts to locate each referenced artifact file and verify its SHA256 hash. The new verify_windows_runtime_manifest function (verify-release-artifacts.sh:128-195) only validates the manifest structure — correct hash format, expected DLL names, no duplicates, all expected DLLs present — but never verifies the hash values against actual files. This is likely intentional because the DLL files (MSVCP140.dll, VCRUNTIME140.dll, etc.) are not uploaded as artifacts; only the manifest .sha256 proof file is uploaded. The old verify_file_manifest would have failed when artifact_for_label at verify-release-artifacts.sh:115 tried to find these DLLs in the downloaded artifacts directory. This raises the question of whether the old path was ever exercised successfully in production, or whether the runtime manifest was always absent/empty in practice prior to this change.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


verify_proof_file_hash() {
local manifest="$1"
local digest label file actual
Expand Down Expand Up @@ -360,7 +419,7 @@ verify_windows() {

verify_file_manifest "${final_manifest}"
if [ -n "${runtime_manifest}" ]; then
verify_file_manifest "${runtime_manifest}"
verify_windows_runtime_manifest "${runtime_manifest}"
fi
verify_tauri_signatures_in_artifacts
}
Expand Down
Loading