diff --git a/tangem-core/src/main/java/com/tangem/TangemSdkError.kt b/tangem-core/src/main/java/com/tangem/TangemSdkError.kt index 9e35b75edd..d58771fc77 100644 --- a/tangem-core/src/main/java/com/tangem/TangemSdkError.kt +++ b/tangem-core/src/main/java/com/tangem/TangemSdkError.kt @@ -105,7 +105,7 @@ sealed class TangemSdkError(val code: Int) : Exception(code.toString()) { class TooManyHashesInOneTransaction : TangemSdkError(40906) //Write Extra Issuer Data Errors - class ExendedDataSizeTooLarge : TangemSdkError(41101) + class ExtendedDataSizeTooLarge : TangemSdkError(41101) //General Errors class NotPersonalized() : TangemSdkError(40001) 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 09b6f08b94..672ca2da62 100644 --- a/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt @@ -70,19 +70,14 @@ class CheckWalletCommand( } } - override fun performPreCheck( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ): Boolean { - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.status == CardStatus.NotPersonalized) { + return TangemSdkError.NotPersonalized() } - if (session.environment.card?.isActivated == true) { - callback(CompletionResult.Failure(TangemSdkError.NotActivated())) - return true + if (card.isActivated) { + return TangemSdkError.NotActivated() } - return false + return null } override fun serialize(environment: SessionEnvironment): CommandApdu { 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 96343045a1..860b954ebf 100644 --- a/tangem-core/src/main/java/com/tangem/commands/Command.kt +++ b/tangem-core/src/main/java/com/tangem/commands/Command.kt @@ -41,47 +41,46 @@ abstract class Command : ApduSerializable, CardSessionRu override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { Log.i("Command", "Initializing ${this::class.java.simpleName}") - if (session.environment.handleErrors) { - if (performPreCheck(session, callback)) return - } - transceive(session) { result -> - if (session.environment.handleErrors) { - if (performAfterCheck(session, result, callback)) return@transceive - } - callback(result) - } + transceive(session, callback) } - open fun performPreCheck( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ): Boolean { - return false - } + open fun performPreCheck(card: Card): TangemSdkError? = null - open fun performAfterCheck( - session: CardSession, - result: CompletionResult, - callback: (result: CompletionResult) -> Unit - ): Boolean { - return false - } + open fun performAfterCheck(card: Card?, error: TangemSdkError): TangemSdkError? = error fun transceive(session: CardSession, callback: (result: CompletionResult) -> Unit) { - try { - val apdu = serialize(session.environment) - transceiveApdu(apdu, session) { result -> - when (result) { - is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) - is CompletionResult.Success -> { + + val card = session.environment.card + if (session.environment.handleErrors && card != null) { + performPreCheck(card)?.let { error -> + callback(CompletionResult.Failure(error)) + return + } + } + + val apdu = serialize(session.environment) + transceiveApdu(apdu, session) { result -> + when (result) { + is CompletionResult.Failure -> { + if (session.environment.handleErrors) { + performAfterCheck(session.environment.card, result.error)?.let { + callback(CompletionResult.Failure(it)) + return@transceiveApdu + } + } + callback(CompletionResult.Failure(result.error)) + } + is CompletionResult.Success -> { + try { val response = deserialize(session.environment, result.data) callback(CompletionResult.Success(response)) + } catch (error: TangemSdkError) { + callback(CompletionResult.Failure(error)) } } } - } catch (error: TangemSdkError) { - callback(CompletionResult.Failure(error)) } + } private fun transceiveApdu( 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 dba1b085d9..6d0bab7883 100644 --- a/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt @@ -1,9 +1,7 @@ package com.tangem.commands -import com.tangem.CardSession import com.tangem.SessionEnvironment import com.tangem.TangemSdkError -import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu @@ -12,18 +10,18 @@ import com.tangem.common.tlv.TlvDecoder import com.tangem.common.tlv.TlvTag class CreateWalletResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, - /** - * Current status of the card [1 - Empty, 2 - Loaded, 3- Purged] - */ - val status: CardStatus, - /** + /** + * CID, Unique Tangem card ID number. + */ + val cardId: String, + /** + * Current status of the card [1 - Empty, 2 - Loaded, 3- Purged] + */ + val status: CardStatus, + /** - */ - val walletPublicKey: ByteArray + */ + val walletPublicKey: ByteArray ) : CommandResponse /** @@ -39,39 +37,25 @@ class CreateWalletResponse( */ class CreateWalletCommand : Command() { - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.isActivated) { + return TangemSdkError.NotActivated() } - if (session.environment.card?.isActivated == true) { - callback(CompletionResult.Failure(TangemSdkError.NotActivated())) - return true + + return when (card.status) { + CardStatus.Empty -> null + CardStatus.NotPersonalized -> TangemSdkError.NotPersonalized() + CardStatus.Loaded -> TangemSdkError.AlreadyCreated() + CardStatus.Purged -> TangemSdkError.CardIsPurged() + null -> TangemSdkError.CardError() } - if (session.environment.card?.status == CardStatus.Purged) { - callback(CompletionResult.Failure(TangemSdkError.CardIsPurged())) - return true - } - if (session.environment.card?.status == CardStatus.Loaded) { - callback(CompletionResult.Failure(TangemSdkError.AlreadyCreated())) - return true - } - return false } - override fun performAfterCheck(session: CardSession, - result: CompletionResult, - callback: (result: CompletionResult) -> Unit): Boolean { - when (result) { - is CompletionResult.Failure -> { - if (result.error is TangemSdkError.InvalidParams) { - callback(CompletionResult.Failure(TangemSdkError.Pin2OrCvcRequired())) - return true - } - return false - } - else -> return false + override fun performAfterCheck(card: Card?, error: TangemSdkError): TangemSdkError? { + if (error is TangemSdkError.InvalidParams) { + return TangemSdkError.Pin2OrCvcRequired() } + return null } override fun serialize(environment: SessionEnvironment): CommandApdu { @@ -83,15 +67,18 @@ class CreateWalletCommand : Command() { return CommandApdu(Instruction.CreateWallet, tlvBuilder.serialize()) } - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): CreateWalletResponse { + override fun deserialize( + environment: SessionEnvironment, + apdu: ResponseApdu + ): CreateWalletResponse { val tlvData = apdu.getTlvData() - ?: throw TangemSdkError.DeserializeApduFailed() + ?: throw TangemSdkError.DeserializeApduFailed() val decoder = TlvDecoder(tlvData) return CreateWalletResponse( - cardId = decoder.decode(TlvTag.CardId), - status = decoder.decode(TlvTag.Status), - walletPublicKey = decoder.decode(TlvTag.WalletPublicKey) + cardId = decoder.decode(TlvTag.CardId), + status = decoder.decode(TlvTag.Status), + walletPublicKey = decoder.decode(TlvTag.WalletPublicKey) ) } } \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/PurgeWalletCommand.kt b/tangem-core/src/main/java/com/tangem/commands/PurgeWalletCommand.kt index f1277e8220..3ec6ff7315 100644 --- a/tangem-core/src/main/java/com/tangem/commands/PurgeWalletCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/PurgeWalletCommand.kt @@ -1,9 +1,7 @@ package com.tangem.commands -import com.tangem.CardSession import com.tangem.SessionEnvironment import com.tangem.TangemSdkError -import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu @@ -31,37 +29,33 @@ class PurgeWalletResponse( */ class PurgeWalletCommand : Command() { - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.status == CardStatus.NotPersonalized) { + return TangemSdkError.NotPersonalized() } - if (session.environment.card?.isActivated == true) { - callback(CompletionResult.Failure(TangemSdkError.NotActivated())) - return true + if (card.isActivated) { + return TangemSdkError.NotActivated() } - if (session.environment.card?.settingsMask?.contains(Settings.ProhibitPurgeWallet) == true) { - callback(CompletionResult.Failure(TangemSdkError.PurgeWalletProhibited())) - return true + if (card.settingsMask?.contains(Settings.ProhibitPurgeWallet) == true) { + return TangemSdkError.PurgeWalletProhibited() + } + + return when (card.status) { + CardStatus.Loaded -> null + CardStatus.NotPersonalized -> TangemSdkError.NotPersonalized() + CardStatus.Empty, CardStatus.Purged -> TangemSdkError.CardIsEmpty() + null -> TangemSdkError.CardError() } - return false } - override fun performAfterCheck(session: CardSession, - result: CompletionResult, - callback: (result: CompletionResult) -> Unit): Boolean { - when (result) { - is CompletionResult.Failure -> { - if (result.error is TangemSdkError.InvalidParams) { - callback(CompletionResult.Failure(TangemSdkError.Pin2OrCvcRequired())) - return true - } - return false - } - else -> return false + override fun performAfterCheck(card: Card?, error: TangemSdkError): TangemSdkError? { + if (error is TangemSdkError.InvalidParams) { + return TangemSdkError.Pin2OrCvcRequired() } + return null } + override fun serialize(environment: SessionEnvironment): CommandApdu { val tlvBuilder = TlvBuilder() tlvBuilder.append(TlvTag.Pin, environment.pin1) 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 3c6aa19bff..d0efbf78bd 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt @@ -1,10 +1,8 @@ package com.tangem.commands -import com.tangem.CardSession import com.tangem.SessionEnvironment import com.tangem.TangemSdkError import com.tangem.commands.common.CardDeserializer -import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu @@ -317,6 +315,8 @@ class Card( /** * Whether the card requires issuer’s confirmation of activation. + * is "true" if the card requires activation, + * is 'false" if the card is activated or does not require activation */ val isActivated: Boolean, @@ -367,17 +367,11 @@ class Card( */ class ReadCommand : Command() { - override fun performAfterCheck(session: CardSession, result: CompletionResult, callback: (result: CompletionResult) -> Unit): Boolean { - when (result) { - is CompletionResult.Failure -> { - if (result.error is TangemSdkError.InvalidParams) { - callback(CompletionResult.Failure(TangemSdkError.Pin1Required())) - return true - } - return false - } - else -> return false + override fun performAfterCheck(card: Card?, error: TangemSdkError): TangemSdkError? { + if (error is TangemSdkError.InvalidParams) { + return TangemSdkError.Pin1Required() } + return null } override fun serialize(environment: SessionEnvironment): CommandApdu { 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 b3015b0be3..97bc306083 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt @@ -17,32 +17,32 @@ import com.tangem.common.tlv.TlvTag class ReadIssuerDataResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, + /** + * CID, Unique Tangem card ID number. + */ + val cardId: String, - /** - * Data defined by issuer. - */ - val issuerData: ByteArray, + /** + * Data defined by issuer. + */ + val issuerData: ByteArray, - /** - * Issuer’s signature of [issuerData] with Issuer Data Private Key (which is kept on card). - * Issuer’s signature of SHA256-hashed [cardId] concatenated with [issuerData]: - * SHA256([cardId] | [issuerData]). - * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] then signature of - * SHA256-hashed CID Issuer_Data concatenated with and [issuerDataCounter]: - * SHA256([cardId] | [issuerData] | [issuerDataCounter]). - */ - val issuerDataSignature: ByteArray, + /** + * Issuer’s signature of [issuerData] with Issuer Data Private Key (which is kept on card). + * Issuer’s signature of SHA256-hashed [cardId] concatenated with [issuerData]: + * SHA256([cardId] | [issuerData]). + * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] then signature of + * SHA256-hashed CID Issuer_Data concatenated with and [issuerDataCounter]: + * SHA256([cardId] | [issuerData] | [issuerDataCounter]). + */ + val issuerDataSignature: ByteArray, - /** - * An optional counter that protect issuer data against replay attack. - * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] - * then this value is mandatory and must increase on each execution of [WriteIssuerDataCommand]. - */ - val issuerDataCounter: Int? + /** + * An optional counter that protect issuer data against replay attack. + * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] + * then this value is mandatory and must increase on each execution of [WriteIssuerDataCommand]. + */ + val issuerDataCounter: Int? ) : CommandResponse @@ -54,21 +54,17 @@ class ReadIssuerDataResponse( * @property cardId CID, Unique Tangem card ID number. */ class ReadIssuerDataCommand( - val issuerPublicKey: ByteArray? = null, - verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() + val issuerPublicKey: ByteArray? = null, + verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() ) : Command(), IssuerDataVerifier by verifier { - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val card = session.environment.card - if (card == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead())) - return - } - val publicKey = issuerPublicKey ?: card.issuerPublicKey - if (publicKey == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingIssuerPubicKey())) - return - } + override fun run( + session: CardSession, + callback: (result: CompletionResult) -> Unit + ) { + + val publicKey = issuerPublicKey ?: session.environment.card?.issuerPublicKey + super.run(session) { result -> when (result) { is CompletionResult.Failure -> callback(result) @@ -78,9 +74,9 @@ class ReadIssuerDataCommand( return@run } val issuerDataToVerify = IssuerDataToVerify( - card.cardId, result.data.issuerData, result.data.issuerDataCounter + result.data.cardId, result.data.issuerData, result.data.issuerDataCounter ) - if (verify(publicKey, result.data.issuerDataSignature, issuerDataToVerify)) { + if (verify(publicKey!!, result.data.issuerDataSignature, issuerDataToVerify)) { callback(result) } else { callback(CompletionResult.Failure(TangemSdkError.VerificationFailed())) @@ -90,12 +86,12 @@ class ReadIssuerDataCommand( } } - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.status == CardStatus.NotPersonalized) { + return TangemSdkError.NotPersonalized() } - return false + issuerPublicKey ?: card.issuerPublicKey ?: return TangemSdkError.MissingIssuerPubicKey() + return null } override fun serialize(environment: SessionEnvironment): CommandApdu { @@ -106,15 +102,18 @@ class ReadIssuerDataCommand( return CommandApdu(Instruction.ReadIssuerData, tlvBuilder.serialize()) } - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): ReadIssuerDataResponse { + override fun deserialize( + environment: SessionEnvironment, + apdu: ResponseApdu + ): ReadIssuerDataResponse { val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() val decoder = TlvDecoder(tlvData) return ReadIssuerDataResponse( - cardId = decoder.decode(TlvTag.CardId), - issuerData = decoder.decode(TlvTag.IssuerData), - issuerDataSignature = decoder.decode(TlvTag.IssuerDataSignature), - issuerDataCounter = decoder.decodeOptional(TlvTag.IssuerDataCounter) + cardId = decoder.decode(TlvTag.CardId), + issuerData = decoder.decode(TlvTag.IssuerData), + issuerDataSignature = decoder.decode(TlvTag.IssuerDataSignature), + issuerDataCounter = decoder.decodeOptional(TlvTag.IssuerDataCounter) ) } } \ No newline at end of file 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 1f5c77b1da..cb7bba09d0 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt @@ -18,37 +18,37 @@ import java.io.ByteArrayOutputStream class ReadIssuerExtraDataResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, + /** + * CID, Unique Tangem card ID number. + */ + val cardId: String, - /** - * Size of all Issuer_Extra_Data field. - */ - val size: Int?, + /** + * Size of all Issuer_Extra_Data field. + */ + val size: Int?, - /** - * Data defined by issuer. - */ - val issuerData: ByteArray, + /** + * Data defined by issuer. + */ + val issuerData: ByteArray, - /** - * Issuer’s signature of [issuerData] with Issuer Data Private Key (which is kept on card). - * Issuer’s signature of SHA256-hashed [cardId] concatenated with [issuerData]: - * SHA256([cardId] | [issuerData]). - * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] then signature of - * SHA256-hashed CID Issuer_Data concatenated with and [issuerDataCounter]: - * SHA256([cardId] | [issuerData] | [issuerDataCounter]). - */ - val issuerDataSignature: ByteArray?, + /** + * Issuer’s signature of [issuerData] with Issuer Data Private Key (which is kept on card). + * Issuer’s signature of SHA256-hashed [cardId] concatenated with [issuerData]: + * SHA256([cardId] | [issuerData]). + * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] then signature of + * SHA256-hashed CID Issuer_Data concatenated with and [issuerDataCounter]: + * SHA256([cardId] | [issuerData] | [issuerDataCounter]). + */ + val issuerDataSignature: ByteArray?, - /** - * An optional counter that protects issuer data against replay attack. - * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] - * then this value is mandatory and must increase on each execution of [WriteIssuerDataCommand]. - */ - val issuerDataCounter: Int? + /** + * An optional counter that protects issuer data against replay attack. + * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] + * then this value is mandatory and must increase on each execution of [WriteIssuerDataCommand]. + */ + val issuerDataCounter: Int? ) : CommandResponse @@ -60,42 +60,38 @@ class ReadIssuerExtraDataResponse( * a series of these commands have to be executed to read the entire Issuer_Extra_Data. */ class ReadIssuerExtraDataCommand( - private val issuerPublicKey: ByteArray? = null, - verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() + private val issuerPublicKey: ByteArray? = null, + verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() ) : Command(), IssuerDataVerifier by verifier { private val issuerData = ByteArrayOutputStream() private var offset: Int = 0 private var issuerDataSize: Int = 0 - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val card = session.environment.card - if (card == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead())) - return + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.status == CardStatus.NotPersonalized) { + return TangemSdkError.NotPersonalized() } - val publicKey = issuerPublicKey ?: card.issuerPublicKey - if (publicKey == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingIssuerPubicKey())) - return - } - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return - } - - readIssuerData(session, card.cardId, publicKey, callback) + issuerPublicKey ?: card.issuerPublicKey ?: return TangemSdkError.MissingIssuerPubicKey() + return null } + override fun run( + session: CardSession, + callback: (result: CompletionResult) -> Unit + ) { + val publicKey = issuerPublicKey ?: session.environment.card?.issuerPublicKey + readIssuerData(session, publicKey!!, callback) + } private fun readIssuerData( - session: CardSession, - cardId: String, publicKey: ByteArray, - callback: (result: CompletionResult) -> Unit) { + session: CardSession, publicKey: ByteArray, + callback: (result: CompletionResult) -> Unit + ) { if (issuerDataSize != 0) { session.viewDelegate.onDelay( - issuerDataSize, offset, WriteIssuerExtraDataCommand.SINGLE_WRITE_SIZE + issuerDataSize, offset, WriteIssuerExtraDataCommand.SINGLE_WRITE_SIZE ) } @@ -112,9 +108,9 @@ class ReadIssuerExtraDataCommand( issuerData.write(result.data.issuerData) if (result.data.issuerDataSignature == null) { offset = issuerData.size() - readIssuerData(session, cardId, publicKey, callback) + readIssuerData(session, publicKey, callback) } else { - completeTask(result.data, cardId, publicKey, callback) + completeTask(result.data, publicKey, callback) } } is CompletionResult.Failure -> { @@ -124,21 +120,22 @@ class ReadIssuerExtraDataCommand( } } - private fun completeTask(data: ReadIssuerExtraDataResponse, - cardId: String, publicKey: ByteArray, - callback: (result: CompletionResult) -> Unit) { + private fun completeTask( + data: ReadIssuerExtraDataResponse, publicKey: ByteArray, + callback: (result: CompletionResult) -> Unit + ) { val dataToVerify = IssuerDataToVerify( - cardId, - issuerData.toByteArray(), - data.issuerDataCounter + data.cardId, + issuerData.toByteArray(), + data.issuerDataCounter ) if (verify(publicKey, data.issuerDataSignature!!, dataToVerify)) { val finalResult = ReadIssuerExtraDataResponse( - data.cardId, - issuerDataSize, - issuerData.toByteArray(), - data.issuerDataSignature, - data.issuerDataCounter + data.cardId, + issuerDataSize, + issuerData.toByteArray(), + data.issuerDataSignature, + data.issuerDataCounter ) callback(CompletionResult.Success(finalResult)) } else { @@ -155,16 +152,19 @@ class ReadIssuerExtraDataCommand( return CommandApdu(Instruction.ReadIssuerData, tlvBuilder.serialize()) } - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): ReadIssuerExtraDataResponse { + override fun deserialize( + environment: SessionEnvironment, + apdu: ResponseApdu + ): ReadIssuerExtraDataResponse { val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() val decoder = TlvDecoder(tlvData) return ReadIssuerExtraDataResponse( - cardId = decoder.decode(TlvTag.CardId), - size = decoder.decodeOptional(TlvTag.Size), - issuerData = decoder.decodeOptional(TlvTag.IssuerData) ?: byteArrayOf(), - issuerDataSignature = decoder.decodeOptional(TlvTag.IssuerDataSignature), - issuerDataCounter = decoder.decodeOptional(TlvTag.IssuerDataCounter) + cardId = decoder.decode(TlvTag.CardId), + size = decoder.decodeOptional(TlvTag.Size), + issuerData = decoder.decodeOptional(TlvTag.IssuerData) ?: byteArrayOf(), + issuerDataSignature = decoder.decodeOptional(TlvTag.IssuerDataSignature), + issuerDataCounter = decoder.decodeOptional(TlvTag.IssuerDataCounter) ) } 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 3f79960e93..2e68b631ef 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt @@ -1,9 +1,7 @@ package com.tangem.commands -import com.tangem.CardSession import com.tangem.SessionEnvironment import com.tangem.TangemSdkError -import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu @@ -51,16 +49,14 @@ class ReadUserDataResponse( */ class ReadUserDataCommand : Command() { - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.status == CardStatus.NotPersonalized) { + return TangemSdkError.NotPersonalized() } - if (session.environment.card?.isActivated == true) { - callback(CompletionResult.Failure(TangemSdkError.NotActivated())) - return true + if (card.isActivated) { + return TangemSdkError.NotActivated() } - return false + return null } override fun serialize(environment: SessionEnvironment): CommandApdu { 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 816a0cd373..b5135be2b3 100644 --- a/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt @@ -1,9 +1,7 @@ package com.tangem.commands -import com.tangem.CardSession import com.tangem.SessionEnvironment import com.tangem.TangemSdkError -import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu @@ -20,10 +18,10 @@ import com.tangem.crypto.sign * Sums up array elements within all SIGN commands */ class SignResponse( - val cardId: String, - val signature: ByteArray, - val walletRemainingSignatures: Int, - val walletSignedHashes: Int + val cardId: String, + val signature: ByteArray, + val walletRemainingSignatures: Int, + val walletSignedHashes: Int ) : CommandResponse /** @@ -32,60 +30,44 @@ class SignResponse( * @property hashes Array of transaction hashes. * @property cardId CID, Unique Tangem card ID number */ -class SignCommand(private val hashes: Array) - : Command() { +class SignCommand(private val hashes: Array) : Command() { + + //TODO: Allow signing more than 10 hashes private val hashSizes = if (hashes.isNotEmpty()) hashes.first().size else 0 - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.isActivated) { + return TangemSdkError.NotActivated() } - if (session.environment.card?.isActivated == true) { - callback(CompletionResult.Failure(TangemSdkError.NotActivated())) - return true + if (card.walletRemainingSignatures == 0) { + return TangemSdkError.NoRemainingSignatures() } - if (session.environment.card?.status == CardStatus.Purged) { - callback(CompletionResult.Failure(TangemSdkError.CardIsPurged())) - return true - } - if (session.environment.card?.status == CardStatus.Empty) { - callback(CompletionResult.Failure(TangemSdkError.CardIsEmpty())) - return true - } - if (session.environment.card?.walletRemainingSignatures == 0) { - callback(CompletionResult.Failure(TangemSdkError.NoRemainingSignatures())) - return true - } - if (session.environment.card?.signingMethods?.contains(SigningMethod.SignHash) != true) { - callback(CompletionResult.Failure(TangemSdkError.SignHashesNotAvailable())) - return true + if (card.signingMethods?.contains(SigningMethod.SignHash) != true) { + return TangemSdkError.SignHashesNotAvailable() } if (hashSizes == 0) { - callback(CompletionResult.Failure(TangemSdkError.EmptyHashes())) - return true + return TangemSdkError.EmptyHashes() } if (hashes.any { it.size != hashSizes }) { - callback(CompletionResult.Failure(TangemSdkError.HashSizeMustBeEqual())) - return true + return TangemSdkError.HashSizeMustBeEqual() + } + + return when (card.status) { + CardStatus.Loaded -> null + CardStatus.Empty -> TangemSdkError. + CardIsEmpty() + CardStatus.NotPersonalized -> TangemSdkError.NotPersonalized() + CardStatus.Purged -> TangemSdkError.CardIsPurged() + null -> TangemSdkError.CardError() } - return false } - override fun performAfterCheck(session: CardSession, - result: CompletionResult, - callback: (result: CompletionResult) -> Unit): Boolean { - when (result) { - is CompletionResult.Failure -> { - if (result.error is TangemSdkError.InvalidParams) { - callback(CompletionResult.Failure(TangemSdkError.Pin2OrCvcRequired())) - return true - } - return false - } - else -> return false + override fun performAfterCheck(card: Card?, error: TangemSdkError): TangemSdkError? { + if (error is TangemSdkError.InvalidParams) { + return TangemSdkError.Pin2OrCvcRequired() } + return null } override fun serialize(environment: SessionEnvironment): CommandApdu { @@ -103,16 +85,9 @@ class SignCommand(private val hashes: Array) } private fun flattenHashes(): ByteArray { - checkForErrors() return hashes.reduce { arr1, arr2 -> arr1 + arr2 } } - private fun checkForErrors() { - if (hashes.isEmpty()) throw TangemSdkError.EmptyHashes() - if (hashes.size > 10) throw TangemSdkError.TooManyHashesInOneTransaction() - if (hashes.any { it.size != hashSizes }) throw TangemSdkError.HashSizeMustBeEqual() - } - /** * Application can optionally submit a public key Terminal_PublicKey in [SignCommand]. * Submitted key is stored by the Tangem card if it differs from a previous submitted Terminal_PublicKey. @@ -121,7 +96,8 @@ class SignCommand(private val hashes: Array) * (this key should be generated and securily stored by the application). */ private fun addTerminalSignature( - environment: SessionEnvironment, 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) @@ -134,10 +110,10 @@ class SignCommand(private val hashes: Array) val decoder = TlvDecoder(tlvData) return SignResponse( - cardId = decoder.decode(TlvTag.CardId), - signature = decoder.decode(TlvTag.Signature), - walletRemainingSignatures = decoder.decode(TlvTag.RemainingSignatures), - walletSignedHashes = decoder.decode(TlvTag.SignedHashes) + cardId = decoder.decode(TlvTag.CardId), + signature = decoder.decode(TlvTag.Signature), + walletRemainingSignatures = decoder.decode(TlvTag.RemainingSignatures), + walletSignedHashes = decoder.decode(TlvTag.SignedHashes) ) } } \ No newline at end of file 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 e9a23afac7..68b97dbf54 100644 --- a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt @@ -1,13 +1,11 @@ package com.tangem.commands -import com.tangem.CardSession import com.tangem.SessionEnvironment import com.tangem.TangemSdkError import com.tangem.commands.common.DefaultIssuerDataVerifier import com.tangem.commands.common.IssuerDataMode import com.tangem.commands.common.IssuerDataToVerify import com.tangem.commands.common.IssuerDataVerifier -import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu @@ -16,10 +14,10 @@ import com.tangem.common.tlv.TlvDecoder import com.tangem.common.tlv.TlvTag class WriteIssuerDataResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String + /** + * CID, Unique Tangem card ID number. + */ + val cardId: String ) : CommandResponse /** @@ -33,75 +31,53 @@ class WriteIssuerDataResponse( * @property issuerDataCounter An optional counter that protect issuer data against replay attack. */ class WriteIssuerDataCommand( - private val issuerData: ByteArray, - private val issuerDataSignature: ByteArray, - private val issuerDataCounter: Int? = null, - private val issuerPublicKey: ByteArray? = null, - verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() + private val issuerData: ByteArray, + private val issuerDataSignature: ByteArray, + private val issuerDataCounter: Int? = null, + private val issuerPublicKey: ByteArray? = null, + verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() ) : Command(), IssuerDataVerifier by verifier { - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - val card = session.environment.card - if (card == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead())) - return true - } + override fun performPreCheck(card: Card): TangemSdkError? { val publicKey = issuerPublicKey ?: card.issuerPublicKey - if (publicKey == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingIssuerPubicKey())) - return true + ?: return TangemSdkError.MissingIssuerPubicKey() + + if (card.status == CardStatus.NotPersonalized) { + return TangemSdkError.NotPersonalized() } - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true - } - if (session.environment.card?.isActivated == true) { - callback(CompletionResult.Failure(TangemSdkError.NotActivated())) - return true + if (card.isActivated) { + return TangemSdkError.NotActivated() } if (issuerData.size > MAX_SIZE) { - callback(CompletionResult.Failure(TangemSdkError.DataSizeTooLarge())) - return true + return TangemSdkError.DataSizeTooLarge() } if (!isCounterValid(issuerDataCounter, card)) { - callback(CompletionResult.Failure(TangemSdkError.MissingCounter())) - return true + return TangemSdkError.MissingCounter() } if (!verifySignature(publicKey, card.cardId)) { - callback(CompletionResult.Failure(TangemSdkError.VerificationFailed())) - return true + return TangemSdkError.VerificationFailed() } - return false + return null } - override fun performAfterCheck(session: CardSession, - result: CompletionResult, - callback: (result: CompletionResult) -> Unit - ): Boolean { - when (result) { - is CompletionResult.Failure -> { - if (result.error is TangemSdkError.InvalidParams && - isCounterRequired(session.environment.card)) { - callback(CompletionResult.Failure(TangemSdkError.DataCannotBeWritten())) - return true - } - return false - } - else -> return false + override fun performAfterCheck(card: Card?, error: TangemSdkError): TangemSdkError? { + if (error is TangemSdkError.InvalidParams && isCounterRequired(card)) { + return TangemSdkError.DataCannotBeWritten() } + return null } private fun isCounterValid(issuerDataCounter: Int?, card: Card): Boolean = - if (isCounterRequired(card)) issuerDataCounter != null else true + if (isCounterRequired(card)) issuerDataCounter != null else true private fun isCounterRequired(card: Card?): Boolean = - card?.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) != false + card?.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) == true private fun verifySignature(publicKey: ByteArray, cardId: String): Boolean { return verify( - publicKey, - issuerDataSignature, - IssuerDataToVerify(cardId, issuerData, issuerDataCounter) + publicKey, + issuerDataSignature, + IssuerDataToVerify(cardId, issuerData, issuerDataCounter) ) } @@ -117,12 +93,15 @@ class WriteIssuerDataCommand( return CommandApdu(Instruction.WriteIssuerData, tlvBuilder.serialize()) } - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): WriteIssuerDataResponse { + override fun deserialize( + environment: SessionEnvironment, + apdu: ResponseApdu + ): WriteIssuerDataResponse { val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() val decoder = TlvDecoder(tlvData) return WriteIssuerDataResponse( - cardId = decoder.decode(TlvTag.CardId) + cardId = decoder.decode(TlvTag.CardId) ) } 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 5fd85d01c3..ac71e3c40c 100644 --- a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt @@ -32,89 +32,64 @@ import com.tangem.common.tlv.TlvTag * @param issuerDataCounter An optional counter that protect issuer data against replay attack. */ class WriteIssuerExtraDataCommand( - private val issuerData: ByteArray, - private val startingSignature: ByteArray, - private val finalizingSignature: ByteArray, - private val issuerDataCounter: Int? = null, - private val issuerPublicKey: ByteArray? = null, - verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() + private val issuerData: ByteArray, + private val startingSignature: ByteArray, + private val finalizingSignature: ByteArray, + private val issuerDataCounter: Int? = null, + private val issuerPublicKey: ByteArray? = null, + verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() ) : Command(), IssuerDataVerifier by verifier { var mode: IssuerDataMode = IssuerDataMode.InitializeWritingExtraData var offset: Int = 0 - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val card = session.environment.card - if (card == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead())) - return - } - val publicKey = issuerPublicKey ?: card.issuerPublicKey - if (publicKey == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingIssuerPubicKey())) - return - } - - writeIssuerData(session, card.cardId, publicKey) { response -> - when (response) { - is CompletionResult.Success -> callback(response) - is CompletionResult.Failure -> { - if (response.error is TangemSdkError.InvalidParams && isCounterRequired(card)) { - callback(CompletionResult.Failure(TangemSdkError.DataCannotBeWritten())) - return@writeIssuerData - } - if (response.error is TangemSdkError.InvalidState && - card.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) != false) { - callback(CompletionResult.Failure(TangemSdkError.OverwritingDataIsProhibited())) - return@writeIssuerData - } - } - } - } + override fun run( + session: CardSession, + callback: (result: CompletionResult) -> Unit + ) { + writeIssuerData(session, callback) } - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - val card = session.environment.card - if (card == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead())) - return true - } + override fun performPreCheck(card: Card): TangemSdkError? { val publicKey = issuerPublicKey ?: card.issuerPublicKey - if (publicKey == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingIssuerPubicKey())) - return true - } + ?: return TangemSdkError.MissingIssuerPubicKey() - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true + if (card.status == CardStatus.NotPersonalized) { + return TangemSdkError.NotPersonalized() } - if (session.environment.card?.isActivated == true) { - callback(CompletionResult.Failure(TangemSdkError.NotActivated())) - return true + if (card.isActivated) { + return TangemSdkError.NotActivated() } if (issuerData.size > MAX_SIZE) { - callback(CompletionResult.Failure(TangemSdkError.ExendedDataSizeTooLarge())) - return true + return TangemSdkError.DataSizeTooLarge() } if (!isCounterValid(issuerDataCounter, card)) { - callback(CompletionResult.Failure(TangemSdkError.MissingCounter())) - return true + return TangemSdkError.MissingCounter() } - if (!verifySignatures(card.cardId, publicKey)) { - callback(CompletionResult.Failure(TangemSdkError.VerificationFailed())) - return true + if (!verifySignatures(publicKey, card.cardId)) { + return TangemSdkError.VerificationFailed() } - return false + return null + } + + override fun performAfterCheck(card: Card?, error: TangemSdkError): TangemSdkError? { + if (error is TangemSdkError.InvalidParams && isCounterRequired(card)) { + return TangemSdkError.DataCannotBeWritten() + } + if (error is TangemSdkError.InvalidState && + card?.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) == true) { + return TangemSdkError.OverwritingDataIsProhibited() + } + return null } private fun isCounterValid(issuerDataCounter: Int?, card: Card): Boolean = - if (isCounterRequired(card)) issuerDataCounter != null else true + if (isCounterRequired(card)) issuerDataCounter != null else true - private fun isCounterRequired(card: Card): Boolean = - card.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) != false + private fun isCounterRequired(card: Card?): Boolean = + card?.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) == true - private fun verifySignatures(cardId: String, publicKey: ByteArray): Boolean { + private fun verifySignatures(publicKey: ByteArray, cardId: String): Boolean { val firstData = IssuerDataToVerify(cardId, null, issuerDataCounter, issuerData.size) val secondData = IssuerDataToVerify(cardId, issuerData, issuerDataCounter) @@ -124,13 +99,16 @@ class WriteIssuerExtraDataCommand( } private fun writeIssuerData( - session: CardSession, - cardId: String, publicKey: ByteArray, - callback: (result: CompletionResult) -> Unit + session: CardSession, + callback: (result: CompletionResult) -> Unit ) { if (mode == IssuerDataMode.WriteExtraData) { - session.viewDelegate.onDelay(issuerData.size, offset, WriteIssuerExtraDataCommand.SINGLE_WRITE_SIZE) + session.viewDelegate.onDelay( + issuerData.size, + offset, + SINGLE_WRITE_SIZE + ) } transceive(session) { result -> when (result) { @@ -138,7 +116,7 @@ class WriteIssuerExtraDataCommand( when (mode) { IssuerDataMode.InitializeWritingExtraData -> { mode = IssuerDataMode.WriteExtraData - writeIssuerData(session, cardId, publicKey, callback) + writeIssuerData(session, callback) return@transceive } IssuerDataMode.WriteExtraData -> { @@ -146,7 +124,7 @@ class WriteIssuerExtraDataCommand( if (offset >= issuerData.size) { mode = IssuerDataMode.FinalizeExtraData } - writeIssuerData(session, cardId, publicKey, callback) + writeIssuerData(session, callback) return@transceive } IssuerDataMode.FinalizeExtraData -> { @@ -155,6 +133,11 @@ class WriteIssuerExtraDataCommand( } } is CompletionResult.Failure -> { + if (session.environment.handleErrors) { + performAfterCheck(session.environment.card, result.error)?.let { + callback(CompletionResult.Failure(it)) + } + } callback(CompletionResult.Failure(result.error)) } } @@ -188,17 +171,21 @@ class WriteIssuerExtraDataCommand( } private fun getDataToWrite(): ByteArray = - issuerData.copyOfRange(offset, offset + calculatePartSize()) + issuerData.copyOfRange(offset, offset + calculatePartSize()) private fun calculatePartSize(): Int { val bytesLeft = issuerData.size - offset return if (bytesLeft < SINGLE_WRITE_SIZE) bytesLeft else SINGLE_WRITE_SIZE } - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): WriteIssuerDataResponse { + override fun deserialize( + environment: SessionEnvironment, + apdu: ResponseApdu + ): WriteIssuerDataResponse { val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - return WriteIssuerDataResponse(cardId = TlvDecoder(tlvData).decode(TlvTag.CardId) + return WriteIssuerDataResponse( + cardId = TlvDecoder(tlvData).decode(TlvTag.CardId) ) } 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 1cdac8447a..8402ad9266 100644 --- a/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt @@ -1,9 +1,7 @@ package com.tangem.commands -import com.tangem.CardSession import com.tangem.SessionEnvironment import com.tangem.TangemSdkError -import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu @@ -34,36 +32,24 @@ class WriteUserDataCommand(private val userData: ByteArray? = null, private val private val userCounter: Int? = null, private val userProtectedCounter: Int? = null) : Command() { - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - if (session.environment.card?.status == CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.NotPersonalized())) - return true + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.status == CardStatus.NotPersonalized) { + return TangemSdkError.NotPersonalized() } - if (session.environment.card?.isActivated == true) { - callback(CompletionResult.Failure(TangemSdkError.NotActivated())) - return true + if (card.isActivated) { + return TangemSdkError.NotActivated() } if (userData?.size ?: 0 > MAX_SIZE || userProtectedData?.size ?: 0 > MAX_SIZE) { - callback(CompletionResult.Failure(TangemSdkError.DataSizeTooLarge())) - return true + return TangemSdkError.DataSizeTooLarge() } - return false + return null } - override fun performAfterCheck(session: CardSession, - result: CompletionResult, - callback: (result: CompletionResult) -> Unit - ): Boolean { - when (result) { - is CompletionResult.Failure -> { - if (result.error is TangemSdkError.InvalidParams) { - callback(CompletionResult.Failure(TangemSdkError.Pin2OrCvcRequired())) - return true - } - return false - } - else -> return false + override fun performAfterCheck(card: Card?, error: TangemSdkError): TangemSdkError? { + if (error is TangemSdkError.InvalidParams) { + return TangemSdkError.Pin2OrCvcRequired() } + return null } override fun serialize(environment: SessionEnvironment): CommandApdu { 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 5648b69def..d7099728b8 100644 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt @@ -9,7 +9,6 @@ import com.tangem.commands.CardStatus import com.tangem.commands.Command import com.tangem.commands.common.CardDeserializer import com.tangem.commands.personalization.entities.* -import com.tangem.common.CompletionResult import com.tangem.common.apdu.CommandApdu import com.tangem.common.apdu.Instruction import com.tangem.common.apdu.ResponseApdu @@ -38,12 +37,11 @@ class PersonalizeCommand( private val acquirer: Acquirer? = null ) : Command() { - override fun performPreCheck(session: CardSession, callback: (result: CompletionResult) -> Unit): Boolean { - if (session.environment.card?.status != CardStatus.NotPersonalized) { - callback(CompletionResult.Failure(TangemSdkError.AlreadyPersonalized())) - return true + override fun performPreCheck(card: Card): TangemSdkError? { + if (card.status != CardStatus.NotPersonalized) { + return TangemSdkError.AlreadyPersonalized() } - return false + return null } override fun serialize(environment: SessionEnvironment): CommandApdu { diff --git a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdkError.kt b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdkError.kt index 7ef49ed0e0..29c26fa50f 100644 --- a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdkError.kt +++ b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdkError.kt @@ -40,7 +40,7 @@ fun TangemSdkError.localizedDescription(): Int { is TangemSdkError.Pin2OrCvcRequired -> R.string.error_operation is TangemSdkError.VerificationFailed -> R.string.error_verification_failed is TangemSdkError.DataSizeTooLarge -> R.string.error_data_size_too_large - is TangemSdkError.ExendedDataSizeTooLarge -> R.string.error_data_size_too_large_extended + is TangemSdkError.ExtendedDataSizeTooLarge -> R.string.error_data_size_too_large_extended is TangemSdkError.MissingCounter -> R.string.error_missing_counter is TangemSdkError.OverwritingDataIsProhibited -> R.string.error_data_cannot_be_written is TangemSdkError.DataCannotBeWritten -> R.string.error_data_cannot_be_written