Updated on 2026-08-14

This commit is contained in:
Tangem 2018-07-10 17:31:35 +03:00
parent 5c482bf194
commit 425a9019f2
9 changed files with 465 additions and 400 deletions

View file

@ -1,4 +0,0 @@
package com.tangem.data.DB;
public class Repository {
}

View file

@ -1,4 +0,0 @@
package com.tangem.data.network.model;
public class UserModel {
}

View file

@ -0,0 +1,197 @@
package com.tangem.data.network.task.request_pin;
import android.annotation.TargetApi;
import android.hardware.fingerprint.FingerprintManager;
import android.os.AsyncTask;
import android.os.Build;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import com.tangem.domain.wallet.FingerprintHelper;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.presentation.activity.RequestPINActivity;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class StartFingerprintReaderTask extends AsyncTask<Void, Void, Boolean> {
private WeakReference<RequestPINActivity> reference;
private KeyStore keyStore;
private Cipher cipher;
private FingerprintManager.CryptoObject cryptoObject;
FingerprintManager fingerprintManager;
FingerprintHelper fingerprintHelper;
RequestPINActivity activity;
public StartFingerprintReaderTask(RequestPINActivity activity, FingerprintManager fingerprintManager, FingerprintHelper fingerprintHelper) {
reference = new WeakReference<>(activity);
this.fingerprintManager = fingerprintManager;
this.fingerprintHelper = fingerprintHelper;
this.activity = activity;
}
@Override
protected Boolean doInBackground(Void... params) {
if (!getKeyStore())
return false;
if (!createNewKey(false))
return false;
if (!getCipher())
return false;
if (!initCipher(Cipher.DECRYPT_MODE))
return false;
return initCryptObject();
}
@Override
protected void onPostExecute(final Boolean success) {
RequestPINActivity requestPINActivity = reference.get();
onCancelled();
if (!success) {
requestPINActivity.doLog("Authentication failed!");
} else {
fingerprintHelper.startAuth(fingerprintManager, cryptoObject);
requestPINActivity.doLog("Authenticate using fingerprint!");
}
}
@Override
protected void onCancelled() {
RequestPINActivity requestPINActivity = reference.get();
requestPINActivity.mStartFingerprintReaderTask = null;
}
private boolean getKeyStore() {
RequestPINActivity requestPINActivity = reference.get();
requestPINActivity.doLog("Getting keystore...");
try {
keyStore = KeyStore.getInstance(RequestPINActivity.KEYSTORE);
keyStore.load(null); // Create empty keystore
return true;
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
return false;
}
@TargetApi(Build.VERSION_CODES.M)
public boolean createNewKey(boolean forceCreate) {
RequestPINActivity requestPINActivity = reference.get();
requestPINActivity.doLog("Creating new key...");
try {
if (forceCreate)
keyStore.deleteEntry(RequestPINActivity.KEY_ALIAS);
if (!keyStore.containsAlias(RequestPINActivity.KEY_ALIAS)) {
KeyGenerator generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, RequestPINActivity.KEYSTORE);
generator.init(new KeyGenParameterSpec.Builder(RequestPINActivity.KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.build()
);
generator.generateKey();
requestPINActivity.doLog("Key created.");
} else
requestPINActivity.doLog("Key exists.");
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private boolean getCipher() {
RequestPINActivity requestPINActivity = reference.get();
requestPINActivity.doLog("Getting cipher...");
try {
cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7);
return true;
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
return false;
}
@TargetApi(Build.VERSION_CODES.M)
private boolean initCipher(int mode) {
RequestPINActivity requestPINActivity = reference.get();
requestPINActivity.doLog("Initializing cipher...");
try {
keyStore.load(null);
SecretKey keyspec = (SecretKey) keyStore.getKey(RequestPINActivity.KEY_ALIAS, null);
if (mode == Cipher.ENCRYPT_MODE) {
cipher.init(mode, keyspec);
} else {
byte[] iv = null;
if (requestPINActivity.mode == RequestPINActivity.Mode.RequestPIN || activity.mode == RequestPINActivity.Mode.RequestNewPIN || activity.mode == RequestPINActivity.Mode.ConfirmNewPIN) {
iv = PINStorage.loadEncryptedIV();
} else if (activity.mode == RequestPINActivity.Mode.RequestPIN2 || activity.mode == RequestPINActivity.Mode.RequestNewPIN2 || activity.mode == RequestPINActivity.Mode.ConfirmNewPIN2) {
iv = PINStorage.loadEncryptedIV2();
}
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(mode, keyspec, ivspec);
}
return true;
} catch (KeyPermanentlyInvalidatedException e) {
e.printStackTrace();
createNewKey(true); // Retry after clearing entry
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@TargetApi(Build.VERSION_CODES.M)
private boolean initCryptObject() {
RequestPINActivity requestPINActivity = reference.get();
requestPINActivity.doLog("Initializing crypt object...");
try {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

View file

@ -0,0 +1,65 @@
package com.tangem.data.network.task.save_pin;
import android.os.AsyncTask;
import android.widget.Toast;
import com.tangem.domain.wallet.FingerprintHelper;
import com.tangem.presentation.activity.SavePINActivity;
import com.tangem.wallet.R;
import java.lang.ref.WeakReference;
import javax.crypto.Cipher;
public class ConfirmWithFingerprintTask extends AsyncTask<Void, Void, Boolean> {
private WeakReference<SavePINActivity> reference;
public ConfirmWithFingerprintTask(SavePINActivity context) {
reference = new WeakReference<>(context);
reference.get().fingerprintHelper = new FingerprintHelper(reference.get());
}
@Override
protected Boolean doInBackground(Void... params) {
SavePINActivity savePINActivity = reference.get();
if (!savePINActivity.getKeyStore())
return false;
if (!savePINActivity.createNewKey(false))
return false;
if (!savePINActivity.getCipher())
return false;
return savePINActivity.initCipher(Cipher.ENCRYPT_MODE) && savePINActivity.initCryptObject();
}
@Override
protected void onPostExecute(final Boolean success) {
SavePINActivity savePINActivity = reference.get();
onCancelled();
if (!success) {
Toast.makeText(savePINActivity, R.string.pin_save_fail, Toast.LENGTH_LONG).show();
} else {
savePINActivity.print("Confirm PIN action using fingerprint!");
savePINActivity.fingerprintHelper.startAuth(savePINActivity.fingerprintManager, savePINActivity.cryptoObject);
savePINActivity.CreateFingerPrintConfirmationDialog();
}
}
@Override
protected void onCancelled() {
SavePINActivity savePINActivity = reference.get();
savePINActivity.mConfirmWithFingerprintTask = null;
if (savePINActivity.dFingerPrintConfirmation != null) {
savePINActivity.dFingerPrintConfirmation.cancel();
}
}
}

View file

@ -0,0 +1,86 @@
package com.tangem.data.network.task.send_transaction;
import android.util.Log;
import com.tangem.data.network.request.ElectrumRequest;
import com.tangem.data.network.task.ElectrumTask;
import com.tangem.domain.wallet.Blockchain;
import com.tangem.domain.wallet.CoinEngine;
import com.tangem.domain.wallet.CoinEngineFactory;
import com.tangem.domain.wallet.LastSignStorage;
import com.tangem.domain.wallet.SharedData;
import com.tangem.presentation.activity.SendTransactionActivity;
import org.json.JSONException;
import java.lang.ref.WeakReference;
import java.math.BigInteger;
import java.util.List;
public class ConnectTask extends ElectrumTask {
private WeakReference<SendTransactionActivity> reference;
public ConnectTask(SendTransactionActivity context, String host, int port) {
super(host, port);
reference = new WeakReference<>(context);
}
public ConnectTask(SendTransactionActivity context, String host, int port, SharedData sharedData) {
super(host, port, sharedData);
reference = new WeakReference<>(context);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(List<ElectrumRequest> requests) {
super.onPostExecute(requests);
SendTransactionActivity sendTransactionActivity = reference.get();
CoinEngine engine = CoinEngineFactory.Create(Blockchain.Bitcoin);
for (ElectrumRequest request : requests) {
try {
if (request.error == null) {
if (request.isMethod(ElectrumRequest.METHOD_SendTransaction)) {
try {
String hashTX = request.getResultString();
try {
LastSignStorage.setLastMessage(sendTransactionActivity.mCard.getWallet(), hashTX);
if (hashTX.startsWith("0x") || hashTX.startsWith("0X")) {
hashTX = hashTX.substring(2);
}
BigInteger bigInt = new BigInteger(hashTX, 16); //TODO: очень плохой способ
LastSignStorage.setTxWasSend(sendTransactionActivity.mCard.getWallet());
LastSignStorage.setLastMessage(sendTransactionActivity.mCard.getWallet(), "");
Log.e("TX_RESULT", hashTX);
sendTransactionActivity.finishWithSuccess();
} catch (Exception e) {
engine.SwitchNode(null);
sendTransactionActivity.finishWithError(hashTX);
return;
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(null);
sendTransactionActivity.finishWithError(e.toString());
}
}
} else if (request.error != null) {
engine.SwitchNode(null);
sendTransactionActivity.finishWithError(request.error);
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(null);
sendTransactionActivity.finishWithError(e.toString());
}
}
}
}

View file

@ -0,0 +1,80 @@
package com.tangem.data.network.task.send_transaction;
import android.util.Log;
import com.tangem.data.network.request.InfuraRequest;
import com.tangem.data.network.task.InfuraTask;
import com.tangem.domain.wallet.Blockchain;
import com.tangem.domain.wallet.LastSignStorage;
import com.tangem.presentation.activity.SendTransactionActivity;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.math.BigInteger;
import java.util.List;
public class ETHRequestTask extends InfuraTask {
private WeakReference<SendTransactionActivity> reference;
public ETHRequestTask(SendTransactionActivity context, Blockchain blockchain) {
super(blockchain);
reference = new WeakReference<>(context);
}
@Override
protected void onPostExecute(List<InfuraRequest> requests) {
super.onPostExecute(requests);
SendTransactionActivity sendTransactionActivity = reference.get();
for (InfuraRequest request : requests) {
try {
if (request.error == null) {
if (request.isMethod(InfuraRequest.METHOD_ETH_SendRawTransaction)) {
try {
String hashTX = "";
try {
String tmp = request.getResultString();
hashTX = tmp;
} catch (JSONException e) {
JSONObject msg = request.getAnswer();
JSONObject err = msg.getJSONObject("error");
hashTX = err.getString("message");
LastSignStorage.setLastMessage(sendTransactionActivity.mCard.getWallet(), hashTX);
sendTransactionActivity.finishWithError(hashTX);
return;
}
try {
if (hashTX.startsWith("0x") || hashTX.startsWith("0X")) {
hashTX = hashTX.substring(2);
}
BigInteger bigInt = new BigInteger(hashTX, 16); //TODO: очень плохой способ
LastSignStorage.setTxWasSend(sendTransactionActivity.mCard.getWallet());
LastSignStorage.setLastMessage(sendTransactionActivity.mCard.getWallet(), "");
BigInteger nonce = sendTransactionActivity.mCard.GetConfirmTXCount();
nonce.add(BigInteger.valueOf(1));
sendTransactionActivity.mCard.SetConfirmTXCount(nonce);
Log.e("TX_RESULT", hashTX);
sendTransactionActivity.finishWithSuccess();
} catch (Exception e) {
sendTransactionActivity.finishWithError(hashTX);
}
} catch (JSONException e) {
e.printStackTrace();
sendTransactionActivity.finishWithError(e.toString());
}
}
} else if (request.error != null) {
sendTransactionActivity.finishWithError(request.error);
}
} catch (JSONException e) {
e.printStackTrace();
sendTransactionActivity.finishWithError(e.toString());
}
}
}
}