From 00f7883e3b28725e7177bfe69b4163e2e9e6bf51 Mon Sep 17 00:00:00 2001 From: Vitalii Irkha Date: Thu, 14 Nov 2019 20:35:33 +0200 Subject: [PATCH] Draft Created API for SVR DB Integrity check https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/610 (cherry-picked from b2f7a3c0a121bf83f3551b0bca18061d8b5263f1) Change-Id: I6fe01f4de77a8e8f538666f8745b9b46cfd057fd Signed-off-by: Vitalii Irkha Signed-off-by: DoHyun Pyun --- .../csdk/security/include/internal/aclresource.h | 7 + .../csdk/security/include/internal/psinterface.h | 12 + .../csdk/security/include/internal/pstatresource.h | 9 + resource/csdk/security/src/aclresource.c | 47 ++++ resource/csdk/security/src/doxmresource.c | 4 +- resource/csdk/security/src/psinterface.c | 263 +++++++++++++++++++++ resource/csdk/security/src/pstatresource.c | 9 + resource/csdk/stack/src/ocstack.c | 10 + 8 files changed, 359 insertions(+), 2 deletions(-) diff --git a/resource/csdk/security/include/internal/aclresource.h b/resource/csdk/security/include/internal/aclresource.h index 0172ae4..8b28c3a 100644 --- a/resource/csdk/security/include/internal/aclresource.h +++ b/resource/csdk/security/include/internal/aclresource.h @@ -184,6 +184,13 @@ OicSecAcl_t* CBORPayloadToAcl2(const uint8_t *cborPayload, const size_t size); */ void printACL(const OicSecAcl_t* acl); +/** + * Check if Security ACE permission property matched + * @param permission value for matching + * @return OC_STACK_OK if permissions matched, else::OC_STACK_ERROR. + */ +OCStackResult CheckSecurityACEPermision(uint16_t permission); + #ifdef __cplusplus } #endif diff --git a/resource/csdk/security/include/internal/psinterface.h b/resource/csdk/security/include/internal/psinterface.h index 73bc90e..9dbfc53 100644 --- a/resource/csdk/security/include/internal/psinterface.h +++ b/resource/csdk/security/include/internal/psinterface.h @@ -158,4 +158,16 @@ OCStackResult setSecurePSI(const unsigned char *key, const OCPersistentStorage * */ resetSVRDBCB_t* const GetResetSVRDBCB(void); +/** + * API to validate data in SVR DB. + * @return ::OC_STACK_OK on success and other value otherwise. + */ +OCStackResult CheckSVRDBValidity(void); + +/** + * This function check if ResetPF are created + * @return true in positive case, false otherwise. + */ +bool isResetPFExist(void); + #endif //IOTVT_SRM_PSI_H diff --git a/resource/csdk/security/include/internal/pstatresource.h b/resource/csdk/security/include/internal/pstatresource.h index c021cb0..d158cff 100644 --- a/resource/csdk/security/include/internal/pstatresource.h +++ b/resource/csdk/security/include/internal/pstatresource.h @@ -122,6 +122,15 @@ bool GetPstatIsop(); */ OCStackResult SetPstatSelfOwnership(const OicUuid_t* newROwner); +/** + * Gets the cm value for pstat resource. + * + * @param[out] cm pointer for pstat.cm copy value. + * + * @retval ::OC_STACK_OK for Success, otherwise some error value. + */ +OCStackResult GetPstatCm(OicSecDpm_t *cm); + #ifdef __cplusplus } #endif diff --git a/resource/csdk/security/src/aclresource.c b/resource/csdk/security/src/aclresource.c index dc4b874..566bf79 100644 --- a/resource/csdk/security/src/aclresource.c +++ b/resource/csdk/security/src/aclresource.c @@ -2895,3 +2895,50 @@ OCStackResult GetAclRownerId(OicUuid_t *rowneruuid) } return retVal; } + +OCStackResult CheckSecurityACEPermision(uint16_t permission) +{ + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + OCStackResult ret = OC_STACK_ERROR; + OicSecAce_t *ace = NULL; + OicSecAce_t *tempAce = NULL; + + if(NULL == gAcl) + { + OIC_LOG_V(ERROR, TAG, "%s - gAcl is NULL!", __func__); + ret = OC_STACK_ERROR; + goto exit; + } + + LL_FOREACH_SAFE(gAcl->aces, ace, tempAce) + { + if(0 != memcmp(&ace->subjectuuid, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t))) + { + continue; + } + + OicSecRsrc_t* rsrc = NULL; + int flag = 0; + LL_FOREACH(ace->resources, rsrc) + { + if(strncmp(rsrc->href, OIC_RSRC_DOXM_URI, strlen(OIC_RSRC_DOXM_URI) + 1) == 0 || + strncmp(rsrc->href, OIC_RSRC_CRED_URI, strlen(OIC_RSRC_CRED_URI) + 1) == 0 || + strncmp(rsrc->href, OIC_RSRC_PSTAT_URI, strlen(OIC_RSRC_PSTAT_URI) + 1) == 0) + { + flag = 1; + break; + } + } + + if (flag && !(permission & ace->permission) ) + { + ret = OC_STACK_ERROR; + goto exit; + } + } + + exit: + OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__); + return ret; +} diff --git a/resource/csdk/security/src/doxmresource.c b/resource/csdk/security/src/doxmresource.c index c7362fb..98c8405 100644 --- a/resource/csdk/security/src/doxmresource.c +++ b/resource/csdk/security/src/doxmresource.c @@ -2493,7 +2493,7 @@ OCStackResult GetDoxmDevOwnerId(OicUuid_t *devownerid) { OIC_LOG_V(DEBUG, TAG, "GetDoxmDevOwnerId(): gDoxm owned = %d.", \ gDoxm->owned); - if (gDoxm->owned) + //if (gDoxm->owned) { *devownerid = gDoxm->owner; retVal = OC_STACK_OK; @@ -2507,7 +2507,7 @@ OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid) OCStackResult retVal = OC_STACK_ERROR; if (gDoxm) { - if( gDoxm->owned ) + // if( gDoxm->owned ) { *rowneruuid = gDoxm->rownerID; retVal = OC_STACK_OK; diff --git a/resource/csdk/security/src/psinterface.c b/resource/csdk/security/src/psinterface.c index d6474ab..e1e5a43 100644 --- a/resource/csdk/security/src/psinterface.c +++ b/resource/csdk/security/src/psinterface.c @@ -42,6 +42,8 @@ #include "psinterface.h" #include "doxmresource.h" #include "octhread.h" +#include "aclresource.h" +#include "credresource.h" #define TAG "OIC_SRM_PSI" @@ -1235,3 +1237,264 @@ void PrintPSStatus(void) } } + +OCStackResult CheckSVRDBValidity(void) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + OCStackResult res = OC_STACK_ERROR; + OicUuid_t emptyUuid = {.id={0}}; + + bool isOwned = false; + res = GetDoxmIsOwned(&isOwned); + + if( OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "%s - doxm is NULL!", __func__); + goto exit; + } + + OicUuid_t devOwnerUuid = {.id={0}}; + OicUuid_t devRownerUuid = {.id={0}}; + OicUuid_t resRowneruuid = {.id={0}}; + bool isDevOwnerUuidEmpty = false; + bool isDevRownerUuidEmpty = false; + bool isPstatRownerUuidEmpty = false; + bool isAclRownerUuidEmpty = false; + bool isCredRownerUuidEmpty = false; + + if(OC_STACK_OK != GetDoxmDevOwnerId(&devOwnerUuid) | + OC_STACK_OK != GetDoxmRownerId(&devRownerUuid)) + { + res = OC_STACK_ERROR; + goto exit; + } + + if (0 == memcmp(&devOwnerUuid, &emptyUuid, sizeof(devOwnerUuid))) + { + isDevOwnerUuidEmpty = true; + } + else + { + isDevOwnerUuidEmpty = false; + } + + if (0 == memcmp(&devRownerUuid, &emptyUuid, sizeof(devRownerUuid))) + { + isDevRownerUuidEmpty = true; + } + else + { + isDevRownerUuidEmpty = false; + } + + if (OC_STACK_OK != GetPstatRownerId(&resRowneruuid)) + { + res = OC_STACK_ERROR; + goto exit; + } + + if (0 == memcmp(&resRowneruuid, &emptyUuid, sizeof(resRowneruuid))) + { + isPstatRownerUuidEmpty = true; + } + else + { + isPstatRownerUuidEmpty = false; + } + + OicSecDpm_t cm = 0; + VERIFY_SUCCESS(TAG, OC_STACK_OK == GetPstatCm(&cm), ERROR); + + if (OC_STACK_OK != GetAclRownerId(&resRowneruuid)) + { + res = OC_STACK_ERROR; + goto exit; + } + + if (0 == memcmp(&resRowneruuid, &emptyUuid, sizeof(resRowneruuid))) + { + isAclRownerUuidEmpty = true; + } + else + { + isAclRownerUuidEmpty = false; + } + + if (OC_STACK_OK != GetCredRownerId(&resRowneruuid)) + { + res = OC_STACK_ERROR; + goto exit; + } + + if (0 == memcmp(&resRowneruuid, &emptyUuid, sizeof(resRowneruuid))) + { + isCredRownerUuidEmpty = true; + } + else + { + isCredRownerUuidEmpty = false; + } + + if(true == isOwned) + { + if ( isDevOwnerUuidEmpty ||isDevRownerUuidEmpty ) + { + OIC_LOG_V(ERROR, TAG, "%s - uuid is empty for owned device!", __func__); + res = OC_STACK_ERROR; + goto exit; + } + + if(!GetPstatIsop() || (cm & TAKE_OWNER)) + { + res = OC_STACK_ERROR; + goto exit; + } + + if (isPstatRownerUuidEmpty) + { + OIC_LOG_V(ERROR, TAG, "%s - pstatRownerUuid is empty for owned device!", __func__); + res = OC_STACK_ERROR;; + goto exit; + } + + if (isAclRownerUuidEmpty) + { + OIC_LOG_V(ERROR, TAG, "%s - aclRownerUuid is empty for owned device!", __func__); + res = OC_STACK_ERROR; + goto exit; + } + + if (isCredRownerUuidEmpty) + { + OIC_LOG_V(ERROR, TAG, "%s - credRownerUuid is empty for owned device!", __func__); + res = OC_STACK_ERROR; + goto exit; + } + + if (OC_STACK_OK != CheckSecurityACEPermision(PERMISSION_READ)) + { + res = OC_STACK_ERROR; + goto exit; + } + } + else + { + if ( !isDevOwnerUuidEmpty ||!isDevRownerUuidEmpty ) + { + OIC_LOG_V(ERROR, TAG, "%s - uuid is not empty for unOwned device!", __func__); + res = OC_STACK_ERROR; + goto exit; + } + + if (!isPstatRownerUuidEmpty) + { + OIC_LOG_V(ERROR, TAG, "%s - pstatRownerUuid is not empty for unOwned device!", __func__); + res = OC_STACK_ERROR; + goto exit; + } + + if(GetPstatIsop() || !(cm & TAKE_OWNER)) + { + res = OC_STACK_ERROR; + goto exit; + } + + if (!isAclRownerUuidEmpty) + { + OIC_LOG_V(ERROR, TAG, "%s - aclRownerUuid is not empty for unOwned device!", __func__); + res = OC_STACK_ERROR; + goto exit; + } + + if (!isCredRownerUuidEmpty) + { + OIC_LOG_V(ERROR, TAG, "%s - credRownerUuid is not empty for unOwned device!", __func__); + res = OC_STACK_ERROR; + goto exit; + } + + if (OC_STACK_OK != CheckSecurityACEPermision(PERMISSION_READ | PERMISSION_WRITE)) + { + res = OC_STACK_ERROR; + goto exit; + } + + } + res = OC_STACK_OK; + + exit: + + if (OC_STACK_OK != res) + { + if (isResetPFExist() && !isOwned) + { + res = ResetSecureResourceInPS(); + OIC_LOG_V(INFO, TAG, "%s - Secure resources reseted (%d)", __func__, res); + } + else + { + SetPSStatus(PS_PARSE_FAIL); + res = DestroySecureResources(); + if(OC_STACK_OK == res) + { + res = InitSecureResources(); + if(OC_STACK_OK != res) + { + res = OC_STACK_INCONSISTENT_DB; + } + } + else + { + res = OC_STACK_INCONSISTENT_DB; + } + } + } + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + + return res; +} + +bool isResetPFExist(void) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + bool ret = false; + size_t dbSize = 0; + uint8_t *dbData = NULL; + + OCStackResult ocRes = OC_STACK_ERROR; + + ocRes = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize); + if (OC_STACK_OK != ocRes) + { + OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ocRes); + } + if (dbData && dbSize) + { + ocRes = OC_STACK_ERROR; + { + CborParser parser; + CborValue cbor; + cbor_parser_init(dbData, dbSize, 0, &parser, &cbor); + CborValue curVal = {0}; + CborError cborFindResult = CborNoError; + + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + OIC_LOG(DEBUG, TAG, "Reset Profile already exists!"); + ret = true; + } + else + { + OIC_LOG(DEBUG, TAG, "Reset Profile doesn't exists!"); + ret = false; + } + } + } + OICFree(dbData); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + + return ret; +} \ No newline at end of file diff --git a/resource/csdk/security/src/pstatresource.c b/resource/csdk/security/src/pstatresource.c index ceb8949..61e2713 100644 --- a/resource/csdk/security/src/pstatresource.c +++ b/resource/csdk/security/src/pstatresource.c @@ -1060,3 +1060,12 @@ exit: return ret; } +OCStackResult GetPstatCm(OicSecDpm_t *cm) +{ + if (gPstat && cm) + { + *cm = gPstat->cm; + return OC_STACK_OK; + } + return OC_STACK_ERROR; +} diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index c5b6fd3..e1ffc3d 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -4666,6 +4666,16 @@ OCStackResult initResources() } #endif + //check SVR DB Validity + OCStackResult validRes = CheckSVRDBValidity(); + + if( OC_STACK_INCONSISTENT_DB == validRes) + { + OIC_LOG_V(ERROR, TAG,"%s - SVR DB is not valid!",__func__); + } + + result = validRes; + if(result == OC_STACK_OK) { CreateResetProfile(); -- 2.7.4