I've been trying over the past few days to use a PIV-programmed Yubikey to perform mTLS (i.e. mutual client cert auth) in my custom app. My understanding is that I need to feed NSURLSession a SecIdentity to do so.
Yubico's instructions state that I need their Yubico Authenticator app for this, but this directly contradicts Apple's own documentation here. I dont need NFC/lightening support, and I only need support for my specific app.
When I plug in my key to my iPhone and have TKTokenWatcher active, I DO see "com.apple.pivtoken" appear in the logs. And using Yubico's SDK, I CAN get data from the key (so I'm pretty sure my entitlements and such are correct).
But using the below query to get the corresponding (fake? temporary?) keychain item, it returns NULL no matter what I do:
let query: [String: Any] = [
kSecClass as String: kSecClassIdentity,
kSecReturnRef as String: true,
kSecAttrTokenID as String: "apple.com.pivtoken", // Essential for shared iPads
kSecMatchLimit as String: kSecMatchLimitOne
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
"status" is always -25300 (which is "not found").
I've also created a CTK extension (as Yubico's authenticator does) and tried to use self.keychainContents.fill(), and then tried to access it with kSecAttrTokenID as "<myAppExtensionId>:Yubico YubiKey OTP+FIDO+CCID", as that's what shows via TKTokenWatcher, and this also doesn't work. I've also tried just the app extension ID, and that doesn't work. Both my extension and my main app have the following entitlements:
<key>com.apple.developer.default-data-protection</key>
<string>NSFileProtectionComplete</string>
<key>com.apple.security.application-groups</key>
<array/>
<key>com.apple.security.smartcard</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.apple.pivtoken</string>
<string>$(AppIdentifierPrefix)myAppExtensionId</string>
</array>
As one final test, I tried using the yubikey in safari to access my server using mTLS, and it works! I get prompted for a PIN (which is odd because I've programmed it not to require a PIN), but the request succeeds using the key's default PIN. I just cannot get it working with my own app.
Can anyone here (or preferably, at Apple) point me in the right direction? I have a feeling that the documentation I've been reading applies to MacOS, and that iOS/ipadOS have their own restrictions that I either need to work around, or which prevent me from doing what I need to do. It's obviously possible (i.e. the Yubico Authenticator sort of does what I need it to), but not in the way that Apple seems to describe in their own documentation.