Add agent support

This commit is contained in:
Max Goedjen 2020-03-08 21:11:59 -07:00
parent 286e2dc558
commit a0bd55d1bf
No known key found for this signature in database
GPG Key ID: E58C21DD77B9B8E8
4 changed files with 30 additions and 16 deletions

View File

@ -4,14 +4,14 @@ import OSLog
import SecretKit import SecretKit
import SecretAgentKit import SecretAgentKit
class Agent<StoreType: SecretStore> { class Agent {
fileprivate let store: StoreType fileprivate let storeList: SecretStoreList
fileprivate let notifier: Notifier fileprivate let notifier: Notifier
public init(store: StoreType, notifier: Notifier) { public init(storeList: SecretStoreList, notifier: Notifier) {
os_log(.debug, "Agent is running") os_log(.debug, "Agent is running")
self.store = store self.storeList = storeList
self.notifier = notifier self.notifier = notifier
} }
@ -57,17 +57,18 @@ extension Agent {
extension Agent { extension Agent {
func identities() throws -> Data { func identities() throws -> Data {
var count = UInt32(store.secrets.count).bigEndian let secrets = storeList.stores.flatMap(\.secrets)
var count = UInt32(secrets.count).bigEndian
let countData = Data(bytes: &count, count: UInt32.bitWidth/8) let countData = Data(bytes: &count, count: UInt32.bitWidth/8)
var keyData = Data() var keyData = Data()
let writer = OpenSSHKeyWriter() let writer = OpenSSHKeyWriter()
for secret in store.secrets { for secret in secrets {
let keyBlob = writer.data(secret: secret) let keyBlob = writer.data(secret: secret)
keyData.append(writer.lengthAndData(of: keyBlob)) keyData.append(writer.lengthAndData(of: keyBlob))
let curveData = OpenSSHKeyWriter.Constants.curveType.data(using: .utf8)! let curveData = OpenSSHKeyWriter.Constants.curveType.data(using: .utf8)!
keyData.append(writer.lengthAndData(of: curveData)) keyData.append(writer.lengthAndData(of: curveData))
} }
os_log(.debug, "Agent enumerated %@ identities", store.secrets.count as NSNumber) os_log(.debug, "Agent enumerated %@ identities", secrets.count as NSNumber)
return countData + keyData return countData + keyData
} }
@ -75,10 +76,16 @@ extension Agent {
let reader = OpenSSHReader(data: data) let reader = OpenSSHReader(data: data)
let writer = OpenSSHKeyWriter() let writer = OpenSSHKeyWriter()
let hash = try reader.readNextChunk() let hash = try reader.readNextChunk()
let matching = store.secrets.filter { secret in let matching = storeList.stores.compactMap { store -> (AnySecretStore, AnySecret)? in
hash == writer.data(secret: secret) let allMatching = store.secrets.filter { secret in
hash == writer.data(secret: secret)
}
if let matching = allMatching.first {
return (store, matching)
}
return nil
} }
guard let secret = matching.first else { guard let (store, secret) = matching.first else {
throw AgentError.noMatchingKey throw AgentError.noMatchingKey
} }
let dataToSign = try reader.readNextChunk() let dataToSign = try reader.readNextChunk()

View File

@ -5,10 +5,15 @@ import OSLog
@NSApplicationMain @NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate { class AppDelegate: NSObject, NSApplicationDelegate {
let store = SecureEnclave.Store() let storeList: SecretStoreList = {
let list = SecretStoreList()
list.add(store: SecureEnclave.Store())
list.add(store: SmartCard.Store())
return list
}()
let notifier = Notifier() let notifier = Notifier()
lazy var agent: Agent = { lazy var agent: Agent = {
Agent(store: store, notifier: notifier) Agent(storeList: storeList, notifier: notifier)
}() }()
lazy var socketController: SocketController = { lazy var socketController: SocketController = {
let path = (NSHomeDirectory() as NSString).appendingPathComponent("socket.ssh") as String let path = (NSHomeDirectory() as NSString).appendingPathComponent("socket.ssh") as String

View File

@ -17,7 +17,7 @@ public class AnySecretStore: SecretStore {
_name = { secretStore.name } _name = { secretStore.name }
_id = { secretStore.id } _id = { secretStore.id }
_secrets = { secretStore.secrets.map { AnySecret($0) } } _secrets = { secretStore.secrets.map { AnySecret($0) } }
_sign = { try secretStore.sign(data: $0, with: $1 as! SecretStoreType.SecretType) } _sign = { try secretStore.sign(data: $0, with: $1.base as! SecretStoreType.SecretType) }
sink = secretStore.objectWillChange.sink { _ in sink = secretStore.objectWillChange.sink { _ in
self.objectWillChange.send() self.objectWillChange.send()
} }
@ -65,5 +65,3 @@ public class AnySecretStoreModifiable: AnySecretStore, SecretStoreModifiable {
} }
} }

View File

@ -20,7 +20,11 @@ public class SecretStoreList: ObservableObject {
addInternal(store: modifiable) addInternal(store: modifiable)
} }
public func addInternal(store: AnySecretStore) { }
extension SecretStoreList {
fileprivate func addInternal(store: AnySecretStore) {
stores.append(store) stores.append(store)
let sink = store.objectWillChange.sink { let sink = store.objectWillChange.sink {
self.objectWillChange.send() self.objectWillChange.send()