Linux BlueZ BLE GATT 服务加密+指示

问题描述 投票:0回答:1

我正在 Linux 中使用 Bluez 5.65 设置 BLE GATT 服务。我有自己的流程,与 BlueZ 源代码一起编译。在 makefile 中,我将其添加为另一个工具。我的新工具基于现有的 bluez“工具”gatt-service.c

我使用 Bluez 自己的 dbus 和 gdbus 接口与 bluetoothd 进程通信,就像 gatt-service 一样。该工具的整体设计与 gatt-service 相同。

我设法设置了一个具有两个特征的服务,一个用于写入服务,一个用于读取/指示回客户端。

我现在正在考虑添加配对,以启用加密和关键短语。我已经成功地与我的手机建立了配对连接,以便它可以对如下配置的两个特征执行写入和读取操作:

static const char *tx_characteristic_properties[] = { "encrypt-authenticated-read", "encrypt-authenticated-indicate", NULL };
static const char *rx_characteristic_properties[] = { "encrypt-authenticated-write", NULL };

这是我到目前为止添加的所有加密配置,但它似乎有效。在我成功将设备与服务配对之前,它不允许我读取或写入特征。到目前为止,我通过 bluetoothctl 手动进行配对,稍后我将考虑使其自动进行。

我当前的问题是,激活加密后,指示不再起作用。当我从手机上激活特征指示时,btmon 会吐出以下内容:

> ACL Data RX: Handle 68 flags 0x02 dlen 9                                                                                  #25387 [hci0] 75486.664071
      ATT: Write Request (0x12) len 4
        Handle: 0x009b Type: Client Characteristic Configuration (0x2902)
          Data: 0200
            Indication (0x02)
< ACL Data TX: Handle 68 flags 0x00 dlen 9                                                                                  #25388 [hci0] 75486.664606
      ATT: Error Response (0x01) len 4
        Write Request (0x12)
        Handle: 0x009b
        Error: Write Not Permitted (0x03)
> HCI Event: Number of Completed Packets (0x13) plen 5                                                                      #25389 [hci0] 75486.784052
        Num handles: 1
        Handle: 68 Address: 66:65:18:91:30:D5 (Resolvable)
          Identity type: Public (0x00)
          Identity: A8:79:8D:EB:B9:8B (OUI A8-79-8D)
        Count: 1

我的理解是,由于新的安全设置,我不再被允许修改 CCC 描述符来激活指示。如果这是正确的,我的问题是如何配置 CCC 以允许从配对设备写入/读取它?

到目前为止,我遵循 gatt-service.c 工具的设计。我没有为特征创建任何 CCC 描述符,它似乎会作为默认描述符自动添加到我添加的每个指示特征中。这可以在我用来测试连接的 Android BLE 扫描仪应用程序的屏幕截图中看到。



更新1:

gatt-database::parse_chrc_flags 负责根据用户发送的特征属性字符串进行初始 CCC 权限标志设置。

if (!strcmp("encrypt-authenticated-indicate", flag)) {
    *ccc_perm |= BT_ATT_PERM_WRITE_AUTHEN;
    *props |= BT_GATT_CHRC_PROP_INDICATE;

当我们稍后想要通过写入 CCC 描述符来激活指示时,gatt-server::check_permissions 将失败,因为 BT_ATT_PERM_WRITE 位未设置。

static uint8_t check_permissions(struct bt_gatt_server *server,
                struct gatt_db_attribute *attr, uint32_t mask)
{
    uint8_t enc_size;
    uint32_t perm;
    int security;

    perm = gatt_db_attribute_get_permissions(attr);
    
    if (perm && mask & BT_ATT_PERM_READ && !(perm & BT_ATT_PERM_READ))
        return BT_ATT_ERROR_READ_NOT_PERMITTED;

    if (perm && mask & BT_ATT_PERM_WRITE && !(perm & BT_ATT_PERM_WRITE))
        return BT_ATT_ERROR_WRITE_NOT_PERMITTED;

如果我修改 gatt-database::parse_chrc_flags 并通过设置 BT_ATT_PERM_WRITE 标志来初始化 ccc_perm,则权限检查将通过,并且指示也开始与 encrypt-authenticated-indicate 属性一起工作。要读取 CCC,我还需要添加 BT_ATT_PERM_READ 权限。

else if (!strcmp("encrypt-authenticated-indicate", flag)) {
            *ccc_perm |= BT_ATT_PERM_WRITE_AUTHEN;
            *ccc_perm |= BT_ATT_PERM_WRITE;
            *ccc_perm |= BT_ATT_PERM_READ;
            *props |= BT_GATT_CHRC_PROP_INDICATE;

考虑到我们最初设置了 BT_ATT_PERM_WRITE_AUTHEN,我认为权限检查应该集中在 BT_ATT_PERM_WRITE_AUTHEN 而不是 BT_ATT_PERM_WRITE。我想知道CCC写权限检查是否不知何故不理解我们处于权限写认证模式?

c linux service bluez bluetooth-gatt
1个回答
0
投票

我现在的假设是这是 BlueZ 中的一个错误。

最近添加的加密验证写入类型特征属性可能未正确设置 ccc_perm 所需的所有权限标志。

特性属性设置接口 gatt-database::parse_chrc_flags 只在 ccc_perm 中设置一个专门的写标志,而不是通用的 BT_ATT_PERM_WRITE 标志。

if (!strcmp("encrypt-authenticated-indicate", flag)) {
    *ccc_perm |= BT_ATT_PERM_WRITE_AUTHEN;
    *props |= BT_GATT_CHRC_PROP_INDICATE;

如果我们检查 gatt-database::parse_desc_flags 中的标志是如何设置的,我们可以看到 BT_ATT_PERM_WRITE 总是与更专门的写权限标志一起设置:

if (!strcmp("encrypt-authenticated-write", flag))
            *perm |= BT_ATT_PERM_WRITE | BT_ATT_PERM_WRITE_AUTHEN;

我会将其作为错误报告给 BlueZ github 存储库,除非其他人提出更好的解释:)

更新1

是的,这是一个问题。几个月前修好了。 https://github.com/bluez/bluez/issues/607

© www.soinside.com 2019 - 2024. All rights reserved.