Gatekeeper quarantine issue with certificate - macos

Our app has been code signed. Our Apple certificate is up to date. Previous versions of our app have run just fine.
However, when the DMG is downloaded by the users, on some Macs the application is quarantined, but for the majority of users, it's not. So some users can open the app and others get the "X.app can’t be opened because the identity of the developer cannot be confirmed."
Luckily I have 2 Macs here that have the quarantine problem, but we can't find a difference between these Macs and the others. Has anyone else run into this problem?

I think you may be a bit confused about how quarantine, code signing, and Gatekeeper work. The error you're seeing is from Gatekeeper, and indicates two different (and independent) things: 1) the app is quarantined (which has to do with how it was downloaded, not how it's signed) and 2) it is not signed in a way that complies with the Gatekeeper policy defined in Security & Privacy preferences. Let me explain these two things in more detail.
Quarantine is a result of the app (or the disk image it was in) being downloaded. When you download a file with a browser, the browser will attach a com.apple.quarantine attribute to it, indicating that it came from an untrusted network source. Other types of internet apps (email, chat, etc) should also attach this attribute to downloaded files.
But not all network download methods will apply the quarantine attribute. For example, copying a file over a file sharing connection (e.g. AFP or SMB) with the Finder will not mark it as being in quarantine. Also, command-line tools like curl and wget won't apply quarantine.
In your case, when you download the .dmg file, it gets marked as quarantined; when you open it, the attribute gets propagated to its contents, so the app is also marked as being in quarantine (and if you copy it to /Applications, the quarantine attribute gets copied along with everything else).
To check whether a file is quarantined, use ls -l# on it and look for the com.apple.quarantine attribute. It's entirely possible that the difference you're seeing between different computers has to do with how the disk image was downloaded and therefore whether the apps are quarantined.
When you open a quarantined app, Gatekeeper checks to see whether it complies with you computer's security policy subsystem. This is where code signing comes into it. You can view and change your policy in System Preferences -> Security & Privacy pane -> General tab -> "Allow apps downloaded from" or with the spctl command-line tool. The default policy is to allow quarantined apps that are from the Mac App Store (i.e. signed with Apple's app store keys) or from an identified developer (i.e. signed with a developer ID key issued by Apple to a registered developer).
When you try to open an app that's quarantined, and not signed in a way that complies with this policy, you get an error saying that "X.app cannot be opened because it is from an unidentified developer" or "... was not downloaded from the Mac App Store." If it's quarantined but does comply with the policy, you get a message that "X.app is an application downloaded from the internet. Are you sure you want to open it?" (with an Open button available). If it's not quarantined, the check is not performed, and the app opens directly.
You can get more information about the code signing and policy status of an application with spctl --assess -vv /path/to/X.app (which'll tell you whether it complies with the Gatekeeper policy) and codesign -dvv /path/to/X.app.
In summary, quarantine is normal and you should expect your users to experience it (and if you're not seeing it on one of your test computers, there's something wrong with how you're testing). Gatekeeper errors depend on both proper signing (check with codesign and spctl) and the Gatekeeper policy settings on the computer; check both to see what's going on.

Gordon Davissons answer is quite extensive and should help in most cases. In my case, it did not.
Besides the two gatekeeper error messages that he mentions, there is a third one and that is the one from your question:
".app can’t be opened because the identity of the developer cannot be confirmed."
In my case this message came up, when an embedded third party framework had a bad run path setting: LD_RUNPATH_SEARCH_PATHS in build settings did reference something that it was not allowed to.
Apple documents this here https://developer.apple.com/library/content/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG207
If an app uses #rpath or an absolute path to link to a dynamic library
outside of the app, the app will be rejected by Gatekeeper.
And they even state:
Neither the codesign nor the spctl tool will show the error. The error
will only appear in the system log.
The solution was to modify the third party framework to something standard like this:
$(inherited) #executable_path/../Frameworks #loader_path/Frameworks

Related

How to properly sign a Mac application for self-distribution?

I created a Mac file upload client application that implements a high-performance reliable data transfer over UDP protocol, based on the UDT library.
My setup:
MacOS Mojave
Xcode 10.3
Deployment Target: 10.10 (minimum for storyboard-based forms)
Now I'm trying to figure out how to sign it properly so end users can run it without doing a Gatekeeper override.
Here's where I'm at:
I have a paid Apple Developer account, delegated to me from an organization paid Developer account
I have roles assigned to me allowing me to manage apps, certificates, provisioning, etc.
I am signed into this account under Xcode accounts under Preferences.
I have created a bundle registration under the account, copied exactly from Xcode
I have created a Mac Distribution certificate, starting with a CSR from my development machine.
I have downloaded and imported the certificate into my machine's keychain (listed as "3rd Party Mac Developer Application:...")
I have created a provisioning profile for this app, with above certificate assigned, the profile type is App Store, but I will be distributing the app myself (is there a more correct provisioning type?)
Under Entitlements I chose "Custom Network Protocol", which sounds like an accurate description of my application.
I have imported the provisioning profile into Xcode and chose it under Signing (Debug) and Signing (Release) of my project's target, it automatically populated Team (the parent organization) and the above certificate.
I changed the scheme in the project to "Release" and built it for "Running", I get a keychain access prompt during build, and signing step completes successfully
codesign -vvv -d xyz.app returns the registered bundle, certificate, team, etc, all matching the above choices.
I placed the produced .app into a .dmg image and emailed it to myself
I downloaded the .dmg on another Mac and mounted it
I tried running the .app but got the following Gatekeeper message:
"XYZ" can't be opened because it is from an unindentified developer.
Your security preferences allow installation of only apps from the App Store and identified developers.
How do I get around this so a downloaded application will have an "Open" button in the Gatekeeper prompt by default. Some applications, GIMP for example, are correctly identified, even though they did not originate from the App Store.
What do I need to to resolve this?
I kept digging at it and I found my answer:
https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution?language=objc
The type if certificate I needed was Developer ID and the type of provision Developer ID Application, which is what is intended for self-distribution of a signed Mac application.
After that it needs to be submitted to Apple for notarization to satisfy the requirement for 10.14.5+. After notarization had completed I was able to send the exported app to myself and it offered me an "Open" option for the app downloaded from Internet. This is the desired behavior.
It required me to request the account holder to issue me the Developer ID certificate by sending them a CSR, as Developer ID certificate option is greyed out for delegated users that are not the original developer account holder (admin role may satisfy, but I am not one so can't say).
Yay.

iTunes Connect and Xcode 8: your app has changed to invalid binary

Last week, with Xcode 7, I was able to upload without any issue. But today I am getting the message your app has changed to invalid binary.
I have seen that now with Xcode 8 a new icon 20x20 2x and 3x is added. I added one, but still getting the error.
Does anyone had similar problem?
Сheck your email!
In my case, I wasted a lot of time because I did not check my email. When you get such an error, Apple sends you an email with it's description.
For example, this is what Apple sent me:
"This app attempts to access privacy-sensitive data without a usage
description. The app's Info.plist must contain an
NSCameraUsageDescription key with a string value explaining to the
user how the app uses this data."
After days of wrestling with the same problem I finally got my app successfully submitted, but only after being on the phone with Apple Developer support.
A couple of things to keep in mind:
Make sure you set the Info.plist description keys for any entitlements. This is necessary for iOS apps. Mine was a macOS app, so this didn't apply.
Head over to iTunes Connect, and recreate all your provisioning profiles and code signing certificates if you're not 100% sure that they're valid. You can do it for both Developer and Distribution.
In Xcode, turn off automatic code signing for your app, and any build targets (you can try automatic code signing in Xcode after completing steps #2 and #4 but that wasn't what worked for me).
Go to Xcode preferences, and click your development team, and in the sheet that comes up, you should see some "Download" buttons beside the newly created (in iTunes Connect) code signing certificates and provisioning profiles. Click them all. And so you don't get confused in step #5, delete all the other stale provisioning profiles and code signing identities for this app.
In Build Settings for each of your targets, make sure that the Release build setting for code signing, and provision profile are set to the above newly created code signing certificate and provisioning profile.
Bump your build number.
Deep clean your project (Option-Shift-Command-K).
Archive build your app.
In the Organizer that opens up, select the newly archived app, and validate (it always validated, but I still would get Invalid Binary later).
Export the build and select the option "Save for Mac App Store Deployment" or similar.
When prompted, use the same Provisioning Profiles you used previously and save.
Open the .pkg in Application Loader which you can launch from Xcode > Open Developer Tool > Application Loader menu.
I was't getting any emails on the Invalid Binary issue. Instead, I was lucky enough to have set up my iPad with iTunes Connect, and so, like clock-work, I was getting notifications within a couple minutes of uploading the app: "Your app ... has changed to Invalid Binary."
If you don't get one of these Invalid Binary notifications, that's a good sign. Another 10-15 minutes later, I checked the iTunes Connect portal, and I could finally add the uploaded build and submit for review.
After a while of searching, as a last-ditch effort I added every possible 'NS...UsageDescription into each of my target's Info.plist and this seems to have worked. After process of elimination, I deduced that it was either the NSAppleMusicUsageDescription or the NSFaceIDUsageDescription key-string pair that was preventing the upload from being successful so I just added them even though I don't use either in my project. I have also read on some other threads that something with a new version of Xcode required them to have the NSAppleMusicUsageDescription even though they didn't use anything related to Apple Music.

Will Gatekeeper kick in when launching an external unsigned applications from a signed application?

I'm developing an application that will launch other applications (by system("javaws ...) to be specific).
My question is, if I sign my application with my Apple Identified Developer key, will Gatekeeper kick in and show popups / warnings if my application launches other unsigned applications?
(I'd try this out myself, but I don't have an Identified Developer key yet, and I thought I'd ask here before applying for one.)
Here's the only related questions that I've found: How to sign (dynamic) JNLP files for OSX and Gatekeeper
No, Gatekeeper will not show additional warnings if you launch a different unsigned application using system(...).
Gatekeeper works by checking the quarantine flag for a .app bundle, and, if it is set, performing a signature check on that .app bundle before it is launched. (The quarantine flag is stored as an extended attribute when an application is downloaded from the Internet, e.g., with Firefox or Safari.) This seems to happen for users double-clicking a .app from the finder, or from the command-line 'open' utility being invoked. I am not aware of any other mechanisms which trigger a Gatekeeper check.
You can open anything you like using system(..) without Gatekeeper trouble, regardless of whether the executable you are invoking is inside a signed .app bundle or not. Additionally, javaws should not trigger a Gatekeeper check for whatever it opens.

Permission Denied when running Mac app after upgrading to XCode 4.4

I had a working Mac application until I updated to XCode 4.4 and Mountain Lion. Now the application still compiles, but when I try to run it I get an error message.
error: failed to launch '/Users/username/James/mac/Browser/trunk/Browser/DerivedData/Browser/Build/Products/Debug/Browser.app/Contents/MacOS/Browser' -- Permission denied*
Can anybody explain why I might be getting this?
I found this on an iPhone 5 (iOS 6.0) newly set up for development. I had to manually launch the app on the phone, and it said "Are you sure you want to launch this app signed by this devloper?" Once I approved that, the "permission denied" went away and it now launches from Xcode.
Unlock the Device
Try simply unlocking your device before running on it. I was stumped by this very same issue. Upon building and running with no changes to OS, environment, code, etc., I was receiving the error.
Similar questions have been asked here and here, but were not helpful in this situation.
This is caused by an entitlement (and, presumably, having the wrong kind of certificate for it).
If you have the sandbox enabled, and try to sign with a Developer ID certificate, your application will crash on launch (as of Lion—I haven't tried this on Mountain Lion).
If you have iCloud enabled, and try to sign with a Developer ID certificate, your application will not launch at all—in Xcode, you'll get the error message in the question, and in Finder, the application will launch ever so briefly and then get SIGKILLed.
Presumably, there is a right kind of certificate with which one can sign an app in order to be able to test with a sandbox and maybe even iCloud that you can obtain if you have a Mac Developer Program membership. A Developer ID certificate is not that kind of cert.
(That solves my problem, anyway. Dennis, what kind of cert were you trying to sign with?)
Open the organizer and make sure you're mac is in developer mode.
Also check your gatekeeper settings.
The device is seeing the app as an "unauthorized app downloaded from the web" for lack of a better description. Go into Settings > Security & Privacy, and at the bottom, allow applications downloaded from Anywhere.
Throwing a few thoughts on the wall:
Are you perhaps building on an external disk? Some drives get special permissions (like the "ignore permissions" checkbox), or maybe have ACLs set in a weird way. Tried building on internal startup disk?
Are you code signing? Have you tried just turning that off, to see if there's a bug in code signing or entitlements? Not the first time a new codesign tool has a bug.
Have you tried using xcode-select and updating any command line tools that are installed to make sure they all match the version of Xcode used?
Do you have any shell script build phases or the likes that might be editing the application after it's been signed, thus breaking the signature?
Have you checked if your hard disk is full or there's a (broken?) symlink somewhere in a path, or a volume name that has been unmounted?
i am sure this is long been figured out, but I have been getting the Permission denied and it turned out I had to add my laptop to the provisioning profile. I had recently reimaged my machine and in doing so the provisioning profile was no longer valid for that machine. It worked fine until i enabled iCloud. That's when the permission denied started.
Check the organizer in XCODE, click on the devices tab and click on your machine on the left. Check to see that the UDID it shows is listed in the devices section in your mac developer portal.
The short answer is when you get this error message, there is no valid development provisioning profile in the built application.
That alone won't solve your problem! There are a number of common causes of this:
You've moved to a new machine and haven't installed the provisioning profile in Xcode. Also see below
You've moved to a new machine and it's not in developer mode OR not added to the provisioning profile
For both of these, let Xcode regenerate it, or do it yourself in the Member centre... You can validate the causes is something to do with your provisioning profile by running Console and filtering on taskgated where you can see which provisioning profile it is trying to use (it will pull the one embedded in the application first, then try to pull from any installed on the Mac).
Make sure you check in your build settings that the right one is being used for Debug builds. Simple steps that normally resolve (XCode 5)
Go to member centre and create a new development profile
Select the app and certificate
Validate that the machine you are using is in the list of machines to be included in the profile, tick the box
Generate the certificate
Download it, and drag it over the Xcode icon in the doc
Go to the Build Settings tab in your target and set the provisioning profile to the one you've just downloaded
You haven't configured your iCloud/APN/GameCenter entitlements correctly.

Before signing a mac app and uploading it to the app store

I've been dealing with an issue for a while. The issue is that when I submit my mac app to the app store I'm always getting invalid binary and they are saying it's because of an invalid signature. And that I should make sure it's signed with the installer certificate which it is.
Here is the complete message from them:
Dear Developer,
We have discovered one or more issues with your recent binary
submission for "Mini Week". The following issues will need to be
corrected in order for your application to proceed to review:
Invalid Signature - This error occurs when you have signed your app's
installer incorrectly. There are two certs required for this process:
the "3rd Party Mac Developer Application" cert and the "3rd Party Mac
Developer Installer" cert. When signing your package, you need to
ensure that you are using the Installer cert to sign your package.
Ensure that you are specifying this cert when submitting your app via
the Xcode Organizer or when running productbuild from the command
line.
Once you have corrected these issues, go to the app's version details
page (found in the Manage Your Applications module of iTunes Connect)
and click Ready to Submit Binary. Proceed through the submission
process until the app's status is Waiting for Upload. You can then use
Application Loader to upload the corrected binary.
Regards,
The iTunes Store Team
I've revoked and reinstalled my certificates and development providing profile but that doesn't seem to help so I'm assuming that's not the issue.
Is there something else that could cause this? Maybe I need to make sure something is correct in my build settings or something like that? But if so what? :)
Thank you in advance!
Actually, the signing process does not happen when you submit the app from Code Organizer. Conversely, it may happen when you build your app for deployment, but only if you selected the appropriate cert on the "Code Signing Identity" in the target build settings.
Note that you could also manually sign an existing app via command line:
codesign -s "<name of your signing cert>" -fv "<path/to/your/app/bundle>" -o kill,hard
where <name of your signing cert> is the canonical name of your 3rd Party Mac Developer Installer cert. The optional -o kill,hard enforces the code signature for the OS to allow user to launch the application: if you omit this option, an user could open the app bundle, delete the code sign folder, and copy the app on a different machine. With this option, your app bundle will only launch on the authorized machine, and will not run when the signature folder is not present.

Resources