Read item from keychain right after creating

I'm working with custom keychain in my application and I have problems with reading keychain item right after adding new one. This is code example:


let path = "/tmp/testkeychain_48"
let password = "password"
let serviceName = "service"
let account = "account"
let data = "data".data(using: .utf8)
var keychain: SecKeychain? = nil

var status = SecKeychainCreate(path, UInt32(password.characters.count), password, false, nil, &keychain)
assert(status == errSecSuccess)

var query: [String: AnyObject] = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrService as String: serviceName as AnyObject,
    kSecAttrAccount as String: account as AnyObject,
    kSecValueData as String: data as AnyObject,
    kSecUseKeychain as String: keychain as AnyObject,
]
var item: CFTypeRef? = nil
status = SecItemAdd(query as CFDictionary, &item)
assert(status == errSecSuccess)
assert(item != nil)

query = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrService as String: serviceName as AnyObject,
    kSecAttrAccount as String: account as AnyObject,
    kSecMatchLimit as String: kSecMatchLimitAll as AnyObject,
    kSecUseKeychain as String: keychain as AnyObject,
]
status = SecItemCopyMatching(query as CFDictionary, &item)
assert(status == errSecSuccess)
assert(item != nil)
  
try? FileManager.default.removeItem(atPath: path)


SecItemAdd(_:_)
returns success but
SecItemCopyMatching(_:_)
fails with error
The specified item could not be found in the keychain
. With default keychain all works correctly.

Replies

It wasn’t clear from your post whether the key issue here is “right after creating” or whether there’s a more general problem with reading items from a custom keychain. If you split these tasks into two, one that does the create and one that does the read, what happens? Critically, after running the create code, you can use Keychain Access (or

security
) to inspect the keychain to see if things got created correctly.

If you’re running this code in an app, you can just wire this up to two separate buttons. Or if you’re in a command line tool, you can have two tools, or two options to the same tool to trigger the separate behaviour.

Share and Enjoy

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

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

Thanks for response. I've solved my issue. I just need to use

kSecMatchSearchList
instead of
kSecUseKeychain
for reading from keychain.