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

[secure-store][android] Secure store audit #23804

Merged
merged 20 commits into from
Aug 28, 2023

Conversation

behenate
Copy link
Member

@behenate behenate commented Aug 2, 2023

Why

ENG-6327
Secure-store was using the old modules API. We wanted to add synchronous functions to the API, so it's possible to use SecureStore in the global JS scope. During the migration I've also found some bugs/unexpected behaviours which were corrected

How

  • Migrated secure-store to Kotlin and the new modules API
  • Changed callback-based authentication prompt to Kotlin coroutines
  • Added getItemSync and setItemSync functions
    • Both functions call the same functions as Async versions, but on the main thread
  • It is now possible to save values which require authentication and ones that don't under one keychain on the JS side. This is archived by creating two separate keys on the native side.
    • Before it wasn't possible to save a no-authentication value under a keychain, which was initialised with a require-auth value (an exception was thrown). It was possible to save a value which requires authentication into a keychain which was already initialised as no-auth, but it wasn't really encrypted with the necessity of auth and could've been decrypted without authentication (although secure-store always asked for biometrics correctly)
  • It is now possible to save values under different keychains but the same key. Secure-store can now differentiate between them. Before saving value1 under key1 and keychain1 and value2 under key1 and keychain2 would overwrite the value1 under key1 with a new value. Now they are separate. This archived by saving the items in shared preferences under a key which includes the keychain eq. keychain1-key1 and keychain2-key1. This emulates the ios secure-store behavior
  • Backwards compatibility with the current naming scheme of keystore aliases has been kept
  • Improved invalidated key exception handling. When removing a key from the key store all values under that key will be removed from shared preferences in order to avoid exceptions caused by decryption fails. This doesn't apply to values stored with previous versions of expo-secure-store as it is not possible to determine if value was stored with a keychain without making an decryption attempt.
  • Updated the docs
  • Removed SDK20 read support

Test Plan

Tested in Bare Expo and Expo Go on a physical android 13 and 7 devices (forced api < 23 functions on android 7 only for testing since we don't have such an old device)

@behenate behenate self-assigned this Aug 2, 2023
@expo-bot expo-bot added the bot: suggestions ExpoBot has some suggestions label Aug 2, 2023
# Conflicts:
#	packages/expo-secure-store/build/SecureStore.d.ts.map
#	packages/expo-secure-store/build/SecureStore.js.map
@behenate behenate force-pushed the @behenate/secure-store-api-migration branch from 9cc1f06 to b076255 Compare August 3, 2023 10:44
@expo-bot expo-bot added bot: passed checks ExpoBot has nothing to complain about and removed bot: suggestions ExpoBot has some suggestions labels Aug 7, 2023
@behenate behenate requested a review from lukmccall August 8, 2023 11:42
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
packages/expo-secure-store/src/SecureStore.ts Outdated Show resolved Hide resolved
# Conflicts:
#	android/expoview/src/main/java/versioned/host/exp/exponent/modules/universal/ExpoModuleRegistryAdapter.kt
@behenate behenate merged commit 8e6653a into main Aug 28, 2023
12 of 14 checks passed
@behenate behenate deleted the @behenate/secure-store-api-migration branch August 28, 2023 09:03
behenate added a commit that referenced this pull request Dec 5, 2023
# Why

In #23804 I modified the behaviour of
SecureStore to be consistent with iOS.
This introduced a change, where trying to get a value from a keychain
service in which it isn't registered will return null instead of
throwing an exception. (I would prefer to do it the other way around -
throwing an exception in that case seems to make more sense - it was not
possible to do on iOS)

This causes one of the tests to fail in `test-suite`

# How

Removed OS type check from the failing test

# Test Plan

✅  `native-component-list` in unversioned Expo Go
behenate added a commit that referenced this pull request Dec 7, 2023
…dling (#23841)

# Why

Synchronous read and write functions will be added to Android in this PR
#23804, we need to add them to iOS too.
The Android PR also changes the keychain handling to allow users to save
authenticated and unauthenticated values under the same keychain, this
PR adds similar changes to iOS.

# How

Added synchronous functions, keychainService will now add a "auth" or
"no-auth" suffix to it's name to allow saving authenticated and
unauthenticated values into the same keychain from the JS perspective.
This behaviour is a more intuitive for the users and makes Android and
iOS versions of the module work exactly the same, but adds some
complexity on the native side.

# Test Plan

Tested on a physical iOS 16 device.

## Do NOT merge before #23804 as this
PR relies on some code changes from that PR
onizam95 pushed a commit to onizam95/expo-av-drm that referenced this pull request Jan 15, 2024
# Why

In expo#23804 I modified the behaviour of
SecureStore to be consistent with iOS.
This introduced a change, where trying to get a value from a keychain
service in which it isn't registered will return null instead of
throwing an exception. (I would prefer to do it the other way around -
throwing an exception in that case seems to make more sense - it was not
possible to do on iOS)

This causes one of the tests to fail in `test-suite`

# How

Removed OS type check from the failing test

# Test Plan

✅  `native-component-list` in unversioned Expo Go
onizam95 pushed a commit to onizam95/expo-av-drm that referenced this pull request Jan 15, 2024
…dling (expo#23841)

# Why

Synchronous read and write functions will be added to Android in this PR
expo#23804, we need to add them to iOS too.
The Android PR also changes the keychain handling to allow users to save
authenticated and unauthenticated values under the same keychain, this
PR adds similar changes to iOS.

# How

Added synchronous functions, keychainService will now add a "auth" or
"no-auth" suffix to it's name to allow saving authenticated and
unauthenticated values into the same keychain from the JS perspective.
This behaviour is a more intuitive for the users and makes Android and
iOS versions of the module work exactly the same, but adds some
complexity on the native side.

# Test Plan

Tested on a physical iOS 16 device.

## Do NOT merge before expo#23804 as this
PR relies on some code changes from that PR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bot: passed checks ExpoBot has nothing to complain about
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants