mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-15 16:24:28 +08:00
mesh: Fix inOOB and outOOB agent handling on prov initiate
This code fixes the Provisioner Initiator role so that the following Out-of-Band agent calls are made correctly, and their results handled properly: "push", "twist", "blink", "beep", "vibrate", "in-numeric", "out-numeric", "in-alpha", "out-alpha"
This commit is contained in:
parent
53a81750db
commit
4853937edd
28
mesh/agent.c
28
mesh/agent.c
@ -363,7 +363,7 @@ static void key_reply(struct l_dbus_message *reply, void *user_data)
|
||||
mesh_agent_key_cb_t cb;
|
||||
struct l_dbus_message_iter iter_array;
|
||||
uint32_t n = 0, expected_len = 0;
|
||||
uint8_t buf[64];
|
||||
uint8_t *buf;
|
||||
int err;
|
||||
|
||||
if (!l_queue_find(agents, simple_match, agent) || !agent->req)
|
||||
@ -376,13 +376,13 @@ static void key_reply(struct l_dbus_message *reply, void *user_data)
|
||||
if (err != MESH_ERROR_NONE)
|
||||
goto done;
|
||||
|
||||
if (!l_dbus_message_get_arguments(reply, "au", &iter_array)) {
|
||||
if (!l_dbus_message_get_arguments(reply, "ay", &iter_array)) {
|
||||
l_error("Failed to retrieve key input");
|
||||
err = MESH_ERROR_FAILED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!l_dbus_message_iter_get_fixed_array(&iter_array, buf, &n)) {
|
||||
if (!l_dbus_message_iter_get_fixed_array(&iter_array, &buf, &n)) {
|
||||
l_error("Failed to retrieve key input");
|
||||
err = MESH_ERROR_FAILED;
|
||||
goto done;
|
||||
@ -390,7 +390,7 @@ static void key_reply(struct l_dbus_message *reply, void *user_data)
|
||||
|
||||
if (req->type == MESH_AGENT_REQUEST_PRIVATE_KEY)
|
||||
expected_len = 32;
|
||||
else if (MESH_AGENT_REQUEST_PUBLIC_KEY)
|
||||
else if (req->type == MESH_AGENT_REQUEST_PUBLIC_KEY)
|
||||
expected_len = 64;
|
||||
else
|
||||
expected_len = 16;
|
||||
@ -402,13 +402,13 @@ static void key_reply(struct l_dbus_message *reply, void *user_data)
|
||||
}
|
||||
|
||||
done:
|
||||
l_dbus_message_unref(req->msg);
|
||||
|
||||
if (req->cb) {
|
||||
cb = req->cb;
|
||||
cb(req->user_data, err, buf, n);
|
||||
}
|
||||
|
||||
l_dbus_message_unref(req->msg);
|
||||
|
||||
l_free(req);
|
||||
agent->req = NULL;
|
||||
}
|
||||
@ -601,11 +601,19 @@ int mesh_agent_prompt_number(struct mesh_agent *agent, bool initiator,
|
||||
return prompt_input(agent, str_type, type, true, cb, user_data);
|
||||
}
|
||||
|
||||
int mesh_agent_prompt_alpha(struct mesh_agent *agent, mesh_agent_key_cb_t cb,
|
||||
void *user_data)
|
||||
int mesh_agent_prompt_alpha(struct mesh_agent *agent, bool initiator,
|
||||
mesh_agent_key_cb_t cb, void *user_data)
|
||||
{
|
||||
return prompt_input(agent, "in-alpha", MESH_AGENT_REQUEST_IN_ALPHA,
|
||||
false, cb, user_data);
|
||||
if (initiator)
|
||||
return prompt_input(agent,
|
||||
cap_table[MESH_AGENT_REQUEST_OUT_ALPHA].action,
|
||||
MESH_AGENT_REQUEST_OUT_ALPHA, false, cb,
|
||||
user_data);
|
||||
else
|
||||
return prompt_input(agent,
|
||||
cap_table[MESH_AGENT_REQUEST_IN_ALPHA].action,
|
||||
MESH_AGENT_REQUEST_IN_ALPHA, false, cb,
|
||||
user_data);
|
||||
}
|
||||
|
||||
int mesh_agent_request_static(struct mesh_agent *agent, mesh_agent_key_cb_t cb,
|
||||
|
@ -54,8 +54,8 @@ int mesh_agent_display_number(struct mesh_agent *agent, bool initiator,
|
||||
int mesh_agent_prompt_number(struct mesh_agent *agent, bool initiator,
|
||||
uint8_t action, mesh_agent_number_cb_t cb,
|
||||
void *user_data);
|
||||
int mesh_agent_prompt_alpha(struct mesh_agent *agent, mesh_agent_key_cb_t cb,
|
||||
void *user_data);
|
||||
int mesh_agent_prompt_alpha(struct mesh_agent *agent, bool initiator,
|
||||
mesh_agent_key_cb_t cb, void *user_data);
|
||||
int mesh_agent_request_static(struct mesh_agent *agent, mesh_agent_key_cb_t cb,
|
||||
void *user_data);
|
||||
int mesh_agent_request_private_key(struct mesh_agent *agent,
|
||||
|
@ -479,7 +479,7 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
|
||||
if (prov->conf_inputs.start.auth_action ==
|
||||
PROV_ACTION_IN_ALPHA) {
|
||||
fail.reason = mesh_agent_prompt_alpha(
|
||||
prov->agent,
|
||||
prov->agent, false,
|
||||
static_cb, prov);
|
||||
} else {
|
||||
fail.reason = mesh_agent_prompt_number(
|
||||
|
@ -433,6 +433,54 @@ failure:
|
||||
/* TODO: Call Complete Callback (Fail)*/
|
||||
}
|
||||
|
||||
static void get_random_key(struct mesh_prov_initiator *prov, uint8_t action,
|
||||
uint8_t size)
|
||||
{
|
||||
uint32_t oob_key;
|
||||
int i;
|
||||
|
||||
if (action >= PROV_ACTION_IN_ALPHA) {
|
||||
uint8_t alpha;
|
||||
char tmp[17];
|
||||
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
|
||||
if (size > 16)
|
||||
size = 16;
|
||||
|
||||
/* Create random alphanumeric string made of 0-9, a-z, A-Z */
|
||||
for (i = 0; i < size; i++) {
|
||||
l_getrandom(&alpha, sizeof(alpha));
|
||||
alpha %= (10 + 26 + 26);
|
||||
|
||||
if (alpha < 10)
|
||||
alpha += '0';
|
||||
else if (alpha < 10 + 26)
|
||||
alpha += 'a' - 10;
|
||||
else
|
||||
alpha += 'A' - 10 - 26;
|
||||
|
||||
tmp[i] = (char) alpha;
|
||||
}
|
||||
memcpy(prov->rand_auth_workspace + 16, tmp, size);
|
||||
memcpy(prov->rand_auth_workspace + 32, tmp, size);
|
||||
return;
|
||||
}
|
||||
|
||||
l_getrandom(&oob_key, sizeof(oob_key));
|
||||
|
||||
if (action <= PROV_ACTION_TWIST)
|
||||
oob_key %= size;
|
||||
else
|
||||
oob_key %= digit_mod(size);
|
||||
|
||||
if (!oob_key)
|
||||
oob_key = size;
|
||||
|
||||
/* Save two copies, for two confirmation values */
|
||||
l_put_be32(oob_key, prov->rand_auth_workspace + 28);
|
||||
l_put_be32(oob_key, prov->rand_auth_workspace + 44);
|
||||
}
|
||||
|
||||
static void int_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
@ -575,7 +623,7 @@ static void int_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
|
||||
if (prov->conf_inputs.start.auth_action ==
|
||||
PROV_ACTION_OUT_ALPHA) {
|
||||
fail_code[1] = mesh_agent_prompt_alpha(
|
||||
prov->agent,
|
||||
prov->agent, true,
|
||||
static_cb, prov);
|
||||
} else {
|
||||
fail_code[1] = mesh_agent_prompt_number(
|
||||
@ -591,22 +639,22 @@ static void int_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
|
||||
|
||||
case 3:
|
||||
/* Auth Type 3b - input OOB */
|
||||
l_getrandom(&oob_key, sizeof(oob_key));
|
||||
oob_key %= digit_mod(prov->conf_inputs.start.auth_size);
|
||||
get_random_key(prov,
|
||||
prov->conf_inputs.start.auth_action,
|
||||
prov->conf_inputs.start.auth_size);
|
||||
oob_key = l_get_be32(prov->rand_auth_workspace + 28);
|
||||
|
||||
/* Save two copies, for two confirmation values */
|
||||
l_put_be32(oob_key, prov->rand_auth_workspace + 28);
|
||||
l_put_be32(oob_key, prov->rand_auth_workspace + 44);
|
||||
prov->material |= MAT_RAND_AUTH;
|
||||
/* Ask Agent to Display U32 */
|
||||
/* Ask Agent to Display random key */
|
||||
if (prov->conf_inputs.start.auth_action ==
|
||||
PROV_ACTION_IN_ALPHA) {
|
||||
/* TODO: Construst NUL-term string to pass */
|
||||
|
||||
fail_code[1] = mesh_agent_display_string(
|
||||
prov->agent, NULL, NULL, prov);
|
||||
prov->agent,
|
||||
(char *) prov->rand_auth_workspace + 16,
|
||||
NULL, prov);
|
||||
} else {
|
||||
fail_code[1] = mesh_agent_display_number(
|
||||
prov->agent, false,
|
||||
prov->agent, true,
|
||||
prov->conf_inputs.start.auth_action,
|
||||
oob_key, NULL, prov);
|
||||
}
|
||||
@ -625,6 +673,7 @@ static void int_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
|
||||
|
||||
case PROV_INP_CMPLT: /* Provisioning Input Complete */
|
||||
/* TODO: Cancel Agent prompt */
|
||||
prov->material |= MAT_RAND_AUTH;
|
||||
send_confirm(prov);
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user