lokinet/docs/macos-signing.txt
Jason Rhinelander 09372994bb macOS system extension support
Adds support for building Lokinet as a system extension, and fixes
various problems in the macos implementation found during development of
the system extension support.
2022-08-12 21:13:38 -03:00

124 lines
6.9 KiB
Plaintext

If you are reading this to try to build Lokinet for yourself for an Apple operating system and
simultaneously care about open source, privacy, or freedom then you, my friend, are a walking
contradiction: you are trying to get Lokinet to work on a platform that actively despises open
source, privacy, and freedom. Even Windows is a better choice in all of these categories than
Apple.
This directory contains the magical incantations and random voodoo symbols needed to coax an Apple
build. There's no reason builds have to be this stupid, except that Apple wants to funnel everyone
into the no-CI, no-help, undocumented, non-toy-apps-need-not-apply modern Apple culture.
This is disgusting.
But it gets worse.
The following two files, in particular, are the very worst manifestations of this already toxic
Apple cancer: they are required for proper permissions to run on macOS, are undocumented, and can
only be regenerated through the entirely closed source Apple Developer backend, for which you have
to pay money first to get a team account (a personal account will not work), and they lock the
resulting binaries to only run on individually selected Apple computers selected at the time the
profile is provisioned (with no ability to allow it to run anywhere).
lokinet.dev.provisionprofile
lokinet-extension.dev.provisionprofile
This is actively hostile to open source development, but that is nothing new for Apple.
There are also release provisioning profiles
lokinet.release.provisionprofile
lokinet-extension.release.provisionprofile
These ones allow distribution of the app, but only if notarized, and again require notarization plus
signing by a (paid) Apple developer account.
In order to make things work, you'll have to replace these provisioning profiles with your own
(after paying Apple for the privilege of developing on their platform, of course) and change all the
team/application/bundle IDs to reference your own team, matching the provisioning profiles. The dev
provisioning profiles must be a "macOS Development" provisioning profile, and must include the
signing keys and the authorized devices on which you want to run it. (The profiles bundled in this
repository contains the lokinet team's "Apple Development" keys associated with the Oxen project,
and mac dev boxes. This is *useless* for anyone else).
For release builds, you still need a provisioning profile, but it must be a "Distribution: Developer
ID" provisioning profile, and are tied to a (paid) Developer ID. The ones in the repository are
attached to the Oxen Project Developer ID and are useless to anyone else.
Once you have that in place, you need to build and sign the package using a certificate matching
your provisioning profile before your Apple system will allow it to run. (That's right, your $2000
box won't let you run programs you build from source on it unless you also subscribe to a $100/year
Apple developer account).
Okay, so now that you have paid Apple more money for the privilege of using your own computer,
here's how you make a signed lokinet app:
1) Decide which type of build you are doing: a lokinet system extension, or an app extension. The
former must be signed and notarized and will only work when placed in the /Applications folder,
but will not work as a dev build and cannot be distributed outside the Mac App Store. The latter
is usable as a dev build, but still requires a signature and Apple-provided provisioningprofile
listing the limited number of devices on which it is allowed to run.
For system extension builds you want to add the -DMACOS_SYSTEM_EXTENSION=ON flag to cmake.
2) Figure out the certificate to use for signing and make sure you have it installed. For a
distributable system extension build you need a "Developer ID Application" key and certificate,
issued by your paid developer.apple.com account. For dev builds you need a "Apple Development"
certificate.
In most cases you don't need to specify these; the default cmake script will figure them out.
(If it can't, e.g. because you have multiple of the right type installed, it will error with the
keys it found).
To be explicit, use `security find-identity -v` to list your keys, then list the key identity
with -DCODESIGN_ID=.....
3) If you are doing a system extension build you will need to provide notarization login information by adding:
-DMACOS_NOTARIZE_ASC=XYZ123 -DMACOS_NOTARIZE_USER=me@example.com -DMACOS_NOTARIZE_PASS=@keychain:codesigning-password
a) The first value (XYZ123) needs to be the organization-specific unique value, and is printed in
brackets in the certificate description. For example:
15095CD1E6AF441ABC69BDC52EE186A18200A49F "Developer ID Application: Some Developer (ABC123XYZ9)"
would require ABC123XYZ9 for this field.
b) The USER field is your Apple Developer login e-mail address.
c) The PASS field is a keychain reference holding your "Application-Specific Password". To set
up such a password for your account, consult Apple documentation. Once you have it, load it
into your keychain via:
export HISTFILE='' # Don't want to store this in the shell history
xcrun altool --store-password-in-keychain-item "codesigning-password" -u "user" -p "password"
You can change "codesigning-password" to whatever you want (just make sure it agrees with the
-DMACOS_NOTARIZE_PASS option you build with). "user" and "password" should be your developer
account device-specific login credentials provided by Apple.
To make your life easier, stash these settings into a `~/.notarization.cmake` file inside your
home directory; if you have not specified them in the build, and this file exists, lokinet's
cmake will load it:
set(MACOS_NOTARIZE_USER "me@example.com")
set(MACOS_NOTARIZE_PASS "@keychain:codesigning-password")
set(MACOS_NOTARIZE_ASC "ABC123XYZ9")
4) Build and sign the package; there is a script `contrib/mac.sh` that can help (extra cmake options
you need can be appended to the end), or you can build yourself in a build directory. See the
script for the other cmake options that are typically needed. Note that `-G Ninja` (as well as a
working ninja builder) are required.
If you get an error `errSecInternalComponent` this is Apple's highly descriptive way of telling
you that you need to unlock your keychain, which you can do by running `security unlock`.
If doing it yourself, `ninja sign` will build and then sign the app.
If you need to also notarize (e.g. for a system extension build) run `./notarize.py` from the
build directory (or alternatively `ninja notarize`, but the former gives you status output while
it runs).
5) Packaging the app: you want to use `-DBUILD_PACKAGE=ON` when configuring with cmake and then,
once all signing and notarization is complete, run `cpack` which will give you a .dmg and a .zip
containing the release.