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

fix: encrypt stored sdk config #275

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/io.customer/android/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package io.customer.android
object Dependencies {
const val androidGradlePlugin =
"com.android.tools.build:gradle:${Versions.ANDROID_GRADLE_PLUGIN}"
const val androidxSecurityCrypto =
"androidx.security:security-crypto:${Versions.ANDROIDX_SECURITY_CRYPTO}"
const val androidxTestJunit = "androidx.test.ext:junit:${Versions.ANDROIDX_TEST_JUNIT}"
const val androidxTestRunner = "androidx.test:runner:${Versions.ANDROIDX_TEST_RUNNER}"
const val androidxTestRules = "androidx.test:rules:${Versions.ANDROIDX_TEST_RULES}"
Expand Down
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/io.customer/android/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package io.customer.android

object Versions {
internal const val ANDROID_GRADLE_PLUGIN = "7.2.0"

// Using alpha version as current stable version (1.0.0) has minSdkVersion 23
internal const val ANDROIDX_SECURITY_CRYPTO = "1.1.0-alpha06"
Comment on lines +6 to +7
Copy link
Contributor

@levibostian levibostian Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because 1.1-alpha releases support minSdk 21 while 1.0 supports minSdk 23, do we anticipate that 1.1 stable will move to minSdk 21?

I would like to avoid us having to bump our minSdk because of this dependency.

internal const val ANDROIDX_TEST_JUNIT = "1.1.4"
internal const val ANDROIDX_TEST_RUNNER = "1.4.0"
internal const val ANDROIDX_TEST_RULES = "1.4.0"
Expand Down
2 changes: 1 addition & 1 deletion messagingpush/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<application>
<application android:fullBackupContent="@xml/backup_rules">
<service
android:name=".CustomerIOFirebaseMessagingService"
android:exported="false">
Expand Down
8 changes: 8 additions & 0 deletions messagingpush/src/main/res/xml/backup_rules.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<!-- Encrypted preferences should not be backed up as the key used to encrypt it will no
longer be present when backup is restored -->
<exclude
domain="sharedpref"
path="io.customer.sdk.EncryptedConfigCache.xml" />
Copy link
Contributor

@levibostian levibostian Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: No need to act on this yet, until my original questions are discussed.

Does this hard-coded string need to match this hard-coded string?

If so, I suggest using a string resource value to store this string in 1 place.

</full-backup-content>
1 change: 1 addition & 0 deletions sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ dependencies {

implementation Dependencies.coroutinesCore
implementation Dependencies.coroutinesAndroid
implementation Dependencies.androidxSecurityCrypto
implementation Dependencies.retrofit
implementation Dependencies.moshi
implementation Dependencies.retrofitMoshiConverter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ internal abstract class BasePreferenceRepository(val context: Context) {

abstract val prefsName: String

internal val prefs: SharedPreferences
get() = context.applicationContext.getSharedPreferences(
prefsName,
Context.MODE_PRIVATE
)
// Making this abstract so base class has option to use encrypted shared prefs
internal abstract val prefs: SharedPreferences

// this would clear the prefs asynchronously
open fun clearAll() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package io.customer.sdk.repository.preference

import android.content.Context
import android.content.SharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import io.customer.sdk.Version
import io.customer.sdk.data.model.Region
import io.customer.sdk.data.store.Client
Expand All @@ -16,8 +19,29 @@ internal interface SharedPreferenceRepository {
internal class SharedPreferenceRepositoryImp(context: Context) : SharedPreferenceRepository,
BasePreferenceRepository(context) {

// The file name used for storing shared preferences.
// This preference file should not be included in Auto Backup.
// Upon restoration, the encryption key originally used may no longer be present.
// To prevent this, ensure the file name matches the one excluded in backup_rules.xml.
// Read more: https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences
override val prefsName: String by lazy {
"io.customer.sdk.${context.packageName}.PREFERENCE_FILE_KEY"
"io.customer.sdk.EncryptedConfigCache"
}

override val prefs: SharedPreferences

init {
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()

prefs = EncryptedSharedPreferences.create(
context,
prefsName,
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
}

override fun saveSettings(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.customer.sdk.repository.preference

import android.content.Context
import android.content.SharedPreferences
import io.customer.sdk.CustomerIOConfig
import io.customer.sdk.extensions.getDate
import io.customer.sdk.extensions.putDate
Expand Down Expand Up @@ -28,6 +29,12 @@ internal class SitePreferenceRepositoryImpl(
"io.customer.sdk.${context.packageName}.${config.siteId}"
}

override val prefs: SharedPreferences
get() = context.applicationContext.getSharedPreferences(
prefsName,
Context.MODE_PRIVATE
)

companion object {
private const val KEY_IDENTIFIER = "identifier"
private const val KEY_DEVICE_TOKEN = "device_token"
Expand Down
Loading