Xcode code signing madness

February 23 2020 by Jeff Johnson

I was trying to build my app StopTheMadness, which I had been building successfully in Xcode for years, but suddenly the build started failing with a mysterious code signing error. Argh!

error: Embedded binary is not signed with the same certificate as the parent app. Verify the embedded binary target's code sign settings match the parent app's.

Embedded Binary Signing Certificate: - (Ad Hoc Code Signed)
Parent App Signing Certificate: Apple Development: Jeff Johnson

Huh? I checked the build settings for my Safari extension — the aforementioned embedded binary — and it uses the same code signing identity as the app. Moreover, the project's build settings hadn't changed at all.

Then I looked at the build transcript for the Safari extension, specifically at the code signing phase, and I discovered this:

Warning: unable to build chain to self-signed root for signer Apple Development: Jeff Johnson

Strangely, the warning did not appear in the Xcode build issues, only the error did, which is why I didn't see the warning until I read the entire transcript. The other strange thing was the mention of "self-signed". Development certificates are not self-signed, they're signed by Apple! This is what prompted me to look at the certificate in Keychain Access app, where I found a warning that the "certificate is not trusted", despite the fact that the certificate was issued by the Apple Worldwide Developer Relations Certification Authority. What the…?

I looked at the WWDR cert in my keychain, and it doesn't expire until 2023, so that seemed fine. But looking again at my development certificate, I noticed that it said Not Valid Before February 20, 2021, which was just a few days ago. So this was a recently generated certificate, although I didn't generate one manually. It seems that my previous development certificate expired, and Xcode generated a new certificate automatically. Which is fine, that's what Xcode is supposed to do, because I have "Automatically manage signing" enabled in my Xcode project settings. Yet there was still a problem.

I actually have two Macs, an Intel MacBook Pro that I use as my main development machine, and a new M1 Mac Mini that I use as a test and build machine. The build error was occurring on my Intel Mac, but when I switched to my M1 Mac there were no problems. Looking at the other keychain, I was surprised to find two Apple WWDR intermediate certificates: the one that expires in 2023, and another one that expires in 2030! It turns out that a few weeks ago Apple started signing development certificates with a newer intermediate certificate, the one that expires in 2030.

The new Apple Worldwide Developer Relations Intermediate Certificate is downloaded automatically by Xcode 11.4.1 or later and is available for download on the Certificate Authority page. Confirm that the correct intermediate certificate is installed by verifying that the expiration date is set to 2030.

Xcode 12.2 is installed on my M1 Mac, so it must have downloaded the new WWDR cert, but my Intel Mac only has Xcode 11.3.1 installed. Despite the fact that Xcode 11.3.1 successfully generated the new development cert, it neglected to download the Apple intermediate cert that was used to sign the new development cert. Which resulted in mysterious code signing errors for me.

The solution was to manually download the new WWDR intermediate cert and add it to my Intel Mac keychain. According to Apple, "Xcode 11.4.0 and earlier may not be able to sign software using signing certificates issued by the new Apple Worldwide Developer Relations Certification Intermediate Certificate", but I'm having no trouble with it. My app doesn't use any special entitlements or any Apple "services", however, so YMMV.

Jeff Johnson (My apps, PayPal.Me)