Updated on 2026-08-14

This commit is contained in:
Tangem 2020-06-23 14:50:26 +03:00
parent 58e6564cc8
commit 11f0197caa
8 changed files with 22 additions and 19 deletions

View file

@ -24,13 +24,13 @@ data class SessionEnvironment(
val handleErrors: Boolean = true
) {
var isDefaultPin1: Boolean = Companion.pin1.contentEquals(DEFAULT_PIN.calculateSha256())
var isDefaultPin2: Boolean = pin2.contentEquals(DEFAULT_PIN2.calculateSha256())
var pin1: ByteArray = SessionEnvironment.pin1
private set
get() = SessionEnvironment.pin1
fun isCurrentPin1Default(): Boolean = Companion.pin1.contentEquals(DEFAULT_PIN.calculateSha256())
fun isCurrentPin2Default(): Boolean = pin2.contentEquals(DEFAULT_PIN2.calculateSha256())
fun setPin1(pin1: String) {
SessionEnvironment.pin1 = pin1.calculateSha256()
}

View file

@ -38,21 +38,11 @@ interface CommandResponse
abstract class Command<T : CommandResponse> : ApduSerializable<T>, CardSessionRunnable<T> {
override val performPreflightRead: Boolean = true
open val requiresPin2: Boolean = false
override fun run(session: CardSession, callback: (result: CompletionResult<T>) -> Unit) {
Log.i("Command", "Initializing ${this::class.java.simpleName}")
if (requiresPin2() && session.environment.isDefaultPin2) {
handlePin2(session, callback)
} else {
transceive(session, callback)
}
}
private fun Command<*>.requiresPin2(): Boolean {
return this is SignCommand || this is PurgeWalletCommand ||
this is CreateWalletCommand || this is WriteUserDataCommand
transceive(session, callback)
}
open fun performPreCheck(card: Card): TangemSdkError? = null
@ -69,6 +59,11 @@ abstract class Command<T : CommandResponse> : ApduSerializable<T>, CardSessionRu
}
}
if (requiresPin2 && session.environment.isCurrentPin2Default()) {
handlePin2(session, callback)
return
}
val apdu = serialize(session.environment)
transceiveApdu(apdu, session) { result ->
when (result) {
@ -192,7 +187,7 @@ abstract class Command<T : CommandResponse> : ApduSerializable<T>, CardSessionRu
session: CardSession,
callback: (result: CompletionResult<T>) -> Unit
) {
if (!session.environment.isDefaultPin1) {
if (!session.environment.isCurrentPin1Default()) {
session.environment.setPin1(SessionEnvironment.DEFAULT_PIN)
transceive(session, callback)
return
@ -225,7 +220,7 @@ abstract class Command<T : CommandResponse> : ApduSerializable<T>, CardSessionRu
transceive(session, callback)
} else {
session.environment.setPin2(SessionEnvironment.DEFAULT_PIN2)
transceive(session, callback)
callback(CompletionResult.Failure(TangemSdkError.Pin2OrCvcRequired()))
}
}
}

View file

@ -37,6 +37,8 @@ class CreateWalletResponse(
*/
class CreateWalletCommand : Command<CreateWalletResponse>() {
override val requiresPin2 = true
override fun performPreCheck(card: Card): TangemSdkError? {
if (card.isActivated) {
return TangemSdkError.NotActivated()

View file

@ -29,6 +29,8 @@ class PurgeWalletResponse(
*/
class PurgeWalletCommand : Command<PurgeWalletResponse>() {
override val requiresPin2 = true
override fun performPreCheck(card: Card): TangemSdkError? {
if (card.status == CardStatus.NotPersonalized) {
return TangemSdkError.NotPersonalized()

View file

@ -66,7 +66,7 @@ class SetPinCommand(
tlvBuilder.append(TlvTag.NewPin, newPin1)
tlvBuilder.append(TlvTag.NewPin2, newPin2)
tlvBuilder.append(TlvTag.NewPin3, newPin3)
return CommandApdu(Instruction.SwapPIN, tlvBuilder.serialize())
return CommandApdu(Instruction.SetPin, tlvBuilder.serialize())
}
override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): SetPinResponse {

View file

@ -32,6 +32,8 @@ class SignResponse(
*/
class SignCommand(private val hashes: Array<ByteArray>) : Command<SignResponse>() {
override val requiresPin2 = true
//TODO: Allow signing more than 10 hashes
private val hashSizes = if (hashes.isNotEmpty()) hashes.first().size else 0

View file

@ -32,6 +32,8 @@ class WriteUserDataCommand(private val userData: ByteArray? = null, private val
private val userCounter: Int? = null,
private val userProtectedCounter: Int? = null) : Command<WriteUserDataResponse>() {
override val requiresPin2 = true
override fun performPreCheck(card: Card): TangemSdkError? {
if (card.status == CardStatus.NotPersonalized) {
return TangemSdkError.NotPersonalized()

View file

@ -15,7 +15,7 @@ enum class Instruction(var code: Int) {
ReadIssuerData(0xF7),
CreateWallet(0xF8),
CheckWallet(0xF9),
SwapPIN(0xFA),
SetPin(0xFA),
Sign(0xFB),
PurgeWallet(0xFC),
Activate(0xFE),