Updated on 2026-08-14

This commit is contained in:
Tangem 2020-04-10 18:22:35 +03:00
parent 47b2de0b22
commit 2b2413cb14
24 changed files with 111 additions and 115 deletions

View file

@ -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)

View file

@ -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<T : CommandResponse> {
* 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

View file

@ -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
)

View file

@ -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,

View file

@ -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.

View file

@ -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<Card>) -> Unit) {
cardSession = CardSession(buildEnvironment(), reader, viewDelegate)
cardSession!!.startWithRunnable(ScanTask(), callback)
fun scanCard(initialMessage: Message? = null, callback: (result: CompletionResult<Card>) -> 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<ByteArray>, cardId: String,
fun sign(hashes: Array<ByteArray>, cardId: String, initialMessage: Message? = null,
callback: (result: CompletionResult<SignResponse>) -> 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<ReadIssuerDataResponse>) -> 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<ReadIssuerExtraDataResponse>) -> 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<WriteIssuerDataResponse>) -> 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<WriteIssuerDataResponse>) -> 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<WriteUserDataResponse>) -> 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<ReadUserDataResponse>) -> Unit) {
cardSession = CardSession(buildEnvironment(), reader, viewDelegate, cardId)
cardSession!!.startWithRunnable(ReadUserDataCommand(), callback)
fun readUserData(cardId: String, initialMessage: Message? = null,
callback: (result: CompletionResult<ReadUserDataResponse>) -> 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<CreateWalletResponse>) -> 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<PurgeWalletResponse>) -> 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<DepersonalizeResponse>) -> 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<Card>) -> 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 <T : CommandResponse> startSession(
runnable: CardSessionRunnable<T>, cardId: String? = null, initialMessage: Message? = null,
callback: (result: CompletionResult<T>) -> 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 <T : CommandResponse> 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
)
}

View file

@ -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()

View file

@ -22,20 +22,20 @@ abstract class Command<T : CommandResponse> : CardSessionRunnable<T> {
/**
* 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<T>) -> Unit) {
transceive(session, callback)
@ -92,9 +92,8 @@ abstract class Command<T : CommandResponse> : CardSessionRunnable<T> {
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<T : CommandResponse> : CardSessionRunnable<T> {
*
* @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
}

View file

@ -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<CreateWalletResponse>() {
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<CreateWalletResponse>() {
)
}
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()

View file

@ -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<OpenSessionResponse>() {
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<OpenSessi
)
}
override fun deserialize(environment: CardEnvironment, apdu: ResponseApdu): OpenSessionResponse {
override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): OpenSessionResponse {
val tlvData = apdu.getTlvData()
?: throw SessionError.DeserializeApduFailed()

View file

@ -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
@ -29,7 +29,7 @@ class PurgeWalletResponse(
*/
class PurgeWalletCommand : Command<PurgeWalletResponse>() {
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<PurgeWalletResponse>() {
)
}
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()

View file

@ -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<Card>() {
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 cards 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<Card>() {
)
}
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()

View file

@ -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()

View file

@ -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()

View file

@ -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<ReadUserDataResponse>() {
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<ReadUserDataResponse>() {
)
}
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()

View file

@ -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<ByteArray>)
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<ByteArray>)
* (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<ByteArray>)
}
}
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()

View file

@ -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()

View file

@ -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()

View file

@ -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<WriteUserDataResponse>() {
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))

View file

@ -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<DepersonalizeResponse>() {
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)
}
}

View file

@ -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<Card>() {
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()

View file

@ -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
}
}

View file

@ -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

View file

@ -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 {