Skip to content

Commit

Permalink
Implement KeychainKeyManager (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
amika-sq authored Feb 16, 2024
1 parent e19b6e2 commit 14af4ff
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions Sources/Web5/Crypto/KeyManager/Local/KeychainKeyManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import Foundation
import Security

/// A KeyManager that generates and stores cryptographic keys in the Keychain
public class KeychainKeyManager: LocalKeyManager {

public init() {
super.init(keyStore: KeychainKeyStore())
}
}

class KeychainKeyStore: LocalKeyStore {

func getKey(keyAlias: String) throws -> Jwk? {
let keychainQuery: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
kSecAttrApplicationLabel as String: keyAlias,
kSecReturnData as String: kCFBooleanTrue!,
kSecMatchLimit as String: kSecMatchLimitOne
]

var item: CFTypeRef?
let status = SecItemCopyMatching(keychainQuery as CFDictionary, &item)

guard status == errSecSuccess else {
if status == errSecItemNotFound {
return nil
} else {
throw NSError(
domain: NSOSStatusErrorDomain,
code: Int(status),
userInfo: [
NSLocalizedDescriptionKey: "Failed to fetch key for alias \(keyAlias) from KeychainKeyStore"
]
)
}
}

guard let data = item as? Data else {
return nil
}

let jwk = try JSONDecoder().decode(Jwk.self, from: data)
return jwk
}

func setKey(_ privateKey: Jwk, keyAlias: String) throws {
let dataToStore = try JSONEncoder().encode(privateKey)

let keychainQuery: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
kSecAttrApplicationLabel as String: keyAlias,
kSecValueData as String: dataToStore
]

let status = SecItemAdd(keychainQuery as CFDictionary, nil)
guard status == errSecSuccess else {
throw NSError(
domain: NSOSStatusErrorDomain,
code: Int(status),
userInfo: [
NSLocalizedDescriptionKey: "Failed to store key for alias \(keyAlias) in KeychainKeyStore"
]
)
}
}
}

0 comments on commit 14af4ff

Please sign in to comment.