diff --git a/blockchain/src/test/java/com/tangem/blockchain/common/WalletManagerFactoryTest.kt b/blockchain/src/test/java/com/tangem/blockchain/common/WalletManagerFactoryTest.kt index 58034631e7..9ce1fd90ac 100644 --- a/blockchain/src/test/java/com/tangem/blockchain/common/WalletManagerFactoryTest.kt +++ b/blockchain/src/test/java/com/tangem/blockchain/common/WalletManagerFactoryTest.kt @@ -1,7 +1,7 @@ package com.tangem.blockchain.common import com.google.common.truth.Truth -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.blockchain.bitcoin.BitcoinWalletManager import com.tangem.blockchain.cardano.CardanoWalletManager import com.tangem.blockchain.ethereum.EthereumWalletManager @@ -18,7 +18,7 @@ internal class WalletManagerFactoryTest { fun createBitcoinWalletManager() { val data = "0108bb00000000000304200754414e47454d00020102800a322e3432642053444b000341040876bdec26b89bd2159a668b9af3d9fe86370f318717c92b8d6c1186fb3648c32a5f9321998cc2d042901c91d40601e79a641e1cbcebe7a2358be6054e1b6e5d0a04041e76310c618102ffff8a0101820407e30b0d830b54414e47454d2053444b0084034254438640e17ceec48c5be36240c98019f95ad8b6e56acfebe60d11979c6279f715d607d76a860a137da8d109e805753f3f56b0130709f4bbf4cb9974b4c57b8469bf4b873041045f16bd1d2eafe463e62a335a09e6b2bbcbd04452526885cb679fc4d27af1bd22f553c7deefb54fd3d4f361d14e6dc3f11b7d4ea183250a60720ebdf9e110cd26050a736563703235366b310008040000006407010009020bb8604104752a727e14bba5bd73b6714d72500f61ffd11026ad1196d2e1c54577cbeeac3d11fc68a64700f8d533f4e311964ea8fb3aa26c588295f2133868d69c3e62869362040000005c6304000000090f01009000" val responseApdu = ResponseApdu(data.hexToBytes()) - val card = ReadCommand().deserialize(CardEnvironment(), responseApdu) + val card = ReadCommand().deserialize(SessionEnvironment(), responseApdu) val walletManager = WalletManagerFactory.makeWalletManager(card!!) Truth.assertThat(walletManager) @@ -29,7 +29,7 @@ internal class WalletManagerFactoryTest { fun createEthereumWalletManager() { val data = "0108bb00000000000536200754414e47454d00020102800a322e3432642053444b000341046c8aea0d5a850b0a608acf9a0c453c39ea86131e88bfa78800de3cfb5bf1007aeaa7b9ffc184212255758605c2461be343c0a661d73cabafa4c9c175b3f0e59a0a04041e76310c618102ffff8a0101820407e30b0d830b54414e47454d2053444b0084034554488640431b6244acfeac479becdff201a7f720a7d70a97edc4e019fb678596baf52dfe9d0e8faf08ceb4443b82d4e66815541f2dc8ec6dd3ff83eb42f06e5eab07f25f3041045f16bd1d2eafe463e62a335a09e6b2bbcbd04452526885cb679fc4d27af1bd22f553c7deefb54fd3d4f361d14e6dc3f11b7d4ea183250a60720ebdf9e110cd26050a736563703235366b3100080400000064070100090205dc60410464dddc3f356744aaecfa07427f9eb996ff537d65f20fb5be3abccf0354352a6b5f8a1942e0f8ddeea3a170eda78d060be8162ad60e94e4e91fbbdf0a7054785562040000005b6304000000090f01009000" val responseApdu = ResponseApdu(data.hexToBytes()) - val card = ReadCommand().deserialize(CardEnvironment(), responseApdu) + val card = ReadCommand().deserialize(SessionEnvironment(), responseApdu) val walletManager = WalletManagerFactory.makeWalletManager(card!!) Truth.assertThat(walletManager) @@ -40,7 +40,7 @@ internal class WalletManagerFactoryTest { fun createStellarWalletManager() { val data = "0108bb00000000000379200754414e47454d00020102800a322e3432642053444b0003410487d7bb51b189213e3cedc3fcfa3fc047b3b71b7805b5b215e14639b3a8ebb1952c9dd5ea4354441b6ada4e8b8327674bb102ddae69df55be69643a2c916edf650a04041e76310c618102ffff8a0101820407e30b0d830b54414e47454d2053444b008403584c4d86409a4bc2baf0e5836887da21167cf33458d5249d1a610bced0e31dc053f23729ed24d715912bf89e6804669430dfe396ed83274e0031f6803e2bdb8c041fa993413041045f16bd1d2eafe463e62a335a09e6b2bbcbd04452526885cb679fc4d27af1bd22f553c7deefb54fd3d4f361d14e6dc3f11b7d4ea183250a60720ebdf9e110cd2605086564323535313900080400000064070100090205dc6020e078212d58b2b9d0edc9c936830d10081cd38b90c31778c56dfb1171027e294e62040000003863040000002c0f01009000" val responseApdu = ResponseApdu(data.hexToBytes()) - val card = ReadCommand().deserialize(CardEnvironment(), responseApdu) + val card = ReadCommand().deserialize(SessionEnvironment(), responseApdu) val walletManager = WalletManagerFactory.makeWalletManager(card!!) Truth.assertThat(walletManager) @@ -51,7 +51,7 @@ internal class WalletManagerFactoryTest { fun createCardanoWalletManager() { val data = "0108bb00000000000502200754414e47454d00020102800a322e3432642053444b0003410402c1e39257d60583489da2d67d35d1cc2a1c005cc05c1021f44838edcaf25d5615cad7c9d11c2e23f5efa93e50904d33c88808d0e169060508df840992e31f4d0a04041e76310c658102ffff8a0101820407e30b0d830b54414e47454d2053444b00840743415244414e4f8640f24ef5c8c6eba0ff97560d5b013edb4a452594270db9647bd0a3543df8104dec75731d4db3ebe0fc493f2afee00195e560b51e3c41189b7c61ba7895d6434b9d3041045f16bd1d2eafe463e62a335a09e6b2bbcbd04452526885cb679fc4d27af1bd22f553c7deefb54fd3d4f361d14e6dc3f11b7d4ea183250a60720ebdf9e110cd2605086564323535313900080400000064070100090205dc60208a71161cfdf1e0a85d8e7ff372aa4a01136046292aceb5f9ad7ebdb98d3f60a86204000000646304000000000f01009000" val responseApdu = ResponseApdu(data.hexToBytes()) - val card = ReadCommand().deserialize(CardEnvironment(), responseApdu) + val card = ReadCommand().deserialize(SessionEnvironment(), responseApdu) val walletManager = WalletManagerFactory.makeWalletManager(card!!) Truth.assertThat(walletManager) @@ -62,7 +62,7 @@ internal class WalletManagerFactoryTest { fun createXrpWalletManager() { val data = "0108cb21000000002154200b534d4152542043415348000201028006322e31317200034104bdad63848f97c535da53cf8fd300d24fa33f0516d194aa78ec164a06994d00204bae243a424e316c6ec845e02d9b15eafae8c19018a926b0b7435e6e941cdadb0a0400007e210c5a81020028820407e30502830754414e47454d00840358525086400ed8734b877869722c7d0b37ffb154b9fef21c54bf2c6496feb1fb5c1fc28a2ac28e201dde84f27495fa7f08b3ca2be2fb4954bf0fe78af027d6cdc16c3eee923041048196aa4b410ac44a3b9cce18e7be226aea070acc83a9cf67540fac49af25129f6a538a28ad6341358e3c4f9963064f7e365372a651d374e5c23cdd37fd099bf2050a736563703235366b31000804000f4240070100090205dc604104d2b9fb288540d54e5b32ecaf0381cd571f97f6f1ecd036b66bb11aa52ffe9981110d883080e2e255c6b1640586f7765e6faa325d1340f49b56b83d9de56bc7ed6204000f42406304000000000f01009000" val responseApdu = ResponseApdu(data.hexToBytes()) - val card = ReadCommand().deserialize(CardEnvironment(), responseApdu) + val card = ReadCommand().deserialize(SessionEnvironment(), responseApdu) val walletManager = WalletManagerFactory.makeWalletManager(card!!) Truth.assertThat(walletManager) diff --git a/tangem-core/src/main/java/com/tangem/CardSession.kt b/tangem-core/src/main/java/com/tangem/CardSession.kt index f8455ace3e..1852ae25d9 100644 --- a/tangem-core/src/main/java/com/tangem/CardSession.kt +++ b/tangem-core/src/main/java/com/tangem/CardSession.kt @@ -7,7 +7,6 @@ import com.tangem.commands.ReadCommand import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.extensions.calculateSha256 import com.tangem.crypto.EncryptionHelper import com.tangem.crypto.FastEncryptionHelper import com.tangem.crypto.StrongEncryptionHelper @@ -41,9 +40,9 @@ interface CardSessionRunnable { * If null, a default header and text body will be used. */ class CardSession( - val environment: CardEnvironment, - val reader: CardReader, - val viewDelegate: CardSessionViewDelegate, + val environment: SessionEnvironment, + private val reader: CardReader, + val viewDelegate: SessionViewDelegate, private var cardId: String? = null, private val initialMessage: Message? = null ) { @@ -208,7 +207,7 @@ class CardSession( when (result) { is CompletionResult.Success -> { val uid = result.data.uid - val protocolKey = environment.pin1.calculateSha256().pbkdf2Hash(uid, 50) + val protocolKey = environment.pin1.pbkdf2Hash(uid, 50) val secret = encryptionHelper.generateSecret(result.data.sessionKeyB) val sessionKey = (secret + protocolKey).calculateSha256() environment.encryptionKey = sessionKey diff --git a/tangem-core/src/main/java/com/tangem/Config.kt b/tangem-core/src/main/java/com/tangem/Config.kt index 7403a4c771..d99c57fcf9 100644 --- a/tangem-core/src/main/java/com/tangem/Config.kt +++ b/tangem-core/src/main/java/com/tangem/Config.kt @@ -24,5 +24,10 @@ class Config( * If not null, it will be used to validate Issuer data and issuer extra data. * If null, issuerPublicKey from current card will be used. */ - val issuerPublicKey: ByteArray? = null + val issuerPublicKey: ByteArray? = null, + + /** + * Level of encryption used in communication with a Tangem Card. + */ + val encryptionMode: EncryptionMode = EncryptionMode.NONE ) \ 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/SessionEnvironment.kt similarity index 89% rename from tangem-core/src/main/java/com/tangem/CardEnvironment.kt rename to tangem-core/src/main/java/com/tangem/SessionEnvironment.kt index e4b2c36c55..81a541184c 100644 --- a/tangem-core/src/main/java/com/tangem/CardEnvironment.kt +++ b/tangem-core/src/main/java/com/tangem/SessionEnvironment.kt @@ -2,17 +2,18 @@ package com.tangem import com.tangem.commands.Card import com.tangem.commands.EllipticCurve +import com.tangem.common.extensions.calculateSha256 import com.tangem.crypto.CryptoUtils.generatePublicKey /** * Contains data relating to a Tangem card. It is used in constructing all the commands, - * and commands can return modified [CardEnvironment]. + * and commands can return modified [SessionEnvironment]. * * @property card Current card, read by preflight [com.tangem.commands.ReadCommand]. * @property terminalKeys generated terminal keys used in Linked Terminal feature. */ -data class CardEnvironment( +data class SessionEnvironment( val pin1: String = DEFAULT_PIN, val pin2: String = DEFAULT_PIN2, var card: Card? = null, diff --git a/tangem-core/src/main/java/com/tangem/CardSessionViewDelegate.kt b/tangem-core/src/main/java/com/tangem/SessionViewDelegate.kt similarity index 97% rename from tangem-core/src/main/java/com/tangem/CardSessionViewDelegate.kt rename to tangem-core/src/main/java/com/tangem/SessionViewDelegate.kt index da5f26e020..c372b1730c 100644 --- a/tangem-core/src/main/java/com/tangem/CardSessionViewDelegate.kt +++ b/tangem-core/src/main/java/com/tangem/SessionViewDelegate.kt @@ -7,7 +7,7 @@ import com.tangem.common.CompletionResult * * Its default implementation, DefaultCardManagerDelegate, is in our tangem-sdk module. */ -interface CardSessionViewDelegate { +interface SessionViewDelegate { /** * It is called when user is expected to scan a Tangem Card with an Android device. diff --git a/tangem-core/src/main/java/com/tangem/TangemSdk.kt b/tangem-core/src/main/java/com/tangem/TangemSdk.kt index 786249d22b..145efc088e 100644 --- a/tangem-core/src/main/java/com/tangem/TangemSdk.kt +++ b/tangem-core/src/main/java/com/tangem/TangemSdk.kt @@ -27,12 +27,11 @@ import com.tangem.tasks.ScanTask */ class TangemSdk( private val reader: CardReader, - private val viewDelegate: CardSessionViewDelegate, + private val viewDelegate: SessionViewDelegate, var config: Config = Config() ) { private var terminalKeysService: TerminalKeysService? = null - private var cardSession: CardSession? = null init { CryptoUtils.initCrypto() @@ -49,9 +48,8 @@ class TangemSdk( * @param callback is triggered on the completion of the [ScanTask] and provides card response * in the form of [Card] if the task was performed successfully or [SessionError] in case of an error. */ - fun scanCard(callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate) - cardSession!!.startWithRunnable(ScanTask(), callback) + fun scanCard(initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { + startSession(ScanTask(), null, initialMessage, callback) } /** @@ -64,7 +62,7 @@ class TangemSdk( * * Please note that Tangem cards usually protect the signing with a security delay * that may last up to 90 seconds, depending on a card. - * It is for [CardSessionViewDelegate] to notify users of security delay. + * It is for [SessionViewDelegate] to notify users of security delay. * * @param hashes Array of transaction hashes. It can be from one or up to ten hashes of the same length. * @param cardId CID, Unique Tangem card ID number @@ -72,10 +70,9 @@ class TangemSdk( * in the form of [SignResponse] if the task was performed successfully * or [SessionError] in case of an error. */ - fun sign(hashes: Array, cardId: String, + fun sign(hashes: Array, cardId: String, initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(SignCommand(hashes), callback) + startSession(SignCommand(hashes), cardId, initialMessage, callback) } /** @@ -91,10 +88,9 @@ class TangemSdk( * card response in the form of [ReadIssuerDataResponse] if the task was performed successfully * or [SessionError] in case of an error. */ - fun readIssuerData(cardId: String, + fun readIssuerData(cardId: String, initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(ReadIssuerDataCommand(config.issuerPublicKey), callback) + startSession(ReadIssuerDataCommand(config.issuerPublicKey), cardId, initialMessage, callback) } /** @@ -113,8 +109,7 @@ class TangemSdk( */ fun readIssuerExtraData(cardId: String, callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(ReadIssuerExtraDataCommand(config.issuerPublicKey), callback) + startSession(ReadIssuerExtraDataCommand(config.issuerPublicKey), cardId, null, callback) } /** @@ -137,6 +132,7 @@ class TangemSdk( issuerData: ByteArray, issuerDataSignature: ByteArray, issuerDataCounter: Int? = null, + initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { val command = WriteIssuerDataCommand( issuerData, @@ -144,8 +140,7 @@ class TangemSdk( issuerDataCounter, config.issuerPublicKey ) - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(command, callback) + startSession(command, cardId, initialMessage, callback) } /** @@ -176,6 +171,7 @@ class TangemSdk( startingSignature: ByteArray, finalizingSignature: ByteArray, issuerDataCounter: Int? = null, + initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { val command = WriteIssuerExtraDataCommand( issuerData, @@ -183,8 +179,7 @@ class TangemSdk( issuerDataCounter, config.issuerPublicKey ) - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(command, callback) + startSession(command, cardId, initialMessage, callback) } /** @@ -207,11 +202,11 @@ class TangemSdk( userProtectedData: ByteArray? = null, userCounter: Int? = null, userProtectedCounter: Int? = null, + initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit ) { val command = WriteUserDataCommand(userData, userProtectedData, userCounter, userProtectedCounter) - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(command, callback) + startSession(command, cardId, initialMessage, callback) } /** @@ -231,9 +226,9 @@ class TangemSdk( * card response in the form of [ReadUserDataResponse] if the task was performed successfully * or [SessionError] in case of an error. */ - fun readUserData(cardId: String, callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(ReadUserDataCommand(), callback) + fun readUserData(cardId: String, initialMessage: Message? = null, + callback: (result: CompletionResult) -> Unit) { + startSession(ReadUserDataCommand(), cardId, initialMessage, callback) } /** @@ -253,10 +248,9 @@ class TangemSdk( * card response in the form of [CreateWalletResponse] if the task was performed successfully * or [SessionError] in case of an error. */ - fun createWallet(cardId: String, + fun createWallet(cardId: String, initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(CreateWalletTask(), callback) + startSession(CreateWalletTask(), cardId, initialMessage, callback) } /** @@ -273,10 +267,9 @@ class TangemSdk( * card response in the form of [PurgeWalletResponse] if the task was performed successfully * or [SessionError] in case of an error. */ - fun purgeWallet(cardId: String, + fun purgeWallet(cardId: String, initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(PurgeWalletCommand(), callback) + startSession(PurgeWalletCommand(), cardId, initialMessage, callback) } /** @@ -292,10 +285,9 @@ class TangemSdk( * card response in the form of [DepersonalizeResponse] if the task was performed successfully * or [SessionError] in case of an error. * */ - fun depersonalize(cardId: String, + fun depersonalize(cardId: String, initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId) - cardSession!!.startWithRunnable(DepersonalizeCommand(), callback) + startSession(DepersonalizeCommand(), cardId, initialMessage, callback) } /** @@ -318,10 +310,10 @@ class TangemSdk( */ fun personalize(config: CardConfig, issuer: Issuer, manufacturer: Manufacturer, acquirer: Acquirer? = null, + initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { val command = PersonalizeCommand(config, issuer, manufacturer, acquirer) - cardSession = CardSession(buildEnvironment(), reader, viewDelegate) - cardSession!!.startWithRunnable(command, callback) + startSession(command, null, initialMessage, callback) } /** @@ -341,8 +333,8 @@ class TangemSdk( fun startSession( runnable: CardSessionRunnable, cardId: String? = null, initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId, initialMessage) - Thread().run { cardSession!!.startWithRunnable(runnable, callback) } + val cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId, initialMessage) + Thread().run { cardSession.startWithRunnable(runnable, callback) } } /** @@ -360,8 +352,8 @@ class TangemSdk( fun startSession( cardId: String? = null, initialMessage: Message? = null, callback: (session: CardSession, error: SessionError?) -> Unit) { - cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId, initialMessage) - Thread().run { cardSession!!.start(callback) } + val cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId, initialMessage) + Thread().run { cardSession.start(callback) } } /** @@ -372,9 +364,9 @@ class TangemSdk( this.terminalKeysService = terminalKeysService } - private fun buildEnvironment(): CardEnvironment { + private fun buildEnvironment(): SessionEnvironment { val terminalKeys = if (config.linkedTerminal) terminalKeysService?.getKeys() else null - return CardEnvironment( + return SessionEnvironment( terminalKeys = terminalKeys ) } diff --git a/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt b/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt index d6df4c4204..4d9c3a53ff 100644 --- a/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt @@ -1,7 +1,7 @@ package com.tangem.commands -import com.tangem.CardEnvironment import com.tangem.CardSession +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu @@ -70,7 +70,7 @@ class CheckWalletCommand( } } - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) @@ -81,7 +81,7 @@ class CheckWalletCommand( ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): CheckWalletResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): CheckWalletResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-core/src/main/java/com/tangem/commands/Command.kt b/tangem-core/src/main/java/com/tangem/commands/Command.kt index 9d06c5fe7f..a44332d04f 100644 --- a/tangem-core/src/main/java/com/tangem/commands/Command.kt +++ b/tangem-core/src/main/java/com/tangem/commands/Command.kt @@ -22,20 +22,20 @@ abstract class Command : CardSessionRunnable { /** * Serializes data into an array of [com.tangem.common.tlv.Tlv], * then creates [CommandApdu] with this data. - * @param environment [CardEnvironment] of the current card + * @param environment [SessionEnvironment] of the current card * @return command data converted to [CommandApdu] that allows to convert it to [ByteArray] * that can be sent to a Tangem card */ - abstract fun serialize(environment: CardEnvironment): CommandApdu + abstract fun serialize(environment: SessionEnvironment): CommandApdu /** * Deserializes data received from a card and stored in [ResponseApdu] * into an array of [com.tangem.common.tlv.Tlv]. Then maps it into a [CommandResponse]. - * @param environment [CardEnvironment] of the current card. + * @param environment [SessionEnvironment] of the current card. * @param apdu received data. * @return Card response converted to a [CommandResponse] of a type [T] */ - abstract fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): T + abstract fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): T override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { transceive(session, callback) @@ -92,9 +92,8 @@ abstract class Command : CardSessionRunnable { is CompletionResult.Failure -> if (result.error == SessionError.TagLost()) { session.viewDelegate.onTagLost() - } else if (result.error is SessionError.UserCancelled) { - callback(CompletionResult.Failure(SessionError.UserCancelled())) - session.reader.closeSession() + } else { + callback(CompletionResult.Failure(result.error)) } } } @@ -105,12 +104,12 @@ abstract class Command : CardSessionRunnable { * * @return Remaining security delay in milliseconds. */ - private fun deserializeSecurityDelay(responseApdu: ResponseApdu, cardEnvironment: CardEnvironment): Int? { + private fun deserializeSecurityDelay(responseApdu: ResponseApdu, environment: SessionEnvironment): Int? { val tlv = responseApdu.getTlvData() return tlv?.find { it.tag == TlvTag.Pause }?.value?.toInt() } - private fun tryHandleError(error: SessionError) : Boolean { + private fun tryHandleError(error: SessionError): Boolean { return false } diff --git a/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt b/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt index d93da64242..089a134702 100644 --- a/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt @@ -1,6 +1,6 @@ package com.tangem.commands -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction @@ -37,7 +37,7 @@ class CreateWalletResponse( */ class CreateWalletCommand : Command() { - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) @@ -49,7 +49,7 @@ class CreateWalletCommand : Command() { ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): CreateWalletResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): CreateWalletResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-core/src/main/java/com/tangem/commands/OpenSessionCommand.kt b/tangem-core/src/main/java/com/tangem/commands/OpenSessionCommand.kt index 48b3d9a80e..7484f9d48b 100644 --- a/tangem-core/src/main/java/com/tangem/commands/OpenSessionCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/OpenSessionCommand.kt @@ -1,6 +1,6 @@ package com.tangem.commands -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction @@ -21,7 +21,7 @@ class OpenSessionResponse( */ class OpenSessionCommand(private val sessionKeyA: ByteArray) : Command() { - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.SessionKeyA, sessionKeyA) return CommandApdu( @@ -30,7 +30,7 @@ class OpenSessionCommand(private val sessionKeyA: ByteArray) : Command() { - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) @@ -40,7 +40,7 @@ class PurgeWalletCommand : Command() { ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): PurgeWalletResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): PurgeWalletResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt b/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt index e0deea6cb8..09c188072d 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt @@ -1,6 +1,6 @@ package com.tangem.commands -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction @@ -382,10 +382,10 @@ class Card( */ class ReadCommand : Command() { - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() /** - * [CardEnvironment] stores the pin1 value. If no pin1 value was set, it will contain + * [SessionEnvironment] stores the pin1 value. If no pin1 value was set, it will contain * default value of ‘000000’. * In order to obtain card’s data, [ReadCommand] should use the correct pin 1 value. * The card will not respond if wrong pin 1 has been submitted. @@ -398,7 +398,7 @@ class ReadCommand : Command() { ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): Card { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): Card { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt index 3909e0cbb6..7055bc403f 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt @@ -1,7 +1,7 @@ package com.tangem.commands -import com.tangem.CardEnvironment import com.tangem.CardSession +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.commands.common.DefaultIssuerDataVerifier import com.tangem.commands.common.IssuerDataMode @@ -90,7 +90,7 @@ class ReadIssuerDataCommand( } } - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) @@ -101,7 +101,7 @@ class ReadIssuerDataCommand( ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): ReadIssuerDataResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): ReadIssuerDataResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt index 83120f9c41..4140000621 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt @@ -1,7 +1,7 @@ package com.tangem.commands -import com.tangem.CardEnvironment import com.tangem.CardSession +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.commands.common.DefaultIssuerDataVerifier import com.tangem.commands.common.IssuerDataMode @@ -142,7 +142,7 @@ class ReadIssuerExtraDataCommand( } } - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) @@ -154,7 +154,7 @@ class ReadIssuerExtraDataCommand( ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): ReadIssuerExtraDataResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): ReadIssuerExtraDataResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() 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 7209d424df..528ba98fb0 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt @@ -1,6 +1,6 @@ package com.tangem.commands -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction @@ -49,7 +49,7 @@ class ReadUserDataResponse( */ class ReadUserDataCommand: Command() { - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val builder = TlvBuilder() builder.append(TlvTag.CardId, environment.card?.cardId) builder.append(TlvTag.Pin, environment.pin1) @@ -60,7 +60,7 @@ class ReadUserDataCommand: Command() { ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): ReadUserDataResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): ReadUserDataResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt b/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt index 0a48b022d6..7707f82197 100644 --- a/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt @@ -1,6 +1,6 @@ package com.tangem.commands -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction @@ -35,7 +35,7 @@ class SignCommand(private val hashes: Array) private val hashSizes = if (hashes.isNotEmpty()) hashes.first().size else 0 - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val dataToSign = flattenHashes() val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) @@ -71,7 +71,7 @@ class SignCommand(private val hashes: Array) * (this key should be generated and securily stored by the application). */ private fun addTerminalSignature( - environment: CardEnvironment, dataToSign: ByteArray, tlvBuilder: TlvBuilder) { + environment: SessionEnvironment, dataToSign: ByteArray, tlvBuilder: TlvBuilder) { environment.terminalKeys?.let { terminalKeyPair -> val signedData = dataToSign.sign(terminalKeyPair.privateKey) tlvBuilder.append(TlvTag.TerminalTransactionSignature, signedData) @@ -79,7 +79,7 @@ class SignCommand(private val hashes: Array) } } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): SignResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): SignResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt index 0345eb300f..a425f5a740 100644 --- a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt @@ -1,7 +1,7 @@ package com.tangem.commands -import com.tangem.CardEnvironment import com.tangem.CardSession +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.commands.common.DefaultIssuerDataVerifier import com.tangem.commands.common.IssuerDataMode @@ -76,7 +76,7 @@ class WriteIssuerDataCommand( ) } - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) @@ -91,7 +91,7 @@ class WriteIssuerDataCommand( ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): WriteIssuerDataResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): WriteIssuerDataResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt index 29bf3cd0d5..4a93ebd734 100644 --- a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt @@ -1,7 +1,7 @@ package com.tangem.commands -import com.tangem.CardEnvironment import com.tangem.CardSession +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.commands.common.DefaultIssuerDataVerifier import com.tangem.commands.common.IssuerDataMode @@ -119,7 +119,7 @@ class WriteIssuerExtraDataCommand( } - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) @@ -154,7 +154,7 @@ class WriteIssuerExtraDataCommand( return if (bytesLeft < SINGLE_WRITE_SIZE) bytesLeft else SINGLE_WRITE_SIZE } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): WriteIssuerDataResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): WriteIssuerDataResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() 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 912c57f7e6..e9771d0b87 100644 --- a/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt @@ -1,6 +1,6 @@ package com.tangem.commands -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction @@ -32,7 +32,7 @@ class WriteUserDataCommand(private val userData: ByteArray? = null, private val private val userCounter: Int? = null, private val userProtectedCounter: Int? = null) : Command() { - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { val builder = TlvBuilder() builder.append(TlvTag.CardId, environment.card?.cardId) builder.append(TlvTag.Pin, environment.pin1) @@ -49,7 +49,7 @@ class WriteUserDataCommand(private val userData: ByteArray? = null, private val ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): WriteUserDataResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): WriteUserDataResponse { val tlvData = apdu.getTlvData(environment.encryptionKey) ?: throw SessionError.DeserializeApduFailed() return WriteUserDataResponse(TlvDecoder(tlvData).decode(TlvTag.CardId)) diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/DepersonalizeCommand.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/DepersonalizeCommand.kt index 2fcd962966..2ed9366331 100644 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/DepersonalizeCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/DepersonalizeCommand.kt @@ -1,6 +1,6 @@ package com.tangem.commands.personalization -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.commands.Command import com.tangem.commands.CommandResponse import com.tangem.common.apdu.CommandApdu @@ -17,13 +17,13 @@ data class DepersonalizeResponse(val success: Boolean) : CommandResponse */ class DepersonalizeCommand : Command() { - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { return CommandApdu( Instruction.Depersonalize, byteArrayOf() ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): DepersonalizeResponse { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): DepersonalizeResponse { return DepersonalizeResponse(true) } } \ 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 2d81d479a2..24a118322a 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 @@ -1,6 +1,6 @@ package com.tangem.commands.personalization -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.commands.Card import com.tangem.commands.CardData @@ -36,7 +36,7 @@ class PersonalizeCommand( private val acquirer: Acquirer? = null ) : Command() { - override fun serialize(environment: CardEnvironment): CommandApdu { + override fun serialize(environment: SessionEnvironment): CommandApdu { return CommandApdu( Instruction.Personalize, serializePersonalizationData(config), @@ -44,7 +44,7 @@ class PersonalizeCommand( ) } - override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): Card { + override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): Card { val tlvData = apdu.getTlvData(devPersonalizationKey) ?: throw SessionError.DeserializeApduFailed() diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/TestUserDataActivity.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/TestUserDataActivity.kt index 0df7bd9aa6..7f3ba0639d 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/TestUserDataActivity.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/TestUserDataActivity.kt @@ -5,7 +5,7 @@ import android.view.View import android.widget.CompoundButton import android.widget.TextView import androidx.appcompat.app.AppCompatActivity -import com.tangem.CardEnvironment +import com.tangem.SessionEnvironment import com.tangem.SessionError import com.tangem.TangemSdk import com.tangem.common.CompletionResult @@ -143,7 +143,7 @@ class WriteOptions { } fun updatePin2(chbx: CompoundButton) { - val value = CardEnvironment.DEFAULT_PIN2 + val value = SessionEnvironment.DEFAULT_PIN2 pin2 = if (chbx.isChecked) value else null } } \ No newline at end of file diff --git a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/DefaultCardSessionViewDelegate.kt b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/DefaultSessionViewDelegate.kt similarity index 97% rename from tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/DefaultCardSessionViewDelegate.kt rename to tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/DefaultSessionViewDelegate.kt index 56cce78f88..d9cdf14304 100644 --- a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/DefaultCardSessionViewDelegate.kt +++ b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/DefaultSessionViewDelegate.kt @@ -6,10 +6,10 @@ import android.view.View import android.view.animation.DecelerateInterpolator import androidx.fragment.app.FragmentActivity import com.google.android.material.bottomsheet.BottomSheetDialog -import com.tangem.CardSessionViewDelegate import com.tangem.Log import com.tangem.LoggerInterface import com.tangem.Message +import com.tangem.SessionViewDelegate import com.tangem.common.CompletionResult import com.tangem.tangem_sdk_new.extensions.hide import com.tangem.tangem_sdk_new.extensions.show @@ -20,10 +20,10 @@ import kotlinx.android.synthetic.main.layout_touch_card.* import kotlinx.android.synthetic.main.nfc_bottom_sheet.* /** - * Default implementation of [CardSessionViewDelegate]. + * Default implementation of [SessionViewDelegate]. * If no customisation is required, this is the preferred way to use Tangem SDK. */ -class DefaultCardSessionViewDelegate(private val reader: NfcReader) : CardSessionViewDelegate { +class DefaultSessionViewDelegate(private val reader: NfcReader) : SessionViewDelegate { lateinit var activity: FragmentActivity private var readingDialog: BottomSheetDialog? = null diff --git a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdk.kt b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdk.kt index 90a47a9d29..f69b7c96cf 100644 --- a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdk.kt +++ b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdk.kt @@ -2,7 +2,7 @@ package com.tangem.tangem_sdk_new.extensions import androidx.fragment.app.FragmentActivity import com.tangem.TangemSdk -import com.tangem.tangem_sdk_new.DefaultCardSessionViewDelegate +import com.tangem.tangem_sdk_new.DefaultSessionViewDelegate import com.tangem.tangem_sdk_new.NfcLifecycleObserver import com.tangem.tangem_sdk_new.TerminalKeysStorage import com.tangem.tangem_sdk_new.nfc.NfcManager @@ -12,7 +12,7 @@ fun TangemSdk.Companion.init(activity: FragmentActivity): TangemSdk { this.setCurrentActivity(activity) activity.lifecycle.addObserver(NfcLifecycleObserver(this)) } - val viewDelegate = DefaultCardSessionViewDelegate(nfcManager.reader).apply { + val viewDelegate = DefaultSessionViewDelegate(nfcManager.reader).apply { this.activity = activity } return TangemSdk(nfcManager.reader, viewDelegate).apply {