SVR DB Editor 33/21333/3
authorsangjoon.je <sangjoon.je@samsung.com>
Tue, 4 Jul 2017 06:04:09 +0000 (15:04 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Tue, 11 Jul 2017 06:27:41 +0000 (06:27 +0000)
This tool provides following features :
 [Doxm]
  - Print Doxm data
  - Modify Doxm data (T.B.D)

 [Pstat]
  - Print Pstat data
  - Modify Pstat data (T.B.D)

 [ACL]
  - Print ACL/ACE data
  - Modify ACL/ACE data (T.B.D)
  - Insert ACE to ACL
  - Remove ACE from ACL

 [Credential]
  - Print Credential data (Not fully supported yet)
  - Modify Credential data (T.B.D)
  - Insert credential to credential list (Not fully supported yet)
  - Remove credential from credential list

 [Generate default SVR DB]
  - (T.B.D)

New Feature: https://jira.iotivity.org/browse/IOT-2378
Change-Id: Ibf530c055207aced5270c5f8e1fb8019adc7243a
Signed-off-by: Chul Lee <chuls.lee@samsung.com>
Signed-off-by: sangjoon.je <sangjoon.je@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/17365
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Youngman Jung <yman.jung@samsung.com>
Reviewed-by: Jongmin Choi <jminl.choi@samsung.com>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
(cherry picked from commit f43943b5ca63b3bc9c060ea2b7b17cfe4226e39c)
Reviewed-on: https://gerrit.iotivity.org/gerrit/21333
Reviewed-by: Phil Coval <philippe.coval@osg.samsung.com>
resource/csdk/security/tool/SConscript
resource/csdk/security/tool/svrdbeditor.c [new file with mode: 0644]

index 5820028..1a6e307 100644 (file)
@@ -44,7 +44,9 @@ tools_env.PrependUnique(CPPPATH=[
     '../../connectivity/api',
     '../../connectivity/inc/pkix',
     '../include',
-    '../include/internal'
+    '../include/internal',
+    '../provisioning/include',
+    '../provisioning/include/internal'
 ])
 tools_env.AppendUnique(CXXFLAGS=['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x'])
 tools_env.AppendUnique(RPATH=[tools_env.get('BUILD_DIR')])
@@ -55,7 +57,9 @@ if target_os in ['windows', 'msys_nt']:
     tools_env.AppendUnique(CPPDEFINES=['CJSON_HIDE_SYMBOLS'])
 
 if target_os not in ['darwin', 'msys_nt', 'windows']:
-    tools_env.PrependUnique(LIBS=['octbstack', 'ocsrm', 'm'])
+    tools_env.PrependUnique(LIBS=[
+        'octbstack', 'ocsrm', 'm', 'mbedtls', 'mbedx509', 'mbedcrypto'
+    ])
 else:
     if target_os in ['darwin']:
         tools_env.AppendUnique(LIBS=['octbstack', 'connectivity_abstraction'])
@@ -79,10 +83,14 @@ else:
 
 tools_env.PrependUnique(LIBS=['cjson'])
 
+if tools_env.get('MULTIPLE_OWNER') == '1':
+    tools_env.AppendUnique(CPPDEFINES=['MULTIPLE_OWNER'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
 json2cbor_src = ['json2cbor.c']
 json2cbor = tools_env.Program('json2cbor', json2cbor_src)
-Alias("json2cbor", [json2cbor])
-tools_env.AppendTarget('json2cbor')
+svrdbeditor = tools_env.Program('svrdbeditor', ['svrdbeditor.c'])
+Alias("securitytool", [json2cbor, svrdbeditor])
+tools_env.AppendTarget('securitytool')
diff --git a/resource/csdk/security/tool/svrdbeditor.c b/resource/csdk/security/tool/svrdbeditor.c
new file mode 100644 (file)
index 0000000..4c3e882
--- /dev/null
@@ -0,0 +1,2377 @@
+//******************************************************************
+//
+// Copyright 2017 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// 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 _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "iotivity_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mbedtls/ssl.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/x509_crt.h>
+#include <mbedtls/pkcs12.h>
+#include <mbedtls/ssl_internal.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "utlist.h"
+#include "cJSON.h"
+#include "base64.h"
+#include "cainterface.h"
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
+#include "payload_logging.h"
+#include "secureresourcemanager.h"
+#include "secureresourceprovider.h"
+#include "srmresourcestrings.h"
+#include "srmutility.h"
+#include "aclresource.h"
+#include "pstatresource.h"
+#include "doxmresource.h"
+#include "amaclresource.h"
+#include "credresource.h"
+#include "security_internals.h"
+#include "psinterface.h"
+#include "pinoxmcommon.h"
+
+#define TAG  "OIC_SVR_DB_EDITOR"
+
+#define BOLD_BEGIN    "\033[1m"
+#define RED_BEGIN      "\033[1;31m"
+#define YELLOW_BEGIN  "\033[1;33m"
+#define CYAN_BEGIN  "\033[1;36m"
+#define GREEN_BEGIN  "\033[1;92m"
+#define COLOR_END      "\033[0m"
+#define COLOR_END_NL      "\033[0m\n"
+
+#define ACL_PEMISN_CNT (5)
+#define SVR_MAX_ENTITY (16)
+
+#define SVR_DB_PATH_LENGTH 1024
+#define PRINT_ERR(fmt,...) printf(RED_BEGIN "error: " fmt COLOR_END_NL, ##__VA_ARGS__)
+
+typedef enum OperationType
+{
+    SVR_PRINT_ALL = 1,
+    SVR_EDIT_CRED = 2,
+    SVR_EDIT_ACL = 3,
+    SVR_EDIT_DOXM = 4,
+    SVR_EDIT_PSTAT = 5,
+    EXIT = 99
+} OperationType_t;
+
+typedef enum SubOperationType
+{
+    SVR_PRINT = 1,
+    SVR_ADD = 2,
+    SVR_REMOVE = 3,
+    SVR_MODIFY = 4,
+    SVR_EDIT_IDX_SIZE = 5,
+    BACK = 99
+} SubOperationType_t;
+
+bool gAllowedEditMenu[SVR_EDIT_IDX_SIZE] = {false/*unused*/, false, false, false, false};
+char gSvrDbPath[SVR_DB_PATH_LENGTH] = {0};
+
+OicSecDoxm_t *gDoxmResource = NULL;
+OicSecPstat_t *gPstatResource = NULL;
+OicSecAcl_t *gAclResource = NULL;
+
+
+/**
+ * input |g_svr_db_fname| internally by force, not using |path| parameter
+ * because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
+ * with its own |SVR_DB_FILE_NAME|
+ */
+static FILE *fopen_svreditor(const char *path, const char *mode)
+{
+    (void)path;  // unused |path| parameter
+
+    return fopen(gSvrDbPath, mode);
+}
+
+static void RefreshSVRInstance(bool credRefFlag, bool aclRefFlag, bool doxmRefFlag,
+                               bool pstatRefFlag);
+static int ReadDataFromFile(const char *infoTxt, uint8_t **buffer, size_t *bufferSize);
+
+static void FreeACE(OicSecAce_t *ace);
+
+static void PrintMainMenu();
+static void PrintEditMenu(const char *resourceName, bool print, bool add, bool remove, bool modify);
+static void PrintUuid(const OicUuid_t *uuid);
+static void PrintIntArray(const int *array, size_t length);
+static void PrintStringArray(const char **array, size_t length);
+static void PrintInt(int value);
+static void PrintString(const char *text);
+static void PrintBuffer(const uint8_t *buf, size_t bufLen);
+static void PrintDpm(const OicSecDpm_t dpm);
+static void PrintDpom(const OicSecDpom_t dpom);
+#ifdef MULTIPLE_OWNER
+static void PrintMom(const OicSecMom_t *mom);
+#endif
+static void PrintCredType(OicSecCredType_t credType);
+static void PrintCredEncodingType(OicEncodingType_t encoding);
+static void PrintHelp();
+
+static void PrintResourceList(const OicSecRsrc_t *rsrcList);
+static void PrintValidity(const OicSecValidity_t *validity);
+static void PrintPermission(uint16_t permission);
+
+
+static void PrintDoxm(const OicSecDoxm_t *doxm);
+static void PrintPstat(const OicSecPstat_t *pstat);
+static size_t PrintAcl(const OicSecAcl_t *acl);
+/**
+ * Print credential list.
+ */
+static void PrintCredList(const OicSecCred_t *creds);
+
+
+static int InputNumber(const char *infoText);
+static char InputChar(const char *infoText);
+static char *InputString(const char *infoText);
+static int InputUuid(OicUuid_t *uuid);
+
+
+static int InputResources(OicSecRsrc_t *resources);
+static int InputAceData(OicSecAce_t *ace);
+
+static int InputCredUsage(char **credUsage);
+static int InputCredEncodingType(const char *dataType, OicEncodingType_t *encoding);
+static int InputCredentialData(OicSecCred_t *cred);
+
+static void HandleCredOperation(SubOperationType_t cmd);
+static void HandleAclOperation(const SubOperationType_t cmd);
+static void HandleDoxmOperation(const SubOperationType_t cmd);
+static void HandlePstatOperation(const SubOperationType_t cmd);
+
+
+/**
+ * Parse chain of X.509 certificates.
+ *
+ * @param[out] crt     container for X.509 certificates
+ * @param[in]  buf     buffer with X.509 certificates. Certificates may be in either in PEM
+ or DER format in a jumble. Each PEM certificate must be NULL-terminated.
+ * @param[in]  bufLen  buffer length
+ *
+ * @return  0 on success, -1 on error
+ */
+static int ParseCertChain(mbedtls_x509_crt *crt, unsigned char *buf, size_t bufLen);
+static void ParseDerCaCert(ByteArray_t *crt, const char *usage, uint16_t credId);
+static void ParseDerKey(ByteArray_t *key, const char *usage, uint16_t credId);
+static void ParseDerOwnCert(ByteArray_t *crt, const char *usage, uint16_t credId);
+
+
+static int MainOperation(const char *svrpath)
+{
+    OperationType_t menu = EXIT;
+    SubOperationType_t editMenu = EXIT;
+    OCStackResult ocResult = OC_STACK_ERROR;
+    bool run = true;
+
+    // initialize persistent storage for SVR DB
+    static OCPersistentStorage psInst =
+    {
+        .open = fopen_svreditor,
+        .read = fread,
+        .write = fwrite,
+        .close = fclose,
+        .unlink = unlink
+    };
+
+    if (!svrpath)
+    {
+        PRINT_ERR("Incorrect file path");
+        return -1;
+    }
+
+    strcpy(gSvrDbPath, svrpath);
+
+    ocResult = OCRegisterPersistentStorageHandler(&psInst);
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_ERR("OCRegisterPersistentStorageHandler : %d", ocResult);
+        return -1;
+    }
+
+    RefreshSVRInstance(true, true, true, true);
+
+    while (run)
+    {
+        PrintMainMenu();
+        menu = (OperationType_t)InputNumber("\tSelect the menu : ");
+        switch (menu)
+        {
+            case SVR_PRINT_ALL:
+                PrintDoxm(gDoxmResource);
+                PrintPstat(gPstatResource);
+                PrintAcl(gAclResource);
+                PrintCredList(GetCredList());
+                break;
+            case SVR_EDIT_CRED:
+                do
+                {
+                    if (NULL == GetCredList())
+                    {
+                        printf(YELLOW_BEGIN "WARNING : Credential resource is empty." COLOR_END_NL);
+                        PrintEditMenu("Credential Resource", false, true, false, false);
+                    }
+                    else
+                    {
+                        PrintEditMenu("Credential Resource", true, true, true, true);
+                    }
+                    editMenu = (SubOperationType_t)InputNumber("Select the menu : ");
+                    HandleCredOperation(editMenu);
+                    RefreshSVRInstance(true, false, false, false);
+                }
+                while (BACK != editMenu);
+                break;
+            case SVR_EDIT_ACL:
+                do
+                {
+                    if (NULL == gAclResource)
+                    {
+                        printf(YELLOW_BEGIN "WARNING : ACL resource is empty." COLOR_END_NL);
+                        PrintEditMenu("ACL Resource", false, true, false, false);
+                    }
+                    else
+                    {
+                        PrintEditMenu("ACL Resource", true, true, true, false);
+                    }
+                    editMenu = (SubOperationType_t)InputNumber("Select the menu : ");
+                    HandleAclOperation(editMenu);
+                    RefreshSVRInstance(false, true, false, false);
+                }
+                while (BACK != editMenu);
+
+                break;
+            case SVR_EDIT_DOXM:
+                printf(YELLOW_BEGIN "NOT SUPPORTED YET" COLOR_END_NL);
+                //PrintEditMenu("Doxm Resource", false, false, true);
+                //T.B.D
+                break;
+            case SVR_EDIT_PSTAT:
+                printf(YELLOW_BEGIN "NOT SUPPORTED YET" COLOR_END_NL);
+                //PrintEditMenu("Pstat Resource", false, false, true);
+                //T.B.D
+                break;
+            case EXIT:
+                run = false;
+                break;
+            default:
+                PRINT_ERR("Unknown operation");
+                PRINT_ERR("Please make sure the menu.");
+                break;
+        }
+    }
+
+    DeInitCredResource();
+    DeletePstatBinData(gPstatResource);
+    DeleteDoxmBinData(gDoxmResource);
+    DeleteACLList(gAclResource);
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    if (argc == 2)
+    {
+        printf("SVR DB File Path: %s\n", argv[1]);
+        return MainOperation(argv[1]);
+    }
+    else
+    {
+        PrintHelp();
+        return 0;
+    }
+}
+
+
+
+///////////////////////////// Internal API implementation /////////////////////////////
+
+
+static void RefreshSVRInstance(bool credRefFlag, bool aclRefFlag, bool doxmRefFlag,
+                               bool pstatRefFlag)
+{
+    uint8_t *secPayload = NULL;
+    size_t payloadSize = 0;
+    OCStackResult ocResult = OC_STACK_ERROR;
+
+    if (credRefFlag)
+    {
+        OicSecCred_t *credList = NULL;
+        OicSecCred_t *cred = NULL;
+        OicSecCred_t *tmpCred = NULL;
+        //Load security resouce data from SVR DB.
+        ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &secPayload, &payloadSize);
+        if (OC_STACK_OK != ocResult)
+        {
+            printf(YELLOW_BEGIN "WARNING : GetSecureVirtualDatabaseFromPS error : %d" COLOR_END_NL, ocResult);
+        }
+        if (secPayload && 0 != payloadSize)
+        {
+            ocResult = CBORPayloadToCred(secPayload, payloadSize, &credList);
+            if (OC_STACK_OK != ocResult)
+            {
+                OICFree(secPayload);
+                PRINT_ERR("CBORPayloadToCred error : %d", ocResult);
+                return;
+            }
+        }
+        OICFree(secPayload);
+        secPayload = NULL;
+
+        //Add the loaded credentials into gCred of CredResource module in order to use the credential management mechanism.
+        LL_FOREACH_SAFE(credList, cred, tmpCred)
+        {
+            ocResult = AddCredential(cred);
+            if (OC_STACK_OK != ocResult)
+            {
+                PRINT_ERR("AddCredential : %d", ocResult);
+                return;
+            }
+        }
+    }
+
+    if (aclRefFlag)
+    {
+        ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &secPayload, &payloadSize);
+        if (OC_STACK_OK != ocResult)
+        {
+            printf(YELLOW_BEGIN "WARNING : GetSecureVirtualDatabaseFromPS error : %d" COLOR_END_NL, ocResult);
+        }
+
+        if (gAclResource)
+        {
+            DeleteACLList(gAclResource);
+            gAclResource = NULL;
+        }
+
+        gAclResource = CBORPayloadToAcl(secPayload, payloadSize);
+        if (NULL == gAclResource)
+        {
+            OICFree(secPayload);
+            PRINT_ERR("CBORPayloadToAcl error : %d", ocResult);
+            return;
+        }
+
+        OICFree(secPayload);
+        secPayload = NULL;
+    }
+
+    if (doxmRefFlag)
+    {
+        ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_DOXM_NAME, &secPayload, &payloadSize);
+        if (OC_STACK_OK != ocResult)
+        {
+            printf(YELLOW_BEGIN "WARNING : GetSecureVirtualDatabaseFromPS error : %d" COLOR_END_NL, ocResult);
+        }
+
+        if (gDoxmResource)
+        {
+            DeleteDoxmBinData(gDoxmResource);
+            gDoxmResource = NULL;
+        }
+
+        ocResult = CBORPayloadToDoxm(secPayload, payloadSize, &gDoxmResource);
+        if (OC_STACK_OK != ocResult)
+        {
+            OICFree(secPayload);
+            PRINT_ERR("CBORPayloadToDoxm error : %d" , ocResult);
+            return;
+        }
+
+        OICFree(secPayload);
+        secPayload = NULL;
+    }
+
+    if (pstatRefFlag)
+    {
+        ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_PSTAT_NAME, &secPayload, &payloadSize);
+        if (OC_STACK_OK != ocResult)
+        {
+            printf(YELLOW_BEGIN "WARNING : GetSecureVirtualDatabaseFromPS error : %d" COLOR_END_NL, ocResult);
+        }
+
+        if (gPstatResource)
+        {
+            DeletePstatBinData(gPstatResource);
+            gPstatResource = NULL;
+        }
+
+        ocResult = CBORPayloadToPstat(secPayload, payloadSize, &gPstatResource);
+        if (OC_STACK_OK != ocResult)
+        {
+            OICFree(secPayload);
+            PRINT_ERR("CBORPayloadToPstat error : %d" , ocResult);
+            return;
+        }
+
+        OICFree(secPayload);
+        secPayload = NULL;
+    }
+}
+
+static void FreeACE(OicSecAce_t *ace)
+{
+    if (NULL == ace)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid Parameter");
+        return;
+    }
+
+    //Clean Resources
+    OicSecRsrc_t *rsrc = NULL;
+    OicSecRsrc_t *tmpRsrc = NULL;
+    LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
+    {
+        LL_DELETE(ace->resources, rsrc);
+        FreeRsrc(rsrc);
+    }
+
+    //Clean Validities
+    OicSecValidity_t *validity = NULL;
+    OicSecValidity_t *tmpValidity = NULL;
+    LL_FOREACH_SAFE(ace->validities, validity, tmpValidity)
+    {
+        LL_DELETE(ace->validities, validity);
+
+        //Clean period
+        OICFree(validity->period);
+
+        //Clean recurrence
+        for (size_t i = 0; i < validity->recurrenceLen; i++)
+        {
+            OICFree(validity->recurrences[i]);
+        }
+        OICFree(validity->recurrences);
+        OICFree(validity);
+        validity = NULL;
+    }
+
+#ifdef MULTIPLE_OWNER
+    OICFree(ace->eownerID);
+#endif
+
+    //Clean ACE
+    OICFree(ace);
+    ace = NULL;
+}
+
+
+static void PrintUuid(const OicUuid_t *uuid)
+{
+    char *strUuid = NULL;
+    if (OC_STACK_OK == ConvertUuidToStr(uuid, &strUuid))
+    {
+        printf(CYAN_BEGIN "%s" COLOR_END_NL, strUuid);
+        OICFree(strUuid);
+    }
+    else
+    {
+        PRINT_ERR("Can not convert UUID to String");
+    }
+}
+
+static void PrintIntArray(const int *array, size_t length)
+{
+    bool colorToogle = true;
+
+    if (length == 0)
+    {
+        printf("\n");
+    }
+    else
+    {
+        for (size_t i = 0; i < length; i++)
+        {
+            if (i == length - 1)
+            {
+                colorToogle ? printf(CYAN_BEGIN "%d" COLOR_END_NL, array[i]) : printf(GREEN_BEGIN "%d" COLOR_END_NL,
+                        array[i]);
+            }
+            else
+            {
+                colorToogle ? printf(CYAN_BEGIN "%d " COLOR_END, array[i]) : printf(GREEN_BEGIN "%d " COLOR_END,
+                        array[i]);
+            }
+            colorToogle = (!colorToogle);
+        }
+    }
+}
+
+static void PrintStringArray(const char **array, size_t length)
+{
+    bool colorToogle = true;
+
+    if (length == 0)
+    {
+        printf("\n");
+    }
+    else
+    {
+        for (size_t i = 0; i < length; i++)
+        {
+            if (i == length - 1)
+            {
+                colorToogle ? printf(CYAN_BEGIN "%s" COLOR_END_NL, array[i]) : printf(GREEN_BEGIN "%s" COLOR_END_NL,
+                        array[i]);
+            }
+            else
+            {
+                colorToogle ? printf(CYAN_BEGIN "%s " COLOR_END, array[i]) : printf(GREEN_BEGIN "%s " COLOR_END,
+                        array[i]);
+            }
+            colorToogle = (!colorToogle);
+        }
+    }
+}
+
+static void PrintInt(int value)
+{
+    printf(CYAN_BEGIN "%d" COLOR_END_NL, value);
+}
+
+static void PrintString(const char *text)
+{
+    printf(CYAN_BEGIN "%s" COLOR_END_NL, text);
+}
+
+static void PrintBuffer(const uint8_t *buf, size_t bufLen)
+{
+    size_t i = 0;
+
+    for (i = 0; i < bufLen; i++)
+    {
+        if ((i + 1) % 20 == 0 || i == bufLen - 1)
+        {
+            printf(CYAN_BEGIN "%02X " COLOR_END_NL, buf[i]);
+        }
+        else
+        {
+            printf(CYAN_BEGIN "%02X " COLOR_END, buf[i]);
+        }
+    }
+}
+
+static void PrintDpm(const OicSecDpm_t dpm)
+{
+    printf(CYAN_BEGIN "%d (" COLOR_END, dpm);
+
+    if (dpm == NORMAL)
+    {
+        printf(CYAN_BEGIN " NORMAL " COLOR_END);
+    }
+    if (dpm & RESET)
+    {
+        printf(CYAN_BEGIN " RESET " COLOR_END);
+    }
+    if (dpm & TAKE_OWNER)
+    {
+        printf(CYAN_BEGIN " TAKE_OWNER " COLOR_END);
+    }
+    if (dpm & BOOTSTRAP_SERVICE)
+    {
+        printf(CYAN_BEGIN " BOOTSTRAP_SERVICE " COLOR_END);
+    }
+    if (dpm & SECURITY_MANAGEMENT_SERVICES)
+    {
+        printf(CYAN_BEGIN " SECURITY_MANAGEMENT_SERVICES " COLOR_END);
+    }
+    if (dpm & PROVISION_CREDENTIALS)
+    {
+        printf(CYAN_BEGIN " PROVISION_CREDENTIALS " COLOR_END);
+    }
+    if (dpm & PROVISION_ACLS)
+    {
+        printf(CYAN_BEGIN " PROVISION_ACLS " COLOR_END);
+    }
+    printf(CYAN_BEGIN ") " COLOR_END_NL);
+}
+
+static void PrintDpom(const OicSecDpom_t dpom)
+{
+    printf(CYAN_BEGIN "%d (" COLOR_END, dpom);
+
+    if (dpom & MULTIPLE_SERVICE_SERVER_DRIVEN)
+    {
+        printf(CYAN_BEGIN " MULTIPLE_SERVICE_SERVER_DRIVEN " COLOR_END);
+    }
+    if (dpom & SINGLE_SERVICE_SERVER_DRIVEN)
+    {
+        printf(CYAN_BEGIN " SINGLE_SERVICE_SERVER_DRIVEN " COLOR_END);
+    }
+    if (dpom & SINGLE_SERVICE_CLIENT_DRIVEN)
+    {
+        printf(CYAN_BEGIN " SINGLE_SERVICE_CLIENT_DRIVEN " COLOR_END);
+    }
+    printf(CYAN_BEGIN ") " COLOR_END_NL);
+}
+
+#ifdef MULTIPLE_OWNER
+static void PrintMom(const OicSecMom_t *mom)
+{
+    if (mom)
+    {
+        printf(CYAN_BEGIN "%d (" COLOR_END, mom->mode);
+
+        switch (mom->mode)
+        {
+            case OIC_MULTIPLE_OWNER_DISABLE:
+                printf(CYAN_BEGIN " OIC_MULTIPLE_OWNER_DISABLE " COLOR_END);
+                break;
+            case OIC_MULTIPLE_OWNER_ENABLE:
+                printf(CYAN_BEGIN " OIC_MULTIPLE_OWNER_ENABLE " COLOR_END);
+                break;
+            case OIC_MULTIPLE_OWNER_TIMELY_ENABLE:
+                printf(CYAN_BEGIN " OIC_MULTIPLE_OWNER_TIMELY_ENABLE " COLOR_END);
+                break;
+            default:
+                break;
+        }
+
+        printf(CYAN_BEGIN ") " COLOR_END_NL);
+    }
+    else
+    {
+        printf(CYAN_BEGIN "NULL" COLOR_END_NL);
+    }
+}
+#endif
+static void PrintCredType(OicSecCredType_t credType)
+{
+    printf(CYAN_BEGIN "%d" COLOR_END, credType);
+    switch (credType)
+    {
+        case NO_SECURITY_MODE:
+            printf(CYAN_BEGIN " (NO_SECURITY_MODE)" COLOR_END_NL);
+            break;
+        case SYMMETRIC_PAIR_WISE_KEY:
+            printf(CYAN_BEGIN " (SYMMETRIC_PAIR_WISE_KEY)" COLOR_END_NL);
+            break;
+        case SYMMETRIC_GROUP_KEY:
+            printf(CYAN_BEGIN " (SYMMETRIC_GROUP_KEY)" COLOR_END_NL);
+            break;
+        case ASYMMETRIC_KEY:
+            printf(CYAN_BEGIN " (ASYMMETRIC_KEY)" COLOR_END_NL);
+            break;
+        case SIGNED_ASYMMETRIC_KEY:
+            printf(CYAN_BEGIN " (SIGNED_ASYMMETRIC_KEY)" COLOR_END_NL);
+            break;
+        case PIN_PASSWORD:
+            printf(CYAN_BEGIN " (PIN_PASSWORD)" COLOR_END_NL);
+            break;
+        case ASYMMETRIC_ENCRYPTION_KEY:
+            printf(CYAN_BEGIN " (ASYMMETRIC_ENCRYPTION_KEY)" COLOR_END_NL);
+            break;
+        default:
+            PRINT_ERR(" (Unknown Cred type)");
+            break;
+    }
+}
+
+static void PrintCredEncodingType(OicEncodingType_t encoding)
+{
+    printf(CYAN_BEGIN "%d" COLOR_END, encoding);
+    switch (encoding)
+    {
+        case OIC_ENCODING_RAW:
+            printf(CYAN_BEGIN " (OIC_ENCODING_RAW)" COLOR_END_NL);
+            break;
+        case OIC_ENCODING_BASE64:
+            printf(CYAN_BEGIN " (OIC_ENCODING_BASE64)" COLOR_END_NL);
+            break;
+        case OIC_ENCODING_PEM:
+            printf(CYAN_BEGIN " (OIC_ENCODING_PEM)" COLOR_END_NL);
+            break;
+        case OIC_ENCODING_DER:
+            printf(CYAN_BEGIN " (OIC_ENCODING_DER)" COLOR_END_NL);
+            break;
+        default:
+            PRINT_ERR(" (Unknown Encoding type)");
+            break;
+    }
+
+}
+
+static void PrintHelp()
+{
+    PRINT_ERR("<This program requires one input>");
+    printf(YELLOW_BEGIN "./svrdbeditor <svr_db_file_path>" COLOR_END_NL);
+}
+
+static void PrintDoxm(const OicSecDoxm_t *doxm)
+{
+    printf(YELLOW_BEGIN "\n\n********************* [%-20s] *********************" COLOR_END_NL,
+           "DOXM Resource");
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_OWNED_NAME);
+    (doxm->owned ? PrintString("True (Owned)") : PrintString("False (Unowned)"));
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_OXMS_NAME);
+    PrintIntArray((int *)doxm->oxm, doxm->oxmLen);
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_OXM_SEL_NAME);
+    PrintInt((int)doxm->oxmSel);
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
+    PrintInt((int)doxm->sct);
+
+#ifdef MULTIPLE_OWNER
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_MOM_NAME);
+    PrintMom(doxm->mom);
+
+    // TODO: Print Subowner List
+#endif //MULTIPLE_OWNER
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_DEVICE_ID_NAME);
+    PrintUuid(&doxm->deviceID);
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_DEVOWNERID_NAME);
+    PrintUuid(&doxm->owner);
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_ROWNERID_NAME);
+    PrintUuid(&doxm->rownerID);
+    printf(YELLOW_BEGIN "********************* [%-20s] *********************" COLOR_END_NL,
+           "DOXM Resource");
+}
+
+static void PrintPstat(const OicSecPstat_t *pstat)
+{
+    printf(YELLOW_BEGIN "\n\n********************* [%-20s] *********************" COLOR_END_NL,
+           "PSTAT Resource");
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_ISOP_NAME);
+    (pstat->isOp ? PrintString("True") : PrintString("False"));
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_SM_NAME);
+    for (size_t i = 0; i < pstat->smLen; i++)
+    {
+        PrintDpom(pstat->sm[i]);
+    }
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_OM_NAME);
+    PrintDpom(pstat->om);
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_CM_NAME);
+    PrintDpm(pstat->cm);
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_TM_NAME);
+    PrintDpm(pstat->tm);
+
+    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_ROWNERID_NAME);
+    PrintUuid(&pstat->rownerID);
+    printf(YELLOW_BEGIN "********************* [%-20s] *********************" COLOR_END_NL,
+           "PSTAT Resource");
+}
+
+static void PrintResourceList(const OicSecRsrc_t *rsrcList)
+{
+    const OicSecRsrc_t *rsrc = NULL;
+    const OicSecRsrc_t *tempRsrc = NULL;
+    size_t rsrcCnt = 0;
+
+    LL_FOREACH_SAFE(rsrcList, rsrc, tempRsrc)
+    {
+        printf(CYAN_BEGIN "Resource #%zu:" COLOR_END_NL, rsrcCnt + 1);
+        printf(CYAN_BEGIN "%10s : %s" COLOR_END_NL, OIC_JSON_HREF_NAME, rsrc->href);
+        printf(CYAN_BEGIN "%10s : %s" COLOR_END_NL, OIC_JSON_REL_NAME, rsrc->rel);
+        printf(CYAN_BEGIN "%10s : " COLOR_END, OIC_JSON_RT_NAME);
+        PrintStringArray((const char **)rsrc->types, rsrc->typeLen);
+        printf(CYAN_BEGIN "%10s : " COLOR_END, OIC_JSON_IF_NAME);
+        PrintStringArray((const char **)rsrc->interfaces, rsrc->interfaceLen);
+        rsrcCnt++;
+    }
+}
+
+static void PrintValidity(const OicSecValidity_t *validities)
+{
+    const OicSecValidity_t *validity = NULL;
+    const OicSecValidity_t *tempValidity = NULL;
+    size_t validityCnt = 0;
+
+    LL_FOREACH_SAFE(validities, validity, tempValidity)
+    {
+        printf(CYAN_BEGIN "Validity #%zu:" COLOR_END_NL, validityCnt + 1);
+        printf(CYAN_BEGIN "%10s : %s" COLOR_END_NL, OIC_JSON_PERIOD_NAME, validity->period);
+        printf(CYAN_BEGIN "%10s : " COLOR_END, OIC_JSON_RESOURCES_NAME);
+        PrintStringArray((const char **)validity->recurrences, validity->recurrenceLen);
+        validityCnt++;
+    }
+}
+
+static void PrintPermission(uint16_t permission)
+{
+    printf(CYAN_BEGIN "%d (" COLOR_END, permission);
+
+    if (0 == permission)
+    {
+        printf(CYAN_BEGIN " NO PERMISSION" COLOR_END);
+    }
+    else
+    {
+        if (permission & PERMISSION_CREATE)
+        {
+            printf(CYAN_BEGIN " CREATE " COLOR_END);
+        }
+        if (permission & PERMISSION_READ)
+        {
+            printf(CYAN_BEGIN " READ " COLOR_END);
+        }
+        if (permission & PERMISSION_WRITE)
+        {
+            printf(CYAN_BEGIN " WRITE " COLOR_END);
+        }
+        if (permission & PERMISSION_DELETE)
+        {
+            printf(CYAN_BEGIN " DELETE " COLOR_END);
+        }
+        if (permission & PERMISSION_NOTIFY)
+        {
+            printf(CYAN_BEGIN " NOTIFY " COLOR_END);
+        }
+    }
+
+    printf(CYAN_BEGIN ") " COLOR_END_NL);
+}
+
+static size_t PrintAcl(const OicSecAcl_t *acl)
+{
+    char *strUuid = NULL;
+
+    OicSecAce_t *ace = NULL;
+    OicSecAce_t *tempAce = NULL;
+    bool isEmptyList = true;
+    size_t aceCnt = 0;
+
+    printf(YELLOW_BEGIN "\n\n********************* [%-20s] *********************" COLOR_END_NL,
+           "ACL Resource");
+
+    if (acl)
+    {
+        LL_FOREACH_SAFE(acl->aces, ace, tempAce)
+        {
+            printf(YELLOW_BEGIN "[ACE #%zu]" COLOR_END_NL, ++aceCnt);
+            printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_SUBJECTID_NAME);
+            if (memcmp(&(ace->subjectuuid), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0)
+            {
+                PrintString((char *)WILDCARD_SUBJECT_ID.id);
+            }
+            else
+            {
+                strUuid = NULL;
+                if (OC_STACK_OK != ConvertUuidToStr(&(ace->subjectuuid), &strUuid))
+                {
+                    PRINT_ERR("ConvertUuidToStr error");
+                    return aceCnt;
+                }
+                PrintString(strUuid);
+                OICFree(strUuid);
+            }
+
+#ifdef MULTIPLE_OWNER
+            if (ace->eownerID)
+            {
+                printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_EOWNERID_NAME);
+                strUuid = NULL;
+                if (OC_STACK_OK != ConvertUuidToStr(ace->eownerID, &strUuid))
+                {
+                    PRINT_ERR("ConvertUuidToStr error");
+                    return aceCnt;
+                }
+                PrintString(strUuid);
+                OICFree(strUuid);
+            }
+#endif
+
+            //permission
+            printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_PERMISSION_NAME);
+            PrintPermission(ace->permission);
+
+            //resource list
+            printf(BOLD_BEGIN "%15s : " COLOR_END_NL, OIC_JSON_RESOURCES_NAME);
+            PrintResourceList(ace->resources);
+
+            //Validity
+            PrintValidity(ace->validities);
+
+            printf(BOLD_BEGIN "------------------------------------------------------------------"
+                   COLOR_END_NL);
+            isEmptyList = false;
+        }
+
+        if (isEmptyList)
+        {
+            printf(BOLD_BEGIN "ACE is empty." COLOR_END_NL);
+            printf(BOLD_BEGIN "------------------------------------------------------------------"
+                   COLOR_END_NL);
+        }
+
+        printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_ROWNERID_NAME);
+        strUuid = NULL;
+        if (OC_STACK_OK != ConvertUuidToStr(&(acl->rownerID), &strUuid))
+        {
+            PRINT_ERR("ConvertUuidToStr error");
+            return aceCnt;
+        }
+        PrintString(strUuid);
+        OICFree(strUuid);
+    }
+    else
+    {
+        printf(BOLD_BEGIN "ACL is empty." COLOR_END_NL);
+    }
+
+    printf(YELLOW_BEGIN "********************* [%-20s] *********************" COLOR_END_NL,
+           "ACL Resource");
+
+    return aceCnt;
+}
+
+/**
+ * This API to print credential list.
+ * Also return the number of credential in credential list.
+ */
+static void PrintCredList(const OicSecCred_t *creds)
+{
+    const OicSecCred_t *cred = NULL;
+    const OicSecCred_t *tempCred = NULL;
+    bool isEmptyList = true;
+    char *strUuid = NULL;
+    printf(YELLOW_BEGIN "\n\n********************* [%-20s] *********************" COLOR_END_NL,
+           "Credential Resource");
+    LL_FOREACH_SAFE(creds, cred, tempCred)
+    {
+        printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_CREDID_NAME);
+        PrintInt(cred->credId);
+
+        printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_SUBJECTID_NAME);
+        if (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0)
+        {
+            PrintString((char *)WILDCARD_SUBJECT_ID.id);
+        }
+        else
+        {
+            strUuid = NULL;
+            if (OC_STACK_OK != ConvertUuidToStr(&(cred->subject), &strUuid))
+            {
+                PRINT_ERR("ConvertUuidToStr error");
+                return;
+            }
+            PrintString(strUuid);
+            OICFree(strUuid);
+        }
+
+#ifdef MULTIPLE_OWNER
+        if (creds->eownerID)
+        {
+            printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_EOWNERID_NAME);
+            strUuid = NULL;
+            if (OC_STACK_OK != ConvertUuidToStr(cred->eownerID, &strUuid))
+            {
+                PRINT_ERR("ConvertUuidToStr error");
+                return;
+            }
+            PrintString(strUuid);
+            OICFree(strUuid);
+        }
+#endif
+
+        printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_CREDTYPE_NAME);
+        PrintCredType(cred->credType);
+
+        switch (cred->credType)
+        {
+            case SYMMETRIC_PAIR_WISE_KEY:
+            case SYMMETRIC_GROUP_KEY:
+                printf(BOLD_BEGIN "%15s : " COLOR_END_NL, OIC_JSON_PRIVATEDATA_NAME);
+                if (cred->privateData.data)
+                {
+                    printf(CYAN_BEGIN "%s : " COLOR_END, OIC_JSON_ENCODING_NAME);
+                    PrintCredEncodingType(cred->privateData.encoding);
+
+                    printf(CYAN_BEGIN "%s : " COLOR_END, OIC_JSON_DATA_NAME);
+                    if (OIC_ENCODING_BASE64 == cred->privateData.encoding)
+                    {
+                        PrintString((char *)cred->privateData.data);
+                    }
+                    else
+                    {
+                        PrintBuffer(cred->privateData.data, cred->privateData.len);
+                    }
+                }
+                else
+                {
+                    PRINT_ERR("private data is null");
+                }
+                break;
+            case ASYMMETRIC_KEY:
+            case SIGNED_ASYMMETRIC_KEY:
+                // TODO: Print certificate and asymmetric key in readable formats
+
+                //cred usage
+                if (cred->credUsage)
+                {
+                    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_CREDUSAGE_NAME);
+                    printf(CYAN_BEGIN "%s" COLOR_END_NL, cred->credUsage);
+                }
+
+                //private data
+                if (cred->privateData.data)
+                {
+                    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_PRIVATEDATA_NAME);
+                    printf(YELLOW_BEGIN "will be updated to print private data" COLOR_END_NL);
+
+                    PrintBuffer(cred->privateData.data, cred->privateData.len);
+
+                    if (cred->credUsage &&
+                        (strcmp(cred->credUsage, PRIMARY_CERT) == 0 ||
+                         strcmp(cred->credUsage, MF_PRIMARY_CERT) == 0))
+                    {
+                        // TODO: T.B.D
+                    }
+                    else
+                    {
+                        // TODO: T.B.D
+                    }
+                }
+
+                //public data
+                if (cred->publicData.data)
+                {
+                    printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_PUBLICDATA_NAME);
+                    printf(CYAN_BEGIN "%-17s : " COLOR_END, OIC_JSON_ENCODING_NAME);
+                    PrintCredEncodingType(cred->publicData.encoding);
+
+
+                    if (cred->credUsage &&
+                        (strcmp(cred->credUsage, PRIMARY_CERT) == 0 ||
+                         strcmp(cred->credUsage, MF_PRIMARY_CERT) == 0))
+                    {
+                        char buf[2048];
+                        mbedtls_x509_crt crt;
+                        mbedtls_x509_crt *tmpCrt = NULL;
+                        PkiInfo_t inf;
+                        int i = 0;
+
+                        memset(&inf, 0x00, sizeof(PkiInfo_t));
+                        mbedtls_x509_crt_init(&crt);
+
+                        ParseDerOwnCert(&inf.crt, cred->credUsage, cred->credId);
+                        ParseCertChain(&crt, inf.crt.data, inf.crt.len);
+
+                        for (i = 0, tmpCrt = &crt; NULL != tmpCrt; i++, tmpCrt = tmpCrt->next)
+                        {
+                            printf(YELLOW_BEGIN "[Cert #%d]" COLOR_END_NL, (i + 1));
+                            mbedtls_x509_crt_info( buf, sizeof(buf) - 1, "", tmpCrt );
+                            printf(CYAN_BEGIN "%s" COLOR_END, buf);
+                        }
+                        mbedtls_x509_crt_free(&crt);
+                    }
+                    else
+                    {
+                        printf(YELLOW_BEGIN "will be updated to print public data" COLOR_END_NL);
+                    }
+                }
+
+                //optional data
+                if (cred->optionalData.data)
+                {
+                    printf(BOLD_BEGIN "%15s : " COLOR_END_NL, OIC_JSON_OPTDATA_NAME);
+
+                    //revocation status
+                    printf(CYAN_BEGIN "%-17s : %s" COLOR_END_NL, OIC_JSON_REVOCATION_STATUS_NAME,
+                           (cred->optionalData.revstat ? "True" : "False"));
+
+                    printf(CYAN_BEGIN "%-17s : " COLOR_END, OIC_JSON_ENCODING_NAME);
+                    PrintCredEncodingType(cred->optionalData.encoding);
+
+                    //CA chain
+                    if (cred->credUsage &&
+                        (strcmp(cred->credUsage, TRUST_CA) == 0 ||
+                         strcmp(cred->credUsage, MF_TRUST_CA) == 0))
+                    {
+                        char buf[2048];
+                        mbedtls_x509_crt ca;
+                        mbedtls_x509_crt *tmpCa = NULL;
+                        PkiInfo_t inf;
+                        int i = 0;
+
+                        memset(&inf, 0x00, sizeof(PkiInfo_t));
+                        mbedtls_x509_crt_init(&ca);
+
+                        ParseDerCaCert(&inf.ca, cred->credUsage, cred->credId);
+                        ParseCertChain(&ca, inf.ca.data, inf.ca.len);
+
+                        for (i = 0, tmpCa = &ca; NULL != tmpCa; i++, tmpCa = tmpCa->next)
+                        {
+                            printf(YELLOW_BEGIN "[Cert #%d]" COLOR_END_NL, (i + 1));
+                            mbedtls_x509_crt_info( buf, sizeof(buf) - 1, "", tmpCa );
+                            printf(CYAN_BEGIN "%s" COLOR_END, buf);
+                        }
+                        mbedtls_x509_crt_free(&ca);
+                    }
+                    else
+                    {
+                        // TODO: T.B.D
+                        printf(YELLOW_BEGIN "will be updated to print optional data" COLOR_END_NL);
+                    }
+                }
+                break;
+            case PIN_PASSWORD:
+                printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_PRIVATEDATA_NAME);
+                if (cred->privateData.data)
+                {
+                    printf(CYAN_BEGIN "%s : " COLOR_END, OIC_JSON_ENCODING_NAME);
+                    PrintCredEncodingType(cred->privateData.encoding);
+
+                    printf(CYAN_BEGIN "%s : " COLOR_END, OIC_JSON_DATA_NAME);
+                    printf(CYAN_BEGIN "%s" COLOR_END_NL, cred->privateData.data);
+                }
+                else
+                {
+                    PRINT_ERR("private data is null");
+                }
+                break;
+            case ASYMMETRIC_ENCRYPTION_KEY:
+                break;
+            default:
+                PRINT_ERR(" (Unknown Cred type)");
+                break;
+        }
+        printf(BOLD_BEGIN "------------------------------------------------------------------"
+               COLOR_END_NL);
+        isEmptyList = false;
+    }
+
+    if (!isEmptyList)
+    {
+        printf(BOLD_BEGIN "%15s : " COLOR_END, OIC_JSON_ROWNERID_NAME);
+        strUuid = NULL;
+        if (OC_STACK_OK != ConvertUuidToStr(&(creds->rownerID), &strUuid))
+        {
+            PRINT_ERR("ConvertUuidToStr error");
+            return;
+        }
+        PrintString(strUuid);
+        OICFree(strUuid);
+    }
+    else
+    {
+        printf(BOLD_BEGIN "Cred List is empty." COLOR_END_NL);
+    }
+
+    printf(YELLOW_BEGIN "********************* [%-20s] *********************" COLOR_END_NL,
+           "Credential Resource");
+
+    return;
+}
+
+static int InputNumber(const char *infoText)
+{
+    int inputValue = 0;
+
+    printf(BOLD_BEGIN"%s"COLOR_END, infoText);
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%d", &inputValue);
+        for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+        // '0x20<=code' is character region
+    }
+
+    return inputValue;
+}
+
+inline static char InputChar(const char *infoText)
+{
+    char inputValue = 0;
+
+    printf(BOLD_BEGIN"%s"COLOR_END, infoText);
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%c", &inputValue);
+        for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+        // '0x20<=code' is character region
+    }
+
+    return inputValue;
+}
+
+static char *InputString(const char *infoText)
+{
+    char tmpStr[SVR_DB_PATH_LENGTH] = {0};
+
+    printf(BOLD_BEGIN"%s"COLOR_END, infoText);
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%1024s", tmpStr);
+        for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+        // '0x20<=code' is character region
+    }
+
+    return OICStrdup(tmpStr);
+}
+
+static void PrintEditMenu(const char *resourceName, bool print, bool add, bool remove, bool modify)
+{
+    printf(BOLD_BEGIN "\n\nYou can perform the " COLOR_END
+           CYAN_BEGIN "cyan color opertions " COLOR_END
+           BOLD_BEGIN "for" COLOR_END
+           YELLOW_BEGIN " %s" COLOR_END_NL, resourceName);
+
+    for (int i = 0; i < SVR_EDIT_IDX_SIZE; i++)
+    {
+        gAllowedEditMenu[i] = false;
+    }
+
+    if (print)
+    {
+        gAllowedEditMenu[SVR_PRINT] = true;
+        printf(CYAN_BEGIN "\t%2d. Print all entities" COLOR_END_NL, SVR_PRINT);
+    }
+    else
+    {
+        printf("\t%2d. Print all entities\n", SVR_PRINT);
+    }
+
+    if (add)
+    {
+        gAllowedEditMenu[SVR_ADD] = true;
+        printf(CYAN_BEGIN "\t%2d. Add entity" COLOR_END_NL, SVR_ADD);
+    }
+    else
+    {
+        printf("\t%2d. Add entity\n", SVR_ADD);
+    }
+
+
+    if (remove)
+    {
+        gAllowedEditMenu[SVR_REMOVE] = true;
+        printf(CYAN_BEGIN "\t%2d. Remove entity" COLOR_END_NL, SVR_REMOVE);
+    }
+    else
+    {
+        printf("\t%2d. Remove entity\n", SVR_REMOVE);
+    }
+
+    if (modify)
+    {
+        gAllowedEditMenu[SVR_MODIFY] = true;
+        printf(CYAN_BEGIN "\t%2d. Modify entity" COLOR_END_NL, SVR_MODIFY);
+    }
+    else
+    {
+        printf("\t%2d. Modify entity\n", SVR_MODIFY);
+    }
+    printf(CYAN_BEGIN "\t%2d. Back to the main menu" COLOR_END_NL, BACK);
+}
+
+static void PrintMainMenu()
+{
+    printf(BOLD_BEGIN "\n\nYou can perform the " COLOR_END
+           CYAN_BEGIN "cyan color opertions : " COLOR_END_NL);
+
+    printf(CYAN_BEGIN "\t%2d. Print All Security Resource." COLOR_END_NL, SVR_PRINT_ALL);
+    printf(CYAN_BEGIN "\t%2d. Edit Credential Resource." COLOR_END_NL, SVR_EDIT_CRED);
+    printf(CYAN_BEGIN "\t%2d. Edit ACL Resource." COLOR_END_NL, SVR_EDIT_ACL);
+    printf(BOLD_BEGIN "\t%2d. Edit Doxm Resource. (T.B.D)" COLOR_END_NL, SVR_EDIT_DOXM);
+    printf(BOLD_BEGIN "\t%2d. Edit Pstat Resource. (T.B.D)" COLOR_END_NL, SVR_EDIT_PSTAT);
+    printf(CYAN_BEGIN "\t%2d. Exit." COLOR_END_NL, EXIT);
+}
+
+static int InputUuid(OicUuid_t *uuid)
+{
+    char strSubject[UUID_LENGTH * 2 + 4 + 1] = {0};
+    OCStackResult ocResult = OC_STACK_ERROR;
+
+    if (NULL == uuid)
+    {
+        PRINT_ERR("ConvertStrToUuid error : %d" , ocResult);
+        return -1;
+    }
+
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%37s", strSubject);
+        for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+        // '0x20<=code' is character region
+    }
+
+    if (strncmp(strSubject, (char *)WILDCARD_SUBJECT_ID.id, sizeof(OicUuid_t)) == 0)
+    {
+        memset(uuid->id, 0x00, sizeof(uuid->id));
+        memcpy(uuid->id, WILDCARD_SUBJECT_ID.id, WILDCARD_SUBJECT_ID_LEN);
+    }
+    else
+    {
+        ocResult = ConvertStrToUuid(strSubject, uuid);
+        if (OC_STACK_OK != ocResult)
+        {
+            PRINT_ERR("ConvertStrToUuid error : %d" , ocResult);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int InputResources(OicSecRsrc_t *resources)
+{
+    size_t i = 0;
+
+    if (NULL == resources)
+    {
+        PRINT_ERR("InputResources : Invalid param");
+        return -1;
+    }
+
+    memset(resources, 0x00, sizeof(OicSecRsrc_t));
+
+    resources->href = InputString("\tInput the resource URI : ");
+    if (NULL == resources->href)
+    {
+        PRINT_ERR("InputResources : InputString error");
+        return -1;
+    }
+
+    printf(BOLD_BEGIN "\tInput the number of interface for %s : " COLOR_END, resources->href);
+    resources->interfaceLen = InputNumber("");
+    if (0 == resources->interfaceLen || SVR_MAX_ENTITY < resources->interfaceLen)
+    {
+        PRINT_ERR("Invalid number");
+        return -1;
+    }
+
+    resources->interfaces = (char **)OICMalloc(sizeof(char **) * resources->interfaceLen);
+    if (NULL == resources->interfaces)
+    {
+        PRINT_ERR("InputResources : Failed to allocate memory");
+        return -1;
+    }
+
+    for (i = 0; i < resources->interfaceLen; i++)
+    {
+        printf(BOLD_BEGIN "\tInput the interface name #%zu : " COLOR_END, i + 1);
+        resources->interfaces[i] = InputString("");
+        if (NULL == resources->interfaces[i] )
+        {
+            PRINT_ERR("InputResources : InputString error");
+            return -1;
+        }
+    }
+
+
+    printf(BOLD_BEGIN "\tInput the number of resource type for %s : " COLOR_END, resources->href);
+    resources->typeLen = InputNumber("");
+    if (0 == resources->typeLen || SVR_MAX_ENTITY < resources->typeLen)
+    {
+        PRINT_ERR("Invalid number");
+        return -1;
+    }
+
+    resources->types = (char **)OICMalloc(sizeof(char **) * resources->typeLen);
+    if (NULL == resources->types)
+    {
+        PRINT_ERR("InputResources : Failed to allocate memory");
+        return -1;
+    }
+
+    for (i = 0; i < resources->typeLen; i++)
+    {
+        printf(BOLD_BEGIN "\tInput the resource type name #%zu : " COLOR_END, i + 1);
+        resources->types[i] = InputString("");
+        if (NULL == resources->types[i] )
+        {
+            PRINT_ERR("InputResources : InputString error");
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static uint16_t InputAccessPermission()
+{
+    uint16_t pmsn = PERMISSION_FULL_CONTROL;  // default full permission
+    uint16_t pmsn_msk = PERMISSION_CREATE;  // default permission mask
+    const char *ACL_PEMISN[ACL_PEMISN_CNT] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
+
+    for (int i = 0; i < ACL_PEMISN_CNT; i++)
+    {
+        char ans = 0;
+        for ( ; ; )
+        {
+            printf("\tEnter %s Permission (y/n): ", ACL_PEMISN[i]);
+            for (int ret = 0; 1 != ret; )
+            {
+                ret = scanf("%c", &ans);
+                for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+                // '0x20<=code' is character region
+            }
+            if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
+            {
+                ans &= ~0x20;  // for masking lower case, 'y/n'
+                break;
+            }
+            printf("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
+        }
+        if ('N' == ans)  // masked lower case, 'n'
+        {
+            pmsn -= pmsn_msk;
+        }
+        pmsn_msk <<= 1;
+    }
+    return pmsn;
+}
+
+static int InputAceData(OicSecAce_t *ace)
+{
+    int ret = 0;
+    size_t numOfRsrc = 0;
+
+    printf(BOLD_BEGIN"\n\nPlease input the each entity of new ACE."COLOR_END_NL);
+
+    printf(BOLD_BEGIN
+           "\tInput the Subject UUID for this access (e.g. 61646D69-6E44-6576-6963-655575696430) : "COLOR_END);
+    ret = InputUuid(&ace->subjectuuid);
+    if (0 != ret)
+    {
+        PRINT_ERR("InputAceData : InputUuid error");
+        return ret;
+    }
+
+    printf(BOLD_BEGIN "\tInput the number of resource for this access : " COLOR_END);
+    numOfRsrc = InputNumber("");
+    if (0 == numOfRsrc || SVR_MAX_ENTITY < numOfRsrc)
+    {
+        PRINT_ERR("Invalid number");
+        return -1;
+    }
+
+    for (size_t i = 0; i < numOfRsrc; i++)
+    {
+        printf(BOLD_BEGIN "Please input the resource information for resource #%zu"COLOR_END_NL, i + 1);
+        OicSecRsrc_t *rsrc = (OicSecRsrc_t *)OICCalloc(1, sizeof(OicSecRsrc_t));
+        if (NULL == rsrc)
+        {
+            PRINT_ERR("InputAceData : Failed to allocate memory");
+            return -1;
+        }
+        LL_APPEND(ace->resources, rsrc);
+
+        ret = InputResources(rsrc);
+        if (0 != ret)
+        {
+            PRINT_ERR("InputAceData : InputResources error");
+            return ret;
+        }
+    }
+
+    printf(BOLD_BEGIN"\tSelect permission for this access." COLOR_END_NL);
+    ace->permission = InputAccessPermission();
+
+#ifdef MULTIPLE_OWNER
+    // TODO: Input eowner
+#endif
+
+    // TODO: Input the validity (T.B.D)
+
+    return 0;
+}
+
+static int InputCredUsage(char **credUsage)
+{
+    char inputUsage[128] = {0};
+    int credUsageNum = 0;
+
+    if (NULL == credUsage || NULL != *credUsage)
+    {
+        PRINT_ERR("InputCredUsage error : invaild param");
+        return -1;
+    }
+
+    do
+    {
+        printf("\n\n");
+        printf("\t1. %s\n", TRUST_CA);
+        printf("\t2. %s\n", PRIMARY_CERT);
+        printf("\t3. %s\n", MF_TRUST_CA);
+        printf("\t4. %s\n", MF_PRIMARY_CERT);
+        printf("\t5. Input manually\n");
+        credUsageNum = InputNumber("\tSelect the credential usage : ");
+        switch (credUsageNum)
+        {
+            case 1:
+                *credUsage = OICStrdup(TRUST_CA);
+                break;
+            case 2:
+                *credUsage = OICStrdup(PRIMARY_CERT);
+                break;
+            case 3:
+                *credUsage = OICStrdup(MF_TRUST_CA);
+                break;
+            case 4:
+                *credUsage = OICStrdup(MF_PRIMARY_CERT);
+                break;
+            case 5:
+                printf("\tInput the credential usage : ");
+                for (int ret = 0; 1 != ret; )
+                {
+                    ret = scanf("%128s", inputUsage);
+                    for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+                    // '0x20<=code' is character region
+                }
+                *credUsage = OICStrdup(inputUsage);
+                break;
+            default:
+                PRINT_ERR("Invaild credential usage");
+                credUsageNum = 0;
+                break;
+        }
+    }
+    while (0 == credUsageNum);
+
+    if (NULL == *credUsage)
+    {
+        PRINT_ERR("OICStrdup error");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int InputCredEncodingType(const char *dataType, OicEncodingType_t *encoding)
+{
+    int credEncType = 0;
+    char infoText[512] = {0};
+
+    if (NULL == dataType || NULL == encoding)
+    {
+        PRINT_ERR("InputCredEncodingType error : invaild param");
+        return -1;
+    }
+
+    snprintf(infoText, sizeof(infoText), "\tSelect the encoding type of %s : ", dataType);
+
+    do
+    {
+        printf("\n\n");
+        printf("\t%d. %s\n", OIC_ENCODING_RAW, "OIC_ENCODING_RAW");
+        printf("\t%d. %s\n", OIC_ENCODING_BASE64, "OIC_ENCODING_BASE64");
+        printf("\t%d. %s\n", OIC_ENCODING_PEM, "OIC_ENCODING_PEM");
+        printf("\t%d. %s\n", OIC_ENCODING_DER, "OIC_ENCODING_DER");
+        credEncType = InputNumber(infoText);
+        switch ( (OicEncodingType_t)credEncType )
+        {
+            case OIC_ENCODING_RAW:
+                break;
+            case OIC_ENCODING_BASE64:
+                break;
+            case OIC_ENCODING_PEM:
+                break;
+            case OIC_ENCODING_DER:
+                break;
+            default:
+                PRINT_ERR("Invaild encoding type");
+                credEncType = 0;
+                break;
+        }
+    }
+    while (0 == credEncType);
+
+    *encoding = (OicEncodingType_t)credEncType;
+
+    return 0;
+}
+
+static int ReadDataFromFile(const char *infoTxt, uint8_t **buffer, size_t *bufferSize)
+{
+    char filePath[512] = {0};
+    char tmpBuffer[SVR_DB_PATH_LENGTH] = {0};
+    FILE *fp = NULL;
+    size_t fileSize = 0;
+
+    if (NULL == buffer || NULL != *buffer || NULL == bufferSize)
+    {
+        PRINT_ERR("ReadDataFromFile error : invaild param");
+        return -1;
+    }
+
+    printf("%s", infoTxt);
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%512s", filePath);
+        for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+        // '0x20<=code' is character region
+    }
+
+    //Get a file size
+    fp = fopen(filePath, "rb");
+    if (fp)
+    {
+        size_t bytesRead = 0;
+        do
+        {
+            bytesRead = fread(tmpBuffer, 1, 1023, fp);
+            fileSize += bytesRead;
+        }
+        while (bytesRead);
+        fclose(fp);
+        fp = NULL;
+    }
+    else
+    {
+        PRINT_ERR("Failed to open %s" , filePath);
+        PRINT_ERR("Please make sure the file path and access permission.");
+        goto error;
+    }
+
+    if (0 == fileSize)
+    {
+        PRINT_ERR("%s is empty." , filePath);
+        goto error;
+    }
+
+    fp = fopen(filePath, "rb");
+    if (fp)
+    {
+        *buffer = (uint8_t *) OICCalloc(1, fileSize);
+        if ( NULL == *buffer)
+        {
+            PRINT_ERR("Failed to allocate memory.");
+            goto error;
+        }
+
+        if ( fread(*buffer, 1, fileSize, fp) == fileSize)
+        {
+            *bufferSize = fileSize;
+        }
+        fclose(fp);
+    }
+    else
+    {
+        PRINT_ERR("Failed to open %s" , filePath);
+        PRINT_ERR("Please make sure the file path and access permission.");
+        goto error;
+    }
+
+    return 0;
+
+error:
+    if (fp)
+    {
+        fclose(fp);
+    }
+    if (*buffer)
+    {
+        OICFree(*buffer);
+    }
+    return -1;
+}
+
+static int InputCredentialData(OicSecCred_t *cred)
+{
+    uint8_t *certChain = NULL;
+    uint8_t *privateKey = NULL;
+    uint8_t *publicKey = NULL;
+    size_t certChainSize = 0;
+    size_t privateKeySize = 0;
+    size_t publicKeySize = 0;
+
+
+    printf(BOLD_BEGIN"\n\nPlease input the each entity of new credential."COLOR_END_NL);
+
+    printf("\t%3d. Symmetric pair wise key\n", SYMMETRIC_PAIR_WISE_KEY);
+    printf("\t%3d. Symmetric group key\n", SYMMETRIC_GROUP_KEY);
+    printf("\t%3d. Asymmetric key\n", ASYMMETRIC_KEY);
+    printf("\t%3d. Signed asymmetric key\n", SIGNED_ASYMMETRIC_KEY);
+    printf("\t%3d. PIN/Password\n", PIN_PASSWORD);
+    printf("\t%3d. Asymmetric encryption key\n", ASYMMETRIC_ENCRYPTION_KEY);
+    cred->credType = (OicSecCredType_t)InputNumber("\tSelect the credential type : ");
+    if (SYMMETRIC_PAIR_WISE_KEY != cred->credType &&
+        SYMMETRIC_GROUP_KEY != cred->credType &&
+        SIGNED_ASYMMETRIC_KEY != cred->credType &&
+        PIN_PASSWORD != cred->credType &&
+        ASYMMETRIC_ENCRYPTION_KEY != cred->credType)
+    {
+        PRINT_ERR("Invaild credential type");
+        goto error;
+    }
+
+    //Input the key data according to credential type
+    switch (cred->credType)
+    {
+        case SYMMETRIC_PAIR_WISE_KEY:
+            printf(YELLOW_BEGIN "Unsupported yet." COLOR_END_NL);
+            goto error;
+            // TODO: T.B.D
+            /*
+            printf(BOLD_BEGIN "\tSubject UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : " COLOR_END);
+            if (0 != InputUuid(&cred->subject))
+            {
+                PRINT_ERR("InputUuid error");
+                goto error;
+            }
+            */
+            break;
+        case SYMMETRIC_GROUP_KEY:
+            // TODO: T.B.D
+            printf(YELLOW_BEGIN "Unsupported yet." COLOR_END_NL);
+            goto error;
+            break;
+        case ASYMMETRIC_KEY:
+            // TODO: T.B.D
+            printf(YELLOW_BEGIN "Unsupported yet." COLOR_END_NL);
+            goto error;
+            break;
+        case SIGNED_ASYMMETRIC_KEY:
+            //Credential usage
+            if ( 0 != InputCredUsage(&cred->credUsage))
+            {
+                PRINT_ERR("InputCredUsage error");
+                goto error;
+            }
+
+            //Input the other data according to credential usage.
+            if ( strcmp(cred->credUsage, TRUST_CA) == 0 ||
+                 strcmp(cred->credUsage, MF_TRUST_CA) == 0)
+            {
+                //Subject
+                memcpy(cred->subject.id, gDoxmResource->deviceID.id, sizeof(gDoxmResource->deviceID.id));
+
+                //encoding type
+                if ( 0 != InputCredEncodingType("certificate chain", &cred->optionalData.encoding))
+                {
+                    PRINT_ERR("InputCredEncodingType error");
+                    goto error;
+                }
+
+                //Read chain data from file (readed data will be saved to optional data)
+                if (0 != ReadDataFromFile("\tInput the certificate chain path : ", &certChain, &certChainSize))
+                {
+                    PRINT_ERR("ReadDataFromFile error");
+                    goto error;
+                }
+
+                //optional data
+                if (cred->optionalData.encoding == OIC_ENCODING_PEM)
+                {
+                    cred->optionalData.data = (uint8_t *)OICCalloc(1, certChainSize + 1);
+                    if (NULL == cred->optionalData.data)
+                    {
+                        PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                        goto error;
+                    }
+                    cred->optionalData.len = certChainSize + 1;
+                }
+                else
+                {
+                    cred->optionalData.data = (uint8_t *)OICCalloc(1, certChainSize);
+                    if (NULL == cred->optionalData.data)
+                    {
+                        PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                        goto error;
+                    }
+                    cred->optionalData.len = certChainSize;
+                }
+                memcpy(cred->optionalData.data, certChain, certChainSize);
+                cred->optionalData.revstat = false;
+            }
+            else if ( strcmp(cred->credUsage, PRIMARY_CERT) == 0 ||
+                      strcmp(cred->credUsage, MF_PRIMARY_CERT) == 0)
+            {
+                memcpy(cred->subject.id, gDoxmResource->deviceID.id, sizeof(gDoxmResource->deviceID.id));
+
+                //private key
+                //encoding type
+                if ( 0 != InputCredEncodingType(YELLOW_BEGIN"Private key"COLOR_END, &cred->privateData.encoding))
+                {
+                    PRINT_ERR("InputCredEncodingType error");
+                    goto error;
+                }
+
+                if (OIC_ENCODING_RAW != cred->privateData.encoding)
+                {
+                    PRINT_ERR("Unsupported encoding type for private key");
+                    goto error;
+                }
+
+                //Read private key data from file
+                if (0 != ReadDataFromFile("\tInput the private key's path : ", &privateKey, &privateKeySize))
+                {
+                    PRINT_ERR("ReadDataFromFile error");
+                    goto error;
+                }
+
+                cred->privateData.data = OICCalloc(1, privateKeySize);
+                if (NULL == cred->privateData.data)
+                {
+                    PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                    goto error;
+                }
+                memcpy(cred->privateData.data, privateKey, privateKeySize);
+                cred->privateData.len = privateKeySize;
+
+
+                //public key
+                //encoding type
+                if ( 0 != InputCredEncodingType(YELLOW_BEGIN"Certificate"COLOR_END, &cred->publicData.encoding))
+                {
+                    PRINT_ERR("InputCredEncodingType error");
+                    goto error;
+                }
+
+                if (OIC_ENCODING_DER != cred->publicData.encoding &&
+                    OIC_ENCODING_PEM != cred->publicData.encoding)
+                {
+                    PRINT_ERR("Unsupported encoding type for private key");
+                    goto error;
+                }
+
+                //Read certificate data from file
+                if (0 != ReadDataFromFile("\tInput the certificate's path : ", &publicKey, &publicKeySize))
+                {
+                    PRINT_ERR("ReadDataFromFile error");
+                    goto error;
+                }
+
+                if (cred->optionalData.encoding == OIC_ENCODING_PEM)
+                {
+                    cred->publicData.data = OICCalloc(1, publicKeySize + 1);
+                    if (NULL == cred->publicData.data)
+                    {
+                        PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                        goto error;
+                    }
+                    cred->publicData.len = publicKeySize + 1;
+                }
+                else
+                {
+                    cred->publicData.data = OICCalloc(1, publicKeySize);
+                    if (NULL == cred->publicData.data)
+                    {
+                        PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                        goto error;
+                    }
+                    cred->publicData.len = publicKeySize;
+                }
+                memcpy(cred->publicData.data, publicKey, publicKeySize);
+            }
+            else
+            {
+                // TODO: T.B.D : Data type should be selected by user.
+                PRINT_ERR("Not supported yet.");
+                goto error;
+            }
+            break;
+        case PIN_PASSWORD:
+            {
+                char pinPass[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
+
+                printf("\tSubject UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+                if (0 != InputUuid(&cred->subject))
+                {
+                    PRINT_ERR("InputUuid error");
+                    goto error;
+                }
+
+                printf("\tInput the PIN or Password : ");
+                for (int ret = 0; 1 != ret; )
+                {
+                    ret = scanf("%32s", pinPass);
+                    for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+                    // '0x20<=code' is character region
+                }
+                cred->privateData.data = (uint8_t *)OICStrdup(pinPass);
+                if (NULL == cred->privateData.data)
+                {
+                    PRINT_ERR("OICStrdup error");
+                    goto error;
+                }
+                cred->privateData.len = strlen((char *)cred->privateData.data);
+                cred->privateData.encoding = OIC_ENCODING_RAW;
+                break;
+            }
+        case ASYMMETRIC_ENCRYPTION_KEY:
+            // TODO: T.B.D
+            printf(YELLOW_BEGIN "Unsupported yet." COLOR_END_NL);
+            goto error;
+            break;
+        default:
+            PRINT_ERR("Invalid credential type");
+            goto error;
+    }
+
+    OICFree(certChain);
+    OICFree(privateKey);
+    OICFree(publicKey);
+    return 0;
+
+error:
+    OICFree(certChain);
+    OICFree(privateKey);
+    OICFree(publicKey);
+    memset(cred, 0x00, sizeof(OicSecCred_t));
+    return -1;
+}
+
+// TODO: Update to use credresource.c
+static int ParseCertChain(mbedtls_x509_crt *crt, unsigned char *buf, size_t bufLen)
+{
+    if (NULL == crt || NULL == buf || 0 == bufLen)
+    {
+        PRINT_ERR("ParseCertChain : Invalid param");
+        return -1;
+    }
+
+    /* byte encoded ASCII string '-----BEGIN CERTIFICATE-----' */
+    char pemCertHeader[] =
+    {
+        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+        0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+    };
+    // byte encoded ASCII string '-----END CERTIFICATE-----' */
+    char pemCertFooter[] =
+    {
+        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+        0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+    };
+    size_t pemCertHeaderLen = sizeof(pemCertHeader);
+    size_t pemCertFooterLen = sizeof(pemCertFooter);
+
+    size_t len = 0;
+    unsigned char *tmp = NULL;
+    int count = 0;
+    int ret = 0;
+    size_t pos = 0;
+
+    while (pos < bufLen)
+    {
+        if (buf[pos] == 0x30 && buf[pos + 1] == 0x82)
+        {
+            tmp = (unsigned char *)buf + pos + 1;
+            ret = mbedtls_asn1_get_len(&tmp, buf + bufLen, &len);
+            if (0 != ret)
+            {
+                PRINT_ERR("mbedtls_asn1_get_len error : %d" , ret);
+                return -1;
+            }
+
+            if (pos + len < bufLen)
+            {
+                ret = mbedtls_x509_crt_parse_der(crt, buf + pos, len + 4);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    PRINT_ERR("mbedtls_x509_crt_parse_der error : 0x%04x" , ret);
+                }
+            }
+            pos += len + 4;
+        }
+        else if ((buf + pos + pemCertHeaderLen < buf + bufLen) &&
+                 0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen))
+        {
+            void *endPos = NULL;
+            endPos = memmem(&(buf[pos]), bufLen - pos, pemCertFooter, pemCertFooterLen);
+            if (NULL == endPos)
+            {
+                PRINT_ERR("end of PEM certificate not found.");
+                return -1;
+            }
+
+            len = (char *)endPos - ((char *)buf + pos) + pemCertFooterLen;
+            if (pos + len + 1 <= bufLen)
+            {
+                char con = buf[pos + len];
+                buf[pos + len] = 0x00;
+                ret = mbedtls_x509_crt_parse(crt, buf + pos, len + 1);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    PRINT_ERR("mbedtls_x509_crt_parse returned : 0x%04x" , ret);
+                }
+                buf[pos + len] = con;
+            }
+            else
+            {
+                unsigned char *lastCert = (unsigned char *)OICMalloc((len + 1) * sizeof(unsigned char));
+                if (NULL == lastCert)
+                {
+                    PRINT_ERR("Failed to allocate memory for certificate");
+                    return -1;
+                }
+                memcpy(lastCert, buf + pos, len);
+                lastCert[len] = 0x00;
+                ret = mbedtls_x509_crt_parse(crt, lastCert, len + 1);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    PRINT_ERR("mbedtls_x509_crt_parse error : 0x%04x" , ret);
+                }
+                OICFree(lastCert);
+            }
+            pos += len;
+        }
+        else
+        {
+            pos++;
+        }
+    }
+
+    return 0;
+}
+
+// TODO: Update to use credresource.c
+static void ParseDerCaCert(ByteArray_t *crt, const char *usage, uint16_t credId)
+{
+    if (NULL == crt || NULL == usage)
+    {
+        PRINT_ERR("ParseDerCaCert : Invalid param");
+        return;
+    }
+    crt->len = 0;
+    OicSecCred_t *temp = NULL;
+
+    LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
+    {
+        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            0 == strcmp(temp->credUsage, usage) &&
+            temp->credId == credId)
+        {
+            if (OIC_ENCODING_BASE64 == temp->optionalData.encoding)
+            {
+                size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
+                uint8_t *buf = OICCalloc(1, bufSize);
+                if (NULL == buf)
+                {
+                    PRINT_ERR("ParseDerCaCert : Failed to allocate memory");
+                    return;
+                }
+                size_t outSize;
+                if (B64_OK != b64Decode((char *)(temp->optionalData.data), temp->optionalData.len, buf, bufSize,
+                                        &outSize))
+                {
+                    OICFree(buf);
+                    PRINT_ERR("ParseDerCaCert : Failed to decode base64 data");
+                    return;
+                }
+                crt->data = OICRealloc(crt->data, crt->len + outSize);
+                memcpy(crt->data + crt->len, buf, outSize);
+                crt->len += outSize;
+                OICFree(buf);
+            }
+            else
+            {
+                crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
+                memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
+                crt->len += temp->optionalData.len;
+            }
+        }
+    }
+    if (0 == crt->len)
+    {
+        printf(YELLOW_BEGIN "ParseDerCaCert : %s not found" COLOR_END_NL, usage);
+    }
+    return;
+}
+
+// TODO: Update to use credresource.c
+static void ParseDerOwnCert(ByteArray_t *crt, const char *usage, uint16_t credId)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (NULL == crt || NULL == usage)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return;
+    }
+    crt->len = 0;
+    OicSecCred_t *temp = NULL;
+    LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
+    {
+        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            0 == strcmp(temp->credUsage, usage) &&
+            temp->credId == credId)
+        {
+            crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
+            memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
+            crt->len += temp->publicData.len;
+            OIC_LOG_V(DEBUG, TAG, "%s found", usage);
+        }
+    }
+    if (0 == crt->len)
+    {
+        OIC_LOG_V(WARNING, TAG, "%s not found", usage);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return;
+}
+
+inline static void ParseDerKey(ByteArray_t *key, const char *usage, uint16_t credId)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (NULL == key || NULL == usage)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return;
+    }
+
+    OicSecCred_t *temp = NULL;
+    key->len = 0;
+    LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
+    {
+        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            0 == strcmp(temp->credUsage, usage) &&
+            temp->credId == credId)
+        {
+            key->data = OICRealloc(key->data, key->len + temp->privateData.len);
+            memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
+            key->len += temp->privateData.len;
+            OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
+        }
+    }
+    if (0 == key->len)
+    {
+        OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
+
+static void HandleCredOperation(SubOperationType_t cmd)
+{
+    uint16_t credId = 0;
+    OCStackResult credResult = OC_STACK_ERROR;
+
+    if (SVR_EDIT_IDX_SIZE <= cmd)
+    {
+        PRINT_ERR("Invalid menu for credential");
+        return;
+    }
+    if (gAllowedEditMenu[cmd])
+    {
+        switch (cmd)
+        {
+            case SVR_PRINT:
+                PrintCredList(GetCredList());
+                break;
+            case SVR_ADD:
+                {
+                    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
+                    if (NULL == cred)
+                    {
+                        PRINT_ERR("Failed to allocate memory");
+                        return;
+                    }
+
+                    if (0 != InputCredentialData(cred))
+                    {
+                        PRINT_ERR("Failed to InputCredentialData");
+                        DeleteCredList(cred);
+                        return;
+                    }
+
+                    credResult = AddCredential(cred);
+                    if ( OC_STACK_OK != credResult)
+                    {
+                        PRINT_ERR("AddCredential error : %d" , credResult);
+                        DeleteCredList(cred);
+                        return;
+                    }
+
+                    break;
+                }
+            case SVR_REMOVE:
+                PrintCredList(GetCredList());
+                credId = (uint16_t)InputNumber("\tPlease input the credential ID : ");
+
+                credResult = RemoveCredentialByCredId(credId);
+                if ( OC_STACK_RESOURCE_DELETED != credResult)
+                {
+                    PRINT_ERR("RemoveCredentialByCredId error : %d" , credResult);
+                    return;
+                }
+
+                break;
+            case SVR_MODIFY:
+                printf(YELLOW_BEGIN "Unsupported yet." COLOR_END_NL);
+                // TODO: T.B.D
+                break;
+            case BACK:
+                printf(YELLOW_BEGIN "Back to the previous menu." COLOR_END_NL);
+                break;
+            default:
+                PRINT_ERR("Invalid menu for credential");
+                break;
+        }
+    }
+    else
+    {
+        PRINT_ERR("Invalid menu for credential");
+    }
+}
+
+static void HandleAclOperation(const SubOperationType_t cmd)
+{
+    OCStackResult aclResult = OC_STACK_ERROR;
+    size_t aclIdx = 0;
+    uint8_t *aclPayload = NULL;
+    size_t aclPayloadSize = 0;
+
+    if (SVR_EDIT_IDX_SIZE <= cmd)
+    {
+        PRINT_ERR("Invalid menu for ACL");
+        return;
+    }
+    if (gAllowedEditMenu[cmd])
+    {
+        switch (cmd)
+        {
+            case SVR_PRINT:
+                {
+                    PrintAcl(gAclResource);
+                    break;
+                }
+            case SVR_ADD:
+                {
+                    OicSecAce_t *ace = (OicSecAce_t *)OICCalloc(1, sizeof(OicSecAce_t));
+                    if (NULL == ace)
+                    {
+                        PRINT_ERR("Failed to allocate memory");
+                        return;
+                    }
+
+                    //Input ACE
+                    if (0 != InputAceData(ace))
+                    {
+                        PRINT_ERR("Failed to input ACE");
+                        FreeACE(ace);
+                        return;
+                    }
+
+                    //Add ACE
+                    LL_APPEND(gAclResource->aces, ace);
+
+                    aclResult = AclToCBORPayload(gAclResource, OIC_SEC_ACL_V2, &aclPayload, &aclPayloadSize);
+                    if (OC_STACK_OK != aclResult)
+                    {
+                        PRINT_ERR("AclToCBORPayload error : %d " , aclResult);
+                        return;
+                    }
+
+                    aclResult = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, aclPayload, aclPayloadSize);
+                    if (OC_STACK_OK != aclResult)
+                    {
+                        PRINT_ERR("UpdateSecureResourceInPS error : %d " , aclResult);
+                        return;
+                    }
+
+                    break;
+                }
+            case SVR_REMOVE:
+                {
+                    OicSecAce_t *ace = NULL;
+                    OicSecAce_t *tempAce = NULL;
+                    uint16_t curIdx = 0;
+
+                    size_t numOfAce = PrintAcl(gAclResource);
+                    aclIdx = (uint16_t)InputNumber("\tPlease input the number of ACE : ");
+
+                    if (0 == aclIdx || aclIdx > numOfAce)
+                    {
+                        PRINT_ERR("Wrong number of ACE.");
+                        return;
+                    }
+
+                    //Revmoe the ACE
+                    LL_FOREACH_SAFE(gAclResource->aces, ace, tempAce)
+                    {
+                        if (ace)
+                        {
+                            //If found target ACE, delete it.
+                            if (aclIdx == ++curIdx)
+                            {
+                                LL_DELETE(gAclResource->aces, ace);
+                                FreeACE(ace);
+
+                                aclResult = AclToCBORPayload(gAclResource, OIC_SEC_ACL_V2, &aclPayload, &aclPayloadSize);
+                                if (OC_STACK_OK != aclResult)
+                                {
+                                    PRINT_ERR("AclToCBORPayload error : %d " , aclResult);
+                                    return;
+                                }
+
+                                aclResult = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, aclPayload, aclPayloadSize);
+                                if (OC_STACK_OK != aclResult)
+                                {
+                                    PRINT_ERR("UpdateSecureResourceInPS error : %d " , aclResult);
+                                    return;
+                                }
+                            }
+                        }
+                    }
+                    break;
+                }
+            case SVR_MODIFY:
+                printf(YELLOW_BEGIN "Not supported yet." COLOR_END_NL);
+                // TODO: T.B.D
+                break;
+            case BACK:
+                printf(YELLOW_BEGIN "Back to the previous menu." COLOR_END_NL);
+                break;
+            default:
+                PRINT_ERR("Invalid menu for ACL");
+                break;
+        }
+    }
+    else
+    {
+        PRINT_ERR("Invalid menu for ACL");
+    }
+
+}
+
+inline static void HandleDoxmOperation(const SubOperationType_t cmd)
+{
+    (void)cmd;
+    //T.B.D
+}
+
+inline static void HandlePstatOperation(const SubOperationType_t cmd)
+{
+    (void)cmd;
+    //T.B.D
+}