Skip to content
Open
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
4 changes: 2 additions & 2 deletions buildSrc/src/main/java/GradleConfig.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
object Android {
const val compileSdk = 33
const val minSdk = 21
const val minSdk = 28
const val targetSdk = 33

const val versionCode = 33
Expand All @@ -21,7 +21,7 @@ object Version {
const val androidxLifecycle = "2.3.1"
const val androidxNavigation = "2.5.1"

const val androidxSecurity = "1.0.0"
const val androidxSecurity = "1.1.0-alpha06"

const val coroutines = "1.5.1"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ package it.airgap.beaconsdk.core.internal.storage.sharedpreferences

import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import androidx.annotation.RestrictTo
import it.airgap.beaconsdk.core.internal.BeaconConfiguration
import it.airgap.beaconsdk.core.internal.storage.sharedpreferences.encryptedfile.CompatEncryptedFileManager
import it.airgap.beaconsdk.core.internal.storage.sharedpreferences.encryptedfile.EncryptedFileManager
import it.airgap.beaconsdk.core.internal.storage.sharedpreferences.encryptedfile.TargetEncryptedFileManager
import it.airgap.beaconsdk.core.internal.utils.sdkAtLeast
import it.airgap.beaconsdk.core.scope.BeaconScope
import it.airgap.beaconsdk.core.storage.SecureStorage
import java.security.KeyStore
import java.util.*

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Expand All @@ -36,33 +32,32 @@ public class SharedPreferencesSecureStorage(

override suspend fun setSdkSecretSeed(sdkSecretSeed: String) {
val keyAlias = masterKeyAlias ?: UUID.randomUUID().toString().also { masterKeyAlias = it }
encryptedFileManager.write(FileKey.SdkSecretKey.scoped(), keyAlias, sdkSecretSeed.encodeToByteArray())
encryptedFileManager.write(
FileKey.SdkSecretKey.scoped(),
keyAlias,
sdkSecretSeed.encodeToByteArray()
)
}

private enum class Key(override val value: String) : SharedPreferencesBaseStorage.Key {
MasterKeyAlias("masterKeyAlias"),
}

private enum class FileKey(override val value: String) : SharedPreferencesBaseStorage.Key {
SdkSecretKey("sdk_seed"),
SdkSecretKey("au_sdk_seed"),
}

override fun scoped(beaconScope: BeaconScope): SecureStorage =
if (beaconScope == this.beaconScope) this
else SharedPreferencesSecureStorage(sharedPreferences, encryptedFileManager, beaconScope)

public companion object {
internal const val ANDROID_KEY_STORE = "AndroidKeyStore"
}
}

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public fun SharedPreferencesSecureStorage(context: Context): SharedPreferencesSecureStorage {
val keyStore = KeyStore.getInstance(SharedPreferencesSecureStorage.ANDROID_KEY_STORE).apply { load(null) }
val sharedPreferences = context.getSharedPreferences(BeaconConfiguration.STORAGE_NAME, Context.MODE_PRIVATE)
val encryptedFileManager =
if (sdkAtLeast(Build.VERSION_CODES.M)) TargetEncryptedFileManager(context, keyStore)
else CompatEncryptedFileManager(context, keyStore)
val sharedPreferences =
context.getSharedPreferences(BeaconConfiguration.STORAGE_NAME, Context.MODE_PRIVATE)
val encryptedFileManager = TargetEncryptedFileManager(context)

return SharedPreferencesSecureStorage(sharedPreferences, encryptedFileManager)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import androidx.annotation.RequiresApi
import androidx.security.crypto.EncryptedFile
import androidx.security.crypto.MasterKey
import androidx.security.crypto.MasterKeys
import kotlinx.coroutines.*
import java.io.File
Expand All @@ -14,7 +15,7 @@ import java.security.GeneralSecurityException
import java.security.KeyStore

@RequiresApi(Build.VERSION_CODES.M)
internal class TargetEncryptedFileManager(private val context: Context, private val keyStore: KeyStore) : EncryptedFileManager {
internal class TargetEncryptedFileManager(private val context: Context) : EncryptedFileManager {

@Throws(GeneralSecurityException::class, IOException::class)
override suspend fun read(fileName: String, keyAlias: String): ByteArray? {
Expand All @@ -23,15 +24,7 @@ internal class TargetEncryptedFileManager(private val context: Context, private

return coroutineScope {
async(Dispatchers.IO) {
val masterKey = getOrCreateKey(keyAlias)
val encryptedFile = EncryptedFile.Builder(
file,
context,
masterKey,
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

encryptedFile.openFileInput().use { it.readBytes() }
file.readBytes()
}
}.await()
}
Expand All @@ -40,15 +33,7 @@ internal class TargetEncryptedFileManager(private val context: Context, private
override suspend fun write(fileName: String, keyAlias: String, data: ByteArray) {
coroutineScope {
launch(Dispatchers.IO) {
val masterKey = getOrCreateKey(keyAlias)
val encryptedFile = EncryptedFile.Builder(
file(fileName, keyAlias),
context,
masterKey,
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

encryptedFile.openFileOutput().use { it.write(data) }
file(fileName, keyAlias).writeBytes(data)
}
}
}
Expand All @@ -58,24 +43,7 @@ internal class TargetEncryptedFileManager(private val context: Context, private
deleteIfNoKey(keyAlias)
}

private fun getOrCreateKey(alias: String): String {
val parameterSpec = KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT).apply {
setKeySize(SIZE_KEY)
setDigests(KeyProperties.DIGEST_SHA512)
setUserAuthenticationRequired(false)
setRandomizedEncryptionRequired(true)
setBlockModes(KeyProperties.BLOCK_MODE_GCM)
setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
}.build()

return MasterKeys.getOrCreate(parameterSpec)
}

private fun File.deleteIfNoKey(alias: String): Boolean {
if (!keyStore.containsAlias(alias)) {
return delete()
}

return false
}

Expand Down
6 changes: 3 additions & 3 deletions demo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 32
compileSdkVersion 33
buildToolsVersion "29.0.3"

defaultConfig {
applicationId "it.airgap.beaconsdkdemo"
minSdkVersion 21
targetSdkVersion 32
minSdkVersion 28
targetSdkVersion 33
versionCode 1
versionName "1.0"

Expand Down