From 5e18b15775f4c6d9c563d61a71143320620e968e Mon Sep 17 00:00:00 2001 From: Nikita Mikhailov Date: Wed, 6 Apr 2016 22:49:52 +0600 Subject: OTG: Rename 'javacard' package, methods, remove JavacardInterface --- .../keychain/javacard/CardException.java | 17 -- .../keychain/javacard/KeyType.java | 48 ----- .../keychain/javacard/NfcTransport.java | 31 --- .../javacard/OnDiscoveredUsbDeviceListener.java | 7 - .../keychain/javacard/PinException.java | 7 - .../keychain/javacard/PinType.java | 16 -- .../keychain/javacard/Transport.java | 11 - .../keychain/javacard/TransportIoException.java | 20 -- .../keychain/javacard/UsbConnectionManager.java | 150 -------------- .../keychain/javacard/UsbTransport.java | 226 --------------------- 10 files changed, 533 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/CardException.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/KeyType.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/NfcTransport.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/OnDiscoveredUsbDeviceListener.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/PinException.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/PinType.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/Transport.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/TransportIoException.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbConnectionManager.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbTransport.java (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/CardException.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/CardException.java deleted file mode 100644 index 3e9e9f2ca..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/CardException.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import java.io.IOException; - -public class CardException extends IOException { - private short mResponseCode; - - public CardException(String detailMessage, short responseCode) { - super(detailMessage); - mResponseCode = responseCode; - } - - public short getResponseCode() { - return mResponseCode; - } - -} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/KeyType.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/KeyType.java deleted file mode 100644 index e0190f8bd..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/KeyType.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; - -public enum KeyType { - SIGN(0, 0xB6, 0xCE, 0xC7), - ENCRYPT(1, 0xB8, 0xCF, 0xC8), - AUTH(2, 0xA4, 0xD0, 0xC9),; - - private final int mIdx; - private final int mSlot; - private final int mTimestampObjectId; - private final int mFingerprintObjectId; - - KeyType(final int idx, final int slot, final int timestampObjectId, final int fingerprintObjectId) { - this.mIdx = idx; - this.mSlot = slot; - this.mTimestampObjectId = timestampObjectId; - this.mFingerprintObjectId = fingerprintObjectId; - } - - public static KeyType from(final CanonicalizedSecretKey key) { - if (key.canSign() || key.canCertify()) { - return SIGN; - } else if (key.canEncrypt()) { - return ENCRYPT; - } else if (key.canAuthenticate()) { - return AUTH; - } - return null; - } - - public int getIdx() { - return mIdx; - } - - public int getmSlot() { - return mSlot; - } - - public int getTimestampObjectId() { - return mTimestampObjectId; - } - - public int getmFingerprintObjectId() { - return mFingerprintObjectId; - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/NfcTransport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/NfcTransport.java deleted file mode 100644 index 421b28aa8..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/NfcTransport.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import java.io.IOException; - -import nordpol.IsoCard; - -public class NfcTransport implements Transport { - // timeout is set to 100 seconds to avoid cancellation during calculation - private static final int TIMEOUT = 100 * 1000; - private final IsoCard mIsoCard; - - public NfcTransport(final IsoCard isoDep) throws IOException { - this.mIsoCard = isoDep; - mIsoCard.setTimeout(TIMEOUT); - mIsoCard.connect(); - } - - @Override - public byte[] sendAndReceive(final byte[] data) throws TransportIoException, IOException { - return mIsoCard.transceive(data); - } - - @Override - public void release() { - } - - @Override - public boolean isConnected() { - return mIsoCard.isConnected(); - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/OnDiscoveredUsbDeviceListener.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/OnDiscoveredUsbDeviceListener.java deleted file mode 100644 index 6104985be..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/OnDiscoveredUsbDeviceListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import android.hardware.usb.UsbDevice; - -public interface OnDiscoveredUsbDeviceListener { - void usbDeviceDiscovered(UsbDevice usbDevice); -} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/PinException.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/PinException.java deleted file mode 100644 index 84a34f116..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/PinException.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -public class PinException extends CardException { - public PinException(final String detailMessage, final short responseCode) { - super(detailMessage, responseCode); - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/PinType.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/PinType.java deleted file mode 100644 index b6787a9e1..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/PinType.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -public enum PinType { - BASIC(0x81), - ADMIN(0x83),; - - private final int mMode; - - PinType(final int mode) { - this.mMode = mode; - } - - public int getmMode() { - return mMode; - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/Transport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/Transport.java deleted file mode 100644 index 2d7dd3309..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/Transport.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import java.io.IOException; - -public interface Transport { - byte[] sendAndReceive(byte[] data) throws IOException; - - void release(); - - boolean isConnected(); -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/TransportIoException.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/TransportIoException.java deleted file mode 100644 index 2dfb7df94..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/TransportIoException.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import java.io.IOException; - -public class TransportIoException extends IOException { - public TransportIoException() { - } - - public TransportIoException(final String detailMessage) { - super(detailMessage); - } - - public TransportIoException(final String message, final Throwable cause) { - super(message, cause); - } - - public TransportIoException(final Throwable cause) { - super(cause); - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbConnectionManager.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbConnectionManager.java deleted file mode 100644 index 6b049159a..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbConnectionManager.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -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; - -import java.util.Collections; -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 final Semaphore mRunning = new Semaphore(1); - private final Set mProcessedDevices = Collections.newSetFromMap(new ConcurrentHashMap()); - 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 (!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); - - final Intent intent = new Intent(ACTION_USB_PERMISSION); - - IntentFilter filter = new IntentFilter(); - 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)); - } - - try { - sleep(1000); - } catch (InterruptedException ignored) { - } - } - } - }; - 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); - - if (permission) { - interceptIntent(intent); - } - - context.unregisterReceiver(mUsbReceiver); - } - } - }; - - public UsbConnectionManager(final Activity activity, final OnDiscoveredUsbDeviceListener listener) { - this.mActivity = activity; - this.mListener = listener; - mRunning.acquireUninterruptibly(); - mWatchThread.start(); - } - - private static UsbDevice getDevice(UsbManager manager) { - HashMap deviceList = manager.getDeviceList(); - for (UsbDevice device : deviceList.values()) { - if (device.getVendorId() == 0x1050 && (device.getProductId() == 0x0112 || device.getProductId() == 0x0115)) { - return device; - } - } - return null; - } - - public void startListeningForDevices() { - mRunning.release(); - } - - public void stopListeningForDevices() { - mRunning.acquireUninterruptibly(); - } - - public void interceptIntent(final Intent intent) { - if (intent == null || intent.getAction() == null) return; - switch (intent.getAction()) { - /*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); - usbI.setAction(ACTION_USB_PERMISSION); - usbI.putExtra(UsbManager.EXTRA_DEVICE, device); - 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) - mListener.usbDeviceDiscovered(device); - break; - } - default: - break; - } - } - - public void onDestroy() { - mStopped.set(true); - mRunning.release(); - try { - mActivity.unregisterReceiver(mUsbReceiver); - } catch (IllegalArgumentException ignore) { - } - mActivity = null; - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbTransport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbTransport.java deleted file mode 100644 index 07697f11e..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/javacard/UsbTransport.java +++ /dev/null @@ -1,226 +0,0 @@ -package org.sufficientlysecure.keychain.javacard; - -import android.hardware.usb.UsbConstants; -import android.hardware.usb.UsbDevice; -import android.hardware.usb.UsbDeviceConnection; -import android.hardware.usb.UsbEndpoint; -import android.hardware.usb.UsbInterface; -import android.hardware.usb.UsbManager; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.util.Pair; - -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.encoders.Hex; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class UsbTransport implements Transport { - private static final int CLASS_SMARTCARD = 11; - private static final int TIMEOUT = 20 * 1000; // 2 s - - private final UsbManager mUsbManager; - private final UsbDevice mUsbDevice; - private final UsbInterface mUsbInterface; - private final UsbEndpoint mBulkIn; - private final UsbEndpoint mBulkOut; - private final UsbDeviceConnection mConnection; - private byte mCounter = 0; - - public UsbTransport(final UsbDevice usbDevice, final UsbManager usbManager) throws TransportIoException { - mUsbDevice = usbDevice; - mUsbManager = usbManager; - - mUsbInterface = getSmartCardInterface(mUsbDevice); - // throw if mUsbInterface == null - final Pair ioEndpoints = getIoEndpoints(mUsbInterface); - mBulkIn = ioEndpoints.first; - mBulkOut = ioEndpoints.second; - // throw if any endpoint is null - - mConnection = mUsbManager.openDevice(mUsbDevice); - // throw if connection is null - mConnection.claimInterface(mUsbInterface, true); - // check result - - powerOn(); - - setTimings(); - } - - private void setTimings() throws TransportIoException { - byte[] data = { - 0x6C, - 0x00, 0x00, 0x00, 0x00, - 0x00, - mCounter++, - 0x00, 0x00, 0x00 - }; - sendRaw(data); - data = receive(); - - data[0] = 0x61; - data[1] = 0x04; - data[2] = data[3] = data[4] = 0x00; - data[5] = 0x00; - data[6] = mCounter++; - data[7] = 0x00; - data[8] = data[9] = 0x00; - - data[13] = 1; - - sendRaw(data); - receive(); - } - - private void powerOff() throws TransportIoException { - final byte[] iccPowerOff = { - 0x63, - 0x00, 0x00, 0x00, 0x00, - 0x00, - mCounter++, - 0x00, - 0x00, 0x00 - }; - sendRaw(iccPowerOff); - receive(); - } - - void powerOn() throws TransportIoException { - final byte[] iccPowerOn = { - 0x62, - 0x00, 0x00, 0x00, 0x00, - 0x00, - mCounter++, - 0x00, - 0x00, 0x00 - }; - sendRaw(iccPowerOn); - receive(); - } - - /** - * Get first class 11 (Chip/Smartcard) interface for the device - * - * @param device {@link UsbDevice} which will be searched - * @return {@link UsbInterface} of smartcard or null if it doesn't exist - */ - @Nullable - private static UsbInterface getSmartCardInterface(final UsbDevice device) { - for (int i = 0; i < device.getInterfaceCount(); i++) { - final UsbInterface anInterface = device.getInterface(i); - if (anInterface.getInterfaceClass() == CLASS_SMARTCARD) { - return anInterface; - } - } - return null; - } - - @NonNull - private static Pair getIoEndpoints(final UsbInterface usbInterface) { - UsbEndpoint bulkIn = null, bulkOut = null; - for (int i = 0; i < usbInterface.getEndpointCount(); i++) { - final UsbEndpoint endpoint = usbInterface.getEndpoint(i); - if (endpoint.getType() != UsbConstants.USB_ENDPOINT_XFER_BULK) { - continue; - } - - if (endpoint.getDirection() == UsbConstants.USB_DIR_IN) { - bulkIn = endpoint; - } else if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) { - bulkOut = endpoint; - } - } - return new Pair<>(bulkIn, bulkOut); - } - - @Override - public void release() { - mConnection.releaseInterface(mUsbInterface); - mConnection.close(); - } - - @Override - public boolean isConnected() { - // TODO: redo - return mUsbManager.getDeviceList().containsValue(mUsbDevice); - } - - @Override - public byte[] sendAndReceive(byte[] data) throws TransportIoException { - send(data); - byte[] bytes; - do { - bytes = receive(); - } while (isXfrBlockNotReady(bytes)); - - checkXfrBlockResult(bytes); - return Arrays.copyOfRange(bytes, 10, bytes.length); - } - - public void send(byte[] d) throws TransportIoException { - int l = d.length; - byte[] data = Arrays.concatenate(new byte[]{ - 0x6f, - (byte) l, (byte) (l >> 8), (byte) (l >> 16), (byte) (l >> 24), - 0x00, - mCounter++, - 0x00, - 0x00, 0x00}, - d); - - int send = 0; - while (send < data.length) { - final int len = Math.min(mBulkIn.getMaxPacketSize(), data.length - send); - sendRaw(Arrays.copyOfRange(data, send, send + len)); - send += len; - } - } - - public byte[] receive() throws TransportIoException { - byte[] buffer = new byte[mBulkIn.getMaxPacketSize()]; - byte[] result = null; - int readBytes = 0, totalBytes = 0; - - do { - int res = mConnection.bulkTransfer(mBulkIn, buffer, buffer.length, TIMEOUT); - if (res < 0) { - throw new TransportIoException("USB error, failed to receive response " + res); - } - if (result == null) { - if (res < 10) { - throw new TransportIoException("USB error, failed to receive ccid header"); - } - totalBytes = ByteBuffer.wrap(buffer, 1, 4).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get() + 10; - result = new byte[totalBytes]; - } - System.arraycopy(buffer, 0, result, readBytes, res); - readBytes += res; - } while (readBytes < totalBytes); - - return result; - } - - private void sendRaw(final byte[] data) throws TransportIoException { - final int tr1 = mConnection.bulkTransfer(mBulkOut, data, data.length, TIMEOUT); - if (tr1 != data.length) { - throw new TransportIoException("USB error, failed to send data " + tr1); - } - } - - private byte getStatus(byte[] bytes) { - return (byte) ((bytes[7] >> 6) & 0x03); - } - - private void checkXfrBlockResult(byte[] bytes) throws TransportIoException { - final byte status = getStatus(bytes); - if (status != 0) { - throw new TransportIoException("CCID error, status " + status + " error code: " + Hex.toHexString(bytes, 8, 1)); - } - } - - private boolean isXfrBlockNotReady(byte[] bytes) { - return getStatus(bytes) == 2; - } -} -- cgit v1.2.3