Use Nordpol for BaseNfcActivity

- Replace handling of intents with Nordpol tag dispatcher
- Update CreateKeyActivity to pass it's intent to the tag dispatcher
  when invoked by the system (onCreate)
- Add Fidesmo marmeladburk repository
- Add dependency on nordpol-android and nordpol-core
This commit is contained in:
Petter Arvidsson
2015-11-27 13:20:18 +01:00
parent 808a9e4f54
commit dd85bbb4b5
4 changed files with 35 additions and 61 deletions

View File

@@ -64,6 +64,10 @@ dependencies {
compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0' compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0'
compile 'com.cocosw:bottomsheet:1.2.0@aar' compile 'com.cocosw:bottomsheet:1.2.0@aar'
// Nordpol
compile 'com.fidesmo:nordpol-android:0.1.10@aar'
compile 'com.fidesmo:nordpol-core:0.1.10'
// libs as submodules // libs as submodules
compile project(':extern:openpgp-api-lib:openpgp-api') compile project(':extern:openpgp-api-lib:openpgp-api')
compile project(':extern:openkeychain-api-lib:openkeychain-intents') compile project(':extern:openkeychain-api-lib:openkeychain-intents')

View File

@@ -77,7 +77,7 @@ public class CreateKeyActivity extends BaseSecurityTokenNfcActivity {
// NOTE: ACTION_NDEF_DISCOVERED and not ACTION_TAG_DISCOVERED like in BaseNfcActivity // NOTE: ACTION_NDEF_DISCOVERED and not ACTION_TAG_DISCOVERED like in BaseNfcActivity
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
handleIntentInBackground(getIntent()); mTagDispatcher.interceptIntent(getIntent());
setTitle(R.string.title_manage_my_keys); setTitle(R.string.title_manage_my_keys);

View File

@@ -36,6 +36,11 @@ import android.nfc.tech.IsoDep;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import nordpol.android.TagDispatcher;
import nordpol.android.AndroidCard;
import nordpol.android.OnDiscoveredTagListener;
import nordpol.IsoCard;
import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.util.Arrays; import org.spongycastle.util.Arrays;
import org.spongycastle.util.encoders.Hex; import org.spongycastle.util.encoders.Hex;
@@ -61,8 +66,7 @@ import org.sufficientlysecure.keychain.util.Iso7816TLV;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Passphrase;
public abstract class BaseSecurityTokenNfcActivity extends BaseActivity { public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implements OnDiscoveredTagListener {
public static final int REQUEST_CODE_PIN = 1; public static final int REQUEST_CODE_PIN = 1;
public static final String EXTRA_TAG_HANDLING_ENABLED = "tag_handling_enabled"; public static final String EXTRA_TAG_HANDLING_ENABLED = "tag_handling_enabled";
@@ -73,8 +77,8 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
protected boolean mPw1ValidatedForSignature; protected boolean mPw1ValidatedForSignature;
protected boolean mPw1ValidatedForDecrypt; // Mode 82 does other things; consider renaming? protected boolean mPw1ValidatedForDecrypt; // Mode 82 does other things; consider renaming?
protected boolean mPw3Validated; protected boolean mPw3Validated;
private NfcAdapter mNfcAdapter; protected TagDispatcher mTagDispatcher;
private IsoDep mIsoDep; private IsoCard mIsoCard;
private boolean mTagHandlingEnabled; private boolean mTagHandlingEnabled;
private static final int TIMEOUT = 100000; private static final int TIMEOUT = 100000;
@@ -139,8 +143,10 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
onNfcError(error); onNfcError(error);
} }
public void handleIntentInBackground(final Intent intent) { public void tagDiscovered(final Tag tag) {
// Actual NFC operations are executed in doInBackground to not block the UI thread // Actual NFC operations are executed in doInBackground to not block the UI thread
if(!mTagHandlingEnabled)
return;
new AsyncTask<Void, Void, IOException>() { new AsyncTask<Void, Void, IOException>() {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
@@ -151,7 +157,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
@Override @Override
protected IOException doInBackground(Void... params) { protected IOException doInBackground(Void... params) {
try { try {
handleTagDiscoveredIntent(intent); handleTagDiscovered(tag);
} catch (IOException e) { } catch (IOException e) {
return e; return e;
} }
@@ -185,6 +191,8 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mTagDispatcher = TagDispatcher.get(this, this, false);
// Check whether we're recreating a previously destroyed instance // Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) { if (savedInstanceState != null) {
// Restore value of members from saved state // Restore value of members from saved state
@@ -214,10 +222,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
*/ */
@Override @Override
public void onNewIntent(final Intent intent) { public void onNewIntent(final Intent intent) {
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction()) mTagDispatcher.interceptIntent(intent);
&& mTagHandlingEnabled) {
handleIntentInBackground(intent);
}
} }
private void handleNfcError(IOException e) { private void handleNfcError(IOException e) {
@@ -320,7 +325,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
super.onPause(); super.onPause();
Log.d(Constants.TAG, "BaseNfcActivity.onPause"); Log.d(Constants.TAG, "BaseNfcActivity.onPause");
disableNfcForegroundDispatch(); mTagDispatcher.disableExclusiveNfc();
} }
/** /**
@@ -330,8 +335,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
Log.d(Constants.TAG, "BaseNfcActivity.onResume"); Log.d(Constants.TAG, "BaseNfcActivity.onResume");
mTagDispatcher.enableExclusiveNfc();
enableNfcForegroundDispatch();
} }
protected void obtainSecurityTokenPin(RequiredInputParcel requiredInput) { protected void obtainSecurityTokenPin(RequiredInputParcel requiredInput) {
@@ -388,17 +392,15 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
* on ISO SmartCard Systems specification. * on ISO SmartCard Systems specification.
* *
*/ */
protected void handleTagDiscoveredIntent(Intent intent) throws IOException { protected void handleTagDiscovered(Tag tag) throws IOException {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// Connect to the detected tag, setting a couple of settings // Connect to the detected tag, setting a couple of settings
mIsoDep = IsoDep.get(detectedTag); mIsoCard = AndroidCard.get(tag);
if (mIsoDep == null) { if (mIsoCard == null) {
throw new IsoDepNotSupportedException("Tag does not support ISO-DEP (ISO 14443-4)"); throw new IsoDepNotSupportedException("Tag does not support ISO-DEP (ISO 14443-4)");
} }
mIsoDep.setTimeout(TIMEOUT); // timeout is set to 100 seconds to avoid cancellation during calculation mIsoCard.setTimeout(TIMEOUT); // timeout is set to 100 seconds to avoid cancellation during calculation
mIsoDep.connect(); mIsoCard.connect();
// SW1/2 0x9000 is the generic "ok" response, which we expect most of the time. // SW1/2 0x9000 is the generic "ok" response, which we expect most of the time.
// See specification, page 51 // See specification, page 51
@@ -429,7 +431,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
} }
public boolean isNfcConnected() { public boolean isNfcConnected() {
return mIsoDep.isConnected(); return mIsoCard.isConnected();
} }
/** 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
@@ -457,7 +459,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
*/ */
public byte[] nfcGetFingerprints() throws IOException { public byte[] nfcGetFingerprints() throws IOException {
String data = "00CA006E00"; String data = "00CA006E00";
byte[] buf = mIsoDep.transceive(Hex.decode(data)); byte[] buf = mIsoCard.transceive(Hex.decode(data));
Iso7816TLV tlv = Iso7816TLV.readSingle(buf, true); Iso7816TLV tlv = Iso7816TLV.readSingle(buf, true);
Log.d(Constants.TAG, "nfcGetFingerprints() Iso7816TLV tlv data:\n" + tlv.prettyPrint()); Log.d(Constants.TAG, "nfcGetFingerprints() Iso7816TLV tlv data:\n" + tlv.prettyPrint());
@@ -476,7 +478,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
*/ */
public byte[] nfcGetPwStatusBytes() throws IOException { public byte[] nfcGetPwStatusBytes() throws IOException {
String data = "00CA00C400"; String data = "00CA00C400";
return mIsoDep.transceive(Hex.decode(data)); return mIsoCard.transceive(Hex.decode(data));
} }
/** Return the fingerprint from application specific data stored on tag, or /** Return the fingerprint from application specific data stored on tag, or
@@ -502,7 +504,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
public byte[] nfcGetAid() throws IOException { public byte[] nfcGetAid() throws IOException {
String info = "00CA004F00"; String info = "00CA004F00";
return mIsoDep.transceive(Hex.decode(info)); return mIsoCard.transceive(Hex.decode(info));
} }
public String nfcGetUserId() throws IOException { public String nfcGetUserId() throws IOException {
@@ -928,41 +930,6 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
} }
} }
/**
* Receive new NFC Intents to this activity only by enabling foreground dispatch.
* This can only be done in onResume!
*/
public void enableNfcForegroundDispatch() {
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
return;
}
Intent nfcI = new Intent(this, getClass())
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent nfcPendingIntent = PendingIntent.getActivity(this, 0, nfcI, PendingIntent.FLAG_CANCEL_CURRENT);
IntentFilter[] writeTagFilters = new IntentFilter[]{
new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
};
try {
mNfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null);
} catch (IllegalStateException e) {
Log.i(Constants.TAG, "NfcForegroundDispatch Exception: Activity is not currently in the foreground?", e);
}
Log.d(Constants.TAG, "NfcForegroundDispatch has been enabled!");
}
/**
* Disable foreground dispatch in onPause!
*/
public void disableNfcForegroundDispatch() {
if (mNfcAdapter == null) {
return;
}
mNfcAdapter.disableForegroundDispatch(this);
Log.d(Constants.TAG, "NfcForegroundDispatch has been disabled!");
}
public String nfcGetHolderName(String name) { public String nfcGetHolderName(String name) {
try { try {
String slength; String slength;
@@ -988,7 +955,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity {
} }
public String nfcCommunicate(String apdu) throws IOException { public String nfcCommunicate(String apdu) throws IOException {
return getHex(mIsoDep.transceive(Hex.decode(apdu))); return getHex(mIsoCard.transceive(Hex.decode(apdu)));
} }
public static String getHex(byte[] raw) { public static String getHex(byte[] raw) {

View File

@@ -23,6 +23,9 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
jcenter() jcenter()
maven {
url 'http://releases.marmeladburk.fidesmo.com'
}
} }
} }