@@ -828,20 +828,26 @@ public class RustLogins: LoginsProtocol, KeyManager {
828828 }
829829
830830 private func getKeychainData( rustKeys: RustLoginEncryptionKeys ) -> ( String ? , String ? ) {
831- let key = rustKeys. keychain. string ( forKey: rustKeys. loginPerFieldKeychainKey)
832- let encryptedCanaryPhrase = rustKeys. keychain. string ( forKey: rustKeys. canaryPhraseKey)
833- return ( key, encryptedCanaryPhrase)
831+ var keychainData : ( String ? , String ? ) = ( nil , nil )
832+
833+ DispatchQueue . global ( qos: . background) . sync {
834+ let key = rustKeys. keychain. string ( forKey: rustKeys. loginPerFieldKeychainKey)
835+ let encryptedCanaryPhrase = rustKeys. keychain. string ( forKey: rustKeys. canaryPhraseKey)
836+ keychainData = ( key, encryptedCanaryPhrase)
837+ }
838+
839+ return keychainData
834840 }
835841
836842 public func getStoredKey( completion: @escaping ( Result < String , NSError > ) -> Void ) {
837843 let rustKeys = RustLoginEncryptionKeys ( )
838844 let ( key, encryptedCanaryPhrase) = getKeychainData ( rustKeys: rustKeys)
839845 switch ( key, encryptedCanaryPhrase) {
840846 case ( . some( key) , . some( encryptedCanaryPhrase) ) :
841- self . handleExpectedKeyAction ( rustKeys: rustKeys,
842- encryptedCanaryPhrase: encryptedCanaryPhrase,
843- key: key,
844- completion: completion)
847+ self . handleExpectedKeyAction ( rustKeys: rustKeys,
848+ encryptedCanaryPhrase: encryptedCanaryPhrase,
849+ key: key,
850+ completion: completion)
845851 case ( . some( key) , . none) :
846852 self . handleUnexpectedKeyAction ( rustKeys: rustKeys, completion: completion)
847853 case ( . none, . some( encryptedCanaryPhrase) ) :
@@ -942,4 +948,39 @@ public class RustLogins: LoginsProtocol, KeyManager {
942948 // possible but is disallowed nonetheless
943949 completion ( . failure( LoginEncryptionKeyError . illegalState as NSError ) )
944950 }
951+
952+ // MARK: - KeyManager
953+
954+ /**
955+ * Retrieves the encryption key used by the Rust logins component for encrypting and decrypting login data.
956+ *
957+ * This method is invoked internally by the Rust component whenever encryption or decryption is required.
958+ *
959+ * **Note on thread safety:**
960+ * Each CRUD operation in Rust acquires a mutex lock on the db to ensure thread safety.
961+ * Therefore, it's crucial to call `getStoredKey` before performing any such CRUD operations in Swift.
962+ * `addLogin` and `updateLogin` are good examples of that.
963+ *
964+ * **Usage Example:**
965+ * ```
966+ * public func methodThatRequiresEncDec() {
967+ * ...
968+ * self.getStoredKey {
969+ * ...
970+ * self.storage.someRustMethod()
971+ * ...
972+ * }
973+ * }
974+ * ```
975+ */
976+ public func getKey( ) throws -> Data {
977+ let rustKeys = RustLoginEncryptionKeys ( )
978+ let ( key, _) = getKeychainData ( rustKeys: rustKeys)
979+
980+ guard let keyData = key? . data ( using: . utf8) else {
981+ throw LoginsStoreError . MissingKey
982+ }
983+
984+ return keyData
985+ }
945986}
0 commit comments