kSecUseDataProtectionKeychain creates sometimes keys into icloud keychain

Hi,

On my macos 13.4.1 if we use kSecUseDataProtectionKeychain to save passwords into the keychain, then the keys are create sometimes into login keychain, but sometimes into iCloud(or Local items when iCloud is disabled). If kSecUseDataProtectionKeychain is removed, then they are always into login.

I've even tried to set kSecAttrSynchronizable to kCFBooleanFalse, but the behaviour is the same.

Where should the keys be created when kSecUseDataProtectionKeychain is used?

And does it mean that if the key is into the iClound keychain it will be sync on other devices, even if it doesn't have kSecAttrSynchronizable?

Thanks

First up, I’m going to use the terms from TN3137 On Mac keychain APIs and implementations. Read it before continuing here.

On my macos 13.4.1 if we use kSecUseDataProtectionKeychain to save passwords into the keychain, then the keys are create sometimes into login keychain, but sometimes [in the data protection keychain]

When you add an item using SecItemAdd, specifying kSecUseDataProtectionKeychain will always result in the item going into the data protection keychain. It’ll never go into the file-based keychain. If you see that happening, that’s very likely a bug in your code or an issue with how you’re interpreting the results.

Keep in mind that, once you create an item, it’ll stay in the keychain that you created it in. So a common source of confusion is to create an item in the file-based keychain, then update your code to use kSecUseDataProtectionKeychain, and then wonder why it’s still in the file-based keychain.

If you rule out the above possibility and are still seeing problems, please post a snippet showing how you reproduce the issue.

And does it mean that if the key is into the [data protection] keychain it will be sync on other devices, even if it doesn't have kSecAttrSynchronizable?

No. Items in the data protection keychain are only synced if:

  • iCloud Keychain is enabled

  • kSecAttrSynchronizable is set

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for info, very helpful.

Actually we have this case in our app, the keys were created without kSecUseDataProtectionKeychain and at a later app update it was added kSecUseDataProtectionKeychain. In this case, if the keys were created without kSecUseDataProtectionKeychain and then updated, will they use kSecUseDataProtectionKeychain or they must be deleted and recreated so they are moved to data protection keychain?

Regarding the random creation place for me I always delete the keys from keychain using Keychain.app, then I'm running the app app and the keys are recreated(always with kSecUseDataProtectionKeychain). I'll spend some more time to reproduce the issue maybe from another test app.

Thanks

if the keys were created without kSecUseDataProtectionKeychain and then updated, will they use kSecUseDataProtectionKeychain

Updating with SecItemUpdate?

I don’t think so. AFAIK there’s no easy way to move keychain items from the file-based keychain to the data protection keychain, or vice versa. You have to get the item and then add it to the new place. For most items that’s just scutwork, but for private keys in the file-based keychain it’s really tricky because such keys are typically not extractable and, even when they are, extracting the key trigger typically triggers an authorisation alert.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

kSecUseDataProtectionKeychain creates sometimes keys into icloud keychain
 
 
Q