Fix macOS publish bundle signing
This commit is contained in:
@@ -15,8 +15,11 @@ dotnet build clients/apple/VoiceCat.Apple.slnx -c Debug --no-restore
|
||||
|
||||
Use `publish-macos.sh --dry-run` to validate a local ad-hoc macOS bundle. The dry-run build does
|
||||
not enable hardened runtime because ad-hoc signatures have no Team ID and cannot satisfy macOS
|
||||
library validation. Distribution builds remain hardened and require `VOICECAT_CODESIGN_IDENTITY`;
|
||||
optional notarization uses `APPLE_ID`, `APPLE_TEAM_ID`, and `APPLE_APP_PASSWORD`.
|
||||
library validation. The script normalizes nested signatures and installs the verified bundle at
|
||||
both `VoiceCat.Mac/bin/Release/net10.0-macos27.0/osx-arm64/VoiceCat.app` and
|
||||
`VoiceCat.Mac/bin/Release/distribution/VoiceCat.app`. Distribution builds remain hardened and
|
||||
require `VOICECAT_CODESIGN_IDENTITY`; optional notarization uses `APPLE_ID`, `APPLE_TEAM_ID`, and
|
||||
`APPLE_APP_PASSWORD`.
|
||||
|
||||
For a physical iOS device, use `build-ios-device.sh` and `deploy-ios-device.sh`. The host and
|
||||
ReplayKit extension require signing profiles with App Group `group.me.iamtalon.voicecat`.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0"><dict>
|
||||
<key>com.apple.security.app-sandbox</key><true/>
|
||||
<key>com.apple.security.cs.allow-jit</key><true/>
|
||||
<key>com.apple.security.network.client</key><true/>
|
||||
<key>com.apple.security.device.audio-input</key><true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key><true/>
|
||||
|
||||
@@ -45,11 +45,39 @@ fi
|
||||
mkdir -p "$distribution"
|
||||
ditto "$built_app" "$app"
|
||||
|
||||
entitlements="$script_dir/VoiceCat.Mac/VoiceCat.Mac.entitlements"
|
||||
|
||||
sign_nested_code() {
|
||||
local identity=$1
|
||||
local timestamp_option=${2:-}
|
||||
local runtime_option=${3:-}
|
||||
local nested
|
||||
local sign_options=(--force)
|
||||
|
||||
[[ -n "$timestamp_option" ]] && sign_options+=("$timestamp_option")
|
||||
[[ -n "$runtime_option" ]] && sign_options+=("$runtime_option")
|
||||
|
||||
# Do not use codesign --deep for signing. It is intended as an emergency repair operation
|
||||
# and can apply the app's entitlements to nested code. Sign each bundled Mach-O library first,
|
||||
# then sign the outer app once with its own entitlements.
|
||||
while IFS= read -r -d '' nested; do
|
||||
codesign "${sign_options[@]}" --sign "$identity" "$nested"
|
||||
done < <(find "$app/Contents" -type f \( -name '*.dylib' -o -name '*.so' \) -print0)
|
||||
}
|
||||
|
||||
install_verified_primary_bundle() {
|
||||
# dotnet publish must create the workload bundle before it can be normalized. Replace that
|
||||
# misleading intermediate with the verified result so both documented output paths work.
|
||||
rm -rf "$built_app"
|
||||
ditto "$app" "$built_app"
|
||||
}
|
||||
|
||||
if (( dry_run )); then
|
||||
# Normalize the workload's mixed nested signatures after bundling.
|
||||
codesign --force --deep --sign - "$app"
|
||||
sign_nested_code -
|
||||
codesign --force --entitlements "$entitlements" --sign - "$app"
|
||||
codesign --verify --deep --strict "$app"
|
||||
spctl --assess --type execute "$app" 2>/dev/null || true
|
||||
install_verified_primary_bundle
|
||||
print "Validated ad-hoc build: $app"
|
||||
exit 0
|
||||
fi
|
||||
@@ -60,10 +88,12 @@ if [[ -z "$identity" ]]; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
codesign --force --deep --timestamp --options runtime \
|
||||
--entitlements "$script_dir/VoiceCat.Mac/VoiceCat.Mac.entitlements" \
|
||||
sign_nested_code "$identity" --timestamp --options=runtime
|
||||
codesign --force --timestamp --options runtime \
|
||||
--entitlements "$entitlements" \
|
||||
--sign "$identity" "$app"
|
||||
codesign --verify --deep --strict --verbose=2 "$app"
|
||||
install_verified_primary_bundle
|
||||
|
||||
archive="$distribution/VoiceCat-macOS-arm64.zip"
|
||||
ditto -c -k --keepParent "$app" "$archive"
|
||||
|
||||
@@ -24,6 +24,21 @@ public class PublishServerScriptTests
|
||||
Assert.Contains("(?:bin|obj)", script);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MacPublishPreservesAppEntitlementsAndReplacesBrokenWorkloadBundle()
|
||||
{
|
||||
string root = FindRoot();
|
||||
string script = await File.ReadAllTextAsync(Path.Combine(root, "clients", "apple", "publish-macos.sh"));
|
||||
string entitlements = await File.ReadAllTextAsync(Path.Combine(
|
||||
root, "clients", "apple", "VoiceCat.Mac", "VoiceCat.Mac.entitlements"));
|
||||
|
||||
Assert.Contains("sign_nested_code", script);
|
||||
Assert.Contains("--entitlements \"$entitlements\"", script);
|
||||
Assert.Contains("install_verified_primary_bundle", script);
|
||||
Assert.DoesNotContain("codesign --force --deep", script);
|
||||
Assert.Contains("com.apple.security.cs.allow-jit", entitlements);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DefaultPublishTargetsWindowsAndLinuxWhileRuntimeCanSelectOne()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user