2014-06-17 13:31:09

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH 1/3] android/gatt: Move get_sec_level function

This will be used in read and write handlers functions.
---
android/gatt.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index a19fe5c..9531577 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -2715,6 +2715,22 @@ static void read_char_cb(guint8 status, const guint8 *pdu, guint16 len,
free(data);
}

+static int get_sec_level(struct gatt_device *dev)
+{
+ GIOChannel *io;
+ int sec_level;
+
+ io = g_attrib_get_channel(dev->attrib);
+
+ if (!bt_io_get(io, NULL, BT_IO_OPT_SEC_LEVEL, &sec_level,
+ BT_IO_OPT_INVALID)) {
+ error("gatt: Failed to get sec_level");
+ return -1;
+ }
+
+ return sec_level;
+}
+
static void handle_client_read_characteristic(const void *buf, uint16_t len)
{
const struct hal_cmd_gatt_client_read_characteristic *cmd = buf;
@@ -2835,22 +2851,6 @@ static bool signed_write_cmd(struct gatt_device *dev, uint16_t handle,
return true;
}

-static int get_sec_level(struct gatt_device *dev)
-{
- GIOChannel *io;
- int sec_level;
-
- io = g_attrib_get_channel(dev->attrib);
-
- if (!bt_io_get(io, NULL, BT_IO_OPT_SEC_LEVEL, &sec_level,
- BT_IO_OPT_INVALID)) {
- error("gatt: Failed to get sec_level");
- return -1;
- }
-
- return sec_level;
-}
-
static void handle_client_write_characteristic(const void *buf, uint16_t len)
{
const struct hal_cmd_gatt_client_write_characteristic *cmd = buf;
--
1.9.3



2014-06-17 19:57:11

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH 1/3] android/gatt: Move get_sec_level function

Hi Marcin,

On Tuesday 17 June 2014 15:31:09 Marcin Kraglak wrote:
> This will be used in read and write handlers functions.
> ---
> android/gatt.c | 32 ++++++++++++++++----------------
> 1 file changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/android/gatt.c b/android/gatt.c
> index a19fe5c..9531577 100644
> --- a/android/gatt.c
> +++ b/android/gatt.c
> @@ -2715,6 +2715,22 @@ static void read_char_cb(guint8 status, const guint8
> *pdu, guint16 len, free(data);
> }
>
> +static int get_sec_level(struct gatt_device *dev)
> +{
> + GIOChannel *io;
> + int sec_level;
> +
> + io = g_attrib_get_channel(dev->attrib);
> +
> + if (!bt_io_get(io, NULL, BT_IO_OPT_SEC_LEVEL, &sec_level,
> + BT_IO_OPT_INVALID)) {
> + error("gatt: Failed to get sec_level");
> + return -1;
> + }
> +
> + return sec_level;
> +}
> +
> static void handle_client_read_characteristic(const void *buf, uint16_t
> len) {
> const struct hal_cmd_gatt_client_read_characteristic *cmd = buf;
> @@ -2835,22 +2851,6 @@ static bool signed_write_cmd(struct gatt_device *dev,
> uint16_t handle, return true;
> }
>
> -static int get_sec_level(struct gatt_device *dev)
> -{
> - GIOChannel *io;
> - int sec_level;
> -
> - io = g_attrib_get_channel(dev->attrib);
> -
> - if (!bt_io_get(io, NULL, BT_IO_OPT_SEC_LEVEL, &sec_level,
> - BT_IO_OPT_INVALID)) {
> - error("gatt: Failed to get sec_level");
> - return -1;
> - }
> -
> - return sec_level;
> -}
> -
> static void handle_client_write_characteristic(const void *buf, uint16_t
> len) {
> const struct hal_cmd_gatt_client_write_characteristic *cmd = buf;

This patch is now applied. Thanks.

--
Szymon K. Janc
[email protected]

2014-06-17 19:52:09

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH 3/3] android/gatt: Set security level if user requested

Hi Marcin,

On Tuesday 17 June 2014 15:31:11 Marcin Kraglak wrote:
> Set security level if user requested. It is used when frameworks receives
> INSUFFICIENT_ENCRYPTION or INSUFFICIENT_AUTHENTICATIONS errors on read/write
> requests and tries to elevate security.
> ---
> android/gatt.c | 72
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed,
> 72 insertions(+)
>
> diff --git a/android/gatt.c b/android/gatt.c
> index 9531577..b958167 100644
> --- a/android/gatt.c
> +++ b/android/gatt.c
> @@ -2731,6 +2731,52 @@ static int get_sec_level(struct gatt_device *dev)
> return sec_level;
> }
>
> +static bool set_security(struct gatt_device *device, int security)
> +{
> + int req_sec_level, sec_level;
> + GError *gerr = NULL;
> + GIOChannel *io;
> +
> + if (security < HAL_AUTHENTICATION_NONE ||
> + security > HAL_AUTHENTICATION_MITM) {
> + error("gatt: Invalid security value: %d", security);
> + return false;
> + }

Mmove this into default case in switch below.

> +
> + switch (security) {
> + case HAL_AUTHENTICATION_MITM:
> + req_sec_level = BT_SECURITY_HIGH;
> + break;
> + case HAL_AUTHENTICATION_NO_MITM:
> + req_sec_level = BT_SECURITY_MEDIUM;
> + break;
> + case HAL_AUTHENTICATION_NONE:
> + req_sec_level = BT_SECURITY_LOW;
> + break;
> + }
> +
> + sec_level = get_sec_level(device);
> + if (sec_level < 0)
> + return false;
> +
> + if (req_sec_level <= sec_level)
> + return true;
> +
> + io = g_attrib_get_channel(device->attrib);
> + if (!io)
> + return false;
> +
> + bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, req_sec_level,
> + BT_IO_OPT_INVALID);
> + if (gerr) {
> + error("%s\n", gerr->message);

Prefix error with "gatt: Failed to set..."

> + g_error_free(gerr);
> + return false;
> + }
> +
> + return true;
> +}
> +
> static void handle_client_read_characteristic(const void *buf, uint16_t
> len) {
> const struct hal_cmd_gatt_client_read_characteristic *cmd = buf;
> @@ -2771,6 +2817,13 @@ static void handle_client_read_characteristic(const
> void *buf, uint16_t len) goto failed;
> }
>
> + if (!set_security(conn->device, cmd->auth_req)) {
> + error("gatt: Failed to set security %d", cmd->auth_req);
> + status = HAL_STATUS_FAILED;
> + free(cb_data);
> + goto failed;
> + }
> +
> if (!gatt_read_char(conn->device->attrib, ch->ch.value_handle,
> read_char_cb, cb_data)) {
> error("gatt: Cannot read characteristic with inst_id: %d",
> @@ -2898,6 +2951,12 @@ static void handle_client_write_characteristic(const
> void *buf, uint16_t len) }
> }
>
> + if (!set_security(conn->device, cmd->auth_req)) {
> + error("gatt: Failed to set security %d", cmd->auth_req);
> + status = HAL_STATUS_FAILED;
> + goto failed;
> + }
> +
> switch (cmd->write_type) {
> case GATT_WRITE_TYPE_NO_RESPONSE:
> res = gatt_write_cmd(conn->device->attrib, ch->ch.value_handle,
> @@ -3099,6 +3158,13 @@ static void handle_client_read_descriptor(const void
> *buf, uint16_t len) goto failed;
> }
>
> + if (!set_security(conn->device, cmd->auth_req)) {
> + error("gatt: Failed to set security %d", cmd->auth_req);
> + status = HAL_STATUS_FAILED;
> + free(cb_data);
> + goto failed;
> + }
> +
> if (!gatt_read_char(conn->device->attrib, descr->handle, read_desc_cb,
> cb_data)) {
> free(cb_data);
> @@ -3224,6 +3290,12 @@ static void handle_client_write_descriptor(const void
> *buf, uint16_t len) }
> }
>
> + if (!set_security(conn->device, cmd->auth_req)) {
> + error("gatt: Failed to set security %d", cmd->auth_req);
> + status = HAL_STATUS_FAILED;
> + goto failed;
> + }
> +
> switch (cmd->write_type) {
> case GATT_WRITE_TYPE_NO_RESPONSE:
> res = gatt_write_cmd(conn->device->attrib, descr->handle,

--
Szymon K. Janc
[email protected]

2014-06-17 13:31:11

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH 3/3] android/gatt: Set security level if user requested

Set security level if user requested. It is used when frameworks receives
INSUFFICIENT_ENCRYPTION or INSUFFICIENT_AUTHENTICATIONS errors on read/write
requests and tries to elevate security.
---
android/gatt.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)

diff --git a/android/gatt.c b/android/gatt.c
index 9531577..b958167 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -2731,6 +2731,52 @@ static int get_sec_level(struct gatt_device *dev)
return sec_level;
}

+static bool set_security(struct gatt_device *device, int security)
+{
+ int req_sec_level, sec_level;
+ GError *gerr = NULL;
+ GIOChannel *io;
+
+ if (security < HAL_AUTHENTICATION_NONE ||
+ security > HAL_AUTHENTICATION_MITM) {
+ error("gatt: Invalid security value: %d", security);
+ return false;
+ }
+
+ switch (security) {
+ case HAL_AUTHENTICATION_MITM:
+ req_sec_level = BT_SECURITY_HIGH;
+ break;
+ case HAL_AUTHENTICATION_NO_MITM:
+ req_sec_level = BT_SECURITY_MEDIUM;
+ break;
+ case HAL_AUTHENTICATION_NONE:
+ req_sec_level = BT_SECURITY_LOW;
+ break;
+ }
+
+ sec_level = get_sec_level(device);
+ if (sec_level < 0)
+ return false;
+
+ if (req_sec_level <= sec_level)
+ return true;
+
+ io = g_attrib_get_channel(device->attrib);
+ if (!io)
+ return false;
+
+ bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, req_sec_level,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s\n", gerr->message);
+ g_error_free(gerr);
+ return false;
+ }
+
+ return true;
+}
+
static void handle_client_read_characteristic(const void *buf, uint16_t len)
{
const struct hal_cmd_gatt_client_read_characteristic *cmd = buf;
@@ -2771,6 +2817,13 @@ static void handle_client_read_characteristic(const void *buf, uint16_t len)
goto failed;
}

+ if (!set_security(conn->device, cmd->auth_req)) {
+ error("gatt: Failed to set security %d", cmd->auth_req);
+ status = HAL_STATUS_FAILED;
+ free(cb_data);
+ goto failed;
+ }
+
if (!gatt_read_char(conn->device->attrib, ch->ch.value_handle,
read_char_cb, cb_data)) {
error("gatt: Cannot read characteristic with inst_id: %d",
@@ -2898,6 +2951,12 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
}
}

+ if (!set_security(conn->device, cmd->auth_req)) {
+ error("gatt: Failed to set security %d", cmd->auth_req);
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+
switch (cmd->write_type) {
case GATT_WRITE_TYPE_NO_RESPONSE:
res = gatt_write_cmd(conn->device->attrib, ch->ch.value_handle,
@@ -3099,6 +3158,13 @@ static void handle_client_read_descriptor(const void *buf, uint16_t len)
goto failed;
}

+ if (!set_security(conn->device, cmd->auth_req)) {
+ error("gatt: Failed to set security %d", cmd->auth_req);
+ status = HAL_STATUS_FAILED;
+ free(cb_data);
+ goto failed;
+ }
+
if (!gatt_read_char(conn->device->attrib, descr->handle, read_desc_cb,
cb_data)) {
free(cb_data);
@@ -3224,6 +3290,12 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
}
}

+ if (!set_security(conn->device, cmd->auth_req)) {
+ error("gatt: Failed to set security %d", cmd->auth_req);
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+
switch (cmd->write_type) {
case GATT_WRITE_TYPE_NO_RESPONSE:
res = gatt_write_cmd(conn->device->attrib, descr->handle,
--
1.9.3


2014-06-17 13:31:10

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH 2/3] android/hal-msg: Add defines of HAL_AUTHENTICATION values

These values are are used in read characteristic/write characteristic
functions in gatt_client.
---
android/hal-msg.h | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 2c21a85..841f016 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -1610,3 +1610,7 @@ struct hal_ev_gatt_server_rsp_confirmation {
#define HAL_GATT_PERMISSION_WRITE_ENCRYPTED_MITM 0x0040
#define HAL_GATT_PERMISSION_WRITE_SIGNED 0x0080
#define HAL_GATT_PERMISSION_WRITE_SIGNED_MITM 0x0100
+
+#define HAL_AUTHENTICATION_NONE 0
+#define HAL_AUTHENTICATION_NO_MITM 1
+#define HAL_AUTHENTICATION_MITM 2
--
1.9.3