[IOT-1884] Allow IoTivity to generate and persist PIID
[platform/upstream/iotivity.git] / resource / csdk / security / src / psinterface.c
index 0bd6cca..e525c6f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <inttypes.h>
 
 #include "cainterface.h"
 #include "logger.h"
 #include "srmutility.h"
 #include "pstatresource.h"
 #include "doxmresource.h"
+#include "ocresourcehandler.h"
 
 #define TAG  "OIC_SRM_PSI"
 
-//SVR database buffer block size
+/**
+ * Helps cover adding the name of the resource, map addition, and ending while
+ * performing CBOR encoding.
+ */
+#define CBOR_ENCODING_SIZE_ADDITION 255
+
+/**
+ * Virtual database buffer block size
+ */
 #ifdef _WIN32
 #define DB_FILE_SIZE_BLOCK 1023
 #else
 const size_t DB_FILE_SIZE_BLOCK = 1023;
 #endif
 
+typedef enum _PSDatabase
+{
+    PS_DATABASE_SECURITY = 0,
+    PS_DATABASE_DEVICEPROPERTIES
+} PSDatabase;
+
+/**
+ * Writes CBOR payload to the specified database in persistent storage.
+ *
+ * @param databaseName is the name of the database to access through persistent storage.
+ * @param payload      is the CBOR payload to write to the database in persistent storage.
+ * @param size         is the size of payload.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value
+ */
+static OCStackResult WritePayloadToPS(const char *databaseName, uint8_t *payload, size_t size)
+{
+    if (!databaseName || !payload || (size <= 0))
+    {
+        OC_STACK_INVALID_PARAM;
+    }
+
+    OCStackResult result = OC_STACK_ERROR;
+
+    OIC_LOG_V(DEBUG, TAG, "Writing in the file: %" PRIuPTR, size);
+
+    OCPersistentStorage* ps = OCGetPersistentStorageHandler();
+    if (ps)
+    {
+        FILE *fp = ps->open(databaseName, "wb");
+        if (fp)
+        {
+            size_t numberItems = ps->write(payload, 1, size, fp);
+            if (size == numberItems)
+            {
+                OIC_LOG_V(DEBUG, TAG, "Written %" PRIuPTR " bytes into %s", size, databaseName);
+                result = OC_STACK_OK;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, TAG, "Failed writing %" PRIuPTR " in %s", numberItems, databaseName);
+            }
+            ps->close(fp);
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "File open failed.");
+        }
+    }
+
+    return result;
+}
+
 /**
- * Gets the Secure Virtual Database size
+ * Gets the database size
  *
- * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
+ * @param ps            is a pointer to OCPersistentStorage for the Virtual Resource(s).
+ * @param databaseName  is the name of the database to access through persistent storage.
  *
- * @return size_t - total size of the SVR database
+ * @return size_t - total size of the database
  */
-static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
+static size_t GetDatabaseSize(const OCPersistentStorage *ps, const char *databaseName)
 {
     if (!ps)
     {
@@ -64,7 +128,7 @@ static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
     size_t size = 0;
     char buffer[DB_FILE_SIZE_BLOCK];  // can not initialize with declaration
                                       // but maybe not needed to initialize
-    FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
+    FILE *fp = ps->open(databaseName, "rb");
     if (fp)
     {
         size_t bytesRead = 0;
@@ -79,18 +143,24 @@ static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
 }
 
 /**
- * Gets the Secure Virtual Database from the Persistent Storage
+ * Reads the database from PS
+ * 
+ * @note Caller of this method MUST use OICFree() method to release memory
+ *       referenced by the data argument.
  *
- * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
- * @param data - pointer of the returned Secure Virtual Resource(s)
- * @param size - pointer of the returned size of Secure Virtual Resource(s)
+ * @param databaseName is the name of the database to access through persistent storage.
+ * @param resourceName is the name of the field for which file content are read.
+ *                     if the value is NULL it will send the content of the whole file.
+ * @param data         is the pointer to the file contents read from the database.
+ * @param size         is the size of the file contents read.
  *
- * @return OCStackResult - result of getting Secure Virtual Resource(s)
+ * @return ::OC_STACK_OK for Success, otherwise some error value
  */
-OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
+OCStackResult ReadDatabaseFromPS(const char *databaseName, const char *resourceName, uint8_t **data, size_t *size)
 {
-    OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS IN");
-    if (!data || *data || !size)
+    OIC_LOG(DEBUG, TAG, "ReadDatabaseFromPS IN");
+
+    if (!databaseName || !data || *data || !size)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -100,36 +170,36 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat
     size_t fileSize = 0;
     OCStackResult ret = OC_STACK_ERROR;
 
-    OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
+    OCPersistentStorage *ps = OCGetPersistentStorageHandler();
     VERIFY_NOT_NULL(TAG, ps, ERROR);
 
-    fileSize = GetSVRDatabaseSize(ps);
+    fileSize = GetDatabaseSize(ps, databaseName);
     OIC_LOG_V(DEBUG, TAG, "File Read Size: %zu", fileSize);
     if (fileSize)
     {
         fsData = (uint8_t *) OICCalloc(1, fileSize);
         VERIFY_NOT_NULL(TAG, fsData, ERROR);
 
-        fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
+        fp = ps->open(databaseName, "rb");
         VERIFY_NOT_NULL(TAG, fp, ERROR);
         if (ps->read(fsData, 1, fileSize, fp) == fileSize)
         {
-            if (rsrcName)
+            if (resourceName)
             {
                 CborParser parser;  // will be initialized in |cbor_parser_init|
                 CborValue cbor;     // will be initialized in |cbor_parser_init|
                 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
                 CborValue cborValue = {0};
-                CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
+                CborError cborFindResult = cbor_value_map_find_value(&cbor, resourceName, &cborValue);
                 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
                 {
                     cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
-                    VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
+                    VERIFY_SUCCESS(TAG, CborNoError == cborFindResult, ERROR);
                     ret = OC_STACK_OK;
                 }
                 // in case of |else (...)|, svr_data not found
             }
-            // return everything in case rsrcName is NULL
+            // return everything in case resourceName is NULL
             else
             {
                 *size = fileSize;
@@ -140,7 +210,7 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat
             }
         }
     }
-    OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS OUT");
+    OIC_LOG(DEBUG, TAG, "ReadDatabaseFromPS OUT");
 
 exit:
     if (fp)
@@ -152,20 +222,19 @@ exit:
 }
 
 /**
- * Updates the Secure Virtual Resource(s) into the Persistent Storage.
- * This function stores cbor-payload of each resource by appending resource name,
- * and empty payload implies deleting the value
+ * This method updates the database in PS
  *
- * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
- * @param psPayload - pointer of the updated Secure Virtual Resource(s)
- * @param psSize - the updated size of Secure Virtual Resource(s)
+ * @param databaseName  is the name of the database to access through persistent storage.
+ * @param resourceName  is the name of the resource that will be updated.
+ * @param payload       is the pointer to memory where the CBOR payload is located.
+ * @param size          is the size of the CBOR payload.
  *
- * @return OCStackResult - result of updating Secure Virtual Resource(s)
+ * @return ::OC_STACK_OK for Success, otherwise some error value
  */
-OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
+OCStackResult UpdateResourceInPS(const char *databaseName, const char *resourceName, const uint8_t *payload, size_t size)
 {
-    OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS IN");
-    if (!rsrcName)
+    OIC_LOG(DEBUG, TAG, "UpdateResourceInPS IN");
+    if (!databaseName || !resourceName)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -179,25 +248,33 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
     uint8_t *pstatCbor = NULL;
     uint8_t *doxmCbor = NULL;
     uint8_t *amaclCbor = NULL;
-    uint8_t *svcCbor = NULL;
     uint8_t *credCbor = NULL;
     uint8_t *pconfCbor = NULL;
     uint8_t *resetPfCbor = NULL;
     uint8_t *crlCbor = NULL;
+    uint8_t *dpCbor = NULL;
 
     int64_t cborEncoderResult = CborNoError;
-    OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
+    OCStackResult ret = ReadDatabaseFromPS(databaseName, NULL, &dbData, &dbSize);
     if (dbData && dbSize)
     {
+        PSDatabase database = PS_DATABASE_SECURITY;
+        size_t allocSize = 0;
         size_t aclCborLen = 0;
         size_t pstatCborLen = 0;
         size_t doxmCborLen = 0;
         size_t amaclCborLen = 0;
-        size_t svcCborLen = 0;
         size_t credCborLen = 0;
         size_t pconfCborLen = 0;
         size_t resetPfCborLen = 0;
         size_t crlCborLen = 0;
+        size_t dpCborLen = 0;
+
+        // Determine which database we are working with so we can scope our operations
+        if (0 == strcmp(OC_DEVICE_PROPS_FILE_NAME, databaseName))
+        {
+            database = PS_DATABASE_DEVICEPROPERTIES;
+        }
 
         // Gets each secure virtual resource from persistent storage
         // this local scoping intended, for destroying large cbor instances after use
@@ -208,200 +285,212 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
             CborValue curVal = {0};
             CborError cborFindResult = CborNoError;
 
-            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
-            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
-            {
-                cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
-            }
-            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
-            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
-            {
-                cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
-            }
-            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
-            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
-            {
-                cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
-            }
-            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
-            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
-            {
-                cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
-            }
-            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
-            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
-            {
-                cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
-            }
-            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
-            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
-            {
-                cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
-            }
-            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
-            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            // Only search for and copy resources owned by the target database
+            if (PS_DATABASE_SECURITY == database)
             {
-                cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
-            }
-            int64_t cborFindCrlResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRL_NAME, &curVal);
-            if (CborNoError == cborFindCrlResult && cbor_value_is_byte_string(&curVal))
-            {
-                cborFindCrlResult = cbor_value_dup_byte_string(&curVal, &crlCbor, &crlCborLen, NULL);
-                if (CborNoError != cborFindCrlResult && CborErrorOutOfMemory != cborFindCrlResult)
+                // Security database
+                cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
+                if ((CborNoError == cborFindResult) && cbor_value_is_byte_string(&curVal))
+                {
+                    cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
+                }
+                cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
+                if ((CborNoError == cborFindResult) && cbor_value_is_byte_string(&curVal))
+                {
+                    cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
+                }
+                cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
+                if ((CborNoError == cborFindResult) && cbor_value_is_byte_string(&curVal))
+                {
+                    cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
+                }
+                cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
+                if ((CborNoError == cborFindResult) && cbor_value_is_byte_string(&curVal))
+                {
+                    cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
+                }
+                cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
+                if ((CborNoError == cborFindResult) && cbor_value_is_byte_string(&curVal))
                 {
-                    OIC_LOG(ERROR, TAG, "Failed Finding optional CRL Name Value.");
+                    cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
+                }
+                cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
+                if ((CborNoError == cborFindResult) && cbor_value_is_byte_string(&curVal))
+                {
+                    cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
+                }
+                cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
+                if ((CborNoError == cborFindResult) && cbor_value_is_byte_string(&curVal))
+                {
+                    cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
+                }
+                int64_t cborFindCrlResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRL_NAME, &curVal);
+                if ((CborNoError == cborFindCrlResult) && cbor_value_is_byte_string(&curVal))
+                {
+                    cborFindCrlResult = cbor_value_dup_byte_string(&curVal, &crlCbor, &crlCborLen, NULL);
+                    if ((CborNoError != cborFindCrlResult) && (CborErrorOutOfMemory != cborFindCrlResult))
+                    {
+                        OIC_LOG(ERROR, TAG, "Failed Finding optional CRL Name Value.");
+                    }
+                    else
+                    {
+                        OIC_LOG(INFO, TAG, "Successfully Finding optional CRL Name Value.");
+                    }
                 }
-                else
+            }
+            else
+            {
+                // Device Properties database
+                cborFindResult = cbor_value_map_find_value(&cbor, OC_JSON_DEVICE_PROPS_NAME, &curVal);
+                if ((CborNoError == cborFindResult) && cbor_value_is_byte_string(&curVal))
                 {
-                    OIC_LOG(INFO, TAG, "Successfully Finding optional CRL Name Value.");
+                    cborFindResult = cbor_value_dup_byte_string(&curVal, &dpCbor, &dpCborLen, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Properties Name Value.");
                 }
             }
         }
 
-        // Updates the added |psPayload| with the existing secure virtual resource(s)
+        // Updates the added |payload| with the existing secure virtual resource(s)
         // this local scoping intended, for destroying large cbor instances after use
         {
-            size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
-                        + svcCborLen + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
-                        + psSize + 255;
-            // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
+            if (PS_DATABASE_SECURITY == database)
+            {
+                allocSize = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
+                          + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
+                          + size + CBOR_ENCODING_SIZE_ADDITION;
+            }
+            else
+            {
+                allocSize = dpCborLen + size + CBOR_ENCODING_SIZE_ADDITION;
+            }
 
-            outPayload = (uint8_t *) OICCalloc(1, size);
+
+            outPayload = (uint8_t *)OICCalloc(1, allocSize);
             VERIFY_NOT_NULL(TAG, outPayload, ERROR);
             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
-            cbor_encoder_init(&encoder, outPayload, size, 0);
-            CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
-            cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
+            cbor_encoder_init(&encoder, outPayload, allocSize, 0);
+            CborEncoder resource;  // will be initialized in |cbor_encoder_create_map|
+            cborEncoderResult |= cbor_encoder_create_map(&encoder, &resource, CborIndefiniteLength);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
 
-            if (psPayload && psSize)
+            if (payload && size)
             {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
+                cborEncoderResult |= cbor_encode_text_string(&resource, resourceName, strlen(resourceName));
                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
+                cborEncoderResult |= cbor_encode_byte_string(&resource, payload, size);
                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
             }
-            if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
-            {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
-            }
-            if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
-            {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
-            }
-            if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
-            {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
-            }
-            if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
-            {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
-            }
-            if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
-            {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
-            }
-            if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
-            {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
-            }
-            if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen)
+
+            if (PS_DATABASE_SECURITY == database)
             {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
+                // Security database
+                if (strcmp(OIC_JSON_ACL_NAME, resourceName) && aclCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, aclCbor, aclCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
+                }
+                else if (strcmp(OIC_JSON_PSTAT_NAME, resourceName) && pstatCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, pstatCbor, pstatCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
+                }
+                else if (strcmp(OIC_JSON_DOXM_NAME, resourceName) && doxmCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, doxmCbor, doxmCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
+                }
+                else if (strcmp(OIC_JSON_AMACL_NAME, resourceName) && amaclCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, amaclCbor, amaclCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
+                }
+                else if (strcmp(OIC_JSON_CRED_NAME, resourceName) && credCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, credCbor, credCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
+                }
+                else if (strcmp(OIC_JSON_PCONF_NAME, resourceName) && pconfCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, pconfCbor, pconfCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
+                }
+                else if (strcmp(OIC_JSON_RESET_PF_NAME, resourceName) && resetPfCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, resetPfCbor, resetPfCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
+                }
+                else if (strcmp(OIC_JSON_CRL_NAME, resourceName) && crlCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OIC_JSON_CRL_NAME, strlen(OIC_JSON_CRL_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, crlCbor, crlCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Value.");
+                }
             }
-            if (strcmp(OIC_JSON_CRL_NAME, rsrcName) && crlCborLen)
+            else
             {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRL_NAME, strlen(OIC_JSON_CRL_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, crlCbor, crlCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Value.");
+                // Device Properties database
+                if (strcmp(OC_JSON_DEVICE_PROPS_NAME, resourceName) && dpCborLen)
+                {
+                    cborEncoderResult |= cbor_encode_text_string(&resource, OC_JSON_DEVICE_PROPS_NAME, strlen(OC_JSON_DEVICE_PROPS_NAME));
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Properties Name.");
+                    cborEncoderResult |= cbor_encode_byte_string(&resource, dpCbor, dpCborLen);
+                    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Properties Value.");
+                }
             }
 
-            cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
+            cborEncoderResult |= cbor_encoder_close_container(&encoder, &resource);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
             outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
         }
     }
-    else if (psPayload && psSize)
+    else if (payload && size)
     {
-        size_t size = psSize + 255;
-        // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
+        size_t allocSize = size + CBOR_ENCODING_SIZE_ADDITION;
 
-        outPayload = (uint8_t *) OICCalloc(1, size);
+        outPayload = (uint8_t *)OICCalloc(1, allocSize);
         VERIFY_NOT_NULL(TAG, outPayload, ERROR);
         CborEncoder encoder;  // will be initialized in |cbor_parser_init|
-        cbor_encoder_init(&encoder, outPayload, size, 0);
-        CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
-        cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
+        cbor_encoder_init(&encoder, outPayload, allocSize, 0);
+        CborEncoder resource;  // will be initialized in |cbor_encoder_create_map|
+        cborEncoderResult |= cbor_encoder_create_map(&encoder, &resource, CborIndefiniteLength);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
 
-        cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
+        cborEncoderResult |= cbor_encode_text_string(&resource, resourceName, strlen(resourceName));
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
-        cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
+        cborEncoderResult |= cbor_encode_byte_string(&resource, payload, size);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
 
-        cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
+        cborEncoderResult |= cbor_encoder_close_container(&encoder, &resource);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
         outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
     }
 
-    if (outPayload && outSize)
-    {
-        OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
-        OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
-        if (ps)
-        {
-            FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
-            if (fp)
-            {
-                size_t numberItems = ps->write(outPayload, 1, outSize, fp);
-                if (outSize == numberItems)
-                {
-                    OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
-                    ret = OC_STACK_OK;
-                }
-                else
-                {
-                    OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
-                }
-                ps->close(fp);
-            }
-            else
-            {
-                OIC_LOG(ERROR, TAG, "File open failed.");
-            }
-        }
-    }
+    ret = WritePayloadToPS(databaseName, outPayload, outSize);
+    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR);
 
-    OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS OUT");
+    OIC_LOG(DEBUG, TAG, "UpdateResourceInPS OUT");
 
 exit:
     OICFree(dbData);
@@ -410,15 +499,47 @@ exit:
     OICFree(pstatCbor);
     OICFree(doxmCbor);
     OICFree(amaclCbor);
-    OICFree(svcCbor);
     OICFree(credCbor);
     OICFree(pconfCbor);
     OICFree(resetPfCbor);
     OICFree(crlCbor);
+    OICFree(dpCbor);
     return ret;
 }
 
 /**
+ * Reads the Secure Virtual Database from PS
+ *
+ * @note Caller of this method MUST use OICFree() method to release memory
+ *       referenced by return value.
+ *
+ * @param resourceName is the name of the field for which file content are read.
+ *                     if the value is NULL it will send the content of the whole file.
+ * @param data         is the pointer to the file contents read from the database.
+ * @param size         is the size of the file contents read.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult GetSecureVirtualDatabaseFromPS(const char *resourceName, uint8_t **data, size_t *size)
+{
+    return ReadDatabaseFromPS(SVR_DB_DAT_FILE_NAME, resourceName, data, size);
+}
+
+/**
+ * This method updates the Secure Virtual Database in PS
+ *
+ * @param resourceName  is the name of the secure resource that will be updated.
+ * @param payload       is the pointer to memory where the CBOR payload is located.
+ * @param size          is the size of the CBOR payload.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult UpdateSecureResourceInPS(const char *resourceName, const uint8_t *payload, size_t size)
+{
+    return UpdateResourceInPS(SVR_DB_DAT_FILE_NAME, resourceName, payload, size);
+}
+
+/**
  * Resets the Secure Virtual Resource(s).
  * This function reads the Reset Profile
  * and resets the secure virtual resources accordingly.
@@ -442,7 +563,6 @@ OCStackResult ResetSecureResourceInPS(void)
 
     int64_t cborEncoderResult = CborNoError;
     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
-
     if(dbData && dbSize)
     {
         size_t aclCborLen = 0;
@@ -500,8 +620,7 @@ OCStackResult ResetSecureResourceInPS(void)
         }
 
         {
-            size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
-            // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
+            size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + CBOR_ENCODING_SIZE_ADDITION;
 
             outPayload = (uint8_t *) OICCalloc(1, size);
             VERIFY_NOT_NULL(TAG, outPayload, ERROR);
@@ -543,34 +662,8 @@ OCStackResult ResetSecureResourceInPS(void)
             outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
         }
 
-        if (outPayload && outSize)
-        {
-            OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
-            OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
-            if (ps)
-            {
-                FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
-                if (fp)
-                {
-                    size_t numberItems = ps->write(outPayload, 1, outSize, fp);
-                    if (outSize == numberItems)
-                    {
-                        OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
-                        ret= OC_STACK_OK;
-                    }
-                    else
-                    {
-                        OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
-                    }
-                    ps->close(fp);
-                }
-                else
-                {
-                    OIC_LOG(ERROR, TAG, "File open failed.");
-                }
-
-            }
-        }
+        ret = WritePayloadToPS(SVR_DB_DAT_FILE_NAME, outPayload, outSize);
+        VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR);
     }
 
     SRMDeInitSecureResources();
@@ -662,7 +755,7 @@ OCStackResult CreateResetProfile(void)
         }
 
         {
-            size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + 255;
+            size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + CBOR_ENCODING_SIZE_ADDITION;
             resetPfCbor = (uint8_t *) OICCalloc(1, size);
             VERIFY_NOT_NULL(TAG, resetPfCbor, ERROR);
             CborEncoder encoder;  // will be initialized in |cbor_parser_init|