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

Keystore accessibility option for iOS based secret #522

Open
codepushr opened this issue Mar 7, 2024 · 9 comments
Open

Keystore accessibility option for iOS based secret #522

codepushr opened this issue Mar 7, 2024 · 9 comments

Comments

@codepushr
Copy link

Is your feature request related to a problem? Please describe.
We are building an app that heavily relies on keystore access with the accessibility ".afterFirstUnlockThisDeviceOnly". This enables access after first unlock and prevents backups at all times. Using this plugin we can't set this accessibility option and our app can't access the db in closed and locked state (for example when receiving data push notifications).

Describe the solution you'd like
Possibility to configure the accessibility option when setting/getting the database secret.

Describe alternatives you've considered
Forking and setting it ourselves, however this plugin extension might be helpful for others too.

@jepiqueau
Copy link
Collaborator

@codepushr Thanks for this. The plugin provides a biometric login and methods to access the keystore (isSecretStored , setEncryptionSecret, changeEncryptionSecret, clearEncryptionSecret , checkEncryptionSecret)|. As i already explain in issue#480 the plugin cannot provides access to the database by background applications or data push notifications.

I could look at adding secure accessibility options but there are several

  • none equivalent to AccessibleWhenUnlocked
  • AccessibleAfterFirstUnlock
  • AccessibleWhenPasscodeSetThisDeviceOnly
  • AccessibleWhenUnlockedThisDeviceOnly
  • AccessibleAfterFirstUnlockThisDeviceOnly

i will not provide

  • AccessibleAlways
  • AccessibleAlwaysThisDeviceOnly

is that will sweet you?

@jepiqueau
Copy link
Collaborator

@codepushr this will be only for encrypted databases.

@codepushr
Copy link
Author

Oh I didn't realize this. In that case accessing the keystore secret is not really necessary. I guess you can close the issue.

@jepiqueau
Copy link
Collaborator

@codepushr How you will send push notifications (from the device itself from a server ...) to the database application and what kind of payload will have your notification. I need to understand your scenario. May be it could be at your swift app itself you can manage the push notification.

@codepushr
Copy link
Author

codepushr commented Mar 11, 2024

Remote push (server) -> launches terminated app in background -> app will get bootstrapped -> db init -> can't access keystore secret due to wrong accessibility.

However, if you say we can't access an encrypted SQLite db anyway from background with lockscreen, then this scenario is obsolete. Can you maybe elaborate what the exact limitations are and why we can't provide access to the db?

@jepiqueau
Copy link
Collaborator

@codepushr providing the accessibility mode is quite easy my problem where you can help describe is

  • launches the application in background
  • what type of data the remote server will provide set of sql statements, json object
    If you can tell me a bit more i may be looking at this

@codepushr
Copy link
Author

@jepiqueau
I'm a bit confused by the response in issue #480 . The issue/author describes pretty much my scenario:

  1. App is terminated
  2. Phone in standby with lock screen
  3. App receives a push notification

In that case the app is being launched by the system for a brief time (30sec). My understanding from your response in #480 is, that due to some reasons access to the database is not possible? Or did I misunderstood?

@jepiqueau
Copy link
Collaborator

@codepushr it is but i may look at how to implement this and see the implications

@codepushr
Copy link
Author

The data in the push is a simple JSON, later in the processing I'm using TypeORM to write to the underlying SQLite db. But all of this has nothing to do with the actual problem of this issue report.

To get back to my initial post, I encountered an exception when the plugin attempts to retrieve the secret from the iOS keystore when opening the db connection.

const sqliteService = new SQLiteService();
const sqliteConnection = sqliteService.getSqliteConnection(); // returns sqliteConnection

// TypeORM
export const AppDataSource = new DataSource({
  type: 'capacitor',
  driver: sqliteConnection,
  database: environment.get().databaseName,
  mode: 'secret',
  ...
})

This is because when .setEncryptionSecret() is called, the iOS native code is not setting a accessibility attribute and my app requires the kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly flag. The default does not allow access of the keychain without unlock.

// Models/KeychainServices.swift
let query: [String: Any] = [
    // 2
    kSecClass as String: kSecClassGenericPassword,
    // 3
    kSecAttrAccount as String: account, 
    // 4
    kSecAttrService as String: service, // "cap_sec"
    // 5
    kSecValueData as String: passwordData,
    // 6 --> missing 
    // kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
]

As for the explanation in #480 what were you referring to? In what other scenario we can't access the database?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants