Draft Created API for SVR DB Integrity check 94/218794/1
authorVitalii Irkha <v.irkha@samsung.com>
Thu, 14 Nov 2019 18:35:33 +0000 (20:35 +0200)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Thu, 28 Nov 2019 07:26:13 +0000 (16:26 +0900)
https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/610
(cherry-picked from b2f7a3c0a121bf83f3551b0bca18061d8b5263f1)

Change-Id: I6fe01f4de77a8e8f538666f8745b9b46cfd057fd
Signed-off-by: Vitalii Irkha <v.irkha@samsung.com>
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
resource/csdk/security/include/internal/aclresource.h
resource/csdk/security/include/internal/psinterface.h
resource/csdk/security/include/internal/pstatresource.h
resource/csdk/security/src/aclresource.c
resource/csdk/security/src/doxmresource.c
resource/csdk/security/src/psinterface.c
resource/csdk/security/src/pstatresource.c
resource/csdk/stack/src/ocstack.c

index 0172ae4..8b28c3a 100644 (file)
@@ -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
index 73bc90e..9dbfc53 100644 (file)
@@ -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
index c021cb0..d158cff 100644 (file)
@@ -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
index dc4b874..566bf79 100644 (file)
@@ -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;
+}
index c7362fb..98c8405 100644 (file)
@@ -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;
index d6474ab..e1e5a43 100644 (file)
@@ -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
index ceb8949..61e2713 100644 (file)
@@ -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;
+}
index c5b6fd3..e1ffc3d 100644 (file)
@@ -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();