Hi Apple Developer Technical Support,
We have a locally signed macOS system daemon that an administrator starts manually. It needs to use a dedicated P-256 signing key in a file-based keychain. We want macOS to let only the exact approved build use that key, without a prompt. A different build signed with the same certificate should be denied.
Apple’s published Security source shows that the keychain can identify some callers by their code directory hash (cdhash). Is setting a key’s partition list to that exact hash a supported way to enforce this restriction for a system daemon? If so, which macOS versions support it, and what API or Apple tool should we use to configure it?
After setup, how can we verify that the intended key has the exact restriction in place, including whether any broader rule allows another process to sign with the key, export it, or change its access rules? If macOS doesn’t offer a supported way to set and verify this restriction, please confirm that limitation.
The easiest way to achieve this goal is to ad hoc sign (Sign to Run Locally in Xcode parlance) your daemon. If you do this then it’s designated requirement (DR) is set to its cdhash, which then flows through into the keychain ACL.
Note For more about DRs, see TN3127 Inside Code Signing: Requirements.
Consider this code:
import Foundation
// `secCall(…)` is from <https://developer.apple.com/forums/thread/710961>.
func main() throws {
let k = try secCall { SecKeyCreateRandomKey([
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits: 256,
kSecAttrIsPermanent: true,
] as NSDictionary, $0) }
print(k)
}
try main()
I built it into a tool with ad hoc signing:
% codesign -d -vvv Test856050
…
CodeDirectory v=20400 size=556 flags=0x2(adhoc) …
…
The system synthesises a DR based on the cdhash:
% codesign -d -r - Test856050
…
# designated => cdhash H"a52923c51b919c8d6495b09156f91363e3f63c10"
And the keychain used the DR to track access:
% ./Test856050
<SecCDSAKeyRef 0x7c08c20e40: algorithm id: 3, class=1, algorithm=49, usage=186 attrs=21>
% security dump-keychain -a ~/Library/Keychains/login.keychain-db
…
keychain: "/Users/quinn/Library/Keychains/login.keychain-db"
version: 512
class: 0x00000010
attributes:
0x00000000 <uint32>=0x00000010
…
access: 5 entries
entry 0:
authorizations (1): encrypt
don't-require-password
description: <key>
applications: <null>
entry 1:
authorizations (6): decrypt derive export_clear export_wrapped mac sign
don't-require-password
description: <key>
applications (1):
0: /Users/quinn/Test856050 (OK)
requirement: cdhash H"a52923c51b919c8d6495b09156f91363e3f63c10"
entry 2:
authorizations (1): integrity
don't-require-password
description: 328e407327a906f55b16f2853356fafc497034f54645c681f8346bdb31b9786c
applications: <null>
entry 3:
authorizations (1): partition_id
don't-require-password
description: cdhash:a52923c51b919c8d6495b09156f91363e3f63c10
applications: <null>
entry 4:
authorizations (1): change_acl
don't-require-password
description: <key>
applications (0):
…
Here the cdhash shows up in two places:
- The traditional ACL entry (1)
- The partition ID entry (3)
Either would be sufficient to enforce this restriction.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"