.. _apple_codesign_certificate_management: ================================== Managing Code Signing Certificates ================================== In order to add cryptographic signatures using this tool, you'll need to use a :ref:`apple_codesign_code_signing_certificate`. (Follow the link for what that means.) In order to perform code signing in a way that is recognized and trusted by Apple operating systems, you will need to obtain a code signing certificate that is signed/issued by Apple. This requires joining the `Apple Developer Program `_, which has an annual membership fee. Once you are a member, there are various ways to generate and manage your certificates. But first, a primer about flavors of Apple code signing certificates. Apple Code Signing Certificate Flavors ====================================== Apple issues different types/flavors of code signing certificates. Each one is used to sign a different class of software. If you are logged into your Apple Developer account, you can see Apple's description for these at https://developer.apple.com/account/resources/certificates/add. Here's our concise definitions: *Apple Development* Sign applications for Apple operating systems that aren't distributed publicly. *Apple Distribution* Sign applications for submission to the App Store or for Ad Hoc distribution. *iOS App Development* Legacy version of *Apple Development* just for iOS apps. (We think.) *iOS Distribution* Legacy version of *Apple Distribution* just for iOS apps. (We think.) *Mac Development* Legacy version of *Apple Development* just for macOS apps. (We think.) *Mac App Distribution* Sign macOS applications and configure a Distribution Provisioning Profile for distribution through Mac App Store. *Mac Installer Distribution* Sign package installers (e.g. ``.pkg`` files) which will be distributed via the Mac App Store. *Developer ID Installer* Sign package installers (e.g. ``.pkg`` files) which will be distributed outside the Mac App Store. i.e. if users fetch your installer via your website, you sign with this. *Developer ID Application* Sign applications which will be distributed outside the Mac App Store. Used for signing Mach-O binaries, ``.app`` bundles, and ``.dmg`` files. Essentially, if you are distributing macOS software to end-users via non-Apple channels like your website, you need *Developer ID Application* and/or *Developer ID Installer*. If you are distributing via Apple's App stores, you need *Apple Distribution* or one of the other types having *Distribution* in the name. .. tip:: The ``rcodesign analyze-certificate`` command can be used to print information about Apple code signing certificates. Look for a line with ``Certificate Profile`` in its output to see which flavor of certificate this software thinks it is. Generating Certificates with Xcode ================================== Using Xcode from macOS is probably the easiest way to create and manage your certificates as Xcode has built-in UI to facilitate this. Apple keeps thorough `documentation about how to do this `_. Please follow Apple's documentation to generate a certificate. Obtaining a Certificate via a Certificate Signing Request ========================================================= You can obtain a code signing certificate by uploading a *Certificate Signing Request (CSR)* to Apple. Essentially, you generate a CSR, send it to Apple, and Apple will issue a new code signing certificate which you can download. A CSR is produced by creating a cryptographic signature (using a *private key*) over a small set of metadata describing the *private key* for which a certificate shall be issued. In order to generate a CSR, you need a *private key*. As of April 2022, Apple appears to require the use of RSA 2048 private keys. If you have access to macOS, the easiest way to generate a private key and CSR is to use ``Keychain Access`` using the `procedure outlined here `_. If you want to generate your own CSR using ``rcodesign``, follow instructions in one of the following sections. If you already have a CSR, skip ahead to :ref:`apple_codesign_exchange_csr`. .. _apple_codesign_generate_csr_from_p12: Generating a CSR from a ``.p12`` / ``.pfx`` File ------------------------------------------------ If you've exported a ``.p12`` / ``.pfx`` / PKCS#12 file from ``KeyChain Access.app`` or some other source, you can use ``rcodesign`` to turn it into a CSR:: rcodesign generate-certificate-signing-request --p12-file cert.p12 --p12-password my-password This command will print the CSR to stdout. e.g.:: -----BEGIN CERTIFICATE REQUEST----- MIHeMIGDAgEAMCExHzAdBgNVBAMMFkFwcGxlIENvZGUgU2lnbmluZyBDU1IwWTAT BgcqhkjOPQIBBggqhkjOPQMBBwNCAAQxluBlPIv/HgBDz0O3GLPhhna/NJU7menq GzUc9sZFOgZ7XmpR9vQTxHPEyg5D6huBapVQZsDG9IgAXjvSOmimoAAwDAYIKoZI zj0EAwIFAANIADBFAiEAoZpbfrlm7HgQXByfwuoPt7/V+QM7DCIILcTKCBrkIZUC IEIp8yA9bSg7bM9XJl8bgFesTjermlSYQI/2JY834/z7 -----END CERTIFICATE REQUEST----- You probably want to use ``--csr-pem-file`` to write that to a file automatically:: rcodesign generate-certificate-signing-request --p12-file cert.p12 --p12-password my-password --csr-pem-file csr.pem Generating a CSR From a YubiKey or Other SmartCard Device --------------------------------------------------------- See the instructions at :ref:`apple_codesign_smartcard_key_generation`. .. _apple_codesign_generate_rsa_key_and_csr: Generating an RSA Private Key and CSR ------------------------------------- To generate an RSA 2048 private key using OpenSSL:: openssl genrsa -out private.pem 2048 .. warning:: The RSA private key will be in plain text on your filesystem. This is not very secure! Then once you have a private key, we can generate a CSR using ``rcodesign``:: rcodesign generate-certificate-signing-request --pem-file private.pem Like the instructions above, you probably want to use ``--csr-pem-file`` to save the CSR data to a file for submission to Apple. .. _apple_codesign_exchange_csr: Exchanging a CSR for a Code Signing Certificate ----------------------------------------------- Once you have a CSR file, you can attempt to exchange it for a code signing certificate. 1. Go to https://developer.apple.com/account/resources/certificates/add (you must be logged into Apple's website) 2. Select the certificate *flavor* you want to issue. 3. Click ``Continue`` to advance to the next form. 4. Select the ``G2 Sub-CA (Xcode 11.4.1 or later)`` *Profile Type* (we support it). 5. Choose the file containing your CSR. 6. Click ``Continue``. 7. If all goes according to plan, you should see a page saying ``Download Your Certificate``. 8. Click the ``Download`` button. 9. Save the certificate somewhere. (The file content is likely not sensitive and doesn't need to be kept secret because this content will be copied to everything you sign with it!) At this point, you have both a *private key* and a *public certificate*: you can sign Apple software! Exporting a Code Signing Certificate to a File ============================================== ``rcodesign`` supports consuming code signing certificates from multiple sources, including hardware devices. But sometimes it is desirable to have your code signing certificate exist as a file. Use the instructions in one of the following sections to export a code signing certificate. .. danger:: It is generally accepted that private keys stored in files are less secure than stored in special operating system enclaves like keychains. This is because the operating system has protections around accessing the private keys and these protections are often much stronger than those on a file on the filesystem. This tool has support for using certificates / keys directly from macOS keychains. So exporting to a file is not always necessary. Using Keychain Access --------------------- (macOS) 1. Open the ``Keychain Access`` application. 2. Find the certificate you want to export and command click or right click on it. 3. Select the ``Export`` option. 4. Choose the ``Personal Information Exchange (.p12)`` format and select a file destination. 5. Enter a password used to protect the contents of the certificate. 6. If prompted to enter your system password to unlock your keychain, do so. The exported certificate is in the PKCS#12 / PFX / p12 file format. Command arguments with these labels in the same can be used to interact with the exported certificate. Using Xcode ----------- (macOS) See `Apple's Xcode documentation `_. Using ``security`` ------------------ (macOS) 1. Run ``security find-identity`` to locate certificates available for export. 2. Run ``security export -t identities -f pkcs12 -o keys.p12`` If you have multiple identifies (which is common), ``security export`` will export all of them. ``security`` doesn't seem to have a command to export just a single certificate pair. You will need to invoke some ``openssl`` command to extract just the certificate you care about. Please contribute back a fix for this documentation once you figure it out! Using a Self-Signed Certificate =============================== If you want to cut some corners and play around with certificates not signed by Apple, you can run ``rcodesign generate-self-signed-certificate`` to generate a self-signed code signing certificate. This command will include special attributes in the certificate that indicate compatibility with Apple code signing. However, since the certificate isn't signed by Apple, its signatures won't confer the same trust that Apple signed certificates would. These certificates can be useful for debugging and testing.