From 5f7612ca57acc3d4d84ae5ef730b8aa62b138605 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 30 Mar 2020 20:09:57 +0300 Subject: [PATCH 1/8] Updated on 2026-08-14 --- .../src/main/java/com/tangem/CardManager.kt | 6 +-- .../personalization/PersonalizeCommand.kt | 15 +++--- .../personalization/util/CardIdCreator.kt | 49 +++++++++++++++++++ .../com/tangem/tangemtest/MainActivity.kt | 4 +- 4 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/util/CardIdCreator.kt diff --git a/tangem-core/src/main/java/com/tangem/CardManager.kt b/tangem-core/src/main/java/com/tangem/CardManager.kt index f5d064d4e9..fb97714bc6 100644 --- a/tangem-core/src/main/java/com/tangem/CardManager.kt +++ b/tangem-core/src/main/java/com/tangem/CardManager.kt @@ -262,14 +262,12 @@ class CardManager( * during personalization. * @param cardId this parameter will set up CID, Unique Tangem card ID. */ - fun personalize(config: CardConfig, - cardId: String, - callback: (result: TaskEvent) -> Unit) { + fun personalize(config: CardConfig, callback: (result: TaskEvent) -> Unit) { if (this.config.issuer == null) { callback(TaskEvent.Completion(TaskError.IssuerIsRequired())) return } - val personalizationCommand = PersonalizeCommand(config, cardId) + val personalizationCommand = PersonalizeCommand(config) val task = SingleCommandTask(personalizationCommand) task.performPreflightRead = false runTask(task, callback = callback) diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt index 6bcdd815a5..7e118ae9f0 100644 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt @@ -4,6 +4,7 @@ import com.tangem.commands.Card import com.tangem.commands.CardData import com.tangem.commands.CommandSerializer import com.tangem.commands.personalization.entities.Issuer +import com.tangem.commands.personalization.util.CardIdCreator import com.tangem.common.CardEnvironment import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction @@ -27,7 +28,7 @@ import com.tangem.tasks.TaskError * during personalization. * @param cardId this parameter will set up CID, Unique Tangem card ID. */ -class PersonalizeCommand(private val config: CardConfig, private val cardId: String) : CommandSerializer() { +class PersonalizeCommand(private val config: CardConfig) : CommandSerializer() { override fun serialize(cardEnvironment: CardEnvironment): CommandApdu { if (cardEnvironment.issuer == null || cardEnvironment.manufacturerKeyPair == null) { @@ -36,9 +37,8 @@ class PersonalizeCommand(private val config: CardConfig, private val cardId: Str return CommandApdu( Instruction.Personalize, serializePersonalizationData( - cardId, config, - cardEnvironment.issuer, cardEnvironment.manufacturerKeyPair.privateKey, - cardEnvironment.acquirerKeyPair?.publicKey), + config, cardEnvironment.issuer, + cardEnvironment.manufacturerKeyPair.privateKey, cardEnvironment.acquirerKeyPair?.publicKey), encryptionKey = devPersonalizationKey ) } @@ -99,13 +99,14 @@ class PersonalizeCommand(private val config: CardConfig, private val cardId: Str ) } - private fun serializePersonalizationData(cardId: String, config: CardConfig, - issuer: Issuer, manufacturerPrivateKey: ByteArray, + private fun serializePersonalizationData(config: CardConfig, issuer: Issuer, + manufacturerPrivateKey: ByteArray, acquirePublicKey: ByteArray? ): ByteArray { + val cardId = CardIdCreator.create(config.series, config.startNumber) + ?: throw TaskError.SerializeCommandError() val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.CardId, cardId) - tlvBuilder.append(TlvTag.CurveId, config.curveID) tlvBuilder.append(TlvTag.MaxSignatures, config.maxSignatures) tlvBuilder.append(TlvTag.SigningMethod, config.signingMethod) diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/util/CardIdCreator.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/util/CardIdCreator.kt new file mode 100644 index 0000000000..a95e6f9cfc --- /dev/null +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/util/CardIdCreator.kt @@ -0,0 +1,49 @@ +package com.tangem.commands.personalization.util + +/** +[REDACTED_AUTHOR] + */ +internal class CardIdCreator { + + companion object { + private val Alf = "ABCDEF0123456789" + + fun create(nsSeries: String?, number: Long): String? { + val series = nsSeries ?: return null + if (number <= 0 || (series.length != 2 && series.length != 4)) return null + if (!checkSeries(series)) return null + + val tail = if (series.length == 2) String.format("%013d", number) else String.format("%011d", number) + val cardId = series + tail + return completeCardID(cardId) + } + + private fun checkSeries(series: String): Boolean { + val containsList = series.filter { Alf.contains(it) } + return containsList.length == series.length + } + + private fun completeCardID(imCardId: String): String? { + var cardId = imCardId + cardId = cardId.replace(" ", "") + if (cardId.length != 15 || Alf.indexOf(cardId[0]) == -1 || Alf.indexOf(cardId[1]) == -1) + return null + + cardId += "0" + val length = cardId.length + var sum = 0 + for (i in 0 until length) { + // get digits in reverse order + var digit: Int + val cDigit = cardId[length - i - 1] + digit = if (cDigit in '0'..'9') cDigit - '0' else cDigit - 'A' + + // every 2nd number multiply with 2 + if (i % 2 == 1) digit *= 2 + sum += if (digit > 9) digit - 9 else digit + } + val lunh = (10 - sum % 10) % 10 + return cardId.substring(0, 15) + String.format("%d", lunh) + } + } +} \ 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 1a294a8897..402ef369db 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt @@ -154,9 +154,7 @@ class MainActivity : AppCompatActivity() { } btn_read_write_user_data?.setOnClickListener { startActivity(Intent(this, TestUserDataActivity::class.java)) } btn_personalize?.setOnClickListener { _ -> - cardManager.personalize( - CardConfig.init(application), "BB00000000000395" - ) { + cardManager.personalize(CardConfig.init(application)) { when (it) { is TaskEvent.Completion -> { if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } From 3c80122b6edc184d54d94cb796240d6b2f88a594 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 31 Mar 2020 12:30:59 +0300 Subject: [PATCH 2/8] Updated on 2026-08-14 --- .../src/main/java/com/tangem/CardManager.kt | 7 ------ .../personalization/PersonalizeCommand.kt | 1 - .../com/tangem/tangemtest/MainActivity.kt | 24 ------------------- 3 files changed, 32 deletions(-) diff --git a/tangem-core/src/main/java/com/tangem/CardManager.kt b/tangem-core/src/main/java/com/tangem/CardManager.kt index 68f75476d5..bc3abf024f 100644 --- a/tangem-core/src/main/java/com/tangem/CardManager.kt +++ b/tangem-core/src/main/java/com/tangem/CardManager.kt @@ -263,18 +263,11 @@ class CardManager( * During this procedure all data exchange is encrypted. * @param config is a configuration file with all the card settings that are written on the card * during personalization. - * @param cardId this parameter will set up CID, Unique Tangem card ID. * @param issuer Issuer is a third-party team or company wishing to use Tangem cards. * @param manufacturer Tangem Card Manufacturer. * @param acquirer Acquirer is a trusted third-party company that operates proprietary * (non-EMV) POS terminal infrastructure and transaction processing back-end. */ - fun personalize(config: CardConfig, callback: (result: TaskEvent) -> Unit) { - if (this.config.issuer == null) { - callback(TaskEvent.Completion(TaskError.IssuerIsRequired())) - return - } - val personalizationCommand = PersonalizeCommand(config) fun personalize(config: CardConfig, issuer: Issuer, manufacturer: Manufacturer, acquirer: Acquirer? = null, callback: (result: TaskEvent) -> Unit) { diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt index 1e91cdddd6..eedcced227 100644 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt @@ -6,7 +6,6 @@ import com.tangem.commands.CommandSerializer import com.tangem.commands.personalization.entities.Acquirer import com.tangem.commands.personalization.entities.Issuer import com.tangem.commands.personalization.entities.Manufacturer -import com.tangem.commands.personalization.entities.Manufacturer import com.tangem.commands.personalization.util.CardIdCreator import com.tangem.common.CardEnvironment import com.tangem.common.apdu.CommandApdu 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 402ef369db..01207d703d 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt @@ -4,9 +4,7 @@ import android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.tangem.CardManager -import com.tangem.commands.personalization.CardConfig import com.tangem.tangem_sdk_new.extensions.init -import com.tangem.tangemtest.extensions.init import com.tangem.tasks.ScanEvent import com.tangem.tasks.TaskError import com.tangem.tasks.TaskEvent @@ -153,28 +151,6 @@ class MainActivity : AppCompatActivity() { } } btn_read_write_user_data?.setOnClickListener { startActivity(Intent(this, TestUserDataActivity::class.java)) } - btn_personalize?.setOnClickListener { _ -> - cardManager.personalize(CardConfig.init(application)) { - when (it) { - is TaskEvent.Completion -> { - if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } - } - is TaskEvent.Event -> runOnUiThread { tv_card_cid?.text = it.data.cardId } - } - } - } - btn_depersonalize?.setOnClickListener { _ -> - cardManager.depersonalize(cardId) { - when (it) { - is TaskEvent.Completion -> { - if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } - } - is TaskEvent.Event -> runOnUiThread { - tv_card_cid?.text = "Depersonalized: ${it.data.success.toString()}" - } - } - } - } } private fun createSampleHashes(): Array { From 0b9d306c9ef5edfa797f361d9b9996815b6b7056 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 31 Mar 2020 16:00:40 +0300 Subject: [PATCH 3/8] Updated on 2026-08-14 --- .../src/main/java/com/tangem/CardManager.kt | 2 +- .../commands/personalization/CardConfig.kt | 112 ----------------- .../commands/personalization/NdefEncoder.kt | 1 + .../personalization/PersonalizeCommand.kt | 44 +------ .../personalization/entities/CardConfig.kt | 70 +++++++++++ .../entities/CardConfigExtensions.kt | 113 ++++++++++++++++++ .../personalization/util/CardIdCreator.kt | 49 -------- .../tangemtest/extensions/CardConfig.kt | 4 +- 8 files changed, 193 insertions(+), 202 deletions(-) delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/CardConfig.kt create mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfig.kt create mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/util/CardIdCreator.kt diff --git a/tangem-core/src/main/java/com/tangem/CardManager.kt b/tangem-core/src/main/java/com/tangem/CardManager.kt index bc3abf024f..c5a1f99e77 100644 --- a/tangem-core/src/main/java/com/tangem/CardManager.kt +++ b/tangem-core/src/main/java/com/tangem/CardManager.kt @@ -1,11 +1,11 @@ package com.tangem import com.tangem.commands.* -import com.tangem.commands.personalization.CardConfig import com.tangem.commands.personalization.DepersonalizeCommand import com.tangem.commands.personalization.DepersonalizeResponse import com.tangem.commands.personalization.PersonalizeCommand import com.tangem.commands.personalization.entities.Acquirer +import com.tangem.commands.personalization.entities.CardConfig import com.tangem.commands.personalization.entities.Issuer import com.tangem.commands.personalization.entities.Manufacturer import com.tangem.common.CardEnvironment diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/CardConfig.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/CardConfig.kt deleted file mode 100644 index 15548f9871..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/CardConfig.kt +++ /dev/null @@ -1,112 +0,0 @@ -package com.tangem.commands.personalization - -import com.tangem.commands.* - -data class NdefRecord( - val type: Type, - val value: String -) { - enum class Type { - URI, AAR, TEXT - } - - val valueInBytes: ByteArray by lazy { value.toByteArray() } -} - -/** - * It is a configuration file with all the card settings that are written on the card - * during [PersonalizeCommand]. - */ -data class CardConfig( - val issuerName: String? = null, - val acquirerName: String? = null, - val series: String? = null, - val startNumber: Long = 0, - val count: Int = 0, - val pin: String, - val pin2: String, - val pin3: String, - val hexCrExKey: String?, - val cvc: String, - val pauseBeforePin2: Int, - val smartSecurityDelay: Boolean, - val curveID: EllipticCurve, - val signingMethod: SigningMethod, - val maxSignatures: Int, - val isReusable: Boolean, - val allowSwapPin: Boolean, - val allowSwapPin2: Boolean, - val useActivation: Boolean, - val useCvc: Boolean, - val useNdef: Boolean, - val useDynamicNdef: Boolean, - val useOneCommandAtTime: Boolean, - val useBlock: Boolean, - val allowSelectBlockchain: Boolean, - val forbidPurgeWallet: Boolean, - val protocolAllowUnencrypted: Boolean, - val protocolAllowStaticEncryption: Boolean, - val protectIssuerDataAgainstReplay: Boolean, - val forbidDefaultPin: Boolean, - val disablePrecomputedNdef: Boolean, - val skipSecurityDelayIfValidatedByIssuer: Boolean, - val skipCheckPIN2andCVCIfValidatedByIssuer: Boolean, - val skipSecurityDelayIfValidatedByLinkedTerminal: Boolean, - - val restrictOverwriteIssuerDataEx: Boolean, - - val requireTerminalTxSignature: Boolean, - val requireTerminalCertSignature: Boolean, - val checkPin3onCard: Boolean, - - val createWallet: Boolean, - - val cardData: CardData, - val ndefRecords: List -) { - - fun getSettingsMask(): SettingsMask { - val builder = SettingsMaskBuilder() - - if (allowSwapPin) builder.add(Settings.AllowSwapPIN) - if (allowSwapPin2) builder.add(Settings.AllowSwapPIN2) - if (useCvc) builder.add(Settings.UseCVC) - if (isReusable) builder.add(Settings.IsReusable) - - if (useOneCommandAtTime) builder.add(Settings.UseOneCommandAtTime) - if (useNdef) builder.add(Settings.UseNdef) - if (useDynamicNdef) builder.add(Settings.UseDynamicNdef) - if (disablePrecomputedNdef) builder.add(Settings.DisablePrecomputedNdef) - - if (protocolAllowUnencrypted) builder.add(Settings.ProtocolAllowUnencrypted) - if (protocolAllowStaticEncryption) builder.add(Settings.ProtocolAllowStaticEncryption) - - if (forbidDefaultPin) builder.add(Settings.ForbidDefaultPIN) - - if (useActivation) builder.add(Settings.UseActivation) - - if (useBlock) builder.add(Settings.UseBlock) - if (smartSecurityDelay) builder.add(Settings.SmartSecurityDelay) - - if (protectIssuerDataAgainstReplay) builder.add(Settings.ProtectIssuerDataAgainstReplay) - - if (forbidPurgeWallet) builder.add(Settings.ForbidPurgeWallet) - if (allowSelectBlockchain) builder.add(Settings.AllowSelectBlockchain) - - if (skipCheckPIN2andCVCIfValidatedByIssuer) builder.add(Settings.SkipCheckPin2andCvcIfValidatedByIssuer) - if (skipSecurityDelayIfValidatedByIssuer) builder.add(Settings.SkipSecurityDelayIfValidatedByIssuer) - - if (skipSecurityDelayIfValidatedByLinkedTerminal) builder.add(Settings.SkipSecurityDelayIfValidatedByLinkedTerminal) - if (restrictOverwriteIssuerDataEx) builder.add(Settings.RestrictOverwriteIssuerDataEx) - - if (requireTerminalTxSignature) builder.add(Settings.RequireTermTxSignature) - - if (requireTerminalCertSignature) builder.add(Settings.RequireTermCertSignature) - - if (checkPin3onCard) builder.add(Settings.CheckPIN3onCard) - - return builder.build() - } - - companion object -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/NdefEncoder.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/NdefEncoder.kt index a034d171cb..6c6103556e 100644 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/NdefEncoder.kt +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/NdefEncoder.kt @@ -1,5 +1,6 @@ package com.tangem.commands.personalization +import com.tangem.commands.personalization.entities.NdefRecord import java.io.ByteArrayOutputStream import java.nio.charset.StandardCharsets diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt index eedcced227..a0ec909e12 100644 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt @@ -3,21 +3,16 @@ package com.tangem.commands.personalization import com.tangem.commands.Card import com.tangem.commands.CardData import com.tangem.commands.CommandSerializer -import com.tangem.commands.personalization.entities.Acquirer -import com.tangem.commands.personalization.entities.Issuer -import com.tangem.commands.personalization.entities.Manufacturer -import com.tangem.commands.personalization.util.CardIdCreator +import com.tangem.commands.personalization.entities.* import com.tangem.common.CardEnvironment import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu import com.tangem.common.extensions.calculateSha256 -import com.tangem.common.extensions.hexToBytes import com.tangem.common.tlv.Tlv import com.tangem.common.tlv.TlvBuilder import com.tangem.common.tlv.TlvMapper import com.tangem.common.tlv.TlvTag -import com.tangem.crypto.sign import com.tangem.tasks.TaskError /** @@ -104,18 +99,18 @@ class PersonalizeCommand( } private fun serializePersonalizationData(config: CardConfig): ByteArray { - val cardId = CardIdCreator.create(config.series, config.startNumber) - ?: throw TaskError.SerializeCommandError() + val cardId = config.createCardId() ?: throw TaskError.SerializeCommandError() val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.CardId, cardId) tlvBuilder.append(TlvTag.CurveId, config.curveID) tlvBuilder.append(TlvTag.MaxSignatures, config.maxSignatures) tlvBuilder.append(TlvTag.SigningMethod, config.signingMethod) - tlvBuilder.append(TlvTag.SettingsMask, config.getSettingsMask()) + tlvBuilder.append(TlvTag.SettingsMask, config.createSettingsMask()) tlvBuilder.append(TlvTag.PauseBeforePin2, config.pauseBeforePin2 / 10) tlvBuilder.append(TlvTag.Cvc, config.cvc.toByteArray()) - if (!config.ndefRecords.isNullOrEmpty()) tlvBuilder.append(TlvTag.NdefData, serializeNdef(config.ndefRecords)) + if (!config.ndefRecords.isNullOrEmpty()) + tlvBuilder.append(TlvTag.NdefData, config.serializeNdef(config.ndefRecords)) tlvBuilder.append(TlvTag.CreateWalletAtPersonalize, config.createWallet) @@ -128,37 +123,10 @@ class PersonalizeCommand( tlvBuilder.append(TlvTag.AcquirerPublicKey, acquirer?.keyPair?.publicKey) - tlvBuilder.append(TlvTag.CardData, serializeCardData(cardId, config.cardData)) + tlvBuilder.append(TlvTag.CardData, config.serializeCardData(cardId, issuer, manufacturer)) return tlvBuilder.serialize() } - private fun serializeCardData(cardId: String, cardData: CardData): ByteArray { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Batch, cardData.batchId) - tlvBuilder.append(TlvTag.ProductMask, cardData.productMask) - - tlvBuilder.append(TlvTag.ManufactureDateTime, cardData.manufactureDateTime) - - tlvBuilder.append(TlvTag.IssuerId, issuer.id) - - tlvBuilder.append(TlvTag.BlockchainId, cardData.blockchainName) - - if (cardData.tokenSymbol != null) { - tlvBuilder.append(TlvTag.TokenSymbol, cardData.tokenSymbol) - tlvBuilder.append(TlvTag.TokenContractAddress, cardData.tokenContractAddress) - tlvBuilder.append(TlvTag.TokenDecimal, cardData.tokenDecimal) - } - tlvBuilder.append( - TlvTag.CardIdManufacturerSignature, - cardId.hexToBytes().sign(manufacturer.keyPair.privateKey) - ) - return tlvBuilder.serialize() - } - - private fun serializeNdef(ndefRecords: List): ByteArray { - return NdefEncoder(ndefRecords, config.useDynamicNdef).encode() - } - companion object { val devPersonalizationKey = "1234".calculateSha256().copyOf(32) } diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfig.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfig.kt new file mode 100644 index 0000000000..bc1a082237 --- /dev/null +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfig.kt @@ -0,0 +1,70 @@ +package com.tangem.commands.personalization.entities + +import com.tangem.commands.CardData +import com.tangem.commands.EllipticCurve +import com.tangem.commands.SigningMethod + +data class NdefRecord( + val type: Type, + val value: String +) { + enum class Type { + URI, AAR, TEXT + } + + val valueInBytes: ByteArray by lazy { value.toByteArray() } +} + +/** + * It is a configuration file with all the card settings that are written on the card + * during [PersonalizeCommand]. + */ +data class CardConfig( + val issuerName: String? = null, + val acquirerName: String? = null, + val series: String? = null, + val startNumber: Long = 0, + val count: Int = 0, + val pin: String, + val pin2: String, + val pin3: String, + val hexCrExKey: String?, + val cvc: String, + val pauseBeforePin2: Int, + val smartSecurityDelay: Boolean, + val curveID: EllipticCurve, + val signingMethod: SigningMethod, + val maxSignatures: Int, + val isReusable: Boolean, + val allowSwapPin: Boolean, + val allowSwapPin2: Boolean, + val useActivation: Boolean, + val useCvc: Boolean, + val useNdef: Boolean, + val useDynamicNdef: Boolean, + val useOneCommandAtTime: Boolean, + val useBlock: Boolean, + val allowSelectBlockchain: Boolean, + val forbidPurgeWallet: Boolean, + val protocolAllowUnencrypted: Boolean, + val protocolAllowStaticEncryption: Boolean, + val protectIssuerDataAgainstReplay: Boolean, + val forbidDefaultPin: Boolean, + val disablePrecomputedNdef: Boolean, + val skipSecurityDelayIfValidatedByIssuer: Boolean, + val skipCheckPIN2andCVCIfValidatedByIssuer: Boolean, + val skipSecurityDelayIfValidatedByLinkedTerminal: Boolean, + + val restrictOverwriteIssuerDataEx: Boolean, + + val requireTerminalTxSignature: Boolean, + val requireTerminalCertSignature: Boolean, + val checkPin3onCard: Boolean, + + val createWallet: Boolean, + + val cardData: CardData, + val ndefRecords: List +) { + companion object +} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt new file mode 100644 index 0000000000..5deb6fa048 --- /dev/null +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt @@ -0,0 +1,113 @@ +package com.tangem.commands.personalization.entities + +import com.tangem.commands.Settings +import com.tangem.commands.SettingsMask +import com.tangem.commands.SettingsMaskBuilder +import com.tangem.commands.personalization.NdefEncoder +import com.tangem.common.extensions.hexToBytes +import com.tangem.common.tlv.TlvBuilder +import com.tangem.common.tlv.TlvTag +import com.tangem.crypto.sign + +/** +[REDACTED_AUTHOR] + */ +internal fun CardConfig.createSettingsMask(): SettingsMask { + val builder = SettingsMaskBuilder() + + if (allowSwapPin) builder.add(Settings.AllowSwapPIN) + if (allowSwapPin2) builder.add(Settings.AllowSwapPIN2) + if (useCvc) builder.add(Settings.UseCVC) + if (isReusable) builder.add(Settings.IsReusable) + + if (useOneCommandAtTime) builder.add(Settings.UseOneCommandAtTime) + if (useNdef) builder.add(Settings.UseNdef) + if (useDynamicNdef) builder.add(Settings.UseDynamicNdef) + if (disablePrecomputedNdef) builder.add(Settings.DisablePrecomputedNdef) + + if (protocolAllowUnencrypted) builder.add(Settings.ProtocolAllowUnencrypted) + if (protocolAllowStaticEncryption) builder.add(Settings.ProtocolAllowStaticEncryption) + + if (forbidDefaultPin) builder.add(Settings.ForbidDefaultPIN) + + if (useActivation) builder.add(Settings.UseActivation) + + if (useBlock) builder.add(Settings.UseBlock) + if (smartSecurityDelay) builder.add(Settings.SmartSecurityDelay) + + if (protectIssuerDataAgainstReplay) builder.add(Settings.ProtectIssuerDataAgainstReplay) + + if (forbidPurgeWallet) builder.add(Settings.ForbidPurgeWallet) + if (allowSelectBlockchain) builder.add(Settings.AllowSelectBlockchain) + + if (skipCheckPIN2andCVCIfValidatedByIssuer) builder.add(Settings.SkipCheckPin2andCvcIfValidatedByIssuer) + if (skipSecurityDelayIfValidatedByIssuer) builder.add(Settings.SkipSecurityDelayIfValidatedByIssuer) + + if (skipSecurityDelayIfValidatedByLinkedTerminal) builder.add(Settings.SkipSecurityDelayIfValidatedByLinkedTerminal) + if (restrictOverwriteIssuerDataEx) builder.add(Settings.RestrictOverwriteIssuerDataEx) + + if (requireTerminalTxSignature) builder.add(Settings.RequireTermTxSignature) + + if (requireTerminalCertSignature) builder.add(Settings.RequireTermCertSignature) + + if (checkPin3onCard) builder.add(Settings.CheckPIN3onCard) + + return builder.build() +} + +internal fun CardConfig.createCardId(): String? { + if (series == null) return null + if (startNumber <= 0 || (series.length != 2 && series.length != 4)) return null + + val Alf = "ABCDEF0123456789" + fun checkSeries(series: String): Boolean { + val containsList = series.filter { Alf.contains(it) } + return containsList.length == series.length + } + if (!checkSeries(series)) return null + + val tail = if (series.length == 2) String.format("%013d", startNumber) else String.format("%011d", startNumber) + var cardId = (series + tail).replace(" ", "") + if (cardId.length != 15 || Alf.indexOf(cardId[0]) == -1 || Alf.indexOf(cardId[1]) == -1) + return null + + cardId += "0" + val length = cardId.length + var sum = 0 + for (i in 0 until length) { + // get digits in reverse order + var digit: Int + val cDigit = cardId[length - i - 1] + digit = if (cDigit in '0'..'9') cDigit - '0' else cDigit - 'A' + + // every 2nd number multiply with 2 + if (i % 2 == 1) digit *= 2 + sum += if (digit > 9) digit - 9 else digit + } + val lunh = (10 - sum % 10) % 10 + return cardId.substring(0, 15) + String.format("%d", lunh) +} + +internal fun CardConfig.serializeNdef(ndefRecords: List): ByteArray { + return NdefEncoder(ndefRecords, useDynamicNdef).encode() +} + +internal fun CardConfig.serializeCardData(cardId: String, issuer: Issuer, manufacturer: Manufacturer): ByteArray { + val tlvBuilder = TlvBuilder() + tlvBuilder.append(TlvTag.Batch, cardData.batchId) + tlvBuilder.append(TlvTag.ProductMask, cardData.productMask) + tlvBuilder.append(TlvTag.ManufactureDateTime, cardData.manufactureDateTime) + tlvBuilder.append(TlvTag.IssuerId, issuer.id) + tlvBuilder.append(TlvTag.BlockchainId, cardData.blockchainName) + + if (cardData.tokenSymbol != null) { + tlvBuilder.append(TlvTag.TokenSymbol, cardData.tokenSymbol) + tlvBuilder.append(TlvTag.TokenContractAddress, cardData.tokenContractAddress) + tlvBuilder.append(TlvTag.TokenDecimal, cardData.tokenDecimal) + } + tlvBuilder.append( + TlvTag.CardIdManufacturerSignature, + cardId.hexToBytes().sign(manufacturer.keyPair.privateKey) + ) + return tlvBuilder.serialize() +} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/util/CardIdCreator.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/util/CardIdCreator.kt deleted file mode 100644 index a95e6f9cfc..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/util/CardIdCreator.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.tangem.commands.personalization.util - -/** -[REDACTED_AUTHOR] - */ -internal class CardIdCreator { - - companion object { - private val Alf = "ABCDEF0123456789" - - fun create(nsSeries: String?, number: Long): String? { - val series = nsSeries ?: return null - if (number <= 0 || (series.length != 2 && series.length != 4)) return null - if (!checkSeries(series)) return null - - val tail = if (series.length == 2) String.format("%013d", number) else String.format("%011d", number) - val cardId = series + tail - return completeCardID(cardId) - } - - private fun checkSeries(series: String): Boolean { - val containsList = series.filter { Alf.contains(it) } - return containsList.length == series.length - } - - private fun completeCardID(imCardId: String): String? { - var cardId = imCardId - cardId = cardId.replace(" ", "") - if (cardId.length != 15 || Alf.indexOf(cardId[0]) == -1 || Alf.indexOf(cardId[1]) == -1) - return null - - cardId += "0" - val length = cardId.length - var sum = 0 - for (i in 0 until length) { - // get digits in reverse order - var digit: Int - val cDigit = cardId[length - i - 1] - digit = if (cDigit in '0'..'9') cDigit - '0' else cDigit - 'A' - - // every 2nd number multiply with 2 - if (i % 2 == 1) digit *= 2 - sum += if (digit > 9) digit - 9 else digit - } - val lunh = (10 - sum % 10) % 10 - return cardId.substring(0, 15) + String.format("%d", lunh) - } - } -} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/extensions/CardConfig.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/extensions/CardConfig.kt index 5412ab7c15..0ef2666e1d 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/extensions/CardConfig.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/extensions/CardConfig.kt @@ -3,8 +3,8 @@ package com.tangem.tangemtest.extensions import android.app.Application import android.content.Context import com.tangem.commands.* -import com.tangem.commands.personalization.CardConfig -import com.tangem.commands.personalization.NdefRecord +import com.tangem.commands.personalization.entities.CardConfig +import com.tangem.commands.personalization.entities.NdefRecord import java.util.* fun CardConfig.Companion.init(application: Application): CardConfig { From 8eabf7de691921e99e7b90311503681838473504 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 31 Mar 2020 17:37:34 +0300 Subject: [PATCH 4/8] Updated on 2026-08-14 --- .../personalization/PersonalizeCommand.kt | 30 +++++++++++++++-- .../entities/CardConfigExtensions.kt | 32 ------------------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt index a0ec909e12..035963c21a 100644 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt @@ -9,10 +9,12 @@ import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu import com.tangem.common.extensions.calculateSha256 +import com.tangem.common.extensions.hexToBytes import com.tangem.common.tlv.Tlv import com.tangem.common.tlv.TlvBuilder import com.tangem.common.tlv.TlvMapper import com.tangem.common.tlv.TlvTag +import com.tangem.crypto.sign import com.tangem.tasks.TaskError /** @@ -110,7 +112,7 @@ class PersonalizeCommand( tlvBuilder.append(TlvTag.PauseBeforePin2, config.pauseBeforePin2 / 10) tlvBuilder.append(TlvTag.Cvc, config.cvc.toByteArray()) if (!config.ndefRecords.isNullOrEmpty()) - tlvBuilder.append(TlvTag.NdefData, config.serializeNdef(config.ndefRecords)) + tlvBuilder.append(TlvTag.NdefData, serializeNdef(config)) tlvBuilder.append(TlvTag.CreateWalletAtPersonalize, config.createWallet) @@ -123,7 +125,31 @@ class PersonalizeCommand( tlvBuilder.append(TlvTag.AcquirerPublicKey, acquirer?.keyPair?.publicKey) - tlvBuilder.append(TlvTag.CardData, config.serializeCardData(cardId, issuer, manufacturer)) + tlvBuilder.append(TlvTag.CardData, serializeCardData(cardId, config.cardData)) + return tlvBuilder.serialize() + } + + private fun serializeNdef(config: CardConfig): ByteArray { + return NdefEncoder(config.ndefRecords, config.useDynamicNdef).encode() + } + + private fun serializeCardData(cardId: String, cardData: CardData): ByteArray { + val tlvBuilder = TlvBuilder() + tlvBuilder.append(TlvTag.Batch, cardData.batchId) + tlvBuilder.append(TlvTag.ProductMask, cardData.productMask) + tlvBuilder.append(TlvTag.ManufactureDateTime, cardData.manufactureDateTime) + tlvBuilder.append(TlvTag.IssuerId, issuer.id) + tlvBuilder.append(TlvTag.BlockchainId, cardData.blockchainName) + + if (cardData.tokenSymbol != null) { + tlvBuilder.append(TlvTag.TokenSymbol, cardData.tokenSymbol) + tlvBuilder.append(TlvTag.TokenContractAddress, cardData.tokenContractAddress) + tlvBuilder.append(TlvTag.TokenDecimal, cardData.tokenDecimal) + } + tlvBuilder.append( + TlvTag.CardIdManufacturerSignature, + cardId.hexToBytes().sign(manufacturer.keyPair.privateKey) + ) return tlvBuilder.serialize() } diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt index 5deb6fa048..4d7895f3c4 100644 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt @@ -3,15 +3,7 @@ package com.tangem.commands.personalization.entities import com.tangem.commands.Settings import com.tangem.commands.SettingsMask import com.tangem.commands.SettingsMaskBuilder -import com.tangem.commands.personalization.NdefEncoder -import com.tangem.common.extensions.hexToBytes -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvTag -import com.tangem.crypto.sign -/** -[REDACTED_AUTHOR] - */ internal fun CardConfig.createSettingsMask(): SettingsMask { val builder = SettingsMaskBuilder() @@ -86,28 +78,4 @@ internal fun CardConfig.createCardId(): String? { } val lunh = (10 - sum % 10) % 10 return cardId.substring(0, 15) + String.format("%d", lunh) -} - -internal fun CardConfig.serializeNdef(ndefRecords: List): ByteArray { - return NdefEncoder(ndefRecords, useDynamicNdef).encode() -} - -internal fun CardConfig.serializeCardData(cardId: String, issuer: Issuer, manufacturer: Manufacturer): ByteArray { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Batch, cardData.batchId) - tlvBuilder.append(TlvTag.ProductMask, cardData.productMask) - tlvBuilder.append(TlvTag.ManufactureDateTime, cardData.manufactureDateTime) - tlvBuilder.append(TlvTag.IssuerId, issuer.id) - tlvBuilder.append(TlvTag.BlockchainId, cardData.blockchainName) - - if (cardData.tokenSymbol != null) { - tlvBuilder.append(TlvTag.TokenSymbol, cardData.tokenSymbol) - tlvBuilder.append(TlvTag.TokenContractAddress, cardData.tokenContractAddress) - tlvBuilder.append(TlvTag.TokenDecimal, cardData.tokenDecimal) - } - tlvBuilder.append( - TlvTag.CardIdManufacturerSignature, - cardId.hexToBytes().sign(manufacturer.keyPair.privateKey) - ) - return tlvBuilder.serialize() } \ No newline at end of file From 1a373382b0abdbf02242c3f952335440d0e8200b Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 31 Mar 2020 17:41:25 +0300 Subject: [PATCH 5/8] Updated on 2026-08-14 --- .idea/codeStyles/codeStyleConfig.xml | 1 + .../src/main/java/com/tangem/commands/ReadUserDataCommand.kt | 3 --- .../src/main/java/com/tangem/commands/WriteUserDataCommand.kt | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml index a55e7a179b..6e6eec1148 100644 --- a/.idea/codeStyles/codeStyleConfig.xml +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -1,5 +1,6 @@ + \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt index ba5954fe01..656c1750f0 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt @@ -9,9 +9,6 @@ import com.tangem.common.tlv.TlvMapper import com.tangem.common.tlv.TlvTag import com.tangem.tasks.TaskError -/** -[REDACTED_AUTHOR] - */ class ReadUserDataResponse( /** * CID, Unique Tangem card ID number. diff --git a/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt index 804abf6601..ac79cba45c 100644 --- a/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt @@ -9,10 +9,6 @@ import com.tangem.common.tlv.TlvMapper import com.tangem.common.tlv.TlvTag import com.tangem.tasks.TaskError -/** -[REDACTED_AUTHOR] - */ - class WriteUserDataResponse( /** * CID, Unique Tangem card ID number. From bc05ddd7ba8827ca9738dc0a42fe8bc49193e524 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 31 Mar 2020 17:42:06 +0300 Subject: [PATCH 6/8] Updated on 2026-08-14 --- .idea/codeStyles/codeStyleConfig.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml index 6e6eec1148..a55e7a179b 100644 --- a/.idea/codeStyles/codeStyleConfig.xml +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -1,6 +1,5 @@ - \ No newline at end of file From 7079824bd6d8cfcdc648f56c39e29577b82743f0 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 1 Apr 2020 08:39:21 +0300 Subject: [PATCH 7/8] Updated on 2026-08-14 --- .../main/java/com/tangem/ui/fragment/VerifyCardFragment.kt | 5 +++++ .../main/java/com/tangem/tangem_card/data/TangemCard.java | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt b/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt index 421f780cc1..a5b287d6ed 100644 --- a/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt @@ -69,6 +69,11 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter. super.onViewCreated(view, savedInstanceState) updateViews() + val card = ctx.card + if (!card.allowSwapPIN() && !card.allowSwapPIN2() && card.forbidPurgeWallet()) { + fabMenu.hide() + } + // set listeners fabMenu.setOnClickListener { showMenu(fabMenu) } diff --git a/tangem-card-old/src/main/java/com/tangem/tangem_card/data/TangemCard.java b/tangem-card-old/src/main/java/com/tangem/tangem_card/data/TangemCard.java index 37da532954..7d924574a6 100644 --- a/tangem-card-old/src/main/java/com/tangem/tangem_card/data/TangemCard.java +++ b/tangem-card-old/src/main/java/com/tangem/tangem_card/data/TangemCard.java @@ -8,7 +8,6 @@ import com.tangem.tangem_card.reader.TLVList; import com.tangem.tangem_card.util.Util; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.Date; import java.util.EnumSet; @@ -359,6 +358,11 @@ public class TangemCard { return (settingsMask & SettingsMask.AllowSwapPIN2) != 0; } + public Boolean forbidPurgeWallet() { + if (settingsMask == null) return null; + return (settingsMask & SettingsMask.ForbidPurgeWallet) != 0; + } + public Boolean needCVC() { if (settingsMask == null) return null; return (settingsMask & SettingsMask.UseCVC) != 0; From 64fa83024e1ddea3ac75f0fc30b7042007e865b7 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 1 Apr 2020 09:52:31 +0300 Subject: [PATCH 8/8] Updated on 2026-08-14 --- .../tangem/ui/fragment/VerifyCardFragment.kt | 62 --------------- app/src/main/res/layout/fr_verify_card.xml | 75 +------------------ 2 files changed, 1 insertion(+), 136 deletions(-) diff --git a/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt b/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt index 421f780cc1..68ecebc90d 100644 --- a/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt @@ -278,11 +278,6 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter. ivBlockchain.setImageResource(Blockchain.getLogoImageResource(ctx.card!!.blockchainID, ctx.card!!.tokenSymbol)) - if (ctx.card!!.isReusable!!) - tvReusable.setText(R.string.details_reusable) - else - tvReusable.setText(R.string.details_one_off_card) - var s = "" for (signingM in ctx.card!!.allowedSigningMethod) { s += if (signingM == ctx.card!!.signingMethod) { @@ -328,44 +323,6 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter. tvFirmware.text = ctx.card!!.firmwareVersion - var features = "" - - features += if (ctx.card!!.allowSwapPIN()!! && ctx.card!!.allowSwapPIN2()!!) { - getString(R.string.details_both_pins_can_be_changed) - } else if (ctx.card!!.allowSwapPIN()!!) { - getString(R.string.details_pin1_can_be_changed) - } else if (ctx.card!!.allowSwapPIN2()!!) { - getString(R.string.details_pin2_can_be_changed) - } else { - getString(R.string.details_both_pins_fixed) - } - - if (ctx.card!!.needCVC()!!) - features += getString(R.string.details_required_cvc) - - - if (ctx.card!!.supportDynamicNDEF()!!) { - features += getString(R.string.details_dynamic_ndef) - } else if (ctx.card!!.supportNDEF()!!) - features += getString(R.string.details_ndef) - - if (ctx.card!!.supportBlock()!!) - features += getString(R.string.details_blockable) - - if (ctx.card!!.supportLinkingTerminal()) { - features += getString(R.string.details_linking_card_supported) - llLinkedCard.visibility = View.VISIBLE - } - - - if (ctx.card!!.supportOnlyOneCommandAtTime()) - features += getString(R.string.details_atomic_commmands) - - if (features.endsWith("\n")) - features = features.substring(0, features.length - 1) - - tvFeatures.text = features - val textIsLinked = if (ctx.card.terminalIsLinked) { getString(R.string.details_linked_card_to_phone) } else { @@ -373,25 +330,6 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter. } tvIsLinked.text = textIsLinked - if (ctx.card!!.useDefaultPIN1()) { - imgPIN.setImageResource(R.drawable.unlock_pin1) - imgPIN.setOnClickListener { Toast.makeText(context, R.string.details_protected_by_default_pin_1, Toast.LENGTH_LONG).show() } - } else { - imgPIN.setImageResource(R.drawable.lock_pin1) - imgPIN.setOnClickListener { Toast.makeText(context, R.string.details_protected_by_user_pin_1, Toast.LENGTH_LONG).show() } - } - - if (ctx.card!!.pauseBeforePIN2 > 0 && (ctx.card!!.useDefaultPIN2()!! || !ctx.card!!.useSmartSecurityDelay())) { - imgPIN2orSecurityDelay.setImageResource(R.drawable.timer) - imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, String.format(getString(R.string.details_security_delay), ctx.card!!.pauseBeforePIN2 / 1000.0), Toast.LENGTH_LONG).show() } - } else if (ctx.card!!.useDefaultPIN2()!!) { - imgPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2) - imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, R.string.details_protected_by_default_pin_2, Toast.LENGTH_LONG).show() } - } else { - imgPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2) - imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, R.string.details_protected_by_user_pin_2, Toast.LENGTH_LONG).show() } - } - if (ctx.card!!.useDevelopersFirmware()!!) { imgDeveloperVersion.setImageResource(R.drawable.ic_developer_version) imgDeveloperVersion.visibility = View.VISIBLE diff --git a/app/src/main/res/layout/fr_verify_card.xml b/app/src/main/res/layout/fr_verify_card.xml index 189186e5f5..cef381db19 100644 --- a/app/src/main/res/layout/fr_verify_card.xml +++ b/app/src/main/res/layout/fr_verify_card.xml @@ -159,32 +159,6 @@ - - - - - - - - - - - - - - - - - - - - -