diff options
author | Nikita Mikhailov <nikita.s.mikhailov@gmail.com> | 2016-04-08 00:41:53 +0600 |
---|---|---|
committer | Nikita Mikhailov <nikita.s.mikhailov@gmail.com> | 2016-04-14 22:48:01 +0600 |
commit | b5eb6468fecfc16ea041eb0f4bf48c37ec2e81f2 (patch) | |
tree | d9ee439e49649dfdbc81d61431bca22e48d85c34 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui | |
parent | 3798249570e97861793f5d0ebc695d94e8d5ddcd (diff) | |
download | open-keychain-b5eb6468fecfc16ea041eb0f4bf48c37ec2e81f2.tar.gz open-keychain-b5eb6468fecfc16ea041eb0f4bf48c37ec2e81f2.tar.bz2 open-keychain-b5eb6468fecfc16ea041eb0f4bf48c37ec2e81f2.zip |
OTG: Add support for persistent usb connection
No need to reinsert token on each operation
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui')
3 files changed, 68 insertions, 72 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java index a0e93ed85..aba06ac47 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java @@ -249,9 +249,9 @@ public class CreateSecurityTokenImportResetFragment @Override public void doNfcInBackground() throws IOException { - mTokenFingerprints = mCreateKeyActivity.mSmartcardDevice.getFingerprints(); - mTokenAid = mCreateKeyActivity.mSmartcardDevice.getAid(); - mTokenUserId = mCreateKeyActivity.mSmartcardDevice.getUserId(); + mTokenFingerprints = mCreateKeyActivity.getSmartcardDevice().getFingerprints(); + mTokenAid = mCreateKeyActivity.getSmartcardDevice().getAid(); + mTokenUserId = mCreateKeyActivity.getSmartcardDevice().getUserId(); byte[] fp = new byte[20]; ByteBuffer.wrap(fp).put(mTokenFingerprints, 0, 20); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java index c68936577..5f0093678 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java @@ -140,6 +140,32 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenNfcActivity if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_MOVE_KEY_TO_CARD && mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_RESET_CARD) { obtainSecurityTokenPin(mRequiredInput); + checkPinAvailability(); + } else { + // No need for pin, rescan USB devices + mUsbDispatcher.rescanDevices(); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (REQUEST_CODE_PIN == requestCode) { + checkPinAvailability(); + } + } + + private void checkPinAvailability() { + try { + Passphrase passphrase = PassphraseCacheService.getCachedPassphrase(this, + mRequiredInput.getMasterKeyId(), mRequiredInput.getSubKeyId()); + if (passphrase != null) { + // Rescan USB devices + mUsbDispatcher.rescanDevices(); + } + } catch (PassphraseCacheService.KeyNotFoundException e) { + throw new AssertionError( + "tried to find passphrase for non-existing key. this is a programming error!"); } } @@ -275,28 +301,33 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenNfcActivity nfcGuideView.setCurrentStatus(NfcGuideView.NfcGuideViewStatus.DONE); - new AsyncTask<Void, Void, Void>() { - @Override - protected Void doInBackground(Void... params) { - // check all 200ms if Security Token has been taken away - while (true) { - if (isNfcConnected()) { - try { - Thread.sleep(200); - } catch (InterruptedException ignored) { + if (mSmartcardDevice.allowPersistentConnection()) { + // Just close + finish(); + } else { + new AsyncTask<Void, Void, Void>() { + @Override + protected Void doInBackground(Void... params) { + // check all 200ms if Security Token has been taken away + while (true) { + if (isNfcConnected()) { + try { + Thread.sleep(200); + } catch (InterruptedException ignored) { + } + } else { + return null; } - } else { - return null; } } - } - @Override - protected void onPostExecute(Void result) { - super.onPostExecute(result); - finish(); - } - }.execute(); + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + finish(); + } + }.execute(); + } } /** diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenNfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenNfcActivity.java index a6f8c0b0f..ecec98aaf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenNfcActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenNfcActivity.java @@ -31,7 +31,6 @@ import android.nfc.TagLostException; import android.os.AsyncTask; import android.os.Bundle; -import org.bouncycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; @@ -41,9 +40,9 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; -import org.sufficientlysecure.keychain.smartcard.SmartcardDevice; import org.sufficientlysecure.keychain.smartcard.NfcTransport; import org.sufficientlysecure.keychain.smartcard.OnDiscoveredUsbDeviceListener; +import org.sufficientlysecure.keychain.smartcard.SmartcardDevice; import org.sufficientlysecure.keychain.smartcard.UsbConnectionManager; import org.sufficientlysecure.keychain.smartcard.UsbTransport; import org.sufficientlysecure.keychain.ui.CreateKeyActivity; @@ -72,7 +71,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity private static final String FIDESMO_APP_PACKAGE = "com.fidesmo.sec.android"; - public SmartcardDevice mSmartcardDevice = new SmartcardDevice(); + protected SmartcardDevice mSmartcardDevice = SmartcardDevice.getInstance(); protected TagDispatcher mTagDispatcher; protected UsbConnectionManager mUsbDispatcher; private boolean mTagHandlingEnabled; @@ -175,7 +174,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity public void usbDeviceDiscovered(final UsbDevice device) { - // Actual NFC operations are executed in doInBackground to not block the UI thread + // Actual USB operations are executed in doInBackground to not block the UI thread if (!mTagHandlingEnabled) return; new AsyncTask<Void, Void, IOException>() { @@ -372,7 +371,6 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity Log.d(Constants.TAG, "BaseNfcActivity.onPause"); mTagDispatcher.disableExclusiveNfc(); -// mUsbDispatcher.stopListeningForDevices(); } /** @@ -453,10 +451,15 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity } protected void handleUsbDevice(UsbDevice device) throws IOException { - UsbManager usbManager = (UsbManager) getSystemService(USB_SERVICE); - mSmartcardDevice.setTransport(new UsbTransport(device, usbManager)); - mSmartcardDevice.connectToDevice(); - + // Don't reconnect if device was already connected + if (!mSmartcardDevice.isConnected() + || !(mSmartcardDevice.getTransport() instanceof UsbTransport) + || !((UsbTransport) mSmartcardDevice.getTransport()).getUsbDevice().equals(device)) { + UsbManager usbManager = (UsbManager) getSystemService(USB_SERVICE); + + mSmartcardDevice.setTransport(new UsbTransport(device, usbManager)); + mSmartcardDevice.connectToDevice(); + } doNfcInBackground(); } @@ -464,48 +467,6 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity return mSmartcardDevice.isConnected(); } - /** - * Parses out the status word from a JavaCard response string. - * - * @param response A hex string with the response from the token - * @return A short indicating the SW1/SW2, or 0 if a status could not be determined. - */ - short parseCardStatus(String response) { - if (response.length() < 4) { - return 0; // invalid input - } - - try { - return Short.parseShort(response.substring(response.length() - 4), 16); - } catch (NumberFormatException e) { - return 0; - } - } - - public String getHolderName(String name) { - try { - String slength; - int ilength; - name = name.substring(6); - slength = name.substring(0, 2); - ilength = Integer.parseInt(slength, 16) * 2; - name = name.substring(2, ilength + 2); - name = (new String(Hex.decode(name))).replace('<', ' '); - return name; - } catch (IndexOutOfBoundsException e) { - // try-catch for https://github.com/FluffyKaon/OpenPGP-Card - // Note: This should not happen, but happens with - // https://github.com/FluffyKaon/OpenPGP-Card, thus return an empty string for now! - - Log.e(Constants.TAG, "Couldn't get holder name, returning empty string!", e); - return ""; - } - } - - public static String getHex(byte[] raw) { - return new String(Hex.encode(raw)); - } - public class IsoDepNotSupportedException extends IOException { public IsoDepNotSupportedException(String detailMessage) { @@ -575,4 +536,8 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity super.onStart(); mUsbDispatcher.onStart(); } + + public SmartcardDevice getSmartcardDevice() { + return mSmartcardDevice; + } } |