Skip to content

Commit

Permalink
suppor FIDO2 devices
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamVe committed Nov 26, 2024
1 parent 998a263 commit b987eb1
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConfiguration;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Build;

Expand All @@ -48,6 +51,35 @@ final class UsbDeviceManager {

private static final org.slf4j.Logger logger = LoggerFactory.getLogger(UsbDeviceManager.class);

public static boolean isSupportedYubicoDevice(@Nullable UsbDevice device) {
return device != null && device.getVendorId() == YUBICO_VENDOR_ID;
}

public static boolean isSupportedDevice(@Nullable UsbDevice device) {
return isSupportedYubicoDevice(device) || isFidoUsbDevice(device);
}

private static boolean isFidoUsbDevice(@Nullable UsbDevice device) {
if (device == null) {
return false;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
for (int configIndex = 0; configIndex < device.getConfigurationCount(); configIndex++) {
UsbConfiguration configuration = device.getConfiguration(configIndex);
for (int i = 0; i < configuration.getInterfaceCount(); i++) {
UsbInterface usbInterface = configuration.getInterface(i);
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID &&
usbInterface.getInterfaceSubclass() == 0) {
return true;
}
}
}
}

return false;
}

private static synchronized UsbDeviceManager getInstance() {
if (instance == null) {
instance = new UsbDeviceManager();
Expand Down Expand Up @@ -81,7 +113,7 @@ private synchronized void addUsbListener(Context context, UsbDeviceListener list
intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(broadcastReceiver, intentFilter);
for (UsbDevice usbDevice : usbDevices) {
if (usbDevice.getVendorId() == YUBICO_VENDOR_ID) {
if (isSupportedDevice(usbDevice)) {
onDeviceAttach(usbDevice);
}
}
Expand Down Expand Up @@ -181,7 +213,7 @@ private class DeviceBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
UsbDevice usbDevice = getUsbManagerExtraDevice(intent);
if (usbDevice == null || usbDevice.getVendorId() != YUBICO_VENDOR_ID) {
if (!isSupportedDevice(usbDevice)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

package com.yubico.yubikit.android.transport.usb;

import static com.yubico.yubikit.android.transport.usb.UsbDeviceManager.YUBICO_VENDOR_ID;
import static com.yubico.yubikit.android.transport.usb.UsbDeviceManager.isSupportedDevice;
import static com.yubico.yubikit.android.transport.usb.UsbDeviceManager.isSupportedYubicoDevice;

import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
Expand Down Expand Up @@ -68,11 +69,13 @@ public class UsbYubiKeyDevice implements YubiKeyDevice, Closeable {
public UsbYubiKeyDevice(UsbManager usbManager, UsbDevice usbDevice)
throws IllegalArgumentException {

if (usbDevice.getVendorId() != YUBICO_VENDOR_ID) {
throw new IllegalArgumentException("Invalid vendor id");
if (!isSupportedDevice(usbDevice)) {
throw new IllegalArgumentException("Device not supported");
}

this.usbPid = UsbPid.fromValue(usbDevice.getProductId());
this.usbPid = isSupportedYubicoDevice(usbDevice)
? UsbPid.fromValue(usbDevice.getProductId())
: UsbPid.FIDO_SECURITY_KEY;

this.connectionManager = new ConnectionManager(usbManager, usbDevice);
this.usbDevice = usbDevice;
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/com/yubico/yubikit/core/UsbPid.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public enum UsbPid {
YK4_OTP_CCID(0x0405, YubiKeyType.YK4, UsbInterface.OTP | UsbInterface.CCID),
YK4_FIDO_CCID(0x0406, YubiKeyType.YK4, UsbInterface.FIDO | UsbInterface.CCID),
YK4_OTP_FIDO_CCID(0x0407, YubiKeyType.YK4, UsbInterface.OTP | UsbInterface.FIDO | UsbInterface.CCID),
YKP_OTP_FIDO(0x0410, YubiKeyType.YKP, UsbInterface.OTP | UsbInterface.FIDO);
YKP_OTP_FIDO(0x0410, YubiKeyType.YKP, UsbInterface.OTP | UsbInterface.FIDO),
FIDO_SECURITY_KEY(-1, YubiKeyType.FIDO_SECURITY_KEY, UsbInterface.FIDO);

public final int value;
public final YubiKeyType type;
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/com/yubico/yubikit/core/YubiKeyType.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public enum YubiKeyType {
NEO("YubiKey NEO"),
SKY("Security Key by Yubico"),
YKP("YubiKey Plus"),
YK4("YubiKey");
YK4("YubiKey"),
FIDO_SECURITY_KEY("Fido Security Key");

public final String name;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public void getYubiKey() throws InterruptedException {
? ((UsbYubiKeyDevice) device).getPid()
: null;


if (usbPid == UsbPid.FIDO_SECURITY_KEY) {
return;
}

try (SmartCardConnection connection = device.openConnection(SmartCardConnection.class)) {
final DeviceInfo deviceInfo = DeviceUtil.readInfo(connection, usbPid);
if (deviceInfo.getVersion().major == 0) {
Expand Down

0 comments on commit b987eb1

Please sign in to comment.