summaryrefslogtreecommitdiff
path: root/mesh/appkey.c
diff options
context:
space:
mode:
authorInga Stotland <inga.stotland@intel.com>2019-02-13 19:45:25 -0800
committerBrian Gix <brian.gix@intel.com>2019-02-19 08:54:07 -0800
commit52b840d0a5cc93194cc20d3b1d8c922229720d12 (patch)
tree25052b48e40769e3d8601ddf3883972b98eae197 /mesh/appkey.c
parent19bf426290835fa5ef5fd37a2fe03b0f88f4d430 (diff)
downloadbluez-52b840d0a5cc93194cc20d3b1d8c922229720d12.tar.gz
mesh: Separate functions for app key add and update
This splits appkey_key_add() into two separate functions: app_key_add() and app_key_update(). Fix checks for miscellaneous invalid conditions and return appropriate error status.
Diffstat (limited to 'mesh/appkey.c')
-rw-r--r--mesh/appkey.c89
1 files changed, 51 insertions, 38 deletions
diff --git a/mesh/appkey.c b/mesh/appkey.c
index a437763db..f799b7782 100644
--- a/mesh/appkey.c
+++ b/mesh/appkey.c
@@ -364,8 +364,8 @@ bool appkey_have_key(struct mesh_net *net, uint16_t app_idx)
return true;
}
-int appkey_key_add(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
- const uint8_t *new_key, bool update)
+int appkey_key_update(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
+ const uint8_t *new_key)
{
struct mesh_app_key *key;
struct l_queue *app_keys;
@@ -375,61 +375,74 @@ int appkey_key_add(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
if (!app_keys)
return MESH_STATUS_INSUFF_RESOURCES;
- key = l_queue_find(app_keys, match_key_index, L_UINT_TO_PTR(app_idx));
-
- if (!mesh_net_have_key(net, net_idx) ||
- (update && key->net_idx != net_idx))
+ if (!mesh_net_have_key(net, net_idx))
return MESH_STATUS_INVALID_NETKEY;
- if (update && !key)
+ key = l_queue_find(app_keys, match_key_index, L_UINT_TO_PTR(app_idx));
+
+ if (!key)
return MESH_STATUS_INVALID_APPKEY;
+ if (key->net_idx != net_idx)
+ return MESH_STATUS_INVALID_BINDING;
+
mesh_net_key_refresh_phase_get(net, net_idx, &phase);
- if (update && phase != KEY_REFRESH_PHASE_ONE)
+ if (phase != KEY_REFRESH_PHASE_ONE)
return MESH_STATUS_CANNOT_UPDATE;
+ /* Check if the key has been already successfully updated */
+ if (memcmp(new_key, key->new_key, 16) == 0)
+ return MESH_STATUS_SUCCESS;
+
+ if (!set_key(key, app_idx, new_key, true))
+ return MESH_STATUS_INSUFF_RESOURCES;
+
+ if (!storage_app_key_add(net, net_idx, app_idx, new_key, true))
+ return MESH_STATUS_STORAGE_FAIL;
+
+ return MESH_STATUS_SUCCESS;
+}
+
+int appkey_key_add(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
+ const uint8_t *new_key)
+{
+ struct mesh_app_key *key;
+ struct l_queue *app_keys;
+
+ app_keys = mesh_net_get_app_keys(net);
+ if (!app_keys)
+ return MESH_STATUS_INSUFF_RESOURCES;
+
+ key = l_queue_find(app_keys, match_key_index, L_UINT_TO_PTR(app_idx));
if (key) {
if (memcmp(new_key, key->key, 16) == 0)
return MESH_STATUS_SUCCESS;
-
- if (!update) {
- l_debug("Failed to add key: index already stored %x",
- (net_idx << 16) | app_idx);
+ else
return MESH_STATUS_IDX_ALREADY_STORED;
- }
}
- if (!key) {
- if (!(l_queue_length(app_keys) < MAX_APP_KEYS))
- return MESH_STATUS_INSUFF_RESOURCES;
-
- key = app_key_new();
- if (!key)
- return MESH_STATUS_INSUFF_RESOURCES;
+ if (!mesh_net_have_key(net, net_idx))
+ return MESH_STATUS_INVALID_NETKEY;
- if (!set_key(key, app_idx, new_key, false)) {
- appkey_key_free(key);
- return MESH_STATUS_INSUFF_RESOURCES;
- }
+ if (l_queue_length(app_keys) >= MAX_APP_KEYS)
+ return MESH_STATUS_INSUFF_RESOURCES;
- if (!storage_app_key_add(net, net_idx, app_idx, new_key,
- false)) {
- appkey_key_free(key);
- return MESH_STATUS_STORAGE_FAIL;
- }
+ key = app_key_new();
- key->net_idx = net_idx;
- key->app_idx = app_idx;
- l_queue_push_tail(app_keys, key);
- } else {
- if (!set_key(key, app_idx, new_key, true))
- return MESH_STATUS_INSUFF_RESOURCES;
+ if (!set_key(key, app_idx, new_key, false)) {
+ appkey_key_free(key);
+ return MESH_STATUS_INSUFF_RESOURCES;
+ }
- if (!storage_app_key_add(net, net_idx, app_idx, new_key,
- true))
- return MESH_STATUS_STORAGE_FAIL;
+ if (!storage_app_key_add(net, net_idx, app_idx, new_key, false)) {
+ appkey_key_free(key);
+ return MESH_STATUS_STORAGE_FAIL;
}
+ key->net_idx = net_idx;
+ key->app_idx = app_idx;
+ l_queue_push_tail(app_keys, key);
+
l_queue_clear(key->replay_cache, l_free);
return MESH_STATUS_SUCCESS;