linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: Dagan Martinez <dmartinez@starry.com>
Cc: "linux-bluetooth@vger.kernel.org" <linux-bluetooth@vger.kernel.org>
Subject: Re: [PATCH BlueZ v3 1/2] gatt: Allow GATT server to dicate CCC permissions
Date: Thu, 30 Sep 2021 13:25:20 -0700	[thread overview]
Message-ID: <CABBYNZ+mqHC3=8HRoALCUiJrns0yeVwKy92w1gt6rsfx__oVPw@mail.gmail.com> (raw)
In-Reply-To: <20210930150819.34270-2-dmartinez@starry.com>

Hi Dagan,

On Thu, Sep 30, 2021 at 8:24 AM Dagan Martinez <dmartinez@starry.com> wrote:
>
> Allow a GATT server to impose permissions/restrictions on a CCC by
> setting additional `X-notify` and `X-indicate` permissions on its
> associated characteristic.
>
> This allows a developer to require encryption/authentication in order
> for a GATT client to subscribe to server-initiated updates.
>
> Test procedure:
> Attempt to read/write with a "low" security level on an unprotected CCC
> using gatttool, and succeed
> Attempt to READ with a "low" security level on an protected CCC
> using gatttool, and succeed
> Attempt to WRITE with a "low" security level on an protected CCC
> using gatttool, and fail
> Attempt to read/write while paired on a protected CCC using
> `bluetoothctl`, and succeed
> ---
>  src/gatt-database.c    | 42 ++++++++++++++++++++++++++++++++++++++----
>  src/shared/att-types.h |  4 ++++
>  2 files changed, 42 insertions(+), 4 deletions(-)
>
> diff --git a/src/gatt-database.c b/src/gatt-database.c
> index 68f411ba4..fd4a39166 100644
> --- a/src/gatt-database.c
> +++ b/src/gatt-database.c
> @@ -1060,17 +1060,33 @@ service_add_ccc(struct gatt_db_attribute *service,
>                                 struct btd_gatt_database *database,
>                                 btd_gatt_database_ccc_write_t write_callback,
>                                 void *user_data,
> +                               uint32_t parent_permissions,
>                                 btd_gatt_database_destroy_t destroy)
>  {
>         struct gatt_db_attribute *ccc;
>         struct ccc_cb_data *ccc_cb;
>         bt_uuid_t uuid;
> +       uint32_t permissions;
>
>         ccc_cb = new0(struct ccc_cb_data, 1);
>
> +       /*
> +        * Provide a way for the permissions on a characteristic to dictate
> +        * the permissions on the CCC
> +        */
> +       permissions = BT_ATT_PERM_READ | BT_ATT_PERM_WRITE;
> +
> +       if (parent_permissions & BT_ATT_PERM_SERVER_INITIATED_UPDATE_ENCRYPT)
> +               permissions |= BT_ATT_PERM_WRITE_ENCRYPT;
> +
> +       if (parent_permissions & BT_ATT_PERM_SERVER_INITIATED_UPDATE_AUTHEN)
> +               permissions |= BT_ATT_PERM_WRITE_AUTHEN;
> +
> +       if (parent_permissions & BT_ATT_PERM_SERVER_INITIATED_UPDATE_SECURE)
> +               permissions |= BT_ATT_PERM_WRITE_SECURE;
> +
>         bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
> -       ccc = gatt_db_service_add_descriptor(service, &uuid,
> -                               BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
> +       ccc = gatt_db_service_add_descriptor(service, &uuid, permissions,
>                                 gatt_ccc_read_cb, gatt_ccc_write_cb, database);
>         if (!ccc) {
>                 error("Failed to create CCC entry in database");
> @@ -1227,7 +1243,7 @@ static void populate_gatt_service(struct btd_gatt_database *database)
>                                 NULL, NULL, database);
>
>         database->svc_chngd_ccc = service_add_ccc(service, database, NULL, NULL,
> -                                                                       NULL);
> +                                                                   0, NULL);
>
>         bt_uuid16_create(&uuid, GATT_CHARAC_CLI_FEAT);
>         database->cli_feat = gatt_db_service_add_characteristic(service,
> @@ -1690,6 +1706,24 @@ static bool parse_chrc_flags(DBusMessageIter *array, uint8_t *props,
>                         *perm |= BT_ATT_PERM_WRITE | BT_ATT_PERM_WRITE_SECURE;
>                 } else if (!strcmp("authorize", flag)) {
>                         *req_prep_authorization = true;
> +               } else if (!strcmp("encrypt-notify", flag)) {
> +                       *perm |= BT_ATT_PERM_SERVER_INITIATED_UPDATE_ENCRYPT;
> +                       *props |= BT_GATT_CHRC_PROP_NOTIFY;
> +               } else if (!strcmp("encrypt-authenticated-notify", flag)) {
> +                       *perm |= BT_ATT_PERM_SERVER_INITIATED_UPDATE_AUTHEN;
> +                       *props |= BT_GATT_CHRC_PROP_NOTIFY;
> +               } else if (!strcmp("secure-notify", flag)) {
> +                       *perm |= BT_ATT_PERM_SERVER_INITIATED_UPDATE_SECURE;
> +                       *props |= BT_GATT_CHRC_PROP_NOTIFY;
> +               } else if (!strcmp("encrypt-indicate", flag)) {
> +                       *perm |= BT_ATT_PERM_SERVER_INITIATED_UPDATE_ENCRYPT;
> +                       *props |= BT_GATT_CHRC_PROP_INDICATE;
> +               } else if (!strcmp("encrypt-authenticated-indicate", flag)) {
> +                       *perm |= BT_ATT_PERM_SERVER_INITIATED_UPDATE_AUTHEN;
> +                       *props |= BT_GATT_CHRC_PROP_INDICATE;
> +               } else if (!strcmp("secure-indicate", flag)) {
> +                       *perm |= BT_ATT_PERM_SERVER_INITIATED_UPDATE_SECURE;
> +                       *props |= BT_GATT_CHRC_PROP_INDICATE;
>                 } else {
>                         error("Invalid characteristic flag: %s", flag);
>                         return false;
> @@ -2796,7 +2830,7 @@ static bool database_add_ccc(struct external_service *service,
>                 return true;
>
>         chrc->ccc = service_add_ccc(service->attrib, service->app->database,
> -                                               ccc_write_cb, chrc, NULL);
> +                                       ccc_write_cb, chrc, chrc->perm, NULL);
>         if (!chrc->ccc) {
>                 error("Failed to create CCC entry for characteristic");
>                 return false;
> diff --git a/src/shared/att-types.h b/src/shared/att-types.h
> index a08b24155..eb5def503 100644
> --- a/src/shared/att-types.h
> +++ b/src/shared/att-types.h
> @@ -137,6 +137,10 @@ struct bt_att_pdu_error_rsp {
>                                         BT_ATT_PERM_WRITE_AUTHEN | \
>                                         BT_ATT_PERM_WRITE_ENCRYPT | \
>                                         BT_ATT_PERM_WRITE_SECURE)
> +/* Permissions to be applied to the CCC*/
> +#define BT_ATT_PERM_SERVER_INITIATED_UPDATE_ENCRYPT 0x0400
> +#define BT_ATT_PERM_SERVER_INITIATED_UPDATE_AUTHEN 0x0800
> +#define BT_ATT_PERM_SERVER_INITIATED_UPDATE_SECURE 0x1000

I don't think we really need these above, how about we do something
like the following:

https://gist.github.com/Vudentz/af6899625df3d83b62cfbc61bbd4b94b

That way we don't need to define more permissions since we can just
reuse the existing one which imo are easier to understand.

>  /* GATT Characteristic Properties Bitfield values */
>  #define BT_GATT_CHRC_PROP_BROADCAST                    0x01
> --
> 2.31.1

Btw, it would be great to have an example using the new flags in the
patch description, bluetoothctl> register-characteristic...


-- 
Luiz Augusto von Dentz

  reply	other threads:[~2021-09-30 20:25 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-30 15:08 [PATCH BlueZ v3 0/2] Optionally require security for notify/indicate Dagan Martinez
2021-09-30 15:08 ` [PATCH BlueZ v3 1/2] gatt: Allow GATT server to dicate CCC permissions Dagan Martinez
2021-09-30 20:25   ` Luiz Augusto von Dentz [this message]
2021-09-30 15:08 ` [PATCH BlueZ v3 2/2] doc/gatt-api: Add 'X-notify`/`X-indicate` Dagan Martinez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CABBYNZ+mqHC3=8HRoALCUiJrns0yeVwKy92w1gt6rsfx__oVPw@mail.gmail.com' \
    --to=luiz.dentz@gmail.com \
    --cc=dmartinez@starry.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).