无法读取/写入FIDO2特征

时间:2019-06-11 07:53:36

标签: android bluetooth-lowenergy android-authenticator webauthn fido

我正在为FIDO2构建一个Android身份验证器。我陷于读/写特性。我正在使用Mac-Chrome75。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);

客户端应该在预期fidoServiceBitFieldversion之后读取/写入特征。

3 个答案:

答案 0 :(得分:2)

  

我无法依次添加这两项服务

我认为您可以像下面这样添加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的索引a device that only supports FIDO2 Rev 1 will only have a fidoServiceRevisionBitfield characteristic of length 1 with value 0x20.处遵循了该语句8.3.5.1. FIDO Service。因此,我的实现是:

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

答案 1 :(得分:2)

您应该覆盖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);
}

答案 2 :(得分:2)

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

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
);
相关问题