Documentation/Nightly/Developers/Mac OS X Code Signing

From Slicer Wiki
Jump to: navigation, search
Home < Documentation < Nightly < Developers < Mac OS X Code Signing

Overview

This page contains information on code signing on OS X and on integrating code signing into the Slicer packaging process.

Some useful external references from the Mac Developer Library include:

Prerequisites

The Gatekeeper feature in OS X helps protect against malicious software. If a user runs an application downloaded from the internet, Gatekeeper verifies the application's digital signature and displays a warning if verification fails. Reasons verification might fail include the app having been tampered with, or the app not having been signed at all.

Currently the OS X Slicer package is not digitally signed. Therefore, depending on system configuration, Gatekeeper may display a warning and confirmation dialog when running a new Slicer build for the first time.

Developer ID certificate

A Developer ID certificate is required to sign an application for distribution outside of the Mac App Store. Once Slicer is signed with this type of certificate, Gatekeeper's signature verification will succeed and users will be able to run Slicer without warnings.

Only the team agent for an organization in the Apple Developer program has authority to create Developer ID certificates. Certificates can be created using Xcode or on the Apple Developer site: https://developer.apple.com/account/mac/certificate/.

There are two types of Developer ID certificates: Developer ID Application certificate and Developer ID Installer certificate. Only the Developer ID Application certificate is required to sign Slicer. The Developer ID Installer certificate is used to sign installers in .pkg format.

Using a self-signed certificate as opposed to a Developer ID certificate is appropriate while testing the packaging process. To create a self-signed certificate, follow the steps in Obtaining a Signing Identity described in the section titled "To use the Certificate Assistant to create a self-signed signing identity."

App identifier

Code signing an application requires a unique app identifier. If each new build of an application is signed using the same identifier, Gatekeeper will recognize new builds as being an updated version and will transparently run the updated version as usually without requested verification from the user.

The unique app identifier can be specified in different ways:

  • implicitly from the value of CFBundleIdentifier in the application's Info.plist
  • explicitly on the command line when signing the code (e.g. codesign -i <identifier>)

For Slicer, in the first case, the factory could set the CMake variable MACOSX_BUNDLE_GUI_IDENTIFIER (see CMake/MacOSXBundleInfo.plist.in). In the second case, a new CMake variable could be added and used when signing the code.

The unique app identifiers are typically hierarchical names in reverse DNS notation.[1] Therefore, an appropriate identifier could be something like com.kitware.medical.Slicer.

Authentication

Depending on the environment in which code signing is being performed, it may be necessary to take one or more of the following steps to use the codesign tool without user interaction (i.e. authentication):

  • Run security unlock-keychain, like here
  • In Keychain Access, edit the certificate's private key to "allow all applications to access this item" (right click on the private key, then choose Get Info)
  • Add the signing certificate to the system keychain instead of the login keychain

Also see the following discussions:

Code signing

The codesign command signs the code; its usage is summarized below. See Signing Your Code for more information. Advanced options for specifying requirements and entitlements shouldn't be necessary when signing Slicer.

Tasks

List all certificates to verify the name of the Developer ID Application certificate to use:

   certtool y

Sign Slicer using a Developer ID Application certificate:

   codesign --deep --force --sign "Developer ID Application: <id>" ./Slicer.app

Sign Slicer using a self-signed certificate (for testing):

   codesign --deep --force --sign "<certificate id>" ./Slicer.app

However, note that Apple does not recommend using the --deep option when signing.[2]

Show signing info:

   codesign -dv

Show designated requirements[3]:

   codesign -d -r- ./Slicer.app

Verify signature (mimic what Gatekeeper does to check your app):

   codesign --verify --deep --verbose=2 ./Slicer.app

 

Integration with CPack

Preliminary testing shows one possible way to integrate code signing into Slicer's packaging process with CPack.

After running fixup_bundle in CMake/SlicerCPackBundleFixup.cmake.in (or outside the function after calling fixup_bundle_with_plugins?), call codesign like:

   execute_process(
     COMMAND codesign --deep --force --sign "<certificate id>" -i "<unique app identifier>" "${app_dir}"
   )

Note that <certificate id> and <unique app identifier> should be CMake variables.

The process could also verify the signing:

   execute_process(
     COMMAND codesign -dv "${app_dir}"
   )

Logic could be added to only sign if the required CMake variables are specified.

Note that the CPack Bundle generator can be configured to sign by setting variables such as CPACK_BUNDLE_APPLE_CERT_APP. However, this cannot be used here because Slicer uses the DragNDrop generator (see CMake/SlicerCPack.cmake).

Verifying

See Checking Gatekeeper Conformance and Verifying Your Steps for detailed instructions on how to verify a signed application works with Gatekeeper.

The spctl tool tests code signatures against Gatekeeper policies and manages the security assessment policy subsystem. Some basic commands using the spctl tool are summarized below.

Tasks

List current assessment rules:

   spctl --list --type execute

Assess an application or tool:

   spctl --assess --type execute ./Slicer.app

Show whether assessment is enabled:

   spctl --status

Check if Gatekeeper will accept the app's signature:

   spctl -a -t exec -vv ./Slicer.app

Reference list

  1. Adding an Info.plist to Single-File Tools, Mac Developer Library—Code Signing Guide
  2. Using the codesign Tool's --deep Option Correctly, Mac Developer Library—OS X Code Signing In Depth
  3. Code Requirements, Mac Developer Library—OS X Code Signing In Depth