@@ -25,6 +25,21 @@ Future<void> verifyCodesignedTestRunner() async {
25
25
await verifySignatures (flutterRoot);
26
26
}
27
27
28
+ /// Some binaries should always be codesigned, even on master. Verify that they
29
+ /// are codesigned and have the correct entitlements.
30
+ Future <void > verifyPreCodesignedTestRunner () async {
31
+ printProgress ('${green }Running binaries codesign verification$reset ' );
32
+ await runCommand ('flutter' , < String > [
33
+ 'precache' ,
34
+ '--android' ,
35
+ '--ios' ,
36
+ '--macos' ,
37
+ ], workingDirectory: flutterRoot);
38
+
39
+ await verifyExist (flutterRoot);
40
+ await verifySignatures (flutterRoot, forRelease: false );
41
+ }
42
+
28
43
const List <String > expectedEntitlements = < String > [
29
44
'com.apple.security.cs.allow-jit' ,
30
45
'com.apple.security.cs.allow-unsigned-executable-memory' ,
@@ -39,69 +54,69 @@ const List<String> expectedEntitlements = <String>[
39
54
/// This list should be kept in sync with the actual contents of Flutter's
40
55
/// cache.
41
56
List <String > binariesWithEntitlements (String flutterRoot) {
42
- return < String > [
43
- 'artifacts/engine/android-arm-profile/darwin-x64/gen_snapshot' ,
44
- 'artifacts/engine/android-arm-release/darwin-x64/gen_snapshot' ,
45
- 'artifacts/engine/android-arm64-profile/darwin-x64/gen_snapshot' ,
46
- 'artifacts/engine/android-arm64-release/darwin-x64/gen_snapshot' ,
47
- 'artifacts/engine/android-x64-profile/darwin-x64/gen_snapshot' ,
48
- 'artifacts/engine/android-x64-release/darwin-x64/gen_snapshot' ,
49
- 'artifacts/engine/darwin-x64-profile/gen_snapshot' ,
50
- 'artifacts/engine/darwin-x64-profile/gen_snapshot_arm64' ,
51
- 'artifacts/engine/darwin-x64-profile/gen_snapshot_x64' ,
52
- 'artifacts/engine/darwin-x64-release/gen_snapshot' ,
53
- 'artifacts/engine/darwin-x64-release/gen_snapshot_arm64' ,
54
- 'artifacts/engine/darwin-x64-release/gen_snapshot_x64' ,
55
- 'artifacts/engine/darwin-x64/flutter_tester' ,
56
- 'artifacts/engine/darwin-x64/gen_snapshot' ,
57
- 'artifacts/engine/darwin-x64/gen_snapshot_arm64' ,
58
- 'artifacts/engine/darwin-x64/gen_snapshot_x64' ,
59
- 'artifacts/engine/ios-profile/gen_snapshot_arm64' ,
60
- 'artifacts/engine/ios-release/gen_snapshot_arm64' ,
61
- 'artifacts/engine/ios/gen_snapshot_arm64' ,
62
- 'artifacts/libimobiledevice/idevicescreenshot' ,
63
- 'artifacts/libimobiledevice/idevicesyslog' ,
64
- 'artifacts/libimobiledevice/libimobiledevice-1.0.6.dylib' ,
65
- 'artifacts/libimobiledeviceglue/libimobiledevice-glue-1.0.0.dylib' ,
66
- 'artifacts/libplist/libplist-2.0.4.dylib' ,
67
- 'artifacts/openssl/libcrypto.3.dylib' ,
68
- 'artifacts/openssl/libssl.3.dylib' ,
69
- 'artifacts/libusbmuxd/iproxy' ,
70
- 'artifacts/libusbmuxd/libusbmuxd-2.0.7.dylib' ,
71
- 'dart-sdk/bin/dart' ,
72
- 'dart-sdk/bin/dartaotruntime' ,
73
- 'dart-sdk/bin/utils/gen_snapshot' ,
74
- 'dart-sdk/bin/utils/wasm-opt' ,
75
- ].map ((String relativePath) => path.join (flutterRoot, 'bin' , 'cache' , relativePath)).toList ();
57
+ final List <String > binaries =
58
+ < String > [
59
+ 'artifacts/engine/android-arm-profile/darwin-x64/gen_snapshot' ,
60
+ 'artifacts/engine/android-arm-release/darwin-x64/gen_snapshot' ,
61
+ 'artifacts/engine/android-arm64-profile/darwin-x64/gen_snapshot' ,
62
+ 'artifacts/engine/android-arm64-release/darwin-x64/gen_snapshot' ,
63
+ 'artifacts/engine/android-x64-profile/darwin-x64/gen_snapshot' ,
64
+ 'artifacts/engine/android-x64-release/darwin-x64/gen_snapshot' ,
65
+ 'artifacts/engine/darwin-x64-profile/gen_snapshot' ,
66
+ 'artifacts/engine/darwin-x64-profile/gen_snapshot_arm64' ,
67
+ 'artifacts/engine/darwin-x64-profile/gen_snapshot_x64' ,
68
+ 'artifacts/engine/darwin-x64-release/gen_snapshot' ,
69
+ 'artifacts/engine/darwin-x64-release/gen_snapshot_arm64' ,
70
+ 'artifacts/engine/darwin-x64-release/gen_snapshot_x64' ,
71
+ 'artifacts/engine/darwin-x64/flutter_tester' ,
72
+ 'artifacts/engine/darwin-x64/gen_snapshot' ,
73
+ 'artifacts/engine/darwin-x64/gen_snapshot_arm64' ,
74
+ 'artifacts/engine/darwin-x64/gen_snapshot_x64' ,
75
+ 'artifacts/engine/ios-profile/gen_snapshot_arm64' ,
76
+ 'artifacts/engine/ios-release/gen_snapshot_arm64' ,
77
+ 'artifacts/engine/ios/gen_snapshot_arm64' ,
78
+ 'dart-sdk/bin/dart' ,
79
+ 'dart-sdk/bin/dartaotruntime' ,
80
+ 'dart-sdk/bin/utils/gen_snapshot' ,
81
+ 'dart-sdk/bin/utils/wasm-opt' ,
82
+ ].map ((String relativePath) => path.join (flutterRoot, 'bin' , 'cache' , relativePath)).toList ();
83
+
84
+ presignedBinariesWithEntitlements (flutterRoot).forEach (binaries.add);
85
+
86
+ return binaries;
76
87
}
77
88
78
89
/// Binaries that are only expected to be codesigned.
79
90
///
80
91
/// This list should be kept in sync with the actual contents of Flutter's
81
92
/// cache.
82
93
List <String > binariesWithoutEntitlements (String flutterRoot) {
83
- return < String > [
84
- 'artifacts/engine/darwin-x64-profile/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS' ,
85
- 'artifacts/engine/darwin-x64-release/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS' ,
86
- 'artifacts/engine/darwin-x64/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS' ,
87
- 'artifacts/engine/darwin-x64/font-subset' ,
88
- 'artifacts/engine/darwin-x64/impellerc' ,
89
- 'artifacts/engine/darwin-x64/libpath_ops.dylib' ,
90
- 'artifacts/engine/darwin-x64/libtessellator.dylib' ,
91
- 'artifacts/engine/ios-profile/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
92
- 'artifacts/engine/ios-profile/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
93
- 'artifacts/engine/ios-profile/extension_safe/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
94
- 'artifacts/engine/ios-profile/extension_safe/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
95
- 'artifacts/engine/ios-release/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
96
- 'artifacts/engine/ios-release/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
97
- 'artifacts/engine/ios-release/extension_safe/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
98
- 'artifacts/engine/ios-release/extension_safe/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
99
- 'artifacts/engine/ios/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
100
- 'artifacts/engine/ios/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
101
- 'artifacts/engine/ios/extension_safe/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
102
- 'artifacts/engine/ios/extension_safe/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
103
- 'artifacts/ios-deploy/ios-deploy' ,
104
- ].map ((String relativePath) => path.join (flutterRoot, 'bin' , 'cache' , relativePath)).toList ();
94
+ final List <String > binaries =
95
+ < String > [
96
+ 'artifacts/engine/darwin-x64-profile/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS' ,
97
+ 'artifacts/engine/darwin-x64-release/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS' ,
98
+ 'artifacts/engine/darwin-x64/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS' ,
99
+ 'artifacts/engine/darwin-x64/font-subset' ,
100
+ 'artifacts/engine/darwin-x64/impellerc' ,
101
+ 'artifacts/engine/darwin-x64/libpath_ops.dylib' ,
102
+ 'artifacts/engine/darwin-x64/libtessellator.dylib' ,
103
+ 'artifacts/engine/ios-profile/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
104
+ 'artifacts/engine/ios-profile/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
105
+ 'artifacts/engine/ios-profile/extension_safe/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
106
+ 'artifacts/engine/ios-profile/extension_safe/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
107
+ 'artifacts/engine/ios-release/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
108
+ 'artifacts/engine/ios-release/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
109
+ 'artifacts/engine/ios-release/extension_safe/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
110
+ 'artifacts/engine/ios-release/extension_safe/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
111
+ 'artifacts/engine/ios/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
112
+ 'artifacts/engine/ios/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
113
+ 'artifacts/engine/ios/extension_safe/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter' ,
114
+ 'artifacts/engine/ios/extension_safe/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter' ,
115
+ ].map ((String relativePath) => path.join (flutterRoot, 'bin' , 'cache' , relativePath)).toList ();
116
+
117
+ presignedBinariesWithoutEntitlements (flutterRoot).forEach (binaries.add);
118
+
119
+ return binaries;
105
120
}
106
121
107
122
/// Binaries that are not expected to be codesigned.
@@ -117,6 +132,28 @@ List<String> unsignedBinaries(String flutterRoot) {
117
132
].map ((String relativePath) => path.join (flutterRoot, 'bin' , 'cache' , relativePath)).toList ();
118
133
}
119
134
135
+ /// Binaries with entitlements that should always be signed, even on master.
136
+ List <String > presignedBinariesWithEntitlements (String flutterRoot) {
137
+ return < String > [
138
+ 'artifacts/libimobiledevice/idevicescreenshot' ,
139
+ 'artifacts/libimobiledevice/idevicesyslog' ,
140
+ 'artifacts/libusbmuxd/iproxy' ,
141
+ ].map ((String relativePath) => path.join (flutterRoot, 'bin' , 'cache' , relativePath)).toList ();
142
+ }
143
+
144
+ /// Binaries without entitlements that should always be signed, even on master.
145
+ List <String > presignedBinariesWithoutEntitlements (String flutterRoot) {
146
+ return < String > [
147
+ 'artifacts/ios-deploy/ios-deploy' ,
148
+ 'artifacts/libimobiledevice/libimobiledevice-1.0.6.dylib' ,
149
+ 'artifacts/libimobiledeviceglue/libimobiledevice-glue-1.0.0.dylib' ,
150
+ 'artifacts/libplist/libplist-2.0.4.dylib' ,
151
+ 'artifacts/openssl/libcrypto.3.dylib' ,
152
+ 'artifacts/openssl/libssl.3.dylib' ,
153
+ 'artifacts/libusbmuxd/libusbmuxd-2.0.7.dylib' ,
154
+ ].map ((String relativePath) => path.join (flutterRoot, 'bin' , 'cache' , relativePath)).toList ();
155
+ }
156
+
120
157
/// xcframeworks that are expected to be codesigned.
121
158
///
122
159
/// This list should be kept in sync with the actual contents of Flutter's
@@ -180,10 +217,13 @@ Future<void> verifyExist(
180
217
print ('All expected binaries present.' );
181
218
}
182
219
183
- /// Verify code signatures and entitlements of all binaries in the cache.
220
+ /// Verify code signatures and entitlements of binaries in the cache.
221
+ ///
222
+ /// If [forRelease] is true, verify for all binaries. Otherwise, only verify for pre-signed binaries.
184
223
Future <void > verifySignatures (
185
224
String flutterRoot, {
186
225
@visibleForTesting ProcessManager processManager = const LocalProcessManager (),
226
+ bool forRelease = true ,
187
227
}) async {
188
228
final List <String > unsignedFiles = < String > [];
189
229
final List <String > wrongEntitlementBinaries = < String > [];
@@ -194,24 +234,42 @@ Future<void> verifySignatures(
194
234
(await findBinaryPaths (cacheDirectory, processManager: processManager)) +
195
235
(await findXcframeworksPaths (cacheDirectory, processManager: processManager));
196
236
237
+ final List <String > binariesToVerifyEntitlements;
238
+ final List <String > binariesToVerifyWithoutEntitlements;
239
+ final List <String > xcframeworksToVerifyCodesigned;
240
+ if (forRelease) {
241
+ binariesToVerifyEntitlements = binariesWithEntitlements (flutterRoot);
242
+ binariesToVerifyWithoutEntitlements = binariesWithoutEntitlements (flutterRoot);
243
+ xcframeworksToVerifyCodesigned = signedXcframeworks (flutterRoot);
244
+ } else {
245
+ binariesToVerifyEntitlements = presignedBinariesWithEntitlements (flutterRoot);
246
+ binariesToVerifyWithoutEntitlements = presignedBinariesWithoutEntitlements (flutterRoot);
247
+ xcframeworksToVerifyCodesigned = < String > [];
248
+ }
249
+
197
250
for (final String pathToCheck in binariesAndXcframeworks) {
198
251
bool verifySignature = false ;
199
252
bool verifyEntitlements = false ;
200
- if (binariesWithEntitlements (flutterRoot) .contains (pathToCheck)) {
253
+ if (binariesToVerifyEntitlements .contains (pathToCheck)) {
201
254
verifySignature = true ;
202
255
verifyEntitlements = true ;
203
256
}
204
- if (binariesWithoutEntitlements (flutterRoot) .contains (pathToCheck)) {
257
+ if (binariesToVerifyWithoutEntitlements .contains (pathToCheck)) {
205
258
verifySignature = true ;
206
259
}
207
- if (signedXcframeworks (flutterRoot) .contains (pathToCheck)) {
260
+ if (xcframeworksToVerifyCodesigned .contains (pathToCheck)) {
208
261
verifySignature = true ;
209
262
}
210
263
if (unsignedBinaries (flutterRoot).contains (pathToCheck)) {
211
264
// Binary is expected to be unsigned. No need to check signature, entitlements.
212
265
continue ;
213
266
}
214
267
268
+ // If not testing for release, skip path if not going to verify it's codesigned/entitlements.
269
+ if (! forRelease && ! verifySignature && ! verifyEntitlements) {
270
+ continue ;
271
+ }
272
+
215
273
if (! verifySignature && ! verifyEntitlements) {
216
274
unexpectedFiles.add (pathToCheck);
217
275
print ('Unexpected binary or xcframework $pathToCheck found in cache!' );
0 commit comments