Compare commits

..

9 Commits

Author SHA1 Message Date
fe16e4d9c4 Build and About page (#64)
* Adding credits txt

* Switch up build number
2020-03-19 21:16:14 -07:00
1caf65c68d Header cleanup 2020-03-18 20:04:48 -07:00
85eb4983bc Split witness call (fixes #62) 2020-03-18 20:04:24 -07:00
5a2d3ecc2e Fix dumb mistake. 2020-03-17 23:28:51 -07:00
32f0ed88f4 Validate code signature as well. 2020-03-17 22:59:03 -07:00
d35c58509b Hacky fix for #16 2020-03-17 20:41:37 -07:00
f810b185f0 Fix debug config for running 2020-03-17 20:34:32 -07:00
5ef1fe996b Add path to request trace (#61) 2020-03-17 01:23:49 -07:00
2b5fdf541d Request Attribution (#59) 2020-03-17 00:56:55 -07:00
12 changed files with 88 additions and 10 deletions

View File

@ -45,9 +45,12 @@ jobs:
- name: Update Build Number - name: Update Build Number
env: env:
TAG_NAME: ${{ github.ref }} TAG_NAME: ${{ github.ref }}
RUN_ID: ${{ github.run_id }}
run: | run: |
export CLEAN_TAG=$(echo $TAG_NAME | sed -e 's/refs\/tags\/v//') export CLEAN_TAG=$(echo $TAG_NAME | sed -e 's/refs\/tags\/v//')
sed -i '' -e "s/CI_VERSION = 0.0.0/CI_VERSION = $CLEAN_TAG/g" Config/Config.xcconfig sed -i '' -e "s/GITHUB_CI_VERSION/$CLEAN_TAG/g" Config/Config.xcconfig
sed -i '' -e "s/GITHUB_BUILD_NUMBER/1.$RUN_ID/g" Config/Config.xcconfig
sed -i '' -e "s/GITHUB_BUILD_URL/https:\/\/github.com\/maxgoedjen\/secretive\/actions\/runs\/$RUN_ID/g" Secretive/Credits.rtf
- name: Build - name: Build
run: xcrun xcodebuild -project Secretive.xcodeproj -scheme Secretive -configuration Release -archivePath Archive.xcarchive archive run: xcrun xcodebuild -project Secretive.xcodeproj -scheme Secretive -configuration Release -archivePath Archive.xcarchive archive
- name: Create ZIPs - name: Create ZIPs

View File

@ -1 +1,2 @@
CI_VERSION = 0.0.0 CI_VERSION = GITHUB_CI_VERSION
CI_BUILD_NUMBER = GITHUB_BUILD_NUMBER

View File

@ -24,6 +24,9 @@ class Notifier {
extension Notifier: SigningWitness { extension Notifier: SigningWitness {
func speakNowOrForeverHoldYourPeace(forAccessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws {
}
func witness(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws { func witness(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws {
notify(accessTo: secret, by: provenance) notify(accessTo: secret, by: provenance)
} }

View File

@ -87,7 +87,7 @@ extension Agent {
let provenance = requestTracer.provenance(from: pid) let provenance = requestTracer.provenance(from: pid)
if let witness = witness { if let witness = witness {
try witness.witness(accessTo: secret, by: provenance) try witness.speakNowOrForeverHoldYourPeace(forAccessTo: secret, by: provenance)
} }
let dataToSign = try reader.readNextChunk() let dataToSign = try reader.readNextChunk()
@ -122,6 +122,10 @@ extension Agent {
sub.append(writer.lengthAndData(of: signatureChunk)) sub.append(writer.lengthAndData(of: signatureChunk))
signedData.append(writer.lengthAndData(of: sub)) signedData.append(writer.lengthAndData(of: sub))
if let witness = witness {
try witness.witness(accessTo: secret, by: provenance)
}
os_log(.debug, "Agent signed request") os_log(.debug, "Agent signed request")
return signedData return signedData

View File

@ -7,6 +7,16 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <Security/Security.h>
// Forward declarations
// from libproc.h
int proc_pidpath(int pid, void * buffer, uint32_t buffersize);
// from SecTask.h
OSStatus SecCodeCreateWithPID(int32_t, SecCSFlags, SecCodeRef *);
//! Project version number for SecretAgentKit. //! Project version number for SecretAgentKit.
FOUNDATION_EXPORT double SecretAgentKitVersionNumber; FOUNDATION_EXPORT double SecretAgentKitVersionNumber;
@ -14,6 +24,4 @@ FOUNDATION_EXPORT double SecretAgentKitVersionNumber;
//! Project version string for SecretAgentKit. //! Project version string for SecretAgentKit.
FOUNDATION_EXPORT const unsigned char SecretAgentKitVersionString[]; FOUNDATION_EXPORT const unsigned char SecretAgentKitVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <SecretAgentKit/PublicHeader.h>

View File

@ -16,6 +16,10 @@ extension SigningRequestProvenance {
chain.last! chain.last!
} }
public var intact: Bool {
return chain.reduce(true) { $0 && $1.validSignature }
}
} }
extension SigningRequestProvenance { extension SigningRequestProvenance {
@ -25,12 +29,14 @@ extension SigningRequestProvenance {
public let pid: Int32 public let pid: Int32
public let name: String public let name: String
public let path: String public let path: String
public let validSignature: Bool
let parentPID: Int32? let parentPID: Int32?
init(pid: Int32, name: String, path: String, parentPID: Int32?) { 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
self.validSignature = validSignature
self.parentPID = parentPID self.parentPID = parentPID
} }

View File

@ -1,5 +1,6 @@
import Foundation import Foundation
import AppKit import AppKit
import Security
struct SigningRequestTracer { struct SigningRequestTracer {
@ -29,7 +30,14 @@ struct SigningRequestTracer {
var pidAndNameInfo = self.pidAndNameInfo(from: pid) var pidAndNameInfo = self.pidAndNameInfo(from: pid)
let ppid = pidAndNameInfo.kp_eproc.e_ppid != 0 ? pidAndNameInfo.kp_eproc.e_ppid : nil let ppid = pidAndNameInfo.kp_eproc.e_ppid != 0 ? pidAndNameInfo.kp_eproc.e_ppid : nil
let procName = String(cString: &pidAndNameInfo.kp_proc.p_comm.0) let procName = String(cString: &pidAndNameInfo.kp_proc.p_comm.0)
return SigningRequestProvenance.Process(pid: pid, name: procName, path: "", parentPID: ppid) let pathPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: Int(MAXPATHLEN))
_ = proc_pidpath(pid, pathPointer, UInt32(MAXPATHLEN))
let path = String(cString: pathPointer)
var secCode: Unmanaged<SecCode>!
let flags: SecCSFlags = [.considerExpiration, .enforceRevocationChecks]
SecCodeCreateWithPID(pid, SecCSFlags(), &secCode)
let valid = SecCodeCheckValidity(secCode.takeRetainedValue(), flags, nil) == errSecSuccess
return SigningRequestProvenance.Process(pid: pid, name: procName, path: path, validSignature: valid, parentPID: ppid)
} }
} }

View File

@ -3,6 +3,7 @@ import SecretKit
public protocol SigningWitness { public protocol SigningWitness {
func speakNowOrForeverHoldYourPeace(forAccessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws
func witness(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws func witness(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws
} }

View File

@ -11,16 +11,17 @@ extension SmartCard {
// TODO: Read actual smart card name, eg "YubiKey 5c" // TODO: Read actual smart card name, eg "YubiKey 5c"
@Published public var isAvailable: Bool = false @Published public var isAvailable: Bool = false
public let id = UUID() public let id = UUID()
public let name = NSLocalizedString("Smart Card", comment: "Smart Card") public fileprivate(set) var name = NSLocalizedString("Smart Card", comment: "Smart Card")
@Published public fileprivate(set) var secrets: [Secret] = [] @Published public fileprivate(set) var secrets: [Secret] = []
fileprivate let watcher = TKTokenWatcher() fileprivate let watcher = TKTokenWatcher()
fileprivate var tokenID: String? fileprivate var tokenID: String?
public init() { public init() {
tokenID = watcher.tokenIDs.filter { !$0.contains("setoken") }.first tokenID = watcher.nonSecureEnclaveTokens.first
watcher.setInsertionHandler { string in watcher.setInsertionHandler { string in
guard self.tokenID == nil else { return } guard self.tokenID == nil else { return }
guard !string.contains("setoken") else { return } guard !string.contains("setoken") else { return }
self.tokenID = string self.tokenID = string
self.reloadSecrets() self.reloadSecrets()
self.watcher.addRemovalHandler(self.smartcardRemoved, forTokenID: string) self.watcher.addRemovalHandler(self.smartcardRemoved, forTokenID: string)
@ -97,6 +98,14 @@ extension SmartCard.Store {
fileprivate func loadSecrets() { fileprivate func loadSecrets() {
guard let tokenID = tokenID else { return } guard let tokenID = tokenID else { return }
// Hack to read name if there's only one smart card
let slotNames = TKSmartCardSlotManager().slotNames
if watcher.nonSecureEnclaveTokens.count == 1 && slotNames.count == 1 {
name = slotNames.first!
} else {
name = NSLocalizedString("Smart Card", comment: "Smart Card")
}
let attributes = [ let attributes = [
kSecClass: kSecClassKey, kSecClass: kSecClassKey,
kSecAttrTokenID: tokenID, kSecAttrTokenID: tokenID,
@ -124,6 +133,14 @@ extension SmartCard.Store {
} }
extension TKTokenWatcher {
fileprivate var nonSecureEnclaveTokens: [String] {
tokenIDs.filter { !$0.contains("setoken") }
}
}
extension SmartCard { extension SmartCard {
public struct KeychainError: Error { public struct KeychainError: Error {

View File

@ -26,6 +26,7 @@
50617DCE23FCECFA0099B055 /* SecureEnclaveSecret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DCD23FCECFA0099B055 /* SecureEnclaveSecret.swift */; }; 50617DCE23FCECFA0099B055 /* SecureEnclaveSecret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DCD23FCECFA0099B055 /* SecureEnclaveSecret.swift */; };
50617DD023FCED2C0099B055 /* SecureEnclave.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DCF23FCED2C0099B055 /* SecureEnclave.swift */; }; 50617DD023FCED2C0099B055 /* SecureEnclave.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DCF23FCED2C0099B055 /* SecureEnclave.swift */; };
50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DD123FCEFA90099B055 /* PreviewStore.swift */; }; 50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DD123FCEFA90099B055 /* PreviewStore.swift */; };
506772C72424784600034DED /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 506772C62424784600034DED /* Credits.rtf */; };
5068389E241471CD00F55094 /* SecretStoreList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5068389D241471CD00F55094 /* SecretStoreList.swift */; }; 5068389E241471CD00F55094 /* SecretStoreList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5068389D241471CD00F55094 /* SecretStoreList.swift */; };
506838A12415EA5600F55094 /* AnySecret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A02415EA5600F55094 /* AnySecret.swift */; }; 506838A12415EA5600F55094 /* AnySecret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A02415EA5600F55094 /* AnySecret.swift */; };
506838A32415EA5D00F55094 /* AnySecretStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A22415EA5D00F55094 /* AnySecretStore.swift */; }; 506838A32415EA5D00F55094 /* AnySecretStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A22415EA5D00F55094 /* AnySecretStore.swift */; };
@ -199,6 +200,7 @@
50617DCD23FCECFA0099B055 /* SecureEnclaveSecret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclaveSecret.swift; sourceTree = "<group>"; }; 50617DCD23FCECFA0099B055 /* SecureEnclaveSecret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclaveSecret.swift; sourceTree = "<group>"; };
50617DCF23FCED2C0099B055 /* SecureEnclave.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclave.swift; sourceTree = "<group>"; }; 50617DCF23FCED2C0099B055 /* SecureEnclave.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclave.swift; sourceTree = "<group>"; };
50617DD123FCEFA90099B055 /* PreviewStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewStore.swift; sourceTree = "<group>"; }; 50617DD123FCEFA90099B055 /* PreviewStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewStore.swift; sourceTree = "<group>"; };
506772C62424784600034DED /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
5068389D241471CD00F55094 /* SecretStoreList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretStoreList.swift; sourceTree = "<group>"; }; 5068389D241471CD00F55094 /* SecretStoreList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretStoreList.swift; sourceTree = "<group>"; };
506838A02415EA5600F55094 /* AnySecret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecret.swift; sourceTree = "<group>"; }; 506838A02415EA5600F55094 /* AnySecret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecret.swift; sourceTree = "<group>"; };
506838A22415EA5D00F55094 /* AnySecretStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecretStore.swift; sourceTree = "<group>"; }; 506838A22415EA5D00F55094 /* AnySecretStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecretStore.swift; sourceTree = "<group>"; };
@ -337,6 +339,7 @@
50617D8B23FCE48E0099B055 /* Main.storyboard */, 50617D8B23FCE48E0099B055 /* Main.storyboard */,
50617D8E23FCE48E0099B055 /* Info.plist */, 50617D8E23FCE48E0099B055 /* Info.plist */,
50617D8F23FCE48E0099B055 /* Secretive.entitlements */, 50617D8F23FCE48E0099B055 /* Secretive.entitlements */,
506772C62424784600034DED /* Credits.rtf */,
50617D8823FCE48E0099B055 /* Preview Content */, 50617D8823FCE48E0099B055 /* Preview Content */,
); );
path = Secretive; path = Secretive;
@ -741,6 +744,7 @@
50617D8D23FCE48E0099B055 /* Main.storyboard in Resources */, 50617D8D23FCE48E0099B055 /* Main.storyboard in Resources */,
50617D8A23FCE48E0099B055 /* Preview Assets.xcassets in Resources */, 50617D8A23FCE48E0099B055 /* Preview Assets.xcassets in Resources */,
50617D8723FCE48E0099B055 /* Assets.xcassets in Resources */, 50617D8723FCE48E0099B055 /* Assets.xcassets in Resources */,
506772C72424784600034DED /* Credits.rtf in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -67,7 +67,7 @@
</Testables> </Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Test" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0" launchStyle = "0"

23
Secretive/Credits.rtf Normal file
View File

@ -0,0 +1,23 @@
{\rtf1\ansi\ansicpg1252\cocoartf2511
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6119\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
{\field{\*\fldinst{HYPERLINK "https://github.com/maxgoedjen/secretive"}}{\fldrslt
\f0\fs24 \cf0 https://github.com/maxgoedjen/secretive}}
\f0\fs24 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\cf0 \
GITHUB_BUILD_URL\
\
Special Thanks To:\
https://github.com/bdash\
https://github.com/danielctull\
https://github.com/davedelong\
https://github.com/esttorhe\
https://github.com/joeblau\
https://github.com/marksands\
https://github.com/mergesort\
https://github.com/phillco\
https://github.com/zackdotcomputer}