1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-19 09:43:23 +00:00

Add support for biometrics to Safari (#1775)

* Add Biometrics support to Safari
This commit is contained in:
Oscar Hinton
2021-04-07 17:39:59 +02:00
committed by GitHub
parent eeb61b019b
commit ae4c1b29d2
5 changed files with 174 additions and 70 deletions

View File

@@ -31,7 +31,7 @@
containerPortal = 55E037402577FA6B00979016 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 55E037592577FA6F00979016;
remoteInfo = "safari";
remoteInfo = safari;
};
/* End PBXContainerItemProxy section */
@@ -50,6 +50,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
5508DD7926051B5900A85C58 /* libswiftAppKit.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libswiftAppKit.tbd; path = usr/lib/swift/libswiftAppKit.tbd; sourceTree = SDKROOT; };
55E037482577FA6B00979016 /* desktop.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = desktop.app; sourceTree = BUILT_PRODUCTS_DIR; };
55E0374B2577FA6B00979016 /* desktop.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = desktop.entitlements; sourceTree = "<group>"; };
55E0374C2577FA6B00979016 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -127,6 +128,7 @@
55E0375E2577FA6F00979016 /* Frameworks */ = {
isa = PBXGroup;
children = (
5508DD7926051B5900A85C58 /* libswiftAppKit.tbd */,
55E0375F2577FA6F00979016 /* Cocoa.framework */,
);
name = Frameworks;
@@ -157,7 +159,7 @@
55E037782577FA6F00979016 /* _locales */,
);
name = Resources;
path = "safari";
path = safari;
sourceTree = SOURCE_ROOT;
};
/* End PBXGroup section */
@@ -195,7 +197,7 @@
dependencies = (
);
name = safari;
productName = "safari";
productName = safari;
productReference = 55E0375A2577FA6F00979016 /* safari.appex */;
productType = "com.apple.product-type.app-extension";
};
@@ -426,6 +428,53 @@
};
name = Release;
};
55E037692577FA6F00979016 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_ENTITLEMENTS = safari/safari.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = HGT9YVMPAL;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = safari/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
PRODUCT_BUNDLE_IDENTIFIER = com.bitwarden.desktop.safari;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
55E0376A2577FA6F00979016 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_ENTITLEMENTS = safari/safari.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = HGT9YVMPAL;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = safari/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
PRODUCT_BUNDLE_IDENTIFIER = com.bitwarden.desktop.safari;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
};
name = Release;
};
55E0376D2577FA6F00979016 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -435,7 +484,7 @@
CODE_SIGN_ENTITLEMENTS = desktop/desktop.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = LTZ2PFU5D6;
DEVELOPMENT_TEAM = HGT9YVMPAL;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = desktop/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -459,7 +508,7 @@
CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = LTZ2PFU5D6;
DEVELOPMENT_TEAM = HGT9YVMPAL;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = desktop/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -473,51 +522,6 @@
};
name = Release;
};
55E037692577FA6F00979016 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_ENTITLEMENTS = "safari/safari.entitlements";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = LTZ2PFU5D6;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "safari/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
PRODUCT_BUNDLE_IDENTIFIER = com.bitwarden.desktop.safari;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
55E0376A2577FA6F00979016 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_ENTITLEMENTS = "safari/safari.entitlements";
CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = LTZ2PFU5D6;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "safari/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
PRODUCT_BUNDLE_IDENTIFIER = com.bitwarden.desktop.safari;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */

View File

@@ -1,7 +1,9 @@
import SafariServices
import os.log
import LocalAuthentication
let SFExtensionMessageKey = "message"
let ServiceName = "Bitwarden"
class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
@@ -78,14 +80,68 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
context.completeRequest(returningItems: [response], completionHandler: nil)
}
return
case "biometricUnlock":
var error: NSError?
let laContext = LAContext()
guard laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
response.userInfo = [
SFExtensionMessageKey: [
"message": [
"command": "biometricUnlock",
"response": "not supported",
"timestamp": Int64(NSDate().timeIntervalSince1970 * 1000),
],
],
]
break;
}
laContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "Bitwarden Safari Extension") { (success, error) in
if success {
let passwordName = "key"
var passwordLength: UInt32 = 0
var passwordPtr: UnsafeMutableRawPointer? = nil
let status = SecKeychainFindGenericPassword(nil, UInt32(ServiceName.utf8.count), ServiceName, UInt32(passwordName.utf8.count), passwordName, &passwordLength, &passwordPtr, nil)
if status == errSecSuccess {
let result = NSString(bytes: passwordPtr!, length: Int(passwordLength), encoding: String.Encoding.utf8.rawValue) as String?
SecKeychainItemFreeContent(nil, passwordPtr)
response.userInfo = [ SFExtensionMessageKey: [
"message": [
"command": "biometricUnlock",
"response": "unlocked",
"timestamp": Int64(NSDate().timeIntervalSince1970 * 1000),
"keyB64": result!.replacingOccurrences(of: "\"", with: ""),
],
]]
} else {
response.userInfo = [
SFExtensionMessageKey: [
"message": [
"command": "biometricUnlock",
"response": "not enabled",
"timestamp": Int64(NSDate().timeIntervalSince1970 * 1000),
],
],
]
}
}
context.completeRequest(returningItems: [response], completionHandler: nil)
}
return;
default:
return
}
context.completeRequest(returningItems: [response], completionHandler: nil)
}
}
func jsonSerialize<T: Encodable>(obj: T?) -> String? {