-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
sign.trycmd
503 lines (390 loc) · 20.1 KB
/
sign.trycmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
```
$ rcodesign help sign
Adds code signatures to a signable entity.
This command can sign the following entities:
* A single Mach-O binary (specified by its file path)
* A bundle (specified by its directory path)
* A DMG disk image (specified by its path)
* A XAR archive (commonly a .pkg installer file)
If the input is Mach-O binary, it can be a single or multiple/fat/universal
Mach-O binary. If a fat binary is given, each Mach-O within that binary will
be signed.
If the input is a bundle, the bundle will be recursively signed. If the
bundle contains nested bundles or Mach-O binaries, those will be signed
automatically.
# Settings Scope
The following signing settings are global and apply to all signed entities:
* --pem-source
* --team-name
* --timestamp-url
The following signing settings can be scoped so they only apply to certain
entities:
* --digest
* --binary-identifier
* --code-requirements-files
* --code-resources-file
* --code-signature-flags
* --entitlements-xml-file
* --info-plist-file
Scoped settings take the form <value> or <scope>:<value>. If the 2nd form
is used, the string before the first colon is parsed as a /"scoping string/".
It can have the following values:
* `main` - Applies to the main entity being signed and all nested entities.
* `@<integer>` - e.g. `@0`. Applies to a Mach-O within a fat binary at the
specified index. 0 means the first Mach-O in a fat binary.
* `@[cpu_type=<int>` - e.g. `@[cpu_type=7]`. Applies to a Mach-O within a fat
binary targeting a numbered CPU architecture (using numeric constants
as defined by Mach-O).
* `@[cpu_type=<string>` - e.g. `@[cpu_type=x86_64]`. Applies to a Mach-O within
a fat binary targeting a CPU architecture identified by a string. See below
for the list of recognized values.
* `<string>` - e.g. `path/to/file`. Applies to content at a given path. This
should be the bundle-relative path to a Mach-O binary, a nested bundle, or
a Mach-O binary within a nested bundle. If a nested bundle is referenced,
settings apply to everything within that bundle.
* `<string>@<int>` - e.g. `path/to/file@0`. Applies to a Mach-O within a
fat binary at the given path. If the path is to a bundle, the setting applies
to all Mach-O binaries in that bundle.
* `<string>@[cpu_type=<int|string>]` e.g. `Contents/MacOS/binary@[cpu_type=7]`
or `Contents/MacOS/binary@[cpu_type=arm64]`. Applies to a Mach-O within a
fat binary targeting a CPU architecture identified by its integer constant
or string name. If the path is to a bundle, the setting applies to all
Mach-O binaries in that bundle.
The following named CPU architectures are recognized:
* arm
* arm64
* arm64_32
* x86_64
Signing will traverse into nested entities:
* A fat Mach-O binary will traverse into the multiple Mach-O binaries within.
* A bundle will traverse into nested bundles.
* A bundle will traverse non-code "resource" files and sign their digests.
* A bundle will traverse non-main Mach-O binaries and sign them, adding their
metadata to the signed resources file.
When signing nested entities, only some signing settings will be copied
automatically:
* All settings related to the signing certificate/key.
* --timestamp-url
* --signing-time
* --exclude
* --digest
* --runtime-version
All other settings only apply to the main entity being signed or the
scoped path being annotated.
# Bundle Signing Overrides Settings
When signing bundles, some settings specified on the command line will be
ignored. This is to ensure that the produced signing data is correct. The
settings ignored include (but may not be limited to):
* --binary-identifier for the main executable. The `CFBundleIdentifier` value
from the bundle's `Info.plist` will be used instead.
* --code-resources-path. The code resources data will be computed automatically
as part of signing the bundle.
* --info-plist-path. The `Info.plist` from the bundle will be used instead.
* --digest
# Designated Code Requirements
When using Apple issued code signing certificates, we will attempt to apply
an appropriate designated requirement automatically during signing which
matches the behavior of what `codesign` would do. We do not yet support all
signing certificates and signing targets for this, however. So you may
need to provide your own requirements.
Designated code requirements can be specified via --code-requirements-path.
This file MUST contain a binary/compiled code requirements expression. We do
not (yet) support parsing the human-friendly code requirements DSL. A
binary/compiled file can be produced via Apple's `csreq` tool. e.g.
`csreq -r '=<expression>' -b /output/path`. If code requirements data is
specified, it will be parsed and displayed as part of signing to ensure it
is well-formed.
# Code Signing Key Pair
By default, the embedded code signature will only contain digests of the
binary and other important entities (such as entitlements and resources).
This is often referred to as /"ad-hoc/" signing.
To use a code signing key/certificate to derive a cryptographic signature,
you must specify a source certificate to use. This can be done in the following
ways:
* The --p12-file denotes the location to a PFX formatted file. These are
often .pfx or .p12 files. A password is required to open these files.
Specify one via --p12-password or --p12-password-file or enter a password
when prompted.
* The --pem-file argument defines paths to files containing PEM encoded
certificate/key data. (e.g. files with /"===== BEGIN CERTIFICATE =====/").
* The --certificate-der-file argument defines paths to files containing DER
encoded certificate/key data.
* The --keychain-domain and --keychain-fingerprint arguments can be used to
load code signing certificates from macOS keychains. These arguments are
ignored on non-macOS platforms.
* The --smartcard-slot argument defines the name of a slot in a connected
smartcard device to read from. `9c` is common.
* Arguments beginning with --remote activate *remote signing mode* and can
be used to delegate cryptographic signing operations to a separate machine.
It is strongly advised to read the user documentation on remote signing
mode at https://gregoryszorc.com/docs/apple-codesign/main/.
If you export a code signing certificate from the macOS keychain via the
`Keychain Access` application as a .p12 file, we should be able to read these
files via --p12-file.
When using --pem-file, certificates and public keys are parsed from
`BEGIN CERTIFICATE` and `BEGIN PRIVATE KEY` sections in the files.
The way certificate discovery works is that --p12-file is read followed by
all values to --pem-file. The seen signing keys and certificates are
collected. After collection, there must be 0 or 1 signing keys present, or
an error occurs. The first encountered public certificate is assigned
to be paired with the signing key. All remaining certificates are assumed
to constitute the CA issuing chain and will be added to the signature
data to facilitate validation.
If you are using an Apple-issued code signing certificate, we detect this
and automatically register the Apple CA certificate chain so it is included
in the digital signature. This matches the behavior of the `codesign` tool.
For best results, put your private key and its corresponding X.509 certificate
in a single file, either a PFX or PEM formatted file. Then add any additional
certificates constituting the signing chain in a separate PEM file.
When using a code signing key/certificate, a Time-Stamp Protocol server URL
can be specified via --timestamp-url. By default, Apple's server is used. The
special value /"none/" can disable using a timestamp server.
# Selecting What to Sign
By default, this command attempts to recursively sign everything in the source
path. This applies to:
* Bundles. If the specified bundle has nested bundles, those nested bundles
will be signed automatically.
It is possible to exclude nested items from signing using --exclude. This
argument takes a glob expression that matches *relative paths* from the
source path. Glob expressions can be literal string compares. Or the
following special syntax is recognized:
* `?` matches any single character.
* `*` matches any (possibly empty) sequence of characters.
* `**` matches the current directory and arbitrary subdirectories. This sequence
must form a single path component, so both **a and b** are invalid and will
result in an error. A sequence of more than two consecutive * characters is
also invalid.
* `[...]` matches any character inside the brackets. Character sequences can also
specify ranges of characters, as ordered by Unicode, so e.g. [0-9] specifies any
character between 0 and 9 inclusive. An unclosed bracket is invalid.
* `[!...]` is the negation of `[...]`, i.e. it matches any characters not in the
brackets.
* The metacharacters `?`, `*`, `[`, `]` can be matched by using brackets (e.g.
`[?]`). When a `]` occurs immediately following `[` or `[!` then it is
interpreted as being part of, rather then ending, the character set, so `]` and
`NOT ]` can be matched by `[]]` and `[!]]` respectively. The `-` character can
be specified inside a character sequence pattern by placing it at the start or
the end, e.g. `[abc-]`.
Currently, --exclude only applies to the relative path of nested bundles within
the main bundle to sign. e.g. if you sign `MyApp.app` and it has a
`Contents/Frameworks/MyFramework.framework` that you wish to exclude, you would
`--exclude Contents/Frameworks/MyFramework.framework` or even
`--exclude Contents/Frameworks/**` to exclude the entire directory tree.
Exclusions will still be copied and parents that need to reference exclude
entities will continue to do so. If you wish to make a file or directory
disappear, create a new directory without the file(s) and sign that.
To exclude all nested bundles from being signed and only sign the main bundle
(the default behavior of ``codesign`` without ``--deep``), use `--exclude '**'`.
Usage: rcodesign[EXE] sign [OPTIONS] <INPUT_PATH> [OUTPUT_PATH]
Arguments:
<INPUT_PATH>
Path to Mach-O binary to sign
[OUTPUT_PATH]
Path to signed Mach-O binary to write
Options:
--binary-identifier <IDENTIFIER>
Identifier string for binary. The value normally used by CFBundleIdentifier
-C, --config-file <CONFIG_PATH>
Explicit configuration file to load.
If provided, the default configuration files are not loaded, even if they exist.
Can be specified multiple times. Files are loaded/merged in the order given.
The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files.
--code-requirements-file <PATH>
Path to a file containing binary code requirements data to be used as designated requirements
-P, --profile <PROFILE>
Configuration profile to load.
If not specified, the implicit "default" profile is loaded.
--code-resources-file <PATH>
Path to an XML plist file containing code resources
-v, --verbose...
Increase logging verbosity. Can be specified multiple times
--code-signature-flags <CODE_SIGNATURE_FLAGS>
Code signature flags to set
[possible values: host, hard, kill, expires, library, runtime, linker-signed]
--digest <DIGEST>
Digest algorithms to use.
This typically doesn't need to be set since the OS targeting information from signed binaries implicitly derives appropriate digests to sign with.
However, there are special cases where you may want to force use of specific digests.
The first provided value will become the "primary" digest. Subsequent values will become alternative digests. The "primary" digest should be "older" to ensure compatibility with older clients.
When targeting older Apple OS versions, SHA-1 should be the primary digest and SHA-256 should also be present for compatibility with newer OS versions.
When targeting new OS versions, it is sufficient to only provide SHA-256 digests.
The following values are accepted: none, sha1, sha256, sha384, sha512.
Important: only "sha1" and "sha256" are widely used and use of other algorithms may cause problems.
-e, --entitlements-xml-file <PATH>
Path to a plist file containing entitlements
--launch-constraints-self-file <PATH>
Launch constraints on the current executable.
Specify the path to a plist XML file defining launch constraints.
--launch-constraints-parent-file <PATH>
Launch constraints on the parent process.
Specify the path to a plist XML file defining launch constraints.
--launch-constraints-responsible-file <PATH>
Launch constraints on the responsible process.
Specify the path to a plist XML file defining launch constraints.
--library-constraints-file <PATH>
Constraints on loaded libraries.
Specify the path to a plist XML file defining launch constraints.
--runtime-version <VERSION>
Hardened runtime version to use (defaults to SDK version used to build binary)
--info-plist-file <PATH>
Path to an Info.plist file whose digest to include in Mach-O signature
--team-name <NAME>
Team name/identifier to include in code signature
--signing-time <SIGNING_TIME>
An RFC 3339 date and time string to be used in signatures.
e.g. 2023-11-05T10:42:00Z.
If not specified, the current time will be used.
Setting is only used when signing with a signing certificate.
This setting is typically not necessary. It was added to facilitate deterministic signing behavior.
--timestamp-url <TIMESTAMP_URL>
URL of time-stamp server to use to obtain a token of the CMS signature
Can be set to the special value `none` to disable the generation of time-stamp tokens and use of a time-stamp server.
[default: http://timestamp.apple.com/ts01]
--exclude <EXCLUDE>
Glob expression of paths to exclude from signing
--smartcard-slot <SLOT>
Smartcard slot number of signing certificate to use (9c is common)
--smartcard-pin <SECRET>
Smartcard PIN used to unlock certificate
If not provided, you will be prompted for a PIN as necessary.
--smartcard-pin-env <STRING>
Environment variable holding the smartcard PIN
--keychain-domain <DOMAIN>
(macOS only) Keychain domain to operate on
[possible values: user, system, common, dynamic]
--keychain-fingerprint <SHA256 FINGERPRINT>
(macOS only) SHA-256 fingerprint of certificate in Keychain to use
--pem-file <PATH>
Path to file containing PEM encoded certificate/key data
--p12-file <PATH>
Path to a .p12/PFX file containing a certificate key pair
--p12-password <SECRET>
The password to use to open the --p12-file file
--p12-password-file <PATH>
Path to file containing password for opening --p12-file file
--remote-signing-url <URL>
URL of a remote code signing server
--remote-public-key <BASE64 ENCODED PUBLIC KEY>
Base64 encoded public key data describing the signer
--remote-public-key-pem-file <PATH>
PEM encoded public key data describing the signer
--remote-shared-secret <SECRET>
Shared secret used for remote signing
--remote-shared-secret-env <ENV VAR NAME>
Environment variable holding the shared secret used for remote signing
--certificate-der-file <PATH>
Path to file containing DER encoded certificate data
-h, --help
Print help (see a summary with '-h')
```
An ad-hoc signature over a minimal Mach-O works.
```
$ rcodesign debug-create-macho exe
assuming default minimum version 11.0.0
writing Mach-O to exe
$ rcodesign sign exe exe.signed
signing exe to exe.signed
signing exe as a Mach-O binary
setting binary identifier to exe
parsing Mach-O
writing Mach-O to exe.signed
$ rcodesign print-signature-info exe.signed
- path: exe.signed
file_size: 22544
file_sha256: 2adcd25a21eb14fc3f7b5ca4f5465b515f21939dd9843de5bf7d9e3f7acfa9db
entity:
mach_o:
macho_linkedit_start_offset: 16384 / 0x4000
macho_signature_start_offset: 16400 / 0x4010
macho_signature_end_offset: 16772 / 0x4184
macho_linkedit_end_offset: 22544 / 0x5810
macho_end_offset: 22544 / 0x5810
linkedit_signature_start_offset: 16 / 0x10
linkedit_signature_end_offset: 388 / 0x184
linkedit_bytes_after_signature: 5772 / 0x168c
signature:
superblob_length: 372 / 0x174
blob_count: 3
blobs:
- slot: CodeDirectory (0)
magic: fade0c02
length: 316
sha1: 4ca6f9ee2bfe2bfac44ab4e9e9c1ef9b6e4fc0de
sha256: 23fc7207e52f23c0f6d2317dbb92cf9eff2aca8fe61ac241900d48be8f46cf5c
- slot: RequirementSet (2)
magic: fade0c01
length: 12
sha1: 3a75f6db058529148e14dd7ea1b4729cc09ec973
sha256: 987920904eab650e75788c054aa0b0524e6a80bfc71aa32df8d237a61743f986
- slot: CMS Signature (65536)
magic: fade0b01
length: 8
sha1: 2a7254313aa41796079bb0e9d0f044345f69f98b
sha256: e6c83bc98a10348492c7d4d2378a54572ef29e1a5692ccd02b5e29f4b762d6a0
code_directory:
version: '0x20400'
flags: CodeSignatureFlags(ADHOC)
identifier: exe
digest_type: sha256
platform: 0
signed_entity_size: 16400
executable_segment_flags: ExecutableSegmentFlags(MAIN_BINARY)
code_digests_count: 5
slot_digests:
- 'Info (1): 0000000000000000000000000000000000000000000000000000000000000000'
- 'RequirementSet (2): 987920904eab650e75788c054aa0b0524e6a80bfc71aa32df8d237a61743f986'
cms: null
$ rcodesign sign exe.signed exe.signed.2
signing exe.signed to exe.signed.2
signing exe.signed as a Mach-O binary
setting binary identifier to exe
parsing Mach-O
writing Mach-O to exe.signed.2
$ rcodesign diff-signatures exe.signed exe.signed.2
-- path: exe.signed
+- path: exe.signed.2
file_size: 22544
file_sha256: 2adcd25a21eb14fc3f7b5ca4f5465b515f21939dd9843de5bf7d9e3f7acfa9db
entity:
mach_o:
macho_linkedit_start_offset: 16384 / 0x4000
macho_signature_start_offset: 16400 / 0x4010
macho_signature_end_offset: 16772 / 0x4184
macho_linkedit_end_offset: 22544 / 0x5810
macho_end_offset: 22544 / 0x5810
linkedit_signature_start_offset: 16 / 0x10
linkedit_signature_end_offset: 388 / 0x184
linkedit_bytes_after_signature: 5772 / 0x168c
signature:
superblob_length: 372 / 0x174
blob_count: 3
blobs:
- slot: CodeDirectory (0)
magic: fade0c02
length: 316
sha1: 4ca6f9ee2bfe2bfac44ab4e9e9c1ef9b6e4fc0de
sha256: 23fc7207e52f23c0f6d2317dbb92cf9eff2aca8fe61ac241900d48be8f46cf5c
- slot: RequirementSet (2)
magic: fade0c01
length: 12
sha1: 3a75f6db058529148e14dd7ea1b4729cc09ec973
sha256: 987920904eab650e75788c054aa0b0524e6a80bfc71aa32df8d237a61743f986
- slot: CMS Signature (65536)
magic: fade0b01
length: 8
sha1: 2a7254313aa41796079bb0e9d0f044345f69f98b
sha256: e6c83bc98a10348492c7d4d2378a54572ef29e1a5692ccd02b5e29f4b762d6a0
code_directory:
version: '0x20400'
flags: CodeSignatureFlags(ADHOC)
identifier: exe
digest_type: sha256
platform: 0
signed_entity_size: 16400
executable_segment_flags: ExecutableSegmentFlags(MAIN_BINARY)
code_digests_count: 5
slot_digests:
- 'Info (1): 0000000000000000000000000000000000000000000000000000000000000000'
- 'RequirementSet (2): 987920904eab650e75788c054aa0b0524e6a80bfc71aa32df8d237a61743f986'
cms: null
```