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
97 changes: 88 additions & 9 deletions scripts/bundle-engine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,18 @@ have_developer_id() {
# engine that boots nowhere. Ad-hoc is only allowed on a dev machine with no Developer ID identity, or
# explicitly via DORY_ALLOW_ADHOC_SIGN=1. Transient timestamp/keychain hiccups are retried first.
codesign_helper() {
local path="$1" entitlements="${2:-}" id="${DORY_SIGN_ID:-Developer ID Application}"
local path="$1" entitlements="${2:-}" requirement="${3:-}"
local adhoc_requirement="${4:-$requirement}" id="${5:-${DORY_SIGN_ID:-Developer ID Application}}"
local base=(--force --options runtime --timestamp)
[ -n "$entitlements" ] && base+=(--entitlements "$entitlements")
[ -n "$requirement" ] && base+=(--requirements "=designated => $requirement")

if [ "$id" = "-" ]; then
codesign "${base[@]}" -s - "$path"
local adhoc_base=(--force --options runtime)
[ -n "$entitlements" ] && adhoc_base+=(--entitlements "$entitlements")
[ -n "$adhoc_requirement" ] \
&& adhoc_base+=(--requirements "=designated => $adhoc_requirement")
codesign "${adhoc_base[@]}" -s - "$path"
return
fi

Expand All @@ -155,7 +161,11 @@ codesign_helper() {
rm -f "$err"
if [ "${DORY_ALLOW_ADHOC_SIGN:-0}" = "1" ] || ! have_developer_id; then
echo " WARNING: ad-hoc signing $(basename "$path") — NOT distributable and its entitlements will be denied at launch." >&2
codesign --force ${entitlements:+--entitlements "$entitlements"} -s - "$path"
local adhoc_base=(--force --options runtime)
[ -n "$entitlements" ] && adhoc_base+=(--entitlements "$entitlements")
[ -n "$adhoc_requirement" ] \
&& adhoc_base+=(--requirements "=designated => $adhoc_requirement")
codesign "${adhoc_base[@]}" -s - "$path"
return
fi
echo " A Developer ID identity is present but signing failed; refusing to ship an ad-hoc helper. Set DORY_ALLOW_ADHOC_SIGN=1 only for a throwaway local build." >&2
Expand Down Expand Up @@ -187,6 +197,77 @@ sign_runtime_payload_with_entitlements() {
codesign_helper "$1" "$2"
}

developer_id_designated_requirement() {
local identifier="$1" expected_team="${DORY_RENDERER_EXPECTED_TEAM:-864H636QW4}"
printf '%s\n' \
"identifier \"$identifier\" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = \"$expected_team\""
}

test_designated_requirement() {
printf 'identifier "%s"\n' "$1"
}

read_designated_requirement() {
local payload="$1" evidence
evidence="$(codesign -d -r- "$payload" 2>&1)" \
|| { echo " ERROR: could not read the designated requirement for $(basename "$payload")" >&2; return 1; }
printf '%s\n' "$evidence" | sed -n 's/^designated => //p' | tail -1
}

verify_designated_requirement() {
local payload="$1" expected="$2" label="$3" actual
actual="$(read_designated_requirement "$payload")" || return 1
[ "$actual" = "$expected" ] \
|| { echo " ERROR: $label designated requirement is not canonical" >&2; return 1; }
codesign --verify --strict "-R=$expected" "$payload" >/dev/null \
|| { echo " ERROR: $label does not satisfy its canonical designated requirement" >&2; return 1; }
}

# Xcode 26 emits a valid Developer ID signature with an Apple Development compatibility branch in
# the designated requirement. That requirement is intentionally broader than the exact Developer ID
# identity recorded by the optional-component inventory. Normalize only the Xcode-owned filesystem
# worker and its enclosing runner, inside-out, before doryd records any runner/worker Code Directory
# hashes. The qualified renderer worker and its signed inventory are never mutated here.
canonicalize_xcode_runner_signatures() {
local sign_id="${DORY_SIGN_ID:-Developer ID Application}"
local expected_team="${DORY_RENDERER_EXPECTED_TEAM:-864H636QW4}"
local fs_identifier=com.pythonxi.Dory.HVRunner.FSWorker
local runner_identifier=com.pythonxi.Dory.HVRunner
local fs_requirement runner_requirement fs_test_requirement runner_test_requirement

fs_test_requirement="$(test_designated_requirement "$fs_identifier")"
runner_test_requirement="$(test_designated_requirement "$runner_identifier")"
if [ "$sign_id" = - ]; then
fs_requirement="$fs_test_requirement"
runner_requirement="$runner_test_requirement"
else
[ "$expected_team" = 864H636QW4 ] \
|| { echo " ERROR: canonical runner signing requires Dory team 864H636QW4" >&2; return 1; }
fs_requirement="$(developer_id_designated_requirement "$fs_identifier")"
runner_requirement="$(developer_id_designated_requirement "$runner_identifier")"
fi

echo "==> Canonicalizing the Xcode runner signature graph before release identity binding…"
codesign_helper \
"$FS_WORKER_XPC" \
"$REPO_ROOT/Packages/ContainerizationEngine/DoryFSWorker.entitlements" \
"$fs_requirement" \
"$fs_test_requirement" \
"$sign_id"
codesign_helper \
"$HV_RUNNER_APP" \
"$REPO_ROOT/Packages/ContainerizationEngine/dory-hv.entitlements" \
"$runner_requirement" \
"$runner_test_requirement" \
"$sign_id"

verify_designated_requirement "$FS_WORKER_XPC" "$fs_requirement" 'filesystem worker'
verify_designated_requirement "$HV_RUNNER_APP" "$runner_requirement" 'Hypervisor.framework runner'
codesign --verify --strict --verbose=2 "$RENDERER_WORKER_XPC"
codesign --verify --deep --strict --verbose=2 "$HV_RUNNER_APP"
echo " canonicalized filesystem worker + runner; renderer worker bytes remain qualified"
}

normalize_darwin_arch() {
case "$1" in
arm64|aarch64) printf '%s\n' "arm64" ;;
Expand Down Expand Up @@ -726,12 +807,10 @@ macho_has_arches "$FS_WORKER_EXECUTABLE" "$(swiftpm_helper_arches)" \
|| { echo " ERROR: filesystem worker does not contain every requested helper architecture" >&2; exit 1; }
macho_has_arches "$RENDERER_WORKER_EXECUTABLE" "$(swiftpm_helper_arches)" \
|| { echo " ERROR: renderer worker does not contain every requested helper architecture" >&2; exit 1; }
# Xcode owns this nested signature graph. Mutating or repairing it here would split packaging
# authority from the Release target and make the archived candidate differ from its renderer
# inventory. The final outer Dory.app is signed later after bundle-engine adds outer helpers.
codesign --verify --strict --verbose=2 "$FS_WORKER_XPC"
codesign --verify --strict --verbose=2 "$RENDERER_WORKER_XPC"
codesign --verify --deep --strict --verbose=2 "$HV_RUNNER_APP"
# Xcode owns the qualified renderer worker and its inventory. Release assembly owns the exact outer
# requirement policy consumed by component verification, so normalize those enclosing signatures
# now, before renderer release identity and doryd bind this graph. The final Dory.app is signed later.
canonicalize_xcode_runner_signatures

echo "==> Bundling gvproxy (userspace networking for the dory-hv engine)…"
# gvproxy (gvisor-tap-vsock, Apache-2.0) gives the HV engine NAT/DNS with no restricted
Expand Down
29 changes: 29 additions & 0 deletions scripts/test-build-components.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,35 @@ assert 'echo "xcodebuild_exit=$xcodebuild_status"' in text
assert 'echo "build_exit=$status"' in text
PY

python3 - "$ROOT/scripts/bundle-engine.sh" <<'PY'
import pathlib
import re
import sys

text = pathlib.Path(sys.argv[1]).read_text(encoding="utf-8")

def function_body(name):
match = re.search(rf"^{re.escape(name)}\(\) \{{\n(.*?)^\}}$", text, re.M | re.S)
assert match is not None, f"missing bundle-engine function: {name}"
return match.group(1)

signer = function_body("codesign_helper")
assert '--requirements "=designated => $requirement"' in signer
assert '--requirements "=designated => $adhoc_requirement"' in signer
canonicalizer = function_body("canonicalize_xcode_runner_signatures")
assert "DORY_RENDERER_EXPECTED_TEAM:-864H636QW4" in canonicalizer
assert "[ \"$expected_team\" = 864H636QW4 ]" in canonicalizer
assert 'Packages/ContainerizationEngine/DoryFSWorker.entitlements' in canonicalizer
assert 'Packages/ContainerizationEngine/dory-hv.entitlements' in canonicalizer
assert canonicalizer.index('"$FS_WORKER_XPC"') < canonicalizer.index('"$HV_RUNNER_APP"')
assert 'codesign_helper \\\n+ "$RENDERER_WORKER_XPC"' not in canonicalizer
assert 'codesign --verify --strict --verbose=2 "$RENDERER_WORKER_XPC"' in canonicalizer
assert 'codesign --verify --deep --strict --verbose=2 "$HV_RUNNER_APP"' in canonicalizer
packaging = text[text.index('echo "==> Verifying the Xcode-sealed Hypervisor.framework runner application'):]
assert packaging.index("canonicalize_xcode_runner_signatures") < packaging.index("bundle_venus_renderer")
assert packaging.index("canonicalize_xcode_runner_signatures") < packaging.index("finalize_doryd_signature")
PY

if ! (
export DORY_RELEASE_SOURCE_ONLY=1
export DORY_PUBLIC_RELEASE=0
Expand Down
Loading