replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / provisioning / src / OCProvisioningManager.cpp
index e422b9e..3c18238 100644 (file)
@@ -21,7 +21,9 @@
 #include "ocstack.h"
 #include "srmutility.h"
 #include "base64.h"
-#include "OCProvisioningManager.h"
+#include "OCProvisioningManager.hpp"
+#include "mbedtls/x509_crt.h"
+
 
 namespace OC
 {
@@ -44,6 +46,23 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecure::terminatePM()
+    {
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCTerminatePM();
+            return OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            return OC_STACK_ERROR;
+        }
+    }
+
     OCStackResult OCSecure::discoverUnownedDevices(unsigned short timeout,
             DeviceList_t &list)
     {
@@ -121,9 +140,90 @@ namespace OC
         return result;
     }
 
-    OCStackResult OCSecure::discoverSecureResource(unsigned short timeout,
-            const std::string& host,
+    OCStackResult OCSecure::discoverSingleDevice(unsigned short timeout,
+            const OicUuid_t* deviceID,
+            std::shared_ptr<OCSecureResource> &foundDevice)
+    {
+        OCStackResult result;
+        OCProvisionDev_t *pDev = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDiscoverSingleDevice(timeout, deviceID, &pDev);
+            if (result == OC_STACK_OK)
+            {
+                if (pDev)
+                {
+                    foundDevice.reset(new OCSecureResource(csdkLock, pDev));
+                }
+                else
+                {
+                    oclog() <<"Not found Secure resource!";
+                    foundDevice.reset();
+                }
+            }
+            else
+            {
+                oclog() <<"Secure resource discovery failed!";
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+    OCStackResult OCSecure::discoverSingleDeviceInUnicast(unsigned short timeout,
+            const OicUuid_t* deviceID,
+            const std::string& hostAddress,
             OCConnectivityType connType,
+            std::shared_ptr<OCSecureResource> &foundDevice)
+    {
+        OCStackResult result = OC_STACK_ERROR;
+        OCProvisionDev_t *pDev = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDiscoverSingleDeviceInUnicast(timeout, deviceID, hostAddress.c_str(),
+                            connType, &pDev);
+
+            if (result == OC_STACK_OK)
+            {
+                if (pDev)
+                {
+                    foundDevice.reset(new OCSecureResource(csdkLock, pDev));
+                }
+                else
+                {
+                    oclog() <<"Not found Secure resource!";
+                    foundDevice.reset();
+                }
+            }
+            else
+            {
+                oclog() <<"Secure resource discovery failed!";
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+#ifdef MULTIPLE_OWNER
+    OCStackResult OCSecure::discoverMultipleOwnerEnabledDevices(unsigned short timeout,
             DeviceList_t &list)
     {
         OCStackResult result;
@@ -134,7 +234,7 @@ namespace OC
         if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCDiscoverSecureResource(timeout, host.c_str(), connType, &pDevList);
+            result = OCDiscoverMultipleOwnerEnabledDevices(timeout, &pDevList);
             if (result == OC_STACK_OK)
             {
                 pCurDev = pDevList;
@@ -149,7 +249,7 @@ namespace OC
             }
             else
             {
-                oclog() <<"Secure resource discovery failed!";
+                oclog() <<"MultipleOwner Enabled device discovery failed!";
             }
         }
         else
@@ -161,32 +261,76 @@ namespace OC
         return result;
     }
 
-    OCStackResult OCSecure::setOwnerTransferCallbackData(OicSecOxm_t oxm,
-            OTMCallbackData_t* callbackData, InputPinCallback inputPin)
+    OCStackResult OCSecure::discoverMultipleOwnedDevices(unsigned short timeout,
+            DeviceList_t &list)
     {
-        if (NULL == callbackData || oxm >= OIC_OXM_COUNT)
+        OCStackResult result;
+        OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
+
+        if (cLock)
         {
-            oclog() <<"Invalid callbackData or OXM type";
-            return OC_STACK_INVALID_PARAM;
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDiscoverMultipleOwnedDevices(timeout, &pDevList);
+            if (result == OC_STACK_OK)
+            {
+                pCurDev = pDevList;
+                while (pCurDev)
+                {
+                    tmp = pCurDev;
+                    list.push_back(std::shared_ptr<OCSecureResource>(
+                                new OCSecureResource(csdkLock, pCurDev)));
+                    pCurDev = pCurDev->next;
+                    tmp->next = nullptr;
+                }
+            }
+            else
+            {
+                oclog() <<"Multiple Owned device discovery failed!";
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
         }
 
-        if ((OIC_RANDOM_DEVICE_PIN == oxm) && !inputPin)
+        return result;
+    }
+
+#endif
+    OCStackResult OCSecure::setInputPinCallback(InputPinCallback inputPin)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
         {
-            oclog() <<"for OXM type DEVICE_PIN, inputPin callback can't be null";
-            return OC_STACK_INVALID_PARAM;
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetInputPinCB(inputPin);
+            result = OC_STACK_OK;
         }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
 
+    OCStackResult OCSecure::unsetInputPinCallback()
+    {
         OCStackResult result;
         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
 
         if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCSetOwnerTransferCallbackData(oxm, callbackData);
-            if (result == OC_STACK_OK && (OIC_RANDOM_DEVICE_PIN == oxm))
-            {
-                SetInputPinCB(inputPin);
-            }
+            UnsetInputPinCB();
+            result = OC_STACK_OK;
         }
         else
         {
@@ -195,7 +339,24 @@ namespace OC
         }
 
         return result;
+    }
 
+    OCStackResult OCSecure::setRandomPinPolicy(size_t pinSize, OicSecPinType_t pinType)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = SetRandomPinPolicy(pinSize, pinType);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
     }
 
     OCStackResult OCSecure::getDevInfoFromNetwork(unsigned short timeout,
@@ -309,37 +470,416 @@ namespace OC
         return result;
     }
 
-#if defined(__WITH_X509__) || defined(__WITH_TLS__)
-    OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
-                                        OicEncodingType_t encodingType, uint16_t *credId)
+    OCStackResult OCSecure::saveACL(const OicSecAcl_t* acl)
+    {
+        if (!acl)
+        {
+            oclog() <<"ACL can't be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSaveACL(const_cast<OicSecAcl_t*>(acl));
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::displayNumCallbackWrapper(void* ctx,
+            uint8_t verifNum[MUTUAL_VERIF_NUM_LEN])
+    {
+        uint8_t *number = NULL;
+
+        DisplayNumContext* context = static_cast<DisplayNumContext*>(ctx);
+        if (!context)
+        {
+            oclog() << "Invalid context";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        if (NULL != verifNum) {
+            number = new uint8_t[MUTUAL_VERIF_NUM_LEN];
+            memcpy(number, verifNum, MUTUAL_VERIF_NUM_LEN);
+        }
+
+        return context->callback(number);
+    }
+
+    OCStackResult OCSecure::registerDisplayNumCallback(DisplayNumCB displayNumCB)
+    {
+        if(!displayNumCB)
+        {
+            oclog() << "Failed to register callback for display.";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result = OCSecure::deregisterDisplayNumCallback();
+        if (OC_STACK_OK != result)
+        {
+            oclog() << "Failed to de-register callback for display."<<std::endl;
+            return result;
+        }
+
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            DisplayNumContext* context = new DisplayNumContext(displayNumCB);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetDisplayNumCB(static_cast<void*>(context), &OCSecure::displayNumCallbackWrapper);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::deregisterDisplayNumCallback()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            DisplayNumContext* context = static_cast<DisplayNumContext*>(UnsetDisplayNumCB());
+            if (context)
+            {
+                oclog() << "Delete registered display num context"<<std::endl;
+                delete context;
+            }
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::confirmUserCallbackWrapper(void* ctx)
+    {
+        UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(ctx);
+        if (!context)
+        {
+            oclog() << "Invalid context";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        return context->callback();
+    }
+
+    OCStackResult OCSecure::registerUserConfirmCallback(UserConfirmNumCB userConfirmCB)
+    {
+        if(!userConfirmCB)
+        {
+            oclog() << "Failed to set callback for confirming verifying callback.";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result = OCSecure::deregisterUserConfirmCallback();
+        if (OC_STACK_OK != result)
+        {
+            oclog() << "Failed to de-register callback for comfirm."<<std::endl;
+            return result;
+        }
+
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            UserConfirmNumContext* context = new UserConfirmNumContext(userConfirmCB);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetUserConfirmCB(static_cast<void*>(context), &OCSecure::confirmUserCallbackWrapper);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::deregisterUserConfirmCallback()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(UnsetUserConfirmCB());
+            if (context)
+            {
+                oclog() << "Delete registered user confirm context"<<std::endl;
+                delete context;
+            }
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::setVerifyOptionMask(VerifyOptionBitmask_t optionMask)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetVerifyOption(optionMask);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::pdmCleanupForTimeout()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            result = OCPDMCleanupForTimeout();
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::configSelfOwnership()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCConfigSelfOwnership();
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
+                                        OicEncodingType_t encodingType, uint16_t *credId)
+    {
+        if (!trustCertChain)
+        {
+            oclog() <<"trustCertChain can't be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (!credId)
+        {
+            oclog() <<"cred ID can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId );
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::readTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
+            size_t *chainSize)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCReadTrustCertChain(credId, trustCertChain, chainSize);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    void OCSecure::certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain,
+            size_t chainSize)
+    {
+        TrustCertChainContext* context = static_cast<TrustCertChainContext*>(ctx);
+        uint8_t *certChain = new uint8_t[chainSize];
+        memcpy(certChain, trustCertChain, chainSize);
+        std::thread exec(context->callback, credId, certChain, chainSize);
+        exec.detach();
+        delete context;
+    }
+
+    OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback)
+    {
+        if (!callback)
+        {
+            oclog() <<"callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            TrustCertChainContext* context = new TrustCertChainContext(callback);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCRegisterTrustCertChainNotifier(static_cast<void*>(context),
+                    &OCSecure::certCallbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+
+    OCStackResult OCSecure::removeTrustCertChangeNotifier()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCRemoveTrustCertChainNotifier();
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::setDeviceIdSeed(const uint8_t* seed, size_t seedSize)
+    {
+        if (!seed)
+        {
+            oclog() <<"seed can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = SetDeviceIdSeed(seed, seedSize);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    int OCSecure::peerCertCallbackWrapper(void *ctx, const mbedtls_x509_crt *cert,
+            int depth)
     {
-        if (!trustCertChain)
+        OCStackResult ret = OC_STACK_ERROR;
+
+        PeerCertContext *context = static_cast<PeerCertContext*>(ctx);
+        if (NULL == context)
         {
-            oclog() <<"trustCertChain can't be null";
-            return OC_STACK_INVALID_PARAM;
+            oclog() << "Invalid Context";
+            return 1;
         }
-        if (!credId)
+
+        if (context->callback)
         {
-            oclog() <<"cred ID can not be null";
-            return OC_STACK_INVALID_PARAM;
+            ret = context->callback(cert, depth);
         }
 
+        if (0 == depth)
+        {
+            delete context;
+        }
+
+        return (OC_STACK_OK == ret)? 0 : 1;
+    }
+
+    OCStackResult OCSecure::setPeerCertCallback(PeerCertCB peerCertCallback)
+    {
         OCStackResult result;
+        // UNSET cb
+        if (NULL == peerCertCallback)
+        {
+            result = OCSetPeerCertCallback(NULL, NULL);
+            if (OC_STACK_OK != result)
+            {
+                oclog() << "OCSetPeerCertCallback() Failed";
+                return result;
+            }
+        }
+
         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
 
         if (cLock)
         {
+            PeerCertContext *context = new PeerCertContext(peerCertCallback);
+
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId );
+            result = OCSetPeerCertCallback(static_cast<void*>(context),
+                    &OCSecure::peerCertCallbackWrapper);
+            if (OC_STACK_OK != result)
+            {
+                oclog() << "OCSetPeerCertCallback() Failed";
+            }
         }
         else
         {
-            oclog() <<"Mutex not found";
+            oclog() << "Mutex not found";
             result = OC_STACK_ERROR;
         }
         return result;
     }
-#endif // __WITH_X509__ || __WITH_TLS__
+
+#endif // __WITH_DTLS__ || __WITH_TLS__
 
     void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
     {
@@ -413,6 +953,46 @@ namespace OC
         return result;
     }
 
+#ifdef MULTIPLE_OWNER
+    OCStackResult OCSecureResource::doMultipleOwnershipTransfer(ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"Result callback can't be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDoMultipleOwnershipTransfer(static_cast<void*>(context),
+                    devPtr, &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::getSubOwnerList(UuidList_t &uuidList)
+    {
+        validateSecureResource();
+        OicSecSubOwner_t* tmp = NULL;
+        for (tmp = devPtr->doxm->subOwners; tmp; tmp = tmp->next)
+        {
+            uuidList.push_back(tmp->uuid);
+        }
+        return OC_STACK_OK;
+    }
+
+#endif
     OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
             ResultCallBack resultCallback)
     {
@@ -633,7 +1213,7 @@ namespace OC
         return result;
     }
 
-#if defined(__WITH_X509__) || defined(__WITH_TLS__)
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
     OCStackResult OCSecureResource::provisionTrustCertChain(OicSecCredType_t type, uint16_t credId,
                     ResultCallBack resultCallback)
     {
@@ -667,7 +1247,7 @@ namespace OC
         }
         return result;
     }
-#endif // __WITH_X509__ || __WITH_TLS__
+#endif // __WITH_DTLS__ or __WITH_TLS__
 
     std::string OCSecureResource::getDeviceID()
     {
@@ -719,4 +1299,247 @@ namespace OC
             throw OCException("Incomplete secure resource", OC_STACK_RESOURCE_ERROR);
         }
     }
+
+    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)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSelectMOTMethod(static_cast<void*>(context),
+                    devPtr, oxmSelVal,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::changeMOTMode( const OicSecMomType_t momType,
+            ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCChangeMOTMode(static_cast<void*>(context),
+                    devPtr, momType,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+
+    OCStackResult OCSecureResource::addPreconfigPIN(const char* preconfPIN,
+            size_t preconfPINLength)
+    {
+        if (!preconfPIN)
+        {
+            oclog() <<"pre config pin can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (preconfPINLength <= 0)
+        {
+            oclog() <<"pre config pin length can not be zero or less";
+            return OC_STACK_INVALID_PARAM;
+        }
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCAddPreconfigPin(devPtr, preconfPIN,
+                    preconfPINLength);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::provisionPreconfPin(const char * preconfPin,
+            size_t preconfPinLength, ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+        if (!preconfPin)
+        {
+            oclog() <<"pre config pin can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (preconfPinLength <= 0)
+        {
+            oclog() <<"pre config pin length can not be zero or less";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCProvisionPreconfigPin(static_cast<void*>(context),
+                    devPtr, preconfPin, preconfPinLength,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::removeSubOwner(const OicUuid_t* subOwnerId, ResultCallBack resultCallback)
+    {
+        validateSecureResource();
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+            result = OCRemoveSubOwner(static_cast<void*>(context),
+                devPtr, subOwnerId, &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() << "Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::removeAllSubOwner(ResultCallBack resultCallback)
+    {
+        validateSecureResource();
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+            result =OCRemoveAllSubOwner(static_cast<void*>(context),
+                devPtr, &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() << "Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+#endif // MULTIPLE_OWNER
 }