|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# Sign Windows files using the ESRP client (Authenticode). |
| 4 | +# Usage: esrpsign.sh <file1> [file2 ...] |
| 5 | +# |
| 6 | +# Required environment variables: |
| 7 | +# ESRP_TOOL - Path to ESRPClient.exe |
| 8 | +# ESRP_AUTH - Path to the ESRP auth JSON file |
| 9 | +# SYSTEM_ACCESSTOKEN - ADO system access token (OAuth bearer) |
| 10 | +# |
| 11 | +# Optional environment variables: |
| 12 | +# ESRP_KEYCODE - Signing key code (default: CP-231522) |
| 13 | +# |
| 14 | +# The script generates the auth and input JSON files and sets the |
| 15 | +# following ESRP client environment variables automatically: |
| 16 | +# ESRP_AUTH_CONFIG - Path to the auth JSON file |
| 17 | +# ESRP_POLICY_CONFIG - Path to the policy JSON file |
| 18 | +# ESRP_SESSION_CONFIG - Not set; ESRP client defaults are used |
| 19 | +# |
| 20 | +set -euo pipefail |
| 21 | + |
| 22 | +if [ $# -lt 1 ]; then |
| 23 | + echo "usage: esrpsign.sh <file> [file ...]" >&2 |
| 24 | + exit 1 |
| 25 | +fi |
| 26 | + |
| 27 | +if [ -z "${ESRP_TOOL:-}" ]; then |
| 28 | + echo "error: ESRP_TOOL environment variable must be set" >&2 |
| 29 | + exit 1 |
| 30 | +fi |
| 31 | +if [ -z "${ESRP_AUTH:-}" ]; then |
| 32 | + echo "error: ESRP_AUTH environment variable must be set" >&2 |
| 33 | + exit 1 |
| 34 | +fi |
| 35 | +if [ -z "${SYSTEM_ACCESSTOKEN:-}" ]; then |
| 36 | + echo "error: SYSTEM_ACCESSTOKEN environment variable must be set" >&2 |
| 37 | + exit 1 |
| 38 | +fi |
| 39 | + |
| 40 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 41 | +. "$SCRIPT_DIR/../../scripts/windows/utils.sh" |
| 42 | + |
| 43 | +# Check for overriden key code, otherwise use default (Microsoft Third-Party/OSS) |
| 44 | +ESRP_KEYCODE="${ESRP_KEYCODE:-CP-231522}" |
| 45 | + |
| 46 | +# Create work dir and resolve its Windows path by cd-ing into it. |
| 47 | +WORK_DIR="$(mktemp -d)" |
| 48 | +WORK_DIR_WIN="$(cd "$WORK_DIR" && pwd -W | sed 's|/|\\|g')" |
| 49 | + |
| 50 | +echo "==> ESRP signing tool: $ESRP_TOOL" |
| 51 | +echo "==> Working directory: $WORK_DIR" |
| 52 | + |
| 53 | +if [ ! -f "$ESRP_TOOL" ]; then |
| 54 | + echo "error: ESRPClient.exe not found at $ESRP_TOOL" >&2 |
| 55 | + exit 1 |
| 56 | +fi |
| 57 | + |
| 58 | +# Build the SignRequestFiles JSON array |
| 59 | +echo "==> Preparing files for signing ($# file(s))..." |
| 60 | +files_json="" |
| 61 | +for file in "$@"; do |
| 62 | + if [ ! -f "$file" ]; then |
| 63 | + echo "error: file not found: $file" >&2 |
| 64 | + exit 1 |
| 65 | + fi |
| 66 | + |
| 67 | + abs_path="$(cd "$(dirname "$file")" && pwd)/$(basename "$file")" |
| 68 | + win_path="$(to_windows_path "$abs_path")" |
| 69 | + # Escape backslashes for JSON |
| 70 | + win_path_escaped="${win_path//\\/\\\\}" |
| 71 | + echo " - $win_path" |
| 72 | + |
| 73 | + if [ -n "$files_json" ]; then |
| 74 | + files_json+="," |
| 75 | + fi |
| 76 | + files_json+=" |
| 77 | + { |
| 78 | + \"SourceLocation\": \"$win_path_escaped\", |
| 79 | + \"DestinationLocation\": \"$win_path_escaped\" |
| 80 | + }" |
| 81 | +done |
| 82 | + |
| 83 | +# Generate the input JSON |
| 84 | +input_json="$WORK_DIR/input.json" |
| 85 | +output_json="$WORK_DIR/output.json" |
| 86 | + |
| 87 | +echo "==> Generating input JSON: $input_json" |
| 88 | +cat > "$input_json" <<-EOF |
| 89 | + { |
| 90 | + "Version": "1.0.0", |
| 91 | + "SignBatches": [ |
| 92 | + { |
| 93 | + "SourceLocationType": "UNC", |
| 94 | + "DestinationLocationType": "UNC", |
| 95 | + "SignRequestFiles": [$files_json |
| 96 | + ], |
| 97 | + "SigningInfo": { |
| 98 | + "Operations": [ |
| 99 | + { |
| 100 | + "KeyCode": "$ESRP_KEYCODE", |
| 101 | + "OperationCode": "SigntoolSign", |
| 102 | + "ToolName": "sign", |
| 103 | + "ToolVersion": "1.0", |
| 104 | + "Parameters": { |
| 105 | + "OpusName": "Microsoft", |
| 106 | + "OpusInfo": "https://www.microsoft.com", |
| 107 | + "FileDigest": "/fd SHA256", |
| 108 | + "PageHash": "/NPH", |
| 109 | + "TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" |
| 110 | + } |
| 111 | + }, |
| 112 | + { |
| 113 | + "KeyCode": "$ESRP_KEYCODE", |
| 114 | + "OperationCode": "SigntoolVerify", |
| 115 | + "ToolName": "sign", |
| 116 | + "ToolVersion": "1.0", |
| 117 | + "Parameters": {} |
| 118 | + } |
| 119 | + ] |
| 120 | + } |
| 121 | + } |
| 122 | + ] |
| 123 | + } |
| 124 | +EOF |
| 125 | + |
| 126 | +# Generate policy JSON |
| 127 | +echo "==> Generating policy JSON..." |
| 128 | +policy_json="$WORK_DIR/policy.json" |
| 129 | +cat > "$policy_json" <<-EOF |
| 130 | + { |
| 131 | + "Version": "1.0.0", |
| 132 | + "Intent": "ProductRelease", |
| 133 | + "ContentType": "Binaries", |
| 134 | + "ContentOrigin": "1stParty", |
| 135 | + "ProductState": "Current", |
| 136 | + "Audience": "ExternalBroad" |
| 137 | + } |
| 138 | +EOF |
| 139 | + |
| 140 | +# Use auth JSON from ESRP_AUTH |
| 141 | +export ESRP_AUTH_CONFIG="$(to_windows_path "$ESRP_AUTH")" |
| 142 | +export ESRP_POLICY_CONFIG="$WORK_DIR_WIN\\policy.json" |
| 143 | + |
| 144 | +# The ADO system access token is referenced in the auth JSON via the environment |
| 145 | +# variable - export this so the ESRP client can pick it up when it runs. |
| 146 | +export SYSTEM_ACCESSTOKEN |
| 147 | + |
| 148 | +# Print generated JSON files for debugging |
| 149 | +echo "==> Auth JSON:" |
| 150 | +cat "$ESRP_AUTH" |
| 151 | +echo "" |
| 152 | +echo "==> Policy JSON:" |
| 153 | +cat "$policy_json" |
| 154 | +echo "" |
| 155 | +echo "==> Input JSON:" |
| 156 | +cat "$input_json" |
| 157 | +echo "" |
| 158 | + |
| 159 | +# Sign the files |
| 160 | +esrp_tool_win="$(to_windows_path "$ESRP_TOOL")" |
| 161 | +input_json_win="$WORK_DIR_WIN\\input.json" |
| 162 | +output_json_win="$WORK_DIR_WIN\\output.json" |
| 163 | + |
| 164 | +echo "==> ESRP_AUTH_CONFIG=$ESRP_AUTH_CONFIG" |
| 165 | +echo "==> ESRP_POLICY_CONFIG=$ESRP_POLICY_CONFIG" |
| 166 | +echo "==> Running: $esrp_tool_win sign -i $input_json_win -o $output_json_win" |
| 167 | +"$esrp_tool_win" sign \ |
| 168 | + -i "$input_json_win" \ |
| 169 | + -o "$output_json_win" |
| 170 | + |
| 171 | +echo "==> Signing complete." |
| 172 | +echo "==> Output JSON:" |
| 173 | +cat "$output_json" |
0 commit comments