From b79efb17f1890be282dccc093c67b5cc9fc3ca6f Mon Sep 17 00:00:00 2001 From: Milos Bazelides <58462930+sp-milos@users.noreply.github.com> Date: Fri, 31 May 2024 20:47:11 +0200 Subject: [PATCH] Fix inconsistent ownership validation A new ownership check was added to oc_main.c. If the device is not owned based upon that check, all of its existing resources are reset before attempting to load them again. Fixes Issue #628 --------- Co-authored-by: Daniel Adam --- api/oc_main.c | 36 ++++++++++++++++++++-- security/oc_acl_internal.h | 1 + security/oc_ael_internal.h | 2 ++ security/oc_cred_internal.h | 1 + security/oc_pstat_internal.h | 1 + security/oc_store.c | 58 ++++++++++++++++++++++++------------ security/oc_u_ids_internal.h | 24 +++++++++++++++ 7 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 security/oc_u_ids_internal.h diff --git a/api/oc_main.c b/api/oc_main.c index 77f3ad3d8..b3b3f9146 100644 --- a/api/oc_main.c +++ b/api/oc_main.c @@ -38,6 +38,7 @@ #endif /* OC_COLLECTIONS && OC_SERVER && OC_COLLECTIONS_IF_CREATE */ #ifdef OC_SECURITY +#include "oc_storage_internal.h" #include "oc_store.h" #include "security/oc_acl_internal.h" #include "security/oc_ael_internal.h" @@ -52,6 +53,7 @@ #include "security/oc_roles_internal.h" #endif /* OC_PKI */ #include "security/oc_sdi_internal.h" +#include "security/oc_u_ids_internal.h" #endif /* OC_SECURITY */ #ifdef OC_CLOUD @@ -271,6 +273,31 @@ main_init_resources(void) #endif /* OC_SOFTWARE_UPDATE */ } +#ifdef OC_SECURITY +/** + * @brief Clear the security-related resources for a device. + * + * The function clears the device's security-related data from storage. + * It is called when the ownership of the device cannot be established. + * + * @param device The index of the device for which to clear the resources. + */ +static void +main_sec_clear_resources(size_t device) +{ + oc_storage_data_clear(OCF_SEC_U_IDS_STORE_NAME, device); + oc_storage_data_clear(OCF_SEC_PSTAT_STORE_NAME, device); + oc_storage_data_clear(OCF_SEC_CRED_STORE_NAME, device); + oc_storage_data_clear(OCF_SEC_ACL_STORE_NAME, device); + oc_storage_data_clear(OCF_SEC_SP_STORE_NAME, device); + oc_storage_data_clear(OCF_SEC_AEL_STORE_NAME, device); + oc_storage_data_clear(OCF_SEC_SDI_STORE_NAME, device); +#ifdef OC_SOFTWARE_UPDATE + oc_storage_data_clear(OCF_SW_UPDATE_STORE_NAME, device); +#endif /* OC_SOFTWARE_UPDATE */ +} +#endif /* OC_SECURITY */ + static void main_load_resources(void) { @@ -282,11 +309,16 @@ main_load_resources(void) #if defined(OC_SECURITY) || defined(OC_SOFTWARE_UPDATE) for (size_t device = 0; device < oc_core_get_num_devices(); device++) { #ifdef OC_SECURITY + OC_DBG("oc_main_init(): loading doxm(%zu)", device); + oc_sec_load_doxm(device); + const oc_sec_doxm_t *doxm = oc_sec_get_doxm(device); + if (!doxm->owned) { + OC_DBG("oc_main_init(): clearing sec resource storages(%zu)", device); + main_sec_clear_resources(device); + } oc_sec_load_unique_ids(device); OC_DBG("oc_main_init(): loading pstat(%zu)", device); oc_sec_load_pstat(device); - OC_DBG("oc_main_init(): loading doxm(%zu)", device); - oc_sec_load_doxm(device); OC_DBG("oc_main_init(): loading cred(%zu)", device); oc_sec_load_cred(device); OC_DBG("oc_main_init(): loading acl(%zu)", device); diff --git a/security/oc_acl_internal.h b/security/oc_acl_internal.h index f403b6cd7..14b252323 100644 --- a/security/oc_acl_internal.h +++ b/security/oc_acl_internal.h @@ -36,6 +36,7 @@ extern "C" { #define OCF_SEC_ACL_URI "/oic/sec/acl2" #define OCF_SEC_ACL_RT "oic.r.acl2" +#define OCF_SEC_ACL_STORE_NAME "acl" #define OC_ACE_WC_ALL_STR "*" #define OC_ACE_WC_ALL_SECURED_STR "+" diff --git a/security/oc_ael_internal.h b/security/oc_ael_internal.h index 16babf4b9..02962a93f 100644 --- a/security/oc_ael_internal.h +++ b/security/oc_ael_internal.h @@ -31,6 +31,8 @@ extern "C" { #endif +#define OCF_SEC_AEL_STORE_NAME "ael" + typedef struct oc_sec_ael_aux_info_t { struct oc_sec_ael_aux_info_t *next; diff --git a/security/oc_cred_internal.h b/security/oc_cred_internal.h index 28cb0905d..2d65b9ee9 100644 --- a/security/oc_cred_internal.h +++ b/security/oc_cred_internal.h @@ -34,6 +34,7 @@ extern "C" { #define OCF_SEC_CRED_URI "/oic/sec/cred" #define OCF_SEC_CRED_RT "oic.r.cred" +#define OCF_SEC_CRED_STORE_NAME "cred" struct oc_tls_peer_t; diff --git a/security/oc_pstat_internal.h b/security/oc_pstat_internal.h index eed608e16..d83a7fc71 100644 --- a/security/oc_pstat_internal.h +++ b/security/oc_pstat_internal.h @@ -32,6 +32,7 @@ extern "C" { #define OCF_SEC_PSTAT_URI "/oic/sec/pstat" #define OCF_SEC_PSTAT_RT "oic.r.pstat" +#define OCF_SEC_PSTAT_STORE_NAME "pstat" /** Create pstat (/oic/sec/pstat) resource for given device. */ void oc_sec_pstat_create_resource(size_t device); diff --git a/security/oc_store.c b/security/oc_store.c index 22583e28d..f3ea52937 100644 --- a/security/oc_store.c +++ b/security/oc_store.c @@ -33,6 +33,7 @@ #include "oc_sdi_internal.h" #include "oc_sp_internal.h" #include "oc_tls_internal.h" +#include "oc_u_ids_internal.h" #include "port/oc_storage.h" static int @@ -91,12 +92,14 @@ store_decode_pstat(const oc_rep_t *rep, size_t device, void *data) void oc_sec_load_pstat(size_t device) { - if (oc_storage_data_load("pstat", device, store_decode_pstat, NULL) <= 0) { + if (oc_storage_data_load(OCF_SEC_PSTAT_STORE_NAME, device, store_decode_pstat, + NULL) <= 0) { OC_DBG("failed to load pstat from storage for device(%zu)", device); oc_sec_pstat_default(device); return; } - OC_DBG("%s resource loaded from storage for device(%zu)", "pstat", device); + OC_DBG("%s resource loaded from storage for device(%zu)", + OCF_SEC_PSTAT_STORE_NAME, device); } static int @@ -110,7 +113,8 @@ store_encode_pstat(size_t device, const void *data) void oc_sec_dump_pstat(size_t device) { - long ret = oc_storage_data_save("pstat", device, store_encode_pstat, NULL); + long ret = oc_storage_data_save(OCF_SEC_PSTAT_STORE_NAME, device, + store_encode_pstat, NULL); if (ret <= 0) { OC_ERR("cannot dump pstat to storage: error(%ld)", ret); } @@ -230,13 +234,15 @@ oc_sec_load_cred(size_t device) oc_storage_buffer_t sb = oc_storage_get_buffer(OC_MAX_APP_DATA_SIZE); #ifndef OC_APP_DATA_STORAGE_BUFFER if (sb.buffer == NULL) { - OC_ERR("cannot load %s from store: cannot allocate buffer", "cred"); + OC_ERR("cannot load %s from store: cannot allocate buffer", + OCF_SEC_CRED_STORE_NAME); return; } #endif /* !OC_APP_DATA_STORAGE_BUFFER */ char svr_tag[OC_STORAGE_SVR_TAG_MAX]; - oc_storage_gen_svr_tag("cred", device, svr_tag, sizeof(svr_tag)); + oc_storage_gen_svr_tag(OCF_SEC_CRED_STORE_NAME, device, svr_tag, + sizeof(svr_tag)); long ret = oc_storage_read(svr_tag, sb.buffer, sb.size); if (ret > 0) { OC_MEMB_LOCAL(rep_objects, oc_rep_t, OC_MAX_NUM_REP_OBJECTS); @@ -258,7 +264,8 @@ oc_sec_dump_cred(size_t device) oc_storage_buffer_t sb = oc_storage_get_buffer(OC_MIN_APP_DATA_SIZE); #ifndef OC_APP_DATA_STORAGE_BUFFER if (sb.buffer == NULL) { - OC_ERR("cannot dump %s to store: cannot allocate buffer", "cred"); + OC_ERR("cannot dump %s to store: cannot allocate buffer", + OCF_SEC_CRED_STORE_NAME); return; } oc_rep_new_realloc_v1(&sb.buffer, OC_MIN_APP_DATA_SIZE, OC_MAX_APP_DATA_SIZE); @@ -275,7 +282,8 @@ oc_sec_dump_cred(size_t device) if (size > 0) { OC_DBG("oc_store: encoded cred size %d", size); char svr_tag[OC_STORAGE_SVR_TAG_MAX]; - oc_storage_gen_svr_tag("cred", device, svr_tag, sizeof(svr_tag)); + oc_storage_gen_svr_tag(OCF_SEC_CRED_STORE_NAME, device, svr_tag, + sizeof(svr_tag)); oc_storage_write(svr_tag, sb.buffer, size); } oc_storage_free_buffer(sb); @@ -287,13 +295,15 @@ oc_sec_load_acl(size_t device) oc_storage_buffer_t sb = oc_storage_get_buffer(OC_MAX_APP_DATA_SIZE); #ifndef OC_APP_DATA_STORAGE_BUFFER if (sb.buffer == NULL) { - OC_ERR("cannot load %s from store: cannot allocate buffer", "acl"); + OC_ERR("cannot load %s from store: cannot allocate buffer", + OCF_SEC_ACL_STORE_NAME); return; } #endif /* !OC_APP_DATA_STORAGE_BUFFER */ char svr_tag[OC_STORAGE_SVR_TAG_MAX]; - oc_storage_gen_svr_tag("acl", device, svr_tag, sizeof(svr_tag)); + oc_storage_gen_svr_tag(OCF_SEC_ACL_STORE_NAME, device, svr_tag, + sizeof(svr_tag)); long ret = oc_storage_read(svr_tag, sb.buffer, sb.size); if (ret > 0) { OC_MEMB_LOCAL(rep_objects, oc_rep_t, OC_MAX_NUM_REP_OBJECTS); @@ -314,7 +324,8 @@ oc_sec_dump_acl(size_t device) oc_storage_buffer_t sb = oc_storage_get_buffer(OC_MIN_APP_DATA_SIZE); #ifndef OC_APP_DATA_STORAGE_BUFFER if (sb.buffer == NULL) { - OC_ERR("cannot dump %s to store: cannot allocate buffer", "acl"); + OC_ERR("cannot dump %s to store: cannot allocate buffer", + OCF_SEC_ACL_STORE_NAME); return; } oc_rep_new_realloc_v1(&sb.buffer, OC_MIN_APP_DATA_SIZE, OC_MAX_APP_DATA_SIZE); @@ -331,7 +342,8 @@ oc_sec_dump_acl(size_t device) if (size > 0) { OC_DBG("oc_store: encoded ACL size %d", size); char svr_tag[OC_STORAGE_SVR_TAG_MAX]; - oc_storage_gen_svr_tag("acl", device, svr_tag, sizeof(svr_tag)); + oc_storage_gen_svr_tag(OCF_SEC_ACL_STORE_NAME, device, svr_tag, + sizeof(svr_tag)); oc_storage_write(svr_tag, sb.buffer, size); } oc_storage_free_buffer(sb); @@ -362,13 +374,15 @@ oc_sec_load_unique_ids(size_t device) oc_storage_buffer_t sb = oc_storage_get_buffer(OC_MAX_APP_DATA_SIZE); #ifndef OC_APP_DATA_STORAGE_BUFFER if (sb.buffer == NULL) { - OC_ERR("cannot load %s from store: cannot allocate buffer", "unique_ids"); + OC_ERR("cannot load %s from store: cannot allocate buffer", + OCF_SEC_U_IDS_STORE_NAME); return; } #endif /* !OC_APP_DATA_STORAGE_BUFFER */ char svr_tag[OC_STORAGE_SVR_TAG_MAX]; - oc_storage_gen_svr_tag("u_ids", device, svr_tag, sizeof(svr_tag)); + oc_storage_gen_svr_tag(OCF_SEC_U_IDS_STORE_NAME, device, svr_tag, + sizeof(svr_tag)); long ret = oc_storage_read(svr_tag, sb.buffer, sb.size); if (ret > 0) { OC_MEMB_LOCAL(rep_objects, oc_rep_t, OC_MAX_NUM_REP_OBJECTS); @@ -389,7 +403,8 @@ oc_sec_dump_unique_ids(size_t device) oc_storage_buffer_t sb = oc_storage_get_buffer(OC_MIN_APP_DATA_SIZE); #ifndef OC_APP_DATA_STORAGE_BUFFER if (sb.buffer == NULL) { - OC_ERR("cannot dump %s to store: cannot allocate buffer", "unique_ids"); + OC_ERR("cannot dump %s to store: cannot allocate buffer", + OCF_SEC_U_IDS_STORE_NAME); return; } oc_rep_new_realloc_v1(&sb.buffer, OC_MIN_APP_DATA_SIZE, OC_MAX_APP_DATA_SIZE); @@ -417,7 +432,8 @@ oc_sec_dump_unique_ids(size_t device) if (size > 0) { OC_DBG("oc_store: encoded unique identifiers: size %d", size); char svr_tag[OC_STORAGE_SVR_TAG_MAX]; - oc_storage_gen_svr_tag("u_ids", device, svr_tag, sizeof(svr_tag)); + oc_storage_gen_svr_tag(OCF_SEC_U_IDS_STORE_NAME, device, svr_tag, + sizeof(svr_tag)); oc_storage_write(svr_tag, sb.buffer, size); } oc_storage_free_buffer(sb); @@ -429,13 +445,15 @@ oc_sec_load_ael(size_t device) oc_storage_buffer_t sb = oc_storage_get_buffer(OC_MAX_APP_DATA_SIZE); #ifndef OC_APP_DATA_STORAGE_BUFFER if (sb.buffer == NULL) { - OC_ERR("cannot load %s from store: cannot allocate buffer", "ael"); + OC_ERR("cannot load %s from store: cannot allocate buffer", + OCF_SEC_AEL_STORE_NAME); return; } #endif /* !OC_APP_DATA_STORAGE_BUFFER */ char svr_tag[OC_STORAGE_SVR_TAG_MAX]; - oc_storage_gen_svr_tag("ael", device, svr_tag, sizeof(svr_tag)); + oc_storage_gen_svr_tag(OCF_SEC_AEL_STORE_NAME, device, svr_tag, + sizeof(svr_tag)); long ret = oc_storage_read(svr_tag, sb.buffer, sb.size); if (ret > 0) { OC_MEMB_LOCAL(rep_objects, oc_rep_t, OC_MAX_NUM_REP_OBJECTS); @@ -456,7 +474,8 @@ oc_sec_dump_ael(size_t device) oc_storage_buffer_t sb = oc_storage_get_buffer(OC_MIN_APP_DATA_SIZE); #ifndef OC_APP_DATA_STORAGE_BUFFER if (sb.buffer == NULL) { - OC_ERR("cannot dump %s to store: cannot allocate buffer", "ael"); + OC_ERR("cannot dump %s to store: cannot allocate buffer", + OCF_SEC_AEL_STORE_NAME); return; } oc_rep_new_realloc_v1(&sb.buffer, OC_MIN_APP_DATA_SIZE, OC_MAX_APP_DATA_SIZE); @@ -474,7 +493,8 @@ oc_sec_dump_ael(size_t device) if (size > 0) { OC_DBG("oc_store: encoded ael size %d", size); char svr_tag[OC_STORAGE_SVR_TAG_MAX]; - oc_storage_gen_svr_tag("ael", device, svr_tag, sizeof(svr_tag)); + oc_storage_gen_svr_tag(OCF_SEC_AEL_STORE_NAME, device, svr_tag, + sizeof(svr_tag)); oc_storage_write(svr_tag, sb.buffer, size); } oc_storage_free_buffer(sb); diff --git a/security/oc_u_ids_internal.h b/security/oc_u_ids_internal.h new file mode 100644 index 000000000..373f7811c --- /dev/null +++ b/security/oc_u_ids_internal.h @@ -0,0 +1,24 @@ +/**************************************************************************** + * + * Copyright (c) 2016-2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"), + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +#ifndef OC_U_IDS_INTERNAL_H +#define OC_U_IDS_INTERNAL_H + +#define OCF_SEC_U_IDS_STORE_NAME "u_ids" + +#endif /* OC_U_IDS_INTERNAL_H */