What makes a keychain object unique (in iOS)?

My question is about key fobs in iOS (iPhone, iPad, ...). I think (but not sure) that implementing keychains under Mac OS X poses the same question with the same answer.




iOS provides five types (classes) of keychain elements. You must select one of these five values โ€‹โ€‹for the kSecClass key to determine the type:

 kSecClassGenericPassword used to store a generic password kSecClassInternetPassword used to store an internet password kSecClassCertificate used to store a certificate kSecClassKey used to store a kryptographic key kSecClassIdentity used to store an identity (certificate + private key) 

After a long time reading apple documentation, blogs and forum posts, I found out that the keychain element of type kSecClassGenericPassword gets its uniqueness from the attributes kSecAttrAccessGroup , kSecAttrAccount and kSecAttrService .

If these three attributes in request 1 are the same as in request 2, you get the same common key password element, regardless of any other attributes. If one (or two or all) of these attributes changes its value, you get different elements.

But kSecAttrService is only available for elements of type kSecClassGenericPassword , so it cannot be part of the "unique key" of an element of any other type, and there seems to be no documentation that clearly indicates which attributes uniquely identify the keychain element.

The sample code in the "KeychainItemWrapper" class from "GenericKeychain" uses the kSecAttrGeneric attribute to make the element unique, but this is a mistake. Two entries in this example are saved only as two different entries because their kSecAttrAccessGroup is different (one has a group of access groups and the other is freed). If you try to add a second password without an access group using the Apple KeychainItemWrapper , you will fail.

So please answer my questions:

  • Is it true that the combination of kSecAttrAccessGroup , kSecAttrAccount and kSecAttrService is the "unique key" of the keychain element whose kSecClass is kSecClassGenericPassword ?
  • What attributes make a keychain element unique if its kSecClass not kSecClassGenericPassword ?
+80
ios objective-c keychain macos
Jul 23 '12 at 14:00
source share
2 answers

The primary keys are as follows (obtained from open source files from Apple, see Schema.m4 , KeySchema.m4, and SecItem.cpp ):

  • For a keychain element of class kSecClassGenericPassword primary key is a combination of kSecAttrAccount and kSecAttrService .
  • For a keychain element of class kSecClassInternetPassword primary key is a combination of kSecAttrAccount , kSecAttrSecurityDomain , kSecAttrServer , kSecAttrProtocol , kSecAttrAuthenticationType , kSecAttrPort and kSecAttrPath .
  • For a keychain element of class kSecClassCertificate primary key is a combination of kSecAttrCertificateType , kSecAttrIssuer and kSecAttrSerialNumber .
  • For a keychain element of class kSecClassKey primary key is a combination of kSecAttrApplicationLabel , kSecAttrApplicationTag , kSecAttrKeyType , kSecAttrKeySizeInBits , kSecAttrEffectiveKeySize , and the creator, the start date, and the end date are not opened yet.
  • For the keychain element of the kSecClassIdentity class kSecClassIdentity I did not find information about the primary key fields in the open source files, but since the identifier is a combination of the private key and certificate, I assume that the primary key is the combination of the primary key fields for kSecClassKey and kSecClassCertificate .

Since each keychain element belongs to a keychain access group, it looks like the keychain access group ( kSecAttrAccessGroup field) is an added field to all of these primary keys.

+133
Jul 26 '12 at 15:00
source share

I came across a bug the other day (on iOS 7.1) that is related to this issue. I used SecItemCopyMatching to read the kSecClassGenericPassword element and it continued to return errSecItemNotFound (-25300), although kSecAttrAccessGroup , kSecAttrAccount and kSecAttrService all matched the item in the keychain.

In the end, I realized that kSecAttrAccessible does not match. The value in the keychain contained pdmn = dk ( kSecAttrAccessibleAlways ), but I used kSecAttrAccessibleWhenUnlocked .

Of course, this value is not required first of all for SecItemCopyMatching , but OSStatus did not have errSecParam and errSecBadReq , but simply errSecItemNotFound (-25300), which made it somewhat difficult to find.

For SecItemUpdate , I had the same problem, but in this method even using the same kSecAttrAccessible in the query parameter does not work. Fixed only the complete removal of this attribute.

I hope this comment saves some important debugging points for some of you.

+7
Jul 11 '14 at 2:25
source share



All Articles