New NFC dialog design with indeterminate progress, do NFC stuff in background
This commit is contained in:
@@ -692,6 +692,7 @@
|
|||||||
-->
|
-->
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.NfcOperationActivity"
|
android:name=".ui.NfcOperationActivity"
|
||||||
|
android:theme="@style/KeychainTheme.DialogWithoutTitle"
|
||||||
android:allowTaskReparenting="true"
|
android:allowTaskReparenting="true"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:taskAffinity=":Nfc" />
|
android:taskAffinity=":Nfc" />
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ public class CreateKeyActivity extends BaseNfcActivity {
|
|||||||
|
|
||||||
Fragment mCurrentFragment;
|
Fragment mCurrentFragment;
|
||||||
|
|
||||||
|
|
||||||
|
byte[] mScannedFingerprints;
|
||||||
|
byte[] mNfcAid;
|
||||||
|
String mNfcUserId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -72,8 +77,6 @@ public class CreateKeyActivity extends BaseNfcActivity {
|
|||||||
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
|
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
|
||||||
try {
|
try {
|
||||||
handleTagDiscoveredIntent(getIntent());
|
handleTagDiscoveredIntent(getIntent());
|
||||||
} catch (CardException e) {
|
|
||||||
handleNfcError(e);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
handleNfcError(e);
|
handleNfcError(e);
|
||||||
}
|
}
|
||||||
@@ -142,40 +145,47 @@ public class CreateKeyActivity extends BaseNfcActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNfcPerform() throws IOException {
|
protected void doNfcInBackground() throws IOException {
|
||||||
if (mCurrentFragment instanceof NfcListenerFragment) {
|
if (mCurrentFragment instanceof NfcListenerFragment) {
|
||||||
((NfcListenerFragment) mCurrentFragment).onNfcPerform();
|
((NfcListenerFragment) mCurrentFragment).doNfcInBackground();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] scannedFingerprints = nfcGetFingerprints();
|
mScannedFingerprints = nfcGetFingerprints();
|
||||||
byte[] nfcAid = nfcGetAid();
|
mNfcAid = nfcGetAid();
|
||||||
String userId = nfcGetUserId();
|
mNfcUserId = nfcGetUserId();
|
||||||
|
}
|
||||||
|
|
||||||
if (containsKeys(scannedFingerprints)) {
|
@Override
|
||||||
|
protected void onNfcPostExecute() throws IOException {
|
||||||
|
if (mCurrentFragment instanceof NfcListenerFragment) {
|
||||||
|
((NfcListenerFragment) mCurrentFragment).onNfcPostExecute();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsKeys(mScannedFingerprints)) {
|
||||||
try {
|
try {
|
||||||
long masterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(scannedFingerprints);
|
long masterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mScannedFingerprints);
|
||||||
CachedPublicKeyRing ring = new ProviderHelper(this).getCachedPublicKeyRing(masterKeyId);
|
CachedPublicKeyRing ring = new ProviderHelper(this).getCachedPublicKeyRing(masterKeyId);
|
||||||
ring.getMasterKeyId();
|
ring.getMasterKeyId();
|
||||||
|
|
||||||
Intent intent = new Intent(this, ViewKeyActivity.class);
|
Intent intent = new Intent(this, ViewKeyActivity.class);
|
||||||
intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, nfcAid);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, mNfcAid);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, userId);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, scannedFingerprints);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mScannedFingerprints);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
|
|
||||||
} catch (PgpKeyNotFoundException e) {
|
} catch (PgpKeyNotFoundException e) {
|
||||||
Fragment frag = CreateYubiKeyImportFragment.newInstance(
|
Fragment frag = CreateYubiKeyImportFragment.newInstance(
|
||||||
scannedFingerprints, nfcAid, userId);
|
mScannedFingerprints, mNfcAid, mNfcUserId);
|
||||||
loadFragment(frag, FragAction.TO_RIGHT);
|
loadFragment(frag, FragAction.TO_RIGHT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Fragment frag = CreateYubiKeyBlankFragment.newInstance();
|
Fragment frag = CreateYubiKeyBlankFragment.newInstance();
|
||||||
loadFragment(frag, FragAction.TO_RIGHT);
|
loadFragment(frag, FragAction.TO_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsKeys(byte[] scannedFingerprints) {
|
private boolean containsKeys(byte[] scannedFingerprints) {
|
||||||
@@ -246,7 +256,8 @@ public class CreateKeyActivity extends BaseNfcActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface NfcListenerFragment {
|
interface NfcListenerFragment {
|
||||||
public void onNfcPerform() throws IOException;
|
public void doNfcInBackground() throws IOException;
|
||||||
|
public void onNfcPostExecute() throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ public class CreateYubiKeyImportFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNfcPerform() throws IOException {
|
public void doNfcInBackground() throws IOException {
|
||||||
|
|
||||||
mNfcFingerprints = mCreateKeyActivity.nfcGetFingerprints();
|
mNfcFingerprints = mCreateKeyActivity.nfcGetFingerprints();
|
||||||
mNfcAid = mCreateKeyActivity.nfcGetAid();
|
mNfcAid = mCreateKeyActivity.nfcGetAid();
|
||||||
@@ -204,10 +204,13 @@ public class CreateYubiKeyImportFragment
|
|||||||
byte[] fp = new byte[20];
|
byte[] fp = new byte[20];
|
||||||
ByteBuffer.wrap(fp).put(mNfcFingerprints, 0, 20);
|
ByteBuffer.wrap(fp).put(mNfcFingerprints, 0, 20);
|
||||||
mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(fp);
|
mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNfcPostExecute() throws IOException {
|
||||||
|
|
||||||
setData();
|
setData();
|
||||||
refreshSearch();
|
refreshSearch();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -448,10 +448,8 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNfcPerform() throws IOException {
|
protected void onNfcPostExecute() throws IOException {
|
||||||
// this displays the key or moves to the yubikey import dialogue.
|
// either way, finish after NFC AsyncTask
|
||||||
super.onNfcPerform();
|
|
||||||
// either way, finish afterwards
|
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,7 +461,7 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleResult (ImportKeyResult result) {
|
public void handleResult(ImportKeyResult result) {
|
||||||
if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(getIntent().getAction())
|
if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(getIntent().getAction())
|
||||||
|| ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(getIntent().getAction())) {
|
|| ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(getIntent().getAction())) {
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
|
|||||||
@@ -7,8 +7,10 @@
|
|||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.widget.ViewAnimator;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@@ -44,11 +46,15 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
|||||||
|
|
||||||
public static final String RESULT_DATA = "result_data";
|
public static final String RESULT_DATA = "result_data";
|
||||||
|
|
||||||
|
public ViewAnimator vAnimator;
|
||||||
|
|
||||||
private RequiredInputParcel mRequiredInput;
|
private RequiredInputParcel mRequiredInput;
|
||||||
private Intent mServiceIntent;
|
private Intent mServiceIntent;
|
||||||
|
|
||||||
private static final byte[] BLANK_FINGERPRINT = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
private static final byte[] BLANK_FINGERPRINT = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
|
|
||||||
|
private CryptoInputParcel mInputParcel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -56,6 +62,11 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
|||||||
|
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
|
||||||
|
setTitle(R.string.nfc_text);
|
||||||
|
|
||||||
|
vAnimator = (ViewAnimator) findViewById(R.id.view_animator);
|
||||||
|
vAnimator.setDisplayedChild(0);
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
Bundle data = intent.getExtras();
|
Bundle data = intent.getExtras();
|
||||||
|
|
||||||
@@ -74,16 +85,22 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNfcPerform() throws IOException {
|
public void onNfcPreExecute() {
|
||||||
|
// start with indeterminate progress
|
||||||
|
vAnimator.setDisplayedChild(1);
|
||||||
|
}
|
||||||
|
|
||||||
CryptoInputParcel inputParcel = new CryptoInputParcel(mRequiredInput.mSignatureTime);
|
@Override
|
||||||
|
protected void doNfcInBackground() throws IOException {
|
||||||
|
|
||||||
|
mInputParcel = new CryptoInputParcel(mRequiredInput.mSignatureTime);
|
||||||
|
|
||||||
switch (mRequiredInput.mType) {
|
switch (mRequiredInput.mType) {
|
||||||
case NFC_DECRYPT: {
|
case NFC_DECRYPT: {
|
||||||
for (int i = 0; i < mRequiredInput.mInputData.length; i++) {
|
for (int i = 0; i < mRequiredInput.mInputData.length; i++) {
|
||||||
byte[] encryptedSessionKey = mRequiredInput.mInputData[i];
|
byte[] encryptedSessionKey = mRequiredInput.mInputData[i];
|
||||||
byte[] decryptedSessionKey = nfcDecryptSessionKey(encryptedSessionKey);
|
byte[] decryptedSessionKey = nfcDecryptSessionKey(encryptedSessionKey);
|
||||||
inputParcel.addCryptoData(encryptedSessionKey, decryptedSessionKey);
|
mInputParcel.addCryptoData(encryptedSessionKey, decryptedSessionKey);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -92,7 +109,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
|||||||
byte[] hash = mRequiredInput.mInputData[i];
|
byte[] hash = mRequiredInput.mInputData[i];
|
||||||
int algo = mRequiredInput.mSignAlgos[i];
|
int algo = mRequiredInput.mSignAlgos[i];
|
||||||
byte[] signedHash = nfcCalculateSignature(hash, algo);
|
byte[] signedHash = nfcCalculateSignature(hash, algo);
|
||||||
inputParcel.addCryptoData(hash, signedHash);
|
mInputParcel.addCryptoData(hash, signedHash);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -163,7 +180,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Is this really needed?
|
// TODO: Is this really needed?
|
||||||
inputParcel.addCryptoData(subkeyBytes, cardSerialNumber);
|
mInputParcel.addCryptoData(subkeyBytes, cardSerialNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
// change PINs afterwards
|
// change PINs afterwards
|
||||||
@@ -177,16 +194,39 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNfcPostExecute() throws IOException {
|
||||||
if (mServiceIntent != null) {
|
if (mServiceIntent != null) {
|
||||||
CryptoInputParcelCacheService.addCryptoInputParcel(this, mServiceIntent, inputParcel);
|
CryptoInputParcelCacheService.addCryptoInputParcel(this, mServiceIntent, mInputParcel);
|
||||||
setResult(RESULT_OK, mServiceIntent);
|
setResult(RESULT_OK, mServiceIntent);
|
||||||
} else {
|
} else {
|
||||||
Intent result = new Intent();
|
Intent result = new Intent();
|
||||||
result.putExtra(NfcOperationActivity.RESULT_DATA, inputParcel);
|
result.putExtra(NfcOperationActivity.RESULT_DATA, mInputParcel);
|
||||||
setResult(RESULT_OK, result);
|
setResult(RESULT_OK, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
finish();
|
// show finish
|
||||||
|
vAnimator.setDisplayedChild(2);
|
||||||
|
|
||||||
|
new AsyncTask<Void, Void, Void>() {
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... params) {
|
||||||
|
// wait some 1000ms here, give the user time to appreciate the displayed finish
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// never mind
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void result) {
|
||||||
|
super.onPostExecute(result);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldPutKey(byte[] fingerprint, int idx) throws IOException {
|
private boolean shouldPutKey(byte[] fingerprint, int idx) throws IOException {
|
||||||
|
|||||||
@@ -148,6 +148,10 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
|||||||
private String mFingerprint;
|
private String mFingerprint;
|
||||||
private long mMasterKeyId;
|
private long mMasterKeyId;
|
||||||
|
|
||||||
|
private byte[] mNfcFingerprints;
|
||||||
|
private String mNfcUserId;
|
||||||
|
private byte[] mNfcAid;
|
||||||
|
|
||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -540,13 +544,17 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNfcPerform() throws IOException {
|
protected void doNfcInBackground() throws IOException {
|
||||||
|
|
||||||
final byte[] nfcFingerprints = nfcGetFingerprints();
|
mNfcFingerprints = nfcGetFingerprints();
|
||||||
final String nfcUserId = nfcGetUserId();
|
mNfcUserId = nfcGetUserId();
|
||||||
final byte[] nfcAid = nfcGetAid();
|
mNfcAid = nfcGetAid();
|
||||||
|
}
|
||||||
|
|
||||||
long yubiKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(nfcFingerprints);
|
@Override
|
||||||
|
protected void onNfcPostExecute() throws IOException {
|
||||||
|
|
||||||
|
long yubiKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -557,7 +565,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
|||||||
|
|
||||||
// if the master key of that key matches this one, just show the yubikey dialog
|
// if the master key of that key matches this one, just show the yubikey dialog
|
||||||
if (KeyFormattingUtils.convertFingerprintToHex(candidateFp).equals(mFingerprint)) {
|
if (KeyFormattingUtils.convertFingerprintToHex(candidateFp).equals(mFingerprint)) {
|
||||||
showYubiKeyFragment(nfcFingerprints, nfcUserId, nfcAid);
|
showYubiKeyFragment(mNfcFingerprints, mNfcUserId, mNfcAid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,9 +578,9 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
|||||||
Intent intent = new Intent(
|
Intent intent = new Intent(
|
||||||
ViewKeyActivity.this, ViewKeyActivity.class);
|
ViewKeyActivity.this, ViewKeyActivity.class);
|
||||||
intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, nfcAid);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, mNfcAid);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, nfcUserId);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, nfcFingerprints);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
@@ -586,15 +594,14 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
|||||||
public void onAction() {
|
public void onAction() {
|
||||||
Intent intent = new Intent(
|
Intent intent = new Intent(
|
||||||
ViewKeyActivity.this, CreateKeyActivity.class);
|
ViewKeyActivity.this, CreateKeyActivity.class);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, nfcAid);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, mNfcAid);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, nfcUserId);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, nfcFingerprints);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}, R.string.snack_yubikey_import).show();
|
}, R.string.snack_yubikey_import).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showYubiKeyFragment(
|
public void showYubiKeyFragment(
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.content.IntentFilter;
|
|||||||
import android.nfc.NfcAdapter;
|
import android.nfc.NfcAdapter;
|
||||||
import android.nfc.Tag;
|
import android.nfc.Tag;
|
||||||
import android.nfc.tech.IsoDep;
|
import android.nfc.tech.IsoDep;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -74,6 +75,10 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
|||||||
|
|
||||||
private static final int TIMEOUT = 100000;
|
private static final int TIMEOUT = 100000;
|
||||||
|
|
||||||
|
private byte[] mNfcFingerprints;
|
||||||
|
private String mNfcUserId;
|
||||||
|
private byte[] mNfcAid;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -91,28 +96,59 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
|||||||
* All new NFC Intents which are delivered to this activity are handled here
|
* All new NFC Intents which are delivered to this activity are handled here
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onNewIntent(Intent intent) {
|
public void onNewIntent(final Intent intent) {
|
||||||
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
|
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
|
||||||
try {
|
|
||||||
handleTagDiscoveredIntent(intent);
|
// Actual NFC operations are executed in doInBackground to not block the UI thread
|
||||||
} catch (CardException e) {
|
new AsyncTask<Void, Void, Exception>() {
|
||||||
handleNfcError(e);
|
@Override
|
||||||
} catch (IOException e) {
|
protected void onPreExecute() {
|
||||||
handleNfcError(e);
|
super.onPreExecute();
|
||||||
}
|
onNfcPreExecute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Exception doInBackground(Void... params) {
|
||||||
|
try {
|
||||||
|
handleTagDiscoveredIntent(intent);
|
||||||
|
} catch (CardException e) {
|
||||||
|
return e;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Exception exception) {
|
||||||
|
super.onPostExecute(exception);
|
||||||
|
|
||||||
|
if (exception != null) {
|
||||||
|
handleNfcError(exception);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
onNfcPostExecute();
|
||||||
|
} catch (IOException e) {
|
||||||
|
handleNfcError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleNfcError(IOException e) {
|
public void handleNfcError(Exception e) {
|
||||||
|
|
||||||
Log.e(Constants.TAG, "nfc error", e);
|
Log.e(Constants.TAG, "nfc error", e);
|
||||||
Notify.create(this, getString(R.string.error_nfc, e.getMessage()), Style.WARN).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleNfcError(CardException e) {
|
short status;
|
||||||
Log.e(Constants.TAG, "card error", e);
|
if (e instanceof CardException) {
|
||||||
|
status = ((CardException) e).getResponseCode();
|
||||||
short status = e.getResponseCode();
|
} else {
|
||||||
|
status = -1;
|
||||||
|
}
|
||||||
// When entering a PIN, a status of 63CX indicates X attempts remaining.
|
// When entering a PIN, a status of 63CX indicates X attempts remaining.
|
||||||
if ((status & (short)0xFFF0) == 0x63C0) {
|
if ((status & (short)0xFFF0) == 0x63C0) {
|
||||||
Notify.create(this, getString(R.string.error_pin, status & 0x000F), Style.WARN).show();
|
Notify.create(this, getString(R.string.error_pin, status & 0x000F), Style.WARN).show();
|
||||||
@@ -313,20 +349,25 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
|||||||
mPw1ValidatedForDecrypt = false;
|
mPw1ValidatedForDecrypt = false;
|
||||||
mPw3Validated = false;
|
mPw3Validated = false;
|
||||||
|
|
||||||
onNfcPerform();
|
doNfcInBackground();
|
||||||
|
|
||||||
mIsoDep.close();
|
mIsoDep.close();
|
||||||
mIsoDep = null;
|
mIsoDep = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onNfcPerform() throws IOException {
|
protected void onNfcPreExecute() {
|
||||||
|
}
|
||||||
|
|
||||||
final byte[] nfcFingerprints = nfcGetFingerprints();
|
protected void doNfcInBackground() throws IOException {
|
||||||
final String nfcUserId = nfcGetUserId();
|
mNfcFingerprints = nfcGetFingerprints();
|
||||||
final byte[] nfcAid = nfcGetAid();
|
mNfcUserId = nfcGetUserId();
|
||||||
|
mNfcAid = nfcGetAid();
|
||||||
|
}
|
||||||
|
|
||||||
final long subKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(nfcFingerprints);
|
protected void onNfcPostExecute() throws IOException {
|
||||||
|
|
||||||
|
final long subKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CachedPublicKeyRing ring = new ProviderHelper(this).getCachedPublicKeyRing(
|
CachedPublicKeyRing ring = new ProviderHelper(this).getCachedPublicKeyRing(
|
||||||
@@ -335,18 +376,17 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
|||||||
|
|
||||||
Intent intent = new Intent(this, ViewKeyActivity.class);
|
Intent intent = new Intent(this, ViewKeyActivity.class);
|
||||||
intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, nfcAid);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, mNfcAid);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, nfcUserId);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId);
|
||||||
intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, nfcFingerprints);
|
intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} catch (PgpKeyNotFoundException e) {
|
} catch (PgpKeyNotFoundException e) {
|
||||||
Intent intent = new Intent(this, CreateKeyActivity.class);
|
Intent intent = new Intent(this, CreateKeyActivity.class);
|
||||||
intent.putExtra(CreateKeyActivity.EXTRA_NFC_AID, nfcAid);
|
intent.putExtra(CreateKeyActivity.EXTRA_NFC_AID, mNfcAid);
|
||||||
intent.putExtra(CreateKeyActivity.EXTRA_NFC_USER_ID, nfcUserId);
|
intent.putExtra(CreateKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId);
|
||||||
intent.putExtra(CreateKeyActivity.EXTRA_NFC_FINGERPRINTS, nfcFingerprints);
|
intent.putExtra(CreateKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the key id from application specific data stored on tag, or null
|
/** Return the key id from application specific data stored on tag, or null
|
||||||
@@ -608,7 +648,7 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
|||||||
* conformance to the card's requirements for key length.
|
* conformance to the card's requirements for key length.
|
||||||
*
|
*
|
||||||
* @param pw For PW1, this is 0x81. For PW3 (Admin PIN), mode is 0x83.
|
* @param pw For PW1, this is 0x81. For PW3 (Admin PIN), mode is 0x83.
|
||||||
* @param newPinString The new PW1 or PW3.
|
* @param newPin The new PW1 or PW3.
|
||||||
*/
|
*/
|
||||||
public void nfcModifyPIN(int pw, byte[] newPin) throws IOException {
|
public void nfcModifyPIN(int pw, byte[] newPin) throws IOException {
|
||||||
final int MAX_PW1_LENGTH_INDEX = 1;
|
final int MAX_PW1_LENGTH_INDEX = 1;
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 344 KiB After Width: | Height: | Size: 340 KiB |
@@ -1,35 +1,86 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:custom="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<include
|
<org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator
|
||||||
android:id="@+id/toolbar_include"
|
android:id="@+id/view_animator"
|
||||||
layout="@layout/toolbar_standalone" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_below="@id/toolbar_include"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:animateLayoutChanges="true"
|
||||||
android:paddingLeft="16dp"
|
android:inAnimation="@anim/fade_in"
|
||||||
android:paddingRight="16dp"
|
android:measureAllChildren="false"
|
||||||
|
android:minHeight="?listPreferredItemHeightSmall"
|
||||||
|
android:outAnimation="@anim/fade_out"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
|
android:paddingLeft="24dp"
|
||||||
|
android:paddingRight="24dp"
|
||||||
android:paddingTop="16dp"
|
android:paddingTop="16dp"
|
||||||
android:paddingBottom="16dp">
|
custom:initialView="0">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:text="@string/nfc_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="@android:style/TextAppearance.Large"
|
|
||||||
android:id="@+id/nfc_text"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_gravity="center" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:src="@drawable/yubikey_phone" />
|
android:layout_below="@id/toolbar_include"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
</LinearLayout>
|
<TextView
|
||||||
</RelativeLayout>
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/nfc_text"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Medium" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:src="@drawable/yubikey_phone"
|
||||||
|
android:id="@+id/nfc_image"
|
||||||
|
android:background="@android:color/transparent" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/toolbar_include"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/nfc_wait"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Medium" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
style="?android:attr/progressBarStyleLarge"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="8dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/toolbar_include"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/nfc_finished"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Medium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -225,7 +225,9 @@
|
|||||||
<string name="passphrase_for">"Enter password for '%s'"</string>
|
<string name="passphrase_for">"Enter password for '%s'"</string>
|
||||||
<string name="pin_for">"Enter PIN for '%s'"</string>
|
<string name="pin_for">"Enter PIN for '%s'"</string>
|
||||||
<string name="yubikey_pin_for">"Enter PIN to access YubiKey for '%s'"</string>
|
<string name="yubikey_pin_for">"Enter PIN to access YubiKey for '%s'"</string>
|
||||||
<string name="nfc_text">"Hold YubiKey against the back of your device."</string>
|
<string name="nfc_text">"Hold YubiKey against the NFC marker at the back of your device."</string>
|
||||||
|
<string name="nfc_wait">"Don't release the YubiKey yet!"</string>
|
||||||
|
<string name="nfc_finished">"Success"</string>
|
||||||
<string name="file_delete_confirmation_title">"Delete original files?"</string>
|
<string name="file_delete_confirmation_title">"Delete original files?"</string>
|
||||||
<string name="file_delete_confirmation">"The following files will be deleted:%s"</string>
|
<string name="file_delete_confirmation">"The following files will be deleted:%s"</string>
|
||||||
<string name="file_delete_successful">"%1$d out of %2$d files have been deleted.%3$s"</string>
|
<string name="file_delete_successful">"%1$d out of %2$d files have been deleted.%3$s"</string>
|
||||||
|
|||||||
@@ -35,4 +35,9 @@
|
|||||||
<!-- Layout for query suggestion rows -->
|
<!-- Layout for query suggestion rows -->
|
||||||
<!--<item name="suggestionRowLayout">...</item>-->
|
<!--<item name="suggestionRowLayout">...</item>-->
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="KeychainTheme.DialogWithoutTitle" parent="@style/Theme.AppCompat.Light.Dialog.MinWidth">
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user