Hi,
I'm trying to fix an issue in RMStore and reviewing its keychain part. Based on best practise posted here and WWDC 2013 Session 709 "Protecting Secrets with the Keychain".
The issue in short: for a very small percentage of customers, the IAPs stored in the keychain are not accessible and restore of these IAPs also fails. No developer was able to reproduce the issue so far.
The following question will only focus on kSecClassGenericPassword and OS X.
When querying for an item it's best to query for just the keys that are required to make the item unique. For a generic password that's kSecClass, kSecAttrService and kSecAttrAccount. ( https://devforums.apple.com/message/959334#959334)
RMStore also stores and searches for kSecAttrGeneric, see here.
It seems to be no where document how important the right corresponding value per attribute is. A lot of sample code on the internet and the Apple GenericKeychain sample doesn't follow the documentation.
kSecAttrGeneric - Generic attribute key.
The corresponding value is of type CFDataRef and contains a user-defined attribute. Items of class kSecClassGenericPassword have this attribute.
kSecAttrAccount - Account attribute key.
The corresponding value is of type CFStringRef and contains an account name. Items of class kSecClassGenericPassword and kSecClassInternetPassword have this attribute.
Yet in GenericKeychain sample for kSecAttrGeneric a CFStringRef is used. And RMStore sets CFDataRef for kSecAttrAccount, see here.
Update: In the debugger if I query kSecReturnAttributes the attributes don't contain kSecAttrAccount. Only cdat, class, gena, labl, mdat, svce. So I assume because of the wrong type it doesn't get stored. Or is it because one of the two is choosen for uniques and the other is disregard?
Question 1: Is for kSecClassGenericPassword the attributes kSecClass, kSecAttrService, kSecAttrGeneric enough? Or does it require kSecAttrAccount?
Question 2: How is the query behaviour for attributes that are not required to make the item unique. Right now the code searchs for kSecClass, kSecAttrService, kSecAttrGeneric and kSecAttrAccount. See here. But in the store we only have kSecClass, kSecAttrService, kSecAttrGeneric. Yet the search works most of the times.
Recap of the issue: unable to access IAP and restore fails.
This suggest to me that the search for kSecClass, kSecAttrService, kSecAttrGeneric and kSecAttrAccount works most of the times. But can break for a currently unknown reason. The restore fails because it uses the same search and if nothing is found it trys do add the item. See here. But the add fails because an item with the unique part of kSecClass, kSecAttrService and kSecAttrGeneric already exists.
Would appreciate any insight into this!