Closed rjmackay closed 7 years ago
Hi @rjmackay,
It will be the first thing i'm going to fix but I first need to investigate why the .app is modified after signing in the first place. Hopefully in the upcoming weeks as time permits.
As reference for myself: http://stackoverflow.com/questions/22458027/mac-dmg-oddity-signing-and-damaged-applications
Taking a quick look here (I'm no expert though), it seems to be a problem with the bundled Sparkle framework:
$ codesign --verify --verbose --deep Syncthing.app
Syncthing.app: a sealed resource is missing or invalid
In subcomponent: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework
file added: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj/Sparkle.strings
file added: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj/SUAutomaticUpdateAlert.nib
file added: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj/SUUpdateAlert.nib
file added: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj/SUUpdatePermissionPrompt.nib
file added: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj/Sparkle.strings
file added: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj/SUAutomaticUpdateAlert.nib
file added: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj/SUUpdateAlert.nib
file added: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj/SUUpdatePermissionPrompt.nib
file missing: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj
file missing: /Users/jc/tmp/Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj
There seem to be two sets of strings (fr_CA, pt) modified from when it was signed.
It might be as simple as just needing an updated version of the Sparkle framework, or just re-signing it. :smile:
Hi @justinclift thanks for you help!
I have read the sparkle documentation:
Apple code signing
If you are code-signing your application via Apple’s Developer ID program (which is recommended for macOS 10.8+), Sparkle will ensure the new version’s author matches the old version’s. Sparkle also performs basic (but not deep) validation for testing if the new application is archived/distributed correctly as you intended.
Note that embedding the Sparkle.framework into the bundle of a Developer ID application requires that you code-sign the framework with your Developer ID keys. Xcode should do this automatically if you let it “Code Sign on Copy” Sparkle’s framework. You can diagnose code signing problems with RB App Checker app and by checking logs in the Console.app. If you decide to both code-sign your application and include a public DSA key for signing your update archive, Sparkle allows issuing a new update that changes either your code signing certificate or your DSA keys. Note however this is a last resort and should only be done if you lose access to one of them.
The project uses the "Code Sign on Copy" for the Sparkle framework. But this seems to be a different problem. I have found another nice tool to check the validity with more output (GUI): RB App Checker Lite
Which gives:
Evaluating the application “Syncthing”.
The application was signed by “Apple Root CA”, “Mac Developer: jerryjacobs1989@gmail.com (TT7GM4W59N)”.
The (unverified) signing-time is: 23 Aug 2016 19:27:13.
The object code format is “app bundle with Mach-O thin (x86_64)”.
The signature contains the Team ID “C24U83K674”.
Both bundle and signing identifiers are “com.github.xor-gate.syncthing-macosx”.
The signature specifies implicit requirements. 
The signature specifies resource rules (v1). 
The signature specifies resource rules (v2). 
➤ Requirements and resources didn't pass static validation.  
The code signature has the UUID “CAE07AC2-B487-88EE-E762-905692B17C16”.
Executable code for x86_64 has the UUID “D55BA232-79EB-3AA7-86C5-978EC2989411”.
A signing-time snapshot of the application’s Info.plist was found. 
Version 0.14.5 (140500) Copyright © 2016 Jerry Jacobs (github.com/xor-gate). All rights reserved.
The signature contains 3 certificates. 
Certificate “Apple Root CA”: 
Your keychain contains this trusted root certificate.
Will expire on 09 Feb 2035.
Certificate “Apple Worldwide Developer Relations Certification Authority”: 
Will expire on 07 Feb 2023.
Certificate “Mac Developer: jerryjacobs1989@gmail.com (TT7GM4W59N)”: 
Will expire on 07 Aug 2017.
SHA1 fingerprint: “8433783E947D054D7B88A70B0ACDB95B9CF3DAAF”.
Team ID or Organizational Unit: “C24U83K674”.
This matches the Team ID contained in the signature.
The application is not sandboxed.
There is one embedded framework. 
10 auxiliary executables have been found. 
One file is invisible in the Finder.  
6 executables are unsigned.  
One executable is signed by “Apple Root CA”, “Developer ID Application: Jakob Borg (LQE5SYM783)”. 
3 executables are signed by “Apple Root CA”, “Mac Developer: jerryjacobs1989@gmail.com (TT7GM4W59N)”. 
4 executables are in the Resources folder. 
One executable file has no executable permissions, but should.  
Different executables are using the same signing identifier “org.sparkle-project.Sparkle”. 
Different executables are using the same bundle identifier “org.sparkle-project.Sparkle”. 
And:
Error details: “-67054: a sealed resource is missing or invalid” {
Error in subcomponent: Contents/Frameworks/Sparkle.framework
Resources added:
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj/SUAutomaticUpdateAlert.nib
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj/SUUpdateAlert.nib
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj/Sparkle.strings
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj/SUUpdatePermissionPrompt.nib
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj/SUAutomaticUpdateAlert.nib
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj/SUUpdateAlert.nib
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj/SUUpdatePermissionPrompt.nib
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj/Sparkle.strings
Resources missing:
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/fr_CA.lproj
Contents/Frameworks/Sparkle.framework/Versions/Current/Resources/pt.lproj
}
No clue about the solution yet. I can ask the guys from Sparkle.
Yeah, it's probably a good idea to ask the Sparkle guys, as the Resources added
and Resources missing
indicate things in their signed file set changed unexpectedly. They probably know about this already, and have re-signed them since. 😉
As a quick workaround, you could sign the Sparkle framework bundled inside your Syncthing.app, but it's probably better to ping the Sparkle guys first. :smile:
This is weird, when I don't put the .app into the DMG then it is not broken! Can you guys test out? I have build a new one (0.14.5) and packed it inside a zipfile.
https://github.com/xor-gate/syncthing-macosx/releases/download/v0.14.5/Syncthing-0.14.5-signed.zip
I have verified with RB App Checker Lite.
Yeah, that one seems fine to me:
$ codesign --verify --verbose --deep Syncthing.app
Syncthing.app: valid on disk
Syncthing.app: satisfies its Designated Requirement
I must say, pushing the .app into the dmg is not the best way how it is done currently. Probably the script will break somewhere. Needs some investigation...
Ahhhh, found something interesting. The end part of the "unzip" output on your zip file was:
finishing deferred symbolic links:
Syncthing.app/Contents/Frameworks/Sparkle.framework/Resources -> Versions/Current/Resources
Syncthing.app/Contents/Frameworks/Sparkle.framework/Sparkle -> Versions/Current/Sparkle
Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/fr_CA.lproj -> fr.lproj
Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt.lproj -> pt_BR.lproj
Syncthing.app/Contents/Frameworks/Sparkle.framework/Versions/Current -> A
Both the fr_CA.lproj and pr.lproj look like links. Maybe your .dmg creation process isn't doing the links correctly?
Yeah probably how the DMG ramdisk is created and files are copied into is breaking it: https://github.com/xor-gate/syncthing-macosx/blob/master/3thparty/github.com/andreyvit/create-dmg/create-dmg
If you need an alternative (super simple) way to create .dmg's from your app, you can copy ours if it helps? Example .dmg here:
That's ironic. create-dmg
was the first thing we tried too (a few weeks ago), but it was too buggy. Went with https://github.com/LinusU/node-appdmg instead. 1 min, and I'll dig up the bits.
I think I hacked the script. It seems the creation with hdiutils breaks the filesystem. Searched stackoverflow: http://stackoverflow.com/questions/6081503/automating-dmg-build-in-xcode-4-0
Probably it breaks during: https://github.com/xor-gate/syncthing-macosx/blob/master/3thparty/github.com/andreyvit/create-dmg/create-dmg#L214
The bits:
The command we run: https://gist.github.com/justinclift/38887c1cfe480adfb11b#file-build_sqlitebrowser_nightly-sh-L54
Just look at the line highlighted and ignore the rest. :smile:
You can probably just update the values in the json with "Syncthing.app", your own background image (and the 2X), and the X,Y positions and call it a day. :smile:
Thanks @justinclift as I have the dmg-building in-place and not a big fan of node-js utiltity scripts. I probably have solved the problem. During staging before creating the DMG the copy didn't preserved the symlinks. Now I have created a new release which should fix it:
https://github.com/xor-gate/syncthing-macosx/releases/download/v0.14.5/Syncthing-0.14.5-testing.dmg
I have done this fix: https://github.com/xor-gate/syncthing-macosx/commit/e41767958917d3dce0bb61e1edfe8d25fd90ef3a
@rjmackay could you also test this new DMG if it works with filevault enabled?
Crossreference to: https://github.com/sparkle-project/Sparkle/issues/433
Yep, that seems to have fixed it. :smile:
$ codesign --verify --verbose --deep Syncthing.app
Syncthing.app: valid on disk
Syncthing.app: satisfies its Designated Requirement
That's awesome! Thank you for your help and testing.
I have silently removed the "broken" dmg in the 0.14.5
release and replaced with the fixed one. Also the -testing
and zipfile have been removed. Otherwise this would confuse new users.
You're welcome. :smile:
I'm closing this, when there are any problems. Don't hesitate to open a new issue (or continue in this one if there are still problems).
Please sign the the app bundle in release key rather the developer key to make gatekeeper happy.
Now the app is signed with the developer key:
Executable=/Volumes/Syncthing/Syncthing.app/Contents/MacOS/Syncthing Identifier=com.github.xor-gate.syncthing-macosx Format=app bundle with Mach-O thin (x86_64) CodeDirectory v=20200 size=932 flags=0x0(none) hashes=23+3 location=embedded Hash type=sha256 size=32 CandidateCDHash sha1=0f2a975e438011471df9586fdd098cf5b63cece7 CandidateCDHash sha256=8f70bef4824f1922726e5ebec220ee24fdb7ae21 Hash choices=sha1,sha256 CDHash=8f70bef4824f1922726e5ebec220ee24fdb7ae21 Signature size=4696 Authority=Mac Developer: jerryjacobs1989@gmail.com (TT7GM4W59N) Authority=Apple Worldwide Developer Relations Certification Authority Authority=Apple Root CA Signed Time=9 Aug 2016, 6:42:36 PM Info.plist entries=29 TeamIdentifier=C24U83K674 Sealed Resources version=2 rules=12 files=30 Internal requirements count=1 size=208
And gatekeeper prevent me to open it directly even though it is signed correctly. It will make us more convenient if you could sign it in release key.
You should allow from gatekeeper Mac App Store and identified developers
instead of Mac App Store
:
This because the application is distributed without Mac App Store signed key and will never be.
I have already allow gatekeeper from Mac App Store and identified developers. However,
➜ /Applications codesign -dvv Google\ Chrome.app
Executable=/Applications/Google Chrome.app/Contents/MacOS/Google Chrome
Identifier=com.google.Chrome
Format=app bundle with Mach-O thin (x86_64)
CodeDirectory v=20200 size=273 flags=0x800(restrict) hashes=3+3 location=embedded
Signature size=8896
Authority=Developer ID Application: Google Inc.
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=8 Nov 2016, 11:19:50 AM
Info.plist entries=34
TeamIdentifier=EQHXZ8M8AV
Sealed Resources version=2 rules=7 files=191
Internal requirements count=1 size=132
➜ /Applications codesign -dvv Syncthing.app
Executable=/Applications/Syncthing.app/Contents/MacOS/Syncthing
Identifier=com.github.xor-gate.syncthing-macosx
Format=app bundle with Mach-O thin (x86_64)
CodeDirectory v=20200 size=1060 flags=0x0(none) hashes=27+3 location=embedded
Signature size=4696
Authority=Mac Developer: jerryjacobs1989@gmail.com (TT7GM4W59N)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Signed Time=16 Oct 2016, 11:06:46 PM
Info.plist entries=30
TeamIdentifier=C24U83K674
Sealed Resources version=2 rules=13 files=35
Internal requirements count=1 size=208
The difference is that Google Chrome is signed by certificate type of Developer ID Application but Syncthing is signed by certificate type of Mac Development.
From https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html Table 14-2, Mac Development is used to enable certain app services for a Mac app during development and testing. And it would not pass gatekeeper.
Thus, if you could sign application with certificate of Developer ID Application, it will be easier for us to use the application.
Thanks.
I will investigate ASAP (no hard due date).
Clicked close button by accident
Ahhh yeah, I remember having to do this too. The docs for this are way more complicated than they need to be, which was off-putting.
@xor-gate If you have 5 mins, it's actually pretty simple to do. :smile:
Click the + symbol on the right:
Choose "Developer ID", then click continue:
Choose "Developer ID Application", then click continue:
That's how I did it anyway.
Hope that helps. :smile:
Nope, it doesn't show up. I need to pay the 99 bucks to make it work -> Enable Developer ID.
Under XCode it looks like this:
target build settings
preferences -> accounts
Last resort: https://support.apple.com/kb/ph18657?locale=en_US
Ahhhh yeah. Forgot about the $99 thing. Oops. :wink:
I will add a note in the README about this, as I'm not going to spend the $99 any time soon.
As @virusman is now a project contributor he signed the latest v0.14.33-1 release with his apple developer account. Only the auto-updater (Sparkle) is not yet updated because we changed the keys and is disallowed. As seen below:
~/Library/Logs/SparkleUpdateLog.log
2017-08-03 08:06:24 +0000: Code signature of the new version doesn't match the old version: identifier "com.github.xor-gate.syncthing-macosx" and anchor apple generic and certificate leaf[subject.CN] = "Mac Developer: jerryjacobs1989@gmail.com (TT7GM4W59N)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */. Please ensure that old and new app is signed using exactly the same certificate.
2017-08-03 08:06:24 +0000: host info: {
build = 140802;
format = "app bundle with Mach-O thin (x86_64)";
identifier = "com.github.xor-gate.syncthing-macosx";
requirements = "designated => identifier \"com.github.xor-gate.syncthing-macosx\" and anchor apple generic and certificate leaf[subject.CN] = \"Mac Developer: jerryjacobs1989@gmail.com (TT7GM4W59N)\" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */\n";
"signing-time" = "2016-10-16 15:06:46 +0000";
teamid = C24U83K674;
version = "0.14.8-2";
}
2017-08-03 08:06:24 +0000: new info: {
build = 143301;
format = "app bundle with Mach-O thin (x86_64)";
identifier = "com.github.xor-gate.syncthing-macosx";
requirements = "designated => identifier \"com.github.xor-gate.syncthing-macosx\" 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] = JUW2CNK88G\n";
"signing-time" = "2017-08-03 00:43:58 +0000";
teamid = JUW2CNK88G;
version = "0.14.33-1";
}
2017-08-03 08:06:24 +0000: The update archive isn't signed with a DSA key, and the app is signed with a new Code Signing identity that doesn't match code signing of the original app: Error Domain=NSOSStatusErrorDomain Code=-67050 "(null)" UserInfo={SecCSArchitecture=x86_64}. At least one method of signature verification must be valid. The update will be rejected.
We need to write an update errata for old users.
I am more than willing to donate some small amount to have a signed app on MacOS and I am sure others would be willing to. Without signing syncthing future would be kinda doomed as MacOS platform cannot be ignored.
PS. I know that I can build my own, but my life if too short to do that with all my tools, I would rather forget about the one that is not easy to install/use ;)
@ssbarnea last version is signed by @virusman developer account and should work without problems. Latest release breaks the auto-updater so it is not added as latest update-able release yet.
It not reasonable to disable gatekeeper for my whole machine to install a single application. Any idea when package signing will be fixed?