host: Add API to unpair a peer device

This API allows to unpair a device with the specified address. The keys
related to that peer device are removed from storage and peer address
is removed from the resolve list from the controller. If a peer
is connected, the connection is terminated.

This function is used in policy for SM key overflow. Instead of just deleting
the keys from storage, the host performs tasks described above to
ensure correct behavior.
This commit is contained in:
Michał Narajowski
2018-09-24 13:52:28 +02:00
parent 46e80d7f4c
commit d33cdbe5dc
6 changed files with 155 additions and 1 deletions
+1
View File
@@ -155,6 +155,7 @@ int btshell_l2cap_update(uint16_t conn_handle,
struct ble_l2cap_sig_update_params *params);
int btshell_sec_start(uint16_t conn_handle);
int btshell_sec_pair(uint16_t conn_handle);
int btshell_sec_unpair(ble_addr_t *peer_addr);
int btshell_sec_restart(uint16_t conn_handle, uint8_t *ltk, uint16_t ediv,
uint64_t rand_val, int auth);
int btshell_tx_start(uint16_t handle, uint16_t len, uint16_t rate,
+60
View File
@@ -2624,6 +2624,59 @@ static const struct shell_cmd_help security_pair_help = {
};
#endif
/*****************************************************************************
* $security-unpair *
*****************************************************************************/
static int
cmd_security_unpair(int argc, char **argv)
{
ble_addr_t peer;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
rc = parse_arg_mac("peer_addr", peer.val);
if (rc == 0) {
peer.type = parse_arg_kv_dflt("peer_addr_type",
cmd_peer_addr_types,
BLE_ADDR_PUBLIC, &rc);
if (rc != 0) {
console_printf("invalid 'peer_addr_type' parameter\n");
return rc;
}
} else {
console_printf("invalid 'peer_addr' parameter\n");
return rc;
}
rc = ble_gap_unpair(&peer);
if (rc != 0) {
console_printf("error unpairing; rc=%d\n", rc);
return rc;
}
return 0;
}
#if MYNEWT_VAL(SHELL_CMD_HELP)
static const struct shell_param security_unpair_params[] = {
{"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
{"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
{NULL, NULL}
};
static const struct shell_cmd_help security_unpair_help = {
.summary = "unpair a peer device",
.usage = NULL,
.params = security_unpair_params,
};
#endif
/*****************************************************************************
* $security-start *
*****************************************************************************/
@@ -3717,6 +3770,13 @@ static const struct shell_cmd btshell_commands[] = {
.sc_cmd_func = cmd_security_pair,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &security_pair_help,
#endif
},
{
.sc_cmd = "security-unpair",
.sc_cmd_func = cmd_security_unpair,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &security_unpair_help,
#endif
},
{
+13
View File
@@ -1625,6 +1625,19 @@ btshell_sec_pair(uint16_t conn_handle)
return rc;
}
int
btshell_sec_unpair(ble_addr_t *peer_addr)
{
#if !NIMBLE_BLE_SM
return BLE_HS_ENOTSUP;
#endif
int rc;
rc = ble_gap_unpair(peer_addr);
return rc;
}
int
btshell_sec_start(uint16_t conn_handle)
{
+28
View File
@@ -1181,6 +1181,34 @@ int ble_gap_encryption_initiate(uint16_t conn_handle, const uint8_t *ltk,
*/
int ble_gap_conn_rssi(uint16_t conn_handle, int8_t *out_rssi);
/**
* Unpairs a device with the specified address. The keys related to that peer
* device are removed from storage and peer address is removed from the resolve
* list from the controller. If a peer is connected, the connection is terminated.
*
* @param peer_addr Address of the device to be unpaired
*
* @return 0 on success;
* A BLE host HCI return code if the controller
* rejected the request;
* A BLE host core return code on unexpected
* error.
*/
int ble_gap_unpair(const ble_addr_t *peer_addr);
/**
* Unpairs the oldest bonded peer device. The keys related to that peer
* device are removed from storage and peer address is removed from the resolve
* list from the controller. If a peer is connected, the connection is terminated.
*
* @return 0 on success;
* A BLE host HCI return code if the controller
* rejected the request;
* A BLE host core return code on unexpected
* error.
*/
int ble_gap_unpair_oldest_peer(void);
#define BLE_GAP_PRIVATE_MODE_NETWORK 0
#define BLE_GAP_PRIVATE_MODE_DEVICE 1
int ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode);
+52
View File
@@ -4329,6 +4329,58 @@ ble_gap_encryption_initiate(uint16_t conn_handle,
return rc;
}
int
ble_gap_unpair(const ble_addr_t *peer_addr)
{
struct ble_hs_conn *conn;
int rc;
if (ble_addr_cmp(peer_addr, BLE_ADDR_ANY) == 0) {
return BLE_HS_EINVAL;
}
conn = ble_hs_conn_find_by_addr(peer_addr);
if (conn != NULL) {
rc = ble_gap_terminate(conn->bhc_handle, BLE_ERR_REM_USER_CONN_TERM);
if ((rc != BLE_HS_EALREADY) && (rc != BLE_HS_ENOTCONN)) {
return rc;
}
}
rc = ble_hs_pvcy_remove_entry(peer_addr->type,
peer_addr->val);
if (rc != 0) {
return rc;
}
return ble_store_util_delete_peer(peer_addr);
}
int
ble_gap_unpair_oldest_peer(void)
{
ble_addr_t oldest_peer_id_addr;
int num_peers;
int rc;
rc = ble_store_util_bonded_peers(
&oldest_peer_id_addr, &num_peers, 1);
if (rc != 0) {
return rc;
}
if (num_peers == 0) {
return 0;
}
rc = ble_gap_unpair(&oldest_peer_id_addr);
if (rc != 0) {
return rc;
}
return 0;
}
void
ble_gap_passkey_event(uint16_t conn_handle,
struct ble_gap_passkey_params *passkey_params)
+1 -1
View File
@@ -236,7 +236,7 @@ ble_store_util_status_rr(struct ble_store_status_event *event, void *arg)
case BLE_STORE_OBJ_TYPE_OUR_SEC:
case BLE_STORE_OBJ_TYPE_PEER_SEC:
case BLE_STORE_OBJ_TYPE_CCCD:
return ble_store_util_delete_oldest_peer();
return ble_gap_unpair_oldest_peer();
default:
return BLE_HS_EUNKNOWN;