Updated on 2026-08-14
This commit is contained in:
parent
156ab295eb
commit
ddf613590c
14 changed files with 165 additions and 167 deletions
|
|
@ -61,6 +61,17 @@
|
|||
"transactionKey": {
|
||||
"publicKey": "04ECA685AFD135EF2AB24D07BED71ED82CC1882C282976616DAC655ED3E5B8E75487C131F5D79A87895ECDE89AC58CD1BB220A0C29DD544D8D9AD5156184456F3F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "CARDANO",
|
||||
"dataKey": {
|
||||
"publicKey": "0445C312089E57A6952F96D74FF75C962E1E2C2DDA5FB4195661B92E2744791350FE6C60E1A1D145C6A34D8BEAD57506A90FE4A149A9AA43CFF3C6CAE0748B771E",
|
||||
"privateKeyEncrypted": "2791FA18DFD4D2AD11509266C4721CE9BB4E9C7C8A06BF5071C6294EAB1F47A153CFDEBAF804425E5ED49AFEB70DD741"
|
||||
},
|
||||
"transactionKey": {
|
||||
"publicKey": "04969A008E8A61F92EF8D380DB7BB7B8F6F667CA169934371F544F6697D1D2AF97FB87B8D75F550CD782472D46BFCADF354AF17D807C1D2EB82E184C367CACF1FC",
|
||||
"privateKeyEncrypted": "4707EEB8704D53EB1B6D905604C394D1514C205E3EC16423961BB82A7A47896783F8035BE56D6DAE5DE200E67F2D92E3"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.card_common.data.Issuer
|
|||
import com.tangem.data.dp.PrefsManager
|
||||
import com.tangem.di.*
|
||||
import com.tangem.server_android.data.LocalStorage
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import java.io.InputStreamReader
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
|
|
@ -55,6 +56,24 @@ class App : Application() {
|
|||
localStorage = LocalStorage(applicationContext)
|
||||
pinStorage = PINStorage()
|
||||
pendingTransactionsStorage = PendingTransactionsStorage(applicationContext)
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
com.tangem.card_common.util.Log.setLogger(
|
||||
object : com.tangem.card_common.util.LoggerInterface {
|
||||
override fun i(logTag: String, message: String) {
|
||||
android.util.Log.i(logTag, message)
|
||||
}
|
||||
|
||||
override fun e(logTag: String, message: String) {
|
||||
android.util.Log.e(logTag, message)
|
||||
}
|
||||
|
||||
override fun v(logTag: String, message: String) {
|
||||
android.util.Log.v(logTag, message)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildNavigatorComponent(): NavigatorComponent {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ object CoinEngineFactory {
|
|||
fun createCardano(context: TangemContext): CoinEngine? {
|
||||
var result: CoinEngine?
|
||||
try {
|
||||
result = EthEngine(context)// CardanoEngine(context)
|
||||
result = CardanoEngine(context)//EthEngine(context)//
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
result = null
|
||||
|
|
@ -85,11 +86,10 @@ object CoinEngineFactory {
|
|||
}
|
||||
|
||||
fun createCardanoData(): CoinData? {
|
||||
return CardanoData()
|
||||
return CardanoData()//EthData()// CardanoData()
|
||||
}
|
||||
|
||||
fun isCardano(blockchainID: String): Boolean {
|
||||
return blockchainID == Blockchain.Cardano.id
|
||||
return blockchainID==Blockchain.Cardano.id//Ethereum.id
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -81,7 +81,6 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
|
||||
private var unsuccessReadCount = 0
|
||||
private var lastTag: Tag? = null
|
||||
// private var readCardInfoTask: ReadCardInfoTask? = null
|
||||
private var task: CustomReadCardTask? = null
|
||||
private var onNfcReaderCallback: NfcAdapter.ReaderCallback? = null
|
||||
|
||||
|
|
@ -246,76 +245,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
|
||||
lastTag = tag
|
||||
|
||||
// readCardInfoTask = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
|
||||
//readCardInfoTask?.start()
|
||||
val tx: OneTouchSignTask.TransactionToSign = object : OneTouchSignTask.TransactionToSign {
|
||||
var txToSign: SignTask.TransactionToSign?=null
|
||||
var ctx: TangemContext?=null
|
||||
var coinEngine: CoinEngine?=null
|
||||
val amount: CoinEngine.Amount=CoinEngine.Amount(10,"")
|
||||
val fee: CoinEngine.Amount=CoinEngine.Amount(1,"")
|
||||
val incFee: Boolean = true
|
||||
val targetAddress: String = "aaaa"
|
||||
|
||||
suspend fun requestBalanceAndUnspentTransactions(): Boolean = suspendCoroutine { cont ->
|
||||
coinEngine!!.requestBalanceAndUnspentTransactions(object : CoinEngine.BlockchainRequestsCallbacks {
|
||||
override fun onComplete(success: Boolean?) {
|
||||
cont.resume(success!!)
|
||||
}
|
||||
|
||||
override fun onProgress() {
|
||||
}
|
||||
|
||||
override fun allowAdvance(): Boolean {
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun initData(card: TangemCard)
|
||||
{
|
||||
if( ctx==null ) ctx= TangemContext(card)
|
||||
if( coinEngine==null ) {
|
||||
coinEngine=CoinEngineFactory.createCardano(ctx!!)!!
|
||||
coinEngine!!.defineWallet()
|
||||
runBlocking { requestBalanceAndUnspentTransactions() }
|
||||
Log.e(TAG, "requestBalanceAndUnspentTransactions completed")
|
||||
}
|
||||
if( txToSign==null ) txToSign=coinEngine!!.constructTransaction(amount,fee,true, targetAddress)
|
||||
}
|
||||
|
||||
override fun isSigningOnCardSupported(card: TangemCard?): Boolean {
|
||||
initData(card!!)
|
||||
return (card?.blockchainID==Blockchain.Cardano.id)and(txToSign!!.isSigningMethodSupported(card?.signingMethod))
|
||||
}
|
||||
|
||||
override fun getHashesToSign(card: TangemCard?): Array<ByteArray> {
|
||||
initData(card!!)
|
||||
return txToSign!!.hashesToSign
|
||||
}
|
||||
|
||||
override fun getRawDataToSign(card: TangemCard?): ByteArray {
|
||||
initData(card!!)
|
||||
return txToSign!!.rawDataToSign
|
||||
}
|
||||
|
||||
override fun getHashAlgToSign(card: TangemCard?): String {
|
||||
initData(card!!)
|
||||
return txToSign!!.hashAlgToSign
|
||||
}
|
||||
|
||||
override fun getIssuerTransactionSignature(card: TangemCard?, dataToSignByIssuer: ByteArray?): ByteArray {
|
||||
initData(card!!)
|
||||
return txToSign!!.getIssuerTransactionSignature(dataToSignByIssuer)
|
||||
}
|
||||
|
||||
override fun onSignCompleted(card: TangemCard?, signature: ByteArray?) {
|
||||
initData(card!!)
|
||||
txToSign!!.onSignCompleted(signature)
|
||||
}
|
||||
|
||||
}
|
||||
task = OneTouchSignTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, tx)
|
||||
task = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
|
||||
task?.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import android.view.View;
|
|||
import android.view.WindowManager;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.tangem.card_common.util.Log;
|
||||
import com.tangem.wallet.R;
|
||||
|
||||
import java.util.Timer;
|
||||
|
|
@ -104,22 +105,39 @@ public class WaitSecurityDelayDialog extends DialogFragment {
|
|||
}
|
||||
|
||||
public static void onReadWait(final AppCompatActivity activity, final int msec) {
|
||||
Log.e(TAG, "onReadWait callback(" + msec + ")");
|
||||
activity.runOnUiThread(() -> {
|
||||
Log.e(TAG, "onReadWait on ui thread(" + msec + ")");
|
||||
if (timerToShowDelayDialog != null) {
|
||||
timerToShowDelayDialog.cancel();
|
||||
timerToShowDelayDialog = null;
|
||||
}
|
||||
|
||||
if (msec == 0) {
|
||||
if (instance != null && instance.isAdded()) {
|
||||
instance.dismiss();
|
||||
instance = null;
|
||||
if (instance != null) {
|
||||
if (instance.isAdded()) {
|
||||
instance.dismiss();
|
||||
instance = null;
|
||||
} else {
|
||||
Log.e(TAG, "onReadWait(0) with not added dialog");
|
||||
// instance.progressBar.postDelayed(() -> {
|
||||
// Log.e(TAG, "onReadWait(0) dismiss delayed");
|
||||
try {
|
||||
instance.dismiss();
|
||||
instance = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
// }, 10000);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance == null) {
|
||||
if (msec > minRemainingDelayToShowDialog) {
|
||||
if (msec > delayBeforeShowDialog + minRemainingDelayToShowDialog) {
|
||||
instance = new WaitSecurityDelayDialog();
|
||||
// 1000ms - card delay notification interval
|
||||
instance.setup(msec + 1000, 1000);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
|
|||
btnSend.visibility = View.INVISIBLE
|
||||
|
||||
if (!engine.allowSelectFeeLevel()) {
|
||||
rgFee.visibility = View.INVISIBLE
|
||||
rgFee.visibility = View.GONE
|
||||
}
|
||||
|
||||
// set listeners
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.tangem.card_android.data.EXTRA_TANGEM_CARD
|
|||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.card_android.data.asBundle
|
||||
import com.tangem.card_common.data.TangemCard
|
||||
import com.tangem.card_common.reader.CardCrypto
|
||||
import com.tangem.card_common.reader.CardProtocol
|
||||
import com.tangem.card_common.tasks.CustomReadCardTask
|
||||
import com.tangem.card_common.tasks.OneTouchSignTask
|
||||
|
|
@ -123,13 +124,7 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
try {
|
||||
// get IsoDep handle and run cardReader thread
|
||||
val isoDep = IsoDep.get(tag)
|
||||
val uid = tag.id
|
||||
// val sUID = Util.byteArrayToHexString(uid)
|
||||
|
||||
// if (sUID == ctx.card.uid){
|
||||
// if (lastReadSuccess)
|
||||
// isoDep.timeout = ctx.card.pauseBeforePIN2 + 5000
|
||||
// else
|
||||
isoDep.timeout = 65000
|
||||
|
||||
val coinEngine = CoinEngineFactory.createCardano(ctx!!)!!
|
||||
|
|
@ -141,11 +136,6 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
startActivityForResult(intent, Constant.REQUEST_CODE_SEND_TRANSACTION_)
|
||||
}
|
||||
}
|
||||
// val transactionToSign = coinEngine?.constructTransaction(amount, fee, isIncludeFee, outAddressStr)
|
||||
//
|
||||
// task = SignTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, transactionToSign)
|
||||
// task?.start()
|
||||
|
||||
|
||||
val tx: OneTouchSignTask.TransactionToSign = object : OneTouchSignTask.TransactionToSign {
|
||||
var txToSign: SignTask.TransactionToSign? = null
|
||||
|
|
@ -165,9 +155,6 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
}
|
||||
|
||||
fun initData(card: TangemCard) {
|
||||
// if( ctx==null ){
|
||||
// ctx=TangemContext(card)
|
||||
// }
|
||||
if (ctx.card == null) {
|
||||
ctx.card = card
|
||||
}
|
||||
|
|
@ -178,16 +165,6 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
coinEngine.defineWallet()
|
||||
runBlocking { requestBalanceAndUnspentTransactions() }
|
||||
Log.e(MainActivity.TAG, "requestBalanceAndUnspentTransactions completed")
|
||||
|
||||
// coinEngine?.setOnNeedSendTransaction { tx ->
|
||||
// if (tx != null) {
|
||||
// val intent = Intent(this@SignTransactionActivity, SendTransactionActivity::class.java)
|
||||
// ctx!!.saveToIntent(intent)
|
||||
// intent.putExtra(Constant.EXTRA_TX, tx)
|
||||
// startActivityForResult(intent, Constant.REQUEST_CODE_SEND_TRANSACTION_)
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
if (txToSign == null) txToSign = coinEngine!!.constructTransaction(amount, fee, isIncludeFee, outAddressStr)
|
||||
}
|
||||
|
|
@ -197,6 +174,22 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
return CoinEngineFactory.isCardano(card?.blockchainID) and (txToSign!!.isSigningMethodSupported(card?.signingMethod))
|
||||
}
|
||||
|
||||
override fun isIssuerCanSignData(card: TangemCard?): Boolean {
|
||||
return try {
|
||||
card?.issuer?.privateDataKey!=null
|
||||
} catch (e: java.lang.Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun isIssuerCanSignTransaction(card: TangemCard?): Boolean {
|
||||
return try {
|
||||
card?.issuer?.privateTransactionKey!=null
|
||||
} catch (e: java.lang.Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun getHashesToSign(card: TangemCard?): Array<ByteArray> {
|
||||
initData(card!!)
|
||||
return txToSign!!.hashesToSign
|
||||
|
|
@ -214,6 +207,10 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
|
||||
override fun getIssuerTransactionSignature(card: TangemCard?, dataToSignByIssuer: ByteArray?): ByteArray {
|
||||
initData(card!!)
|
||||
if( card.issuer!=null && card.issuer.privateTransactionKey!=null)
|
||||
{
|
||||
return CardCrypto.Signature(card.issuer.privateTransactionKey, dataToSignByIssuer)
|
||||
}
|
||||
return txToSign!!.getIssuerTransactionSignature(dataToSignByIssuer)
|
||||
}
|
||||
|
||||
|
|
@ -226,9 +223,6 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
task = OneTouchSignTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, tx)
|
||||
task!!.start()
|
||||
|
||||
// } else
|
||||
// nfcManager.ignoreTag(isoDep.tag)
|
||||
|
||||
} catch (e: CardProtocol.TangemException_WrongAmount) {
|
||||
try {
|
||||
val intent = Intent()
|
||||
|
|
@ -354,36 +348,19 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
}, 500)
|
||||
}
|
||||
|
||||
// private val waitSecurityDelayDialogNew = WaitSecurityDelayDialogNew()
|
||||
|
||||
override fun onReadBeforeRequest(timeout: Int) {
|
||||
LOG.i(TAG, "onReadBeforeRequest timeout $timeout")
|
||||
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
|
||||
|
||||
// if (!waitSecurityDelayDialogNew.isAdded)
|
||||
// waitSecurityDelayDialogNew.show(supportFragmentManager, WaitSecurityDelayDialogNew.TAG)
|
||||
|
||||
|
||||
// val readBeforeRequest = ReadBeforeRequest()
|
||||
// readBeforeRequest.timeout = timeout
|
||||
// EventBus.getDefault().post(readBeforeRequest)
|
||||
}
|
||||
|
||||
override fun onReadAfterRequest() {
|
||||
LOG.i(TAG, "onReadAfterRequest")
|
||||
WaitSecurityDelayDialog.onReadAfterRequest(this)
|
||||
|
||||
// val readAfterRequest = ReadAfterRequest()
|
||||
// EventBus.getDefault().post(readAfterRequest)
|
||||
}
|
||||
|
||||
override fun onReadWait(msec: Int) {
|
||||
LOG.i(TAG, "onReadWait msec $msec")
|
||||
WaitSecurityDelayDialog.onReadWait(this, msec)
|
||||
|
||||
// val readWait = ReadWait()
|
||||
// readWait.msec = msec
|
||||
// EventBus.getDefault().post(readWait)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,6 +5,6 @@
|
|||
|
||||
<string name="verify">Confirm</string>
|
||||
<string name="send_1">Checkout</string>
|
||||
<string name="now_touch_the_banknote_with_id">Now touch banknote</string>
|
||||
<string name="now_touch_the_banknote_with_id">Now touch the banknote</string>
|
||||
|
||||
</resources>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.card_common.data;
|
||||
|
||||
import com.tangem.card_common.reader.CardCrypto;
|
||||
import com.tangem.card_common.util.PBKDF2;
|
||||
import com.tangem.card_common.util.Util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -15,11 +16,25 @@ public class Issuer {
|
|||
|
||||
static class KeyPair {
|
||||
String privateKey;
|
||||
String privateKeyEncrypted;
|
||||
String publicKey;
|
||||
|
||||
|
||||
byte[] getPrivateKey() throws Exception {
|
||||
if (privateKey != null) {
|
||||
return Util.hexToBytes(privateKey);
|
||||
} else if (privateKeyEncrypted != null) {
|
||||
byte[] A = PBKDF2.deriveKey(Util.calculateSHA256(Tangem().getPrivateTransactionKey()),Util.calculateSHA256(Tangem().getPrivateDataKey()), 100);
|
||||
//String B = Util.bytesToHex(CardCrypto.Encrypt(A, Util.hexToBytes(""), true));
|
||||
try {
|
||||
return CardCrypto.Decrypt(A, Util.hexToBytes(privateKeyEncrypted), true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
throw new Exception("No private key!");
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new Exception("No private key!");
|
||||
}
|
||||
|
|
@ -57,8 +72,7 @@ public class Issuer {
|
|||
instances.add(unknown);
|
||||
}
|
||||
|
||||
public static void fillIssuers(List<Issuer> issuers)
|
||||
{
|
||||
public static void fillIssuers(List<Issuer> issuers) {
|
||||
instances.addAll(issuers);
|
||||
}
|
||||
|
||||
|
|
@ -119,4 +133,9 @@ public class Issuer {
|
|||
public static Issuer Unknown() {
|
||||
return instances.get(0);
|
||||
}
|
||||
|
||||
public static Issuer Tangem() {
|
||||
return instances.get(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -821,9 +821,9 @@ public class CardProtocol {
|
|||
* @throws Exception - if something went wrong
|
||||
*/
|
||||
public TLVList run_SignHashes(String PIN2, byte[][] hashes, byte[] issuerTransactionSignature, byte[] issuerData, byte[] issuerDataSignature) throws Exception {
|
||||
if (mCard.getSigningMethod() != TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer && mCard.getSigningMethod() != TangemCard.SigningMethod.Sign_Hash) {
|
||||
throw new TangemException("Card don't support signing hashes!");
|
||||
}
|
||||
// if (mCard.getSigningMethod() != TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer && mCard.getSigningMethod() != TangemCard.SigningMethod.Sign_Hash) {
|
||||
// throw new TangemException("Card don't support signing hashes!");
|
||||
// }
|
||||
|
||||
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||
if (hashes.length > 10) throw new TangemException("To much hashes in one transaction!");
|
||||
|
|
@ -837,7 +837,7 @@ public class CardProtocol {
|
|||
rqApdu.addTLV_U8(TLV.Tag.TAG_TrOut_HashSize, hashes[0].length);
|
||||
rqApdu.addTLV(TLV.Tag.TAG_TrOut_Hash, bs.toByteArray());
|
||||
if (issuerData != null) {
|
||||
if (mCard.getSigningMethod() != TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer_And_WriteIssuerData)
|
||||
if (!mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer_And_WriteIssuerData))
|
||||
throw new TangemException("Card don't support simultaneous sign with write issuer data!");
|
||||
|
||||
if (issuerDataSignature == null)
|
||||
|
|
@ -849,7 +849,7 @@ public class CardProtocol {
|
|||
if (issuerTransactionSignature != null) {
|
||||
//byte[] issuerSignature = CardCrypto.Signature(issuer.getPrivateTransactionKey(), bs.toByteArray());
|
||||
rqApdu.addTLV(TLV.Tag.TAG_Issuer_Transaction_Signature, issuerTransactionSignature);
|
||||
} else if (mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer) {
|
||||
} else if (!mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Hash)) {
|
||||
throw new TangemException("Card require issuer validation before sign the transaction!");
|
||||
}
|
||||
|
||||
|
|
@ -900,7 +900,7 @@ public class CardProtocol {
|
|||
bs.write(bTxOutData);
|
||||
|
||||
if (issuerData != null) {
|
||||
if (mCard.getSigningMethod() != TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer_And_WriteIssuerData)
|
||||
if (!mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer_And_WriteIssuerData))
|
||||
throw new TangemException("Card don't support simultaneous sign with write issuer data!");
|
||||
|
||||
if (issuerDataSignature == null)
|
||||
|
|
@ -911,7 +911,7 @@ public class CardProtocol {
|
|||
}
|
||||
if (issuerTransactionSignature != null) {
|
||||
rqApdu.addTLV(TLV.Tag.TAG_Issuer_Transaction_Signature, issuerTransactionSignature);
|
||||
} else if (mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer) {
|
||||
} else if (!mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Raw)) {
|
||||
throw new TangemException("Card require issuer validation before sign the transaction!");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -419,6 +419,7 @@ public class CustomReadCardTask extends Thread {
|
|||
|
||||
} finally {
|
||||
Log.i(TAG, String.format("[-- Finish task -- %s --]", getClass().getSimpleName()));
|
||||
mNotifications.onReadWait(0);
|
||||
mNotifications.onReadFinish(protocol);
|
||||
}
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ public class OneTouchSignTask extends ReadCardInfoTask {
|
|||
public interface TransactionToSign {
|
||||
boolean isSigningOnCardSupported(TangemCard card);
|
||||
|
||||
boolean isIssuerCanSignData(TangemCard card);
|
||||
|
||||
boolean isIssuerCanSignTransaction(TangemCard card);
|
||||
|
||||
byte[][] getHashesToSign(TangemCard card) throws Exception;
|
||||
|
||||
byte[] getRawDataToSign(TangemCard card) throws Exception;
|
||||
|
|
@ -46,45 +50,51 @@ public class OneTouchSignTask extends ReadCardInfoTask {
|
|||
mNotifications.onReadProgress(protocol, 30);
|
||||
if (isCancelled) return;
|
||||
|
||||
if (mCard.getPauseBeforePIN2() > 0) {
|
||||
mNotifications.onReadWait(mCard.getPauseBeforePIN2());
|
||||
}
|
||||
|
||||
if (!transactionToSign.isSigningOnCardSupported(mCard)) {
|
||||
throw new CardProtocol.TangemException("Signing method isn't supported!");
|
||||
}
|
||||
|
||||
TLVList signResult;
|
||||
switch (mCard.getSigningMethod()) {
|
||||
case Sign_Hash:
|
||||
signResult = protocol.run_SignHashes(pinsProvider.getPIN2(), transactionToSign.getHashesToSign(mCard), null, null, null);
|
||||
break;
|
||||
case Sign_Hash_Validated_By_Issuer:
|
||||
case Sign_Hash_Validated_By_Issuer_And_WriteIssuerData:
|
||||
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||
byte[][] hashes = transactionToSign.getHashesToSign(mCard);
|
||||
if (hashes.length > 10) throw new CardProtocol.TangemException("To much hashes in one transaction!");
|
||||
for (int i = 0; i < hashes.length; i++) {
|
||||
if (i != 0 && hashes[0].length != hashes[i].length)
|
||||
throw new CardProtocol.TangemException("Hashes length must be identical!");
|
||||
bs.write(hashes[i]);
|
||||
}
|
||||
signResult = protocol.run_SignHashes(pinsProvider.getPIN2(), hashes, transactionToSign.getIssuerTransactionSignature(mCard, bs.toByteArray()), null, null);
|
||||
break;
|
||||
case Sign_Raw:
|
||||
signResult = protocol.run_SignRaw(pinsProvider.getPIN2(), transactionToSign.getHashAlgToSign(mCard), transactionToSign.getRawDataToSign(mCard), null, null, null);
|
||||
break;
|
||||
case Sign_Raw_Validated_By_Issuer:
|
||||
case Sign_Raw_Validated_By_Issuer_And_WriteIssuerData:
|
||||
byte[] txOut = transactionToSign.getRawDataToSign(mCard);
|
||||
signResult = protocol.run_SignRaw(pinsProvider.getPIN2(), transactionToSign.getHashAlgToSign(mCard), txOut, transactionToSign.getIssuerTransactionSignature(mCard, txOut), null, null);
|
||||
break;
|
||||
default:
|
||||
throw new CardProtocol.TangemException("Signing method isn't supported!");
|
||||
|
||||
if (transactionToSign.isIssuerCanSignTransaction(mCard) &&
|
||||
(
|
||||
mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer) ||
|
||||
(
|
||||
transactionToSign.isIssuerCanSignData(mCard) &&
|
||||
mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer_And_WriteIssuerData)
|
||||
)
|
||||
)
|
||||
) {
|
||||
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||
byte[][] hashes = transactionToSign.getHashesToSign(mCard);
|
||||
if (hashes.length > 10) throw new CardProtocol.TangemException("To much hashes in one transaction!");
|
||||
for (int i = 0; i < hashes.length; i++) {
|
||||
if (i != 0 && hashes[0].length != hashes[i].length)
|
||||
throw new CardProtocol.TangemException("Hashes length must be identical!");
|
||||
bs.write(hashes[i]);
|
||||
}
|
||||
signResult = protocol.run_SignHashes(pinsProvider.getPIN2(), hashes, transactionToSign.getIssuerTransactionSignature(mCard, bs.toByteArray()), null, null);
|
||||
} else if (
|
||||
transactionToSign.isIssuerCanSignTransaction(mCard) &&
|
||||
(
|
||||
mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) ||
|
||||
(
|
||||
transactionToSign.isIssuerCanSignData(mCard) &&
|
||||
mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer_And_WriteIssuerData)
|
||||
)
|
||||
)
|
||||
) {
|
||||
byte[] txOut = transactionToSign.getRawDataToSign(mCard);
|
||||
signResult = protocol.run_SignRaw(pinsProvider.getPIN2(), transactionToSign.getHashAlgToSign(mCard), txOut, transactionToSign.getIssuerTransactionSignature(mCard, txOut), null, null);
|
||||
} else if (mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Hash)) {
|
||||
signResult = protocol.run_SignHashes(pinsProvider.getPIN2(), transactionToSign.getHashesToSign(mCard), null, null, null);
|
||||
} else if (mCard.allowedSigningMethod.contains(TangemCard.SigningMethod.Sign_Raw)) {
|
||||
signResult = protocol.run_SignRaw(pinsProvider.getPIN2(), transactionToSign.getHashAlgToSign(mCard), transactionToSign.getRawDataToSign(mCard), null, null, null);
|
||||
} else {
|
||||
throw new CardProtocol.TangemException("Signing method isn't supported!");
|
||||
}
|
||||
|
||||
transactionToSign.onSignCompleted(mCard, signResult.getTLV(TLV.Tag.TAG_Signature).Value);
|
||||
mNotifications.onReadProgress(protocol, 100);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,18 @@ package com.tangem.card_common.util;
|
|||
|
||||
public class Log {
|
||||
public static void i(String logTag, String message) {
|
||||
|
||||
if( loggerInstance!=null ) loggerInstance.i(logTag,message);
|
||||
}
|
||||
public static void e(String logTag, String message) {
|
||||
|
||||
if( loggerInstance!=null ) loggerInstance.e(logTag,message);
|
||||
}
|
||||
public static void v(String logTag, String message) {
|
||||
if( loggerInstance!=null ) loggerInstance.v(logTag,message);
|
||||
}
|
||||
|
||||
private static LoggerInterface loggerInstance=null;
|
||||
public static void setLogger(LoggerInterface logger)
|
||||
{
|
||||
loggerInstance=logger;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.card_common.util;
|
||||
|
||||
public interface LoggerInterface {
|
||||
void i(String logTag, String message);
|
||||
void e(String logTag, String message);
|
||||
void v(String logTag, String message);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue