Update easysetup's security-provisioning logic.
[platform/upstream/iotivity.git] / service / easy-setup / mediator / richsdk / src / EnrolleeSecurity.cpp
index 3a6335c..a7a30d0 100755 (executable)
@@ -68,24 +68,6 @@ namespace OIC
             m_secProvisioningDbPathCb = secProvisioningDbPathCb;
         }
 
-        std::shared_ptr< OC::OCSecureResource > EnrolleeSecurity::findEnrolleeSecurityResource(
-            DeviceList_t &list)
-        {
-            for (unsigned int i = 0; i < list.size(); i++)
-            {
-                if(m_ocResource->sid() == list[i]->getDeviceID().c_str())
-                {
-                    OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Device %d ID %s ", i + 1,
-                            list[i]->getDeviceID().c_str());
-                    OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "From IP :%s",
-                                                            list[i]->getDevAddr().c_str());
-                    return list[i];
-                }
-            }
-            OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,"Error!!! DeviceList_t is NULL");
-            return NULL;
-        }
-
         void EnrolleeSecurity::convertUUIDToString(const uint8_t uuid[UUID_SIZE],
                                                               std::string& uuidString)
         {
@@ -111,13 +93,7 @@ namespace OIC
             if (hasError)
             {
                 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,"Error!!! in OwnershipTransfer");
-
-                std::string uuid;
-                convertUUIDToString(result->at(0).deviceId.id, uuid);
-                std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
-                        std::make_shared< SecProvisioningStatus >(uuid, ES_ERROR);
-                m_securityProvStatusCb(securityProvisioningStatus);
-                return;
+                OTMResult = false;
             }
             else
             {
@@ -125,67 +101,45 @@ namespace OIC
                 for (unsigned int i = 0; i < result->size(); i++)
                 {
                     OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d for device",result->at(i).res);
-                    std::string uuid;
-                    convertUUIDToString(result->at(0).deviceId.id, uuid);
-
-                    OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "UUID : %s",uuid.c_str());
-                    std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
-                            std::make_shared< SecProvisioningStatus >(uuid, ES_OK);
-                    m_securityProvStatusCb(securityProvisioningStatus);
-                    return;
                 }
-
                 delete result;
+                OTMResult = true;
             }
+            m_cond.notify_all();
         }
 
-        void EnrolleeSecurity::provisionOwnership()
+        ESResult EnrolleeSecurity::provisionOwnership()
         {
-            OC::DeviceList_t pUnownedDevList, pOwnedDevList;
-
-            pOwnedDevList.clear();
-            pUnownedDevList.clear();
+            ESResult res = ESResult::ES_ERROR;
 
             OCStackResult result = OC_STACK_ERROR;
+            OicUuid_t uuid;
+            ConvertStrToUuid(m_ocResource->sid().c_str(), &uuid);
 
-            result = OCSecure::discoverOwnedDevices(ES_SEC_DISCOVERY_TIMEOUT,
-                    pOwnedDevList);
+            result = OCSecure::discoverSingleDevice(ES_SEC_DISCOVERY_TIMEOUT,
+                                                    &uuid,
+                                                    m_securedResource);
             if (result != OC_STACK_OK)
             {
-                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Owned Discovery failed.");
-                //Throw exception
-                throw ESPlatformException(result);
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Secure Resource Discovery failed.");
+                res = ESResult:: ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+                return res;
             }
-            else if (pOwnedDevList.size())
+            else if (m_securedResource)
             {
-                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Found owned devices. Count =%d",
-                        pOwnedDevList.size());
-                std::shared_ptr< OC::OCSecureResource > ownedDevice =
-                    findEnrolleeSecurityResource(pOwnedDevList);
-
-                if (ownedDevice)
+                if (m_securedResource->getOwnedStatus()) // owned check logic
                 {
-                    std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
-                            std::make_shared< SecProvisioningStatus >(ownedDevice->getDeviceID(), ES_OK);
-                    m_securityProvStatusCb(securityProvisioningStatus);
-                    return;
+                    if(isOwnedDeviceRegisteredInSVRDB())
+                    {
+                        res = ESResult::ES_OK;
+                    }
+                    else
+                    {
+                        res = ESResult::ES_ERROR;
+                    }
+                    return res;
                 }
-            }
-
-            result = OCSecure::discoverUnownedDevices(ES_SEC_DISCOVERY_TIMEOUT, pUnownedDevList);
-            if (result != OC_STACK_OK)
-            {
-                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "UnOwned Discovery failed.");
-                //Throw exception
-                throw ESPlatformException(result);
-            }
-            else if (pUnownedDevList.size())
-            {
-                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Found Unowned devices. Count =%d",
-                        pUnownedDevList.size());
-
-                m_unownedDevice = findEnrolleeSecurityResource(pUnownedDevList);
-                if (m_unownedDevice)
+                else // unowned check logic
                 {
                     if(isOwnedDeviceRegisteredInSVRDB())
                     {
@@ -196,29 +150,53 @@ namespace OIC
                                 &EnrolleeSecurity::removeDeviceWithUuidCB,
                                 this, std::placeholders::_1, std::placeholders::_2);
 
-                        OCSecure::removeDeviceWithUuid(DISCOVERY_TIMEOUT,
-                                                       m_ocResource->sid(),
-                                                       removeDeviceWithUuidCB);
+                        result = OCSecure::removeDeviceWithUuid(ES_SEC_DISCOVERY_TIMEOUT,
+                                                                m_ocResource->sid(),
+                                                                removeDeviceWithUuidCB);
+                        if(result != OC_STACK_OK)
+                        {
+                            OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "removeDeviceWithUuid failed.");
+                            res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
+                            return res;
+                        }
+
+                        std::unique_lock<std::mutex> lck(m_mtx);
+                        m_cond.wait_for(lck, std::chrono::seconds(ES_SEC_DISCOVERY_TIMEOUT));
+
+                        if(!removeDeviceResult)
+                        {
+                            res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
+                            return res;
+                        }
                     }
