Code Signing for Auxiliary Executables Causes SSL Error kCFStreamErrorDomainSSL

Posted in |

KosmicTask utilises SSL/TLS to ensure the privacy of network communications.

The app also utilises code signing to gain seamless access to the keychain and to permit incoming communications to be routed through the application firewall (see http://developer.apple.com/technotes/tn2007/tn2206.html).

Debug builds of the application worked as expected and SSL communications were established and operative.

Building for release though was another story. SSL communications failed with error kCFStreamErrorDomainSSL code -9800 (Operation could not be completed).

The only clue that this was related to code signing was the appearance of the application firewall prompt asking if the KosmicTask should allow incoming network communications. Having previously wrangled with code signing I had created a wrapper class for codesign and logged the validity of the apps various signed components to the application About window. Checking this revealed that, sure enough, the release build app had a code signing problem.

KosmicTask consists of three fundamental components, all of which are signed.

  1. The main app bundle. This contains the main client executable and the two auxiliary executables listed below
  2. The KosmicTaskServer component which receives requests and generates instances of the script runner component
  3. The KosmicTaskRunner component which encapsulates a script execution instance

The debug build of the app reported that all components were signed and valid. However, the release build reported that only the application bundle was valid and that the server and runner components were invalid.

Anyone who has spent much time with Xcode will comprehend the power and flexibility of the build environment. But when build issues arise it can be difficult resolving exactly which setting is causing a problem. And when projects contain embedded sub-projects and numerous targets for auxiliary executables, plug-ins and frameworks then the hierarchical nature of the way that build settings are imposed means that very close attention needs to be paid to every target build setting.

The Apple build system guide is here
http://tuvix.apple.com/documentation/DeveloperTools/Conceptual/XcodeBuil.... In Particular see the section on Build Setting Evaluation.

The Apple build setting ref is here http://tuvix.apple.com/documentation/DeveloperTools/Reference/XcodeBuild....

My approach to solving this was threefold:

  1. Remove as many target level build settings as possible so that most of the build setting definition occurs at the project level. This makes it a lot easier to enforce gross build setting changes and makes it less likely that a rogue target level build setting is causing a problem
  2. Modify the troublesome Release build configuration so that it matches the Debug configuration. This can be achieved by simply modifying the Release config (which is interesting because you get to see exactly what the differences are) or by duplicating the existing build configuration and renaming it.
  3. At the project level disable every build setting that related to deployment, copying and stripping - in effect everything within the Deployment settings category.

Doing this resolved the SSL issue, at least proving that a build setting was at fault. Reinstating the previous Release build settings one by one eventually revealed the culprit:

Strip Debug Symbols During Copy (COPY_PHASE_STRIP)

The Research Assistant abstract for this states:

Activating this setting causes binary files which are copied during the build (e.g., in a Copy Bundle Resources or Copy Files build phase) to be stripped of debugging symbols. It does not cause the linked product of a target to be stripped (use Strip Linked Product for that). [COPY_PHASE_STRIP]

No stripping was in effect as Deployment Postprocessing (DEPLOYMENT_POSTPROCESSING) was off. However it seems that DEPLOYMENT_POSTPROCESSING is not a pre-requisite for COPY_PHASE_STRIP as it is for STRIP_INSTALLED_PRODUCT (Strip Linked Product). So debug stripping of copied binaries was occurring - which occurs after the binary has been signed and therefore causes the signature invalidation of our auxiliary executables.

A point of note is that COPY_PHASE_STRIP seems to be enabled at the Xcode default build setting level so that unless you override it you are more or less certain to run into this problem in Xcode 3.1 with code signed auxiliary executables.

One unresolved point is that I was unable to determine exactly why the debug build succeeded as it seemed to have COPY_PHASE_STRIP enabled too. Thumps head off table.

Another point is why the SSL communication failed. Code signing is intimately examined by various security subsystems so I can only presume that the SSL subsystem finds an invalid code signature anathema. Scratches head.

Submitted by Jonathan Mitchell on Tue, 08/18/2009 - 10:09

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
Let us know you are human.
6 + 3 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.