Skip to content

Commit

Permalink
fallback to quick unlock without touchid if saving key fails with sel…
Browse files Browse the repository at this point in the history
…ected flags, might fix quick unlock on a hackintosh
  • Loading branch information
findus committed Oct 29, 2024
1 parent 5543eda commit 649c961
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/quickunlock/TouchID.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class TouchID : public QuickUnlockInterface
static bool isTouchIdAvailable();
static bool isPasswordFallbackPossible();
static bool isTouchIdEnrolled();
bool setKey(const QUuid& dbUuid, const QByteArray& passwordKey, const bool ignoreTouchID);

static void deleteKeyEntry(const QString& accountName);
static QString databaseKeyName(const QUuid& dbUuid);
Expand Down
32 changes: 24 additions & 8 deletions src/quickunlock/TouchID.mm
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,10 @@ inline CFMutableDictionaryRef makeDictionary() {
m_encryptedMasterKeys.clear();
}

/**
* Generates a random AES 256bit key and uses it to encrypt the PasswordKey that
* protects the database. The encrypted PasswordKey is kept in memory while the
* AES key is stored in the macOS KeyChain protected by either TouchID or Apple Watch.
*/
bool TouchID::setKey(const QUuid& dbUuid, const QByteArray& passwordKey)



bool TouchID::setKey(const QUuid& dbUuid, const QByteArray& passwordKey, const bool ignoreTouchID)
{
if (passwordKey.isEmpty()) {
debug("TouchID::setKey - illegal arguments");
Expand Down Expand Up @@ -137,12 +135,16 @@ inline CFMutableDictionaryRef makeDictionary() {
// Needs a special check to work with SecItemAdd, when TouchID is not enrolled and the flag
// is set, the method call fails with an error. But we want to still set this flag if TouchID is
// enrolled but temporarily unavailable due to closed lid
if (isTouchIdEnrolled()) {
//
// At least on a Hackintosh the enrolled-check does not work (LAErrorBiometryNotAvailable > LAErrorBiometryNotEnrolled),
// so you cannot know for sure if touchid hardware is temporarily unavailable or not present at all, so to make quick
// unlock fallbacks possible there you have to try to save the key a second time without this flag to make it work.
if (isTouchIdEnrolled() && !ignoreTouchID) {
// Prefer the non-deprecated flag when available
accessControlFlags = kSecAccessControlBiometryCurrentSet;
}
#elif XC_COMPILER_SUPPORT(TOUCH_ID)
if (isTouchIdEnrolled()) {
if (isTouchIdEnrolled() && !ignoreTouchID) {
accessControlFlags = kSecAccessControlTouchIDCurrentSet;
}
#endif
Expand Down Expand Up @@ -203,6 +205,20 @@ inline CFMutableDictionaryRef makeDictionary() {
return true;
}

/**
* Generates a random AES 256bit key and uses it to encrypt the PasswordKey that
* protects the database. The encrypted PasswordKey is kept in memory while the
* AES key is stored in the macOS KeyChain protected by either TouchID or Apple Watch.
*/
bool TouchID::setKey(const QUuid& dbUuid, const QByteArray& passwordKey)
{
if (!setKey(dbUuid,passwordKey, false)) {
return setKey(dbUuid, passwordKey, true);
} else {
return true;
}
}

/**
* Checks if an encrypted PasswordKey is available for the given database, tries to
* decrypt it using the KeyChain and if successful, returns it.
Expand Down

0 comments on commit 649c961

Please sign in to comment.