-                    else
+
+                    res = performOwnershipTransfer();
+
+                    if(res != ESResult::ES_OK)
                     {
-                        performOwnershipTransfer();
+                        OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Ownership-Transfer failed.");
+                        res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
+                        return res;
+                    }
+
+                    std::unique_lock<std::mutex> lck(m_mtx);
+                    m_cond.wait(lck);
+
+                    if(!OTMResult)
+                    {
+                        res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
                     }
-                }
-                else
-                {
-                    OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "No matched unowned devices found.");
-                    throw ESException("No matched unowned devices found.");
                 }
             }
             else
             {
-                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "No unowned devices found.");
-                throw ESException("No unowned devices found.");
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "No secure resource found.");
+                res = ESResult:: ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
             }
+            return res;
         }
 
-        void EnrolleeSecurity::performOwnershipTransfer()
+        ESResult EnrolleeSecurity::performOwnershipTransfer()
         {
             OCStackResult result = OC_STACK_ERROR;
 
@@ -231,18 +209,19 @@ namespace OIC
             OCSecure::setOwnerTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData, NULL);
 
             OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Transfering ownership for : %s ",
-                    m_unownedDevice->getDeviceID().c_str());
+                    m_securedResource->getDeviceID().c_str());
 
             OC::ResultCallBack ownershipTransferCb = std::bind(
                     &EnrolleeSecurity::ownershipTransferCb, this, std::placeholders::_1,
                     std::placeholders::_2);
 
-            result = m_unownedDevice->doOwnershipTransfer(ownershipTransferCb);
+            result = m_securedResource->doOwnershipTransfer(ownershipTransferCb);
             if (result != OC_STACK_OK)
             {
                 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "doOwnershipTransfer is failed");
-                throw ESPlatformException(result);
+                return ESResult::ES_ERROR;
             }
+            return ESResult::ES_OK;
         }
 
         void EnrolleeSecurity::removeDeviceWithUuidCB(OC::PMResultList_t *result, int hasError)
@@ -250,7 +229,7 @@ namespace OIC
             if (hasError)
             {
                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Error in removeDeviceWithUuid operation!");
-               throw ESException("removeDeviceWithUuid Error");
+               removeDeviceResult = false;
             }
 
             else
@@ -265,8 +244,9 @@ namespace OIC
                     OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG,
                         "Result is = %d for device %s",  result->at(i).res, uuid.c_str());
                }
-               performOwnershipTransfer();
+               removeDeviceResult = true;
             }
+            m_cond.notify_all();
         }
 
         bool EnrolleeSecurity::isOwnedDeviceRegisteredInSVRDB()
@@ -308,62 +288,92 @@ namespace OIC
         };
 
 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
