Imported Upstream version 1.0.0
[platform/upstream/iotivity.git] / resource / csdk / security / src / doxmresource.c
old mode 100755 (executable)
new mode 100644 (file)
index 5389595..cb2bd37
 #include "credresource.h"
 #include "ocserverrequest.h"
 #include "srmutility.h"
+#include "pinoxmcommon.h"
+
+#ifdef __WITH_DTLS__
+#include "global.h"
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 
@@ -41,7 +47,7 @@
 #include <strings.h>
 #endif
 
-#define TAG  PCF("SRM-DOXM")
+#define TAG  "SRM-DOXM"
 
 static OicSecDoxm_t        *gDoxm = NULL;
 static OCResourceHandle    gDoxmHandle = NULL;
@@ -54,9 +60,10 @@ static OicSecDoxm_t gDefaultDoxm =
     &gOicSecDoxmJustWorks,  /* uint16_t *oxm */
     1,                      /* size_t oxmLen */
     OIC_JUST_WORKS,         /* uint16_t oxmSel */
+    SYMMETRIC_PAIR_WISE_KEY,/* OicSecCredType_t sct */
     false,                  /* bool owned */
-    {},                     /* OicUuid_t deviceID */
-    {},                     /* OicUuid_t owner */
+    {.id = {0}},            /* OicUuid_t deviceID */
+    {.id = {0}},            /* OicUuid_t owner */
 };
 
 void DeleteDoxmBinData(OicSecDoxm_t* doxm)
@@ -64,7 +71,7 @@ void DeleteDoxmBinData(OicSecDoxm_t* doxm)
     if (doxm)
     {
         //Clean oxmType
-        for(int i = 0; i < doxm->oxmTypeLen; i++)
+        for (size_t i = 0; i < doxm->oxmTypeLen; i++)
         {
             OICFree(doxm->oxmType[i]);
         }
@@ -125,6 +132,9 @@ char * BinToDoxmJSON(const OicSecDoxm_t * doxm)
     //OxmSel -- Mandatory
     cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_OXM_SEL_NAME, (int)doxm->oxmSel);
 
+    //sct -- Mandatory
+    cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_SUPPORTED_CRED_TYPE_NAME, (int)doxm->sct);
+
     //Owned -- Mandatory
     cJSON_AddBoolToObject(jsonDoxm, OIC_JSON_OWNED_NAME, doxm->owned);
 
@@ -195,7 +205,7 @@ OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr)
         doxm->oxmType = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(char *));
         VERIFY_NON_NULL(TAG, (doxm->oxmType), ERROR);
 
-        for(int i  = 0; i < doxm->oxmTypeLen ; i++)
+        for (size_t i  = 0; i < doxm->oxmTypeLen ; i++)
         {
             cJSON *jsonOxmTy = cJSON_GetArrayItem(jsonObj, i);
             VERIFY_NON_NULL(TAG, jsonOxmTy, ERROR);
@@ -217,7 +227,7 @@ OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr)
         doxm->oxm = (OicSecOxm_t*)OICCalloc(doxm->oxmLen, sizeof(OicSecOxm_t));
         VERIFY_NON_NULL(TAG, doxm->oxm, ERROR);
 
-        for(int i  = 0; i < doxm->oxmLen ; i++)
+        for (size_t i  = 0; i < doxm->oxmLen ; i++)
         {
             cJSON *jsonOxm = cJSON_GetArrayItem(jsonObj, i);
             VERIFY_NON_NULL(TAG, jsonOxm, ERROR);
@@ -229,7 +239,7 @@ OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr)
     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_SEL_NAME);
     if(jsonObj)
     {
-        VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR)
+        VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
         doxm->oxmSel = (OicSecOxm_t)jsonObj->valueint;
     }
     else // PUT/POST JSON may not have oxmsel so set it to the gDoxm->oxmSel
@@ -238,11 +248,24 @@ OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr)
         doxm->oxmSel = gDoxm->oxmSel;
     }
 
+    //sct -- Mandatory
+    jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
+    if(jsonObj)
+    {
+        VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+        doxm->sct = (OicSecCredType_t)jsonObj->valueint;
+    }
+    else // PUT/POST JSON may not have sct so set it to the gDoxm->sct
+    {
+        VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+        doxm->sct = gDoxm->sct;
+    }
+
     //Owned -- Mandatory
     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNED_NAME);
     if(jsonObj)
     {
-        VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR)
+        VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR);
         doxm->owned = jsonObj->valueint;
     }
     else // PUT/POST JSON may not have owned so set it to the gDomx->owned
