diff --git a/tangem-core/src/main/java/com/tangem/CardManager.kt b/tangem-core/src/main/java/com/tangem/CardManager.kt index f5d064d4e9..ae2041db9e 100644 --- a/tangem-core/src/main/java/com/tangem/CardManager.kt +++ b/tangem-core/src/main/java/com/tangem/CardManager.kt @@ -5,6 +5,9 @@ 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.Issuer +import com.tangem.commands.personalization.entities.Manufacturer import com.tangem.common.CardEnvironment import com.tangem.common.TerminalKeysService import com.tangem.crypto.CryptoUtils @@ -261,15 +264,16 @@ class CardManager( * @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, cardId: String, + issuer: Issuer, manufacturer: Manufacturer, acquirer: Acquirer? = null, callback: (result: TaskEvent) -> Unit) { - if (this.config.issuer == null) { - callback(TaskEvent.Completion(TaskError.IssuerIsRequired())) - return - } - val personalizationCommand = PersonalizeCommand(config, cardId) + val personalizationCommand = PersonalizeCommand(config, cardId, issuer, manufacturer, acquirer) val task = SingleCommandTask(personalizationCommand) task.performPreflightRead = false runTask(task, callback = callback) @@ -320,10 +324,7 @@ class CardManager( val terminalKeys = if (config.linkedTerminal) terminalKeysService?.getKeys() else null return CardEnvironment( cardId = cardId, - terminalKeys = terminalKeys, - manufacturerKeyPair = config.manufacturerKeyPair, - acquirerKeyPair = config.acquirerKeyPair, - issuer = config.issuer + terminalKeys = terminalKeys ) } diff --git a/tangem-core/src/main/java/com/tangem/Config.kt b/tangem-core/src/main/java/com/tangem/Config.kt index 2067f61920..2d1193e176 100644 --- a/tangem-core/src/main/java/com/tangem/Config.kt +++ b/tangem-core/src/main/java/com/tangem/Config.kt @@ -1,12 +1,6 @@ package com.tangem -import com.tangem.commands.personalization.entities.Issuer -import com.tangem.common.KeyPair - class Config( val linkedTerminal: Boolean = true, - val issuerPublicKey: ByteArray? = null, - val manufacturerKeyPair: KeyPair? = null, - val acquirerKeyPair: KeyPair? = null, - val issuer: Issuer? = null + val issuerPublicKey: ByteArray? = null ) \ No newline at end of file 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..848c72e5e6 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,7 +3,9 @@ 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.common.CardEnvironment import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction @@ -23,22 +25,25 @@ import com.tangem.tasks.TaskError * Personalization is an initialization procedure, required before starting using a card. * During this procedure a card setting is set up. * 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 + * @property 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. + * @property cardId this parameter will set up CID, Unique Tangem card ID. + * @property issuer Issuer is a third-party team or company wishing to use Tangem cards. + * @property manufacturer Tangem Card Manufacturer. + * @property acquirer Acquirer is a trusted third-party company that operates proprietary + * (non-EMV) POS terminal infrastructure and transaction processing back-end. */ -class PersonalizeCommand(private val config: CardConfig, private val cardId: String) : CommandSerializer() { +class PersonalizeCommand( + private val config: CardConfig, private val cardId: String, + private val issuer: Issuer, private val manufacturer: Manufacturer, + private val acquirer: Acquirer? = null +) : CommandSerializer() { override fun serialize(cardEnvironment: CardEnvironment): CommandApdu { - if (cardEnvironment.issuer == null || cardEnvironment.manufacturerKeyPair == null) { - throw TaskError.SerializeCommandError() - } return CommandApdu( Instruction.Personalize, serializePersonalizationData( - cardId, config, - cardEnvironment.issuer, cardEnvironment.manufacturerKeyPair.privateKey, - cardEnvironment.acquirerKeyPair?.publicKey), + cardId, config), encryptionKey = devPersonalizationKey ) } @@ -99,10 +104,7 @@ class PersonalizeCommand(private val config: CardConfig, private val cardId: Str ) } - private fun serializePersonalizationData(cardId: String, config: CardConfig, - issuer: Issuer, manufacturerPrivateKey: ByteArray, - acquirePublicKey: ByteArray? - ): ByteArray { + private fun serializePersonalizationData(cardId: String, config: CardConfig): ByteArray { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.CardId, cardId) @@ -123,17 +125,13 @@ class PersonalizeCommand(private val config: CardConfig, private val cardId: Str tlvBuilder.append(TlvTag.IssuerDataPublicKey, issuer.dataKeyPair.publicKey) tlvBuilder.append(TlvTag.IssuerTransactionPublicKey, issuer.transactionKeyPair.publicKey) - tlvBuilder.append(TlvTag.AcquirerPublicKey, acquirePublicKey) + tlvBuilder.append(TlvTag.AcquirerPublicKey, acquirer?.keyPair?.publicKey) - tlvBuilder.append( - TlvTag.CardData, serializeCardData(cardId, config.cardData, issuer, manufacturerPrivateKey) - ) + tlvBuilder.append(TlvTag.CardData, serializeCardData(cardId, config.cardData)) return tlvBuilder.serialize() } - private fun serializeCardData( - cardId: String, cardData: CardData, - issuer: Issuer, manufacturerPrivateKey: ByteArray): ByteArray { + private fun serializeCardData(cardId: String, cardData: CardData): ByteArray { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Batch, cardData.batchId) tlvBuilder.append(TlvTag.ProductMask, cardData.productMask) @@ -150,7 +148,8 @@ class PersonalizeCommand(private val config: CardConfig, private val cardId: Str tlvBuilder.append(TlvTag.TokenDecimal, cardData.tokenDecimal) } tlvBuilder.append( - TlvTag.CardIdManufacturerSignature, cardId.hexToBytes().sign(manufacturerPrivateKey) + TlvTag.CardIdManufacturerSignature, + cardId.hexToBytes().sign(manufacturer.keyPair.privateKey) ) return tlvBuilder.serialize() } diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Acquirer.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Acquirer.kt new file mode 100644 index 0000000000..cda239b145 --- /dev/null +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Acquirer.kt @@ -0,0 +1,9 @@ +package com.tangem.commands.personalization.entities + +import com.tangem.common.KeyPair + +data class Acquirer( + val keyPair: KeyPair, + val name: String? = null, + val id: String? = null +) \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Manufacturer.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Manufacturer.kt new file mode 100644 index 0000000000..bffdde9384 --- /dev/null +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Manufacturer.kt @@ -0,0 +1,8 @@ +package com.tangem.commands.personalization.entities + +import com.tangem.common.KeyPair + +data class Manufacturer( + val keyPair: KeyPair, + val name: String? = null +) \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt b/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt index bc507bf9a2..c556f427b3 100644 --- a/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt +++ b/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt @@ -1,7 +1,5 @@ package com.tangem.common -import com.tangem.commands.personalization.entities.Issuer - /** * Contains data relating to a Tangem card. It is used in constructing all the commands, @@ -14,10 +12,7 @@ data class CardEnvironment( val terminalKeys: KeyPair? = null, var encryptionMode: EncryptionMode = EncryptionMode.NONE, var encryptionKey: ByteArray? = null, - val cvc: ByteArray? = null, - val manufacturerKeyPair: KeyPair? = null, - val acquirerKeyPair: KeyPair? = null, - val issuer: Issuer? = null + val cvc: ByteArray? = null ) { companion object { diff --git a/tangem-core/src/main/java/com/tangem/tasks/Task.kt b/tangem-core/src/main/java/com/tangem/tasks/Task.kt index b585cd3023..224b163a9a 100644 --- a/tangem-core/src/main/java/com/tangem/tasks/Task.kt +++ b/tangem-core/src/main/java/com/tangem/tasks/Task.kt @@ -141,12 +141,6 @@ sealed class TaskError(val code: Int) : Exception() { * (when the card's requires it), but the counter is missing. */ class MissingCounter : TaskError(7001) - - /** - * This error is returned when [com.tangem.commands.personalization.PersonalizeCommand] is attempted - * without [com.tangem.commands.personalization.entities.Issuer] being set in the [com.tangem.Config]. - */ - class IssuerIsRequired : TaskError(7002) } /** 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..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,30 +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), "BB00000000000395" - ) { - 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 { diff --git a/tangem-demo/src/main/res/layout/activity_main.xml b/tangem-demo/src/main/res/layout/activity_main.xml index d3bb8bbabe..2af3ad92de 100644 --- a/tangem-demo/src/main/res/layout/activity_main.xml +++ b/tangem-demo/src/main/res/layout/activity_main.xml @@ -111,26 +111,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btn_create_wallet" /> -