iOS Keychain: Check that the app has an entitlement to use a correct App Group

  Kiến thức lập trình

I have an iOS Keychain wrapper that supports App Groups. The way it works is so that it can be initialized with an App Group and later that App Group will be used for every query with that instance of Keychain:

let keychain = Keychain(name: "ServiceName", appGroup: "com.group.testgroup")
try keychain.set(key: key, value: data)

However, in case the app is missing the entitlement, I won’t get an error during the initialization and instead, reads or writes to the Keychain will fail later on:

2024-04-26 04:57:42.273+0000 ERROR Failed to get data. A required
entitlement isn’t present.

Example of the query used:

    var query = [String: Any]()
    query[kSecClass as String] = kSecClassGenericPassword
    if let name = name {
        query[kSecAttrService as String] = name
    }
    if let appGroup = appGroup {
        query[kSecAttrAccessGroup as String] = appGroup
    }
    query[kSecAttrAccount as String] = key
    query[kSecReturnData as String] = kCFBooleanTrue
    query[kSecMatchLimit as String] = kSecMatchLimitOne
    query[kSecReturnAttributes as String] = kCFBooleanTrue
    var queryResult: CFTypeRef?
    let status = SecItemCopyMatching(query as CFDictionary, &queryResult)

    guard [errSecItemNotFound, errSecSuccess]
        .contains(status) else {
        let error = makeNSError(osStatus: status)
        print("Failed to get data. (error.localizedDescription)")
        throw error
    }

func makeNSError(osStatus: OSStatus) -> Error {
    let description = SecCopyErrorMessageString(osStatus, nil)
    return NSError(domain: NSOSStatusErrorDomain,
                   code: Int(osStatus),
                   userInfo: [NSLocalizedDescriptionKey: description as Any])
}

So, the request fails with the OSStatus -34018. Is there any way I could already figure this out early on, at the initialization stage of the Keychain class, whether the app has the correct entitlement for the App Group?

LEAVE A COMMENT