@@ -273,20 +296,22 @@ OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr)
     else // PUT/POST JSON will not have deviceID so set it to the gDoxm->deviceID.id
     {
         VERIFY_NON_NULL(TAG, gDoxm, ERROR);
-        VERIFY_SUCCESS(TAG, strcmp((char *)gDoxm->deviceID.id, "") != 0, ERROR);
-        strncpy((char *)doxm->deviceID.id, (char *)gDoxm->deviceID.id, sizeof(doxm->deviceID.id));
+        memcpy((char *)doxm->deviceID.id, (char *)gDoxm->deviceID.id, sizeof(doxm->deviceID.id));
     }
 
-    // Owner -- will be empty when device state is unowned.
-    if (true == doxm->owned)
+    //Owner -- will be empty when device status is unowned.
+    jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNER_NAME);
+    if(true == doxm->owned)
     {
-        jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNER_NAME);
         VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-        VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR)
-            outLen = 0;
+    }
+    if(jsonObj)
+    {
+        VERIFY_SUCCESS(TAG, (cJSON_String == jsonObj->type), ERROR);
+        outLen = 0;
         b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
                 sizeof(base64Buff), &outLen);
-        VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(doxm->owner.id)), ERROR);
+        VERIFY_SUCCESS(TAG, ((b64Ret == B64_OK) && (outLen <= sizeof(doxm->owner.id))), ERROR);
         memcpy(doxm->owner.id, base64Buff, outLen);
     }
 
@@ -332,7 +357,7 @@ static bool UpdatePersistentStorage(OicSecDoxm_t * doxm)
     return bRet;
 }
 
-static bool ValidateQuery(unsigned char * query)
+static bool ValidateQuery(const char * query)
 {
     // Send doxm resource data if the state of doxm resource
     // matches with the query parameters.
@@ -342,33 +367,60 @@ static bool ValidateQuery(unsigned char * query)
     // access rules. Eventually, the PE and PM code will
     // not send a request to the /doxm Entity Handler at all
     // if it should not respond.
-    OC_LOG (INFO, TAG, PCF("In ValidateQuery"));
+    OC_LOG (DEBUG, TAG, "In ValidateQuery");
     if(NULL == gDoxm)
     {
         return false;
     }
 
-    OicParseQueryIter_t parseIter = {};
+    bool bOwnedQry = false;         // does querystring contains 'owned' query ?
+    bool bOwnedMatch = false;       // does 'owned' query value matches with doxm.owned status?
+    bool bDeviceIDQry = false;      // does querystring contains 'deviceid' query ?
+    bool bDeviceIDMatch = false;    // does 'deviceid' query matches with doxm.deviceid ?
+
+    OicParseQueryIter_t parseIter = {.attrPos = NULL};
 
-    ParseQueryIterInit(query, &parseIter);
+    ParseQueryIterInit((unsigned char*)query, &parseIter);
 
     while(GetNextQuery(&parseIter))
     {
         if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_OWNED_NAME, parseIter.attrLen) == 0)
         {
+            bOwnedQry = true;
             if((strncasecmp((char *)parseIter.valPos, OIC_SEC_TRUE, parseIter.valLen) == 0) &&
                     (gDoxm->owned))
             {
-                return true;
+                bOwnedMatch = true;
             }
             else if((strncasecmp((char *)parseIter.valPos, OIC_SEC_FALSE, parseIter.valLen) == 0)
                     && (!gDoxm->owned))
             {
-                return true;
+                bOwnedMatch = true;
+            }
+        }
+
+        if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_DEVICE_ID_NAME, parseIter.attrLen) == 0)
+        {
+            bDeviceIDQry = true;
+            OicUuid_t subject = {.id={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, (B64_OK == b64Ret && outLen <= sizeof(subject.id)), ERROR);
+                       memcpy(subject.id, base64Buff, outLen);
+            if(0 == memcmp(&gDoxm->deviceID.id, &subject.id, sizeof(gDoxm->deviceID.id)))
+            {
+                bDeviceIDMatch = true;
             }
         }
     }
