From 3d538d885e0ed52640ea72d538fe1752a5ffe1f2 Mon Sep 17 00:00:00 2001 From: Nikita Mikhailov Date: Mon, 4 Apr 2016 01:31:14 +0600 Subject: OTG: Usb device manager fixes --- .../keychain/javacard/BaseJavacardDevice.java | 13 ++- .../javacard/CachingBaseJavacardDevice.java | 46 ----------- .../keychain/javacard/JavacardDevice.java | 2 + .../keychain/javacard/UsbConnectionManager.java | 94 ++++++++++++---------- .../ui/base/BaseSecurityTokenNfcActivity.java | 12 ++- 5 files changed, 74 insertions(+), 93 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/CachingBaseJavacardDevice.java (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/BaseJavacardDevice.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/BaseJavacardDevice.java index 46f4c0443..f81d234b3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/BaseJavacardDevice.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/BaseJavacardDevice.java @@ -22,7 +22,7 @@ public class BaseJavacardDevice implements JavacardDevice { private static final String FIDESMO_APPS_AID_PREFIX = "A000000617"; 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 final Transport mTransport; + private Transport mTransport; private Passphrase mPin; private Passphrase mAdminPin; @@ -32,8 +32,7 @@ public class BaseJavacardDevice implements JavacardDevice { private boolean mPw3Validated; private boolean mTagHandlingEnabled; - public BaseJavacardDevice(final Transport mTransport) { - this.mTransport = mTransport; + public BaseJavacardDevice() { } private static String getHex(byte[] raw) { @@ -528,6 +527,9 @@ public class BaseJavacardDevice implements JavacardDevice { String response = nfcCommunicate(apdu); + if (response.length() < 4) { + throw new CardException("Bad response", (short) 0); + } // split up response into signature and status String status = response.substring(response.length() - 4); String signature = response.substring(0, response.length() - 4); @@ -722,4 +724,9 @@ public class BaseJavacardDevice implements JavacardDevice { return fp; } + @Override + public void setTransport(Transport mTransport) { + this.mTransport = mTransport; + + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/CachingBaseJavacardDevice.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/CachingBaseJavacardDevice.java deleted file mode 100644 index 5ad157de1..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/CachingBaseJavacardDevice.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; -import org.sufficientlysecure.keychain.util.Passphrase; - -import java.io.IOException; - -public class CachingBaseJavacardDevice extends BaseJavacardDevice { - private byte[] mFingerprintsCache; - private String mUserIdCache; - private byte[] mAidCache; - - public CachingBaseJavacardDevice(final Transport mTransport) { - super(mTransport); - } - - @Override - public byte[] getFingerprints() throws IOException { - if (mFingerprintsCache == null) { - mFingerprintsCache = super.getFingerprints(); - } - return mFingerprintsCache; - } - - @Override - public String getUserId() throws IOException { - if (mUserIdCache == null) { - mUserIdCache = super.getUserId(); - } - return mUserIdCache; - } - - @Override - public byte[] getAid() throws IOException { - if (mAidCache == null) { - mAidCache = super.getAid(); - } - return mAidCache; - } - - @Override - public void changeKey(final CanonicalizedSecretKey secretKey, final Passphrase passphrase) throws IOException { - super.changeKey(secretKey, passphrase); - mFingerprintsCache = null; - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/JavacardDevice.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/JavacardDevice.java index 04c2c0006..63d4d2ad7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/JavacardDevice.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/JavacardDevice.java @@ -100,4 +100,6 @@ public interface JavacardDevice { * @param data The data to store in the object */ void putData(int dataObject, byte[] data) throws IOException; + + void setTransport(Transport mTransport); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbConnectionManager.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbConnectionManager.java index d140c771c..9dd3bc028 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbConnectionManager.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbConnectionManager.java @@ -8,6 +8,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; +import android.os.Handler; +import android.os.Looper; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.Log; @@ -17,50 +19,29 @@ import java.util.HashMap; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; public class UsbConnectionManager { private static final String LOG_TAG = UsbConnectionManager.class.getName(); private static final String ACTION_USB_PERMISSION = Constants.PACKAGE_NAME + ".USB_PERMITSSION"; - - private Activity mActivity; - private OnDiscoveredUsbDeviceListener mListener; private final Semaphore mRunning = new Semaphore(1); private final Set mProcessedDevices = Collections.newSetFromMap(new ConcurrentHashMap()); - - /** - * Receives broadcast when a supported USB device is attached, detached or - * when a permission to communicate to the device has been granted. - */ - private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); - String deviceName = usbDevice.getDeviceName(); - - if (ACTION_USB_PERMISSION.equals(action)) { - boolean permission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, - false); - Log.d(LOG_TAG, "ACTION_USB_PERMISSION: " + permission + " Device: " + deviceName); - - interceptIntent(intent); - - context.unregisterReceiver(mUsbReceiver); - } - } - }; - + private final AtomicBoolean mStopped = new AtomicBoolean(false); + private Activity mActivity; private final Thread mWatchThread = new Thread() { @Override public void run() { final UsbManager usbManager = (UsbManager) mActivity.getSystemService(Context.USB_SERVICE); - while (true) { - mRunning.acquireUninterruptibly(); + while (!mStopped.get()) { + try { + mRunning.acquire(); + } catch (InterruptedException e) { + } mRunning.release(); + if (mStopped.get()) return; // - final UsbDevice device = getDevice(usbManager); if (device != null && !mProcessedDevices.contains(device)) { mProcessedDevices.add(device); @@ -71,6 +52,7 @@ public class UsbConnectionManager { filter.addAction(ACTION_USB_PERMISSION); mActivity.registerReceiver(mUsbReceiver, filter); + Log.d(LOG_TAG, "Requesting permission for " + device.getDeviceName()); usbManager.requestPermission(device, PendingIntent.getBroadcast(mActivity, 0, intent, 0)); } @@ -81,6 +63,30 @@ public class UsbConnectionManager { } } }; + private OnDiscoveredUsbDeviceListener mListener; + /** + * Receives broadcast when a supported USB device is attached, detached or + * when a permission to communicate to the device has been granted. + */ + private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); + String deviceName = usbDevice.getDeviceName(); + + if (ACTION_USB_PERMISSION.equals(action)) { + boolean permission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, + false); + Log.d(LOG_TAG, "ACTION_USB_PERMISSION: " + permission + " Device: " + deviceName); + + interceptIntent(intent); + + context.unregisterReceiver(mUsbReceiver); + } + } + }; + private Handler handler = new Handler(Looper.getMainLooper()); public UsbConnectionManager(final Activity activity, final OnDiscoveredUsbDeviceListener listener) { this.mActivity = activity; @@ -89,6 +95,16 @@ public class UsbConnectionManager { mWatchThread.start(); } + private static UsbDevice getDevice(UsbManager manager) { + HashMap deviceList = manager.getDeviceList(); + for (UsbDevice device : deviceList.values()) { + if (device.getVendorId() == 0x1050 && device.getProductId() == 0x0112) { + return device; + } + } + return null; + } + public void startListeningForDevices() { mRunning.release(); } @@ -100,7 +116,7 @@ public class UsbConnectionManager { public void interceptIntent(final Intent intent) { if (intent == null || intent.getAction() == null) return; switch (intent.getAction()) { - case UsbManager.ACTION_USB_DEVICE_ATTACHED: { + /*case UsbManager.ACTION_USB_DEVICE_ATTACHED: { final UsbManager usbManager = (UsbManager) mActivity.getSystemService(Context.USB_SERVICE); final UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); Intent usbI = new Intent(mActivity, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); @@ -109,7 +125,7 @@ public class UsbConnectionManager { PendingIntent pi = PendingIntent.getActivity(mActivity, 0, usbI, PendingIntent.FLAG_CANCEL_CURRENT); usbManager.requestPermission(device, pi); break; - } + }*/ case ACTION_USB_PERMISSION: { UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (device != null) @@ -121,15 +137,11 @@ public class UsbConnectionManager { } } - private static UsbDevice getDevice(UsbManager manager) { - HashMap deviceList = manager.getDeviceList(); - for (UsbDevice device : deviceList.values()) { - Log.d(LOG_TAG, device.getDeviceName() + " " + device.getDeviceId()); - if (device.getVendorId() == 0x1050 && device.getProductId() == 0x0112) { - Log.d(LOG_TAG, device.getDeviceName() + " OK"); - return device; - } + public void onDestroy() { + mStopped.set(true); + try { + mActivity.unregisterReceiver(mUsbReceiver); + } catch (IllegalArgumentException ignore) { } - return null; } } 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 573123daf..e3c331b0b 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 @@ -74,7 +74,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity private static final String FIDESMO_APP_PACKAGE = "com.fidesmo.sec.android"; - public JavacardDevice mJavacardDevice; + public JavacardDevice mJavacardDevice = new BaseJavacardDevice(); protected TagDispatcher mTagDispatcher; protected UsbConnectionManager mUsbDispatcher; private boolean mTagHandlingEnabled; @@ -451,7 +451,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity throw new IsoDepNotSupportedException("Tag does not support ISO-DEP (ISO 14443-4)"); } - mJavacardDevice = new BaseJavacardDevice(new NfcTransport(isoCard)); + mJavacardDevice.setTransport(new NfcTransport(isoCard)); mJavacardDevice.connectToDevice(); doNfcInBackground(); @@ -459,7 +459,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity protected void handleUsbDevice(UsbDevice device) throws IOException { UsbManager usbManager = (UsbManager) getSystemService(USB_SERVICE); - mJavacardDevice = new BaseJavacardDevice(new UsbTransport(device, usbManager)); + mJavacardDevice.setTransport(new UsbTransport(device, usbManager)); mJavacardDevice.connectToDevice(); doNfcInBackground(); @@ -567,4 +567,10 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity } return mAppInstalled; } + + @Override + protected void onDestroy() { + super.onDestroy(); + mUsbDispatcher.onDestroy(); + } } -- cgit v1.2.3