我正在为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之后读取/写入特征。
答案 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
);