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);
     }
 

Reply via email to