From 7db8aa448ccb3b99aa194eb8755b3bac6ac55e58 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 14 Nov 2019 17:19:15 +0300 Subject: [PATCH] Updated on 2026-08-14 --- tangem-card-old/tangem-card-old.iml | 36 ------------------- .../src/main/java/com/tangem/CardManager.kt | 16 ++++++--- .../java/com/tangem/CardManagerDelegate.kt | 26 +++++++++++++- .../src/main/java/com/tangem/CardReader.kt | 14 +++----- .../com/tangem/commands/CheckWalletCommand.kt | 6 ++-- .../com/tangem/commands/CommandSerializer.kt | 4 +-- .../java/com/tangem/commands/ReadCommand.kt | 2 +- .../java/com/tangem/commands/SignCommand.kt | 12 ++++--- .../com/tangem/common/CompletionResult.kt | 2 +- .../com/tangem/common/apdu/CommandApdu.kt | 2 +- .../com/tangem/common/apdu/ResponseApdu.kt | 4 +-- .../java/com/tangem/common/tlv/TlvMapper.kt | 2 +- .../java/com/tangem/crypto/CryptoUtils.kt | 22 ++++++------ .../com/tangem/tasks/SingleCommandTask.kt | 2 +- .../src/main/java/com/tangem/tasks/Task.kt | 17 +++++---- 15 files changed, 77 insertions(+), 90 deletions(-) delete mode 100644 tangem-card-old/tangem-card-old.iml diff --git a/tangem-card-old/tangem-card-old.iml b/tangem-card-old/tangem-card-old.iml deleted file mode 100644 index 3571291374..0000000000 --- a/tangem-card-old/tangem-card-old.iml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/CardManager.kt b/tangem-core/src/main/java/com/tangem/CardManager.kt index 91d7d66af3..f8ac316151 100644 --- a/tangem-core/src/main/java/com/tangem/CardManager.kt +++ b/tangem-core/src/main/java/com/tangem/CardManager.kt @@ -14,7 +14,7 @@ import java.util.concurrent.Executors * @property reader is an interface that is responsible for NFC connection and * transfer of data to and from the Tangem Card. * Its default implementation, NfcCardReader, is in our tangem-sdk module. - * @property cardManagerDelegate is an interface that allows interaction with users and shows relevant UI. + * @property cardManagerDelegate An interface that allows interaction with users and shows relevant UI. * Its default implementation, DefaultCardManagerDelegate, is in our tangem-sdk module. */ class CardManager( @@ -30,7 +30,11 @@ class CardManager( } /** - * A method that allows to read a card and verify that its private key. + * To start using any card, you first need to read it using the scanCard() method. + * This method launches an NFC session, and once it’s connected with the card, + * it obtains the card data. Optionally, if the card contains a wallet (private and public key pair), + * it proves that the wallet owns a private key that corresponds to a public one. + * * It launches on the new thread a [ScanTask] that will send the following events in a callback: * [ScanEvent.OnReadEvent] after completing [com.tangem.commands.ReadCommand] * [ScanEvent.OnVerifyEvent] after completing [com.tangem.commands.CheckWalletCommand] @@ -43,8 +47,10 @@ class CardManager( } /** - * A method that allows to sign hashes (usually a blockchain transaction) with a private key - * from a Tangem card. (Please note that the private key itself never leaves the Tangem card). + * This method allows you to sign one or multiple hashes. + * Simultaneous signing of array of hashes in a single [SignCommand] is required to support + * Bitcoin-type multi-input blockchains (UTXO). + * The [SignCommand] will return a corresponding array of signatures. * * This method launches on the new thread [SignCommand] that will send the following events in a callback: * [SignResponse] after completing [SignCommand] @@ -53,7 +59,7 @@ class CardManager( * 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 [CardManagerDelegate] to notify users of security delay. - * @param hashes Array of transaction hashes. It can be a single hash or several hashes of the same length. + * @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 * @param callback * diff --git a/tangem-core/src/main/java/com/tangem/CardManagerDelegate.kt b/tangem-core/src/main/java/com/tangem/CardManagerDelegate.kt index 2492913faa..52f30a5e91 100644 --- a/tangem-core/src/main/java/com/tangem/CardManagerDelegate.kt +++ b/tangem-core/src/main/java/com/tangem/CardManagerDelegate.kt @@ -10,12 +10,36 @@ import com.tangem.tasks.TaskError */ interface CardManagerDelegate { + /** + * It is called when user is expected to scan a Tangem Card with an Android device. + */ fun onNfcSessionStarted() + + /** + * It is called when security delay is triggered by the card. + * A user is expected to hold the card until the security delay is over. + */ fun onSecurityDelay(ms: Int) + + /** + * It is called when user takes the card away from the Android device during the scanning + * (for example when security delay is in progress) and the TagLostException is received. + */ fun onTagLost() + + /** + * It is called when NFC session was completed and a user can take the card away from the Android device. + */ fun onNfcSessionCompleted() + + /** + * It is called when some error occur during NFC session. + */ fun onError(error: TaskError? = null) - fun requestPin(callback: (result: CompletionResult) -> Unit) + /** + * It is called when a user is expected to enter pin code. + */ + fun onPinRequested(callback: (result: CompletionResult) -> Unit) } \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/CardReader.kt b/tangem-core/src/main/java/com/tangem/CardReader.kt index 6b0d912eca..2327e13fe6 100644 --- a/tangem-core/src/main/java/com/tangem/CardReader.kt +++ b/tangem-core/src/main/java/com/tangem/CardReader.kt @@ -11,25 +11,19 @@ import com.tangem.common.apdu.ResponseApdu */ interface CardReader { - /** - * [com.tangem.tasks.Task] sets it to true before the first command, - * and it should be set to false on completion of the task. - */ - var readingActive: Boolean - /** * Sends data to the card and receives the reply. * - * @param apdu data to be sent. [CommandApdu] serializes it to a [ByteArray] - * @param callback returns response from the card, - * [ResponseApdu] allows to convert raw data to [Tlv] + * @param apdu Data to be sent. [CommandApdu] serializes it to a [ByteArray] + * @param callback Returns response from the card, + * [ResponseApdu] Allows to convert raw data to [Tlv] */ fun transceiveApdu(apdu: CommandApdu, callback: (response: CompletionResult) -> Unit) /** * Signals to [CardReader] to become ready to transceive data. */ - fun startNfcSession() + fun openSession() /** * Signals to [CardReader] that no further NFC transition is expected. 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 d7a2567195..32ba138970 100644 --- a/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt @@ -16,8 +16,7 @@ import com.tangem.tasks.TaskError * * @property cardId Unique Tangem card ID number * @property salt Random salt generated by the card - * @property walletSignature Signature with wallet private key of challenge and salt. - * It uses SHA256 for ‘secp256k1’ curve and SHA512 for ‘ed25519’ curve. + * @property walletSignature Challenge and salt signed with the wallet private key. */ class CheckWalletResponse( val cardId: String, @@ -29,8 +28,7 @@ class CheckWalletResponse( * This command proves that the wallet private key from the card corresponds to the wallet public key. * Standard challenge/response scheme is used. * - * @property pin1 hashed user’s pin 1 code to access the card. Default unhashed value: ‘000000’. - * Pin code should be taken from card environment. + * @property pin1 Hashed user’s pin 1 code to access the card. Default unhashed value: ‘000000’. * @property cardId Unique Tangem card ID number * @property challenge Random challenge generated by application */ diff --git a/tangem-core/src/main/java/com/tangem/commands/CommandSerializer.kt b/tangem-core/src/main/java/com/tangem/commands/CommandSerializer.kt index 0a767328c6..0835cff543 100644 --- a/tangem-core/src/main/java/com/tangem/commands/CommandSerializer.kt +++ b/tangem-core/src/main/java/com/tangem/commands/CommandSerializer.kt @@ -20,7 +20,7 @@ abstract class CommandSerializer { * Serializes data into a [List] of [com.tangem.common.tlv.Tlv], * then creates [CommandApdu] with this data. * - * @return command data that can be converted to raw bytes with a method [CommandApdu.toBytes]. + * @return Command data that can be converted to raw bytes with a method [CommandApdu.toBytes]. */ abstract fun serialize(cardEnvironment: CardEnvironment): CommandApdu @@ -28,7 +28,7 @@ abstract class CommandSerializer { * Deserializes data, received from a card and stored in [ResponseApdu], * into a [List] of [com.tangem.common.tlv.Tlv]. Then this method maps it into a [CommandResponse]. * - * @return card response, converted to a [CommandResponse] of a type [T]. + * @return Card response, converted to a [CommandResponse] of a type [T]. */ abstract fun deserialize(cardEnvironment: CardEnvironment, responseApdu: ResponseApdu): T? 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 466c8b8f23..ff8ad89e43 100644 --- a/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt @@ -71,7 +71,7 @@ enum class ProductMask(val code: Byte) { /** * Stores and maps Tangem card settings. * - * @property rawValue are card settings in a form of flags, + * @property rawValue Card settings in a form of flags, * while flags definitions and values are in [SettingsMask.Companion] as constants. */ data class SettingsMask(val rawValue: Int) { 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 db9262466b..23b021fef9 100644 --- a/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt +++ b/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt @@ -14,7 +14,7 @@ import com.tangem.tasks.TaskError /** * @param cardId CID, Unique Tangem card ID number - * @param signature signed hashes (array of resulting signatures) + * @param signature Signed hashes (array of resulting signatures) * @param remainingSignatures Remaining number of sign operations before the wallet will stop signing transactions. * @param signedHashes Total number of signed single hashes returned by the card in sign command responses. * Sums up array elements within all SIGN commands @@ -64,10 +64,12 @@ class SignCommand(private val hashes: Array, private val cardId: Stri } /** - * Adds to the command data the terminal public key (generated by the application) and - * transaction hashes signed by the terminal private key. - * This allows to link the card to the Android device and skip security delay. - * (as described in Linked Terminal section of the Tangem Card Manual). +d + * 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. + * The Tangem card will not enforce security delay if [SignCommand] will be called with + * TerminalTransactionSignature parameter containing a correct signature of raw data to be signed made with TerminalPrivateKey + * (this key should be generated and securily stored by the application). */ private fun addTerminalSignature(cardEnvironment: CardEnvironment, tlvData: MutableList) { cardEnvironment.terminalKeys?.let { terminalKeyPair -> diff --git a/tangem-core/src/main/java/com/tangem/common/CompletionResult.kt b/tangem-core/src/main/java/com/tangem/common/CompletionResult.kt index 4ee035c5ba..afd76a39e8 100644 --- a/tangem-core/src/main/java/com/tangem/common/CompletionResult.kt +++ b/tangem-core/src/main/java/com/tangem/common/CompletionResult.kt @@ -5,7 +5,7 @@ import com.tangem.tasks.TaskError /** * Response class encapsulating successful and failed results. - * [T] is a type of data that is returned in [Success]. + * @param T Type of data that is returned in [Success]. */ sealed class CompletionResult { class Success(val data: T) : CompletionResult() diff --git a/tangem-core/src/main/java/com/tangem/common/apdu/CommandApdu.kt b/tangem-core/src/main/java/com/tangem/common/apdu/CommandApdu.kt index 97fb84652c..f72fa4d0ae 100644 --- a/tangem-core/src/main/java/com/tangem/common/apdu/CommandApdu.kt +++ b/tangem-core/src/main/java/com/tangem/common/apdu/CommandApdu.kt @@ -10,7 +10,7 @@ import java.io.ByteArrayOutputStream * to a raw data that can be sent to the card. * * @property ins Instruction code that determines the type of request for the card. - * @property tlvList list of TLVs that are to be sent to the card + * @property tlvList A list of TLVs that are to be sent to the card */ class CommandApdu( diff --git a/tangem-core/src/main/java/com/tangem/common/apdu/ResponseApdu.kt b/tangem-core/src/main/java/com/tangem/common/apdu/ResponseApdu.kt index 9100322c8a..6141512855 100644 --- a/tangem-core/src/main/java/com/tangem/common/apdu/ResponseApdu.kt +++ b/tangem-core/src/main/java/com/tangem/common/apdu/ResponseApdu.kt @@ -5,9 +5,9 @@ import com.tangem.common.tlv.Tlv /** * Stores response data from the card and parses it to [Tlv] and [StatusWord]. * - * @property data raw response from the card. + * @property data Raw response from the card. * @property sw Status word code, reflecting the status of the response. - * @property statusWord parsed status word. + * @property statusWord Parsed status word. */ class ResponseApdu(val data: ByteArray) { diff --git a/tangem-core/src/main/java/com/tangem/common/tlv/TlvMapper.kt b/tangem-core/src/main/java/com/tangem/common/tlv/TlvMapper.kt index bd2efe73dd..5829f0600a 100644 --- a/tangem-core/src/main/java/com/tangem/common/tlv/TlvMapper.kt +++ b/tangem-core/src/main/java/com/tangem/common/tlv/TlvMapper.kt @@ -28,7 +28,7 @@ class TlvMapper(val tlvList: List) { * * @param tag [TlvTag] of a [Tlv] which value is to be returned. * - * @return value converted to a nullable type [T]. + * @return Value converted to a nullable type [T]. */ inline fun mapOptional(tag: TlvTag): T? = try { diff --git a/tangem-core/src/main/java/com/tangem/crypto/CryptoUtils.kt b/tangem-core/src/main/java/com/tangem/crypto/CryptoUtils.kt index e202fb2727..32742a3076 100644 --- a/tangem-core/src/main/java/com/tangem/crypto/CryptoUtils.kt +++ b/tangem-core/src/main/java/com/tangem/crypto/CryptoUtils.kt @@ -30,12 +30,12 @@ object CryptoUtils { * Helper function to verify that the data was signed with a private key that corresponds * to the provided public key. * - * @param publicKey public key corresponding to the private key that was used to sing a message - * @param message the data that was signed - * @param signature signed data - * @param curve elliptic curve used + * @param publicKey Corresponding to the private key that was used to sing a message + * @param message The data that was signed + * @param signature Signed data + * @param curve Elliptic curve used * - * @return result of a verification + * @return Result of a verification */ fun verify(publicKey: ByteArray, message: ByteArray, signature: ByteArray, curve: EllipticCurve = EllipticCurve.Secp256k1): Boolean { @@ -48,10 +48,10 @@ object CryptoUtils { /** * Helper function that generates public key from a private key. * - * @param privateKeyArray a private key from which a public key is generated - * @param curve elliptic curve used + * @param privateKeyArray A private key from which a public key is generated + * @param curve Elliptic curve used * - * @return public key [ByteArray] + * @return Public key [ByteArray] */ fun generatePublicKey( privateKeyArray: ByteArray, @@ -67,10 +67,10 @@ object CryptoUtils { /** * Extension function to sign a ByteArray with an elliptic curve cryptography. * - * @param privateKeyArray key to sign data - * @param curve curve that is used to sign data + * @param privateKeyArray Key to sign data + * @param curve Elliptic curve that is used to sign data * - * @return signed data + * @return Signed data */ fun ByteArray.sign(privateKeyArray: ByteArray, curve: EllipticCurve = EllipticCurve.Secp256k1): ByteArray { return when (curve) { diff --git a/tangem-core/src/main/java/com/tangem/tasks/SingleCommandTask.kt b/tangem-core/src/main/java/com/tangem/tasks/SingleCommandTask.kt index 6c83f6a9de..34ed9b0a69 100644 --- a/tangem-core/src/main/java/com/tangem/tasks/SingleCommandTask.kt +++ b/tangem-core/src/main/java/com/tangem/tasks/SingleCommandTask.kt @@ -8,7 +8,7 @@ import com.tangem.common.CompletionResult /** * Allows to perform a single command. * - * @property command is a command that will be performed. + * @property command A command that will be performed. */ class SingleCommandTask( private val command: CommandSerializer diff --git a/tangem-core/src/main/java/com/tangem/tasks/Task.kt b/tangem-core/src/main/java/com/tangem/tasks/Task.kt index c00995e180..3998586946 100644 --- a/tangem-core/src/main/java/com/tangem/tasks/Task.kt +++ b/tangem-core/src/main/java/com/tangem/tasks/Task.kt @@ -41,13 +41,12 @@ sealed class TaskError(description: String? = null) : Exception(description) { } /** - * Events that are are sent in callbacks from [Task] during [Task] and Commands completions. + * Events that are are sent in callbacks from [Task]. */ sealed class TaskEvent { /** - * A callback that is triggered when a command returns response from a card - * (on a completion of a [CommandSerializer]). + * A callback that is triggered by a Task. */ class Event(val data: T) : TaskEvent() @@ -72,13 +71,13 @@ abstract class Task { /** * This method should be called to run the [Task] and perform all its operations. * - * @param cardEnvironment is a relevant current version of a card environment - * @param callback is a callback that will be triggered during the performance of the [Task] + * @param cardEnvironment Relevant current version of a card environment + * @param callback It will be triggered during the performance of the [Task] */ fun run(cardEnvironment: CardEnvironment, callback: (result: TaskEvent) -> Unit) { delegate?.onNfcSessionStarted() - reader?.startNfcSession() + reader?.openSession() Log.i(this::class.simpleName!!, "Nfc task is started") onRun(cardEnvironment, callback) } @@ -86,8 +85,8 @@ abstract class Task { /** * Should be called on [Task] completion, whether it was successful or with failure. * - * @param withError is true when there is an error - * @param taskError the error to be shown by [CardManagerDelegate] + * @param withError True when there is an error + * @param taskError The error to be shown by [CardManagerDelegate] */ protected fun completeNfcSession(withError: Boolean = false, taskError: TaskError? = null) { reader?.closeSession() @@ -161,7 +160,7 @@ abstract class Task { delegate?.onTagLost() } else if (result.error is TaskError.UserCancelledError) { callback(CompletionResult.Failure(TaskError.UserCancelledError())) - reader?.readingActive = false + reader?.closeSession() } } }