Add OxM Select API and MOT related API.
authorChul Lee <chuls.lee@samsung.com>
Wed, 14 Dec 2016 01:55:22 +0000 (10:55 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Tue, 20 Dec 2016 04:12:37 +0000 (04:12 +0000)
- Add OxM Select API on C layer.
  : OCSelectOwnershipTransferMethod

- Add OT/MOT related API on C++ layer.
  : OCSecureResource::getMOTMethod
  : OCSecureResource::getMOTMethod
  : OCSecureResource::isMOTSupported
  : OCSecureResource::isMOTEnabled

- Minor bugfix in OT/MOT.

Change-Id: I476fafe3f69f8bcb00036d60be1ab92ad74c6aae
Signed-off-by: Chul Lee <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/15577
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-by: Alex Kelley <alexke@microsoft.com>
Reviewed-by: Jihun Ha <jihun.ha@samsung.com>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
(cherry picked from commit 6ba3036950661ab8c8b4d868adfe80ba12b2f531)
Reviewed-on: https://gerrit.iotivity.org/gerrit/15795

resource/csdk/security/provisioning/include/internal/ownershiptransfermanager.h
resource/csdk/security/provisioning/include/ocprovisioningmanager.h
resource/csdk/security/provisioning/include/pmtypes.h
resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c
resource/csdk/security/provisioning/src/ocprovisioningmanager.c
resource/csdk/security/provisioning/src/ownershiptransfermanager.c
resource/include/OCProvisioningManager.hpp
resource/provisioning/src/OCProvisioningManager.cpp
resource/provisioning/unittests/OCProvisioningTest.cpp

index 5778ea0..1ef3fa4 100644 (file)
@@ -36,21 +36,6 @@ extern "C" {
 typedef struct OTMCallbackData OTMCallbackData_t;\r
 typedef struct OTMContext OTMContext_t;\r
 \r
-\r
-typedef enum OxmAllowTableIdx {\r
-    OXM_IDX_JUST_WORKS = 0,\r
-    OXM_IDX_MV_JUST_WORKS,\r
-#ifdef MULTIPLE_OWNER\r
-    OXM_IDX_PRECONFIG_PIN,\r
-#endif\r
-    OXM_IDX_RANDOM_DEVICE_PIN,\r
-    OXM_IDX_MANUFACTURER_CERTIFICATE,\r
-    OXM_IDX_CON_MFG_CERT,\r
-    OXM_IDX_DECENTRALIZED_PUBLIC_KEY,\r
-    OXM_IDX_COUNT,\r
-    OXM_IDX_UNKNOWN\r
-}OxmAllowTableIdx_t;\r
-\r
 /**\r
  * Do ownership transfer for the unowned devices.\r
  *\r
@@ -138,6 +123,18 @@ OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxm, OTMCallbackDa
  */\r
 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks);\r
 \r
+/**\r
+ * Function to select appropriate security provisioning method.\r
+ *\r
+ * @param[in] supportedMethods   Array of supported methods\r
+ * @param[in] numberOfMethods   number of supported methods\r
+ * @param[out]  selectedMethod         Selected methods\r
+ * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)\r
+ * @return  OC_STACK_OK on success\r
+ */\r
+OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,\r
+        size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType);\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
index e22eb77..75ac24c 100644 (file)
@@ -509,6 +509,18 @@ void OCRemoveTrustCertChainNotifier(void);
 OCStackResult OCReadTrustCertChain(uint16_t credId, uint8_t **trustCertChain,\r
                                      size_t *chainSize);\r
 \r
+/**\r
+ * Function to select appropriate security provisioning method.\r
+ *\r
+ * @param[in] supportedMethods   Array of supported methods\r
+ * @param[in] numberOfMethods   number of supported methods\r
+ * @param[out]  selectedMethod         Selected methods\r
+ * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)\r
+ * @return  OC_STACK_OK on success\r
+ */\r
+OCStackResult OCSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,\r
+        size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType);\r
+\r
 #endif // __WITH_DTLS__ || __WITH_TLS__\r
 \r
 \r
