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
|
@ -1966,6 +1966,7 @@ PREDEFINED = "CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT" \
|
|||
"CONFIG_BT_MESH_MODEL_EXTENSIONS" \
|
||||
"CONFIG_BT_REMOTE_INFO" \
|
||||
"CONFIG_BT_SMP" \
|
||||
"CONFIG_BT_SMP_APP_PAIRING_ACCEPT" \
|
||||
"CONFIG_DEVICE_POWER_MANAGEMENT" \
|
||||
"CONFIG_ERRNO" \
|
||||
"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 */
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
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
|
||||
bool "Disable legacy pairing"
|
||||
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)
|
||||
{
|
||||
struct bt_smp_hdr *hdr;
|
||||
|
@ -2110,6 +2137,26 @@ static u8_t send_pairing_rsp(struct bt_smp *smp)
|
|||
}
|
||||
#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)
|
||||
static int smp_s1(const u8_t k[16], const u8_t r1[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)
|
||||
return BT_SMP_ERR_AUTH_REQUIREMENTS;
|
||||
#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);
|
||||
#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;
|
||||
}
|
||||
|
||||
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) &&
|
||||
!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
|
||||
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)
|
||||
return BT_SMP_ERR_AUTH_REQUIREMENTS;
|
||||
#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);
|
||||
#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->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) &&
|
||||
atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
|
||||
bt_auth && bt_auth->pairing_confirm) {
|
||||
|
|
Loading…
Reference in a new issue