Updated on 2026-08-14

This commit is contained in:
Tangem 2019-04-04 12:31:19 +03:00
parent 156ab295eb
commit ddf613590c
14 changed files with 165 additions and 167 deletions

View file

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

View file

@ -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!");
}

View file

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

View file

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

View file

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

View file

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