I can't get SecIdentity from Keychain

hello, Im trying to use ClientCertificate at iOS app.


First,I get PKCF#12 from web


Second, I get SecIdentity using SecPKCF12import to store identity, And It's Success(get "0" in "status" and get SecIdentity in "identity")

let options = [kSecImportExportPassphrase as String: password]
let status = SecPKCS12Import(data!, options as CFDictionary, &rawItems)
let identity = items[0][kSecImportItemIdentity as String] as! SecIdentity


Then, store identity in keychain,and its Success(get "0" in "status" )

query = [
    kSecClass as String:kSecClassIdentity,
    kSecValueRef as String:identity,
    kSecAttrLabel as String:"1234567890" as AnyObject
]
let status = SecItemAdd(query as CFDictionary, nil)


After that, I tried to get SecIdentity from keychain,but its Fail(get "-25300" in "status" )

query = [
     kSecClass as String:kSecClassIdentity,
     kSecReturnRef as String:true as AnyObject,
     kSecAttrLabel as String:"1234567890" as AnyObject,
     kSecMatchLimit as String:kSecMatchLimitAll
]
var result:AnyObject? = nil
let status = SecItemCopyMatching(query as CFDictionary, &result)


Why?

Should I need to do something more?


Sorry for showing only a part of source code.

please give me advice..

Answered by DTS Engineer in 298464022

Using labels on an identity is tricky because identities are not stored in the keychain as an atomic item but are store as a separate private key and certificate, and those items use labels in different ways. Have you tried using a persistence reference here? That is:

  1. Pass

    kSecReturnPersistentRef
    to
    SecItemAdd
    when you add the identity to the keychain
  2. Save the persistent reference wherever

  3. Later on, when you need the identity back, call

    SecItemCopyMatching
    with that persistent reference

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Accepted Answer

Using labels on an identity is tricky because identities are not stored in the keychain as an atomic item but are store as a separate private key and certificate, and those items use labels in different ways. Have you tried using a persistence reference here? That is:

  1. Pass

    kSecReturnPersistentRef
    to
    SecItemAdd
    when you add the identity to the keychain
  2. Save the persistent reference wherever

  3. Later on, when you need the identity back, call

    SecItemCopyMatching
    with that persistent reference

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Im sorry , if I misunderstand,

you said

"Pass

kSecReturnPersistentRef
to
SecItemAdd
when you add the identity to the keychain"

it mean like this?

query = [
    kSecClass as String:kSecClassIdentity,
    kSecValueRef as String:value2,
    kSecReturnPersistentRef as String : true as AnyObject
]
var returndata:CFTypeRef?
let status = SecItemAdd(query as CFDictionary, &returndata)

let persitentdata = returnData as! CFData

I tried this, but I got "nil" in returndata...


Am I wrong something?

Finally I could get that

I refered to this discussion https://forums.developer.apple.com/thread/43568


I don't know why but it's work when using SecItemAdd without kSecClass inside query of parameter.

And also when using SecItemCopyMatching without kSecClass , it worked!


thank you for your help!

Thank you sho@jp, Your reply for removing the kSecClass from the SecItemAdd helped me too. I did not remove it from the query for SecItemCopyMatching as it gave me a -50 error (errSecParam). I'd appreciate it if I knew why removing the kSecClass worked and if that's the regular case, the Apple docs should be updated to notify users.

I agree, this should be adapted in the documentation, as Storing an Identity in the Keychain gives a completely different implementation example, slightly adapted to Storing a Certificate in the Keychain, which does not work for me when I implement it.


I opened a Feedback/Bug Ticket: FB6706964

Thank you for opening the bug. I CC'd myself on it to get better insight on where the documentation gaps might be.


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

I can't get SecIdentity from Keychain
 
 
Q