index 1a5f8cb..d75320e 100644 (file)
@@ -101,6 +101,31 @@ typedef struct OCPMResult{
 }OCProvisionResult_t;
 
 /**
+ * Owner device type
+ */
+typedef enum OwnerType{
+    SUPER_OWNER = 0,
+    SUB_OWNER = 1
+}OwnerType_t;
+
+/**
+ * Index value to access OxM allow table
+ */
+typedef enum OxmAllowTableIdx {
+    OXM_IDX_JUST_WORKS = 0,
+    OXM_IDX_MV_JUST_WORKS,
+#ifdef MULTIPLE_OWNER
+    OXM_IDX_PRECONFIG_PIN,
+#endif
+    OXM_IDX_RANDOM_DEVICE_PIN,
+    OXM_IDX_MANUFACTURER_CERTIFICATE,
+    OXM_IDX_CON_MFG_CERT,
+    OXM_IDX_DECENTRALIZED_PUBLIC_KEY,
+    OXM_IDX_COUNT,
+    OXM_IDX_UNKNOWN
+}OxmAllowTableIdx_t;
+
+/**
  * Callback function definition of provisioning API
  *
  * @param[OUT] ctx - If user set his/her context, it will be returned here.
index 65bc9db..d7bd054 100644 (file)
@@ -555,6 +555,7 @@ static void SetMOTResult(OTMContext_t* motCtx, const OCStackResult res)
 
             OICFree(motCtx->ctxResultArray);
             OICFree(motCtx);
+            motCtx = NULL;
         }
         else
         {
@@ -981,12 +982,28 @@ static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t* motCtx,
 {
     OIC_LOG(INFO, TAG, "IN StartMultipleOwnershipTransfer");
     OCStackResult res = OC_STACK_INVALID_PARAM;
+    OicUuid_t myUuid = {.id={0}};
 
     VERIFY_NON_NULL(TAG, motCtx, ERROR);
     VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
     VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
     motCtx->selectedDeviceInfo = selectedDevice;
 
+    res = GetDoxmDeviceID(&myUuid);
+    if(OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to GetDoxmDeviceID");
+        SetMOTResult(motCtx, res);
+        return res;
+    }
+    if(memcmp(selectedDevice->doxm->owner.id, myUuid.id, sizeof(myUuid.id)) == 0)
+    {
+        res = OC_STACK_INVALID_DEVICE_INFO;
+        OIC_LOG(ERROR, TAG, "Owner cannot be registered as sub-owner.");
+        SetMOTResult(motCtx, res);
+        return res;
+    }
+
     //Checking duplication of Device ID.
     char* strUuid = NULL;
     PdmDeviceState_t deviceState = PDM_DEVICE_UNKNOWN;
@@ -1124,10 +1141,9 @@ OCStackResult MOTDoOwnershipTransfer(void* ctx,
 
     motCtx->selectedDeviceInfo = selectedDevicelist;
     res = StartMultipleOwnershipTransfer(motCtx, selectedDevicelist);
-    VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
 
     OIC_LOG(DEBUG, TAG, "OUT MOTDoOwnershipTransfer");
-
+    return res;
 exit:
     if(OC_STACK_OK != res)
     {
index 2250e18..0894de4 100644 (file)
@@ -1308,6 +1308,22 @@ OCStackResult OCSelectMOTMethod(void *ctx, const OCProvisionDev_t *targetDeviceI
 }
 #endif //MULTIPLE_OWNER
 
+/**
+ * Function to select appropriate security provisioning method.
+ *
+ * @param[in] supportedMethods   Array of supported methods
+ * @param[in] numberOfMethods   number of supported methods
+ * @param[out]  selectedMethod         Selected methods
+ * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)
+ * @return  OC_STACK_OK on success
+ */
+OCStackResult OCSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
+        size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType)
+{
+    return OTMSelectOwnershipTransferMethod(supportedMethods, numberOfMethods,
+                                            selectedMethod, ownerType);
+}
+
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 /**
  * function to provision Trust certificate chain to devices.
index cecd40c..bf31ed5 100644 (file)
@@ -202,10 +202,11 @@ static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm)
  * @param[in] supportedMethods   Array of supported methods
  * @param[in] numberOfMethods   number of supported methods
  * @param[out]  selectedMethod         Selected methods
+ * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)
  * @return  OC_STACK_OK on success
  */
-static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
-        size_t numberOfMethods, OicSecOxm_t *selectedMethod)
+OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
+        size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType)
 {
     bool isOxmSelected = false;
     OxmAllowTableIdx_t oxmIdx = OXM_IDX_UNKNOWN;
@@ -213,33 +214,70 @@ static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethod
 
     OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
 
-    if(numberOfMethods == 0 || !supportedMethods)
+    if (numberOfMethods == 0 || !supportedMethods)
     {
         OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
         return OC_STACK_ERROR;
     }
 
-    for(size_t i = 0; i < numberOfMethods; i++)
+    switch(ownerType)
     {
-        selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
-        if(OXM_IDX_COUNT <= selectedOxmIdx)
+        case SUPER_OWNER:
         {
-            OIC_LOG(ERROR, TAG, "Invalid oxm index to access OxM allow table");
-            return OC_STACK_ERROR;
-        }
+            for (size_t i = 0; i < numberOfMethods; i++)
+            {
+                selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
+                if (OXM_IDX_COUNT <= selectedOxmIdx)
+                {
+                    OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
+                    continue;
+                }
 
 #ifdef MULTIPLE_OWNER
-        if(ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
-           OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
+                if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
+                   OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
 #else
-        if(ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
+                if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
 #endif //MULTIPLE_OWNER
+                {
+                    *selectedMethod  = supportedMethods[i];
+                    isOxmSelected = true;
+                }
+            }
+        }
+        break;
+#ifdef MULTIPLE_OWNER
+        case SUB_OWNER:
         {
-            *selectedMethod  = supportedMethods[i];
-            isOxmSelected = true;
+            for (size_t i = 0; i < numberOfMethods; i++)
+            {
+                selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
+                if (OXM_IDX_COUNT <= selectedOxmIdx)
+                {
+                    OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
+                    continue;
+                }
+
+                //in case of MOT, only Random PIN & Preconfigured PIN based OxM is allowed
+                if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
+                    (OXM_IDX_RANDOM_DEVICE_PIN == selectedOxmIdx ||
+                     OXM_IDX_PRECONFIG_PIN == selectedOxmIdx))
+                {
+                    *selectedMethod  = supportedMethods[i];
+                    isOxmSelected = true;
+                }
+            }
+        }
+        break;
+#endif
+        default:
+        {
+            OIC_LOG_V(ERROR, TAG, "Unknown owner type or Not supported owner type : %d", ownerType);
+            return OC_STACK_INVALID_PARAM;
         }
     }
-    if(!isOxmSelected)
+
+    if (!isOxmSelected)
     {
         OIC_LOG(ERROR, TAG, "Can not find the allowed OxM.");
         return OC_STACK_NOT_ALLOWED_OXM;
@@ -250,7 +288,6 @@ static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethod
     return OC_STACK_OK;
 }
 
-
 /**
  * Function to select operation mode.This function will return most secure common operation mode.
  *
@@ -392,7 +429,6 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
                              otmCtx->selectedDeviceInfo->securePort))
     {
         OIC_LOG(WARNING, TAG, "Current OTM Process has already ended.");
-        return;
     }
 
     //Revert psk_info callback and new deivce uuid in case of random PIN OxM
@@ -1892,11 +1928,11 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
         }
     }
 
-
-    //Set to the lowest level OxM, and then find more higher level OxM.
-    res = SelectProvisioningMethod(selectedDevice->doxm->oxm,
-                                   selectedDevice->doxm->oxmLen,
-                                   &selectedDevice->doxm->oxmSel);
+    //Select the OxM to performing ownership transfer
+    res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
+                                          selectedDevice->doxm->oxmLen,
+                                          &selectedDevice->doxm->oxmSel,
+                                          SUPER_OWNER);
     if(OC_STACK_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
index bd1e633..45115ef 100644 (file)
@@ -551,6 +551,14 @@ namespace OC
              */
             bool getOwnedStatus();
 
+            /**
+             * API to get the proper OxM for OT.
+             *
+             * @param oxm Address to save the selected OxM.
+             *
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult getOTMethod(OicSecOxm_t* oxm);
 
             /**
              * Common callback wrapper, which will be called from OC-APIs.
@@ -612,6 +620,30 @@ namespace OC
              */
             OCStackResult doMultipleOwnershipTransfer(ResultCallBack resultCallback);
 
+            /**
+             * API to get the proper OxM for MOT.
+             *
+             * @param oxm Address to save the selected OxM.
+             *
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult getMOTMethod( OicSecOxm_t* oxm);
+
+            /**
+             * API to check whether MOT is supported.
+             *
+             * @return ::true in case of MOT supported.
+             */
+            bool isMOTSupported();
+
+            /**
+             * API to check whether MOT is enabled.
+             *
+             * @return ::true in case of MOT enabled.
+             */
+            bool isMOTEnabled();
+
+
 #endif // MULTIPLE_OWNER
 
         private:
index 963b834..6b4da7e 100644 (file)
@@ -1102,7 +1102,81 @@ namespace OC
         }
     }
 
+    OCStackResult OCSecureResource::getOTMethod(OicSecOxm_t* oxm)
+    {
+        if(!oxm)
+        {
+            oclog() << "Null param";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            if(devPtr && devPtr->doxm)
+            {
+                result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
+                                                  oxm, SUPER_OWNER);
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+        }
+        return result;
+    }
+
+
 #ifdef MULTIPLE_OWNER
+    OCStackResult OCSecureResource::getMOTMethod( OicSecOxm_t* oxm)
+    {
+        if (!oxm)
+        {
+            oclog() << "Null param";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            if (devPtr && devPtr->doxm)
+            {
+                result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
+                                                  oxm, SUB_OWNER);
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+        }
+        return result;
+    }
+
+    bool OCSecureResource::isMOTSupported()
+    {
+        if (devPtr && devPtr->doxm)
+        {
+            return (devPtr->doxm->mom ? true : false);
+        }
+        return false;
+    }
+
+    bool OCSecureResource::isMOTEnabled()
+    {
+        if (devPtr && devPtr->doxm && devPtr->doxm->mom)
+        {
+            if (OIC_MULTIPLE_OWNER_DISABLE != devPtr->doxm->mom->mode)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
     OCStackResult OCSecureResource::selectMOTMethod( const OicSecOxm_t oxmSelVal,
             ResultCallBack resultCallback)
     {
index 628b3d0..61b4499 100644 (file)
@@ -160,6 +160,24 @@ namespace OCProvisioningTest
         size_t PinLength = 4;
         EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.provisionPreconfPin(pin, PinLength, NULL));
     }
+
+    TEST(isMOTEnabledTest, isMOTEnabledWithoutDeviceInst)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(false, device.isMOTEnabled());
+    }
+
+    TEST(isMOTSupportedTest, isMOTSupportedWithoutDeviceInst)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(false, device.isMOTSupported());
+    }
+
+    TEST(getMOTMethodTest, getMOTMethodNullOxM)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, device.getMOTMethod(NULL));
+    }
 #endif
 
     TEST(DeviceInfoTest, DevInfoFromNetwork)