add persistency to pairings

This commit is contained in:
Michele Balistreri 2019-10-31 15:03:51 +03:00
parent 3928a035c7
commit 1bc42f4f59
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
5 changed files with 36 additions and 7 deletions

View File

@ -9,7 +9,7 @@ android {
buildToolsVersion "29.0.2" buildToolsVersion "29.0.2"
defaultConfig { defaultConfig {
applicationId "im.status.keycard.connect" applicationId "im.status.keycard.connect"
minSdkVersion 21 minSdkVersion 23
targetSdkVersion 29 targetSdkVersion 29
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
@ -45,6 +45,7 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0' implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0' implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'
implementation 'androidx.security:security-crypto:1.0.0-alpha02'
implementation 'org.bouncycastle:bcprov-jdk15on:1.64' implementation 'org.bouncycastle:bcprov-jdk15on:1.64'
implementation 'com.github.status-im.status-keycard-java:android:3.0.1' implementation 'com.github.status-im.status-keycard-java:android:3.0.1'
implementation "com.github.walletconnect:kotlin-walletconnect-lib:0.9.3" implementation "com.github.walletconnect:kotlin-walletconnect-lib:0.9.3"

View File

@ -8,6 +8,7 @@ import android.util.Base64
import android.view.View import android.view.View
import im.status.keycard.globalplatform.Crypto import im.status.keycard.globalplatform.Crypto
import android.util.Base64.NO_PADDING import android.util.Base64.NO_PADDING
import android.util.Base64.NO_WRAP
import android.widget.TextView import android.widget.TextView
@ -49,6 +50,6 @@ class InitActivity : AppCompatActivity() {
} }
fun randomToken(length: Int): String { fun randomToken(length: Int): String {
return Base64.encodeToString(Crypto.randomBytes(length), NO_PADDING) return Base64.encodeToString(Crypto.randomBytes(length), NO_PADDING or NO_WRAP)
} }
} }

View File

@ -11,6 +11,7 @@ import androidx.navigation.ui.setupWithNavController
import im.status.keycard.android.NFCCardManager import im.status.keycard.android.NFCCardManager
import android.content.Intent import android.content.Intent
import im.status.keycard.connect.card.* import im.status.keycard.connect.card.*
import im.status.keycard.connect.data.PairingManager
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private lateinit var cardManager: NFCCardManager private lateinit var cardManager: NFCCardManager
@ -26,6 +27,8 @@ class MainActivity : AppCompatActivity() {
val appBarConfiguration = AppBarConfiguration(setOf(R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)) val appBarConfiguration = AppBarConfiguration(setOf(R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications))
PairingManager.init(this)
nfcAdapter = NfcAdapter.getDefaultAdapter(this) nfcAdapter = NfcAdapter.getDefaultAdapter(this)
executor = CardScriptExecutor(this) executor = CardScriptExecutor(this)
executor.setScript(listOf(SelectCommand(), InitCommand(), OpenSecureChannelCommand(), VerifyPINCommand())) executor.setScript(listOf(SelectCommand(), InitCommand(), OpenSecureChannelCommand(), VerifyPINCommand()))

View File

@ -29,6 +29,8 @@ class OpenSecureChannelCommand : CardCommand {
PairingManager.putPairing(cmdSet.applicationInfo.instanceUID, cmdSet.pairing) PairingManager.putPairing(cmdSet.applicationInfo.instanceUID, cmdSet.pairing)
cmdSet.autoOpenSecureChannel() cmdSet.autoOpenSecureChannel()
return CommandResult.OK return CommandResult.OK
} catch(e: IOException) {
e.printStackTrace()
} finally { } finally {
pairingPassword = null pairingPassword = null
} }

View File

@ -1,21 +1,43 @@
package im.status.keycard.connect.data package im.status.keycard.connect.data
import android.content.Context
import android.content.SharedPreferences
import android.util.Base64
import android.util.Base64.NO_PADDING
import android.util.Base64.NO_WRAP
import im.status.keycard.applet.Pairing import im.status.keycard.applet.Pairing
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
object PairingManager { object PairingManager {
//TODO: persistency private lateinit var sharedPreferences: SharedPreferences
private val pairings: MutableMap<ByteArrayKey, Pairing> = HashMap() private fun id(instanceUID: ByteArray) : String {
return Base64.encodeToString(instanceUID, NO_PADDING or NO_WRAP)
}
fun init(context: Context) {
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
sharedPreferences = EncryptedSharedPreferences.create("pairings", masterKeyAlias, context, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM)
}
fun getPairing(instanceUID: ByteArray): Pairing? { fun getPairing(instanceUID: ByteArray): Pairing? {
return pairings[ByteArrayKey(instanceUID)] val p = sharedPreferences.getString(id(instanceUID), null)
return if (p != null) Pairing(p) else null
} }
fun putPairing(instanceUID: ByteArray, pairing: Pairing) { fun putPairing(instanceUID: ByteArray, pairing: Pairing) {
pairings[ByteArrayKey(instanceUID)] = pairing sharedPreferences.edit().apply {
putString(id(instanceUID), pairing.toBase64())
apply()
}
} }
fun removePairing(instanceUID: ByteArray) { fun removePairing(instanceUID: ByteArray) {
pairings.remove(ByteArrayKey(instanceUID)) sharedPreferences.edit().apply {
remove(id(instanceUID))
apply()
}
} }
} }