Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TouchID support refactoring #8311

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions src/touchid/TouchID.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,17 @@ class TouchID
bool storeKey(const QString& databasePath, const QByteArray& passwordKey);
bool getKey(const QString& databasePath, QByteArray& passwordKey) const;
bool containsKey(const QString& databasePath) const;
bool isAvailable();
void reset(const QString& databasePath = "");

static bool isAvailable();
static bool isWatchAvailable();
static bool isTouchIdAvailable();
droidmonkey marked this conversation as resolved.
Show resolved Hide resolved

private:
void checkHardwareAvailability();
static bool checkWatchAvailability();
static bool checkTouchIdAvailability();

static void deleteKeyEntry(const QString& accountName);
static QString databaseKeyName(const QString& databasePath);

private:
bool m_availabilityChecked{false};
bool m_isTouchIdAvailable{false};
bool m_isWatchAvailable{false};

QHash<QString, QByteArray> m_encryptedMasterKeys;
};

Expand Down
31 changes: 11 additions & 20 deletions src/touchid/TouchID.mm
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ inline CFMutableDictionaryRef makeDictionary() {
// - Not all flags are available in all OS versions, so we have to check it at compile time
// - Requesting Biometry/TouchID when to fingerprint sensor is available will result in runtime error
SecAccessControlCreateFlags accessControlFlags = 0;
if (m_isTouchIdAvailable) {
if (isTouchIdAvailable()) {
#if XC_COMPILER_SUPPORT(APPLE_BIOMETRY)
// Prefer the non-deprecated flag when available
accessControlFlags = kSecAccessControlBiometryCurrentSet;
Expand All @@ -138,7 +138,7 @@ inline CFMutableDictionaryRef makeDictionary() {
#endif
}

if (m_isWatchAvailable) {
if (isWatchAvailable()) {
#if XC_COMPILER_SUPPORT(WATCH_UNLOCK)
accessControlFlags = accessControlFlags | kSecAccessControlOr | kSecAccessControlWatch;
#endif
Expand Down Expand Up @@ -262,16 +262,8 @@ inline CFMutableDictionaryRef makeDictionary() {
return m_encryptedMasterKeys.contains(dbPath);
}

void TouchID::checkHardwareAvailability()
{
m_isTouchIdAvailable = checkTouchIdAvailability();
m_isWatchAvailable = checkWatchAvailability();
debug("TouchID available: %d", m_isTouchIdAvailable);
debug("Apple Watch available: %d", m_isWatchAvailable);
}

//! @return true if Apple Watch is available for authentication.
bool TouchID::checkWatchAvailability()
bool TouchID::isWatchAvailable()
{
#if XC_COMPILER_SUPPORT(WATCH_UNLOCK)
@try {
Expand All @@ -281,6 +273,7 @@ inline CFMutableDictionaryRef makeDictionary() {

bool canAuthenticate = [context canEvaluatePolicy:policyCode error:nil];
[context release];
debug("Apple Wach available: %d", canAuthenticate);
return canAuthenticate;
} @catch (NSException *) {
return false;
Expand All @@ -291,7 +284,7 @@ inline CFMutableDictionaryRef makeDictionary() {
}

//! @return true if Touch ID is available for authentication.
bool TouchID::checkTouchIdAvailability()
bool TouchID::isTouchIdAvailable()
{
#if XC_COMPILER_SUPPORT(TOUCH_ID)
@try {
Expand All @@ -301,6 +294,7 @@ inline CFMutableDictionaryRef makeDictionary() {

bool canAuthenticate = [context canEvaluatePolicy:policyCode error:nil];
[context release];
debug("Touch ID available: %d", canAuthenticate);
return canAuthenticate;
} @catch (NSException *) {
return false;
Expand All @@ -310,16 +304,13 @@ inline CFMutableDictionaryRef makeDictionary() {
#endif
}

/**
* Dynamic check if TouchID is available on the current machine.
*/
//! @return true if either TouchID or Apple Watch is available at the moment.
bool TouchID::isAvailable()
{
if (!m_availabilityChecked) {
checkHardwareAvailability();
m_availabilityChecked = true;
}
return m_isTouchIdAvailable || m_isWatchAvailable;
// note: we cannot cache the check results because the configuration
// is dynamic in its nature. User can close the laptop lid or take off
// the watch, thus making one (or both )of the authentication types unavailable.
return isWatchAvailable() || isTouchIdAvailable();
}

/**
Expand Down