nimble/att: Support "Insufficient Encryption" error code Access to attributes which require encryption (so this also includes authentication) on an unencrypted link should check if there is LTK available. If present, the proper error response is "Insufficient Encryption" and "Insifficient Authentication" otherwise.
Reference: Bluetooth Specification 4.2, Vol. 3, Part C, Section 10.3.1 Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/4ce57617 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/4ce57617 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/4ce57617 Branch: refs/heads/develop Commit: 4ce576178432c6bf7bd8db2ec2bb05b0434bc734 Parents: 7cd398d Author: Andrzej Kaczmarek <[email protected]> Authored: Sat Dec 31 22:18:48 2016 +0100 Committer: Andrzej Kaczmarek <[email protected]> Committed: Wed Jan 4 14:14:24 2017 +0100 ---------------------------------------------------------------------- net/nimble/host/src/ble_att_svr.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4ce57617/net/nimble/host/src/ble_att_svr.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c index 47a4cff..9e0724d 100644 --- a/net/nimble/host/src/ble_att_svr.c +++ b/net/nimble/host/src/ble_att_svr.c @@ -262,9 +262,14 @@ ble_att_svr_check_perms(uint16_t conn_handle, int is_read, uint8_t *out_att_err) { struct ble_gap_sec_state sec_state; + struct ble_store_value_sec value_sec; + struct ble_store_key_sec key_sec; + struct ble_hs_conn_addrs addrs; + struct ble_hs_conn *conn; int author; int authen; int enc; + int rc; if (is_read) { if (!(entry->ha_flags & BLE_ATT_F_READ)) { @@ -292,11 +297,25 @@ ble_att_svr_check_perms(uint16_t conn_handle, int is_read, } ble_att_svr_get_sec_state(conn_handle, &sec_state); - if (enc && !sec_state.encrypted) { - /* XXX: Check security database; if required key present, respond with - * insufficient encryption error code. - */ - *out_att_err = BLE_ATT_ERR_INSUFFICIENT_AUTHEN; + if ((enc || authen) && !sec_state.encrypted) { + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + if (conn != NULL) { + ble_hs_conn_addrs(conn, &addrs); + + memset(&key_sec, 0, sizeof key_sec); + key_sec.peer_addr_type = addrs.peer_id_addr_type; + memcpy(key_sec.peer_addr, addrs.peer_id_addr, 6); + } + ble_hs_unlock(); + + rc = ble_store_read_peer_sec(&key_sec, &value_sec); + if (rc == 0 && value_sec.ltk_present) { + *out_att_err = BLE_ATT_ERR_INSUFFICIENT_ENC; + } else { + *out_att_err = BLE_ATT_ERR_INSUFFICIENT_AUTHEN; + } + return BLE_HS_ATT_ERR(*out_att_err); }
