From eb468efb99bfd7dd326ad9cc40cf82e8a034f147 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 5 Feb 2020 19:07:31 +0300 Subject: [PATCH] Updated on 2026-08-14 --- tangem-core/build.gradle | 4 +- .../src/main/java/com/tangem/CardManager.kt | 42 +++++++++----- .../src/main/java/com/tangem/Config.kt | 5 ++ .../tangem/{ => common}/CardEnvironment.kt | 2 +- .../com/tangem/common/TerminalKeysService.kt | 12 ++++ .../com/tangem/tangemtest/MainActivity.kt | 3 +- tangem-sdk/build.gradle | 13 +++-- .../tangem_sdk_new/TerminalKeysStorage.kt | 56 +++++++++++++++++++ .../tangem/tangem_sdk_new/nfc/NfcManager.kt | 2 +- 9 files changed, 116 insertions(+), 23 deletions(-) create mode 100644 tangem-core/src/main/java/com/tangem/Config.kt rename tangem-core/src/main/java/com/tangem/{ => common}/CardEnvironment.kt (96%) create mode 100644 tangem-core/src/main/java/com/tangem/common/TerminalKeysService.kt create mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/TerminalKeysStorage.kt diff --git a/tangem-core/build.gradle b/tangem-core/build.gradle index e3cb3b5cba..9ac05921c0 100644 --- a/tangem-core/build.gradle +++ b/tangem-core/build.gradle @@ -7,8 +7,8 @@ version '0.1.0' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation "com.madgag.spongycastle:core:1.56.0.0" - implementation "com.madgag.spongycastle:prov:1.56.0.0" + implementation "com.madgag.spongycastle:core:1.58.0.0" + implementation "com.madgag.spongycastle:prov:1.58.0.0" implementation 'net.i2p.crypto:eddsa:0.3.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2' testImplementation "com.google.truth:truth:1.0" diff --git a/tangem-core/src/main/java/com/tangem/CardManager.kt b/tangem-core/src/main/java/com/tangem/CardManager.kt index e381f57e3d..dba3932cc3 100644 --- a/tangem-core/src/main/java/com/tangem/CardManager.kt +++ b/tangem-core/src/main/java/com/tangem/CardManager.kt @@ -1,6 +1,8 @@ package com.tangem import com.tangem.commands.* +import com.tangem.common.CardEnvironment +import com.tangem.common.TerminalKeysService import com.tangem.crypto.CryptoUtils import com.tangem.tasks.* import java.util.concurrent.Executors @@ -16,10 +18,12 @@ import java.util.concurrent.Executors */ class CardManager( private val reader: CardReader, - private val cardManagerDelegate: CardManagerDelegate? = null) { + private val cardManagerDelegate: CardManagerDelegate? = null, + private val config: Config = Config() +) { + private var terminalKeysService: TerminalKeysService? = null private var isBusy = false - private val cardEnvironmentRepository = mutableMapOf() private val cardManagerExecutor = Executors.newSingleThreadExecutor() init { @@ -67,7 +71,7 @@ class CardManager( callback: (result: TaskEvent) -> Unit) { val signCommand: SignCommand try { - signCommand = SignCommand(hashes, cardId) + signCommand = SignCommand(hashes) } catch (error: Exception) { if (error is TaskError) { callback(TaskEvent.Completion(error)) @@ -91,7 +95,7 @@ class CardManager( */ fun readIssuerData(cardId: String, callback: (result: TaskEvent) -> Unit) { - val getIssuerDataCommand = ReadIssuerDataCommand(cardId) + val getIssuerDataCommand = ReadIssuerDataCommand() val task = SingleCommandTask(getIssuerDataCommand) runTask(task, cardId, callback) } @@ -114,10 +118,10 @@ class CardManager( issuerDataCounter: Int? = null, callback: (result: TaskEvent) -> Unit) { val writeIssuerDataCommand = WriteIssuerDataCommand( - cardId, - issuerData, - issuerDataSignature, - issuerDataCounter) + issuerData, + issuerDataSignature, + issuerDataCounter + ) val task = SingleCommandTask(writeIssuerDataCommand) runTask(task, cardId, callback) } @@ -134,7 +138,7 @@ class CardManager( */ fun createWallet(cardId: String, callback: (result: TaskEvent) -> Unit) { - val createWalletCommand = CreateWalletCommand(cardId) + val createWalletCommand = CreateWalletCommand() val task = SingleCommandTask(createWalletCommand) runTask(task, cardId, callback) } @@ -148,7 +152,7 @@ class CardManager( */ fun purgeWallet(cardId: String, callback: (result: TaskEvent) -> Unit) { - val purgeWalletCommand = PurgeWalletCommand(cardId) + val purgeWalletCommand = PurgeWalletCommand() val task = SingleCommandTask(purgeWalletCommand) runTask(task, cardId, callback) } @@ -163,7 +167,7 @@ class CardManager( return } - val environment = fetchCardEnvironment(cardId) + val environment = prepareCardEnvironment(cardId) isBusy = true task.reader = reader @@ -187,7 +191,19 @@ class CardManager( runTask(task, cardId, callback) } - private fun fetchCardEnvironment(cardId: String?): CardEnvironment { - return cardEnvironmentRepository[cardId] ?: CardEnvironment(cardId = cardId) + /** + * Allows to set a particular [TerminalKeysService] to retrieve terminal keys. + * Default implementation is provided in tangem-sdk module: [TerminalKeysStorage]. + */ + fun setTerminalKeysService(terminalKeysService: TerminalKeysService) { + this.terminalKeysService = terminalKeysService + } + + private fun prepareCardEnvironment(cardId: String?): CardEnvironment { + val terminalKeys = if (config.linkedTerminal) terminalKeysService?.getKeys() else null + return CardEnvironment( + cardId = cardId, + terminalKeys = terminalKeys + ) } } \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/Config.kt b/tangem-core/src/main/java/com/tangem/Config.kt new file mode 100644 index 0000000000..7689e77697 --- /dev/null +++ b/tangem-core/src/main/java/com/tangem/Config.kt @@ -0,0 +1,5 @@ +package com.tangem + +data class Config( + val linkedTerminal: Boolean = true +) \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/CardEnvironment.kt b/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt similarity index 96% rename from tangem-core/src/main/java/com/tangem/CardEnvironment.kt rename to tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt index 39e077006e..21728a8c44 100644 --- a/tangem-core/src/main/java/com/tangem/CardEnvironment.kt +++ b/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt @@ -1,4 +1,4 @@ -package com.tangem +package com.tangem.common /** diff --git a/tangem-core/src/main/java/com/tangem/common/TerminalKeysService.kt b/tangem-core/src/main/java/com/tangem/common/TerminalKeysService.kt new file mode 100644 index 0000000000..d389c172b3 --- /dev/null +++ b/tangem-core/src/main/java/com/tangem/common/TerminalKeysService.kt @@ -0,0 +1,12 @@ +package com.tangem.common + +/** + * Interface for a service for managing Terminal keypair, used for Linked Terminal feature. + * Its implementation Needs to be provided to [com.tangem.CardManager] + * by calling [com.tangem.CardManager.setTerminalKeysService]. + * Default implementation is provided in tangem-sdk module: [TerminalKeysStorage]. + * Linked Terminal feature can be disabled manually by editing [com.tangem.Config]. + */ +interface TerminalKeysService { + fun getKeys(): KeyPair +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt index 11f067114f..581f5d7e09 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt @@ -16,7 +16,7 @@ class MainActivity : AppCompatActivity() { private val nfcManager = NfcManager() private val cardManagerDelegate: DefaultCardManagerDelegate = DefaultCardManagerDelegate(nfcManager.reader) - private val cardManager = CardManager(nfcManager.reader, cardManagerDelegate, TerminalKeysStorage()) + private val cardManager = CardManager(nfcManager.reader, cardManagerDelegate) private lateinit var cardId: String private lateinit var issuerData: ByteArray @@ -26,6 +26,7 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + cardManager.setTerminalKeysService(TerminalKeysStorage(application)) nfcManager.setCurrentActivity(this) cardManagerDelegate.activity = this diff --git a/tangem-sdk/build.gradle b/tangem-sdk/build.gradle index ca1b2e5123..f25dfed9f9 100644 --- a/tangem-sdk/build.gradle +++ b/tangem-sdk/build.gradle @@ -40,16 +40,19 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'com.google.android.material:material:1.1.0-beta01' + implementation 'com.google.android.material:material:1.1.0' implementation 'com.skyfishjy.ripplebackground:library:1.0.1' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.core:core-ktx:1.1.0' - implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' - implementation "androidx.lifecycle:lifecycle-runtime:2.1.0" - implementation "androidx.lifecycle:lifecycle-common-java8:2.1.0" + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" + implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0" + implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.61" + + implementation 'at.favre.lib:armadillo:0.9.0' + testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' - implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.50" } diff --git a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/TerminalKeysStorage.kt b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/TerminalKeysStorage.kt new file mode 100644 index 0000000000..70b2cfa431 --- /dev/null +++ b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/TerminalKeysStorage.kt @@ -0,0 +1,56 @@ +package com.tangem.tangem_sdk_new + +import android.app.Application +import android.content.SharedPreferences +import at.favre.lib.armadillo.Armadillo +import com.tangem.common.KeyPair +import com.tangem.common.TerminalKeysService +import com.tangem.common.extensions.hexToBytes +import com.tangem.common.extensions.toHexString +import com.tangem.crypto.CryptoUtils + + +/** + * Service for managing Terminal keypair, used for Linked Terminal feature. + * Needs to be provided to [com.tangem.CardManager] by calling [com.tangem.CardManager.setTerminalKeysService] + * Linked Terminal feature can be disabled manually by editing [com.tangem.Config]. + * @param applicationContext is required to retrieve an instance of [SharedPreferences] + */ +class TerminalKeysStorage(applicationContext: Application): TerminalKeysService { + + private val preferences: SharedPreferences by lazy { + Armadillo.create(applicationContext, PREFERENCES_KEY) + .encryptionFingerprint(applicationContext) + .build() + } + + /** + * Retrieves generated keys from encrypted shared preferences if the keys exist. + * Generates new and stores them in encrypted shared preferences otherwise + */ + override fun getKeys(): KeyPair { + val privateKey = preferences.getString(TERMINAL_PRIVATE_KEY, null)?.hexToBytes() + val publicKey = preferences.getString(TERMINAL_PUBLIC_KEY, null)?.hexToBytes() + return if (privateKey == null || publicKey == null) { + generateAndSaveKeys() + } else { + KeyPair(publicKey, privateKey) + } + } + + private fun generateAndSaveKeys(): KeyPair { + val privateKey = CryptoUtils.generateRandomBytes(32) + val publicKey = CryptoUtils.generatePublicKey(privateKey) + preferences.edit().putString(TERMINAL_PRIVATE_KEY, privateKey.toHexString()).apply() + preferences.edit().putString(TERMINAL_PUBLIC_KEY, publicKey.toHexString()).apply() + return KeyPair(publicKey, privateKey) + } + + + companion object { + const val PREFERENCES_KEY = "myPrefs" + const val TERMINAL_PRIVATE_KEY = "terminalPrivateKey" + const val TERMINAL_PUBLIC_KEY = "terminalPublicKey" + } + +} \ No newline at end of file diff --git a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcManager.kt b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcManager.kt index cdcb94c1c3..2052890f91 100644 --- a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcManager.kt +++ b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcManager.kt @@ -13,7 +13,7 @@ import android.os.Bundle import com.tangem.Log /** - * Helps use of NFC, leveraging Android NFC functionality. + * Helps use NFC, leveraging Android NFC functionality. * Launches [NfcAdapter], manages it with [Activity] lifecycle, * enables and disables Nfc Reading Mode, receives NFC [Tag]. */