Bluetooth: Host: Add generic pairing query callback
Similar to pairing_confirm this callback is called each time a peer requests pairing, but for all types of pairings, except SSP. The pairing req/rsp information is passed as a parameter so the application can decide wheter to accept or reject the pairing. Fixes: #21036 Signed-off-by: Martin Rieva <mrrv@demant.com>
This commit is contained in:
parent
34346c41ac
commit
2685a94c02
4 changed files with 160 additions and 0 deletions
|
@ -1966,6 +1966,7 @@ PREDEFINED = "CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT" \
|
||||||
"CONFIG_BT_MESH_MODEL_EXTENSIONS" \
|
"CONFIG_BT_MESH_MODEL_EXTENSIONS" \
|
||||||
"CONFIG_BT_REMOTE_INFO" \
|
"CONFIG_BT_REMOTE_INFO" \
|
||||||
"CONFIG_BT_SMP" \
|
"CONFIG_BT_SMP" \
|
||||||
|
"CONFIG_BT_SMP_APP_PAIRING_ACCEPT" \
|
||||||
"CONFIG_DEVICE_POWER_MANAGEMENT" \
|
"CONFIG_DEVICE_POWER_MANAGEMENT" \
|
||||||
"CONFIG_ERRNO" \
|
"CONFIG_ERRNO" \
|
||||||
"CONFIG_EXECUTION_BENCHMARKING" \
|
"CONFIG_EXECUTION_BENCHMARKING" \
|
||||||
|
|
|
@ -711,8 +711,72 @@ struct bt_conn_oob_info {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
|
||||||
|
/** @brief Pairing request and pairing response info structure.
|
||||||
|
*
|
||||||
|
* This structure is the same for both smp_pairing_req and smp_pairing_rsp
|
||||||
|
* and a subset of the packet data, except for the initial Code octet.
|
||||||
|
* It is documented in Core Spec. Vol. 3, Part H, 3.5.1 and 3.5.2.
|
||||||
|
*/
|
||||||
|
struct bt_conn_pairing_feat {
|
||||||
|
/** IO Capability, Core Spec. Vol 3, Part H, 3.5.1, Table 3.4 */
|
||||||
|
u8_t io_capability;
|
||||||
|
|
||||||
|
/** OOB data flag, Core Spec. Vol 3, Part H, 3.5.1, Table 3.5 */
|
||||||
|
u8_t oob_data_flag;
|
||||||
|
|
||||||
|
/** AuthReq, Core Spec. Vol 3, Part H, 3.5.1, Fig. 3.3 */
|
||||||
|
u8_t auth_req;
|
||||||
|
|
||||||
|
/** Maximum Encryption Key Size, Core Spec. Vol 3, Part H, 3.5.1 */
|
||||||
|
u8_t max_enc_key_size;
|
||||||
|
|
||||||
|
/** Initiator Key Distribution/Generation, Core Spec. Vol 3, Part H,
|
||||||
|
* 3.6.1, Fig. 3.11
|
||||||
|
*/
|
||||||
|
u8_t init_key_dist;
|
||||||
|
|
||||||
|
/** Responder Key Distribution/Generation, Core Spec. Vol 3, Part H
|
||||||
|
* 3.6.1, Fig. 3.11
|
||||||
|
*/
|
||||||
|
u8_t resp_key_dist;
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_BT_SMP_APP_PAIRING_ACCEPT */
|
||||||
|
|
||||||
/** Authenticated pairing callback structure */
|
/** Authenticated pairing callback structure */
|
||||||
struct bt_conn_auth_cb {
|
struct bt_conn_auth_cb {
|
||||||
|
#if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
|
||||||
|
/** @brief Query to proceed incoming pairing or not.
|
||||||
|
*
|
||||||
|
* On any incoming pairing req/rsp this callback will be called for
|
||||||
|
* the application to decide whether to allow for the pairing to
|
||||||
|
* continue.
|
||||||
|
*
|
||||||
|
* The pairing info received from the peer is passed to assist
|
||||||
|
* making the decision.
|
||||||
|
*
|
||||||
|
* As this callback is synchronous the application should return
|
||||||
|
* a response value immediately. Otherwise it may affect the
|
||||||
|
* timing during pairing. Hence, this information should not be
|
||||||
|
* conveyed to the user to take action.
|
||||||
|
*
|
||||||
|
* The remaining callbacks are not affected by this, but do notice
|
||||||
|
* that other callbacks can be called during the pairing. Eg. if
|
||||||
|
* pairing_confirm is registered both will be called for Just-Works
|
||||||
|
* pairings.
|
||||||
|
*
|
||||||
|
* This callback may be unregistered in which case pairing continues
|
||||||
|
* as if the Kconfig flag was not set.
|
||||||
|
*
|
||||||
|
* This callback is not called for BR/EDR Secure Simple Pairing (SSP).
|
||||||
|
*
|
||||||
|
* @param conn Connection where pairing is initiated.
|
||||||
|
* @param feat Pairing req/resp info.
|
||||||
|
*/
|
||||||
|
enum bt_security_err (*pairing_accept)(struct bt_conn *conn,
|
||||||
|
const struct bt_conn_pairing_feat *const feat);
|
||||||
|
#endif /* CONFIG_BT_SMP_APP_PAIRING_ACCEPT */
|
||||||
|
|
||||||
/** @brief Display a passkey to the user.
|
/** @brief Display a passkey to the user.
|
||||||
*
|
*
|
||||||
* When called the application is expected to display the given
|
* When called the application is expected to display the given
|
||||||
|
|
|
@ -320,6 +320,16 @@ config BT_SIGNING
|
||||||
This option enables data signing which is used for transferring
|
This option enables data signing which is used for transferring
|
||||||
authenticated data in an unencrypted connection.
|
authenticated data in an unencrypted connection.
|
||||||
|
|
||||||
|
config BT_SMP_APP_PAIRING_ACCEPT
|
||||||
|
bool "Accept or reject pairing initiative"
|
||||||
|
help
|
||||||
|
When receiving pairing request or pairing response query the
|
||||||
|
application whether to accept to proceed with pairing or not. This is
|
||||||
|
for pairing over SMP and does not affect SSP, which will continue
|
||||||
|
pairing without querying the application.
|
||||||
|
The application can return an error code, which is translated into
|
||||||
|
a SMP return value if the pairing is not allowed.
|
||||||
|
|
||||||
config BT_SMP_SC_PAIR_ONLY
|
config BT_SMP_SC_PAIR_ONLY
|
||||||
bool "Disable legacy pairing"
|
bool "Disable legacy pairing"
|
||||||
help
|
help
|
||||||
|
|
|
@ -404,6 +404,33 @@ static enum bt_security_err auth_err_get(u8_t smp_err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
|
||||||
|
static u8_t smp_err_get(enum bt_security_err auth_err)
|
||||||
|
{
|
||||||
|
switch (auth_err) {
|
||||||
|
case BT_SECURITY_ERR_OOB_NOT_AVAILABLE:
|
||||||
|
return BT_SMP_ERR_OOB_NOT_AVAIL;
|
||||||
|
|
||||||
|
case BT_SECURITY_ERR_AUTH_FAIL:
|
||||||
|
case BT_SECURITY_ERR_AUTH_REQUIREMENT:
|
||||||
|
return BT_SMP_ERR_AUTH_REQUIREMENTS;
|
||||||
|
|
||||||
|
case BT_SECURITY_ERR_PAIR_NOT_SUPPORTED:
|
||||||
|
return BT_SMP_ERR_PAIRING_NOTSUPP;
|
||||||
|
|
||||||
|
case BT_SECURITY_ERR_INVALID_PARAM:
|
||||||
|
return BT_SMP_ERR_INVALID_PARAMS;
|
||||||
|
|
||||||
|
case BT_SECURITY_ERR_PIN_OR_KEY_MISSING:
|
||||||
|
case BT_SECURITY_ERR_PAIR_NOT_ALLOWED:
|
||||||
|
case BT_SECURITY_ERR_UNSPECIFIED:
|
||||||
|
return BT_SMP_ERR_UNSPECIFIED;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_SMP_APP_PAIRING_ACCEPT */
|
||||||
|
|
||||||
static struct net_buf *smp_create_pdu(struct bt_smp *smp, u8_t op, size_t len)
|
static struct net_buf *smp_create_pdu(struct bt_smp *smp, u8_t op, size_t len)
|
||||||
{
|
{
|
||||||
struct bt_smp_hdr *hdr;
|
struct bt_smp_hdr *hdr;
|
||||||
|
@ -2110,6 +2137,26 @@ static u8_t send_pairing_rsp(struct bt_smp *smp)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_PERIPHERAL */
|
#endif /* CONFIG_BT_PERIPHERAL */
|
||||||
|
|
||||||
|
static u8_t smp_pairing_accept_query(struct bt_conn *conn,
|
||||||
|
struct bt_smp_pairing *pairing)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
|
||||||
|
if (bt_auth && bt_auth->pairing_accept) {
|
||||||
|
const struct bt_conn_pairing_feat feat = {
|
||||||
|
.io_capability = pairing->io_capability,
|
||||||
|
.oob_data_flag = pairing->oob_flag,
|
||||||
|
.auth_req = pairing->auth_req,
|
||||||
|
.max_enc_key_size = pairing->max_key_size,
|
||||||
|
.init_key_dist = pairing->init_key_dist,
|
||||||
|
.resp_key_dist = pairing->resp_key_dist
|
||||||
|
};
|
||||||
|
|
||||||
|
return smp_err_get(bt_auth->pairing_accept(conn, &feat));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_SMP_APP_PAIRING_ACCEPT */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
|
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
|
||||||
static int smp_s1(const u8_t k[16], const u8_t r1[16],
|
static int smp_s1(const u8_t k[16], const u8_t r1[16],
|
||||||
const u8_t r2[16], u8_t out[16])
|
const u8_t r2[16], u8_t out[16])
|
||||||
|
@ -2809,6 +2856,16 @@ static u8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
|
||||||
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
|
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
|
||||||
return BT_SMP_ERR_AUTH_REQUIREMENTS;
|
return BT_SMP_ERR_AUTH_REQUIREMENTS;
|
||||||
#else
|
#else
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
|
||||||
|
u8_t err;
|
||||||
|
|
||||||
|
err = smp_pairing_accept_query(smp->chan.chan.conn,
|
||||||
|
req);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return legacy_pairing_req(smp);
|
return legacy_pairing_req(smp);
|
||||||
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
|
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
|
||||||
}
|
}
|
||||||
|
@ -2825,6 +2882,15 @@ static u8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
|
||||||
return BT_SMP_ERR_ENC_KEY_SIZE;
|
return BT_SMP_ERR_ENC_KEY_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
|
||||||
|
u8_t err;
|
||||||
|
|
||||||
|
err = smp_pairing_accept_query(smp->chan.chan.conn, req);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((DISPLAY_FIXED(smp) || smp->method == JUST_WORKS) &&
|
if ((DISPLAY_FIXED(smp) || smp->method == JUST_WORKS) &&
|
||||||
!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
|
!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
|
||||||
bt_auth && bt_auth->pairing_confirm) {
|
bt_auth && bt_auth->pairing_confirm) {
|
||||||
|
@ -2991,6 +3057,16 @@ static u8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
|
||||||
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
|
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
|
||||||
return BT_SMP_ERR_AUTH_REQUIREMENTS;
|
return BT_SMP_ERR_AUTH_REQUIREMENTS;
|
||||||
#else
|
#else
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
|
||||||
|
u8_t err;
|
||||||
|
|
||||||
|
err = smp_pairing_accept_query(smp->chan.chan.conn,
|
||||||
|
rsp);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return legacy_pairing_rsp(smp);
|
return legacy_pairing_rsp(smp);
|
||||||
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
|
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
|
||||||
}
|
}
|
||||||
|
@ -3010,6 +3086,15 @@ static u8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
|
||||||
smp->local_dist &= SEND_KEYS_SC;
|
smp->local_dist &= SEND_KEYS_SC;
|
||||||
smp->remote_dist &= RECV_KEYS_SC;
|
smp->remote_dist &= RECV_KEYS_SC;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
|
||||||
|
u8_t err;
|
||||||
|
|
||||||
|
err = smp_pairing_accept_query(smp->chan.chan.conn, rsp);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((DISPLAY_FIXED(smp) || smp->method == JUST_WORKS) &&
|
if ((DISPLAY_FIXED(smp) || smp->method == JUST_WORKS) &&
|
||||||
atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
|
atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
|
||||||
bt_auth && bt_auth->pairing_confirm) {
|
bt_auth && bt_auth->pairing_confirm) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue