Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PW_SID:555789] Optionally require security for notify/indicate #1017

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion doc/gatt-api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,14 @@ Properties string UUID [read-only]
Defines how the characteristic value can be used. See
Core spec "Table 3.5: Characteristic Properties bit
field", and "Table 3.8: Characteristic Extended
Properties bit field". Allowed values:
Properties bit field".

The "x-notify" and "x-indicate" flags restrict access
to notifications and indications by imposing write
restrictions on a characteristic's client
characteristic configuration descriptor.

Allowed values:

"broadcast"
"read"
Expand All @@ -267,10 +274,16 @@ Properties string UUID [read-only]
"writable-auxiliaries"
"encrypt-read"
"encrypt-write"
"encrypt-notify" (Server only)
"encrypt-indicate" (Server only)
"encrypt-authenticated-read"
"encrypt-authenticated-write"
"encrypt-authenticated-notify" (Server only)
"encrypt-authenticated-indicate" (Server only)
"secure-read" (Server only)
"secure-write" (Server only)
"secure-notify" (Server only)
"secure-indicate" (Server only)
"authorize"

uint16 Handle [read-write, optional] (Server Only)
Expand Down
42 changes: 38 additions & 4 deletions src/gatt-database.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions src/shared/att-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

/* GATT Characteristic Properties Bitfield values */
#define BT_GATT_CHRC_PROP_BROADCAST 0x01
Expand Down