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 14cc3249c1eb04725f7820c32a5dae0c2565b317..6c994c004d15cd0d899ee535be8bc4db9819428b 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);
+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);
index 7f5ad8a2b22d03c2c3eea300cba7dec3b977d20d..3163330cd4f1388e3c0b5d593b5e54ca75ba0c12 100644 (file)
@@ -623,6 +623,23 @@ encrypt:
 }
 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)
 {
index 121a5c13b98933d9634009173ea502c7ed7b48d0..5759bb7054f7f4aca8822271b7de4da8997af915 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 (!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);