-    return false;
+
+exit:
+    return ((bOwnedQry ? bOwnedMatch : true) && (bDeviceIDQry ? bDeviceIDMatch : true));
 }
 
 static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest * ehRequest)
@@ -376,13 +428,13 @@ static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest
     char* jsonStr = NULL;
     OCEntityHandlerResult ehRet = OC_EH_OK;
 
-    OC_LOG (INFO, TAG, PCF("Doxm EntityHandle processing GET request"));
+    OC_LOG (DEBUG, TAG, "Doxm EntityHandle processing GET request");
 
     //Checking if Get request is a query.
     if(ehRequest->query)
     {
-        OC_LOG (INFO, TAG, PCF("HandleDoxmGetRequest processing query"));
-        if(!ValidateQuery((unsigned char *)ehRequest->query))
+        OC_LOG (DEBUG, TAG, "HandleDoxmGetRequest processing query");
+        if(!ValidateQuery(ehRequest->query))
         {
             ehRet = OC_EH_ERROR;
         }
@@ -400,7 +452,7 @@ static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest
     // Send response payload to request originator
     if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, jsonStr))
     {
-        OC_LOG (ERROR, TAG, PCF("SendSRMResponse failed in HandleDoxmGetRequest"));
+        OC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDoxmGetRequest");
     }
 
     OICFree(jsonStr);
@@ -408,12 +460,58 @@ static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest
     return ehRet;
 }
 
+#ifdef __WITH_DTLS__
+/*
+ * Generating new credential for provisioning tool
+ *
+ * PSK generated by
+ */
+static OCEntityHandlerResult AddOwnerPSK(const CAEndpoint_t* endpoint,
+                    OicSecDoxm_t* ptDoxm,
+                    const uint8_t* label, const size_t labelLen)
+{
+    size_t ownLen = 1;
+    uint32_t outLen = 0;
+    OicSecCred_t *cred = NULL;
+    uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {};
+
+    CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
+        label, labelLen,
+        ptDoxm->owner.id, sizeof(ptDoxm->owner.id),
+        gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id),
+        ownerPSK, OWNER_PSK_LENGTH_128);
+
+    VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
+
+    char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {};
+    B64Result b64Ret = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, base64Buff,
+                    sizeof(base64Buff), &outLen);
+    VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+
+    OC_LOG (DEBUG, TAG, "Doxm EntityHandle  generating Credential");
+    cred = GenerateCredential(&ptDoxm->owner, SYMMETRIC_PAIR_WISE_KEY,
+                              NULL, base64Buff, ownLen, &ptDoxm->owner);
+    VERIFY_NON_NULL(TAG, cred, ERROR);
+
+    //Adding provisioning tool credential to cred Resource.
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR);
+
+    gDoxm->owned = true;
+    gDoxm->oxmSel = ptDoxm->oxmSel;
+    memcpy(&(gDoxm->owner), &(ptDoxm->owner), sizeof(OicUuid_t));
+
+    return OC_EH_OK;
+
+exit:
+    return OC_EH_ERROR;
+}
+#endif //__WITH_DTLS__
 
 static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest)
 {
-    OC_LOG (INFO, TAG, PCF("Doxm EntityHandle  processing PUT request"));
+    OC_LOG (DEBUG, TAG, "Doxm EntityHandle  processing PUT request");
     OCEntityHandlerResult ehRet = OC_EH_ERROR;
-    OicUuid_t emptyOwner = {};
+    OicUuid_t emptyOwner = {.id = {0}};
 
     /*
      * Convert JSON Doxm data into binary. This will also validate
@@ -433,7 +531,7 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
              */
             if ((false == gDoxm->owned) && (false == newDoxm->owned))
             {
-                OC_LOG (INFO, TAG, PCF("Doxm EntityHandle  enabling AnonECDHCipherSuite"));
+                OC_LOG (INFO, TAG, "Doxm EntityHandle  enabling AnonECDHCipherSuite");
 #ifdef __WITH_DTLS__
                 ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
 #endif //__WITH_DTLS__
@@ -455,40 +553,16 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
                  *
                  */
 #ifdef __WITH_DTLS__
-                CAResult_t pskRet;
-
                 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
-                uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {};
 
                 //Generating OwnerPSK
-                OC_LOG (INFO, TAG, PCF("Doxm EntityHandle  generating OwnerPSK"));
-                pskRet = CAGenerateOwnerPSK((CAEndpoint_t *)&request->devAddr,
-                        (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS),
-                        newDoxm->owner.id, sizeof(newDoxm->owner.id),
-                        gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id),
-                        ownerPSK, OWNER_PSK_LENGTH_128);
+                OC_LOG (INFO, TAG, "Doxm EntityHandle  generating OwnerPSK");
 
-                VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
+                //Generate new credential for provisioning tool
+                ehRet = AddOwnerPSK((CAEndpoint_t *)&request->devAddr, newDoxm,
+                        (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS));
 
-                //Generating new credential for provisioning tool
-                size_t ownLen = 1;
-                uint32_t outLen = 0;
-
-                char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
-                B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff,
-                                sizeof(base64Buff), &outLen);
-                VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
-
-                OC_LOG (INFO, TAG, PCF("Doxm EntityHandle  generating Credential"));
-                OicSecCred_t *cred = GenerateCredential(&newDoxm->owner, SYMMETRIC_PAIR_WISE_KEY,
-                                        NULL, base64Buff, ownLen, &newDoxm->owner);
-                VERIFY_NON_NULL(TAG, cred, ERROR);
-
-                //Adding provisioning tool credential to cred Resource.
-                VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR);
-
-                gDoxm->owned = true;
-                memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+                VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
 
                 // Update new state in persistent storage
                 if (true == UpdatePersistentStorage(gDoxm))
@@ -504,6 +578,7 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
                      * for global variable.
                      */
                     gDoxm->owned = false;
+                    gDoxm->oxmSel = 0;
                     memset(&(gDoxm->owner), 0, sizeof(OicUuid_t));
                 }
 
@@ -512,8 +587,96 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
                  * in owned state.
                  */
                 CAEnableAnonECDHCipherSuite(false);
+#ifdef __WITH_X509__
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE
+                CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
+#endif //__WITH_X509__
+#endif //__WITH_DTLS__
+            }
+        }
+        else if(OIC_RANDOM_DEVICE_PIN == newDoxm->oxmSel)
+        {
+            //this temp Credential ID is used to track temporal Cred Id
+            static OicUuid_t tmpCredId = {.id={0}};
+            static bool tmpCredGenFlag = false;
+
+            if ((false == gDoxm->owned) && (false == newDoxm->owned))
+            {
+#ifdef __WITH_DTLS__
+                CAEnableAnonECDHCipherSuite(false);
+                OC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
+                CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
+
+                char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,};
+                if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1))
+                {
+                    if(tmpCredGenFlag)
+                    {
+                       OC_LOG(INFO, TAG, "Corrupted PSK is detected!!!");
+                       VERIFY_SUCCESS(TAG,
+                                      OC_STACK_RESOURCE_DELETED == RemoveCredential(&tmpCredId),
+                                      ERROR);
+                    }
+
+                    OCStackResult res = AddTmpPskWithPIN( &(newDoxm->owner), SYMMETRIC_PAIR_WISE_KEY,
+                                     ranPin, OXM_RANDOM_PIN_SIZE, 1, &(newDoxm->owner), &tmpCredId);
+                    VERIFY_SUCCESS(TAG, res == OC_STACK_OK, ERROR);
+                    tmpCredGenFlag = true;
+                    ehRet = OC_EH_OK;
+                }
+                else
+                {
+                    OC_LOG(ERROR, TAG, "Failed to generate random PIN");
+                    ehRet = OC_EH_ERROR;
+                }
+
 #endif //__WITH_DTLS__
             }
