auth0/SimpleKeychain

Does not work in iOS13.4 simulator

sam-w opened this issue ยท 19 comments

sam-w commented

Description

When using the iOS13.4 simulator, SimpleKeychain reports that it saved successfully. When I try to retrieve the saved object, I get empty data.

Reproduction

  • Add this to a fresh Xcode project , e.g. in the AppDelegate.
let keychain = A0SimpleKeychain()
keychain.setString("foo", forKey: "f")
let string = keychain.string(forKey: "f")!
assert(string == "foo")
  • Run on iOS 12.4 sim, no assert.
  • Run on iOS 13.4 sim, assertion failed.

Environment

  • Version of this library used: 0.11.0
  • Version of the platform or framework used, if applicable: iOS 13.4 simulator

On iOS 13.3 simulator it works as well. So just the newest iOS simulator seems to be affected.

sam-w commented

https://github.com/evgenyneu/keychain-swift does work on iOS 13.4 simulator, so might provide a point of comparison.

Thanks for reporting @sam-w , does it work on 13.4 device?

@cocojoe Yes, it works on a physical device with 13.4.

Having the same issue here on iOS 13.4 simulator.

Updated my device to 13.4, test suite results:

13.4 Device - All Passing
13.4 Simulator - Failing

Odd situation, working on device implies that code is fine. However, it should work on the simulator of course. So possibly simulator bug or a configuration issue of some kind? Since it was mentioned keychain-swift is okay (I've not checked). cc @Widcket

Did a little debugging and going through previous commits, if you comment this line out then all tests pass in the simulator. So we will dig into this more.

https://github.com/auth0/SimpleKeychain/blob/master/SimpleKeychain/A0SimpleKeychain.m#L305

https://github.com/evgenyneu/keychain-swift does work on iOS 13.4 simulator, so might provide a point of comparison.

Had a look, as suspected it doesn't make any use of LAContext that I can see.

This seems to be a bug in the iOS 13.4 simulator, as it's reproducible just with the Keychain API:

let laContext = LAContext()
let key = "foo"

let query = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrService as String: key,
    kSecValueData as String: "bar".data(using: .utf8)!,
    // kSecUseAuthenticationContext as String: laContext
] as [String : Any]

SecItemAdd(query as CFDictionary, nil)

let loadQuery = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrService as String: key,
    kSecReturnData as String: kCFBooleanTrue!,
    // kSecUseAuthenticationContext as String: laContext
] as [String : Any]

var dataTypeRef: CFTypeRef?
SecItemCopyMatching(loadQuery as CFDictionary, &dataTypeRef)

print(String(data: (dataTypeRef as? Data) ?? "nope!".data(using: .utf8)!, encoding: .utf8)!)

Uncomment the lines and it will print nope! instead of bar.

@sam-w and all, one possible workaround is to disable kSecUseAuthenticationContext for simulator targets. I've set up a branch with the changes, can you give it a try?

sam-w commented

@Widcket still fails for me on 13.4 with your branch.

dionc commented

Possibly related, in the 13.4 simulator hasValueForKey returns true for any key:

(lldb) po self
<A0SimpleKeychain: 0x7fd916471b80>

(lldb) po hasValue(forKey: UUID().uuidString)
true

@sam-w can you comment out linehttps://github.com/auth0/SimpleKeychain/blob/master/SimpleKeychain/A0SimpleKeychain.m#L305
please and feedback.

@Widcket I don't think the branch you provided has the changes committed.

@cocojoe you're right, my bad. I've just pushed the commit.

@dionc that method uses SecItemCopyMatching under the hood. It seems to return a successful status whenever a kSecUseAuthenticationContext is included:

let laContext = LAContext()

let loadQuery = [
  kSecClass as String: kSecClassGenericPassword,
  kSecAttrService as String: UUID().uuidString,
  kSecUseAuthenticationContext as String: laContext
] as [String : Any]

let result = SecItemCopyMatching(loadQuery as CFDictionary, nil)
print("Result: \(result == errSecSuccess)") // Result: true

@sam-w and all, the workaround is out in the 0.11.1 release. Thanks for the report and the input.

sam-w commented

Thanks @Widcket. Given that keychain access has proved to be an issue as iOS continues to develop, I'd like to have the option of using an alternative to SimpleKeychain in the future. Please consider reopening auth0/Auth0.swift#367 so we can achieve that.

ezzz commented

Thanks for the correction!