Updated on 2026-08-14

This commit is contained in:
Tangem 2018-08-06 13:38:59 +03:00
parent 4d77a40172
commit 0410adf771
5 changed files with 333 additions and 353 deletions

View file

@ -81,7 +81,7 @@ public class StartFingerprintReaderTask extends AsyncTask<Void, Void, Boolean> {
protected void onCancelled() {
RequestPINActivity requestPINActivity = reference.get();
requestPINActivity.mStartFingerprintReaderTask = null;
requestPINActivity.setStartFingerprintReaderTask(null);
}
private boolean getKeyStore() {
@ -159,9 +159,9 @@ public class StartFingerprintReaderTask extends AsyncTask<Void, Void, Boolean> {
cipher.init(mode, keyspec);
} else {
byte[] iv = null;
if (requestPINActivity.mode == RequestPINActivity.Mode.RequestPIN || activity.mode == RequestPINActivity.Mode.RequestNewPIN || activity.mode == RequestPINActivity.Mode.ConfirmNewPIN) {
if (requestPINActivity.getMode() == RequestPINActivity.Mode.RequestPIN || activity.getMode() == RequestPINActivity.Mode.RequestNewPIN || activity.getMode() == RequestPINActivity.Mode.ConfirmNewPIN) {
iv = PINStorage.loadEncryptedIV();
} else if (activity.mode == RequestPINActivity.Mode.RequestPIN2 || activity.mode == RequestPINActivity.Mode.RequestNewPIN2 || activity.mode == RequestPINActivity.Mode.ConfirmNewPIN2) {
} else if (activity.getMode() == RequestPINActivity.Mode.RequestPIN2 || activity.getMode() == RequestPINActivity.Mode.RequestNewPIN2 || activity.getMode() == RequestPINActivity.Mode.ConfirmNewPIN2) {
iv = PINStorage.loadEncryptedIV2();
}
IvParameterSpec ivspec = new IvParameterSpec(iv);

View file

@ -1,346 +0,0 @@
package com.tangem.presentation.activity;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.tangem.data.network.task.request_pin.StartFingerprintReaderTask;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.FingerprintHelper;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.domain.wallet.TangemCard;
import com.tangem.wallet.R;
import java.io.IOException;
import javax.crypto.Cipher;
public class RequestPINActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, FingerprintHelper.FingerprintHelperListener {
public enum Mode {RequestPIN, RequestPIN2, RequestNewPIN, RequestNewPIN2, ConfirmNewPIN, ConfirmNewPIN2}
public Mode mode;
boolean allowFingerprint = false;
private NfcManager mNfcManager;
private TextView tvPIN;
public StartFingerprintReaderTask mStartFingerprintReaderTask;
public static final String KEY_ALIAS = "pinKey";
public static final String KEYSTORE = "AndroidKeyStore";
private FingerprintManager fingerprintManager;
private FingerprintHelper fingerprintHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request_pin);
MainActivity.Companion.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);
tvPIN = findViewById(R.id.pin);
OnClickListener onButtonNClick = view -> tvPIN.setText(tvPIN.getText() + (String) ((Button) view).getText());
Button btn0 = findViewById(R.id.btn0);
btn0.setOnClickListener(onButtonNClick);
Button btn1 = findViewById(R.id.btn1);
btn1.setOnClickListener(onButtonNClick);
Button btn2 = findViewById(R.id.btn2);
btn2.setOnClickListener(onButtonNClick);
Button btn3 = findViewById(R.id.btn3);
btn3.setOnClickListener(onButtonNClick);
Button btn4 = findViewById(R.id.btn4);
btn4.setOnClickListener(onButtonNClick);
Button btn5 = findViewById(R.id.btn5);
btn5.setOnClickListener(onButtonNClick);
Button btn6 = findViewById(R.id.btn6);
btn6.setOnClickListener(onButtonNClick);
Button btn7 = findViewById(R.id.btn7);
btn7.setOnClickListener(onButtonNClick);
Button btn8 = findViewById(R.id.btn8);
btn8.setOnClickListener(onButtonNClick);
Button btn9 = findViewById(R.id.btn9);
btn9.setOnClickListener(onButtonNClick);
Button btnBS = findViewById(R.id.btnBackspace);
btnBS.setOnClickListener(view -> {
String S = tvPIN.getText().toString();
if (S.length() > 0) {
tvPIN.setText(S.substring(0, S.length() - 1));
}
});
Button btnContinue = findViewById(R.id.btnContinue);
btnContinue.setOnClickListener(view -> doContinue());
mode = Mode.valueOf(getIntent().getStringExtra("mode"));
TextView tvPrompt = findViewById(R.id.pin_prompt);
if (mode == Mode.RequestNewPIN) {
if (PINStorage.haveEncryptedPIN()) {
allowFingerprint = true;
tvPrompt.setText("Enter new PIN or use fingerprint scanner");
} else {
tvPrompt.setText("Enter new PIN");
}
} else if (mode == Mode.ConfirmNewPIN) {
tvPrompt.setText("Confirm new PIN");
} else if (mode == Mode.RequestPIN) {
if (PINStorage.haveEncryptedPIN()) {
allowFingerprint = true;
tvPrompt.setText("Enter PIN or use fingerprint scanner");
} else {
tvPrompt.setText("Enter PIN");
}
} else if (mode == Mode.RequestNewPIN2) {
if (PINStorage.haveEncryptedPIN2()) {
allowFingerprint = true;
tvPrompt.setText("Enter new PIN2 or use fingerprint scanner");
} else {
tvPrompt.setText("Enter new PIN2");
}
} else if (mode == Mode.ConfirmNewPIN2) {
tvPrompt.setText("Confirm new PIN2");
} else if (mode == Mode.RequestPIN2) {
String UID = getIntent().getStringExtra("UID");
TangemCard mCard = new TangemCard(UID);
mCard.LoadFromBundle(getIntent().getBundleExtra("Card"));
if (mCard.PIN2 == TangemCard.PIN2_Mode.DefaultPIN2 || mCard.PIN2 == TangemCard.PIN2_Mode.Unchecked) {
// if we know PIN2 or not try default previously - use it
PINStorage.setPIN2(PINStorage.getDefaultPIN2());
setResult(Activity.RESULT_OK);
finish();
return;
}
if (PINStorage.haveEncryptedPIN2()) {
allowFingerprint = true;
tvPrompt.setText("Enter PIN2 or use fingerprint scanner");
} else {
tvPrompt.setText("Enter PIN2");
}
}
if (!allowFingerprint) {
tvPrompt.setVisibility(View.GONE);
} else {
tvPrompt.setVisibility(View.VISIBLE);
}
}
@Override
protected void onPause() {
super.onPause();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
if (mStartFingerprintReaderTask != null) {
mStartFingerprintReaderTask.cancel(true);
mStartFingerprintReaderTask = null;
}
mNfcManager.onPause();
}
@Override
protected void onStop() {
super.onStop();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
if (mStartFingerprintReaderTask != null) {
mStartFingerprintReaderTask.cancel(true);
mStartFingerprintReaderTask = null;
}
mNfcManager.onStop();
}
@Override
protected void onResume() {
super.onResume();
mNfcManager.onResume();
if (allowFingerprint) {
startFingerprintReader();
}
}
private void doContinue() {
if (mStartFingerprintReaderTask != null) {
return;
}
// Reset errors.
tvPIN.setError(null);
// Store values at the time of the login attempt.
String pin = tvPIN.getText().toString();
boolean cancel = false;
View focusView = null;
if (mode == Mode.ConfirmNewPIN) {
if (!pin.equals(getIntent().getStringExtra("newPIN"))) {
tvPIN.setError(getString(R.string.error_pin_confirmation_failed));
focusView = tvPIN;
cancel = true;
}
} else if (mode == Mode.ConfirmNewPIN2) {
if (!pin.equals(getIntent().getStringExtra("newPIN2"))) {
tvPIN.setError(getString(R.string.error_pin_confirmation_failed));
focusView = tvPIN;
cancel = true;
}
} else {
if (TextUtils.isEmpty(pin)) {
tvPIN.setError(getString(R.string.error_empty_pin));
focusView = tvPIN;
cancel = true;
}
}
if (cancel) {
focusView.requestFocus();
} else {
if (mode == Mode.RequestNewPIN || mode == Mode.ConfirmNewPIN) {
Intent resultData = new Intent();
resultData.putExtra("newPIN", pin);
if (mode == Mode.ConfirmNewPIN) {
resultData.putExtra("confirmPIN", pin);
}
setResult(Activity.RESULT_OK, resultData);
finish();
} else if (mode == Mode.RequestNewPIN2 || mode == Mode.ConfirmNewPIN2) {
Intent resultData = new Intent();
resultData.putExtra("newPIN2", pin);
if (mode == Mode.ConfirmNewPIN2) {
resultData.putExtra("confirmPIN2", pin);
}
setResult(Activity.RESULT_OK, resultData);
finish();
} else if (mode == Mode.RequestPIN) {
PINStorage.setUserPIN(pin);
setResult(Activity.RESULT_OK);
finish();
} else if (mode == Mode.RequestPIN2) {
PINStorage.setPIN2(pin);
setResult(Activity.RESULT_OK);
finish();
}
}
}
@Override
public void authenticationFailed(String error) {
doLog(error);
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void authenticationSucceeded(FingerprintManager.AuthenticationResult result) {
doLog("Authentication succeeded!");
Cipher cipher = result.getCryptoObject().getCipher();
if (mode == Mode.RequestNewPIN || mode == Mode.ConfirmNewPIN) {
Intent resultData = new Intent();
String pin = PINStorage.loadEncryptedPIN(cipher);
resultData.putExtra("newPIN", pin);
resultData.putExtra("confirmPIN", pin);
setResult(Activity.RESULT_OK, resultData);
finish();
} else if (mode == Mode.RequestNewPIN2 || mode == Mode.ConfirmNewPIN2) {
Intent resultData = new Intent();
String pin = PINStorage.loadEncryptedPIN2(cipher);
resultData.putExtra("newPIN2", pin);
resultData.putExtra("confirmPIN2", pin);
setResult(Activity.RESULT_OK, resultData);
finish();
} else if (mode == Mode.RequestPIN) {
PINStorage.loadEncryptedPIN(cipher);
setResult(Activity.RESULT_OK);
} else if (mode == Mode.RequestPIN2) {
PINStorage.loadEncryptedPIN2(cipher);
setResult(Activity.RESULT_OK);
}
finish();
}
private void startFingerprintReader() {
if (!testFingerPrintSettings())
return;
if (!allowFingerprint)
return;
fingerprintHelper = new FingerprintHelper(RequestPINActivity.this);
mStartFingerprintReaderTask = new StartFingerprintReaderTask(this, fingerprintManager, fingerprintHelper);
mStartFingerprintReaderTask.execute((Void) null);
}
@Override
public void onTagDiscovered(Tag tag) {
try {
Log.w(getClass().getName(), "Ignore discovered tag!");
mNfcManager.ignoreTag(tag);
} catch (IOException e) {
e.printStackTrace();
}
}
public void doLog(String text) {
// Log.e("FP", text);
}
@SuppressLint("NewApi")
private boolean testFingerPrintSettings() {
doLog("Testing Fingerprint Settings");
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
assert keyguardManager != null;
if (!keyguardManager.isKeyguardSecure()) {
doLog("User hasn't enabled Lock Screen");
return false;
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
doLog("User hasn't granted permission to use Fingerprint");
return false;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
doLog("User hasn't registered any fingerprints");
return false;
}
doLog("Fingerprint authentication is set.\n");
return true;
}
}

View file

@ -0,0 +1,317 @@
package com.tangem.presentation.activity
import android.Manifest
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Activity
import android.app.KeyguardManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.hardware.fingerprint.FingerprintManager
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Build
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Button
import com.tangem.data.network.task.request_pin.StartFingerprintReaderTask
import com.tangem.domain.cardReader.NfcManager
import com.tangem.domain.wallet.FingerprintHelper
import com.tangem.domain.wallet.PINStorage
import com.tangem.domain.wallet.TangemCard
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_request_pin.*
import java.io.IOException
class RequestPINActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, FingerprintHelper.FingerprintHelperListener {
companion object {
const val KEY_ALIAS = "pinKey"
const val KEYSTORE = "AndroidKeyStore"
}
lateinit var mode: Mode
private var allowFingerprint = false
private var nfcManager: NfcManager? = null
var startFingerprintReaderTask: StartFingerprintReaderTask? = null
private var fingerprintManager: FingerprintManager? = null
private var fingerprintHelper: FingerprintHelper? = null
enum class Mode {
RequestPIN, RequestPIN2, RequestNewPIN, RequestNewPIN2, ConfirmNewPIN, ConfirmNewPIN2
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_request_pin)
MainActivity.commonInit(applicationContext)
nfcManager = NfcManager(this, this)
mode = Mode.valueOf(intent.getStringExtra("mode"))
if (mode == Mode.RequestNewPIN)
if (PINStorage.haveEncryptedPIN()) {
allowFingerprint = true
tvPinPrompt.setText(R.string.enter_new_pin_or_use_fingerprint_scanner)
} else
tvPinPrompt.setText(R.string.enter_new_pin)
else if (mode == Mode.ConfirmNewPIN)
tvPinPrompt.setText(R.string.confirm_new_pin)
else if (mode == Mode.RequestPIN)
if (PINStorage.haveEncryptedPIN()) {
allowFingerprint = true
tvPinPrompt.setText(R.string.enter_pin_or_use_fingerprint_scanner)
} else
tvPinPrompt.setText(R.string.enter_pin)
else if (mode == Mode.RequestNewPIN2)
if (PINStorage.haveEncryptedPIN2()) {
allowFingerprint = true
tvPinPrompt.setText(R.string.enter_new_pin_2_or_use_fingerprint_scanner)
} else
tvPinPrompt.setText(R.string.enter_new_pin_2)
else if (mode == Mode.ConfirmNewPIN2)
tvPinPrompt.setText(R.string.confirm_new_pin_2)
else if (mode == Mode.RequestPIN2) {
val uid = intent.getStringExtra("UID")
val mCard = TangemCard(uid)
mCard.LoadFromBundle(intent.getBundleExtra("Card"))
if (mCard.PIN2 == TangemCard.PIN2_Mode.DefaultPIN2 || mCard.PIN2 == TangemCard.PIN2_Mode.Unchecked) {
// if we know PIN2 or not try default previously - use it
PINStorage.setPIN2(PINStorage.getDefaultPIN2())
setResult(Activity.RESULT_OK)
finish()
return
}
if (PINStorage.haveEncryptedPIN2()) {
allowFingerprint = true
tvPinPrompt.setText(R.string.enter_pin_2_or_use_fingerprint_scanner)
} else
tvPinPrompt.setText(R.string.enter_pin_2)
}
if (!allowFingerprint)
tvPinPrompt.visibility = View.GONE
else
tvPinPrompt.visibility = View.VISIBLE
// set listeners
btn0.setOnClickListener { buttonClick(btn0) }
btn1.setOnClickListener { buttonClick(btn1) }
btn2.setOnClickListener { buttonClick(btn2) }
btn3.setOnClickListener { buttonClick(btn3) }
btn4.setOnClickListener { buttonClick(btn4) }
btn5.setOnClickListener { buttonClick(btn5) }
btn6.setOnClickListener { buttonClick(btn6) }
btn7.setOnClickListener { buttonClick(btn7) }
btn8.setOnClickListener { buttonClick(btn8) }
btn9.setOnClickListener { buttonClick(btn9) }
btnBackspace.setOnClickListener {
val s = tvPin!!.text.toString()
if (s.isNotEmpty())
tvPin!!.text = s.substring(0, s.length - 1)
}
btnContinue.setOnClickListener { doContinue() }
}
override fun onPause() {
super.onPause()
if (fingerprintHelper != null)
fingerprintHelper!!.cancel()
if (startFingerprintReaderTask != null) {
startFingerprintReaderTask!!.cancel(true)
startFingerprintReaderTask = null
}
nfcManager!!.onPause()
}
override fun onStop() {
super.onStop()
if (fingerprintHelper != null)
fingerprintHelper!!.cancel()
if (startFingerprintReaderTask != null) {
startFingerprintReaderTask!!.cancel(true)
startFingerprintReaderTask = null
}
nfcManager!!.onStop()
}
override fun onResume() {
super.onResume()
nfcManager!!.onResume()
if (allowFingerprint)
startFingerprintReader()
}
override fun onTagDiscovered(tag: Tag) {
try {
Log.w(javaClass.name, "Ignore discovered tag!")
nfcManager!!.ignoreTag(tag)
} catch (e: IOException) {
e.printStackTrace()
}
}
override fun authenticationFailed(error: String) {
doLog(error)
}
@TargetApi(Build.VERSION_CODES.M)
override fun authenticationSucceeded(result: FingerprintManager.AuthenticationResult) {
doLog("Authentication succeeded!")
val cipher = result.cryptoObject.cipher
if (mode == Mode.RequestNewPIN || mode == Mode.ConfirmNewPIN) {
val resultData = Intent()
val pin = PINStorage.loadEncryptedPIN(cipher)
resultData.putExtra("newPIN", pin)
resultData.putExtra("confirmPIN", pin)
setResult(Activity.RESULT_OK, resultData)
finish()
} else if (mode == Mode.RequestNewPIN2 || mode == Mode.ConfirmNewPIN2) {
val resultData = Intent()
val pin = PINStorage.loadEncryptedPIN2(cipher)
resultData.putExtra("newPIN2", pin)
resultData.putExtra("confirmPIN2", pin)
setResult(Activity.RESULT_OK, resultData)
finish()
} else if (mode == Mode.RequestPIN) {
PINStorage.loadEncryptedPIN(cipher)
setResult(Activity.RESULT_OK)
} else if (mode == Mode.RequestPIN2) {
PINStorage.loadEncryptedPIN2(cipher)
setResult(Activity.RESULT_OK)
}
finish()
}
fun doLog(text: String) {
// Log.e("FP", text);
}
@SuppressLint("SetTextI18n")
private fun buttonClick(button: Button) {
tvPin!!.text = tvPin!!.text.toString() + button.text as String
}
@SuppressLint("NewApi")
private fun testFingerPrintSettings(): Boolean {
doLog("Testing Fingerprint Settings")
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
fingerprintManager = getSystemService(Context.FINGERPRINT_SERVICE) as FingerprintManager
if (!keyguardManager.isKeyguardSecure) {
doLog("User hasn't enabled Lock Screen")
return false
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
doLog("User hasn't granted permission to use Fingerprint")
return false
}
if (!fingerprintManager!!.hasEnrolledFingerprints()) {
doLog("User hasn't registered any fingerprints")
return false
}
doLog("Fingerprint authentication is set.\n")
return true
}
private fun startFingerprintReader() {
if (!testFingerPrintSettings())
return
if (!allowFingerprint)
return
fingerprintHelper = FingerprintHelper(this@RequestPINActivity)
startFingerprintReaderTask = StartFingerprintReaderTask(this, fingerprintManager, fingerprintHelper)
startFingerprintReaderTask!!.execute(null as Void?)
}
private fun doContinue() {
if (startFingerprintReaderTask != null)
return
// reset errors.
tvPin!!.error = null
// store values at the time of the login attempt.
val pin = tvPin!!.text.toString()
var cancel = false
var focusView: View? = null
if (mode == Mode.ConfirmNewPIN) {
if (pin != intent.getStringExtra("newPIN")) {
tvPin!!.error = getString(R.string.error_pin_confirmation_failed)
focusView = tvPin
cancel = true
}
} else if (mode == Mode.ConfirmNewPIN2) {
if (pin != intent.getStringExtra("newPIN2")) {
tvPin!!.error = getString(R.string.error_pin_confirmation_failed)
focusView = tvPin
cancel = true
}
} else {
if (TextUtils.isEmpty(pin)) {
tvPin!!.error = getString(R.string.error_empty_pin)
focusView = tvPin
cancel = true
}
}
if (cancel)
focusView!!.requestFocus()
else {
if (mode == Mode.RequestNewPIN || mode == Mode.ConfirmNewPIN) {
val resultData = Intent()
resultData.putExtra("newPIN", pin)
if (mode == Mode.ConfirmNewPIN)
resultData.putExtra("confirmPIN", pin)
setResult(Activity.RESULT_OK, resultData)
finish()
} else if (mode == Mode.RequestNewPIN2 || mode == Mode.ConfirmNewPIN2) {
val resultData = Intent()
resultData.putExtra("newPIN2", pin)
if (mode == Mode.ConfirmNewPIN2)
resultData.putExtra("confirmPIN2", pin)
setResult(Activity.RESULT_OK, resultData)
finish()
} else if (mode == Mode.RequestPIN) {
PINStorage.setUserPIN(pin)
setResult(Activity.RESULT_OK)
finish()
} else if (mode == Mode.RequestPIN2) {
PINStorage.setPIN2(pin)
setResult(Activity.RESULT_OK)
finish()
}
}
}
}