Skip to content

Commit

Permalink
Update instead of replacing
Browse files Browse the repository at this point in the history
  • Loading branch information
flypaper0 committed Oct 31, 2023
1 parent 34d5577 commit 8ad09bb
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 35 deletions.
10 changes: 5 additions & 5 deletions Sources/WalletConnectKMS/Keychain/KeychainError.swift
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import Foundation

// TODO: Integrate with WalletConnectError
struct KeychainError: Error, LocalizedError {
public struct KeychainError: Error, LocalizedError {

let status: OSStatus
public let status: OSStatus

init(_ status: OSStatus) {
public init(_ status: OSStatus) {
self.status = status
}

var errorDescription: String? {
public var errorDescription: String? {
return "OSStatus: \(status), message: \(status.message)"
}
}

extension KeychainError: CustomStringConvertible {

var description: String {
public var description: String {
status.message
}
}
Expand Down
44 changes: 14 additions & 30 deletions Sources/WalletConnectKMS/Keychain/KeychainStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ public final class KeychainStorage: KeychainStorageProtocol {
case errSecSuccess:
return item as? Data
case errSecItemNotFound:
// TODO: Replace with nil once migration period ends
return try tryMigrateAttrAccessible(key: key)
return tryMigrateAttrAccessible(key: key) // TODO: Replace with nil once migration period ends
default:
throw KeychainError(status)
}
Expand Down Expand Up @@ -109,38 +108,23 @@ public final class KeychainStorage: KeychainStorageProtocol {
]
}

private func tryMigrateAttrAccessible(key: String) throws -> Data? {
var query = buildBaseServiceQuery(for: key)
query[kSecReturnData] = true
query[kSecAttrAccessible] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly

var item: CFTypeRef?
let status = secItem.copyMatching(query as CFDictionary, &item)
private func tryMigrateAttrAccessible(key: String) -> Data? {
var updateQuery = buildBaseServiceQuery(for: key)
updateQuery[kSecAttrAccessible] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly

switch status {
case errSecSuccess: // Migration needed
guard let data = item as? Data else { return nil }

// Fetching old value
var deleteQuery = buildBaseServiceQuery(for: key)
deleteQuery[kSecAttrAccessible] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
let attributes = [kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]
let status = secItem.update(updateQuery as CFDictionary, attributes as CFDictionary)

// Deleting old value
let status = secItem.delete(deleteQuery as CFDictionary)
guard status == errSecSuccess else {
return nil
}

guard status == errSecSuccess || status == errSecItemNotFound else {
throw KeychainError(status)
}
var readQuery = buildBaseServiceQuery(for: key)
readQuery[kSecReturnData] = true

// Replacing with new value
try add(data: data, forKey: key)
var item: CFTypeRef?
_ = secItem.copyMatching(readQuery as CFDictionary, &item)

// Continue `readData` execution
return item as? Data
case errSecItemNotFound:
return nil
default:
throw KeychainError(status)
}
return item as? Data
}
}
3 changes: 3 additions & 0 deletions Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public struct ClientIdStorage: ClientIdStoring {
let publicPart = try getPublicPart()
return try getPrivatePart(for: publicPart)
} catch {
guard let error = error as? KeychainError, error.status == errSecItemNotFound else {
throw error
}
let privateKey = SigningPrivateKey()
try setPrivatePart(privateKey)
setPublicPart(privateKey.publicKey)
Expand Down

0 comments on commit 8ad09bb

Please sign in to comment.