无法 read/write FIDO2 特征

Unable to read/write FIDO2 charactersitics

我正在为 FIDO2 构建一个 Android 验证器。我被 read/write 特征卡住了。我正在研究 Mac - Chrome 75。Chrome 可以检测到我的 Android BLE 验证器。在检测到我的 BLE 身份验证器后,onCharacteristicReadRequest() 从身份验证器端调用。在 onCharacteristicReadRequest() 中,我正在使用下面编写的代码,但此后客户端没有任何响应。

我试过版本为 0b01000000 的 U2F。它工作正常。当我移动 FIDO2 版本 0b100000 时,我遇到了这个问题。我正在宣传验证器的 fido 服务和设备信息服务。这两项服务都添加了 Thread.sleep(1000) 间隔。我无法按顺序添加这两项服务。当我依次添加这两个服务时,我得到 ArrayIndexOutofBoundException

我不知道这两个问题是否相互关联。如果我做错了什么,请纠正我。

{
...
}else if (characteristic.getUuid().equals(FidoUUIDConstants.FIDO_SERVICE_REVISION_BITFIELD)) {
    status = BluetoothGatt.GATT_SUCCESS;
    ByteBuffer bb = ByteBuffer.allocate(1);
    bb.order(ByteOrder.BIG_ENDIAN);
    bb.put((byte) (1 << 5));
    bytes = bb.array();
}
mGattServer.sendResponse(device, requestId, status, 0, bytes);

客户端应 read/write fidoServiceBitFieldversion 后的特征。

I couldn't add both services sequentially

我认为您可以像下面这样添加 device info service

gattServer = bleManager.openGattServer(this, new BluetoothGattServerCallback() {
    @Override
    public void onServiceAdded(int status, BluetoothGattService service) {
        if (service.getUuid().equals(FidoUUIDConstants.FIDO2_GATT_SERVICE)) {
            gattServer.addService(deviceInfoService);
        }
    }
});
gattServer.addService(fido2GattService)

对于特征fidoServiceRevisionBitfield,我只是在CTAP document的索引8.3.5.1. FIDO Service处简单地遵循了这条语句a device that only supports FIDO2 Rev 1 will only have a fidoServiceRevisionBitfield characteristic of length 1 with value 0x20.。因此,我的实施是:

if(characteristic.getUuid().equals(FIDO2GattService.SERVICE_REVISION_BITFIELD)) {
    status = BluetoothGatt.GATT_SUCCESS;
    bytes = new byte[] {0x20}
}
gattServer.sendResponse(device, requestId, status, 0, bytes);

您应该覆盖 BluetoothGattServerCallback 的所有方法

我认为您缺少 onDescriptorReadRequest、onDescriptorWriteRequest 实现。

@Override
public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
    if (descriptor.getCharacteristic().getUuid().equals(FIDO2GattService.CONTROL_POINT_UUID) &&
            descriptor.getUuid().equals(FIDO2GattService.CONTROL_POINT_DESCRIPTOR_UUID)) {
        gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[] {0x31, 0x2e, 0x32});
    } else {
        gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[] {0x00, 0x00});
    }
}
@Override
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
    gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
}

同意@Bao的关注。根据 CTAP 规范,您应该使用 READ/WRITE 权限定义每个特征对应的描述符。请注意,每个描述符的 UUID 都需要一个有效的 UUID 128 位格式。所有描述符都具有 READ 和 WRITE 权限。例如:

UUID CONTROL_POINT_DESCRIPTOR_UUID = UUID.fromString("00002901-0000-1000-8000-00805f9b34fb");
BluetoothGattDescriptor controlPointDescriptor = new BluetoothGattDescriptor(
    CONTROL_POINT_DESCRIPTOR_UUID,
    BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE
);