From 367aedc0e9bcd6a667a86fa0fe58d84dd974d1f4 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Sat, 19 Jun 2021 17:58:56 +0200 Subject: [PATCH] gap: send user confirmation negative reply if required security level cannot be met --- src/hci.c | 46 +++++++++++++++++++++++----------------------- src/hci.h | 17 +++++++++-------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/hci.c b/src/hci.c index 3d8587212..db60d5cfa 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2395,22 +2395,6 @@ static bool hci_ssp_security_level_possible_for_io_cap(gap_security_level_t leve // LEVEL 2 requires SSP, which is a given return true; } - -static bool hci_ssp_validate_possible_security_level(bd_addr_t addr){ - hci_connection_t * conn = hci_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); - if (!conn) return false; - // abort pairing, if requested security level cannot be met - if (hci_ssp_security_level_possible_for_io_cap(conn->requested_security_level, hci_stack->ssp_io_capability, conn->io_cap_response_io)) { - // inlined hci_add_connection_flags_for_flipped_bd_addr - hci_connection_timestamp(conn); - return true; - } else { - log_info("Level %u cannot be reached", conn->requested_security_level); - conn->bonding_flags |= BONDING_DISCONNECT_SECURITY_BLOCK; - return false; - }; -} - #endif static void event_handler(uint8_t *packet, uint16_t size){ @@ -2801,16 +2785,26 @@ static void event_handler(uint8_t *packet, uint16_t size){ case HCI_EVENT_USER_CONFIRMATION_REQUEST: hci_event_user_confirmation_request_get_bd_addr(packet, addr); - if (hci_ssp_validate_possible_security_level(addr) == false) break; - if (!hci_stack->ssp_auto_accept) break; - hci_add_connection_flags_for_flipped_bd_addr(&packet[2], AUTH_FLAG_SEND_USER_CONFIRM_REPLY); + conn = hci_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); + if (!conn) break; + if (hci_ssp_security_level_possible_for_io_cap(conn->requested_security_level, hci_stack->ssp_io_capability, conn->io_cap_response_io)) { + if (hci_stack->ssp_auto_accept){ + hci_add_connection_flags_for_flipped_bd_addr(&packet[2], AUTH_FLAG_SEND_USER_CONFIRM_REPLY); + }; + } else { + hci_pairing_complete(conn, ERROR_CODE_INSUFFICIENT_SECURITY); + hci_add_connection_flags_for_flipped_bd_addr(&packet[2], AUTH_FLAG_SEND_USER_CONFIRM_NEGATIVE_REPLY); + // don't forward event to app + hci_run(); + return; + } break; case HCI_EVENT_USER_PASSKEY_REQUEST: - hci_event_user_passkey_request_get_bd_addr(packet, addr); - if (hci_ssp_validate_possible_security_level(addr) == false) break; - if (!hci_stack->ssp_auto_accept) break; - hci_add_connection_flags_for_flipped_bd_addr(&packet[2], AUTH_FLAG_SEND_USER_PASSKEY_REPLY); + // Pairing using Passkey results in MITM protection. If Level 4 is required, support for SC is validated on IO Cap Request + if (hci_stack->ssp_auto_accept){ + hci_add_connection_flags_for_flipped_bd_addr(&packet[2], AUTH_FLAG_SEND_USER_PASSKEY_REPLY); + }; break; case HCI_EVENT_MODE_CHANGE: @@ -4610,6 +4604,12 @@ static bool hci_run_general_pending_commands(void){ return true; } + if (connection->authentication_flags & AUTH_FLAG_SEND_USER_CONFIRM_NEGATIVE_REPLY){ + connectionClearAuthenticationFlags(connection, AUTH_FLAG_SEND_USER_CONFIRM_NEGATIVE_REPLY); + hci_send_cmd(&hci_user_confirmation_request_negative_reply, &connection->address); + return true; + } + if (connection->authentication_flags & AUTH_FLAG_SEND_USER_PASSKEY_REPLY){ connectionClearAuthenticationFlags(connection, AUTH_FLAG_SEND_USER_PASSKEY_REPLY); hci_send_cmd(&hci_user_passkey_request_reply, &connection->address, 000000); diff --git a/src/hci.h b/src/hci.h index 866cd29fd..e38f06ce9 100644 --- a/src/hci.h +++ b/src/hci.h @@ -205,23 +205,24 @@ typedef enum { AUTH_FLAG_SEND_IO_CAPABILITIES_REPLY = 0x0008, AUTH_FLAG_SEND_IO_CAPABILITIES_NEGATIVE_REPLY = 0x0010, AUTH_FLAG_SEND_USER_CONFIRM_REPLY = 0x0020, - AUTH_FLAG_SEND_USER_PASSKEY_REPLY = 0x0040, + AUTH_FLAG_SEND_USER_CONFIRM_NEGATIVE_REPLY = 0x0040, + AUTH_FLAG_SEND_USER_PASSKEY_REPLY = 0x0080, // Classic OOB - AUTH_FLAG_SEND_REMOTE_OOB_DATA_REPLY = 0x0080, + AUTH_FLAG_SEND_REMOTE_OOB_DATA_REPLY = 0x0100, // pairing status - AUTH_FLAG_LEGACY_PAIRING_ACTIVE = 0x0100, - AUTH_FLAG_SSP_PAIRING_ACTIVE = 0x0200, + AUTH_FLAG_LEGACY_PAIRING_ACTIVE = 0x0200, + AUTH_FLAG_SSP_PAIRING_ACTIVE = 0x0400, AUTH_FLAG_PAIRING_ACTIVE_MASK = (AUTH_FLAG_LEGACY_PAIRING_ACTIVE | AUTH_FLAG_SSP_PAIRING_ACTIVE), // connection status - AUTH_FLAG_CONNECTION_AUTHENTICATED = 0x0400, - AUTH_FLAG_CONNECTION_ENCRYPTED = 0x0800, + AUTH_FLAG_CONNECTION_AUTHENTICATED = 0x0800, + AUTH_FLAG_CONNECTION_ENCRYPTED = 0x1000, // errands - AUTH_FLAG_READ_RSSI = 0x1000, - AUTH_FLAG_WRITE_SUPERVISION_TIMEOUT = 0x2000, + AUTH_FLAG_READ_RSSI = 0x2000, + AUTH_FLAG_WRITE_SUPERVISION_TIMEOUT = 0x4000, } hci_authentication_flags_t;