Skip to content
Snippets Groups Projects
Unverified Commit b29232b0 authored by Jakob Möller's avatar Jakob Möller Committed by GitHub
Browse files

Switch the DB Password to use the KeyStore MasterKey (#98)


Signed-off-by: default avatard067928 <jakob.moeller@sap.com>
parent 2db640ba
No related branches found
No related tags found
No related merge requests found
...@@ -10,9 +10,9 @@ import de.rki.coronawarnapp.storage.keycache.KeyCacheEntity ...@@ -10,9 +10,9 @@ import de.rki.coronawarnapp.storage.keycache.KeyCacheEntity
import de.rki.coronawarnapp.storage.tracing.TracingIntervalDao import de.rki.coronawarnapp.storage.tracing.TracingIntervalDao
import de.rki.coronawarnapp.storage.tracing.TracingIntervalEntity import de.rki.coronawarnapp.storage.tracing.TracingIntervalEntity
import de.rki.coronawarnapp.util.Converters import de.rki.coronawarnapp.util.Converters
import de.rki.coronawarnapp.util.security.SecurityHelper
import net.sqlcipher.database.SQLiteDatabase import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SupportFactory import net.sqlcipher.database.SupportFactory
import java.util.UUID
@Database( @Database(
entities = [ExposureSummaryEntity::class, KeyCacheEntity::class, TracingIntervalEntity::class], entities = [ExposureSummaryEntity::class, KeyCacheEntity::class, TracingIntervalEntity::class],
...@@ -39,11 +39,8 @@ abstract class AppDatabase : RoomDatabase() { ...@@ -39,11 +39,8 @@ abstract class AppDatabase : RoomDatabase() {
fun resetInstance(context: Context) = { instance = null }.also { getInstance(context) } fun resetInstance(context: Context) = { instance = null }.also { getInstance(context) }
private fun buildDatabase(context: Context): AppDatabase { private fun buildDatabase(context: Context): AppDatabase {
if (LocalData.databasePassword() == null) {
LocalData.databasePassword(UUID.randomUUID().toString().toCharArray())
}
return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME) return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
.openHelperFactory(SupportFactory(SQLiteDatabase.getBytes(LocalData.databasePassword()))) .openHelperFactory(SupportFactory(SQLiteDatabase.getBytes(SecurityHelper.getDBPassword())))
.build() .build()
} }
} }
......
...@@ -469,27 +469,6 @@ object LocalData { ...@@ -469,27 +469,6 @@ object LocalData {
CoronaWarnApplication.getAppContext().getString(R.string.preference_teletan), null CoronaWarnApplication.getAppContext().getString(R.string.preference_teletan), null
) )
/****************************************************
* DATABASE PASSWORD
****************************************************/
fun databasePassword(): CharArray? = getSharedPreferenceInstance().getString(
CoronaWarnApplication.getAppContext()
.getString(R.string.preference_database_password),
null
)?.toCharArray()
fun databasePassword(password: CharArray) {
with(getSharedPreferenceInstance().edit()) {
putString(
CoronaWarnApplication.getAppContext()
.getString(R.string.preference_database_password),
password.toString()
)
commit()
}
}
/**************************************************** /****************************************************
* ENCRYPTED SHARED PREFERENCES HANDLING * ENCRYPTED SHARED PREFERENCES HANDLING
****************************************************/ ****************************************************/
......
...@@ -24,7 +24,6 @@ import android.util.Log ...@@ -24,7 +24,6 @@ import android.util.Log
import de.rki.coronawarnapp.storage.AppDatabase import de.rki.coronawarnapp.storage.AppDatabase
import de.rki.coronawarnapp.storage.FileStorageHelper import de.rki.coronawarnapp.storage.FileStorageHelper
import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.storage.LocalData
import java.util.UUID
/** /**
* Helper for supplying functionality regarding Data Retention * Helper for supplying functionality regarding Data Retention
...@@ -44,7 +43,6 @@ object DataRetentionHelper { ...@@ -44,7 +43,6 @@ object DataRetentionHelper {
LocalData.getSharedPreferenceInstance().edit().clear().apply() LocalData.getSharedPreferenceInstance().edit().clear().apply()
// Delete Database Instance // Delete Database Instance
AppDatabase.resetInstance(context) AppDatabase.resetInstance(context)
LocalData.databasePassword(UUID.randomUUID().toString().toCharArray())
// Export File Reset // Export File Reset
FileStorageHelper.getAllFilesInKeyExportDirectory().forEach { it.delete() } FileStorageHelper.getAllFilesInKeyExportDirectory().forEach { it.delete() }
Log.w(TAG, "CWA LOCAL DATA DELETION COMPLETED.") Log.w(TAG, "CWA LOCAL DATA DELETION COMPLETED.")
......
...@@ -24,16 +24,30 @@ import android.content.SharedPreferences ...@@ -24,16 +24,30 @@ import android.content.SharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys import androidx.security.crypto.MasterKeys
import de.rki.coronawarnapp.CoronaWarnApplication import de.rki.coronawarnapp.CoronaWarnApplication
import java.security.KeyStore
/**
* Key Store and Password Access
*/
object SecurityHelper { object SecurityHelper {
private const val SHARED_PREF_NAME = "shared_preferences_cwa" private const val SHARED_PREF_NAME = "shared_preferences_cwa"
private val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC private val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
private val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec) private val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
private const val AndroidKeyStore = "AndroidKeyStore"
private val keyStore: KeyStore by lazy {
KeyStore.getInstance(AndroidKeyStore).also {
it.load(null)
}
}
val globalEncryptedSharedPreferencesInstance: SharedPreferences by lazy { val globalEncryptedSharedPreferencesInstance: SharedPreferences by lazy {
CoronaWarnApplication.getAppContext().getEncryptedSharedPrefs(SHARED_PREF_NAME) CoronaWarnApplication.getAppContext().getEncryptedSharedPrefs(SHARED_PREF_NAME)
} }
/**
* Initializes the private encrypted key store
*/
private fun Context.getEncryptedSharedPrefs(fileName: String) = EncryptedSharedPreferences private fun Context.getEncryptedSharedPrefs(fileName: String) = EncryptedSharedPreferences
.create( .create(
fileName, fileName,
...@@ -42,4 +56,12 @@ object SecurityHelper { ...@@ -42,4 +56,12 @@ object SecurityHelper {
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
) )
/**
* Retrieves the Master Key from the Android KeyStore to use in SQLCipher
*/
fun getDBPassword() = keyStore
.getKey(masterKeyAlias, null)
.toString()
.toCharArray()
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment