Fix the messageID handling issue in SVR's request handler.
authorChul Lee <chuls.lee@samsung.com>
Wed, 21 Dec 2016 08:07:31 +0000 (17:07 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Mon, 9 Jan 2017 11:30:15 +0000 (11:30 +0000)
CoAP over UDP is supported messageID to support duplicate message detection.
(Please see RFC 7252)

BTW, other transport adapter does not support message ID.
So we should check message ID to prevent duplicate request handling
in case of CoAP over UDP only.

Also, This patch includes random PIN restart bug fix.

Change-Id: I6b0de7d455a1423e0156806d97a86e3c9af258c4
Signed-off-by: Chul Lee <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/15867
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
(cherry picked from commit aa62467847fc84a89b03eea8cbaa02f0e5e444a0)
Reviewed-on: https://gerrit.iotivity.org/gerrit/16141

resource/csdk/security/provisioning/src/ownershiptransfermanager.c
resource/csdk/security/src/doxmresource.c
resource/csdk/security/src/pstatresource.c

index 433b6a7..26a7525 100644 (file)
@@ -630,19 +630,29 @@ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
                             newDevDoxm->owned = false;
                             otmCtx->attemptCnt++;
 
-                            if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
+                            // In order to re-start ownership transfer, device information should be deleted from PDM.
+                            res = PDMDeleteDevice(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
+                            if (OC_STACK_OK != res)
                             {
-                                res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
-                                if(OC_STACK_OK != res)
-                                {
-                                    SetResult(otmCtx, res);
-                                    OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
-                                }
+                                SetResult(otmCtx, res);
+                                OIC_LOG(ERROR, TAG, "Failed to PDMDeleteDevice");
                             }
                             else
                             {
-                                OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
-                                SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
+                                if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
+                                {
+                                    res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
+                                    if(OC_STACK_OK != res)
+                                    {
+                                        SetResult(otmCtx, res);
+                                        OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
+                                    }
+                                }
+                                else
+                                {
+                                    OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
+                                    SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
+                                }
                             }
                         }
                         else
index b427399..4169063 100644 (file)
@@ -995,6 +995,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
     OCEntityHandlerResult ehRet = OC_EH_ERROR;
     OicUuid_t emptyOwner = {.id = {0} };
     static uint16_t previousMsgId = 0;
+    bool isDuplicatedMsg = false;
 
     /*
      * Convert CBOR Doxm data into binary. This will also validate
@@ -1010,6 +1011,17 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
         OCStackResult res = CBORPayloadToDoxmBin(payload, size, &newDoxm, &roParsed);
         if (newDoxm && OC_STACK_OK == res)
         {
+            /*
+             * message ID is supported for CoAP over UDP only according to RFC 7252
+             * So we should check message ID to prevent duplicate request handling in case of OC_ADAPTER_IP.
+             * In case of other transport adapter, duplicate message check is not required.
+             */
+            if (OC_ADAPTER_IP == ehRequest->devAddr.adapter &&
+                 previousMsgId == ehRequest->messageID)
+            {
+                isDuplicatedMsg = true;
+            }
+
             // Check request on RO property
             if (true == roParsed)
             {
@@ -1168,7 +1180,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
 
                         //In case of Mutual Verified Just-Works, verify mutualVerifNum
                         if (OIC_MV_JUST_WORKS == newDoxm->oxmSel && false == newDoxm->owned &&
-                                        previousMsgId != ehRequest->messageID)
+                            false == isDuplicatedMsg)
                         {
                             uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
                             uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
@@ -1250,33 +1262,10 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                                                     ehRequest->devAddr.adapter);
                         VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
 
-                        char ranPin[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
-                         //TODO ehRequest->messageID for copa over TCP always is null. Find reason why.
-                        if(ehRequest->devAddr.adapter == OC_ADAPTER_IP && previousMsgId != ehRequest->messageID)
-                        {
-                            if(OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
-                            {
-                                //Set the device id to derive temporal PSK
-                                SetUuidForPinBasedOxm(&gDoxm->deviceID);
-
-                                /**
-                                 * Since PSK will be used directly by DTLS layer while PIN based ownership transfer,
-                                 * Credential should not be saved into SVR.
-                                 * For this reason, use a temporary get_psk_info callback to random PIN OxM.
-                                 */
-                                caRes = CAregisterPskCredentialsHandler(GetDtlsPskForRandomPinOxm);
-                                VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
-                                ehRet = OC_EH_OK;
-                            }
-                            else
-                            {
-                                OIC_LOG(ERROR, TAG, "Failed to generate random PIN");
-                                ehRet = OC_EH_ERROR;
-                            }
-                        }
-                        else if(OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
+                        if (!isDuplicatedMsg)
                         {
-                            if(OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
+                            char ranPin[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
+                            if (OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
                             {
                                 //Set the device id to derive temporal PSK
                                 SetUuidForPinBasedOxm(&gDoxm->deviceID);
@@ -1295,7 +1284,6 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                                 OIC_LOG(ERROR, TAG, "Failed to generate random PIN");
                                 ehRet = OC_EH_ERROR;
                             }
-
                         }
 #endif // __WITH_DTLS__ or __WITH_TLS__
                     }
@@ -1343,8 +1331,8 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
 
                     //In case of Confirm Manufacturer Cert, get user confirmation
                     if (OIC_CON_MFG_CERT == newDoxm->oxmSel && false == newDoxm->owned &&
-                                    previousMsgId != ehRequest->messageID &&
-                                    memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
+                        false == isDuplicatedMsg &&
+                        memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
                     {
                         if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, USER_CONFIRM))
                         {
@@ -1455,8 +1443,7 @@ exit:
             {
                 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 (!isDuplicatedMsg)
                 {
                     RestoreDoxmToInitState();
                     RestorePstatToInitState();
@@ -1471,7 +1458,7 @@ exit:
     }
     else
     {
-        previousMsgId = ehRequest->messageID++;
+        previousMsgId = ehRequest->messageID;
     }
 
     //Send payload to request originator
index db79631..ef5bd5f 100644 (file)
@@ -517,6 +517,7 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
     OIC_LOG(INFO, TAG, "HandlePstatPostRequest  processing POST request");
     OicSecPstat_t *pstat = NULL;
     static uint16_t previousMsgId = 0;
+    bool isDuplicatedMsg = false;
 
     if (ehRequest->payload && NULL != gPstat)
     {
@@ -531,6 +532,17 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
         {
             bool validReq = false;
 
+            /*
+             * message ID is supported for CoAP over UDP only according to RFC 7252
+             * So we should check message ID to prevent duplicate request handling in case of OC_ADAPTER_IP.
+             * In case of other transport adapter, duplicate message check is not required.
+             */
+            if (OC_ADAPTER_IP == ehRequest->devAddr.adapter &&
+                 previousMsgId == ehRequest->messageID)
+            {
+                isDuplicatedMsg = true;
+            }
+
             if (true == roParsed)
             {
                     OIC_LOG(ERROR, TAG, "Not acceptable request because of read-only properties");
@@ -641,8 +653,7 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
              {
                 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 (!isDuplicatedMsg)
                 {
                     RestoreDoxmToInitState();
                     RestorePstatToInitState();
@@ -659,7 +670,7 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
      {
         if(ehRequest->devAddr.adapter == OC_ADAPTER_IP)
         {
-            previousMsgId = ehRequest->messageID++;
+            previousMsgId = ehRequest->messageID;
         }
      }