Skip to content

Commit

Permalink
Merge pull request #1204 from WalletConnect/develop
Browse files Browse the repository at this point in the history
1.9.3
  • Loading branch information
flypaper0 authored Nov 1, 2023
2 parents c3c84f2 + 3bb4d86 commit 67a7f0a
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Sources/WalletConnectKMS/Crypto/KeyManagementService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public class KeyManagementService: KeyManagementServiceProtocol {
public func getPrivateKey(for publicKey: AgreementPublicKey) throws -> AgreementPrivateKey? {
do {
return try keychain.read(key: publicKey.hexRepresentation) as AgreementPrivateKey
} catch let error where (error as? KeychainError)?.status == errSecItemNotFound {
} catch KeychainError.itemNotFound {
return nil
} catch {
throw error
Expand Down
36 changes: 27 additions & 9 deletions Sources/WalletConnectKMS/Keychain/KeychainError.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
import Foundation

// TODO: Integrate with WalletConnectError
struct KeychainError: Error, LocalizedError {
public enum KeychainError: Error, LocalizedError {
case itemNotFound
case other(OSStatus)

let status: OSStatus
public init(_ status: OSStatus) {
switch status {
case errSecItemNotFound:
self = .itemNotFound
default:
self = .other(status)
}
}

init(_ status: OSStatus) {
self.status = status
public var status: OSStatus {
switch self {
case .itemNotFound:
return errSecItemNotFound
case .other(let status):
return status
}
}

var errorDescription: String? {
return "OSStatus: \(status), message: \(status.message)"
public var errorDescription: String? {
switch self {
case .itemNotFound:
return "Keychain item not found"
case .other(let status):
return "OSStatus: \(status), message: \(status.message)"
}
}
}

extension KeychainError: CustomStringConvertible {

var description: String {
status.message
public var description: String {
return errorDescription ?? ""
}
}

Expand Down
24 changes: 22 additions & 2 deletions Sources/WalletConnectKMS/Keychain/KeychainStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public final class KeychainStorage: KeychainStorageProtocol {
case errSecSuccess:
return item as? Data
case errSecItemNotFound:
return nil
return tryMigrateAttrAccessible(key: key) // TODO: Replace with nil once migration period ends
default:
throw KeychainError(status)
}
Expand Down Expand Up @@ -100,11 +100,31 @@ public final class KeychainStorage: KeychainStorageProtocol {
private func buildBaseServiceQuery(for key: String) -> [CFString: Any] {
return [
kSecClass: kSecClassGenericPassword,
kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
kSecAttrIsInvisible: true,
kSecUseDataProtectionKeychain: true,
kSecAttrService: service,
kSecAttrAccount: key
]
}

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

let attributes = [kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]
let status = secItem.update(updateQuery as CFDictionary, attributes as CFDictionary)

guard status == errSecSuccess else {
return nil
}

var readQuery = buildBaseServiceQuery(for: key)
readQuery[kSecReturnData] = true

var item: CFTypeRef?
_ = secItem.copyMatching(readQuery as CFDictionary, &item)

return item as? Data
}
}
8 changes: 6 additions & 2 deletions Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ public struct ClientIdStorage: ClientIdStoring {
do {
let publicPart = try getPublicPart()
return try getPrivatePart(for: publicPart)
} catch {
} catch Errors.privatePartNotFound, Errors.publicPartNotFound {
let privateKey = SigningPrivateKey()
try setPrivatePart(privateKey)
setPublicPart(privateKey.publicKey)
return privateKey
} catch {
throw error
}
}

Expand Down Expand Up @@ -76,8 +78,10 @@ private extension ClientIdStorage {
func getPrivatePart(for publicPart: SigningPublicKey) throws -> SigningPrivateKey {
do {
return try keychain.read(key: publicPart.storageId)
} catch {
} catch KeychainError.itemNotFound {
throw Errors.privatePartNotFound
} catch {
throw error
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/WalletConnectRelay/PackageConfig.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version": "1.9.2"}
{"version": "1.9.3"}

0 comments on commit 67a7f0a

Please sign in to comment.