diff --git a/SecretAgent/AppDelegate.swift b/SecretAgent/AppDelegate.swift index 4881158..379b259 100644 --- a/SecretAgent/AppDelegate.swift +++ b/SecretAgent/AppDelegate.swift @@ -1,5 +1,6 @@ import Cocoa import SecretKit +import SecretAgentKit import OSLog @NSApplicationMain @@ -13,7 +14,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { }() let notifier = Notifier() lazy var agent: Agent = { - Agent(storeList: storeList, notifier: notifier) + Agent(storeList: storeList/*, notifier: notifier*/) }() lazy var socketController: SocketController = { let path = (NSHomeDirectory() as NSString).appendingPathComponent("socket.ssh") as String diff --git a/SecretAgent/Notifier.swift b/SecretAgent/Notifier.swift index d5c537c..afde984 100644 --- a/SecretAgent/Notifier.swift +++ b/SecretAgent/Notifier.swift @@ -1,5 +1,6 @@ import Foundation import SecretKit +import SecretAgentKit import UserNotifications import AppKit @@ -11,13 +12,21 @@ class Notifier { } } - func notify(accessTo secret: SecretType, from caller: NSRunningApplication) { + func notify(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) { let notificationCenter = UNUserNotificationCenter.current() let notificationContent = UNMutableNotificationContent() notificationContent.title = "Signed Request" - notificationContent.body = "\(secret.name) was used to sign a request from \(caller.localizedName!)." + notificationContent.body = "\(secret.name) was used to sign a request from \(provenance.origin.name)." let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil) notificationCenter.add(request, withCompletionHandler: nil) } } + +extension Notifier: SigningWitness { + + func witness(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws { + notify(accessTo: secret, by: provenance) + } + +} diff --git a/SecretAgent/Agent.swift b/SecretAgentKit/Agent.swift similarity index 76% rename from SecretAgent/Agent.swift rename to SecretAgentKit/Agent.swift index 6f8ea8e..2da04fd 100644 --- a/SecretAgent/Agent.swift +++ b/SecretAgentKit/Agent.swift @@ -5,22 +5,24 @@ import SecretKit import SecretAgentKit import AppKit -class Agent { +public class Agent { fileprivate let storeList: SecretStoreList - fileprivate let notifier: Notifier + fileprivate let witness: SigningWitness? + fileprivate let writer = OpenSSHKeyWriter() + fileprivate let requestTracer = SigningRequestTracer() - public init(storeList: SecretStoreList, notifier: Notifier) { + public init(storeList: SecretStoreList, witness: SigningWitness? = nil) { os_log(.debug, "Agent is running") self.storeList = storeList - self.notifier = notifier + self.witness = witness } } extension Agent { - func handle(fileHandle: FileHandle) { + public func handle(fileHandle: FileHandle) { os_log(.debug, "Agent handling new data") let data = fileHandle.availableData guard !data.isEmpty else { return } @@ -77,25 +79,19 @@ extension Agent { func sign(data: Data, from pid: Int32) throws -> Data { let reader = OpenSSHReader(data: data) - let writer = OpenSSHKeyWriter() let hash = try reader.readNextChunk() - let matching = storeList.stores.compactMap { store -> (AnySecretStore, AnySecret)? in - let allMatching = store.secrets.filter { secret in - hash == writer.data(secret: secret) - } - if let matching = allMatching.first { - return (store, matching) - } - return nil - } - guard let (store, secret) = matching.first else { + guard let (store, secret) = secret(matching: hash) else { + os_log(.debug, "Agent did not have a key matching %@", hash as NSData) throw AgentError.noMatchingKey } + + let provenance = requestTracer.provenance(from: pid) + if let witness = witness { + try witness.witness(accessTo: secret, by: provenance) + } + let dataToSign = try reader.readNextChunk() let derSignature = try store.sign(data: dataToSign, with: secret) - let callerApp = caller(from: pid) - // TODO: Move this - notifier.notify(accessTo: secret, from: callerApp) let curveData = writer.curveType(for: secret.algorithm, length: secret.keySize).data(using: .utf8)! @@ -131,27 +127,20 @@ extension Agent { return signedData } - func caller(from pid: Int32) -> NSRunningApplication { - let pidPointer = UnsafeMutableRawPointer.allocate(byteCount: 4, alignment: 1) - var len = socklen_t(MemoryLayout.size) - getsockopt(pid, SOCK_STREAM, LOCAL_PEERPID, pidPointer, &len) - let pid = pidPointer.load(as: Int32.self) +} - var current = pid - while NSRunningApplication(processIdentifier: current) == nil { - current = originalProcess(of: current) - } - return NSRunningApplication(processIdentifier: current)! - } +extension Agent { - func originalProcess(of pid: Int32) -> Int32 { - var len = MemoryLayout.size - let infoPointer = UnsafeMutableRawPointer.allocate(byteCount: len, alignment: 1) - var name: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, pid] - sysctl(&name, UInt32(name.count), infoPointer, &len, nil, 0) - let info = infoPointer.load(as: kinfo_proc.self) - let parent = info.kp_eproc.e_ppid - return parent + func secret(matching hash: Data) -> (AnySecretStore, AnySecret)? { + storeList.stores.compactMap { store -> (AnySecretStore, AnySecret)? in + let allMatching = store.secrets.filter { secret in + hash == writer.data(secret: secret) + } + if let matching = allMatching.first { + return (store, matching) + } + return nil + }.first } } diff --git a/SecretAgentKit/SigningRequestProvenance.swift b/SecretAgentKit/SigningRequestProvenance.swift new file mode 100644 index 0000000..a60ef77 --- /dev/null +++ b/SecretAgentKit/SigningRequestProvenance.swift @@ -0,0 +1,39 @@ +import Foundation +import AppKit + +public struct SigningRequestProvenance { + + public var chain: [Process] + public init(root: Process) { + self.chain = [root] + } + +} + +extension SigningRequestProvenance { + + public var origin: Process { + chain.last! + } + +} + +extension SigningRequestProvenance { + + public struct Process { + + public let pid: Int32 + public let name: String + public let path: String + let parentPID: Int32? + + init(pid: Int32, name: String, path: String, parentPID: Int32?) { + self.pid = pid + self.name = name + self.path = path + self.parentPID = parentPID + } + + } + +} diff --git a/SecretAgentKit/SigningRequestTracer.swift b/SecretAgentKit/SigningRequestTracer.swift new file mode 100644 index 0000000..eeca1a5 --- /dev/null +++ b/SecretAgentKit/SigningRequestTracer.swift @@ -0,0 +1,35 @@ +import Foundation +import AppKit + +struct SigningRequestTracer { + + func provenance(from pid: Int32) -> SigningRequestProvenance { + let pidPointer = UnsafeMutableRawPointer.allocate(byteCount: 4, alignment: 1) + var len = socklen_t(MemoryLayout.size) + getsockopt(pid, SOCK_STREAM, LOCAL_PEERPID, pidPointer, &len) + let pid = pidPointer.load(as: Int32.self) + let firstInfo = process(from: pid) + + var provenance = SigningRequestProvenance(root: firstInfo) + while NSRunningApplication(processIdentifier: provenance.origin.pid) == nil && provenance.origin.parentPID != nil { + provenance.chain.append(process(from: provenance.origin.parentPID!)) + } + return provenance + } + + func pidAndNameInfo(from pid: Int32) -> kinfo_proc { + var len = MemoryLayout.size + let infoPointer = UnsafeMutableRawPointer.allocate(byteCount: len, alignment: 1) + var name: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, pid] + sysctl(&name, UInt32(name.count), infoPointer, &len, nil, 0) + return infoPointer.load(as: kinfo_proc.self) + } + + func process(from pid: Int32) -> SigningRequestProvenance.Process { + var pidAndNameInfo = self.pidAndNameInfo(from: pid) + let ppid = pidAndNameInfo.kp_eproc.e_ppid != 0 ? pidAndNameInfo.kp_eproc.e_ppid : nil + let procName = String(cString: &pidAndNameInfo.kp_proc.p_comm.0) + return SigningRequestProvenance.Process(pid: pid, name: procName, path: "", parentPID: ppid) + } + +} diff --git a/SecretAgentKit/SigningWitness.swift b/SecretAgentKit/SigningWitness.swift new file mode 100644 index 0000000..ffc73e3 --- /dev/null +++ b/SecretAgentKit/SigningWitness.swift @@ -0,0 +1,8 @@ +import Foundation +import SecretKit + +public protocol SigningWitness { + + func witness(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws + +} diff --git a/SecretAgent/SocketController.swift b/SecretAgentKit/SocketController.swift similarity index 95% rename from SecretAgent/SocketController.swift rename to SecretAgentKit/SocketController.swift index 9d811fb..ea82b16 100644 --- a/SecretAgent/SocketController.swift +++ b/SecretAgentKit/SocketController.swift @@ -1,13 +1,13 @@ import Foundation import OSLog -class SocketController { +public class SocketController { fileprivate var fileHandle: FileHandle? fileprivate var port: SocketPort? - var handler: ((FileHandle) -> Void)? + public var handler: ((FileHandle) -> Void)? - init(path: String) { + public init(path: String) { os_log(.debug, "Socket controller setting up at %@", path) if let _ = try? FileManager.default.removeItem(atPath: path) { os_log(.debug, "Socket controller removed existing socket") diff --git a/SecretKitTests/OpenSSHWriterTests.swift b/SecretKitTests/OpenSSHWriterTests.swift new file mode 100644 index 0000000..d7a17b5 --- /dev/null +++ b/SecretKitTests/OpenSSHWriterTests.swift @@ -0,0 +1,45 @@ +import Foundation +import XCTest +@testable import SecretKit + +class OpenSSHWriterTests: XCTestCase { + + let writer = OpenSSHKeyWriter() + + func testECDSA256Fingerprint() { + XCTAssertEqual(writer.openSSHFingerprint(secret: Constants.ecdsa256Secret), "dc:60:4d:ff:c2:d9:18:8b:2f:24:40:b5:7f:43:47:e5") + } + + func testECDSA256PublicKey() { + XCTAssertEqual(writer.openSSHString(secret: Constants.ecdsa256Secret), + "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOVEjgAA5PHqRgwykjN5qM21uWCHFSY/Sqo5gkHAkn+e1MMQKHOLga7ucB9b3mif33MBid59GRK9GEPVlMiSQwo=") + } + + func testECDSA256Hash() { + XCTAssertEqual(writer.data(secret: Constants.ecdsa256Secret), Data(base64Encoded: "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOVEjgAA5PHqRgwykjN5qM21uWCHFSY/Sqo5gkHAkn+e1MMQKHOLga7ucB9b3mif33MBid59GRK9GEPVlMiSQwo=")) + } + + func testECDSA384Fingerprint() { + XCTAssertEqual(writer.openSSHFingerprint(secret: Constants.ecdsa384Secret), "66:e0:66:d7:41:ed:19:8e:e2:20:df:ce:ac:7e:2b:6e") + } + + func testECDSA384PublicKey() { + XCTAssertEqual(writer.openSSHString(secret: Constants.ecdsa384Secret), + "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBG2MNc/C5OTHFE2tBvbZCVcpOGa8vBMquiTLkH4lwkeqOPxhi+PyYUfQZMTRJNPiTyWPoMBqNiCIFRVv60yPN/AHufHaOgbdTP42EgMlMMImkAjYUEv9DESHTVIs2PW1yQ==") + } + + func testECDSA384Hash() { + XCTAssertEqual(writer.data(secret: Constants.ecdsa384Secret), Data(base64Encoded: "AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBG2MNc/C5OTHFE2tBvbZCVcpOGa8vBMquiTLkH4lwkeqOPxhi+PyYUfQZMTRJNPiTyWPoMBqNiCIFRVv60yPN/AHufHaOgbdTP42EgMlMMImkAjYUEv9DESHTVIs2PW1yQ==")) + } + +} + +extension OpenSSHWriterTests { + + enum Constants { + static let ecdsa256Secret = SmartCard.Secret(id: Data(), name: "Test Key (ECDSA 256)", algorithm: .ellipticCurve, keySize: 256, publicKey: Data(base64Encoded: "BOVEjgAA5PHqRgwykjN5qM21uWCHFSY/Sqo5gkHAkn+e1MMQKHOLga7ucB9b3mif33MBid59GRK9GEPVlMiSQwo=")!) + static let ecdsa384Secret = SmartCard.Secret(id: Data(), name: "Test Key (ECDSA 384)", algorithm: .ellipticCurve, keySize: 384, publicKey: Data(base64Encoded: "BG2MNc/C5OTHFE2tBvbZCVcpOGa8vBMquiTLkH4lwkeqOPxhi+PyYUfQZMTRJNPiTyWPoMBqNiCIFRVv60yPN/AHufHaOgbdTP42EgMlMMImkAjYUEv9DESHTVIs2PW1yQ==")!) + + } + +} diff --git a/SecretKitTests/SecretKitTests.swift b/SecretKitTests/SecretKitTests.swift deleted file mode 100644 index 051b3f0..0000000 --- a/SecretKitTests/SecretKitTests.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// SecretKitTests.swift -// SecretKitTests -// -// Created by Max Goedjen on 2/18/20. -// Copyright © 2020 Max Goedjen. All rights reserved. -// - -import XCTest -@testable import SecretKit - -class SecretKitTests: XCTestCase { - - override func setUp() { - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testExample() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - -} diff --git a/Secretive.xcodeproj/project.pbxproj b/Secretive.xcodeproj/project.pbxproj index 6255a63..571a35a 100644 --- a/Secretive.xcodeproj/project.pbxproj +++ b/Secretive.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 50020BB024064869003D4025 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50020BAF24064869003D4025 /* AppDelegate.swift */; }; 5018F54F24064786002EB505 /* Notifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5018F54E24064786002EB505 /* Notifier.swift */; }; + 50524B442420969E008DBD97 /* OpenSSHWriterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50524B432420969D008DBD97 /* OpenSSHWriterTests.swift */; }; 50617D8323FCE48E0099B055 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617D8223FCE48E0099B055 /* AppDelegate.swift */; }; 50617D8523FCE48E0099B055 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617D8423FCE48E0099B055 /* ContentView.swift */; }; 50617D8723FCE48E0099B055 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 50617D8623FCE48E0099B055 /* Assets.xcassets */; }; @@ -16,7 +17,6 @@ 50617D8D23FCE48E0099B055 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 50617D8B23FCE48E0099B055 /* Main.storyboard */; }; 50617D9923FCE48E0099B055 /* SecretiveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617D9823FCE48E0099B055 /* SecretiveTests.swift */; }; 50617DB123FCE4AB0099B055 /* SecretKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50617DA823FCE4AB0099B055 /* SecretKit.framework */; }; - 50617DB823FCE4AB0099B055 /* SecretKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DB723FCE4AB0099B055 /* SecretKitTests.swift */; }; 50617DBA23FCE4AB0099B055 /* SecretKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 50617DAA23FCE4AB0099B055 /* SecretKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 50617DBD23FCE4AB0099B055 /* SecretKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50617DA823FCE4AB0099B055 /* SecretKit.framework */; }; 50617DBE23FCE4AB0099B055 /* SecretKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 50617DA823FCE4AB0099B055 /* SecretKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -32,6 +32,11 @@ 506AB87E2412334700335D91 /* SecretAgent.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 50A3B78A24026B7500D209EA /* SecretAgent.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 50731666241DF8660023809E /* Updater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50731665241DF8660023809E /* Updater.swift */; }; 50731669241E00C20023809E /* NoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50731668241E00C20023809E /* NoticeView.swift */; }; + 507CE4ED2420A3C70029F750 /* Agent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79F24026B9900D209EA /* Agent.swift */; }; + 507CE4EE2420A3CA0029F750 /* SocketController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79D24026B9900D209EA /* SocketController.swift */; }; + 507CE4F02420A4C50029F750 /* SigningWitness.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507CE4EF2420A4C50029F750 /* SigningWitness.swift */; }; + 507CE4F42420A8C10029F750 /* SigningRequestProvenance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */; }; + 507CE4F62420A96F0029F750 /* SigningRequestTracer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507CE4F52420A96F0029F750 /* SigningRequestTracer.swift */; }; 508A58AA241E06B40069DC07 /* PreviewUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508A58A9241E06B40069DC07 /* PreviewUpdater.swift */; }; 508A58B3241ED2180069DC07 /* AgentStatusChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */; }; 508A58B5241ED48F0069DC07 /* PreviewAgentStatusChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508A58B4241ED48F0069DC07 /* PreviewAgentStatusChecker.swift */; }; @@ -49,8 +54,6 @@ 50A3B79124026B7600D209EA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 50A3B79024026B7600D209EA /* Assets.xcassets */; }; 50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 50A3B79324026B7600D209EA /* Preview Assets.xcassets */; }; 50A3B79724026B7600D209EA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 50A3B79524026B7600D209EA /* Main.storyboard */; }; - 50A3B7A024026B9900D209EA /* SocketController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79D24026B9900D209EA /* SocketController.swift */; }; - 50A3B7A224026B9900D209EA /* Agent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79F24026B9900D209EA /* Agent.swift */; }; 50A5C18C240E4B4B00E2996C /* SecretAgentKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5099A06C240242BA0062B6F2 /* SecretAgentKit.framework */; }; 50A5C18D240E4B4B00E2996C /* SecretAgentKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5099A06C240242BA0062B6F2 /* SecretAgentKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 50A5C18F240E4B4C00E2996C /* SecretKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50617DA823FCE4AB0099B055 /* SecretKit.framework */; }; @@ -98,6 +101,13 @@ remoteGlobalIDString = 50617DA723FCE4AB0099B055; remoteInfo = SecretKit; }; + 507CE4F12420A6B50029F750 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 50617D7723FCE48D0099B055 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 50617DA723FCE4AB0099B055; + remoteInfo = SecretKit; + }; 5099A076240242BA0062B6F2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 50617D7723FCE48D0099B055 /* Project object */; @@ -166,6 +176,7 @@ /* Begin PBXFileReference section */ 50020BAF24064869003D4025 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 5018F54E24064786002EB505 /* Notifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifier.swift; sourceTree = ""; }; + 50524B432420969D008DBD97 /* OpenSSHWriterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSSHWriterTests.swift; sourceTree = ""; }; 50617D7F23FCE48E0099B055 /* Secretive.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Secretive.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50617D8223FCE48E0099B055 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 50617D8423FCE48E0099B055 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -181,7 +192,6 @@ 50617DAA23FCE4AB0099B055 /* SecretKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecretKit.h; sourceTree = ""; }; 50617DAB23FCE4AB0099B055 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50617DB023FCE4AB0099B055 /* SecretKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecretKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 50617DB723FCE4AB0099B055 /* SecretKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretKitTests.swift; sourceTree = ""; }; 50617DB923FCE4AB0099B055 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50617DC623FCE4EA0099B055 /* SecretStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretStore.swift; sourceTree = ""; }; 50617DC823FCE50E0099B055 /* SecureEnclaveStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclaveStore.swift; sourceTree = ""; }; @@ -194,6 +204,9 @@ 506838A22415EA5D00F55094 /* AnySecretStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecretStore.swift; sourceTree = ""; }; 50731665241DF8660023809E /* Updater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Updater.swift; sourceTree = ""; }; 50731668241E00C20023809E /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = ""; }; + 507CE4EF2420A4C50029F750 /* SigningWitness.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningWitness.swift; sourceTree = ""; }; + 507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningRequestProvenance.swift; sourceTree = ""; }; + 507CE4F52420A96F0029F750 /* SigningRequestTracer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningRequestTracer.swift; sourceTree = ""; }; 508A58A9241E06B40069DC07 /* PreviewUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewUpdater.swift; sourceTree = ""; }; 508A58AB241E121B0069DC07 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; 508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgentStatusChecker.swift; sourceTree = ""; }; @@ -366,7 +379,7 @@ 50617DB623FCE4AB0099B055 /* SecretKitTests */ = { isa = PBXGroup; children = ( - 50617DB723FCE4AB0099B055 /* SecretKitTests.swift */, + 50524B432420969D008DBD97 /* OpenSSHWriterTests.swift */, 50617DB923FCE4AB0099B055 /* Info.plist */, ); path = SecretKitTests; @@ -457,6 +470,11 @@ children = ( 5099A06E240242BA0062B6F2 /* SecretAgentKit.h */, 5099A089240242C20062B6F2 /* SSHAgentProtocol.swift */, + 50A3B79D24026B9900D209EA /* SocketController.swift */, + 507CE4EF2420A4C50029F750 /* SigningWitness.swift */, + 507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */, + 507CE4F52420A96F0029F750 /* SigningRequestTracer.swift */, + 50A3B79F24026B9900D209EA /* Agent.swift */, 5099A06F240242BA0062B6F2 /* Info.plist */, ); path = SecretAgentKit; @@ -482,9 +500,7 @@ isa = PBXGroup; children = ( 50020BAF24064869003D4025 /* AppDelegate.swift */, - 50A3B79F24026B9900D209EA /* Agent.swift */, 5018F54E24064786002EB505 /* Notifier.swift */, - 50A3B79D24026B9900D209EA /* SocketController.swift */, 50A3B79024026B7600D209EA /* Assets.xcassets */, 50A3B79524026B7600D209EA /* Main.storyboard */, 50A3B79824026B7600D209EA /* Info.plist */, @@ -611,6 +627,7 @@ buildRules = ( ); dependencies = ( + 507CE4F22420A6B50029F750 /* PBXTargetDependency */, ); name = SecretAgentKit; productName = SecretAgentKit; @@ -827,7 +844,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 50617DB823FCE4AB0099B055 /* SecretKitTests.swift in Sources */, + 50524B442420969E008DBD97 /* OpenSSHWriterTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -835,7 +852,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 507CE4EE2420A3CA0029F750 /* SocketController.swift in Sources */, 5099A08A240242C20062B6F2 /* SSHAgentProtocol.swift in Sources */, + 507CE4ED2420A3C70029F750 /* Agent.swift in Sources */, + 507CE4F02420A4C50029F750 /* SigningWitness.swift in Sources */, + 507CE4F62420A96F0029F750 /* SigningRequestTracer.swift in Sources */, + 507CE4F42420A8C10029F750 /* SigningRequestProvenance.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -853,8 +875,6 @@ files = ( 50020BB024064869003D4025 /* AppDelegate.swift in Sources */, 5018F54F24064786002EB505 /* Notifier.swift in Sources */, - 50A3B7A224026B9900D209EA /* Agent.swift in Sources */, - 50A3B7A024026B9900D209EA /* SocketController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -886,6 +906,11 @@ target = 50617DA723FCE4AB0099B055 /* SecretKit */; targetProxy = 50617DBB23FCE4AB0099B055 /* PBXContainerItemProxy */; }; + 507CE4F22420A6B50029F750 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 50617DA723FCE4AB0099B055 /* SecretKit */; + targetProxy = 507CE4F12420A6B50029F750 /* PBXContainerItemProxy */; + }; 5099A077240242BA0062B6F2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5099A06B240242BA0062B6F2 /* SecretAgentKit */;