+
+            /*
+             * When current state of the device is un-owned and Provisioning
+             * Tool is attempting to change the state to 'Owned' with a
+             * qualified value for the field 'Owner'
+             */
+            if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
+                (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0))
+            {
+#ifdef __WITH_DTLS__
+                OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;
+
+                //Remove Temporal Credential resource
+                if(tmpCredGenFlag)
+                {
+                    VERIFY_SUCCESS(TAG,
+                                   OC_STACK_RESOURCE_DELETED == RemoveCredential(&tmpCredId),
+                                   ERROR);
+                    tmpCredGenFlag = false;
+                }
+
+                //Generate new credential for provisioning tool
+                ehRet = AddOwnerPSK((CAEndpoint_t*)(&request->devAddr), newDoxm,
+                                    (uint8_t*)OXM_RANDOM_DEVICE_PIN, strlen(OXM_RANDOM_DEVICE_PIN));
+                VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
+
+                //Update new state in persistent storage
+                if((UpdatePersistentStorage(gDoxm) == true))
+                {
+                    ehRet = OC_EH_OK;
+                }
+                else
+                {
+                    /*
+                     * If persistent storage update failed, revert back the state
+                     * for global variable.
+                     */
+                    gDoxm->owned = false;
+                    gDoxm->oxmSel = 0;
+                    memset(&(gDoxm->owner), 0, sizeof(OicUuid_t));
+                    ehRet = OC_EH_ERROR;
+
+                }
+#endif
+             }
         }
     }
 
@@ -522,7 +685,7 @@ exit:
     //Send payload to request originator
     if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))
     {
-        OC_LOG (ERROR, TAG, PCF("SendSRMResponse failed in HandlePstatPostRequest"));
+        OC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest");
     }
     DeleteDoxmBinData(newDoxm);
 
@@ -536,6 +699,7 @@ OCEntityHandlerResult DoxmEntityHandler (OCEntityHandlerFlag flag,
                                         OCEntityHandlerRequest * ehRequest,
                                         void* callbackParam)
 {
+    (void)callbackParam;
     OCEntityHandlerResult ehRet = OC_EH_ERROR;
 
     if(NULL == ehRequest)
@@ -546,7 +710,7 @@ OCEntityHandlerResult DoxmEntityHandler (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");
         switch (ehRequest->method)
         {
             case OC_REST_GET:
@@ -584,7 +748,7 @@ OCStackResult CreateDoxmResource()
 
     if (OC_STACK_OK != ret)
     {
-        OC_LOG (FATAL, TAG, PCF("Unable to instantiate Doxm resource"));
+        OC_LOG (FATAL, TAG, "Unable to instantiate Doxm resource");
         DeInitDoxmResource();
     }
     return ret;
@@ -596,13 +760,39 @@ OCStackResult CreateDoxmResource()
  * Once DeviceID is assigned to the device it does not change for the lifetime of the device.
  *
  */
-void CheckDeviceID()
+static OCStackResult CheckDeviceID()
 {
-    if(strcmp((char *)gDoxm->deviceID.id, "") == 0 )
+    OCStackResult ret = OC_STACK_ERROR;
+    bool validId = false;
+    for (uint8_t i = 0; i < UUID_LENGTH; i++)
     {
-        OCFillRandomMem(gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id));
-        UpdatePersistentStorage(gDoxm);
+        if (gDoxm->deviceID.id[i] != 0)
+        {
+            validId = true;
+            break;
+        }
     }
+
+    if (!validId)
+    {
+        if (OCGenerateUuid(gDoxm->deviceID.id) != RAND_UUID_OK)
+        {
+            OC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!");
+            return ret;
+        }
+        ret = OC_STACK_OK;
+
+        if (UpdatePersistentStorage(gDoxm))
+        {
+            //TODO: After registering PSI handler in all samples, do ret = OC_STACK_OK here.
+            OC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
+        }
+    }
+    else
+    {
+        ret = OC_STACK_OK;
+    }
+    return ret;
 }
 
 /**
@@ -611,7 +801,7 @@ void CheckDeviceID()
  */
 static OicSecDoxm_t* GetDoxmDefault()
 {
-    OC_LOG (INFO, TAG, PCF("GetDoxmToDefault"));
+    OC_LOG (DEBUG, TAG, "GetDoxmToDefault");
     return &gDefaultDoxm;
 }
 
@@ -650,9 +840,16 @@ OCStackResult InitDoxmResource()
     {
         gDoxm = GetDoxmDefault();
     }
-    CheckDeviceID();
-    //Instantiate 'oic.sec.doxm'
-    ret = CreateDoxmResource();
+    ret = CheckDeviceID();
+    if (ret == OC_STACK_OK)
+    {
+        //Instantiate 'oic.sec.doxm'
+        ret = CreateDoxmResource();
+    }
+    else
+    {
+        OC_LOG (ERROR, TAG, "CheckDeviceID failed");
+    }
     OICFree(jsonSVRDatabase);
     return ret;
 }