Prompting for access.

This commit is contained in:
Max Goedjen 2020-09-23 21:32:36 -07:00
parent d68479cf10
commit bbae36a29c
No known key found for this signature in database
GPG Key ID: E58C21DD77B9B8E8
8 changed files with 21 additions and 15 deletions

View File

@ -93,7 +93,7 @@ extension Agent {
}
let dataToSign = reader.readNextChunk()
let derSignature = try store.sign(data: dataToSign, with: secret)
let derSignature = try store.sign(data: dataToSign, with: secret, for: provenance)
let curveData = writer.curveType(for: secret.algorithm, length: secret.keySize).data(using: .utf8)!

View File

@ -1,6 +1,7 @@
import Foundation
import AppKit
import Security
import SecretKit
struct SigningRequestTracer {

View File

@ -8,7 +8,7 @@ public class AnySecretStore: SecretStore {
private let _id: () -> UUID
private let _name: () -> String
private let _secrets: () -> [AnySecret]
private let _sign: (Data, AnySecret) throws -> Data
private let _sign: (Data, AnySecret, SigningRequestProvenance) throws -> Data
private var sink: AnyCancellable?
public init<SecretStoreType>(_ secretStore: SecretStoreType) where SecretStoreType: SecretStore {
@ -17,7 +17,7 @@ public class AnySecretStore: SecretStore {
_name = { secretStore.name }
_id = { secretStore.id }
_secrets = { secretStore.secrets.map { AnySecret($0) } }
_sign = { try secretStore.sign(data: $0, with: $1.base as! SecretStoreType.SecretType) }
_sign = { try secretStore.sign(data: $0, with: $1.base as! SecretStoreType.SecretType, for: $2) }
sink = secretStore.objectWillChange.sink { _ in
self.objectWillChange.send()
}
@ -39,8 +39,8 @@ public class AnySecretStore: SecretStore {
return _secrets()
}
public func sign(data: Data, with secret: AnySecret) throws -> Data {
try _sign(data, secret)
public func sign(data: Data, with secret: AnySecret, for provenance: SigningRequestProvenance) throws -> Data {
try _sign(data, secret, provenance)
}
}

View File

@ -9,7 +9,7 @@ public protocol SecretStore: ObservableObject, Identifiable {
var name: String { get }
var secrets: [SecretType] { get }
func sign(data: Data, with secret: SecretType) throws -> Data
func sign(data: Data, with secret: SecretType, for provenance: SigningRequestProvenance) throws -> Data
}

View File

@ -17,7 +17,7 @@ extension SigningRequestProvenance {
}
public var intact: Bool {
return chain.reduce(true) { $0 && $1.validSignature }
chain.allSatisfy { $0.validSignature }
}
}
@ -30,9 +30,9 @@ extension SigningRequestProvenance {
public let name: String
public let path: String
public let validSignature: Bool
let parentPID: Int32?
public let parentPID: Int32?
init(pid: Int32, name: String, path: String, validSignature: Bool, parentPID: Int32?) {
public init(pid: Int32, name: String, path: String, validSignature: Bool, parentPID: Int32?) {
self.pid = pid
self.name = name
self.path = path

View File

@ -76,9 +76,9 @@ extension SecureEnclave {
reloadSecrets()
}
public func sign(data: Data, with secret: SecretType) throws -> Data {
public func sign(data: Data, with secret: SecretType, for provenance: SigningRequestProvenance) throws -> Data {
let context = LAContext()
context.localizedReason = "sign a request from Terminal using secret \"\(secret.name)\""
context.localizedReason = "sign a request from \(provenance.origin) using secret \"\(secret.name)\""
context.localizedCancelTitle = "Deny"
let attributes = [
kSecClass: kSecClassKey,

View File

@ -1,6 +1,7 @@
import Foundation
import Security
import CryptoTokenKit
import LocalAuthentication
// TODO: Might need to split this up into "sub-stores?"
// ie, each token has its own Store.
@ -43,13 +44,17 @@ extension SmartCard {
fatalError("Keys must be deleted on the smart card.")
}
public func sign(data: Data, with secret: SecretType) throws -> Data {
public func sign(data: Data, with secret: SecretType, for provenance: SigningRequestProvenance) throws -> Data {
guard let tokenID = tokenID else { fatalError() }
let context = LAContext()
context.localizedReason = "sign a request from \(provenance.origin.name) using secret \"\(secret.name)\""
context.localizedCancelTitle = "Deny"
let attributes = [
kSecClass: kSecClassKey,
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
kSecAttrApplicationLabel: secret.id as CFData,
kSecAttrTokenID: tokenID,
kSecUseAuthenticationContext: context,
kSecReturnRef: true
] as CFDictionary
var untyped: CFTypeRef?

View File

@ -11,6 +11,7 @@
50153E20250AFCB200525160 /* UpdateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50153E1F250AFCB200525160 /* UpdateView.swift */; };
50153E22250DECA300525160 /* SecretListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50153E21250DECA300525160 /* SecretListView.swift */; };
5018F54F24064786002EB505 /* Notifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5018F54E24064786002EB505 /* Notifier.swift */; };
501B7AE1251C56F700776EC7 /* SigningRequestProvenance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */; };
50524B442420969E008DBD97 /* OpenSSHWriterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50524B432420969D008DBD97 /* OpenSSHWriterTests.swift */; };
50571E0324393C2600F76F6C /* JustUpdatedChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50571E0224393C2600F76F6C /* JustUpdatedChecker.swift */; };
50571E0524393D1500F76F6C /* LaunchAgentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50571E0424393D1500F76F6C /* LaunchAgentController.swift */; };
@ -49,7 +50,6 @@
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 */; };
507EE34224281E12003C4FE3 /* FileHandleProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507EE34124281E12003C4FE3 /* FileHandleProtocols.swift */; };
507EE34624281F89003C4FE3 /* StubFileHandleReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507EE34524281F89003C4FE3 /* StubFileHandleReader.swift */; };
@ -361,6 +361,7 @@
504BA92D243171F20064740E /* Types */ = {
isa = PBXGroup;
children = (
507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */,
50617DCA23FCECA10099B055 /* Secret.swift */,
50617DC623FCE4EA0099B055 /* SecretStore.swift */,
);
@ -562,7 +563,6 @@
5099A089240242C20062B6F2 /* SSHAgentProtocol.swift */,
50A3B79D24026B9900D209EA /* SocketController.swift */,
507CE4EF2420A4C50029F750 /* SigningWitness.swift */,
507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */,
507CE4F52420A96F0029F750 /* SigningRequestTracer.swift */,
50A3B79F24026B9900D209EA /* Agent.swift */,
507EE34124281E12003C4FE3 /* FileHandleProtocols.swift */,
@ -966,6 +966,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
501B7AE1251C56F700776EC7 /* SigningRequestProvenance.swift in Sources */,
50617DC723FCE4EA0099B055 /* SecretStore.swift in Sources */,
5099A02723FE34FA0062B6F2 /* SmartCard.swift in Sources */,
50617DCB23FCECA10099B055 /* Secret.swift in Sources */,
@ -1010,7 +1011,6 @@
507CE4ED2420A3C70029F750 /* Agent.swift in Sources */,
507CE4F02420A4C50029F750 /* SigningWitness.swift in Sources */,
507CE4F62420A96F0029F750 /* SigningRequestTracer.swift in Sources */,
507CE4F42420A8C10029F750 /* SigningRequestProvenance.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};