We are trying to write a command line tool that will setup a VPN tunnel following a customized protocol.
One step is making sure that the client is starting the connection from a company MacBook by responding to a challenge by signing it with a private key stored in the secure enclave. For the communication with the secure enclave we want to use the EllipticCurveKeyPair project.
When we first ran our tool and tried to access the secure enclave, we got an error thrown from the EllipticCurveKeyPair manager:
underlying(message: "Could not generate keypair.", error: Error Domain=NSOSStatusErrorDomain Code=-34018 "Could not generate keypair." UserInfo={NSLocalizedRecoverySuggestion=See https://www.osstatus.com/search/results?platform=all&framework=all&search=-34018, NSLocalizedDescription=Could not generate keypair.}).
which refers to the error
errSecMissingEntitlement | -34018 | Internal error when a required entitlement isn't present. |
So, we figured that entitlements are missing to access the secure enclave.
To resolve this, we tried to apply the settings of the EllipticCurveKeyPair MacOS demo project to our MacOS command line tool project. So, we added the capability App Sandbox and configured the entitlements keychain-access-groups, com.apple.security.get-task-allow, com.apple.security.files.user-selected.read-only, as in
?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.application-identifier</key>
<string>####</string>
<key>com.apple.developer.game-center</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>####</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>####</string>
</array>
</dict>
</plist>
With the sandbox configured we run into the next problems:
When we execute the tool in Xcode, Xcode will halt execution, and display an error message in the debugger, some place in the code where the sandbox appears to be initialized:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
We made sure that our tool uses a bundleID on its own to avoid sandbox initialization issues arising from multiple apps using the same bundle ID.
When we execute the tool from the command line, we get the error
Illegal instruction: 4
When using codesign -d --entitlements - CmdLineTool we get this list of entitlements
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
Also, we read through the articles available here:
- https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html
- https://eclecticlight.co/2019/01/15/code-signing-for-the-concerned-1-why/ and following articles
Now the question:
- How do we have to proceed to get access to the secure enclave from a command line tool to
- create key pairs
- use private keys to sign / encrypt strings
- Is it necessary or even possible to configure App Sandbox for the command line tool?
Thanks for any help!