77
88import Foundation
99import Security
10+ import Amplify
1011
1112// swiftlint:disable identifier_name
1213public protocol KeychainStoreBehavior {
@@ -76,6 +77,7 @@ public struct KeychainStore: KeychainStoreBehavior {
7677 var attributes = KeychainStoreAttributes ( service: service)
7778 attributes. accessGroup = accessGroup
7879 self . init ( attributes: attributes)
80+ log. verbose ( " [KeychainStore] Initialized keychain with service= \( service) , attributes= \( attributes) , accessGroup= \( accessGroup ?? " " ) " )
7981 }
8082
8183 @_spi ( KeychainStore)
@@ -84,12 +86,13 @@ public struct KeychainStore: KeychainStoreBehavior {
8486 /// - Parameter key: A String key use to look up the value in the Keychain
8587 /// - Returns: A string value
8688 public func _getString( _ key: String ) throws -> String {
87-
89+ log . verbose ( " [KeychainStore] Started retrieving `String` from the store with key= \( key ) " )
8890 let data = try _getData ( key)
89-
9091 guard let string = String ( data: data, encoding: . utf8) else {
92+ log. error ( " [KeychainStore] Unable to create String from Data retrieved " )
9193 throw KeychainStoreError . conversionError ( " Unable to create String from Data retrieved " )
9294 }
95+ log. verbose ( " [KeychainStore] Successfully retrieved string from the store " )
9396 return string
9497
9598 }
@@ -100,6 +103,7 @@ public struct KeychainStore: KeychainStoreBehavior {
100103 /// - Parameter key: A String key use to look up the value in the Keychain
101104 /// - Returns: A data value
102105 public func _getData( _ key: String ) throws -> Data {
106+ log. verbose ( " [KeychainStore] Started retrieving `Data` from the store with key= \( key) " )
103107 var query = attributes. defaultGetQuery ( )
104108
105109 query [ Constants . MatchLimit] = Constants . MatchLimitOne
@@ -113,12 +117,16 @@ public struct KeychainStore: KeychainStoreBehavior {
113117 switch status {
114118 case errSecSuccess:
115119 guard let data = result as? Data else {
120+ log. error ( " [KeychainStore] The keychain item retrieved is not the correct type " )
116121 throw KeychainStoreError . unknown ( " The keychain item retrieved is not the correct type " )
117122 }
123+ log. verbose ( " [KeychainStore] Successfully retrieved `Data` from the store with key= \( key) " )
118124 return data
119125 case errSecItemNotFound:
126+ log. verbose ( " [KeychainStore] No Keychain item found for key= \( key) " )
120127 throw KeychainStoreError . itemNotFound
121128 default :
129+ log. error ( " [KeychainStore] Error of status= \( status) occurred when attempting to retrieve a Keychain item for key= \( key) " )
122130 throw KeychainStoreError . securityError ( status)
123131 }
124132 }
@@ -130,10 +138,13 @@ public struct KeychainStore: KeychainStoreBehavior {
130138 /// - value: A string value to store in Keychain
131139 /// - key: A String key for the value to store in the Keychain
132140 public func _set( _ value: String , key: String ) throws {
141+ log. verbose ( " [KeychainStore] Started setting `String` for key= \( key) " )
133142 guard let data = value. data ( using: . utf8, allowLossyConversion: false ) else {
143+ log. error ( " [KeychainStore] Unable to create Data from String retrieved for key= \( key) " )
134144 throw KeychainStoreError . conversionError ( " Unable to create Data from String retrieved " )
135145 }
136146 try _set ( data, key: key)
147+ log. verbose ( " [KeychainStore] Successfully added `String` for key= \( key) " )
137148 }
138149
139150 @_spi ( KeychainStore)
@@ -143,34 +154,43 @@ public struct KeychainStore: KeychainStoreBehavior {
143154 /// - value: A data value to store in Keychain
144155 /// - key: A String key for the value to store in the Keychain
145156 public func _set( _ value: Data , key: String ) throws {
157+ log. verbose ( " [KeychainStore] Started setting `Data` for key= \( key) " )
146158 var getQuery = attributes. defaultGetQuery ( )
147159 getQuery [ Constants . AttributeAccount] = key
148-
160+ log . verbose ( " [KeychainStore] Initialized fetching to decide whether update or add " )
149161 let fetchStatus = SecItemCopyMatching ( getQuery as CFDictionary , nil )
150162 switch fetchStatus {
151163 case errSecSuccess:
152164 #if os(macOS)
165+ log. verbose ( " [KeychainStore] Deleting item on MacOS to add an item. " )
153166 SecItemDelete ( getQuery as CFDictionary )
154167 fallthrough
155168 #else
169+ log. verbose ( " [KeychainStore] Found existing item, updating " )
156170 var attributesToUpdate = [ String: Any] ( )
157171 attributesToUpdate [ Constants . ValueData] = value
158172
159173 let updateStatus = SecItemUpdate ( getQuery as CFDictionary , attributesToUpdate as CFDictionary )
160174 if updateStatus != errSecSuccess {
175+ log. error ( " [KeychainStore] Error updating item to keychain with status= \( updateStatus) " )
161176 throw KeychainStoreError . securityError ( updateStatus)
162177 }
178+ log. verbose ( " [KeychainStore] Successfully updated `String` in keychain for key= \( key) " )
163179 #endif
164180 case errSecItemNotFound:
181+ log. verbose ( " [KeychainStore] Unable to find an existing item, creating new item " )
165182 var attributesToSet = attributes. defaultSetQuery ( )
166183 attributesToSet [ Constants . AttributeAccount] = key
167184 attributesToSet [ Constants . ValueData] = value
168185
169186 let addStatus = SecItemAdd ( attributesToSet as CFDictionary , nil )
170187 if addStatus != errSecSuccess {
188+ log. error ( " [KeychainStore] Error adding item to keychain with status= \( addStatus) " )
171189 throw KeychainStoreError . securityError ( addStatus)
172190 }
191+ log. verbose ( " [KeychainStore] Successfully added `String` in keychain for key= \( key) " )
173192 default:
193+ log. error ( " [KeychainStore] Error occurred while retrieving data from keychain when deciding to update or add with status= \( fetchStatus) " )
174194 throw KeychainStoreError . securityError ( fetchStatus)
175195 }
176196 }
@@ -180,28 +200,34 @@ public struct KeychainStore: KeychainStoreBehavior {
180200 /// This System Programming Interface (SPI) may have breaking changes in future updates.
181201 /// - Parameter key: A String key to delete the key-value pair
182202 public func _remove( _ key: String ) throws {
203+ log. verbose ( " [KeychainStore] Starting to remove item from keychain with key= \( key) " )
183204 var query = attributes. defaultGetQuery ( )
184205 query [ Constants . AttributeAccount] = key
185206
186207 let status = SecItemDelete ( query as CFDictionary )
187208 if status != errSecSuccess && status != errSecItemNotFound {
209+ log. error ( " [KeychainStore] Error removing itms from keychain with status= \( status) " )
188210 throw KeychainStoreError . securityError ( status)
189211 }
212+ log. verbose ( " [KeychainStore] Successfully removed item from keychain " )
190213 }
191214
192215 @_spi ( KeychainStore)
193216 /// Removes all key-value pair in the Keychain.
194217 /// This System Programming Interface (SPI) may have breaking changes in future updates.
195218 public func _removeAll( ) throws {
219+ log. verbose ( " [KeychainStore] Starting to remove all items from keychain " )
196220 var query = attributes. defaultGetQuery ( )
197221#if !os(iOS) && !os(watchOS) && !os(tvOS)
198222 query [ Constants . MatchLimit] = Constants . MatchLimitAll
199223#endif
200224
201225 let status = SecItemDelete ( query as CFDictionary )
202226 if status != errSecSuccess && status != errSecItemNotFound {
227+ log. error ( " [KeychainStore] Error removing all items from keychain with status= \( status) " )
203228 throw KeychainStoreError . securityError ( status)
204229 }
230+ log. verbose ( " [KeychainStore] Successfully removed all items from keychain " )
205231 }
206232
207233}
@@ -241,3 +267,11 @@ extension KeychainStore {
241267 }
242268}
243269// swiftlint:enable identifier_name
270+
271+ extension KeychainStore : DefaultLogger {
272+ public static var log : Logger {
273+ Amplify . Logging. logger ( forNamespace: String ( describing: self ) )
274+ }
275+
276+ public nonisolated var log : Logger { Self . log }
277+ }
0 commit comments