Merge pull request #1614 from fidesmo/feature-introduce-nfc-handling-via-nordpol
Use Nordpol for BaseNfcActivity
This commit is contained in:
@@ -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.15@aar'
|
||||||
|
compile 'com.fidesmo:nordpol-core:0.1.15'
|
||||||
|
|
||||||
// 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')
|
||||||
@@ -117,6 +121,8 @@ dependencyVerification {
|
|||||||
// 'OpenKeychain.extern:minidns:51e34ebab23ebd6bdd4cc681024040e5cfd2d713a51a4b209e4fbeaa73e5fe57',
|
// 'OpenKeychain.extern:minidns:51e34ebab23ebd6bdd4cc681024040e5cfd2d713a51a4b209e4fbeaa73e5fe57',
|
||||||
'com.android.support:support-annotations:f347a35b9748a4103b39a6714a77e2100f488d623fd6268e259c177b200e9d82',
|
'com.android.support:support-annotations:f347a35b9748a4103b39a6714a77e2100f488d623fd6268e259c177b200e9d82',
|
||||||
'com.squareup.okio:okio:114bdc1f47338a68bcbc95abf2f5cdc72beeec91812f2fcd7b521c1937876266',
|
'com.squareup.okio:okio:114bdc1f47338a68bcbc95abf2f5cdc72beeec91812f2fcd7b521c1937876266',
|
||||||
|
'com.fidesmo:nordpol-core:fe09e65379f2c7300b669ef7df2bfbde47729dac19edacc26b5ddb44b94ff67d',
|
||||||
|
'com.fidesmo:nordpol-android:012f93c2c78bd5e3b35af3e8a6676c4fac56755abee252dcfdbb8b35df19e3dd'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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, 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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user