Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 539 Vote(s) - 3.49 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What makes a keychain item unique (in iOS)?

#1
My question concerns keychains in iOS (iPhone, iPad, ...). I think (but am not sure) that the implementation of keychains under Mac OS X raises the same question with the same answer.

---

iOS provides five types (classes) of keychain items. You must chose one of those five values for the key `kSecClass` 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 long time of reading apples documentation, blogs and forum-entries, I found out that a keychain item of type `kSecClassGenericPassword` gets its uniqueness from the attributes `kSecAttrAccessGroup`, `kSecAttrAccount` and `kSecAttrService`.

If those three attributes in request 1 are the same as in request 2, then you receive the same generic password keychain item, regardless of any other attributes. If one (or two or all) of this attributes changes its value, then you get different items.

But `kSecAttrService` is only available for items of type `kSecClassGenericPassword`, so it can't be part of the "unique key" of an item of any other type, and there seems to be no documentation that points out clearly which attributes uniquely determine a keychain item.

The sample code in the class "KeychainItemWrapper" of "GenericKeychain" uses the attribute `kSecAttrGeneric` to make an item unique, but this is a bug. The two entries in this example only are stored as two distinct entries, because their `kSecAttrAccessGroup` is different (one has the access group set, the other lets it free). If you try to add a 2nd password without an access group, using Apple's `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 a keychain item whose kSecClass is `kSecClassGenericPassword`?
- Which attributes makes a keychain item unique if its `kSecClass` is not `kSecClassGenericPassword`?
Reply

#2
The primary keys are as follows (derived from open source files from Apple, see [Schema.m4][1], [KeySchema.m4][2] and [SecItem.cpp][3]):

- For a keychain item of class `kSecClassGenericPassword`, the primary key is the combination of
`kSecAttrAccount` and `kSecAttrService`.
- For a keychain item of class `kSecClassInternetPassword`, the primary key is the combination of `kSecAttrAccount`, `kSecAttrSecurityDomain`, `kSecAttrServer`, `kSecAttrProtocol `, `kSecAttrAuthenticationType`, `kSecAttrPort` and `kSecAttrPath`.
- For a keychain item of class `kSecClassCertificate`, the primary key is the combination of `kSecAttrCertificateType`, `kSecAttrIssuer` and `kSecAttrSerialNumber `.
- For a keychain item of class `kSecClassKey`, the primary key is the combination of `kSecAttrApplicationLabel`, `kSecAttrApplicationTag`, `kSecAttrKeyType`,
`kSecAttrKeySizeInBits`, `kSecAttrEffectiveKeySize`, and the creator, start date and end date which are not exposed by SecItem yet.
- For a keychain item of class `kSecClassIdentity` I haven't found info on the primary key fields in the open source files, but as an identity is the combination of a private key and a certificate, I assume the primary key is the combination of the primary key fields for `kSecClassKey` and `kSecClassCertificate`.

As each keychain item belongs to a keychain access group, it feels like the keychain access group (field `kSecAttrAccessGroup`) is an added field to all these primary keys.

[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

Reply

#3
I was hitting a bug the other day (on iOS 7.1) that is related to this question. I was using `SecItemCopyMatching` to read a `kSecClassGenericPassword` item and it kept returning `errSecItemNotFound` (-25300) even though `kSecAttrAccessGroup`, `kSecAttrAccount` and `kSecAttrService` were all matching the item in the keychain.

Eventually I figured out that `kSecAttrAccessible` didn't match. The value in the keychain held pdmn = dk (`kSecAttrAccessibleAlways`), but I was using `kSecAttrAccessibleWhenUnlocked`.

Of course this value is not needed in the first place for `SecItemCopyMatching`, but the `OSStatus` was not `errSecParam` nor `errSecBadReq` but just `errSecItemNotFound` (-25300) which made it a bit tricky to find.

For `SecItemUpdate` I have experienced the same issue but in this method even using the same `kSecAttrAccessible` in the `query` parameter didn't work. Only completely removing this attribute fixed it.

I hope this comment will save few precious debugging moments for some of you.
Reply

#4
Answer given by @Tammo Freese seems to be correct (but not mentioning all primary keys). I was searching for some proof in the documentation. Finally found:

**[Apple Documentation mentioning primary keys for each class of secret (quote below):](

[To see links please register here]

)**

> The system considers an item to be a duplicate for a given keychain when that keychain already has an item of the same class with the same set of composite primary keys. Each class of keychain item has a different set of primary keys, although **a few attributes are used in common across all classes. In particular, where applicable, kSecAttrSynchronizable and kSecAttrAccessGroup are part of the set of primary keys**. The additional per-class primary keys are listed below:
>
> - For generic passwords, the primary keys **include kSecAttrAccount and
kSecAttrService.**
> - For internet passwords, the primary keys **include kSecAttrAccount,
kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol,
kSecAttrAuthenticationType, kSecAttrPort, and kSecAttrPath.**
> - For certificates, the primary keys **include kSecAttrCertificateType,
kSecAttrIssuer, and kSecAttrSerialNumber.**
> - For key items, the primary keys **include kSecAttrKeyClass,
kSecAttrKeyType, kSecAttrApplicationLabel, kSecAttrApplicationTag,
kSecAttrKeySizeInBits, and kSecAttrEffectiveKeySize.**
> - For identity items, which are a certificate and a private key bundled
together, the primary keys are **the same as for a certificate.** Because
a private key may be certified more than once, the uniqueness of the
certificate determines that of the identity.
Reply

#5
Here is another piece of useful information about uniqueness of a keychain item, found in the "Ensure Searchability" section of [this Apple docs page][1].

> To be able to find the item later, you’re going to use your knowledge of its attributes. In this example, the server and the account are the item’s distinguishing characteristics. For constant attributes (here, the server), use the same value during lookup. In contrast, the account attribute is dynamic, because it holds a value provided by the user at runtime. **As long as your app never adds similar items with varying attributes (such as passwords for different accounts on the same server), you can omit these dynamic attributes as search parameters and instead retrieve them along with the item. As a result, when you look up the password, you also get the corresponding username.**
>
> If your app does add items with varying dynamic attributes, you’ll need a way to choose among them during retrieval. One option is to record information about the items in another way. For example, if you keep records of users in a Core Data model, you store the username there after using keychain services to store the password field. Later, you use the user name pulled from your data model to condition the search for the password.
>
> In other cases, it may make sense to further characterize the item by adding more attributes. For example, you might include the [`kSecAttrLabel`][2] attribute in the original add query, providing a string that marks the item for the particular purpose. Then you’ll be able to use this attribute to narrow your search later.


Item of class `kSecClassInternetPassword` was used in the example, but there is a note that says:

> Keychain services also offers the related kSecClassGenericPassword item class. Generic passwords are similar in most respects to Internet passwords, but they lack certain attributes specific to remote access (for example, they don’t have a kSecAttrServer attribute). When you don’t need these extra attributes, use a generic password instead.

[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through