Fix 64bit build error for tizen dlog print format
[platform/upstream/iotivity.git] / resource / csdk / security / src / credresource.c
index b1867a7..0bdaa5f 100644 (file)
@@ -20,6 +20,7 @@
 
 #define __STDC_LIMIT_MACROS
 
+#include "iotivity_config.h"
 #include <stdlib.h>
 #ifdef HAVE_STRING_H
 #include <string.h>
@@ -28,6 +29,7 @@
 #include <strings.h>
 #endif
 #include <stdint.h>
+#include <stdbool.h>
 
 #include "cainterface.h"
 #include "payload_logging.h"
@@ -36,7 +38,9 @@
 #include "base64.h"
 #include "ocserverrequest.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 #include "ocpayload.h"
+#include "ocpayloadcbor.h"
 #include "utlist.h"
 #include "credresource.h"
 #include "doxmresource.h"
 #include "psinterface.h"
 #include "pinoxmcommon.h"
 
-#ifdef __WITH_DTLS__
-#include "global.h"
+#ifdef __unix__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 #endif
+#define UNUSED(x) (void)(x)
 
-#define TAG  "SRM-CREDL"
+#define TAG  "OIC_SRM_CREDL"
 
+/** Max credential types number used for TLS */
+#define MAX_TYPE 2
 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
  * The value of payload size is increased until reaching belox max cbor size. */
 static const uint16_t CBOR_SIZE = 2048;
 
 /** Max cbor size payload. */
-static const uint16_t CBOR_MAX_SIZE = 4400;
+//static const uint16_t CBOR_MAX_SIZE = 4400;
 
 /** CRED size - Number of mandatory items. */
 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
 static const uint8_t CRED_MAP_SIZE = 3;
 
-
 static OicSecCred_t        *gCred = NULL;
 static OCResourceHandle    gCredHandle = NULL;
 
+#ifdef MULTIPLE_OWNER
+#define PRECONF_PIN_MIN_SIZE (8)
+#endif
+
+typedef enum CredCompareResult{
+    CRED_CMP_EQUAL = 0,
+    CRED_CMP_NOT_EQUAL = 1,
+    CRED_CMP_ERROR = 2
+}CredCompareResult_t;
+
+/**
+ * Internal function to check a subject of SIGNED_ASYMMETRIC_KEY(Certificate).
+ * If that subject is NULL or wildcard, set it to own deviceID.
+ * @param cred credential on SVR DB file
+ * @param deviceID own deviceuuid of doxm resource
+ *
+ * @return
+ *     true successfully done
+ *     false Invalid cred
+ */
+static bool CheckSubjectOfCertificate(OicSecCred_t* cred, OicUuid_t deviceID)
+{
+    UNUSED(deviceID);
+    OicUuid_t emptyUuid = {.id={0}};
+    UNUSED(emptyUuid);
+    OIC_LOG(DEBUG, TAG, "IN CheckSubjectOfCertificate");
+    VERIFY_NON_NULL(TAG, cred, ERROR);
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    if ( SIGNED_ASYMMETRIC_KEY == cred->credType)
+    {
+        if((0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(cred->subject.id))) ||
+            (0 == memcmp(cred->subject.id, &WILDCARD_SUBJECT_ID, sizeof(cred->subject.id))))
+        {
+            memcpy(cred->subject.id, deviceID.id, sizeof(deviceID.id));
+        }
+    }
+#endif
+
+    OIC_LOG(DEBUG, TAG, "OUT CheckSubjectOfCertificate");
+    return true;
+exit:
+    OIC_LOG(ERROR, TAG, "OUT CheckSubjectOfCertificate");
+    return false;
+}
+
+/**
+ * Internal function to check credential
+ */
+static bool IsValidCredential(const OicSecCred_t* cred)
+{
+    OicUuid_t emptyUuid = {.id={0}};
+
+
+    OIC_LOG(INFO, TAG, "IN IsValidCredential");
+
+    VERIFY_NON_NULL(TAG, cred, ERROR);
+    VERIFY_SUCCESS(TAG, 0 != cred->credId, ERROR);
+    OIC_LOG_V(DEBUG, TAG, "Cred ID = %d", cred->credId);
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    OIC_LOG_V(DEBUG, TAG, "Cred Type = %d", cred->credType);
+
+    switch(cred->credType)
+    {
+        case SYMMETRIC_PAIR_WISE_KEY:
+        case SYMMETRIC_GROUP_KEY:
+        case PIN_PASSWORD:
+        {
+            VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
+            VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
+            VERIFY_SUCCESS(TAG, \
+                           (OIC_ENCODING_RAW == cred->privateData.encoding || \
+                           OIC_ENCODING_BASE64 == cred->privateData.encoding), \
+                           ERROR);
+            break;
+        }
+        case ASYMMETRIC_KEY:
+        {
+            VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
+            VERIFY_SUCCESS(TAG, 0 != cred->publicData.len, ERROR);
+            VERIFY_SUCCESS(TAG, \
+                           (OIC_ENCODING_UNKNOW < cred->publicData.encoding && \
+                            OIC_ENCODING_DER >= cred->publicData.encoding),
+                           ERROR);
+            break;
+        }
+        case SIGNED_ASYMMETRIC_KEY:
+        {
+            VERIFY_SUCCESS(TAG, (NULL != cred->publicData.data ||NULL != cred->optionalData.data) , ERROR);
+            VERIFY_SUCCESS(TAG, (0 != cred->publicData.len || 0 != cred->optionalData.len), ERROR);
+
+            if(NULL != cred->optionalData.data)
+            {
+                VERIFY_SUCCESS(TAG, \
+                               (OIC_ENCODING_UNKNOW < cred->optionalData.encoding && \
+                                OIC_ENCODING_DER >= cred->optionalData.encoding),
+                               ERROR);
+            }
+            break;
+        }
+        case ASYMMETRIC_ENCRYPTION_KEY:
+        {
+            VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
+            VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
+            VERIFY_SUCCESS(TAG, \
+                           (OIC_ENCODING_UNKNOW < cred->privateData.encoding && \
+                            OIC_ENCODING_DER >= cred->privateData.encoding),
+                           ERROR);
+            break;
+        }
+        default:
+        {
+            OIC_LOG(WARNING, TAG, "Unknown credential type");
+            return false;
+        }
+    }
+#endif
+
+    VERIFY_SUCCESS(TAG, 0 != memcmp(emptyUuid.id, cred->subject.id, sizeof(cred->subject.id)), ERROR);
+
+    OIC_LOG(INFO, TAG, "OUT IsValidCredential : Credential are valid.");
+    return true;
+exit:
+    OIC_LOG(WARNING, TAG, "OUT IsValidCredential : Invalid Credential detected.");
+    return false;
+}
+
+static bool IsEmptyCred(const OicSecCred_t* cred)
+{
+    OicUuid_t emptyUuid = {.id={0}};
+
+    VERIFY_SUCCESS(TAG, (0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(emptyUuid))), ERROR);
+    VERIFY_SUCCESS(TAG, (0 == cred->credId), ERROR);
+    VERIFY_SUCCESS(TAG, (0 == cred->credType), ERROR);
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    VERIFY_SUCCESS(TAG, (NULL == cred->privateData.data), ERROR);
+    VERIFY_SUCCESS(TAG, (NULL == cred->publicData.data), ERROR);
+    VERIFY_SUCCESS(TAG, (NULL == cred->optionalData.data), ERROR);
+    VERIFY_SUCCESS(TAG, (NULL == cred->credUsage), ERROR);
+#endif
+    return true;
+exit:
+    return false;
+}
+
 /**
  * This function frees OicSecCred_t object's fields and object itself.
  */
@@ -87,20 +242,26 @@ static void FreeCred(OicSecCred_t *cred)
 #endif
 
     //Clean PublicData/OptionalData/Credusage
-#if defined(__WITH_X509__) || defined(__WITH_TLS__)
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
      // TODO: Need to check credUsage.
     OICFree(cred->publicData.data);
     OICFree(cred->optionalData.data);
     OICFree(cred->credUsage);
 
-#endif /* __WITH_X509__ ||  __WITH_TLS__*/
+#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
 
     //Clean PrivateData
+    OICClearMemory(cred->privateData.data, cred->privateData.len);
     OICFree(cred->privateData.data);
 
     //Clean Period
     OICFree(cred->period);
 
+#ifdef MULTIPLE_OWNER
+    //Clean eowner
+    OICFree(cred->eownerID);
+#endif
+
     //Clean Cred node itself
     OICFree(cred);
 }
@@ -118,6 +279,34 @@ void DeleteCredList(OicSecCred_t* cred)
     }
 }
 
+size_t GetCredKeyDataSize(const OicSecCred_t* cred)
+{
+    size_t size = 0;
+    if (cred)
+    {
+        OicSecCred_t *credPtr = NULL, *credTmp = NULL;
+        LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
+        {
+            if (credPtr->privateData.data && 0 < credPtr->privateData.len)
+            {
+                size += credPtr->privateData.len;
+            }
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+            if (credPtr->publicData.data && 0 < credPtr->publicData.len)
+            {
+                size += credPtr->publicData.len;
+            }
+            if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
+            {
+                size += credPtr->optionalData.len;
+            }
+#endif
+        }
+    }
+    OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %zd\n", size);
+    return size;
+}
+
 static size_t OicSecCredCount(const OicSecCred_t *secCred)
 {
     size_t size = 0;
@@ -128,6 +317,261 @@ static size_t OicSecCredCount(const OicSecCred_t *secCred)
     return size;
 }
 
+static char* EncodingValueToString(OicEncodingType_t encoding)
+{
+    char* str = NULL;
+    switch (encoding)
+    {
+        case OIC_ENCODING_RAW:
+            str = (char*)OIC_SEC_ENCODING_RAW;
+            break;
+        case OIC_ENCODING_BASE64:
+            str = (char*)OIC_SEC_ENCODING_BASE64;
+            break;
+        case OIC_ENCODING_DER:
+            str = (char*)OIC_SEC_ENCODING_DER;
+            break;
+        case OIC_ENCODING_PEM:
+            str = (char*)OIC_SEC_ENCODING_PEM;
+            break;
+        default:
+            break;
+    }
+    return str;
+}
+
+static CborError SerializeEncodingToCborInternal(CborEncoder *map, const OicSecKey_t *value)
+{
+    CborError cborEncoderResult = CborNoError;
+    char *encoding = EncodingValueToString(value->encoding);
+    if (encoding)
+    {
+        cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_ENCODING_NAME,
+            strlen(OIC_JSON_ENCODING_NAME));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Tag.");
+        cborEncoderResult = cbor_encode_text_string(map, encoding,
+            strlen(encoding));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Value.");
+
+        cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_DATA_NAME,
+            strlen(OIC_JSON_DATA_NAME));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Tag.");
+        if (OIC_ENCODING_DER == value->encoding ||
+            OIC_ENCODING_RAW == value->encoding)
+        {
+            cborEncoderResult = cbor_encode_byte_string(map,
+                    value->data, value->len);
+        }
+        else
+        {
+            cborEncoderResult = cbor_encode_text_string(map,
+                    (char*)value->data, value->len);
+        }
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Value.");
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "Unknown encoding type.");
+        VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Encoding Value.");
+    }
+    exit:
+    return cborEncoderResult;
+}
+
+static CborError SerializeEncodingToCbor(CborEncoder *rootMap, const char* tag, const OicSecKey_t *value)
+{
+    CborError cborEncoderResult = CborNoError;
+    CborEncoder map;
+    const size_t mapSize = 2;
+
+    cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
+
+    cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
+
+    VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, value),
+                        "Failed adding OicSecKey_t structure");
+
+    cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
+
+    exit:
+    return cborEncoderResult;
+}
+
+static CborError SerializeSecOptToCbor(CborEncoder *rootMap, const char* tag, const OicSecOpt_t *value)
+{
+    CborError cborEncoderResult = CborNoError;
+    CborEncoder map;
+    const size_t mapSize = 3;
+
+    cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
+
+    cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
+
+    OicSecKey_t in;
+    in.data = value->data;
+    in.encoding = value->encoding;
+    in.len = value->len;
+
+    VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, &in),
+                        "Failed adding OicSecKey_t structure");
+
+    cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_REVOCATION_STATUS_NAME,
+        strlen(OIC_JSON_REVOCATION_STATUS_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Tag.");
+    cborEncoderResult = cbor_encode_boolean(&map, value->revstat);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Value.");
+
+    cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
+
+    exit:
+    return cborEncoderResult;
+}
+
+static CborError DeserializeEncodingFromCborInternal(CborValue *map, char *name, OicSecKey_t *value)
+{
+    size_t len = 0;
+    CborError cborFindResult = CborNoError;
+
+    // data -- Mandatory
+    if (strcmp(name, OIC_JSON_DATA_NAME) == 0)
+    {
+        if(cbor_value_is_byte_string(map))
+        {
+            cborFindResult = cbor_value_dup_byte_string(map, &value->data,
+                &value->len, NULL);
+        }
+        else if(cbor_value_is_text_string(map))
+        {
+            cborFindResult = cbor_value_dup_text_string(map, (char**)(&value->data),
+                &value->len, NULL);
+        }
+        else
+        {
+            cborFindResult = CborErrorUnknownType;
+            OIC_LOG(ERROR, TAG, "Unknown type for private data.");
+        }
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
+    }
+
+    // encoding -- Mandatory
+    if (strcmp(name, OIC_JSON_ENCODING_NAME) == 0)
+    {
+        char* strEncoding = NULL;
+        cborFindResult = cbor_value_dup_text_string(map, &strEncoding, &len, NULL);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
+
+        if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
+        {
+            value->encoding = OIC_ENCODING_RAW;
+        }
+        else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
+        {
+            value->encoding = OIC_ENCODING_BASE64;
+        }
+        else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
+        {
+            value->encoding = OIC_ENCODING_DER;
+        }
+        else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
+        {
+            value->encoding = OIC_ENCODING_PEM;
+        }
+        else
+        {
+            //For unit test
+            value->encoding = OIC_ENCODING_RAW;
+            OIC_LOG(WARNING, TAG, "Unknown encoding type detected.");
+        }
+        OICFree(strEncoding);
+    }
+    exit:
+    return cborFindResult;
+}
+
+static CborError DeserializeEncodingFromCbor(CborValue *rootMap, OicSecKey_t *value)
+{
+    CborValue map = { .parser = NULL };
+    CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
+    size_t len = 0;
+
+    while (cbor_value_is_valid(&map))
+    {
+        char* name = NULL;
+        CborType type = cbor_value_get_type(&map);
+        if (type == CborTextStringType && cbor_value_is_text_string(&map))
+        {
+            cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+            cborFindResult = cbor_value_advance(&map);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+        }
+        if (name)
+        {
+            VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, value),
+                                "Failed to read OicSecKey_t value");
+        }
+        if (cbor_value_is_valid(&map))
+        {
+            cborFindResult = cbor_value_advance(&map);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
+        }
+        OICFree(name);
+    }
+    exit:
+    return cborFindResult;
+}
+
+static CborError DeserializeSecOptFromCbor(CborValue *rootMap, OicSecOpt_t *value)
+{
+    CborValue map = { .parser = NULL };
+    CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
+    size_t len = 0;
+    value->revstat = false;
+
+    while (cbor_value_is_valid(&map))
+    {
+        char* name = NULL;
+        CborType type = cbor_value_get_type(&map);
+        if (type == CborTextStringType && cbor_value_is_text_string(&map))
+        {
+            cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+            cborFindResult = cbor_value_advance(&map);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+        }
+        if (name)
+        {
+            // OptionalData::revstat -- Mandatory
+            if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
+            {
+                cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding revstat Value.")
+            }
+            OicSecKey_t out;
+            VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, &out),
+                                "Failed to read OicSecKey_t value");
+
+            value->data = out.data;
+            value->encoding = out.encoding;
+            value->len = out.len;
+        }
+        if (cbor_value_is_valid(&map))
+        {
+            cborFindResult = cbor_value_advance(&map);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
+        }
+        OICFree(name);
+    }
+    exit:
+    return cborFindResult;
+}
+
 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
                                 size_t *cborSize, int secureFlag)
 {
@@ -179,7 +623,15 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         {
             mapSize++;
         }
-#if defined(__WITH_X509__) || defined(__WITH_TLS__)
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#ifdef MULTIPLE_OWNER
+        if(cred->eownerID)
+        {
+            mapSize++;
+        }
+#endif //MULTIPLE_OWNER
+
         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
         {
             mapSize++;
@@ -192,7 +644,7 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         {
             mapSize++;
         }
-#endif /* __WITH_X509__ ||  __WITH_TLS__*/
+#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
         if (!secureFlag && cred->privateData.data)
         {
             mapSize++;
@@ -211,7 +663,7 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
             strlen(OIC_JSON_SUBJECTID_NAME));
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
-        inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN) == 0) ?
+        inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
             WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
         if(inLen == WILDCARD_SUBJECT_ID_LEN)
         {
@@ -236,124 +688,20 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
 
-#if defined(__WITH_X509__) || defined(__WITH_TLS__)
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
         //PublicData -- Not Mandatory
         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
         {
-            CborEncoder publicMap;
-            const size_t publicMapSize = 2;
-
-            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
-                strlen(OIC_JSON_PUBLICDATA_NAME));
+            cborEncoderResult = SerializeEncodingToCbor(&credMap,
+                                         OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
-
-            cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
-
-            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
-                strlen(OIC_JSON_DATA_NAME));
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
-            cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
-                cred->publicData.len);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
-
-            // TODO: Need to data strucure modification for OicSecCert_t.
-            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
-                strlen(OIC_JSON_ENCODING_NAME));
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
-            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
-                strlen(OIC_SEC_ENCODING_RAW));
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
-
-            cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
         }
         //OptionalData -- Not Mandatory
         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
         {
-            CborEncoder optionalMap;
-            const size_t optionalMapSize = 2;
-
-            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_OPTDATA_NAME,
-                strlen(OIC_JSON_OPTDATA_NAME));
+            cborEncoderResult = SerializeSecOptToCbor(&credMap,
+                                         OIC_JSON_OPTDATA_NAME, &cred->optionalData);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
-
-            cborEncoderResult = cbor_encoder_create_map(&credMap, &optionalMap, optionalMapSize);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Map");
-
-            // TODO: Need to data strucure modification for OicSecCert_t.
-            if(OIC_ENCODING_RAW == cred->optionalData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_RAW,
-                    strlen(OIC_SEC_ENCODING_RAW));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
-                cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
-                    cred->optionalData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
-            }
-            else if(OIC_ENCODING_BASE64 == cred->optionalData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_BASE64,
-                    strlen(OIC_SEC_ENCODING_BASE64));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
-                    cred->optionalData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
-            }
-            else if(OIC_ENCODING_PEM == cred->optionalData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_PEM,
-                    strlen(OIC_SEC_ENCODING_PEM));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
-                    cred->optionalData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
-            }
-            else if(OIC_ENCODING_DER == cred->optionalData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_DER,
-                    strlen(OIC_SEC_ENCODING_DER));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
-                cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
-                    cred->optionalData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
-            }
-            else
-            {
-                OIC_LOG(ERROR, TAG, "Unknow encoding type for optional data.");
-                VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding optional Encoding Value.");
-            }
-
-            cborEncoderResult = cbor_encoder_close_container(&credMap, &optionalMap);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing OptionalData Map.");
         }
         //CredUsage -- Not Mandatory
         if(cred->credUsage)
@@ -365,62 +713,13 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
                 strlen(cred->credUsage));
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
         }
-#endif /* __WITH_X509__ ||  __WITH_TLS__*/
+#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
         //PrivateData -- Not Mandatory
         if(!secureFlag && cred->privateData.data)
         {
-            CborEncoder privateMap;
-            const size_t privateMapSize = 2;
-
-            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
-                strlen(OIC_JSON_PRIVATEDATA_NAME));
+            cborEncoderResult = SerializeEncodingToCbor(&credMap,
+                                         OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
-
-            cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
-
-            // TODO: Need to data strucure modification for OicSecKey_t.
-            // TODO: Added as workaround, will be replaced soon.
-            if(OIC_ENCODING_RAW == cred->privateData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
-                    strlen(OIC_SEC_ENCODING_RAW));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
-                cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
-                    cred->privateData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
-            }
-            else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
-                    strlen(OIC_SEC_ENCODING_BASE64));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
-                cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
-                    cred->privateData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
-            }
-            else
-            {
-                OIC_LOG(ERROR, TAG, "Unknow encoding type for private data.");
-                VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
-            }
-
-            cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
         }
 
         //Period -- Not Mandatory
@@ -434,6 +733,21 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
         }
 
+#ifdef MULTIPLE_OWNER
+        // Eownerid -- Not Mandatory
+        if(cred->eownerID)
+        {
+            char *eowner = NULL;
+            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
+                strlen(OIC_JSON_EOWNERID_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
+            ret = ConvertUuidToStr(cred->eownerID, &eowner);
+            VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+            cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
+            OICFree(eowner);
+        }
+#endif //MULTIPLE_OWNER
 
         cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
@@ -499,7 +813,7 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
     {
         OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
         *cborPayload = outPayload;
-        *cborSize = encoder.ptr - outPayload;
+        *cborSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
         ret = OC_STACK_OK;
     }
     OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
@@ -510,7 +824,7 @@ exit:
         // reallocate and try again!
         OICFree(outPayload);
         // Since the allocated initial memory failed, double the memory.
-        cborLen += encoder.ptr - encoder.end;
+        cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
         cborEncoderResult = CborNoError;
         ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
         *cborSize = cborLen;
@@ -544,6 +858,7 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
     cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
 
     OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
+    VERIFY_NON_NULL(TAG, headCred, ERROR);
 
     // Enter CRED Root Map
     CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
@@ -589,6 +904,7 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                     else
                     {
                         cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
+                        VERIFY_NON_NULL(TAG, cred, ERROR);
                         OicSecCred_t *temp = headCred;
                         while (temp->next)
                         {
@@ -597,8 +913,6 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                         temp->next = cred;
                     }
 
-                    VERIFY_NON_NULL(TAG, cred, ERROR);
-
                     while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
                     {
                         char* name = NULL;
@@ -640,210 +954,42 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                             // credtype
                             if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
                             {
+#ifdef __TIZENRT__
+                                cborFindResult = cbor_value_get_int(&credMap, (int *) &cred->credType);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
+#else
                                 uint64_t credType = 0;
                                 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
                                 cred->credType = (OicSecCredType_t)credType;
+#endif
                             }
                             // privatedata
                             if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME)  == 0)
                             {
-                                CborValue privateMap = { .parser = NULL };
-                                cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
+                                cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->privateData);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read privateData structure");
 
-                                while (cbor_value_is_valid(&privateMap))
+                                OicEncodingType_t encoding = cred->privateData.encoding;
+                                if (OIC_ENCODING_DER == encoding || OIC_ENCODING_PEM == encoding)
                                 {
-                                    char* privname = NULL;
-                                    CborType type = cbor_value_get_type(&privateMap);
-                                    if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
-                                    {
-                                        cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
-                                                &len, NULL);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
-                                        cborFindResult = cbor_value_advance(&privateMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
-                                    }
-                                    if (privname)
-                                    {
-                                        // PrivateData::privdata -- Mandatory
-                                        if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
-                                        {
-                                            if(cbor_value_is_byte_string(&privateMap))
-                                            {
-                                                cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
-                                                    &cred->privateData.len, NULL);
-                                            }
-                                            else if(cbor_value_is_text_string(&privateMap))
-                                            {
-                                                cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
-                                                    &cred->privateData.len, NULL);
-                                            }
-                                            else
-                                            {
-                                                cborFindResult = CborErrorUnknownType;
-                                                OIC_LOG(ERROR, TAG, "Unknow type for private data.");
-                                            }
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
-                                        }
-
-                                        // PrivateData::encoding -- Mandatory
-                                        if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
-                                        {
-                                            // TODO: Added as workaround. Will be replaced soon.
-                                            char* strEncoding = NULL;
-                                            cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
-
-                                            if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
-                                            {
-                                                cred->privateData.encoding = OIC_ENCODING_RAW;
-                                            }
-                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
-                                            {
-                                                cred->privateData.encoding = OIC_ENCODING_BASE64;
-                                            }
-                                            else
-                                            {
-                                                //For unit test
-                                                cred->privateData.encoding = OIC_ENCODING_RAW;
-                                                OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data.");
-                                            }
-
-                                            OICFree(strEncoding);
-                                        }
-                                    }
-                                    if (cbor_value_is_valid(&privateMap))
-                                    {
-                                        cborFindResult = cbor_value_advance(&privateMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
-                                    }
-                                    OICFree(privname);
+                                    //For unit test
+                                    cred->privateData.encoding = OIC_ENCODING_RAW;
+                                    OIC_LOG(WARNING, TAG, "Unknown encoding type detected for private data.");
                                 }
-
                             }
-#if defined(__WITH_X509__) || defined(__WITH_TLS__)
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
                             //PublicData -- Not Mandatory
                             if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
                             {
-                                CborValue pubMap = { .parser = NULL };
-                                cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
-
-                                while (cbor_value_is_valid(&pubMap))
-                                {
-                                    char* pubname = NULL;
-                                    CborType type = cbor_value_get_type(&pubMap);
-                                    if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
-                                    {
-                                        cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
-                                                &len, NULL);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
-                                        cborFindResult = cbor_value_advance(&pubMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
-                                    }
-                                    if (pubname)
-                                    {
-                                        // PrivateData::privdata -- Mandatory
-                                        if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
-                                        {
-                                            cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
-                                                &cred->publicData.len, NULL);
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
-                                        }
-                                        // PublicData::encoding -- Mandatory
-                                        if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
-                                        {
-                                            // TODO: Need to update data structure, just ignore encoding value now.
-                                        }
-                                    }
-                                    if (cbor_value_is_valid(&pubMap))
-                                    {
-                                        cborFindResult = cbor_value_advance(&pubMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
-                                    }
-                                    OICFree(pubname);
-                                }
+                                cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->publicData);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read publicData structure");
                             }
                             //OptionalData -- Not Mandatory
                             if (strcmp(name, OIC_JSON_OPTDATA_NAME)  == 0)
                             {
-                                CborValue optMap = { .parser = NULL };
-                                cborFindResult = cbor_value_enter_container(&credMap, &optMap);
-
-                                while (cbor_value_is_valid(&optMap))
-                                {
-                                    char* optname = NULL;
-                                    CborType type = cbor_value_get_type(&optMap);
-                                    if (type == CborTextStringType && cbor_value_is_text_string(&optMap))
-                                    {
-                                        cborFindResult = cbor_value_dup_text_string(&optMap, &optname,
-                                                &len, NULL);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
-                                        cborFindResult = cbor_value_advance(&optMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
-                                    }
-                                    if (optname)
-                                    {
-                                        // OptionalData::optdata -- Mandatory
-                                        if (strcmp(optname, OIC_JSON_DATA_NAME) == 0)
-                                        {
-                                            if(cbor_value_is_byte_string(&optMap))
-                                            {
-                                                cborFindResult = cbor_value_dup_byte_string(&optMap, &cred->optionalData.data,
-                                                    &cred->optionalData.len, NULL);
-                                            }
-                                            else if(cbor_value_is_text_string(&optMap))
-                                            {
-                                                cborFindResult = cbor_value_dup_text_string(&optMap, (char**)(&cred->optionalData.data),
-                                                    &cred->optionalData.len, NULL);
-                                            }
-                                            else
-                                            {
-                                                cborFindResult = CborErrorUnknownType;
-                                                OIC_LOG(ERROR, TAG, "Unknow type for optional data.");
-                                            }
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OptionalData.");
-                                        }
-                                        // OptionalData::encoding -- Mandatory
-                                        if (strcmp(optname, OIC_JSON_ENCODING_NAME) == 0)
-                                        {
-                                            // TODO: Added as workaround. Will be replaced soon.
-                                            char* strEncoding = NULL;
-                                            cborFindResult = cbor_value_dup_text_string(&optMap, &strEncoding, &len, NULL);
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
-
-                                            if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
-                                            {
-                                                OIC_LOG(INFO,TAG,"cbor_value_is_byte_string");
-                                                cred->optionalData.encoding = OIC_ENCODING_RAW;
-                                            }
-                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
-                                            {
-                                                cred->optionalData.encoding = OIC_ENCODING_BASE64;
-                                            }
-                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
-                                            {
-                                                cred->optionalData.encoding = OIC_ENCODING_PEM;
-                                            }
-                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
-                                            {
-                                                cred->optionalData.encoding = OIC_ENCODING_DER;
-                                            }
-                                            else
-                                            {
-                                                //For unit test
-                                                cred->optionalData.encoding = OIC_ENCODING_RAW;
-                                                OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for optional data.");
-                                            }
-                                            OICFree(strEncoding);
-                                        }
-                                    }
-                                    if (cbor_value_is_valid(&optMap))
-                                    {
-                                        cborFindResult = cbor_value_advance(&optMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing optdata Map.");
-                                    }
-                                    OICFree(optname);
-                                }
+                                cborFindResult = DeserializeSecOptFromCbor(&credMap, &cred->optionalData);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read optionalData structure");
                             }
                             //Credusage -- Not Mandatory
                             if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
@@ -851,7 +997,7 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
                             }
-#endif  //__WITH_X509__ ||  __WITH_TLS__
+#endif  //__WITH_DTLS__ ||  __WITH_TLS__
 
                             if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
                             {
@@ -859,6 +1005,24 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
                             }
 
+#ifdef MULTIPLE_OWNER
+                            // Eowner uuid -- Not Mandatory
+                            if (strcmp(OIC_JSON_EOWNERID_NAME, name)  == 0 && cbor_value_is_text_string(&credMap))
+                            {
+                                char *eowner = NULL;
+                                cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &len, NULL);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
+                                if(NULL == cred->eownerID)
+                                {
+                                    cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
+                                    VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
+                                }
+                                ret = ConvertStrToUuid(eowner, cred->eownerID);
+                                OICFree(eowner);
+                                VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+                            }
+#endif //MULTIPLE_OWNER
+
                             if (cbor_value_is_valid(&credMap))
                             {
                                 cborFindResult = cbor_value_advance(&credMap);
@@ -887,6 +1051,10 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
                 OICFree(stRowner);
             }
+            else if (NULL != gCred)
+            {
+                memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
+            }
             OICFree(tagName);
         }
         if (cbor_value_is_valid(&CredRootMap))
@@ -911,10 +1079,38 @@ exit:
     return ret;
 }
 
+#ifdef MULTIPLE_OWNER
+bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
+{
+    OicSecCred_t* cred = NULL;
+    bool isValidCred = false;
+
+    OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
+
+    VERIFY_NON_NULL(TAG, uuid, ERROR);
+    VERIFY_NON_NULL(TAG, cborPayload, ERROR);
+    VERIFY_SUCCESS(TAG, 0 != size, ERROR);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToCred(cborPayload, size, &cred), ERROR);
+    VERIFY_NON_NULL(TAG, cred, ERROR);
+    VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
+    VERIFY_SUCCESS(TAG, (memcmp(cred->eownerID->id, uuid->id, sizeof(uuid->id)) == 0), ERROR);
+
+    isValidCred = true;
+
+exit:
+    DeleteCredList(cred);
+
+    return isValidCred;
+
+}
+#endif //MULTIPLE_OWNER
+
 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
-                                  const OicSecCert_t * publicData, const OicSecKey_t* privateData,
-                                  const OicUuid_t * rownerID)
+                                  const OicSecKey_t * publicData, const OicSecKey_t* privateData,
+                                  const OicUuid_t * rownerID, const OicUuid_t * eownerID)
 {
+    OIC_LOG(DEBUG, TAG, "IN GenerateCredential");
+
     (void)publicData;
     OCStackResult ret = OC_STACK_ERROR;
 
@@ -932,7 +1128,7 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
             SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
     cred->credType = credType;
 
-#ifdef __WITH_X509__
+#ifdef __WITH_DTLS__
     if (publicData && publicData->data)
     {
         cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
@@ -940,7 +1136,7 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
         memcpy(cred->publicData.data, publicData->data, publicData->len);
         cred->publicData.len = publicData->len;
     }
-#endif // __WITH_X509__
+#endif // __WITH_DTLS__
 
     if (privateData && privateData->data)
     {
@@ -948,52 +1144,77 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
         memcpy(cred->privateData.data, privateData->data, privateData->len);
         cred->privateData.len = privateData->len;
-
-        // TODO: Added as workaround. Will be replaced soon.
         cred->privateData.encoding = OIC_ENCODING_RAW;
+    }
 
-#if 0
-        // NOTE: Test codes to use base64 for credential.
-        uint32_t outSize = 0;
-        size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
-        char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
-        VERIFY_NON_NULL(TAG, b64Buf, ERROR);
-        b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
+    VERIFY_NON_NULL(TAG, rownerID, ERROR);
+    memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
 
-        OICFree( cred->privateData.data );
-        cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
-        VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
+#ifdef MULTIPLE_OWNER
+    if(eownerID)
+    {
+        cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
+        VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
+        memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
+    }
+#else
+    (void)(eownerID);
+#endif //MULTIPLE_OWNER_
 
-        strcpy(cred->privateData.data, b64Buf);
-        cred->privateData.encoding = OIC_ENCODING_BASE64;
-        cred->privateData.len = outSize;
-        OICFree(b64Buf);
-#endif //End of Test codes
+    ret = OC_STACK_OK;
 
+    OIC_LOG_V(DEBUG, TAG, "GenerateCredential : result: %d", ret);
+    OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credId: %d", cred->credId);
+    OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credType: %d", cred->credType);
+    OIC_LOG_BUFFER(DEBUG, TAG, cred->subject.id, sizeof(cred->subject.id));
+    if (cred->privateData.data)
+    {
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : privateData len: %zd", cred->privateData.len);
+        OIC_LOG_BUFFER(DEBUG, TAG, cred->privateData.data, cred->privateData.len);
+    }
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    if(cred->credUsage)
+    {
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credUsage: %s", cred->credUsage);
     }
+    if (cred->publicData.data)
+    {
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : publicData len: %zd", cred->publicData.len);
+        OIC_LOG_BUFFER(DEBUG, TAG, cred->publicData.data, cred->publicData.len);
 
-    VERIFY_NON_NULL(TAG, rownerID, ERROR);
-    memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
+    }
+    if (cred->optionalData.data)
+    {
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %zd", cred->optionalData.len);
+        OIC_LOG_BUFFER(DEBUG, TAG, cred->optionalData.data, cred->optionalData.len);
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData revstat: %d", cred->optionalData.revstat);
+    }
+#endif //defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 
-    ret = OC_STACK_OK;
 exit:
     if (OC_STACK_OK != ret)
     {
         DeleteCredList(cred);
         cred = NULL;
     }
+    OIC_LOG(DEBUG, TAG, "OUT GenerateCredential");
     return cred;
 }
 
 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
 {
     bool ret = false;
+    OIC_LOG(DEBUG, TAG, "IN Cred UpdatePersistentStorage");
 
     // Convert Cred data into JSON for update to persistent storage
     if (cred)
     {
         uint8_t *payload = NULL;
-        size_t size = 0;
+        // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
+        size_t size = GetCredKeyDataSize(cred);
+        size += (512 * OicSecCredCount(cred));
+        OIC_LOG_V(INFO, TAG, "target cred size: %zu - temporal size to make room for encoding", size);
+
         int secureFlag = 0;
         OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
         if ((OC_STACK_OK == res) && payload)
@@ -1002,6 +1223,7 @@ static bool UpdatePersistentStorage(const OicSecCred_t *cred)
             {
                 ret = true;
             }
+            OICClearMemory(payload, size);
             OICFree(payload);
         }
     }
@@ -1012,6 +1234,7 @@ static bool UpdatePersistentStorage(const OicSecCred_t *cred)
             ret = true;
         }
     }
+    OIC_LOG(DEBUG, TAG, "OUT Cred UpdatePersistentStorage");
     return ret;
 }
 
@@ -1085,24 +1308,221 @@ static OicSecCred_t* GetCredDefault()
     return NULL;
 }
 
+static bool IsSameSecOpt(const OicSecOpt_t* sk1, const OicSecOpt_t* sk2)
+{
+    VERIFY_NON_NULL(TAG, sk1, WARNING);
+    VERIFY_NON_NULL(TAG, sk2, WARNING);
+
+    VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
+    VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
+    VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
+    return true;
+exit:
+    return false;
+}
+
+static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
+{
+    VERIFY_NON_NULL(TAG, sk1, WARNING);
+    VERIFY_NON_NULL(TAG, sk2, WARNING);
+
+    VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
+    VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
+    VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
+    return true;
+exit:
+    return false;
+}
+
+/**
+ * Compares credential
+ *
+ * @return CRED_CMP_EQUAL if credentials are equal
+ *         CRED_CMP_NOT_EQUAL if not equal
+ *         otherwise error.
+ */
+
+static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
+{
+    CredCompareResult_t cmpResult = CRED_CMP_ERROR;
+    bool isCompared = false;
+    OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
+
+    VERIFY_NON_NULL(TAG, l, ERROR);
+    VERIFY_NON_NULL(TAG, r, ERROR);
+
+    cmpResult = CRED_CMP_NOT_EQUAL;
+
+    VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
+    VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
+
+    switch(l->credType)
+    {
+        case SYMMETRIC_PAIR_WISE_KEY:
+        case SYMMETRIC_GROUP_KEY:
+        case PIN_PASSWORD:
+        {
+            if(l->privateData.data && r->privateData.data)
+            {
+                VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
+                isCompared = true;
+            }
+            break;
+        }
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+        case ASYMMETRIC_KEY:
+        case SIGNED_ASYMMETRIC_KEY:
+        {
+            if(l->publicData.data && r->publicData.data)
+            {
+                VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
+                isCompared = true;
+            }
+
+            if(l->optionalData.data && r->optionalData.data)
+            {
+                VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
+                isCompared = true;
+            }
+
+            if(l->credUsage && r->credUsage)
+            {
+                VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
+                VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
+                isCompared = true;
+            }
+            break;
+        }
+        case ASYMMETRIC_ENCRYPTION_KEY:
+        {
+            if(l->privateData.data && r->privateData.data)
+            {
+                VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
+                isCompared = true;
+            }
+
+            if(l->publicData.data && r->publicData.data)
+            {
+                VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
+                isCompared = true;
+            }
+
+            if(l->optionalData.data && r->optionalData.data)
+            {
+                VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
+                isCompared = true;
+            }
+
+            break;
+        }
+#endif //__WITH_DTLS__ or __WITH_TLS__
+        default:
+        {
+            OIC_LOG_V(ERROR, TAG, "Invalid CredType(%d)", l->credType);
+            cmpResult = CRED_CMP_ERROR;
+            goto exit;
+        }
+    }
+
+    if(isCompared)
+    {
+        OIC_LOG(DEBUG, TAG, "Same Credentials");
+        cmpResult = CRED_CMP_EQUAL;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
+        cmpResult = CRED_CMP_ERROR;
+    }
+exit:
+    OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
+
+    return cmpResult;
+}
+
 OCStackResult AddCredential(OicSecCred_t * newCred)
 {
     OCStackResult ret = OC_STACK_ERROR;
-    VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
+    OicSecCred_t * temp = NULL;
+    bool validFlag = true;
+    OicUuid_t emptyOwner = { .id = {0} };
+
+    OIC_LOG(DEBUG, TAG, "IN AddCredential");
 
+    VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
     //Assigning credId to the newCred
     newCred->credId = GetCredId();
-    VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
+    VERIFY_SUCCESS(TAG, true == IsValidCredential(newCred), ERROR);
+
+    //the newCred is not valid if it is empty
+
+    if (memcmp(&(newCred->subject), &emptyOwner, sizeof(OicUuid_t)) == 0)
+    {
+        validFlag = false;
+    }
+    else
+    {
+        OicSecCred_t *prev = NULL;
+        LL_FOREACH(gCred, temp)
+        {
+            CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
+            if(CRED_CMP_EQUAL == cmpRes)
+            {
+                OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
+                          "new credential's ID will be replaced.", temp->credId);
+                newCred->credId = temp->credId;
+                newCred->next = temp->next;
+
+                if(NULL == prev)
+                {
+                    gCred = newCred;
+                }
+                else
+                {
+                    prev->next = newCred;
+                }
+
+                FreeCred(temp);
+                ret = OC_STACK_OK;
+                validFlag = false;
+                break;
+            }
+
+            if (CRED_CMP_ERROR == cmpRes)
+            {
+                OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
+                ret = OC_STACK_ERROR;
+                validFlag = false;
+                break;
+            }
 
-    //Append the new Cred to existing list
-    LL_APPEND(gCred, newCred);
+            prev = temp;
+        }
+    }
 
+    //Append the new Cred to existing list if new Cred is valid
+    if (validFlag)
+    {
+        OIC_LOG(INFO, TAG, "New credentials are added to the cred resource");
+        LL_APPEND(gCred, newCred);
+    }
+    if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
+    {
+        memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
+    }
     if (UpdatePersistentStorage(gCred))
     {
+        OIC_LOG(DEBUG, TAG, "UpdatePersistentStorage() Success");
         ret = OC_STACK_OK;
     }
-
+    else
+    {
+        OIC_LOG(ERROR, TAG, "UpdatePersistentStorage() Failed");
+        LL_DELETE(gCred, newCred);
+        ret = OC_STACK_INCONSISTENT_DB;
+    }
 exit:
+    OIC_LOG(DEBUG, TAG, "OUT AddCredential");
     return ret;
 }
 
@@ -1134,6 +1554,46 @@ OCStackResult RemoveCredential(const OicUuid_t *subject)
 
 }
 
+OCStackResult RemoveCredentialByCredId(uint16_t credId)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    OicSecCred_t *cred = NULL;
+    OicSecCred_t *tempCred = NULL;
+    bool deleteFlag = false;
+
+    OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
+
+    if ( 0 == credId)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+
+    LL_FOREACH_SAFE(gCred, cred, tempCred)
+    {
+        if (cred->credId == credId)
+        {
+            OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
+
+            LL_DELETE(gCred, cred);
+            FreeCred(cred);
+            deleteFlag = true;
+        }
+    }
+
+    if (deleteFlag)
+    {
+        if (UpdatePersistentStorage(gCred))
+        {
+            ret = OC_STACK_RESOURCE_DELETED;
+        }
+    }
+    OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
+
+    return ret;
+
+}
+
 /**
  * Remove all credential data on credential resource and persistent storage
  *
@@ -1170,6 +1630,8 @@ static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoi
 {
     //Derive OwnerPSK locally
     const char* oxmLabel = GetOxmString(doxm->oxmSel);
+    char* b64Buf = NULL;
+    size_t b64BufSize = 0;
     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
 
     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
@@ -1188,120 +1650,327 @@ static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoi
     // TODO: Added as workaround, will be replaced soon.
     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
     {
+#ifndef __TIZENRT__
         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
+#else
+        receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, OWNER_PSK_LENGTH_128);
+#endif
         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
     }
     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
     {
+        B64Result b64res = B64_OK;
         uint32_t b64OutSize = 0;
-        size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
-        char* b64Buf = OICCalloc(1, b64BufSize);
+        b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
+        b64Buf = OICCalloc(1, b64BufSize);
         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
 
-        b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
-
+        b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
+        VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
+#ifndef __TIZENRT__
         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
+#else
+        receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, b64OutSize + 1);
+#endif
         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
         receviedCred->privateData.len = b64OutSize;
         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
         receviedCred->privateData.data[b64OutSize] = '\0';
+        OICClearMemory(b64Buf, b64BufSize);
+        OICFree(b64Buf);
+        b64Buf = NULL;
     }
     else
     {
-        // TODO: error
         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
     }
 
     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
 
+    OICClearMemory(ownerPSK, sizeof(ownerPSK));
+
     //Verify OwnerPSK information
     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
 exit:
     //receviedCred->privateData.data will be deallocated when deleting credential.
+    OICClearMemory(ownerPSK, sizeof(ownerPSK));
+    OICClearMemory(b64Buf, b64BufSize);
+    OICFree(b64Buf);
     return false;
 }
 
-#endif //__WITH_DTLS__
 
-static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
+#ifdef MULTIPLE_OWNER
+/**
+ * Internal function to fill private data of SubOwner PSK.
+ *
+ * @param receviedCred recevied owner credential from SubOwner
+ * @param ownerAdd address of SubOwner
+ * @param doxm current device's doxm resource
+ *
+ * @return
+ *     true successfully done and valid subower psk information
+ *     false Invalid subowner psk information or failed to subowner psk generation
+ */
+static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
+                           const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
 {
-    OCEntityHandlerResult ret = OC_EH_ERROR;
-    OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
+    char* b64Buf = NULL;
+    //Derive OwnerPSK locally
+    const char* oxmLabel = GetOxmString(doxm->oxmSel);
+    VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
 
-    static uint16_t previousMsgId = 0;
-    //Get binary representation of cbor
-    OicSecCred_t *cred  = NULL;
-    uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
-    size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
+    uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
+    CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
+        (uint8_t*)oxmLabel, strlen(oxmLabel),
+        subOwner->id, sizeof(subOwner->id),
+        doxm->deviceID.id, sizeof(doxm->deviceID.id),
+        subOwnerPSK, OWNER_PSK_LENGTH_128);
+    VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
 
-    OCStackResult res = CBORPayloadToCred(payload, size, &cred);
-    if (res == OC_STACK_OK)
+    OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
+    OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
+
+    //Generate owner credential based on received credential information
+
+    if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
     {
-#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
-        OicUuid_t emptyUuid = {.id={0}};
-        const OicSecDoxm_t* doxm = GetDoxmResourceData();
-        if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
-        {
-            //in case of owner PSK
-            switch(cred->credType)
-            {
-                case SYMMETRIC_PAIR_WISE_KEY:
-                {
-                    OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
-                    if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
-                    {
-                        if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
-                        {
-                            OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
-                        }
+        receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
+        VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
+        receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
+        memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
+    }
+    else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
+    {
+        uint32_t b64OutSize = 0;
+        size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
+        b64Buf = OICCalloc(1, b64BufSize);
+        VERIFY_NON_NULL(TAG, b64Buf, ERROR);
 
-                        OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
-                        if(OC_STACK_OK == AddCredential(cred))
-                        {
-                            ret = OC_EH_CHANGED;
-                        }
-                        else
-                        {
-                            OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
-                            ret = OC_EH_ERROR;
-                        }
-                    }
-                    else
-                    {
-                        OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
-                        ret = OC_EH_ERROR;
-                    }
+        VERIFY_SUCCESS(TAG, \
+                       B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
+                       ERROR);
 
-                    if(OC_EH_CHANGED == ret)
-                    {
-                        /**
-                         * in case of random PIN based OxM,
+        receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
+        VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
+        receivedCred->privateData.len = b64OutSize;
+        strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
+        receivedCred->privateData.data[b64OutSize] = '\0';
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
+        VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
+    }
+
+    OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
+    OICFree(b64Buf);
+    return true;
+exit:
+    //receivedCred->privateData.data will be deallocated when deleting credential.
+    OICFree(b64Buf);
+    return false;
+}
+#endif //MULTIPLE_OWNER
+
+
+OCStackResult AddPreconfPinCredential(const char* preconfPin)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+#ifdef MULTIPLE_OWNER
+    OCStackResult res = OC_STACK_INVALID_PARAM;
+    OicSecCred_t* cred = NULL;
+    OicSecCred_t* pinCred = NULL;
+    VERIFY_NON_NULL(TAG, preconfPin, ERROR);
+    VERIFY_SUCCESS(TAG, (strlen(preconfPin) >= PRECONF_PIN_MIN_SIZE), ERROR);
+
+    OIC_LOG(DEBUG, TAG, "Finding previous preconfigured PIN...");
+    //Find the previous PIN
+    LL_FOREACH(gCred, cred)
+    {
+        if(memcmp(cred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(cred->subject.id)) == 0 &&
+            PIN_PASSWORD == cred->credType)
+        {
+            break;
+        }
+    }
+
+    //If previous PIN is exist, remove it.
+    if (cred)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Preconfigured PIN already exist.");
+        OIC_LOG_V(DEBUG, TAG, "Previous preconfigured PIN will be removed.");
+
+        res = RemoveCredentialByCredId(cred->credId);
+        if (OC_STACK_RESOURCE_DELETED != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "RemoveCredentialByCredId error : %d", res);
+            cred = NULL;
+            goto exit;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "Adding preconfigured PIN...");
+    //Add preconfig PIN
+    res = OC_STACK_NO_MEMORY;
+    //Generate PIN based credential
+    size_t preconfPinLen = strlen(preconfPin);
+    pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    VERIFY_NON_NULL(TAG, pinCred, ERROR);
+
+    pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPinLen + 1);
+    VERIFY_NON_NULL(TAG, pinCred->privateData.data, ERROR);
+
+    memcpy(pinCred->privateData.data, preconfPin, preconfPinLen);
+    pinCred->privateData.data[preconfPinLen] = '\0';
+    pinCred->privateData.len = preconfPinLen;
+    pinCred->privateData.encoding = OIC_ENCODING_RAW;
+    pinCred->credType = PIN_PASSWORD;
+    memcpy(pinCred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(pinCred->subject.id));
+
+    res = AddCredential(pinCred);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "AddCredential error : %d", res);
+        goto exit;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return OC_STACK_OK;
+exit:
+    if (cred)
+    {
+        FreeCred(cred);
+    }
+    if (pinCred)
+    {
+        FreeCred(pinCred);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return res;
+#else
+    OC_UNUSED(preconfPin);
+    OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return OC_STACK_ERROR;
+#endif //MULTIPLE_OWNER
+}
+
+
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
+static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehRequest)
+{
+    OCEntityHandlerResult ret = OC_EH_ERROR;
+    OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
+
+    static uint16_t previousMsgId = 0;
+    //Get binary representation of cbor
+    OicSecCred_t *cred  = NULL;
+    uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
+    size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
+
+    OCStackResult res = CBORPayloadToCred(payload, size, &cred);
+    if (res == OC_STACK_OK)
+    {
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+        OicUuid_t emptyUuid = {.id={0}};
+        const OicSecDoxm_t* doxm = GetDoxmResourceData();
+        if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
+        {
+            //in case of owner PSK
+            switch(cred->credType)
+            {
+                case SYMMETRIC_PAIR_WISE_KEY:
+                {
+                    OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
+                    if (NULL == request)
+                    {
+                        OIC_LOG(ERROR, TAG, "Failed to get a server request information.");
+                        ret = OC_EH_ERROR;
+                        break;
+                    }
+#ifdef __TIZENRT__
+                    CAEndpoint_t *ep_addr = (CAEndpoint_t *)malloc(sizeof(CAEndpoint_t));
+                    if(!ep_addr)
+                    {
+                        ret = OC_STACK_NO_MEMORY;
+                        break;
+                    }
+                    ep_addr->adapter=   request->devAddr.adapter;
+                    ep_addr->flags=   request->devAddr.flags;
+                    ep_addr->port  =   request->devAddr.port;
+                    memcpy(ep_addr->addr,request->devAddr.addr,MAX_ADDR_STR_SIZE_CA);
+                    ep_addr->ifindex  =   request->devAddr.ifindex;
+#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
+                    memcpy(ep_addr->routeData,request->devAddr.routeData,MAX_ADDR_STR_SIZE_CA);
+#endif
+                    if(FillPrivateDataOfOwnerPSK(cred, ep_addr, doxm))
+#else
+                    if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
+#endif
+                    {
+                        if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
+                        {
+                            OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
+                        }
+
+                        OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
+                        if(OC_STACK_OK == AddCredential(cred))
+                        {
+                            ret = OC_EH_CHANGED;
+                        }
+                        else
+                        {
+                            OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
+                            ret = OC_EH_ERROR;
+                        }
+                    }
+                    else
+                    {
+                        OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
+                        ret = OC_EH_ERROR;
+                    }
+#ifdef __TIZENRT__
+                    free(ep_addr);
+#endif
+                    if(OC_EH_CHANGED == ret)
+                    {
+                        /**
+                         * in case of random PIN based OxM,
                          * revert get_psk_info callback of tinyDTLS to use owner credential.
                          */
                         if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
                         {
-                            OicUuid_t emptyUuid = { .id={0}};
-                            SetUuidForRandomPinOxm(&emptyUuid);
+                            SetUuidForPinBasedOxm(&emptyUuid);
 
-#ifdef __WITH_TLS__
-                            if(CA_STATUS_OK != CAregisterTlsCredentialsHandler(GetDtlsPskCredentials))
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+                            if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
                             {
                                 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
                                 ret = OC_EH_ERROR;
                                 break;
                             }
-#endif
-                            if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
-                            {
-                                OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
-                                ret = OC_EH_ERROR;
-                                break;
-                            }
+#endif // __WITH_DTLS__ or __WITH_TLS__
                         }
-
+                        else
+                        {
+                            if(OIC_MANUFACTURER_CERTIFICATE == doxm->oxmSel)
+                            {
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+                                if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
+                                {
+                                    OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
+                                    ret = OC_EH_ERROR;
+                                    break;
+                                }
+#endif // __WITH_DTLS__ or __WITH_TLS__
+                             }
+                         }
                         //Select cipher suite to use owner PSK
                         if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
                         {
@@ -1313,12 +1982,17 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
                         }
 
-                        if(CA_STATUS_OK !=
-                           CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
+                        if (CA_STATUS_OK != CASelectCipherSuite(
+                                    MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
                         {
-                            OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
+                            OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
                             ret = OC_EH_ERROR;
                         }
+                        else
+                        {
+                            OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
+                        }
+
                     }
 
                     break;
@@ -1335,7 +2009,7 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
                 }
                 default:
                 {
-                    OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
+                    OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
                     ret = OC_EH_ERROR;
                     break;
                 }
@@ -1350,12 +2024,21 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
                 const OicSecDoxm_t* doxm =  GetDoxmResourceData();
                 if(doxm)
                 {
-                    if(!doxm->owned && previousMsgId != ehRequest->messageID)
+                    if(!doxm->owned)
                     {
-                        OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
-                                            "DOXM will be reverted.");
-                        RestoreDoxmToInitState();
-                        RestorePstatToInitState();
+                        OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
+
+                        if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
+                           || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
+                        {
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+                            InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
+                                                  NULL, OIC_OTM_ERROR);
+#endif
+                            RestoreDoxmToInitState();
+                            RestorePstatToInitState();
+                            OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
+                        }
                     }
                 }
                 else
@@ -1364,15 +2047,97 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
                 }
             }
         }
+#ifdef MULTIPLE_OWNER
+        // In case SubOwner Credential
+        else if(doxm && doxm->owned && doxm->mom &&
+                OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
+                0 == cred->privateData.len &&
+                0 == cred->optionalData.len &&
+                0 == cred->publicData.len )
+        {
+            switch(cred->credType)
+            {
+                case SYMMETRIC_PAIR_WISE_KEY:
+                {
+                    OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
+                    if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
+                    {
+                        if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
+                        {
+                            OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
+                        }
+
+                        OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
+                        if(OC_STACK_OK == AddCredential(cred))
+                        {
+                            ret = OC_EH_CHANGED;
+                        }
+                        else
+                        {
+                            OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
+                            ret = OC_EH_ERROR;
+                        }
+                    }
+                    else
+                    {
+                        OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
+                        ret = OC_EH_ERROR;
+                    }
+                }
+                break;
+
+                case SYMMETRIC_GROUP_KEY:
+                case ASYMMETRIC_KEY:
+                case SIGNED_ASYMMETRIC_KEY:
+                case PIN_PASSWORD:
+                case ASYMMETRIC_ENCRYPTION_KEY:
+                {
+                    OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
+                    ret = OC_EH_ERROR;
+                    break;
+                }
+                default:
+                {
+                    OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
+                    ret = OC_EH_ERROR;
+                    break;
+                }
+            }
+        }
+#endif //MULTIPLE_OWNER
         else
         {
-            /*
-             * If the post request credential has credId, it will be
-             * discarded and the next available credId will be assigned
-             * to it before getting appended to the existing credential
-             * list and updating svr database.
-             */
-            ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
+            if(IsEmptyCred(cred))
+            {
+                OicUuid_t emptyUuid = {.id={0}};
+                if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
+                {
+                    OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
+                    memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
+                    if (UpdatePersistentStorage(gCred))
+                    {
+                        ret = OC_EH_CHANGED;
+                    }
+                    else
+                    {
+                        ret = OC_EH_ERROR;
+                    }
+                }
+                else
+                {
+                    ret = OC_EH_ERROR;
+                }
+            }
+            else
+            {
+                /*
+                 * If the post request credential has credId, it will be
+                 * discarded and the next available credId will be assigned
+                 * to it before getting appended to the existing credential
+                 * list and updating svr database.
+                 */
+                ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
+            }
         }
 #else //not __WITH_DTLS__
         /*
@@ -1382,6 +2147,7 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
          * list and updating svr database.
          */
         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
+        OC_UNUSED(previousMsgId);
 #endif//__WITH_DTLS__
     }
 
@@ -1395,7 +2161,10 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
     }
     else
     {
-        previousMsgId = ehRequest->messageID;
+        if(OC_ADAPTER_IP == ehRequest->devAddr.adapter)
+        {
+            previousMsgId = ehRequest->messageID++;
+        }
     }
     //Send response to request originator
     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
@@ -1418,6 +2187,10 @@ static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * eh
     int secureFlag = 1;
 
     const OicSecCred_t *cred = gCred;
+
+    // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
+    size = GetCredKeyDataSize(cred);
+    size += (256 * OicSecCredCount(cred));
     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
 
     // A device should always have a default cred. Therefore, payload should never be NULL.
@@ -1427,6 +2200,7 @@ static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * eh
     //Send payload to request originator
     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
                        OC_EH_OK : OC_EH_ERROR;
+    OICClearMemory(payload, size);
     OICFree(payload);
     return ehRet;
 }
@@ -1525,6 +2299,7 @@ OCStackResult CreateCredResource()
 OCStackResult InitCredResource()
 {
     OCStackResult ret = OC_STACK_ERROR;
+    OicSecCred_t* cred = NULL;
 
     //Read Cred resource from PS
     uint8_t *data = NULL;
@@ -1537,7 +2312,7 @@ OCStackResult InitCredResource()
     }
     if (data)
     {
-        // Read ACL resource from PS
+        // Read Cred resource from PS
         ret = CBORPayloadToCred(data, size, &gCred);
     }
 
@@ -1550,8 +2325,51 @@ OCStackResult InitCredResource()
     {
         gCred = GetCredDefault();
     }
+
+    if (gCred)
+    {
+        OicUuid_t deviceID;
+        OicUuid_t emptyUuid = {.id={0}};
+
+        ret = GetDoxmDeviceID(&deviceID);
+        if (ret != OC_STACK_OK)
+        {
+            OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
+            //Unit tests expect error code OC_STACK_INVALID_PARAM.
+            ret = OC_STACK_INVALID_PARAM;
+            goto exit;
+        }
+
+        //Add a log to track the invalid credential.
+        LL_FOREACH(gCred, cred)
+        {
+            if (false == CheckSubjectOfCertificate(cred, deviceID))
+            {
+                OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
+            }
+            if (false == IsValidCredential(cred))
+            {
+                OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
+                OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
+            }
+        }
+
+        if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
+        {
+            memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
+        }
+
+        if (!UpdatePersistentStorage(gCred))
+        {
+            OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
+        }
+    }
     //Instantiate 'oic.sec.cred'
     ret = CreateCredResource();
+
+exit:
+    OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
+    OICClearMemory(data, size);
     OICFree(data);
     return ret;
 }
@@ -1559,8 +2377,11 @@ OCStackResult InitCredResource()
 OCStackResult DeInitCredResource()
 {
     OCStackResult result = OCDeleteResource(gCredHandle);
-    DeleteCredList(gCred);
-    gCred = NULL;
+    gCredHandle = NULL;
+    if(gCred){
+        DeleteCredList(gCred);
+        gCred = NULL;
+    }
     return result;
 }
 
@@ -1583,22 +2404,81 @@ OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
     return NULL;
 }
 
-OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId)
+const OicSecCred_t* GetCredList()
+{
+    return gCred;
+}
+
+OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
 {
     OicSecCred_t *cred = NULL;
+    OicSecCred_t *tmpCred = NULL;
 
    if ( 1 > credId)
     {
        return NULL;
     }
 
-    LL_FOREACH(gCred, cred)
+    LL_FOREACH(gCred, tmpCred)
     {
-        if(cred->credId == credId)
+        if(tmpCred->credId == credId)
         {
+            cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+            VERIFY_NON_NULL(TAG, cred, ERROR);
+
+            // common
+            cred->next = NULL;
+            cred->credId = tmpCred->credId;
+            cred->credType = tmpCred->credType;
+            memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
+            memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
+            if (tmpCred->period)
+            {
+                cred->period = OICStrdup(tmpCred->period);
+            }
+
+            // key data
+            if (tmpCred->privateData.data)
+            {
+                cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
+                VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
+
+                memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
+                cred->privateData.len = tmpCred->privateData.len;
+                cred->privateData.encoding = tmpCred->privateData.encoding;
+            }
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+            if (tmpCred->publicData.data)
+            {
+                cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
+                VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
+
+                memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
+                cred->publicData.len = tmpCred->publicData.len;
+                cred->publicData.encoding = tmpCred->publicData.encoding;
+            }
+            if (tmpCred->optionalData.data)
+            {
+                cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
+                VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
+
+                memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
+                cred->optionalData.len = tmpCred->optionalData.len;
+                cred->optionalData.encoding = tmpCred->optionalData.encoding;
+                cred->optionalData.revstat= tmpCred->optionalData.revstat;
+            }
+            if (tmpCred->credUsage)
+            {
+                cred->credUsage = OICStrdup(tmpCred->credUsage);
+            }
+#endif /* __WITH_DTLS__  or __WITH_TLS__*/
+
             return cred;
         }
     }
+
+exit:
+    FreeCred(cred);
     return NULL;
 }
 
@@ -1677,7 +2557,7 @@ int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
                             uint32_t outKeySize;
                             if(NULL == outKey)
                             {
-                                OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
+                                OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
                                 return ret;
                             }
 
@@ -1697,12 +2577,105 @@ int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
                         return ret;
                     }
                 }
-            }
-            break;
+                OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
 
-        default:
-            {
-                OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
+#ifdef MULTIPLE_OWNER
+                const OicSecDoxm_t* doxm = GetDoxmResourceData();
+                if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
+                {
+                    // in case of multiple owner transfer authentication
+                    if(OIC_PRECONFIG_PIN == doxm->oxmSel)
+                    {
+                        OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
+                        if(wildCardCred)
+                        {
+                            OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
+                            if(PIN_PASSWORD == wildCardCred->credType)
+                            {
+                                //Read PIN/PW
+                                char* pinBuffer = NULL;
+                                uint32_t pinLength = 0;
+                                if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
+                                {
+                                    pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
+                                    if(NULL == pinBuffer)
+                                    {
+                                        OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
+                                        return ret;
+                                    }
+                                    pinLength = wildCardCred->privateData.len;
+                                    memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
+                                }
+                                else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
+                                {
+                                    size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
+                                    pinBuffer = OICCalloc(1, pinBufSize);
+                                    if(NULL == pinBuffer)
+                                    {
+                                        OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
+                                        return ret;
+                                    }
+
+                                    if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
+                                    {
+                                        OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
+                                        return ret;
+                                    }
+                                }
+                                else
+                                {
+                                    OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
+                                    return ret;
+                                }
+
+                                //Set the PIN/PW to derive PSK
+                                if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
+                                {
+                                    OICFree(pinBuffer);
+                                    OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
+                                    return ret;
+                                }
+                                OICFree(pinBuffer);
+
+                                OicUuid_t myUuid;
+                                if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
+                                {
+                                    OIC_LOG(ERROR, TAG, "Failed to read device ID");
+                                    return ret;
+                                }
+                                SetUuidForPinBasedOxm(&myUuid);
+
+                                //Calculate PSK using PIN/PW
+                                if(0 == DerivePSKUsingPIN((uint8_t*)result))
+                                {
+                                    ret = OWNER_PSK_LENGTH_128;
+                                }
+                                else
+                                {
+                                    OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
+                                }
+
+                                if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
+                                {
+                                    OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
+                                }
+                            }
+                        }
+                    }
+                    else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
+                    {
+                        if(0 == DerivePSKUsingPIN((uint8_t*)result))
+                        {
+                            ret = OWNER_PSK_LENGTH_128;
+                        }
+                        else
+                        {
+                            OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
+                            ret = -1;
+                        }
+                    }
+                }
+#endif //MULTIPLE_OWNER
             }
             break;
     }
@@ -1743,7 +2716,8 @@ OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t cre
     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
 
     cred = GenerateCredential(tmpSubject, credType, NULL,
-                              &privKey, rownerID);
+                              &privKey, rownerID, NULL);
+    OICClearMemory(privData, sizeof(privData));
     if(NULL == cred)
     {
         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
@@ -1755,7 +2729,7 @@ OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t cre
     ret = AddCredential(cred);
     if( OC_STACK_OK != ret)
     {
-        RemoveCredential(tmpSubject);
+        FreeCred(cred);
         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
     }
     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
@@ -1765,81 +2739,6 @@ exit:
 }
 
 #endif /* __WITH_DTLS__ */
-#ifdef __WITH_X509__
-#define CERT_LEN_PREFIX (3)
-#define BYTE_SIZE (8) //bits
-#define PUB_KEY_X_COORD ("x")
-#define PUB_KEY_Y_COORD ("y")
-#define CERTIFICATE ("x5c")
-#define PRIVATE_KEY ("d")
-
-static uint32_t parseCertPrefix(uint8_t *prefix)
-{
-    uint32_t res = 0;
-    if (NULL != prefix)
-    {
-        for (int i = 0; i < CERT_LEN_PREFIX; ++i)
-        {
-            res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
-        }
-    }
-    return res;
-}
-
-static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
-{
-    OCStackResult ret = OC_STACK_ERROR;
-    uint8_t *ccPtr = credInfo->certificateChain;
-    for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
-    {
-        ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
-    }
-
-    ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
-    CertificateX509 certStruct;
-
-    VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
-
-    INC_BYTE_ARRAY(certStruct.pubKey, 2);
-
-    memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
-    memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
-
-    ret = OC_STACK_OK;
-    exit:
-    return ret;
-}
-
-int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
-{
-    int ret = 1;
-    VERIFY_NON_NULL(TAG, credInfo, ERROR);
-    if (NULL == gCred)
-    {
-        VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
-    }
-
-    OicSecCred_t *cred = NULL;
-    LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
-    VERIFY_NON_NULL(TAG, cred, ERROR);
-
-    if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
-    {
-        goto exit;
-    }
-    credInfo->chainLen = 2;
-    memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
-    memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
-    credInfo->certificateChainLen = cred->publicData.len;
-    GetCAPublicKeyData(credInfo);
-    ret = 0;
-
-exit:
-
-    return ret;
-}
-#undef CERT_LEN_PREFIX
-#endif /* __WITH_X509__ */
 
 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
 {
@@ -1863,6 +2762,9 @@ OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
 
+        // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
+        size = GetCredKeyDataSize(gCred);
+        size += (256 * OicSecCredCount(gCred));
         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
 
@@ -1891,257 +2793,323 @@ OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
     return retVal;
 }
 
-#ifdef __WITH_TLS__
-OCStackResult AddCA(OicSecCert_t * cert)
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+void GetDerCaCert(ByteArray_t * crt, const char * usage)
 {
     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
-    OCStackResult ret = OC_STACK_ERROR;
-    if (NULL == cert || NULL == cert->data)
+    if (NULL == crt || NULL == usage)
     {
-        return OC_STACK_INVALID_PARAM;
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return;
     }
-    OicUuid_t  subject;
-    OicUuid_t rowner;
-    ret = GetCredRownerId(&rowner);
-    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
-    ret = ConvertStrToUuid(CA_SUBJECT_ID, &subject);
-    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+    crt->len = 0;
+    OicSecCred_t* temp = NULL;
 
-    OicSecCred_t * cred  = GetCredResourceData(&subject);
-    if (NULL == cred)
+    LL_FOREACH(gCred, temp)
     {
-        //Generating new credential for CA
-        cred = GenerateCredential(&subject, SIGNED_ASYMMETRIC_KEY, cert, NULL, &rowner);
-        VERIFY_NON_NULL(TAG, cred, ERROR);
-        return AddCredential(cred);
+        if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
+            (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
+        {
+            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)
+                {
+                    OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+                    return;
+                }
+                uint32_t outSize;
+                if(B64_OK != b64Decode((char*)(temp->optionalData.data),
+                                       temp->optionalData.len, buf, bufSize, &outSize))
+                {
+                    OICFree(buf);
+                    OIC_LOG(ERROR, TAG, "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;
+            }
+            OIC_LOG_V(DEBUG, TAG, "%s found", usage);
+        }
     }
-
-    uint8_t * tempData = OICRealloc(cred->publicData.data, cred->publicData.len + cert->len);
-    if (NULL == tempData)
+    if(0 == crt->len)
     {
-        return OC_STACK_NO_MEMORY;
+        OIC_LOG_V(WARNING, TAG, "%s not found", usage);
     }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return;
+}
 
-    memcpy(tempData + cred->publicData.len, cert->data, cert->len);
-    cred->publicData.data = tempData;
-    cred->publicData.len += cert->len;
+void GetDerOwnCert(ByteArray_t * crt, const char * usage)
+{
+    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(gCred, temp)
+    {
+        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            0 == strcmp(temp->credUsage, usage))
+        {
+            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;
+}
 
-    if (UpdatePersistentStorage(gCred))
+void GetDerKey(ByteArray_t * key, const char * usage)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (NULL == key || NULL == usage)
     {
-        ret = OC_STACK_OK;
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return;
     }
 
-exit:
+    OicSecCred_t * temp = NULL;
+    key->len = 0;
+    LL_FOREACH(gCred, temp)
+    {
+        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            0 == strcmp(temp->credUsage, usage))
+        {
+            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__);
-    return ret;
 }
-// TODO for testing only
-// will be removed
-const unsigned char ca_cert[] = {
-// AMAZON
-0x30, 0x82, 0x02, 0xFE, 0x30, 0x82, 0x01, 0xE6, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A,
-0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09,
-0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
-0x04, 0x08, 0x0C, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21,
-0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x18, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65,
-0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4C, 0x74,
-0x64, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36, 0x30, 0x36, 0x32, 0x38, 0x30, 0x35, 0x33, 0x33, 0x35,
-0x38, 0x5A, 0x17, 0x0D, 0x32, 0x36, 0x30, 0x36, 0x32, 0x36, 0x30, 0x35, 0x33, 0x33, 0x35, 0x38,
-0x5A, 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55,
-0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D,
-0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x18,
-0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73,
-0x20, 0x50, 0x74, 0x79, 0x20, 0x4C, 0x74, 0x64, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09,
-0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00,
-0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xB5, 0x1C, 0x79, 0x1F, 0x30, 0x6F, 0x5C,
-0x04, 0x9E, 0xD9, 0x78, 0x22, 0x01, 0x29, 0xEE, 0xE9, 0x4A, 0x3A, 0x69, 0xB6, 0xF8, 0xBE, 0x87,
-0x3A, 0x5D, 0x57, 0xBD, 0x96, 0xEE, 0xCC, 0xE9, 0x58, 0x39, 0x53, 0x41, 0xD5, 0x1A, 0x47, 0x12,
-0x8B, 0xF5, 0xAA, 0x0D, 0xC5, 0xBC, 0xAE, 0x17, 0x93, 0x8B, 0xF3, 0x10, 0x10, 0xF6, 0xCD, 0xBC,
-0x22, 0xA2, 0x31, 0x74, 0xF5, 0xBB, 0x5F, 0x72, 0x40, 0x9A, 0x42, 0xE2, 0x83, 0x33, 0x02, 0xA3,
-0x6C, 0x6D, 0x5C, 0x7C, 0xFF, 0x3B, 0x2B, 0xE8, 0x99, 0x4E, 0x9F, 0x86, 0x26, 0xE7, 0x79, 0x0C,
-0x39, 0x0D, 0xEF, 0xA2, 0x52, 0x80, 0xFA, 0xF3, 0x37, 0x46, 0xFB, 0xF9, 0x35, 0x35, 0xC0, 0x16,
-0xC7, 0x1F, 0x95, 0x10, 0x03, 0x30, 0xE1, 0xFB, 0xD9, 0xBD, 0x84, 0x95, 0x11, 0x0D, 0x5A, 0x28,
-0x59, 0xE3, 0xB6, 0xB4, 0x3C, 0xA3, 0xA6, 0x5F, 0x7B, 0x9F, 0x8C, 0x45, 0x3B, 0xC1, 0xAB, 0xE1,
-0xB4, 0xFA, 0x3C, 0x19, 0x58, 0x91, 0x28, 0x29, 0xBA, 0x71, 0x20, 0xFA, 0x4D, 0x58, 0xF1, 0xB1,
-0x01, 0x5D, 0x7B, 0xB4, 0x4A, 0x5E, 0xFA, 0x58, 0x36, 0xEE, 0x31, 0x18, 0x0D, 0x81, 0xB5, 0x41,
-0x48, 0x8B, 0xD9, 0x31, 0xBC, 0xD1, 0x98, 0xD0, 0x40, 0xBF, 0x79, 0x3A, 0x31, 0x13, 0x61, 0xFF,
-0x04, 0x23, 0x1A, 0x2A, 0xAC, 0xA1, 0xEF, 0x1C, 0x2B, 0xC3, 0x8A, 0x7D, 0x33, 0x75, 0xDF, 0x84,
-0xA8, 0xF3, 0x74, 0x63, 0xE4, 0x61, 0x92, 0x5D, 0xCF, 0x62, 0x8C, 0x56, 0x9B, 0xB7, 0x7C, 0xCF,
-0x4A, 0x75, 0x98, 0x3E, 0xE5, 0x73, 0x03, 0x8C, 0xBF, 0x2D, 0x4A, 0x80, 0x48, 0x2D, 0x27, 0xB4,
-0x87, 0xCB, 0x40, 0xF6, 0x48, 0x85, 0xBF, 0x29, 0xA0, 0xE8, 0xC7, 0xF9, 0x11, 0x3C, 0x2D, 0x4F,
-0x92, 0xC1, 0x5E, 0x01, 0x2D, 0x81, 0xD1, 0x9F, 0x73, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0D,
-0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01,
-0x01, 0x00, 0x0B, 0x47, 0x8E, 0x29, 0x8C, 0xCB, 0x05, 0xE7, 0xF3, 0xDD, 0xC8, 0x7E, 0xED, 0x6F,
-0xB4, 0xD9, 0xCB, 0xF4, 0x84, 0xCC, 0xA5, 0x08, 0x6C, 0x1C, 0x09, 0x60, 0xD5, 0x00, 0x55, 0x13,
-0x28, 0xC6, 0x64, 0xB2, 0x23, 0x52, 0x03, 0x21, 0xB1, 0x69, 0x63, 0x57, 0x04, 0xC2, 0xD4, 0xF7,
-0x41, 0xAC, 0xEE, 0xD5, 0xD0, 0x49, 0x58, 0x6D, 0xE5, 0x7E, 0x2C, 0xA6, 0x06, 0xC0, 0x39, 0x3A,
-0x7E, 0x30, 0x49, 0xA2, 0x00, 0x8B, 0x81, 0x98, 0x94, 0xC3, 0x5F, 0x05, 0xF1, 0x38, 0xC7, 0x0B,
-0xFA, 0x83, 0xB2, 0x85, 0x84, 0xB2, 0x6D, 0x62, 0x07, 0x82, 0x9C, 0x4D, 0x99, 0x24, 0xD2, 0x79,
-0xBF, 0xDA, 0xF8, 0x9D, 0x1C, 0xAD, 0x13, 0x30, 0xBC, 0xC2, 0xA2, 0x14, 0x7B, 0xD7, 0xFB, 0xCD,
-0x29, 0x2D, 0xAB, 0xB6, 0x24, 0x03, 0x60, 0x62, 0x9E, 0xF4, 0x4C, 0xE3, 0x35, 0x23, 0xB7, 0x1A,
-0x50, 0x96, 0x91, 0x54, 0xD8, 0xB4, 0x93, 0x61, 0x00, 0xB6, 0xBF, 0x05, 0xF0, 0xF3, 0x6B, 0x99,
-0x1E, 0x46, 0x4C, 0x26, 0x95, 0xD2, 0x58, 0x86, 0x5C, 0x78, 0xAD, 0x01, 0xF9, 0xC9, 0x54, 0x67,
-0xB7, 0x99, 0x3C, 0xEE, 0xF8, 0xD7, 0xD2, 0x1E, 0xE6, 0xF0, 0xCC, 0xC8, 0xC2, 0x20, 0x1B, 0xDA,
-0xCF, 0xDB, 0xF5, 0x70, 0x65, 0x33, 0x51, 0x6E, 0x17, 0x1D, 0xC5, 0xC5, 0xC5, 0x63, 0x06, 0x5E,
-0xCA, 0xB5, 0x40, 0x14, 0xEE, 0xDC, 0x14, 0xF2, 0xFE, 0x4B, 0x7A, 0x78, 0xD6, 0x0D, 0x21, 0xF5,
-0x0F, 0x58, 0xE7, 0x2A, 0x26, 0x54, 0x52, 0xCA, 0x60, 0xA2, 0xF8, 0x68, 0xB0, 0xF4, 0x6A, 0x9B,
-0x11, 0x8D, 0x5E, 0x57, 0x5A, 0x5F, 0x51, 0x3E, 0x44, 0x99, 0xB1, 0x76, 0xDA, 0x94, 0x56, 0x0E,
-0x1C, 0xA3, 0xFC, 0xE3, 0x01, 0xB4, 0xD8, 0xEC, 0x2F, 0xBB, 0x65, 0x82, 0x19, 0x06, 0x8E, 0x3A,
-0x2E, 0x5D,
-//Google
-
-0x30, 0x82, 0x03, 0x54, 0x30, 0x82, 0x02, 0x3c, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x02,
-0x34, 0x56, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
-0x00, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
-0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72,
-0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
-0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
-0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30, 0x35, 0x32, 0x31, 0x30,
-0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x35, 0x32, 0x31, 0x30, 0x34,
-0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
-0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
-0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19,
-0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
-0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
-0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
-0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0xcc, 0x18, 0x63, 0x30, 0xfd,
-0xf4, 0x17, 0x23, 0x1a, 0x56, 0x7e, 0x5b, 0xdf, 0x3c, 0x6c, 0x38, 0xe4, 0x71, 0xb7, 0x78, 0x91,
-0xd4, 0xbc, 0xa1, 0xd8, 0x4c, 0xf8, 0xa8, 0x43, 0xb6, 0x03, 0xe9, 0x4d, 0x21, 0x07, 0x08, 0x88,
-0xda, 0x58, 0x2f, 0x66, 0x39, 0x29, 0xbd, 0x05, 0x78, 0x8b, 0x9d, 0x38, 0xe8, 0x05, 0xb7, 0x6a,
-0x7e, 0x71, 0xa4, 0xe6, 0xc4, 0x60, 0xa6, 0xb0, 0xef, 0x80, 0xe4, 0x89, 0x28, 0x0f, 0x9e, 0x25,
-0xd6, 0xed, 0x83, 0xf3, 0xad, 0xa6, 0x91, 0xc7, 0x98, 0xc9, 0x42, 0x18, 0x35, 0x14, 0x9d, 0xad,
-0x98, 0x46, 0x92, 0x2e, 0x4f, 0xca, 0xf1, 0x87, 0x43, 0xc1, 0x16, 0x95, 0x57, 0x2d, 0x50, 0xef,
-0x89, 0x2d, 0x80, 0x7a, 0x57, 0xad, 0xf2, 0xee, 0x5f, 0x6b, 0xd2, 0x00, 0x8d, 0xb9, 0x14, 0xf8,
-0x14, 0x15, 0x35, 0xd9, 0xc0, 0x46, 0xa3, 0x7b, 0x72, 0xc8, 0x91, 0xbf, 0xc9, 0x55, 0x2b, 0xcd,
-0xd0, 0x97, 0x3e, 0x9c, 0x26, 0x64, 0xcc, 0xdf, 0xce, 0x83, 0x19, 0x71, 0xca, 0x4e, 0xe6, 0xd4,
-0xd5, 0x7b, 0xa9, 0x19, 0xcd, 0x55, 0xde, 0xc8, 0xec, 0xd2, 0x5e, 0x38, 0x53, 0xe5, 0x5c, 0x4f,
-0x8c, 0x2d, 0xfe, 0x50, 0x23, 0x36, 0xfc, 0x66, 0xe6, 0xcb, 0x8e, 0xa4, 0x39, 0x19, 0x00, 0xb7,
-0x95, 0x02, 0x39, 0x91, 0x0b, 0x0e, 0xfe, 0x38, 0x2e, 0xd1, 0x1d, 0x05, 0x9a, 0xf6, 0x4d, 0x3e,
-0x6f, 0x0f, 0x07, 0x1d, 0xaf, 0x2c, 0x1e, 0x8f, 0x60, 0x39, 0xe2, 0xfa, 0x36, 0x53, 0x13, 0x39,
-0xd4, 0x5e, 0x26, 0x2b, 0xdb, 0x3d, 0xa8, 0x14, 0xbd, 0x32, 0xeb, 0x18, 0x03, 0x28, 0x52, 0x04,
-0x71, 0xe5, 0xab, 0x33, 0x3d, 0xe1, 0x38, 0xbb, 0x07, 0x36, 0x84, 0x62, 0x9c, 0x79, 0xea, 0x16,
-0x30, 0xf4, 0x5f, 0xc0, 0x2b, 0xe8, 0x71, 0x6b, 0xe4, 0xf9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
-0x53, 0x30, 0x51, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
-0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc0,
-0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8,
-0xca, 0xcc, 0x4e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
-0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65,
-0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x35, 0xe3, 0x29, 0x6a, 0xe5, 0x2f, 0x5d, 0x54,
-0x8e, 0x29, 0x50, 0x94, 0x9f, 0x99, 0x1a, 0x14, 0xe4, 0x8f, 0x78, 0x2a, 0x62, 0x94, 0xa2, 0x27,
-0x67, 0x9e, 0xd0, 0xcf, 0x1a, 0x5e, 0x47, 0xe9, 0xc1, 0xb2, 0xa4, 0xcf, 0xdd, 0x41, 0x1a, 0x05,
-0x4e, 0x9b, 0x4b, 0xee, 0x4a, 0x6f, 0x55, 0x52, 0xb3, 0x24, 0xa1, 0x37, 0x0a, 0xeb, 0x64, 0x76,
-0x2a, 0x2e, 0x2c, 0xf3, 0xfd, 0x3b, 0x75, 0x90, 0xbf, 0xfa, 0x71, 0xd8, 0xc7, 0x3d, 0x37, 0xd2,
-0xb5, 0x05, 0x95, 0x62, 0xb9, 0xa6, 0xde, 0x89, 0x3d, 0x36, 0x7b, 0x38, 0x77, 0x48, 0x97, 0xac,
-0xa6, 0x20, 0x8f, 0x2e, 0xa6, 0xc9, 0x0c, 0xc2, 0xb2, 0x99, 0x45, 0x00, 0xc7, 0xce, 0x11, 0x51,
-0x22, 0x22, 0xe0, 0xa5, 0xea, 0xb6, 0x15, 0x48, 0x09, 0x64, 0xea, 0x5e, 0x4f, 0x74, 0xf7, 0x05,
-0x3e, 0xc7, 0x8a, 0x52, 0x0c, 0xdb, 0x15, 0xb4, 0xbd, 0x6d, 0x9b, 0xe5, 0xc6, 0xb1, 0x54, 0x68,
-0xa9, 0xe3, 0x69, 0x90, 0xb6, 0x9a, 0xa5, 0x0f, 0xb8, 0xb9, 0x3f, 0x20, 0x7d, 0xae, 0x4a, 0xb5,
-0xb8, 0x9c, 0xe4, 0x1d, 0xb6, 0xab, 0xe6, 0x94, 0xa5, 0xc1, 0xc7, 0x83, 0xad, 0xdb, 0xf5, 0x27,
-0x87, 0x0e, 0x04, 0x6c, 0xd5, 0xff, 0xdd, 0xa0, 0x5d, 0xed, 0x87, 0x52, 0xb7, 0x2b, 0x15, 0x02,
-0xae, 0x39, 0xa6, 0x6a, 0x74, 0xe9, 0xda, 0xc4, 0xe7, 0xbc, 0x4d, 0x34, 0x1e, 0xa9, 0x5c, 0x4d,
-0x33, 0x5f, 0x92, 0x09, 0x2f, 0x88, 0x66, 0x5d, 0x77, 0x97, 0xc7, 0x1d, 0x76, 0x13, 0xa9, 0xd5,
-0xe5, 0xf1, 0x16, 0x09, 0x11, 0x35, 0xd5, 0xac, 0xdb, 0x24, 0x71, 0x70, 0x2c, 0x98, 0x56, 0x0b,
-0xd9, 0x17, 0xb4, 0xd1, 0xe3, 0x51, 0x2b, 0x5e, 0x75, 0xe8, 0xd5, 0xd0, 0xdc, 0x4f, 0x34, 0xed,
-0xc2, 0x05, 0x66, 0x80, 0xa1, 0xcb, 0xe6, 0x33,
-// Device
-0x30, 0x82, 0x01, 0x55, 0x30, 0x81, 0xFB, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30,
-0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x34, 0x31, 0x32, 0x30,
-0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x75, 0x75, 0x69, 0x64, 0x3A, 0x33, 0x32, 0x33,
-0x32, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D,
-0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33,
-0x32, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36, 0x30, 0x37, 0x32, 0x36, 0x31, 0x34, 0x31, 0x32, 0x32,
-0x31, 0x5A, 0x17, 0x0D, 0x31, 0x37, 0x30, 0x31, 0x30, 0x31, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30,
-0x5A, 0x30, 0x34, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x75, 0x75,
-0x69, 0x64, 0x3A, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32,
-0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x33,
-0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48,
-0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42,
-0x00, 0x04, 0x19, 0x1D, 0x6B, 0x4A, 0x12, 0xA7, 0x20, 0xF1, 0x95, 0xC6, 0x6D, 0x2A, 0xD7, 0x3B,
-0xFA, 0x90, 0x8C, 0x52, 0xEB, 0x75, 0x67, 0xFF, 0x0A, 0x3F, 0xF2, 0xDF, 0x8D, 0x81, 0x44, 0xC7,
-0xC8, 0x84, 0x60, 0xD4, 0x07, 0x57, 0xB1, 0x96, 0xAF, 0x5E, 0x00, 0xA5, 0xED, 0xA1, 0x48, 0x3F,
-0x88, 0x43, 0x8D, 0x15, 0x81, 0x0A, 0x21, 0x9B, 0x6C, 0xD3, 0xBD, 0x85, 0x86, 0xE1, 0xA6, 0xDA,
-0xC5, 0xCE, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x49,
-0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xF7, 0x8E, 0x43, 0x19, 0xD2, 0x86, 0xF9, 0x21, 0x84, 0x66,
-0x23, 0x4B, 0x18, 0x7C, 0x56, 0x18, 0x37, 0x48, 0xDF, 0x16, 0x3B, 0x70, 0x52, 0x26, 0x62, 0xB3,
-0xAA, 0xD8, 0x3D, 0xE9, 0x43, 0xC3, 0x02, 0x21, 0x00, 0xD0, 0x16, 0xA4, 0x33, 0x7A, 0xE3, 0x7C,
-0x62, 0x88, 0x88, 0x7B, 0x76, 0x99, 0xBF, 0x2D, 0xDF, 0x6C, 0xF5, 0xD0, 0x5F, 0xBE, 0x4B, 0xAE,
-0xBA, 0xE5, 0xC0, 0x05, 0x26, 0xBC, 0x8B, 0x20, 0x84
-};
-const unsigned char own_cert[] = {
-0x30, 0x82, 0x01, 0x55, 0x30, 0x81, 0xFB, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30,
-0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x34, 0x31, 0x32, 0x30,
-0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x75, 0x75, 0x69, 0x64, 0x3A, 0x33, 0x32, 0x33,
-0x32, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D,
-0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33,
-0x32, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36, 0x30, 0x37, 0x32, 0x36, 0x31, 0x34, 0x31, 0x32, 0x32,
-0x31, 0x5A, 0x17, 0x0D, 0x31, 0x37, 0x30, 0x31, 0x30, 0x31, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30,
-0x5A, 0x30, 0x34, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x75, 0x75,
-0x69, 0x64, 0x3A, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32,
-0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x33,
-0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48,
-0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42,
-0x00, 0x04, 0x19, 0x1D, 0x6B, 0x4A, 0x12, 0xA7, 0x20, 0xF1, 0x95, 0xC6, 0x6D, 0x2A, 0xD7, 0x3B,
-0xFA, 0x90, 0x8C, 0x52, 0xEB, 0x75, 0x67, 0xFF, 0x0A, 0x3F, 0xF2, 0xDF, 0x8D, 0x81, 0x44, 0xC7,
-0xC8, 0x84, 0x60, 0xD4, 0x07, 0x57, 0xB1, 0x96, 0xAF, 0x5E, 0x00, 0xA5, 0xED, 0xA1, 0x48, 0x3F,
-0x88, 0x43, 0x8D, 0x15, 0x81, 0x0A, 0x21, 0x9B, 0x6C, 0xD3, 0xBD, 0x85, 0x86, 0xE1, 0xA6, 0xDA,
-0xC5, 0xCE, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x49,
-0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xF7, 0x8E, 0x43, 0x19, 0xD2, 0x86, 0xF9, 0x21, 0x84, 0x66,
-0x23, 0x4B, 0x18, 0x7C, 0x56, 0x18, 0x37, 0x48, 0xDF, 0x16, 0x3B, 0x70, 0x52, 0x26, 0x62, 0xB3,
-0xAA, 0xD8, 0x3D, 0xE9, 0x43, 0xC3, 0x02, 0x21, 0x00, 0xD0, 0x16, 0xA4, 0x33, 0x7A, 0xE3, 0x7C,
-0x62, 0x88, 0x88, 0x7B, 0x76, 0x99, 0xBF, 0x2D, 0xDF, 0x6C, 0xF5, 0xD0, 0x5F, 0xBE, 0x4B, 0xAE,
-0xBA, 0xE5, 0xC0, 0x05, 0x26, 0xBC, 0x8B, 0x20, 0x84
-};
-const unsigned char ca_key[] = {
-0x30, 0x81, 0x93, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
-0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x04, 0x79, 0x30, 0x77, 0x02,
-0x01, 0x01, 0x04, 0x20, 0xe9, 0xe4, 0x27, 0xb2, 0x5c, 0xe1, 0xe9, 0xc4, 0x9d, 0x23, 0x55, 0x67,
-0x08, 0x66, 0x0c, 0xe5, 0x83, 0xa9, 0xf1, 0xe2, 0x09, 0xfb, 0x89, 0xea, 0xa8, 0xe4, 0x46, 0x6e,
-0x76, 0xff, 0x75, 0x02, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
-0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x19, 0x1d, 0x6b, 0x4a, 0x12, 0xa7, 0x20, 0xf1, 0x95, 0xc6,
-0x6d, 0x2a, 0xd7, 0x3b, 0xfa, 0x90, 0x8c, 0x52, 0xeb, 0x75, 0x67, 0xff, 0x0a, 0x3f, 0xf2, 0xdf,
-0x8d, 0x81, 0x44, 0xc7, 0xc8, 0x84, 0x60, 0xd4, 0x07, 0x57, 0xb1, 0x96, 0xaf, 0x5e, 0x00, 0xa5,
-0xed, 0xa1, 0x48, 0x3f, 0x88, 0x43, 0x8d, 0x15, 0x81, 0x0a, 0x21, 0x9b, 0x6c, 0xd3, 0xbd, 0x85,
-0x86, 0xe1, 0xa6, 0xda, 0xc5, 0xce
-};
-void GetDerOwnCert(OicSecCert_t * crt)
+
+void InitCipherSuiteListInternal(bool * list, const char * usage)
 {
-    crt->data = OICMalloc(sizeof(own_cert));
-    memcpy(crt->data, own_cert, sizeof(own_cert));
-    crt->len = sizeof(own_cert);
-    return;
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (NULL == list || NULL == usage)
+    {
+        OIC_LOG(DEBUG, TAG, "NULL passed");
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return;
+    }
+    OicSecCred_t * temp = NULL;
+    LL_FOREACH(gCred, temp)
+    {
+        switch (temp->credType)
+        {
+            case PIN_PASSWORD:
+            {
+                list[0] = true;
+                OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
+                break;
+            }
+            case SYMMETRIC_PAIR_WISE_KEY:
+            {
+                list[0] = true;
+                OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
+                break;
+            }
+            case SIGNED_ASYMMETRIC_KEY:
+            {
+                if (0 == strcmp(temp->credUsage, usage))
+                {
+                    list[1] = true;
+                    OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
+                }
+                break;
+            }
+            case SYMMETRIC_GROUP_KEY:
+            case ASYMMETRIC_KEY:
+            case ASYMMETRIC_ENCRYPTION_KEY:
+            {
+                OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
+                break;
+            }
+            default:
+            {
+                OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
+                break;
+            }
+        }
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
-void GetDerCaCert(OicSecCert_t * crt)
+#endif
+
+
+//Added as workaround by Chul Lee
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
+                                            OicEncodingType_t encodingType,  const char* usage, uint16_t *credId)
 {
-    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
-    VERIFY_NON_NULL(TAG, crt, ERROR);
-    if (NULL == gCred)
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
     {
-        VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
+        OIC_LOG_V(ERROR, TAG, "Invaild param");
+        return OC_STACK_INVALID_PARAM;
     }
 
-    OicUuid_t  subject;
-    OCStackResult ret = ConvertStrToUuid(CA_SUBJECT_ID, &subject);
-    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+    OCStackResult res = OC_STACK_ERROR;
+    OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    if(NULL == cred)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    cred->credId = 0;
+    memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
 
-    OicSecCred_t * cred  = GetCredResourceData(&subject);
-    VERIFY_NON_NULL(TAG, cred, ERROR);
+    cred->credUsage = OICStrdup(usage);
+    if (NULL == cred->credUsage)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
 
-    INIT_BYTE_ARRAY(*crt);
-    crt->data = (uint8_t *) OICCalloc(1, cred->publicData.len);
-    VERIFY_NON_NULL(TAG, cred, ERROR);
+    cred->credType = SIGNED_ASYMMETRIC_KEY;
 
-    memcpy(crt->data, cred->publicData.data, cred->publicData.len);
-    crt->len = cred->publicData.len;
+    if (encodingType == OIC_ENCODING_PEM)
+    {
+        cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
+        if(NULL == cred->optionalData.data)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+            res = OC_STACK_NO_MEMORY;
+            goto error;
+        }
+        cred->optionalData.len = chainSize + 1;
+    }
+    else
+    {
+        cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
+        if(NULL == cred->optionalData.data)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+            res = OC_STACK_NO_MEMORY;
+            goto error;
+        }
+        cred->optionalData.len = chainSize;
+    }
+    memcpy(cred->optionalData.data, trustCertChain, chainSize);
+    cred->optionalData.encoding = encodingType;
+    cred->optionalData.revstat = false;
 
-exit:
-    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    res = AddCredential(cred);
+    if(res != OC_STACK_OK)
+    {
+        goto error;
+    }
+    *credId = cred->credId;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return res;
+
+error:
+    DeleteCredList(cred);
+    OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
+    return res;
 }
-void GetDerKey(ByteArray * key)
+
+OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
+                                    const char* usage, uint16_t *credId)
 {
-    key->data = OICMalloc(sizeof(ca_key));
-    memcpy(key->data, ca_key, sizeof(ca_key));
-    key->len = sizeof(ca_key);
-    return;
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
+       NULL == credId || NULL == usage || NULL == subject)
+    {
+        OIC_LOG_V(ERROR, TAG, "Invalid param");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCStackResult res = OC_STACK_ERROR;
+    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
+    if(NULL == cred)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    cred->credId = 0;
+    memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
+
+    cred->credUsage = OICStrdup(usage);
+    if (NULL == cred->credUsage)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+
+    cred->credType = SIGNED_ASYMMETRIC_KEY;
+
+    OicSecKey_t *publicData = &cred->publicData;
+    publicData->data = (uint8_t *)OICCalloc(1, cert->len);
+    if(NULL == publicData->data)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    memcpy(publicData->data, cert->data, cert->len);
+    publicData->encoding = cert->encoding;
+    publicData->len = cert->len;
+
+    OicSecKey_t *privateData = &cred->privateData;
+    privateData->data = (uint8_t *)OICCalloc(1, key->len);
+    if(NULL == privateData->data)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    memcpy(privateData->data, key->data, key->len);
+    privateData->len = key->len;
+    privateData->encoding = key->encoding;
+
+    res = AddCredential(cred);
+    if(res != OC_STACK_OK)
+    {
+        goto error;
+    }
+    *credId = cred->credId;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return res;
+
+error:
+    DeleteCredList(cred);
+    OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
+    return res;
 }
-#endif
+
+#endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)