Availibilty

This commit is contained in:
Max Goedjen
2020-03-07 15:42:40 -08:00
parent 734df29065
commit a9d7e7644e
6 changed files with 47 additions and 18 deletions

View File

@@ -3,6 +3,7 @@ import Combine
public protocol SecretStore: ObservableObject {
associatedtype SecretType: Secret
var isAvailable: Bool { get }
var name: String { get }
var secrets: [SecretType] { get }
@@ -20,6 +21,7 @@ extension NSNotification.Name {
public class AnySecretStore: SecretStore {
fileprivate let base: Any
fileprivate let _isAvailable: () -> Bool
fileprivate let _name: () -> String
fileprivate let _secrets: () -> [AnySecret]
fileprivate let _sign: (Data, AnySecret) throws -> Data
@@ -27,11 +29,16 @@ public class AnySecretStore: SecretStore {
public init<T>(_ secretStore: T) where T: SecretStore {
base = secretStore
_isAvailable = { secretStore.isAvailable }
_name = { secretStore.name }
_secrets = { secretStore.secrets.map { AnySecret($0) } }
_sign = { try secretStore.sign(data: $0, with: $1 as! T.SecretType) }
_delete = { try secretStore.delete(secret: $0 as! T.SecretType) }
}
public var isAvailable: Bool {
return _isAvailable()
}
public var name: String {
return _name()

View File

@@ -1,10 +1,17 @@
import Foundation
import Security
import CryptoTokenKit
extension SecureEnclave {
public class Store: SecretStore {
public var isAvailable: Bool {
// For some reason, as of build time, CryptoKit.SecureEnclave.isAvailable always returns false
// error msg "Received error sending GET UNIQUE DEVICE command"
// Verify it with TKTokenWatcher manually.
return TKTokenWatcher().tokenIDs.contains("com.apple.setoken")
}
public let name = NSLocalizedString("Secure Enclave", comment: "Secure Enclave")
@Published public fileprivate(set) var secrets: [Secret] = []

View File

@@ -9,6 +9,7 @@ extension SmartCard {
public class Store: SecretStore {
// TODO: Read actual smart card name, eg "YubiKey 5c"
@Published public var isAvailable: Bool = false
public let name = NSLocalizedString("Smart Card", comment: "Smart Card")
@Published public fileprivate(set) var secrets: [Secret] = []
fileprivate let watcher = TKTokenWatcher()
@@ -21,10 +22,11 @@ extension SmartCard {
guard !string.contains("setoken") else { return }
self.id = string
self.reloadSecrets()
self.watcher.addRemovalHandler(self.reloadSecrets, forTokenID: string)
self.watcher.addRemovalHandler(self.smartcardRemoved, forTokenID: string)
}
if let id = id {
self.watcher.addRemovalHandler(self.reloadSecrets, forTokenID: id)
self.isAvailable = true
self.watcher.addRemovalHandler(self.smartcardRemoved, forTokenID: id)
}
loadSecrets()
}
@@ -70,8 +72,14 @@ extension SmartCard {
extension SmartCard.Store {
fileprivate func reloadSecrets(for tokenID: String? = nil) {
fileprivate func smartcardRemoved(for tokenID: String? = nil) {
id = nil
reloadSecrets()
}
fileprivate func reloadSecrets() {
DispatchQueue.main.async {
self.isAvailable = self.id != nil
self.secrets.removeAll()
self.loadSecrets()
}