Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
aehlke committed Jul 2, 2024
1 parent 135f8bd commit 15460db
Showing 1 changed file with 24 additions and 38 deletions.
62 changes: 24 additions & 38 deletions Distrib/KeychainSwiftDistrib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ open class KeychainSwift {
*/
open var synchronizable: Bool = false

private let lock = NSLock()
private let recursiveLock = NSRecursiveLock()


/// Instantiate a KeychainSwift object
Expand Down Expand Up @@ -102,10 +102,10 @@ open class KeychainSwift {

// The lock prevents the code to be run simultaneously
// from multiple threads which may result in crashing
lock.lock()
defer { lock.unlock() }
recursiveLock.lock()
defer { recursiveLock.unlock() }

deleteNoLock(key) // Delete any existing key before saving it
delete(key) // Delete any existing key before saving it

let accessible = access?.value ?? KeychainSwiftAccessOptions.defaultOption.value

Expand Down Expand Up @@ -181,8 +181,8 @@ open class KeychainSwift {
open func getData(_ key: String, asReference: Bool = false) -> Data? {
// The lock prevents the code to be run simultaneously
// from multiple threads which may result in crashing
lock.lock()
defer { lock.unlock() }
recursiveLock.lock()
defer { recursiveLock.unlock() }

let prefixedKey = keyWithPrefix(key)

Expand Down Expand Up @@ -241,10 +241,23 @@ open class KeychainSwift {
open func delete(_ key: String) -> Bool {
// The lock prevents the code to be run simultaneously
// from multiple threads which may result in crashing
lock.lock()
defer { lock.unlock() }
recursiveLock.lock()
defer { recursiveLock.unlock() }

return deleteNoLock(key)
let prefixedKey = keyWithPrefix(key)

var query: [String: Any] = [
KeychainSwiftConstants.klass : kSecClassGenericPassword,
KeychainSwiftConstants.attrAccount : prefixedKey
]

query = addAccessGroupWhenPresent(query)
query = addSynchronizableIfRequired(query, addingItems: false)
lastQueryParameters = query

lastResultCode = SecItemDelete(query as CFDictionary)

return lastResultCode == noErr
}

/**
Expand Down Expand Up @@ -279,32 +292,6 @@ open class KeychainSwift {
return []
}

/**
Same as `delete` but is only accessed internally, since it is not thread safe.
- parameter key: The key that is used to delete the keychain item.
- returns: True if the item was successfully deleted.
*/
@discardableResult
func deleteNoLock(_ key: String) -> Bool {
let prefixedKey = keyWithPrefix(key)

var query: [String: Any] = [
KeychainSwiftConstants.klass : kSecClassGenericPassword,
KeychainSwiftConstants.attrAccount : prefixedKey
]

query = addAccessGroupWhenPresent(query)
query = addSynchronizableIfRequired(query, addingItems: false)
lastQueryParameters = query

lastResultCode = SecItemDelete(query as CFDictionary)

return lastResultCode == noErr
}

/**
Deletes all Keychain items used by the app. Note that this method deletes all items regardless of the prefix settings used for initializing the class.
Expand All @@ -316,8 +303,8 @@ open class KeychainSwift {
open func clear() -> Bool {
// The lock prevents the code to be run simultaneously
// from multiple threads which may result in crashing
lock.lock()
defer { lock.unlock() }
recursiveLock.lock()
defer { recursiveLock.unlock() }

var query: [String: Any] = [ kSecClass as String : kSecClassGenericPassword ]
query = addAccessGroupWhenPresent(query)
Expand Down Expand Up @@ -505,4 +492,3 @@ public enum KeychainSwiftAccessOptions {
}
}


0 comments on commit 15460db

Please sign in to comment.