Bluetooth: Double check sec req for pre 2.1 device
authorWaldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Fri, 6 May 2011 07:42:31 +0000 (09:42 +0200)
committerGustavo F. Padovan <padovan@profusion.mobi>
Wed, 11 May 2011 17:56:28 +0000 (14:56 -0300)
In case of pre v2.1 devices authentication request will return
success immediately if the link key already exists without any
authentication process.

That means, it's not possible to re-authenticate the link if you
already have combination key and for instance want to re-authenticate
to get the high security (use 16 digit pin).

Therefore, it's necessary to check security requirements on auth
complete event to prevent not enough secure connection.

Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_conn.c
net/bluetooth/rfcomm/core.c

index 14cc324..6c994c0 100644 (file)
@@ -422,6 +422,7 @@ void hci_conn_check_pending(struct hci_dev *hdev);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
 int hci_conn_check_link_mode(struct hci_conn *conn);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
 int hci_conn_check_link_mode(struct hci_conn *conn);
+int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
 int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
 int hci_conn_change_link_key(struct hci_conn *conn);
 int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
 int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
 int hci_conn_change_link_key(struct hci_conn *conn);
 int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
index 7f5ad8a..3163330 100644 (file)
@@ -623,6 +623,23 @@ encrypt:
 }
 EXPORT_SYMBOL(hci_conn_security);
 
 }
 EXPORT_SYMBOL(hci_conn_security);
 
+/* Check secure link requirement */
+int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
+{
+       BT_DBG("conn %p", conn);
+
+       if (sec_level != BT_SECURITY_HIGH)
+               return 1; /* Accept if non-secure is required */
+
+       if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
+                       (conn->key_type == HCI_LK_COMBINATION &&
+                       conn->pin_length == 16))
+               return 1;
+
+       return 0; /* Reject not secure link */
+}
+EXPORT_SYMBOL(hci_conn_check_secure);
+
 /* Change link key */
 int hci_conn_change_link_key(struct hci_conn *conn)
 {
 /* Change link key */
 int hci_conn_change_link_key(struct hci_conn *conn)
 {
index 121a5c1..5759bb7 100644 (file)
@@ -2096,7 +2096,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
                if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
                        continue;
 
                if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
                        continue;
 
-               if (!status)
+               if (!status && hci_conn_check_secure(conn, d->sec_level))
                        set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
                else
                        set_bit(RFCOMM_AUTH_REJECT, &d->flags);
                        set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
                else
                        set_bit(RFCOMM_AUTH_REJECT, &d->flags);