-        void EnrolleeSecurity::provisionSecurityForCloudServer(
+        ESResult EnrolleeSecurity::provisionSecurityForCloudServer(
             std::string cloudUuid, int credId)
         {
+            ESResult res = ESResult::ES_ERROR;
+
             // Need to discover Owned device in a given network, again
-            OC::DeviceList_t pOwnedDevList;
             std::shared_ptr< OC::OCSecureResource > ownedDevice = NULL;
 
-            pOwnedDevList.clear();
-
             OCStackResult result;
+            OicUuid_t uuid;
+            ConvertStrToUuid(m_ocResource->sid().c_str(), &uuid);
 
-            result = OCSecure::discoverOwnedDevices(ES_SEC_DISCOVERY_TIMEOUT,
-                    pOwnedDevList);
+            result = OCSecure::discoverSingleDevice(ES_SEC_DISCOVERY_TIMEOUT,
+                                                    &uuid,
+                                                    ownedDevice);
             if (result != OC_STACK_OK)
             {
-                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Owned Discovery failed.");
-                //Throw exception
-                throw ESPlatformException(result);
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "secureResource Discovery failed.");
+                res = ESResult::ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+                return res;
             }
-            else if (pOwnedDevList.size())
+            else if (ownedDevice)
             {
-                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Found owned devices. Count =%d",
-                        pOwnedDevList.size());
-                ownedDevice = findEnrolleeSecurityResource(pOwnedDevList);
+                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Found secureResource.");
 
-                if (!ownedDevice)
+                if (ownedDevice->getOwnedStatus())
                 {
-                    OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Not found matched owned device.");
-                    throw ESException("Not found matched owned device.");
+                    if(!isOwnedDeviceRegisteredInSVRDB())
+                    {
+                        OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG,
+                            "Not found matched owned deivce in SVR DB.");
+                        res = ESResult::ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+                        return res;
+                    }
+                }
+                else
+                {
+                    OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Target Enrollee is unowned.");
+                    res = ESResult::ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+                    return res;
                 }
             }
             else
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Not found owned devices.");
-                throw ESException("Not found owned devices.");
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Not found secureResource.");
+                res = ESResult::ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+                return res;
             }
 
-            if(!cloudUuid.empty()
-                && performACLProvisioningForCloudServer(ownedDevice, cloudUuid) != ESResult::ES_OK)
+            if(cloudUuid.empty())
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "error performACLProvisioningForCloudServer");
-                throw ESException("error performACLProvisioningForCloudServer");
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                         "ACL provisioning is skipped due to empty UUID of cloud server");
+            }
+            else
+            {
+                res = performACLProvisioningForCloudServer(ownedDevice, cloudUuid);
+                if(res != ESResult::ES_OK)
+                {
+                    OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "error performACLProvisioningForCloudServer");
+                    return res;
+                }
             }
 
-            if(credId != -1
-                && performCertProvisioningForCloudServer(ownedDevice, credId) != ESResult::ES_OK)
+            if(credId < 1)
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "error performCertProvisioningForCloudServer");
-                throw ESException("error performCertProvisioningForCloudServer");
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                         "Cert. provisioning is skipped due to wrong cred ID (<1)");
+            }
+            else
+            {
+                res = performCertProvisioningForCloudServer(ownedDevice, credId);
+                if(res != ESResult::ES_OK)
+                {
+                    OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "error performCertProvisioningForCloudServer");
+                    return res;
+                }
             }
+
+            return res;
         }
 
         ESResult EnrolleeSecurity::performCertProvisioningForCloudServer(
             std::shared_ptr< OC::OCSecureResource > ownedDevice, int credId)
         {
-            ESResult res = ESResult::ES_ERROR;
+            ESResult res = ESResult::ES_CERT_PROVISIONING_FAILURE;
 
             if(!ownedDevice)
             {
@@ -383,7 +393,7 @@ namespace OIC
             }
 
             std::unique_lock<std::mutex> lck(m_mtx);
-            m_cond.wait_for(lck, std::chrono::seconds(ES_SEC_DISCOVERY_TIMEOUT));
+            m_cond.wait(lck);
 
             if(certResult)
             {
@@ -396,18 +406,13 @@ namespace OIC
         ESResult EnrolleeSecurity::performACLProvisioningForCloudServer(
             std::shared_ptr< OC::OCSecureResource > ownedDevice, std::string& cloudUuid)
         {
-            ESResult res = ESResult::ES_ERROR;
+            ESResult res = ESResult::ES_ACL_PROVISIONING_FAILURE;
 
             if(!ownedDevice)
             {
                 OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Invalid param");
                 return res;
             }
-            if(cloudUuid.empty())
-            {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Invalid param");
-                return res;
-            }
 
             OicUuid_t uuid;
             ConvertStrToUuid(cloudUuid.c_str(), &uuid);
@@ -432,7 +437,7 @@ namespace OIC
             }
 
             std::unique_lock<std::mutex> lck(m_mtx);
-            m_cond.wait_for(lck, std::chrono::seconds(ES_SEC_DISCOVERY_TIMEOUT));
+            m_cond.wait(lck);
 
             if(aclResult)
             {