Digitally Signing the application
On This Page
WHAT YOU NEED
OS X 10.9 ("Mavericks") or Higher
SIGNING SCRIPT
Note: This page describes how to digitally sign the Tunnelblick application or a rebranded version. Please read Digital Signatures before the rest of this page.
WHAT YOU NEED
To digitally sign the application (Tunnelblick or a rebranded version), you need:
- OS X 10.9 ("Mavericks") or higher;
- A copy of the unsigned application;
- A code signing certificate; and
- An optional "designated requirement" binary.
OS X 10.9 ("Mavericks") or Higher
You need Mac OS X 10.9 ("Mavericks") because OS X 10.10 ("Yosemite") requires applications to be signed using OS X 10.9.
###Unsigned Application
To get an unsigned version of Tunnelblick or your rebranded version, build an "Unsigned Release" of the source code using the instructions at Building From Source.
###Code signing Certificate
The code signing certificate can be a "self-signed" certificate or a certificate from Apple. There is one difference: if you use a self-signed certificate, Gatekeeper in OS X 10.8 ("Mountain Lion") and higher may not allow the first run of the self-signed application by double-clicking it. The user will need to Control-click and click "Open". That is because the Gatekeeper default is to allow the first launch of an application only if it is signed by an Apple-recognized developer.
To get a self-signed code signing certificate, use the macOS Keychain Assistant application. Apple used to have instructions on doing this but they have disappeared. They may be accessed from the Internet Archive using this link,
To get an certificate from Apple, you must be an Apple Developer. Request your Apple certificates and install them into your Keychain. You can do this from Xcode.
###Designated Requirement Binary
You can use a "designated requirement binary" to set requirements for how an application is to be signed. For example, you can require that the Info.plist's CFBundleIdentifier be "com.example.foo". Generating this binary can be done in Xcode, consult Apple's documentation. The only catch is that requirements created in some recent versions of Xcode are considered invalid by OS X 10.5 ("Lion") and will cause problems. Tunnelblick uses a signing requirements binary created on an older version of Xcode that does not cause this problem. See Gatekeeper vs. Leopard: an ongoing tale.
SIGNING SCRIPT
Use following script to sign Tunnelblick or a rebranded version of Tunnelblick:
#!/bin/bash
#
# sign-tunnelblick
#
# A script to digitally sign Tunnelblick.app or a rebranded version of Tunnelblick.app
#
if [ "$1" == "" ] ; then
echo "Usage:"
echo " sign-tunnelblick app_path certificate_name requirements_path"
exit 1
fi
app_path="$1"
certificate_name="$2"
requirements_path="$3"
# Sign the helpers
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}/Contents/Resources/atsystemstart"
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}/Contents/Resources/installer"
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}/Contents/Resources/openvpnstart"
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}/Contents/Resources/process-network-changes"
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}/Contents/Resources/standardize-scutil-output"
# Before signing each of the signed tun & tap kexts, remove ' Unsigned' from its Info.plist
signed_tun_path="${app_path}/Contents/Resources/tun-signed.kext"
signed_tap_path="${app_path}/Contents/Resources/tap-signed.kext"
tun_path="${app_path}/Contents/Resources/tun.kext"
tap_path="${app_path}/Contents/Resources/tap.kext"
rm -r "${signed_tun_path}"
rm -r "${signed_tap_path}"
sed -e "s| Unsigned||g" "${tun_path}/Contents/Info.plist" > "${signed_tun_path}/Contents/Info.plist"
sed -e "s| Unsigned||g" "${tap_path}/Contents/Info.plist" > "${signed_tap_path}/Contents/Info.plist"
# Sign the *signed* tun and tap kexts, but don't sign the other tun and tap kexts
codesign -s "${certificate_name}" -r "${requirements_path}" "${signed_tun_path}"
codesign -s "${certificate_name}" -r "${requirements_path}" "${signed_tap_path}"
# Sign the openvpn and openvpn-down-root.so binaries
for d in `ls "${app_path}/Contents/Resources/openvpn"`
do
if [ "${d}" != "default" ] ; then
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}/Contents/Resources/openvpn/${d}/openvpn"
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}/Contents/Resources/openvpn/${d}/openvpn-down-root.so"
fi
done
# Sign Sparkle
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}/Contents/Frameworks/Sparkle.framework/Versions/A"
# Sign the application itself
codesign -s "${certificate_name}" -r "${requirements_path}" "${app_path}"
|