Saturday, February 18, 2017

Fixing (and Explaining) PDFpen 8.3.1’s Crash on Launch

Adam C. Engst:

Greg said that the reason PDFpen crashed — even before it actually launched — was because Smile’s developer signing certificate from Apple had expired.

[…]

In the past, the expiration of a code signing certificate had no effect on already shipped software. PDFpen 6.3.2, which Smile still makes available for customers using OS X 10.7 Lion, 10.8 Mountain Lion, and 10.9 Mavericks, is signed with a certificate that expired long ago, and it has no trouble launching.

What’s new with PDFpen 8 is that, in addition to being code signed, it has a provisioning profile, which is essentially a permission slip from Apple that’s checked against an online database in order to allow the app to perform certain actions, called entitlements. For PDFpen, the entitlement that’s being granted is the capability to access iCloud despite being sold directly, rather than through the Mac App Store, a feature that wasn’t possible until about a year ago.

It sounds like every Developer ID app that uses iCloud has a built-in time bomb. Something is not designed properly here. First, why does Apple issue certificates with relatively short expiration dates? They already have a means of revoking certificates in the event of a problem. Second, why does the OS check whether the code signing certificate is valid now, as opposed to when the provisioning profile was signed?

Previously: CloudKit and Map Kit for Gatekeeper Apps, More Mac App Store Certificate Problems, WWDR Intermediate Certificate Expiration.

Update (2017-02-20): See also: MacRumors, Acqualia.

Update (2017-02-22): Rick Fillion:

Due to the expired Provisioning Profile, 1Password mini wouldn’t launch. And without mini running, 1Password itself was unable to startup successfully. Both mini and 1Password itself were signed with the same Developer ID certificate. Gatekeeper allowed 1Password to run, but due to the different rules for apps with provisioning profiles, it would not allow mini to run.

As far as we can tell, the only way to correct this problem is to provide a new build of the app with an updated provisioning profile with a new expiration date.

[…]

When we generated our updated provisioning profile we also needed to generate a new Developer ID certificate. We didn’t realize it at the time, but the common name of newly created certificates now include the team identifier in addition to the company name; “Developer ID Application: AgileBits Inc. (2BUA8C4S2C)” vs. “Developer ID Application: AgileBits Inc.”. Close. Super close. But we weren’t looking for a “close” match.

Rick Fillion:

In case you’re wondering how to tell when a provisioning profile will expire you can run security cms -D -i on the Terminal to have it output information about a profile.

Update (2017-02-24): Rob Griffiths:

Follow me now, if you wish, for a somewhat deep dive into the world of code signing, as I attempt to explain—from a consumer’s perspective yet with a developer’s hat on—what is code signing, why these apps broke, why the breakage wasn’t expected, and other related questions and answers.

[…]

Follow me now, if you wish, for a somewhat deep dive into the world of code signing, as I attempt to explain—from a consumer’s perspective yet with a developer’s hat on—what is code signing, why these apps broke, why the breakage wasn’t expected, and other related questions and answers. Apple explicitly tells developers—in at least two places—that they only need these certificates to build new apps or update existing apps. So if you have a certificate that’s set to expire, but you don’t have an urgent need to update an app or create a new app, it’s supposed to be a non-event.

[…]

So the app can’t tell the user what’s going on, and even worse, the OS doesn’t tell the user what’s going on: The app just seemingly dies in an instant. That’s bad for the user, and bad for the developer, because they’re blamed for something they didn’t even know was occurring (because their app never loads, and no crash reports are generated). If the OS is going to kill the app, the OS should tell the user why it did so, so the user has some understanding about the problem.

Update (2017-03-09): Greg Scown:

Looks like Apple has addressed the Provisioning Profile issue.

3 Comments RSS · Twitter

"Because that's how it works on iOS" is the obvious but unsatisying answer.

Specifically, on iOS:
- ad hoc signing certificates expire one year after issued
- enterprise signing certificates expire three years after issued
- both ad hoc and enterprise provisioning profiles expire one year after they were created/last edited, or with the expiration of the certificate they're tied to, whichever is sooner.
- once the provisioning profile expires, the app will no longer start, and there is no clear error messages around this to explain why to the user

For ad hoc distribution, this kind of makes sense; it's meant for in-house testing, and the device's UDID must also be listed in the provisioning profile for the app to install on the device.

For enterprise, it's silly. There's a one year shelf life (at best) for every build of an enterprise iOS app. Large enterprises tend to be very change-averse; when they get a tool that meets their requirements they want to stick with that for a long time. The short expiry is an unnecessary support burden.

"First, why does Apple issue certificates with relatively short expiration dates?"

Because $$$$$$$. Otherwise, some developers would not renew their subscription as often. e.g. I'm still using my Developer ID Application certificate but haven't renewed my subscription during the last 5 years. I will have to renew it later this year or early next year as the certificate is about to expire.

The only constraint is that you need to be careful not to lose your certificate and private key as when the subscription has expired, the Apple Developer website does not let you access the Certificates section (which is a bug IMHO).

Leave a Comment