Imported Upstream version 1.0.0
[platform/upstream/iotivity.git] / resource / csdk / security / src / credresource.c
old mode 100755 (executable)
new mode 100644 (file)
index af21b26..e7235b5
 #include "base64.h"
 #include "srmutility.h"
 #include "cainterface.h"
+#include "pbkdf2.h"
 #include <stdlib.h>
+#include "iotvticalendar.h"
+#ifdef WITH_ARDUINO
 #include <string.h>
+#else
+#include <strings.h>
+#endif
 #include <stdint.h>
 
+#define TAG  "SRM-CREDL"
 
-#define TAG  PCF("SRM-CREDL")
 
 static OicSecCred_t        *gCred = NULL;
 static OCResourceHandle    gCredHandle = NULL;
 
-void DeleteCredList(OicSecCred_t* cred)
+/**
+ * This function frees OicSecCred_t object's fields and object itself.
+ */
+static void FreeCred(OicSecCred_t *cred)
 {
-    if (cred)
+    if(NULL == cred)
     {
-        OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
-        LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
-        {
-            LL_DELETE(cred, credTmp1);
-
-            //Note: Need further clarification on roleID data type
+        OC_LOG (ERROR, TAG, "Invalid Parameter");
+        return;
+    }
+    //Note: Need further clarification on roleID data type
 #if 0
-            //Clean roleIds
-            OICFree(credTmp1->roleIds);
+    //Clean roleIds
+    OICFree(cred->roleIds);
 #endif
 
-            //Clean PublicData
-            OICFree(credTmp1->publicData.data);
+    //Clean PublicData
+    OICFree(cred->publicData.data);
+
+    //Clean PrivateData
+    OICFree(cred->privateData.data);
 
-            //Clean PrivateData
-            OICFree(credTmp1->privateData.data);
+    //Clean Period
+    OICFree(cred->period);
 
-            //Clean Period
-            OICFree(credTmp1->period);
+    //Clean Owners
+    OICFree(cred->owners);
 
-            //Clean Owners
-            OICFree(credTmp1->owners);
+    //Clean Cred node itself
+    OICFree(cred);
+}
 
-            //Clean Cred node itself
-            OICFree(credTmp1);
+void DeleteCredList(OicSecCred_t* cred)
+{
+    if (cred)
+    {
+        OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
+        LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
+        {
+            LL_DELETE(cred, credTmp1);
+            FreeCred(credTmp1);
         }
     }
 }
@@ -141,17 +159,37 @@ char * BinToCredJSON(const OicSecCred_t * cred)
             //CredType -- Mandatory
             cJSON_AddNumberToObject(jsonCred, OIC_JSON_CREDTYPE_NAME,(int)cred->credType);
 
-#if 0
+#ifdef __WITH_X509__
             //PublicData -- Not Mandatory
             if(cred->publicData.data)
             {
+                if (SIGNED_ASYMMETRIC_KEY == cred->credType)
+                {
+                    cJSON_AddItemToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME,
+                                          cJSON_Parse(cred->publicData.data));
+                }
+                else
+                {
                 cJSON_AddStringToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME, cred->publicData.data);
+                }
             }
-#endif
+#endif /*__WITH_X509__*/
             //PrivateData -- Not Mandatory
             if(cred->privateData.data)
             {
+#ifdef __WITH_X509__
+                if (SIGNED_ASYMMETRIC_KEY == cred->credType)
+                {
+                    cJSON_AddItemToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME,
+                                          cJSON_Parse(cred->privateData.data));
+                }
+                else
+                {
+                    cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data);
+                }
+#else
                 cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data);
+#endif
             }
 
             //Period -- Not Mandatory
@@ -258,7 +296,7 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDTYPE_NAME);
             VERIFY_NON_NULL(TAG, jsonObj, ERROR);
             VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
-            cred->credType = jsonObj->valueint;
+            cred->credType = (OicSecCredType_t)jsonObj->valueint;
 
             //PrivateData is mandatory for some of the credential types listed below.
             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PRIVATEDATA_NAME);
