Show request details in Secure prompts (#146)
This commit is contained in:
parent
85e096f8cc
commit
3774352dfd
Binary file not shown.
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 192 KiB |
|
@ -93,7 +93,7 @@ extension Agent {
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataToSign = reader.readNextChunk()
|
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)!
|
let curveData = writer.curveType(for: secret.algorithm, length: secret.keySize).data(using: .utf8)!
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import AppKit
|
import AppKit
|
||||||
import Security
|
import Security
|
||||||
|
import SecretKit
|
||||||
|
|
||||||
struct SigningRequestTracer {
|
struct SigningRequestTracer {
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ extension Stub {
|
||||||
print("Public Key OpenSSH: \(OpenSSHKeyWriter().openSSHString(secret: secret))")
|
print("Public Key OpenSSH: \(OpenSSHKeyWriter().openSSHString(secret: secret))")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func sign(data: Data, with secret: Secret) throws -> Data {
|
public func sign(data: Data, with secret: Secret, for provenance: SigningRequestProvenance) throws -> Data {
|
||||||
guard !shouldThrow else {
|
guard !shouldThrow else {
|
||||||
throw NSError()
|
throw NSError()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ public class AnySecretStore: SecretStore {
|
||||||
private let _id: () -> UUID
|
private let _id: () -> UUID
|
||||||
private let _name: () -> String
|
private let _name: () -> String
|
||||||
private let _secrets: () -> [AnySecret]
|
private let _secrets: () -> [AnySecret]
|
||||||
private let _sign: (Data, AnySecret) throws -> Data
|
private let _sign: (Data, AnySecret, SigningRequestProvenance) throws -> Data
|
||||||
private var sink: AnyCancellable?
|
private var sink: AnyCancellable?
|
||||||
|
|
||||||
public init<SecretStoreType>(_ secretStore: SecretStoreType) where SecretStoreType: SecretStore {
|
public init<SecretStoreType>(_ secretStore: SecretStoreType) where SecretStoreType: SecretStore {
|
||||||
|
@ -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.base as! SecretStoreType.SecretType) }
|
_sign = { try secretStore.sign(data: $0, with: $1.base as! SecretStoreType.SecretType, for: $2) }
|
||||||
sink = secretStore.objectWillChange.sink { _ in
|
sink = secretStore.objectWillChange.sink { _ in
|
||||||
self.objectWillChange.send()
|
self.objectWillChange.send()
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@ public class AnySecretStore: SecretStore {
|
||||||
return _secrets()
|
return _secrets()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func sign(data: Data, with secret: AnySecret) throws -> Data {
|
public func sign(data: Data, with secret: AnySecret, for provenance: SigningRequestProvenance) throws -> Data {
|
||||||
try _sign(data, secret)
|
try _sign(data, secret, provenance)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ public protocol SecretStore: ObservableObject, Identifiable {
|
||||||
var name: String { get }
|
var name: String { get }
|
||||||
var secrets: [SecretType] { 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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ extension SigningRequestProvenance {
|
||||||
}
|
}
|
||||||
|
|
||||||
public var intact: Bool {
|
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 name: String
|
||||||
public let path: String
|
public let path: String
|
||||||
public let validSignature: Bool
|
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.pid = pid
|
||||||
self.name = name
|
self.name = name
|
||||||
self.path = path
|
self.path = path
|
|
@ -1,6 +1,7 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import Security
|
import Security
|
||||||
import CryptoTokenKit
|
import CryptoTokenKit
|
||||||
|
import LocalAuthentication
|
||||||
|
|
||||||
extension SecureEnclave {
|
extension SecureEnclave {
|
||||||
|
|
||||||
|
@ -75,7 +76,10 @@ extension SecureEnclave {
|
||||||
reloadSecrets()
|
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 \"\(provenance.origin.name)\" using secret \"\(secret.name)\""
|
||||||
|
context.localizedCancelTitle = "Deny"
|
||||||
let attributes = [
|
let attributes = [
|
||||||
kSecClass: kSecClassKey,
|
kSecClass: kSecClassKey,
|
||||||
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
|
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
|
||||||
|
@ -83,6 +87,7 @@ extension SecureEnclave {
|
||||||
kSecAttrKeyType: Constants.keyType,
|
kSecAttrKeyType: Constants.keyType,
|
||||||
kSecAttrTokenID: kSecAttrTokenIDSecureEnclave,
|
kSecAttrTokenID: kSecAttrTokenIDSecureEnclave,
|
||||||
kSecAttrApplicationTag: Constants.keyTag,
|
kSecAttrApplicationTag: Constants.keyTag,
|
||||||
|
kSecUseAuthenticationContext: context,
|
||||||
kSecReturnRef: true
|
kSecReturnRef: true
|
||||||
] as CFDictionary
|
] as CFDictionary
|
||||||
var untyped: CFTypeRef?
|
var untyped: CFTypeRef?
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import Security
|
import Security
|
||||||
import CryptoTokenKit
|
import CryptoTokenKit
|
||||||
|
import LocalAuthentication
|
||||||
|
|
||||||
// TODO: Might need to split this up into "sub-stores?"
|
// TODO: Might need to split this up into "sub-stores?"
|
||||||
// ie, each token has its own Store.
|
// ie, each token has its own Store.
|
||||||
|
@ -43,13 +44,17 @@ extension SmartCard {
|
||||||
fatalError("Keys must be deleted on the smart card.")
|
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() }
|
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 = [
|
let attributes = [
|
||||||
kSecClass: kSecClassKey,
|
kSecClass: kSecClassKey,
|
||||||
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
|
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
|
||||||
kSecAttrApplicationLabel: secret.id as CFData,
|
kSecAttrApplicationLabel: secret.id as CFData,
|
||||||
kSecAttrTokenID: tokenID,
|
kSecAttrTokenID: tokenID,
|
||||||
|
kSecUseAuthenticationContext: context,
|
||||||
kSecReturnRef: true
|
kSecReturnRef: true
|
||||||
] as CFDictionary
|
] as CFDictionary
|
||||||
var untyped: CFTypeRef?
|
var untyped: CFTypeRef?
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
50153E20250AFCB200525160 /* UpdateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50153E1F250AFCB200525160 /* UpdateView.swift */; };
|
50153E20250AFCB200525160 /* UpdateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50153E1F250AFCB200525160 /* UpdateView.swift */; };
|
||||||
50153E22250DECA300525160 /* SecretListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50153E21250DECA300525160 /* SecretListView.swift */; };
|
50153E22250DECA300525160 /* SecretListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50153E21250DECA300525160 /* SecretListView.swift */; };
|
||||||
5018F54F24064786002EB505 /* Notifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5018F54E24064786002EB505 /* Notifier.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 */; };
|
50524B442420969E008DBD97 /* OpenSSHWriterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50524B432420969D008DBD97 /* OpenSSHWriterTests.swift */; };
|
||||||
50571E0324393C2600F76F6C /* JustUpdatedChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50571E0224393C2600F76F6C /* JustUpdatedChecker.swift */; };
|
50571E0324393C2600F76F6C /* JustUpdatedChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50571E0224393C2600F76F6C /* JustUpdatedChecker.swift */; };
|
||||||
50571E0524393D1500F76F6C /* LaunchAgentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50571E0424393D1500F76F6C /* LaunchAgentController.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 */; };
|
507CE4ED2420A3C70029F750 /* Agent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79F24026B9900D209EA /* Agent.swift */; };
|
||||||
507CE4EE2420A3CA0029F750 /* SocketController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79D24026B9900D209EA /* SocketController.swift */; };
|
507CE4EE2420A3CA0029F750 /* SocketController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79D24026B9900D209EA /* SocketController.swift */; };
|
||||||
507CE4F02420A4C50029F750 /* SigningWitness.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507CE4EF2420A4C50029F750 /* SigningWitness.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 */; };
|
507CE4F62420A96F0029F750 /* SigningRequestTracer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507CE4F52420A96F0029F750 /* SigningRequestTracer.swift */; };
|
||||||
507EE34224281E12003C4FE3 /* FileHandleProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507EE34124281E12003C4FE3 /* FileHandleProtocols.swift */; };
|
507EE34224281E12003C4FE3 /* FileHandleProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507EE34124281E12003C4FE3 /* FileHandleProtocols.swift */; };
|
||||||
507EE34624281F89003C4FE3 /* StubFileHandleReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507EE34524281F89003C4FE3 /* StubFileHandleReader.swift */; };
|
507EE34624281F89003C4FE3 /* StubFileHandleReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507EE34524281F89003C4FE3 /* StubFileHandleReader.swift */; };
|
||||||
|
@ -381,6 +381,7 @@
|
||||||
504BA92D243171F20064740E /* Types */ = {
|
504BA92D243171F20064740E /* Types */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */,
|
||||||
50617DCA23FCECA10099B055 /* Secret.swift */,
|
50617DCA23FCECA10099B055 /* Secret.swift */,
|
||||||
50617DC623FCE4EA0099B055 /* SecretStore.swift */,
|
50617DC623FCE4EA0099B055 /* SecretStore.swift */,
|
||||||
);
|
);
|
||||||
|
@ -593,7 +594,6 @@
|
||||||
5099A089240242C20062B6F2 /* SSHAgentProtocol.swift */,
|
5099A089240242C20062B6F2 /* SSHAgentProtocol.swift */,
|
||||||
50A3B79D24026B9900D209EA /* SocketController.swift */,
|
50A3B79D24026B9900D209EA /* SocketController.swift */,
|
||||||
507CE4EF2420A4C50029F750 /* SigningWitness.swift */,
|
507CE4EF2420A4C50029F750 /* SigningWitness.swift */,
|
||||||
507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */,
|
|
||||||
507CE4F52420A96F0029F750 /* SigningRequestTracer.swift */,
|
507CE4F52420A96F0029F750 /* SigningRequestTracer.swift */,
|
||||||
50A3B79F24026B9900D209EA /* Agent.swift */,
|
50A3B79F24026B9900D209EA /* Agent.swift */,
|
||||||
507EE34124281E12003C4FE3 /* FileHandleProtocols.swift */,
|
507EE34124281E12003C4FE3 /* FileHandleProtocols.swift */,
|
||||||
|
@ -1026,6 +1026,7 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
501B7AE1251C56F700776EC7 /* SigningRequestProvenance.swift in Sources */,
|
||||||
50617DC723FCE4EA0099B055 /* SecretStore.swift in Sources */,
|
50617DC723FCE4EA0099B055 /* SecretStore.swift in Sources */,
|
||||||
5099A02723FE34FA0062B6F2 /* SmartCard.swift in Sources */,
|
5099A02723FE34FA0062B6F2 /* SmartCard.swift in Sources */,
|
||||||
50617DCB23FCECA10099B055 /* Secret.swift in Sources */,
|
50617DCB23FCECA10099B055 /* Secret.swift in Sources */,
|
||||||
|
@ -1078,7 +1079,6 @@
|
||||||
507CE4ED2420A3C70029F750 /* Agent.swift in Sources */,
|
507CE4ED2420A3C70029F750 /* Agent.swift in Sources */,
|
||||||
507CE4F02420A4C50029F750 /* SigningWitness.swift in Sources */,
|
507CE4F02420A4C50029F750 /* SigningWitness.swift in Sources */,
|
||||||
507CE4F62420A96F0029F750 /* SigningRequestTracer.swift in Sources */,
|
507CE4F62420A96F0029F750 /* SigningRequestTracer.swift in Sources */,
|
||||||
507CE4F42420A8C10029F750 /* SigningRequestProvenance.swift in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ extension Preview {
|
||||||
self.secrets.append(contentsOf: new)
|
self.secrets.append(contentsOf: new)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sign(data: Data, with secret: Preview.Secret) throws -> Data {
|
func sign(data: Data, with secret: Preview.Secret, for provenance: SigningRequestProvenance) throws -> Data {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue