mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-27 06:35:20 +00:00
successfully enable encryption if security level 2 is requested for l2cap service
This commit is contained in:
parent
dce7800923
commit
a00031e215
@ -246,8 +246,8 @@ extern "C" {
|
|||||||
|
|
||||||
// GAP SECURITY
|
// GAP SECURITY
|
||||||
|
|
||||||
// data: event(8), len(8), status (8), hci_handle (16), security_level (8)
|
// data: event(8), len(8), hci_handle (16), security_level (8)
|
||||||
#define GAP_AUTHENTICATION_RESULT 0xc0
|
#define GAP_SECURITY_LEVEL 0xc0
|
||||||
|
|
||||||
// Error Code
|
// Error Code
|
||||||
#define ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02
|
#define ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02
|
||||||
|
39
src/hci.c
39
src/hci.c
@ -70,6 +70,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void hci_update_scan_enable(void);
|
static void hci_update_scan_enable(void);
|
||||||
|
static gap_security_level_t gap_security_level_for_connection(hci_connection_t * connection);
|
||||||
|
|
||||||
// the STACK is here
|
// the STACK is here
|
||||||
static hci_stack_t hci_stack;
|
static hci_stack_t hci_stack;
|
||||||
@ -703,16 +704,13 @@ static void event_handler(uint8_t *packet, int size){
|
|||||||
} else {
|
} else {
|
||||||
conn->authentication_flags &= ~CONNECTION_ENCRYPTED;
|
conn->authentication_flags &= ~CONNECTION_ENCRYPTED;
|
||||||
}
|
}
|
||||||
|
hci_emit_security_level(handle, gap_security_level_for_connection(conn));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case HCI_EVENT_AUTHENTICATION_COMPLETE_EVENT:
|
// case HCI_EVENT_AUTHENTICATION_COMPLETE_EVENT:
|
||||||
// handle = READ_BT_16(packet, 3);
|
// handle = READ_BT_16(packet, 3);
|
||||||
// conn = hci_connection_for_handle(handle);
|
// conn = hci_connection_for_handle(handle);
|
||||||
// if (!conn) break;
|
// if (!conn) break;
|
||||||
// if (conn->bonding_flags & BONDING_REQUESTED){
|
|
||||||
// gap_security_level_t level = gap_security_level_for_connection(conn);
|
|
||||||
// hci_emit_security_level(handle, packet[2], level);
|
|
||||||
// }
|
|
||||||
// break;
|
// break;
|
||||||
|
|
||||||
#ifndef EMBEDDED
|
#ifndef EMBEDDED
|
||||||
@ -1740,13 +1738,12 @@ void hci_emit_discoverable_enabled(uint8_t enabled){
|
|||||||
hci_stack.packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
|
hci_stack.packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
void hci_emit_security_level(hci_con_handle_t con_handle, uint8_t status, gap_security_level_t level){
|
void hci_emit_security_level(hci_con_handle_t con_handle, gap_security_level_t level){
|
||||||
uint8_t event[6];
|
uint8_t event[5];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
event[pos++] = GAP_AUTHENTICATION_RESULT;
|
event[pos++] = GAP_SECURITY_LEVEL;
|
||||||
event[pos++] = sizeof(event) - 2;
|
event[pos++] = sizeof(event) - 2;
|
||||||
event[pos++] = status;
|
bt_store_16(event, 2, con_handle);
|
||||||
bt_store_16(event, 3, con_handle);
|
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = level;
|
event[pos++] = level;
|
||||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||||
@ -1784,7 +1781,7 @@ gap_security_level_t gap_security_level_for_link_key_type(link_key_type_t link_k
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gap_security_level_t gap_security_level_for_connection(hci_connection_t * connection){
|
static gap_security_level_t gap_security_level_for_connection(hci_connection_t * connection){
|
||||||
if (!connection) return LEVEL_0;
|
if (!connection) return LEVEL_0;
|
||||||
if ((connection->authentication_flags & CONNECTION_ENCRYPTED) == 0) return LEVEL_0;
|
if ((connection->authentication_flags & CONNECTION_ENCRYPTED) == 0) return LEVEL_0;
|
||||||
return gap_security_level_for_link_key_type(connection->link_key_type);
|
return gap_security_level_for_link_key_type(connection->link_key_type);
|
||||||
@ -1807,16 +1804,30 @@ gap_security_level_t gap_security_level(hci_con_handle_t con_handle){
|
|||||||
void gap_request_security_level(hci_con_handle_t con_handle, gap_security_level_t requested_level){
|
void gap_request_security_level(hci_con_handle_t con_handle, gap_security_level_t requested_level){
|
||||||
hci_connection_t * connection = hci_connection_for_handle(con_handle);
|
hci_connection_t * connection = hci_connection_for_handle(con_handle);
|
||||||
if (!connection){
|
if (!connection){
|
||||||
hci_emit_security_level(con_handle, ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, LEVEL_0);
|
hci_emit_security_level(con_handle, LEVEL_0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gap_security_level_t current_level = gap_security_level(con_handle);
|
gap_security_level_t current_level = gap_security_level(con_handle);
|
||||||
log_info("gap_request_security_level %u, current level %u", requested_level, current_level);
|
log_info("gap_request_security_level %u, current level %u", requested_level, current_level);
|
||||||
if (current_level >= requested_level){
|
if (current_level >= requested_level){
|
||||||
hci_emit_security_level(con_handle, 0, current_level);
|
hci_emit_security_level(con_handle, current_level);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection->requested_security_level = requested_level;
|
connection->requested_security_level = requested_level;
|
||||||
connection->bonding_flags |= BONDING_REQUESTED;
|
|
||||||
connection->bonding_flags |= BONDING_SEND_AUTHENTICATE_REQUEST;
|
// would enabling ecnryption suffice?
|
||||||
|
if (hci_stack.remote_device_db){
|
||||||
|
link_key_type_t link_key_type;
|
||||||
|
link_key_t link_key;
|
||||||
|
if (hci_stack.remote_device_db->get_link_key( &connection->address, &link_key, &link_key_type)){
|
||||||
|
if (gap_security_level_for_link_key_type(link_key_type) >= requested_level){
|
||||||
|
connection->bonding_flags |= BONDING_SEND_ENCRYPTION_REQUEST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// connection->bonding_flags |= BONDING_REQUESTED;
|
||||||
|
// connection->bonding_flags |= BONDING_SEND_AUTHENTICATE_REQUEST;
|
||||||
}
|
}
|
||||||
|
@ -401,6 +401,7 @@ void hci_emit_btstack_version(void);
|
|||||||
void hci_emit_system_bluetooth_enabled(uint8_t enabled);
|
void hci_emit_system_bluetooth_enabled(uint8_t enabled);
|
||||||
void hci_emit_remote_name_cached(bd_addr_t *addr, device_name_t *name);
|
void hci_emit_remote_name_cached(bd_addr_t *addr, device_name_t *name);
|
||||||
void hci_emit_discoverable_enabled(uint8_t enabled);
|
void hci_emit_discoverable_enabled(uint8_t enabled);
|
||||||
|
void hci_emit_security_level(hci_con_handle_t con_handle, gap_security_level_t level);
|
||||||
|
|
||||||
// query if remote side supports SSP
|
// query if remote side supports SSP
|
||||||
// query if the local side supports SSP
|
// query if the local side supports SSP
|
||||||
|
23
src/l2cap.c
23
src/l2cap.c
@ -495,10 +495,11 @@ void l2cap_run(void){
|
|||||||
|
|
||||||
switch (channel->state){
|
switch (channel->state){
|
||||||
|
|
||||||
|
case L2CAP_STATE_WAIT_SECURITY_LEVEL_UPDATE:
|
||||||
case L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT:
|
case L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT:
|
||||||
if (channel->state_var & L2CAP_STATE_WAIT_AUTHENTICATION_RESULT) {
|
if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_SEND_CONN_RESP_PEND) {
|
||||||
channelStateVarClearFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONN_RESP_PEND);
|
channelStateVarClearFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONN_RESP_PEND);
|
||||||
l2cap_send_signaling_packet(channel->handle, CONNECTION_RESPONSE, channel->remote_sig_id, 0, 0, 1, 0);
|
l2cap_send_signaling_packet(channel->handle, CONNECTION_RESPONSE, channel->remote_sig_id, channel->local_cid, channel->remote_cid, 1, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -770,23 +771,19 @@ void l2cap_event_handler( uint8_t *packet, uint16_t size ){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GAP_AUTHENTICATION_RESULT:
|
case GAP_SECURITY_LEVEL:
|
||||||
handle = READ_BT_16(packet, 3);
|
handle = READ_BT_16(packet, 2);
|
||||||
for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){
|
for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){
|
||||||
channel = (l2cap_channel_t *) it;
|
channel = (l2cap_channel_t *) it;
|
||||||
if (channel->handle != handle) continue;
|
if (channel->handle != handle) continue;
|
||||||
if (channel->state != L2CAP_STATE_WAIT_AUTHENTICATION_RESULT) continue;
|
if (channel->state != L2CAP_STATE_WAIT_SECURITY_LEVEL_UPDATE) continue;
|
||||||
if (packet[2]){
|
// @todo check security level again
|
||||||
// fail
|
// channel->reason = 0x03; // security block
|
||||||
channel->reason = 0x03; // security block
|
// channel->state = L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_DECLINE;
|
||||||
channel->state = L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_DECLINE;
|
|
||||||
} else {
|
|
||||||
// success
|
// success
|
||||||
// @todo check sercurity level again
|
|
||||||
channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT;
|
channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT;
|
||||||
l2cap_emit_connection_request(channel);
|
l2cap_emit_connection_request(channel);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -872,7 +869,7 @@ static void l2cap_handle_connection_request(hci_con_handle_t handle, uint8_t sig
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set initial state
|
// set initial state
|
||||||
channel->state = L2CAP_STATE_WAIT_AUTHENTICATION_RESULT;
|
channel->state = L2CAP_STATE_WAIT_SECURITY_LEVEL_UPDATE;
|
||||||
channel->state_var = L2CAP_CHANNEL_STATE_VAR_SEND_CONN_RESP_PEND;
|
channel->state_var = L2CAP_CHANNEL_STATE_VAR_SEND_CONN_RESP_PEND;
|
||||||
|
|
||||||
// add to connections list
|
// add to connections list
|
||||||
|
@ -93,7 +93,7 @@ typedef enum {
|
|||||||
L2CAP_STATE_CLOSED = 1, // no baseband
|
L2CAP_STATE_CLOSED = 1, // no baseband
|
||||||
L2CAP_STATE_WILL_SEND_CREATE_CONNECTION,
|
L2CAP_STATE_WILL_SEND_CREATE_CONNECTION,
|
||||||
L2CAP_STATE_WAIT_CONNECTION_COMPLETE,
|
L2CAP_STATE_WAIT_CONNECTION_COMPLETE,
|
||||||
L2CAP_STATE_WAIT_AUTHENTICATION_RESULT,
|
L2CAP_STATE_WAIT_SECURITY_LEVEL_UPDATE,
|
||||||
L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT,
|
L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT,
|
||||||
L2CAP_STATE_WAIT_CONNECT_RSP, // from peer
|
L2CAP_STATE_WAIT_CONNECT_RSP, // from peer
|
||||||
L2CAP_STATE_CONFIG,
|
L2CAP_STATE_CONFIG,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user