@@ -269,12 +307,56 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
                 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
                 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
             }
-            if(jsonObj && cJSON_String == jsonObj->type)
+#ifdef __WITH_X509__
+            else if (cred->credType & SIGNED_ASYMMETRIC_KEY)
             {
-                jsonObjLen = strlen(jsonObj->valuestring) + 1;
-                cred->privateData.data = (char *)OICMalloc(jsonObjLen);
-                VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
-                strncpy((char *)cred->privateData.data, (char *)jsonObj->valuestring, jsonObjLen);
+                VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+                VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR);
+            }
+#endif //  __WITH_X509__
+            if (NULL != jsonObj)
+            {
+                if (cJSON_String == jsonObj->type)
+                {
+                    jsonObjLen = strlen(jsonObj->valuestring) + 1;
+                    cred->privateData.data = (char *)OICMalloc(jsonObjLen);
+                    VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
+                    strncpy((char *)cred->privateData.data, (char *)jsonObj->valuestring, jsonObjLen);
+                }
+#ifdef __WITH_X509__
+                else if (SIGNED_ASYMMETRIC_KEY == cred->credType && cJSON_Object == jsonObj->type)
+                {
+                    cred->privateData.data = cJSON_PrintUnformatted(jsonObj);
+                    VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
+                }
+#endif // __WITH_X509__
+            }
+
+            //PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type.
+            jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PUBLICDATA_NAME);
+#ifdef __WITH_X509__
+            if (cred->credType & SIGNED_ASYMMETRIC_KEY)
+            {
+                VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+                VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR);
+            }
+#endif //  __WITH_X509__
+            if (NULL != jsonObj)
+            {
+                if (cJSON_String == jsonObj->type)
+                {
+                    jsonObjLen = strlen(jsonObj->valuestring) + 1;
+                    cred->publicData.data = (char *)OICMalloc(jsonObjLen);
+                    VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR);
+                    strncpy((char *)cred->publicData.data, (char *)jsonObj->valuestring, jsonObjLen);
+                }
+#ifdef __WITH_X509__
+                else if (SIGNED_ASYMMETRIC_KEY == cred->credType && cJSON_Object == jsonObj->type)
+                {
+                    cred->publicData.data = cJSON_PrintUnformatted(jsonObj);
+                    VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR);
+                }
+#endif //  __WITH_X509__
             }
 
             //Period -- Not Mandatory
@@ -290,7 +372,7 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
             //Owners -- Mandatory
             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_OWNERS_NAME);
             VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-            VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR)
+            VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
             cred->ownersLen = cJSON_GetArraySize(jsonObj);
             VERIFY_SUCCESS(TAG, cred->ownersLen > 0, ERROR);
             cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
@@ -343,6 +425,7 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
                                  const char * publicData, const char * privateData,
                                  size_t ownersLen, const OicUuid_t * owners)
 {
+    (void)publicData;
     OCStackResult ret = OC_STACK_ERROR;
 
     OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
@@ -359,14 +442,14 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
             SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
     cred->credType = credType;
 
-#if 0
+#ifdef __WITH_X509__
     if(publicData)
     {
         cred->publicData.data = (char *)OICMalloc(strlen(publicData)+1);
         VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
         strncpy((char *)cred->publicData.data, publicData, strlen(publicData)+1);
     }
-#endif
+#endif // __WITH_X509__
 
     if(privateData)
     {
@@ -395,7 +478,35 @@ exit:
     return cred;
 }
 
-/*
+static bool UpdatePersistentStorage(const OicSecCred_t *cred)
+{
+    bool ret = false;
+
+    // Convert Cred data into JSON for update to persistent storage
+    char *jsonStr = BinToCredJSON(cred);
+    if (jsonStr)
+    {
+        cJSON *jsonCred = cJSON_Parse(jsonStr);
+        OICFree(jsonStr);
+
+        if ((jsonCred) &&
+          (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRED_NAME, jsonCred)))
+        {
+            ret = true;
+        }
+        cJSON_Delete(jsonCred );
+    }
+    else //Empty cred list
+    {
+        if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRED_NAME, NULL))
+        {
+            ret = true;
+        }
+    }
+    return ret;
+}
+
+/**
  * Compare function used LL_SORT for sorting credentials
  *
  * @param first   pointer to OicSecCred_t struct
@@ -458,6 +569,8 @@ static uint16_t GetCredId()
 exit:
     return 0;
 }
+
+
 /**
  * This function adds the new cred to the credential list.
  *
@@ -470,7 +583,6 @@ exit:
 OCStackResult AddCredential(OicSecCred_t * newCred)
 {
     OCStackResult ret = OC_STACK_ERROR;
-    char * jsonStr = NULL;
 
     VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
 
@@ -482,23 +594,41 @@ OCStackResult AddCredential(OicSecCred_t * newCred)
     //Append the new Cred to existing list
     LL_APPEND(gCred, newCred);
 
-    //Convert CredList to JSON and update the persistent Storage
-    jsonStr = BinToCredJSON(gCred);
-
-    if(jsonStr)
+    if(UpdatePersistentStorage(gCred))
     {
-        cJSON *jsonCred = cJSON_Parse(jsonStr);
-        OICFree(jsonStr);
+        ret = OC_STACK_OK;
+    }
+
+exit:
+    return ret;
+}
 
-        if((jsonCred) && (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRED_NAME, jsonCred)))
+OCStackResult RemoveCredential(const OicUuid_t *subject)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    OicSecCred_t *cred = NULL;
+    OicSecCred_t *tempCred = NULL;
+    bool deleteFlag = false;
+
+    LL_FOREACH_SAFE(gCred, cred, tempCred)
+    {
+        if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
         {
-            ret = OC_STACK_OK;
+            LL_DELETE(gCred, cred);
+            FreeCred(cred);
+            deleteFlag = 1;
         }
-        cJSON_Delete(jsonCred);
     }
 
-exit:
+    if(deleteFlag)
+    {
+        if(UpdatePersistentStorage(gCred))
+        {
+            ret = OC_STACK_RESOURCE_DELETED;
+        }
+    }
     return ret;
+
 }
 
 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
@@ -516,10 +646,51 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
         //list and updating svr database.
         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
     }
-
     return ret;
 }
 
+static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
+{
+    OC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
+
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+    if(NULL == ehRequest->query)
+   {
+       return ehRet;
+   }
+
+   OicParseQueryIter_t parseIter = {.attrPos=NULL};
+   OicUuid_t subject = {.id={0}};
+
+   //Parsing REST query to get the subject
+   ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
+   while(GetNextQuery(&parseIter))
+   {
+       if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME,
+               parseIter.attrLen) == 0)
+       {
+           unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
+           uint32_t outLen = 0;
+           B64Result b64Ret = B64_OK;
+
+           b64Ret = b64Decode((char *)parseIter.valPos, parseIter.valLen,
+                   base64Buff, sizeof(base64Buff), &outLen);
+
+           VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(subject.id)), ERROR);
+           memcpy(subject.id, base64Buff, outLen);
+       }
+   }
+
+   if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
+   {
+       ehRet = OC_EH_RESOURCE_DELETED;
+   }
+
+exit:
+    return ehRet;
+}
+
 /*
  * This internal method is the entity handler for Cred resources
  * to handle REST request (PUT/POST/DEL)
@@ -528,6 +699,7 @@ OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag,
                                         OCEntityHandlerRequest * ehRequest,
                                         void* callbackParameter)
 {
+    (void)callbackParameter;
     OCEntityHandlerResult ret = OC_EH_ERROR;
 
     if(!ehRequest)
@@ -536,7 +708,7 @@ OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag,
     }
     if (flag & OC_REQUEST_FLAG)
     {
-        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+        OC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
         //TODO :  Handle PUT/DEL methods
         switch(ehRequest->method)
         {
@@ -546,6 +718,9 @@ OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag,
             case OC_REST_POST:
                 ret = HandlePostRequest(ehRequest);
                 break;
+            case OC_REST_DELETE:
+                ret = HandleDeleteRequest(ehRequest);
+                break;
             default:
                 ret = OC_EH_ERROR;
                 break;
@@ -576,7 +751,7 @@ OCStackResult CreateCredResource()
 
     if (OC_STACK_OK != ret)
     {
-        OC_LOG (FATAL, TAG, PCF("Unable to instantiate Cred resource"));
+        OC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
         DeInitCredResource();
     }
     return ret;
@@ -655,16 +830,16 @@ const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
 {
     OicSecCred_t *cred = NULL;
 
-    if ( NULL == subject)
+   if ( NULL == subject)
     {
-        return NULL;
+       return NULL;
     }
 
     LL_FOREACH(gCred, cred)
     {
         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
         {
-             return cred;
+            return cred;
         }
     }
     return NULL;
@@ -676,78 +851,313 @@ const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
  * This internal callback is used by lower stack (i.e. CA layer) to
  * retrieve PSK credentials from RI security layer.
  *
- * Note: When finished, caller should initialize memory to zeros and
- * invoke OICFree to delete @p credInfo.
- *
- * @param credInfo
- *     binary blob containing PSK credentials
+ * @param[in]  type type of PSK data required by tinyDTLS layer during DTLS handshake.
+ * @param[in]  desc Additional request information.
+ * @param[in]  desc_len The actual length of desc.
+ * @param[out] result  Must be filled with the requested information.
+ * @param[in]  result_length  Maximum size of @p result.
  *
- * @retval none
+ * @return The number of bytes written to @p result or a value
+ *         less than zero on error.
  */
-void GetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
+int32_t GetDtlsPskCredentials( CADtlsPskCredType_t type,
+              const unsigned char *desc, size_t desc_len,
+              unsigned char *result, size_t result_length)
 {
-    CADtlsPskCredsBlob_t * caBlob = NULL;
-    if(credInfo)
-    {
-        caBlob = (CADtlsPskCredsBlob_t *)OICCalloc(sizeof(CADtlsPskCredsBlob_t), 1);
-        if (caBlob)
-        {
-            OicUuid_t deviceID = {};
+    int32_t ret = -1;
 
-            // Retrieve Device ID from doxm resource and copy in PSK creds blob
-            VERIFY_SUCCESS(TAG, GetDoxmDeviceID(&deviceID) == OC_STACK_OK, ERROR);
-            memcpy(caBlob->identity, deviceID.id, sizeof(caBlob->identity));
+    if (NULL == result)
+    {
+        return ret;
+    }
 
-            OicSecCred_t *cred = NULL;
-            size_t count = 0;
-            LL_FOREACH(gCred, cred)
+    switch (type)
+    {
+        case CA_DTLS_PSK_HINT:
+        case CA_DTLS_PSK_IDENTITY:
             {
-                // Currently, Iotivity supports only symmetric pair wise key credentials
-                if (cred->credType == SYMMETRIC_PAIR_WISE_KEY)
+                OicUuid_t deviceID = {.id={}};
+                // Retrieve Device ID from doxm resource
+                if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
+                {
+                    OC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
+                    return ret;
+                }
+
+                if (result_length < sizeof(deviceID.id))
                 {
-                    ++count;
+                    OC_LOG (ERROR, TAG, "Wrong value for result_length");
+                    return ret;
                 }
+                memcpy(result, deviceID.id, sizeof(deviceID.id));
+                return (sizeof(deviceID.id));
             }
-            caBlob->num = count;
-            if (caBlob->num)
-            {
-                caBlob->creds =
-                    (OCDtlsPskCreds*) OICMalloc(caBlob->num * sizeof(OCDtlsPskCreds));
-                VERIFY_NON_NULL(TAG, caBlob->creds, ERROR);
+            break;
 
-                unsigned int i = 0;
+        case CA_DTLS_PSK_KEY:
+            {
+                OicSecCred_t *cred = NULL;
                 LL_FOREACH(gCred, cred)
                 {
-                    if ((cred->credType == SYMMETRIC_PAIR_WISE_KEY) &&
-                            (i < count))
-
+                    if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
                     {
-                        // Copy subject ID
-                        memcpy(caBlob->creds[i].id, cred->subject.id,
-                                sizeof(caBlob->creds[i].id));
+                        continue;
+                    }
 
-                        // Convert PSK from JSON to binary before copying
+                    if ((desc_len == sizeof(cred->subject.id)) &&
+                        (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
+                    {
+                        /*
+                         * If the credentials are valid for limited time,
+                         * check their expiry.
+                         */
+                        if (cred->period)
+                        {
+                            if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
+                            {
+                                OC_LOG (INFO, TAG, "Credentials are expired.");
+                                ret = -1;
+                                return ret;
+                            }
+                        }
+
+                        // Convert PSK from Base64 encoding to binary before copying
                         uint32_t outLen = 0;
                         B64Result b64Ret = b64Decode(cred->privateData.data,
-                                strlen(cred->privateData.data), caBlob->creds[i].psk,
-                                sizeof(caBlob->creds[i].psk), &outLen);
-                        VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
-                        i++;
+                                strlen(cred->privateData.data), result,
+                                result_length, &outLen);
+                        if (B64_OK != b64Ret)
+                        {
+                            OC_LOG (ERROR, TAG, "Base64 decoding failed.");
+                            ret = -1;
+                            return ret;
+                        }
+                        return outLen;
                     }
                 }
             }
+            break;
+
+        default:
+            {
+                OC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
+                ret = -1;
+            }
+            break;
+    }
+
+    return ret;
+}
+
+/**
+ * Add temporal PSK to PIN based OxM
+ *
+ * @param[in] tmpSubject UUID of target device
+ * @param[in] credType Type of credential to be added
+ * @param[in] pin numeric characters
+ * @param[in] pinSize length of 'pin'
+ * @param[in] ownersLen Number of owners
+ * @param[in] owners Array of owners
+ * @param[out] tmpCredSubject Generated credential's subject.
+ *
+ * @return OC_STACK_OK for success and errorcode otherwise.
+ */
+OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
+                            const char * pin, size_t pinSize,
+                            size_t ownersLen, const OicUuid_t * owners, OicUuid_t* tmpCredSubject)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    if(tmpSubject == NULL || pin == NULL || pinSize == 0 || tmpCredSubject == NULL)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
+    int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, owners->id,
+                                              UUID_LENGTH, PBKDF_ITERATIONS,
+                                              OWNER_PSK_LENGTH_128, privData);
+    VERIFY_SUCCESS(TAG, (dtlsRes == 0) , ERROR);
+
+    uint32_t outLen = 0;
+    char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {};
+    B64Result b64Ret = b64Encode(privData, OWNER_PSK_LENGTH_128, base64Buff,
+                                sizeof(base64Buff), &outLen);
+    VERIFY_SUCCESS(TAG, (B64_OK == b64Ret), ERROR);
+
+    OicSecCred_t* cred = GenerateCredential(tmpSubject, credType, NULL,
+                                            base64Buff, ownersLen, owners);
+    if(NULL == cred)
+    {
+        OC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
+        return OC_STACK_ERROR;
+    }
+
+    memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
+
+    ret = AddCredential(cred);
+    if( OC_STACK_OK != ret)
+    {
+        OC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
+    }
+
+exit:
+    return ret;
+}
+
+#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 void WriteCertPrefix(uint8_t *prefix, uint32_t certLen)
+{
+    for (size_t i = 0; i < CERT_LEN_PREFIX; ++i)
+    {
+        prefix[i] = (certLen >> (BYTE_SIZE * (CERT_LEN_PREFIX - 1 - i))) & 0xFF;
+    }
+}
+
+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));
         }
-        *credInfo = caBlob;
-        // Return from here after making the credential list
-        return;
     }
+    return res;
+}
+
+static uint32_t appendCert2Chain(uint8_t *appendPoint, char *cert, uint32_t max_len)
+{
+    uint32_t ret = 0;
+    VERIFY_NON_NULL(TAG, appendPoint, ERROR);
+    VERIFY_NON_NULL(TAG, cert, ERROR);
+
+    uint32_t certLen;
+    VERIFY_SUCCESS(TAG, B64_OK == b64Decode(cert, strlen(cert), appendPoint + CERT_LEN_PREFIX,
+                                            max_len - CERT_LEN_PREFIX, &certLen), ERROR);
+    WriteCertPrefix(appendPoint, certLen);
 
+    ret = certLen + CERT_LEN_PREFIX;
 exit:
-    if (caBlob)
+    return ret;
+}
+
+static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo){
+    OCStackResult ret = OC_STACK_ERROR;
+    uint8_t *ccPtr = credInfo->certificateChain;
+    for(uint32_t i =0; i < credInfo->chainLen - 1; ++i)
     {
-        memset(caBlob->creds, 0, caBlob->num * sizeof(OCDtlsPskCreds));
-        OICFree(caBlob->creds);
+        ccPtr += CERT_LEN_PREFIX + ParseCertPrefix(ccPtr);
     }
-    OICFree(caBlob);
+
+    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;
 }
-#endif /* __WITH_DTLS__ */
+
+static OCStackResult GetCertCredPublicData(CADtlsX509Creds_t *credInfo, OicSecCred_t *cred)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    VERIFY_NON_NULL(TAG, credInfo, ERROR);
+    VERIFY_NON_NULL(TAG, cred, ERROR);
+    VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
+    //VERIFY_SUCCESS(TAG, NULL == credInfo->certificateChain.data, ERROR);
+    cJSON *jsonRoot = cJSON_Parse(cred->publicData.data);
+    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+    //Get certificate chain
+    cJSON *jsonObj = cJSON_GetObjectItem(jsonRoot, CERTIFICATE);//TODO define field names constants
+    VERIFY_SUCCESS(TAG, NULL != jsonObj && cJSON_Array == jsonObj->type, ERROR);
+
+    size_t certChainLen = cJSON_GetArraySize(jsonObj);
+    credInfo->chainLen = certChainLen;
+    VERIFY_SUCCESS(TAG, MAX_CHAIN_LEN >= certChainLen, ERROR);
+
+    uint32_t len = 0;
+    for (size_t i = 0; i < certChainLen; ++i)
+    {
+        cJSON *item = cJSON_GetArrayItem(jsonObj, i);
+        VERIFY_SUCCESS(TAG, cJSON_String == item->type, ERROR);
+        uint32_t appendedLen = appendCert2Chain(credInfo->certificateChain + len, item->valuestring,
+                                              MAX_CERT_MESSAGE_LEN - len);
+        VERIFY_SUCCESS(TAG, 0 != appendedLen, ERROR);
+        len += appendedLen;
+    }
+    credInfo->certificateChainLen = len;
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCAPublicKeyData(credInfo), ERROR);
+    ret = OC_STACK_OK;
+exit:
+    cJSON_Delete(jsonRoot);
+    return ret;
+}
+
+static OCStackResult GetCertCredPrivateData(CADtlsX509Creds_t *credInfo, OicSecCred_t *cred)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    VERIFY_NON_NULL(TAG, credInfo, ERROR);
+    VERIFY_NON_NULL(TAG, cred, ERROR);
+    VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
+    cJSON *jsonRoot = cJSON_Parse(cred->privateData.data);
+    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+    cJSON *jsonObj = cJSON_GetObjectItem(jsonRoot, PRIVATE_KEY);//TODO define field names constants
+    VERIFY_SUCCESS(TAG, NULL != jsonObj && cJSON_String == jsonObj->type, ERROR);
+
+    uint32_t read = 0u;
+    VERIFY_SUCCESS(TAG, B64_OK == b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring),
+                                            credInfo->devicePrivateKey, PRIVATE_KEY_SIZE, &read)
+                   && PRIVATE_KEY_SIZE == read, ERROR);
+
+    ret = OC_STACK_OK;
+
+exit:
+    cJSON_Delete(jsonRoot);
+    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);
+
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPrivateData(credInfo, cred), ERROR);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPublicData(credInfo, cred), ERROR);
+
+    ret = 0;
+exit:
+
+    return ret;
+}
+#undef CERT_LEN_PREFIX
+#endif /* __WITH_X509__ */