Skip to content

Commit

Permalink
secure storage of secret generator seed
Browse files Browse the repository at this point in the history
  • Loading branch information
artginzburg committed Jan 27, 2020
1 parent 8ce0820 commit 0d9bd88
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 16 deletions.
41 changes: 36 additions & 5 deletions 2FA to Tray.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 52;
objects = {

/* Begin PBXBuildFile section */
3148B57923DE260D0075A192 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3148B57823DE260D0075A192 /* AppDelegate.swift */; };
3148B57B23DE260F0075A192 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3148B57A23DE260F0075A192 /* Assets.xcassets */; };
3148B57E23DE260F0075A192 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3148B57C23DE260F0075A192 /* MainMenu.xib */; };
3148B58723DE2A700075A192 /* StatusMenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3148B58623DE2A700075A192 /* StatusMenuController.swift */; };
3152B18723DF762300B8FA7E /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 3152B18623DF762300B8FA7E /* KeychainAccess */; };
31E0DC8A23DE374900AC1230 /* SwiftyTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31E0DC8823DE374900AC1230 /* SwiftyTimer.swift */; };
31E0DC8B23DE374900AC1230 /* totp.js in Resources */ = {isa = PBXBuildFile; fileRef = 31E0DC8923DE374900AC1230 /* totp.js */; };
/* End PBXBuildFile section */
Expand All @@ -32,6 +33,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
3152B18723DF762300B8FA7E /* KeychainAccess in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -85,6 +87,9 @@
dependencies = (
);
name = "2FA to Tray";
packageProductDependencies = (
3152B18623DF762300B8FA7E /* KeychainAccess */,
);
productName = "2FA to Tray";
productReference = 3148B57523DE260D0075A192 /* 2FA to Tray.app */;
productType = "com.apple.product-type.application";
Expand Down Expand Up @@ -113,6 +118,9 @@
Base,
);
mainGroup = 3148B56C23DE260D0075A192;
packageReferences = (
3152B18523DF762300B8FA7E /* XCRemoteSwiftPackageReference "KeychainAccess" */,
);
productRefGroup = 3148B57623DE260D0075A192 /* Products */;
projectDirPath = "";
projectRoot = "";
Expand Down Expand Up @@ -278,15 +286,17 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "2FA to Tray/2FAtoTray.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = R2294BC6J8;
INFOPLIST_FILE = "2FA to Tray/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.1;
MARKETING_VERSION = 1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.dafuqtor.2FAtoTray;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -298,15 +308,17 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "2FA to Tray/2FAtoTray.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = R2294BC6J8;
INFOPLIST_FILE = "2FA to Tray/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.1;
MARKETING_VERSION = 1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.dafuqtor.2FAtoTray;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand Down Expand Up @@ -335,6 +347,25 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
3152B18523DF762300B8FA7E /* XCRemoteSwiftPackageReference "KeychainAccess" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 4.1.0;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
3152B18623DF762300B8FA7E /* KeychainAccess */ = {
isa = XCSwiftPackageProductDependency;
package = 3152B18523DF762300B8FA7E /* XCRemoteSwiftPackageReference "KeychainAccess" */;
productName = KeychainAccess;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 3148B56D23DE260D0075A192 /* Project object */;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"object": {
"pins": [
{
"package": "KeychainAccess",
"repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess.git",
"state": {
"branch": null,
"revision": "b920ad7df3c73189dcdd4aa05c540849b2010dbf",
"version": "4.1.0"
}
}
]
},
"version": 1
}
12 changes: 8 additions & 4 deletions 2FA to Tray/2FAtoTray.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.dafuqtor.2FAtoTray</string>
</array>
</dict>
</plist>
26 changes: 21 additions & 5 deletions 2FA to Tray/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import Cocoa
import JavaScriptCore
import KeychainAccess

let keychain = Keychain(service: "com.dafuqtor.2FAtoTray")

extension String {

Expand Down Expand Up @@ -126,8 +129,9 @@ class OTP {
textfield.becomeFirstResponder()
}

if !self.secret.isEmpty {
textfield.stringValue = self.secret
let theSecret = keychain["secret"]
if !theSecret!.isEmpty {
textfield.stringValue = theSecret!
}

let response = alert.runModal()
Expand All @@ -136,16 +140,28 @@ class OTP {
let value = textfield.stringValue
if !value.isEmpty {
let secret = value.condenseWhitespace()
print(secret)
UserDefaults.standard.set(secret, forKey: "secret")

do {
try keychain
.synchronizable(true)
.accessibility(.afterFirstUnlock)
.set(secret, key: "secret")
} catch let error {
print("error: \(error)")
}

self.button?.appearsDisabled = false
self.secret = secret
} else {
print("Empty value")
}
} else if response == .alertThirdButtonReturn {
print("Delete secret")
UserDefaults.standard.removeObject(forKey: "secret")
do {
try keychain.remove("secret")
} catch let error {
print("error: \(error)")
}
self.secret = ""
self.token = ""
self.button?.toolTip = ""
Expand Down
3 changes: 2 additions & 1 deletion 2FA to Tray/StatusMenuController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class StatusMenuController: NSObject, NSMenuDelegate {
}

override func awakeFromNib() {
UserDefaults.standard.removeObject(forKey: "secret")
statusItem.menu = statusMenu
statusMenu.delegate = self
statusItem.isVisible = true
Expand All @@ -63,7 +64,7 @@ class StatusMenuController: NSObject, NSMenuDelegate {
button.target = self
otp.button = button

let secret = UserDefaults.standard.string(forKey: "secret")?.condenseWhitespace() ?? ""
let secret = keychain["secret"]?.condenseWhitespace() ?? ""
if secret.isEmpty {
button.appearsDisabled = true
otp.showAlert()
Expand Down

0 comments on commit 0d9bd88

Please sign in to comment.