Add wrong PIN defence codes in case of PIN based OxM 43/4143/14
authorleechul <chuls.lee@samsung.com>
Wed, 11 Nov 2015 07:33:32 +0000 (16:33 +0900)
committerSachin Agrawal <sachin.agrawal@intel.com>
Fri, 18 Dec 2015 06:35:49 +0000 (06:35 +0000)
 * Add CAErrorCallback in OTM to handle result of DTLS handshake.
 * Our implementation as follows :
    1. Implemente CAErrorCallback(DTLSHandshakeCB) in OTM to handle result of DTLS handshake.
    2. Try dtls handshake.
    3. Wait for handshake result.
    4. Invoke CAErrorCallback(DTLSHandshakeCB) at CAHandleSecureEvent() when handshake is finished.
    5. Handle handshake result in DTLSHandshakeCB.
        - in case of success, we can send next coaps request.
        - in case of failure, return the error value or restart ownership transfer.

Related jira : https://jira.iotivity.org/browse/IOT-831

[Patch #1] Intial upload
[Patch #2] Remove white-space
[Patch #3] Update comment
[Patch #4] Update according to comments
[Patch #5] Revert extlibs/tinydtls/crypto.c to seprate changeset
[Patch #6] Rebase
[Patch #7] Modify the stCADtlsContext_t to save the OTMContext.
[Patch #8] Remove white-space.
[Patch #9] Modify according to sachin's comment.
[Patch #10] Modify according to comments.
[Patch #11] Remove whitespace
[Patch #12] Rebase by sachin
[Patch #13] Update commit message

Change-Id: I034b0e9ad267cb6998ce3df3ce50629583740608
Signed-off-by: leechul <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/4143
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Sachin Agrawal <sachin.agrawal@intel.com>
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/api/cainterface.h
resource/csdk/connectivity/api/casecurityinterface.h
resource/csdk/connectivity/inc/caadapternetdtls.h
resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c
resource/csdk/connectivity/src/caconnectivitymanager.c
resource/csdk/security/provisioning/include/internal/ownershiptransfermanager.h
resource/csdk/security/provisioning/src/ownershiptransfermanager.c [changed mode: 0755->0644]
resource/csdk/stack/include/octypes.h
resource/csdk/stack/src/ocstack.c [changed mode: 0755->0644]

index e975e60..8e20518 100644 (file)
@@ -276,6 +276,7 @@ typedef enum
     CA_DESTINATION_DISCONNECTED,    /**< Destination is disconnected */
     CA_NOT_SUPPORTED,               /**< Not supported */
     CA_STATUS_NOT_INITIALIZED,      /**< Not Initialized*/
+    CA_DTLS_AUTHENTICATION_FAILURE, /**< Decryption error in DTLS */
     CA_STATUS_FAILED =255           /**< Failure */
     /* Result code - END HERE */
 } CAResult_t;
@@ -520,6 +521,30 @@ typedef struct
 
 extern CAGlobals_t caglobals;
 
+/**
+ * Callback function type for request delivery.
+ * @param[out]   object       Endpoint object from which the request is received.
+ *                            It contains endpoint address based on the connectivity type.
+ * @param[out]   requestInfo  Info for resource model to understand about the request.
+ */
+typedef void (*CARequestCallback)(const CAEndpoint_t *object,
+                                  const CARequestInfo_t *requestInfo);
+
+/**
+ * Callback function type for response delivery.
+ * @param[out]   object           Endpoint object from which the response is received.
+ * @param[out]   responseInfo     Identifier which needs to be mapped with response.
+ */
+typedef void (*CAResponseCallback)(const CAEndpoint_t *object,
+                                   const CAResponseInfo_t *responseInfo);
+/**
+ * Callback function type for error.
+ * @param[out]   object           remote device information.
+ * @param[out]   errorInfo        CA Error information.
+ */
+typedef void (*CAErrorCallback)(const CAEndpoint_t *object,
+                                const CAErrorInfo_t *errorInfo);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index eb021c3..832772f 100644 (file)
@@ -38,29 +38,6 @@ extern "C"
 {
 #endif
 
-/**
- * Callback function type for request delivery.
- * @param[out]   object       Endpoint object from which the request is received.
- *                            It contains endpoint address based on the connectivity type.
- * @param[out]   requestInfo  Info for resource model to understand about the request.
- */
-typedef void (*CARequestCallback)(const CAEndpoint_t *object,
-                                  const CARequestInfo_t *requestInfo);
-
-/**
- * Callback function type for response delivery.
- * @param[out]   object           Endpoint object from which the response is received.
- * @param[out]   responseInfo     Identifier which needs to be mapped with response.
- */
-typedef void (*CAResponseCallback)(const CAEndpoint_t *object,
-                                   const CAResponseInfo_t *responseInfo);
-/**
- * Callback function type for error.
- * @param[out]   object           remote device information.
- * @param[out]   errorInfo        CA Error information.
- */
-typedef void (*CAErrorCallback)(const CAEndpoint_t *object,
-                                const CAErrorInfo_t *errorInfo);
 #ifdef RA_ADAPTER
 
 /**
index fb8afdb..cff8681 100644 (file)
@@ -31,6 +31,7 @@
 #include "pki.h"
 #endif //__WITH_X509__
 
+#include "cacommon.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -69,6 +70,13 @@ typedef int (*CAGetDTLSPskCredentialsHandler)( CADtlsPskCredType_t type,
                      const unsigned char *desc, size_t desc_len,
                      unsigned char *result, size_t result_length);
 
+/**
+ * Register callback to receive the result of DTLS handshake.
+ * @param[in] dtlsHandshakeCallback callback for get dtls handshake result
+ * @return ::CA_STATUS_OK
+ */
+CAResult_t CARegisterDTLSHandshakeCallback(CAErrorCallback dtlsHandshakeCallback);
+
 /**
  * Register callback to get DTLS PSK credentials.
  * @param[in]   GetDTLSCredentials    GetDTLS Credetials callback.
index 1ef7fb6..d9f6e81 100644 (file)
@@ -122,6 +122,12 @@ void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
                                CAPacketSendCallback sendCallback,
                                CATransportAdapter_t type);
 
+/**
+ * Register callback to deliver the result of DTLS handshake
+ * @param[in] dtlsHandshakeCallback Callback to receive the result of DTLS handshake.
+ */
+void CADTLSSetHandshakeCallback(CAErrorCallback dtlsHandshakeCallback);
+
 /**
  * Register callback to get DTLS PSK credentials.
  * @param[in]  credCallback    callback to get DTLS PSK credentials.
index 4687c6e..36d7b75 100644 (file)
@@ -64,6 +64,12 @@ static ca_mutex g_dtlsContextMutex = NULL;
  */
 static CAGetDTLSPskCredentialsHandler g_getCredentialsCallback = NULL;
 
+/**
+ * @var g_dtlsHandshakeCallback
+ * @brief callback to deliver the DTLS handshake result
+ */
+static CAErrorCallback g_dtlsHandshakeCallback = NULL;
+
 #ifdef __WITH_X509__
 /**
  * @var g_getX509CredentialsCallback
@@ -77,6 +83,7 @@ static CAGetDTLSX509CredentialsHandler g_getX509CredentialsCallback = NULL;
 static CAGetDTLSCrlHandler g_getCrlCallback = NULL;
 #endif //__WITH_X509__
 
+
 static CASecureEndpoint_t *GetPeerInfo(const CAEndpoint_t *peer)
 {
     uint32_t list_index = 0;
@@ -500,22 +507,44 @@ static int32_t CAHandleSecureEvent(dtls_context_t *context,
 
     VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
 
-    OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]", level, code);
+    OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]\n", level, code);
 
-    if (!level && (code == DTLS_EVENT_CONNECTED))
+    CAEndpoint_t endpoint = {.adapter=CA_DEFAULT_ADAPTER};
+    CAErrorInfo_t errorInfo = {.result=CA_STATUS_OK};
+
+    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
+    char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
+    uint16_t port = 0;
+    CAConvertAddrToName(&(addrInfo->addr.st), addrInfo->size, peerAddr, &port);
+
+    if (!level && (DTLS_EVENT_CONNECTED == code))
     {
         OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
+
+        if(g_dtlsHandshakeCallback)
+        {
+            OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, peerAddr);
+            endpoint.port = port;
+            errorInfo.result = CA_STATUS_OK;
+            g_dtlsHandshakeCallback(&endpoint, &errorInfo);
+        }
+
         CASendCachedMsg((stCADtlsAddrInfo_t *)session);
     }
-
-    if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code)
+    else if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_DECRYPT_ERROR == code)
+    {
+        if(g_dtlsHandshakeCallback)
+        {
+            OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, peerAddr);
+            endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
+            endpoint.port = port;
+            errorInfo.result = CA_DTLS_AUTHENTICATION_FAILURE;
+            g_dtlsHandshakeCallback(&endpoint, &errorInfo);
+        }
+    }
+    else if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code)
     {
         OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection");
-
-        stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
-        char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
-        uint16_t port = 0;
-        CAConvertAddrToName(&(addrInfo->addr.st), addrInfo->size, peerAddr, &port);
         CARemovePeerFromPeerInfoList(peerAddr, port);
     }
 
@@ -589,6 +618,13 @@ void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
 }
 
+void CADTLSSetHandshakeCallback(CAErrorCallback dtlsHandshakeCallback)
+{
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+    g_dtlsHandshakeCallback = dtlsHandshakeCallback;
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+}
+
 void CADTLSSetCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback)
 {
     // TODO Does this method needs protection of DtlsContextMutex ?
index edc9d85..8cf6a0d 100644 (file)
@@ -147,6 +147,20 @@ void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHand
 }
 
 #ifdef __WITH_DTLS__
+CAResult_t CARegisterDTLSHandshakeCallback(CAErrorCallback dtlsHandshakeCallback)
+{
+    OIC_LOG(DEBUG, TAG, "CARegisterDTLSHandshakeCallback");
+
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+
+    CADTLSSetHandshakeCallback(dtlsHandshakeCallback);
+
+    return CA_STATUS_OK;
+}
+
 CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentialsHandler)
 {
     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
@@ -387,7 +401,6 @@ CAResult_t CAHandleRequestResponse()
 }
 
 #ifdef __WITH_DTLS__
-
 CAResult_t CASelectCipherSuite(const uint16_t cipher)
 {
     OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
index bcd7b8a..bf7deed 100644 (file)
@@ -31,19 +31,20 @@ extern "C" {
 #endif // __cplusplus\r
 \r
 #define OXM_STRING_MAX_LENGTH 32\r
-\r
+#define WRONG_PIN_MAX_ATTEMP 5\r
 \r
 /**\r
  * Context for ownership transfer(OT)\r
  */\r
 typedef struct OTMContext{\r
-    void* userCtx;                         /**< Context for user.*/\r
-    OCProvisionDev_t* selectedDeviceInfo;  /**< Selected device info for OT. */\r
-    OicUuid_t subIdForPinOxm;              /**< Subject Id which uses PIN based OTM. */\r
-    OCProvisionResultCB ctxResultCallback; /**< Function pointer to store result callback. */\r
-    OCProvisionResult_t* ctxResultArray;   /**< Result array having result of all device. */\r
-    size_t ctxResultArraySize;             /**< No of elements in result array. */\r
-    bool ctxHasError;                      /**< Does OT process have any error. */\r
+    void* userCtx;                            /**< Context for user.*/\r
+    OCProvisionDev_t* selectedDeviceInfo;     /**< Selected device info for OT. */\r
+    OicUuid_t subIdForPinOxm;                 /**< Subject Id which uses PIN based OTM. */\r
+    OCProvisionResultCB ctxResultCallback;    /**< Function pointer to store result callback. */\r
+    OCProvisionResult_t* ctxResultArray;      /**< Result array having result of all device. */\r
+    size_t ctxResultArraySize;                /**< No of elements in result array. */\r
+    bool ctxHasError;                         /**< Does OT process have any error. */\r
+    int attemptCnt;\r
 }OTMContext_t;\r
 \r
 /**\r
@@ -95,7 +96,6 @@ typedef struct OTMCallbackData{
  */\r
 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxm, OTMCallbackData_t* callbackData);\r
 \r
-\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
old mode 100755 (executable)
new mode 100644 (file)
index 6ac1ff0..7adeb46
@@ -79,6 +79,11 @@ static OicSecDpom_t gProvisioningToolCapability[] = { SINGLE_SERVICE_CLIENT_DRIV
  */
 static size_t gNumOfProvisioningMethodsPT = 1;
 
+/**
+ * Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
+ */
+static OTMContext_t* g_otmCtx = NULL;
+
 /**
  * Function to getting string of ownership transfer method
  */
@@ -220,7 +225,6 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
  */
 static OCStackResult FinalizeProvisioning(OTMContext_t* otmCtx);
 
-
 static bool IsComplete(OTMContext_t* otmCtx)
 {
     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
@@ -242,7 +246,7 @@ static bool IsComplete(OTMContext_t* otmCtx)
  */
 static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
 {
-    OC_LOG(DEBUG, TAG, "IN SetResult");
+    OC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
 
     if(!otmCtx)
     {
@@ -265,6 +269,8 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
             }
         }
 
+        g_otmCtx = NULL;
+
         //If all request is completed, invoke the user callback.
         if(IsComplete(otmCtx))
         {
@@ -286,6 +292,79 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
     OC_LOG(DEBUG, TAG, "OUT SetResult");
 }
 
+/**
+ * Function to handle the handshake result in OTM.
+ * This function will be invoked after DTLS handshake
+ * @param   endPoint  [IN] The remote endpoint.
+ * @param   errorInfo [IN] Error information from the endpoint.
+ * @return  NONE
+ */
+void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
+{
+    if(g_otmCtx && endpoint && info)
+    {
+        OC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
+                 endpoint->addr, endpoint->port, info->result);
+
+        //Make sure the address matches.
+        if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr,
+           endpoint->addr,
+           sizeof(endpoint->addr)) == 0 &&
+           g_otmCtx->selectedDeviceInfo->securePort == endpoint->port)
+        {
+            OCStackResult res;
+
+            CARegisterDTLSHandshakeCallback(NULL);
+
+            //In case of success, send next coaps request.
+            if(CA_STATUS_OK == info->result)
+            {
+                //Send request : PUT /oic/sec/doxm [{"Owned":"True", .. , "Owner":"PT's UUID"}]
+                res = PutOwnershipInformation(g_otmCtx);
+                if(OC_STACK_OK != res)
+                {
+                    OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
+                    SetResult(g_otmCtx, res);
+                }
+            }
+            //In case of failure, re-start the ownership transfer in case of PIN OxM
+            else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
+            {
+                g_otmCtx->selectedDeviceInfo->doxm->owned = false;
+                g_otmCtx->attemptCnt++;
+
+                if(g_otmCtx->selectedDeviceInfo->doxm->oxmSel == OIC_RANDOM_DEVICE_PIN)
+                {
+                    res = RemoveCredential(&g_otmCtx->subIdForPinOxm);
+                    if(OC_STACK_RESOURCE_DELETED != res)
+                    {
+                        OC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
+                        SetResult(g_otmCtx, res);
+                        return;
+                    }
+
+                    if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt)
+                    {
+                        res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo);
+                        if(OC_STACK_OK != res)
+                        {
+                            SetResult(g_otmCtx, res);
+                            OC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
+                        }
+                    }
+                    else
+                    {
+                        SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
+                    }
+                }
+                else
+                {
+                    SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
+                }
+            }
+        }
+    }
+}
 
 /**
  * Function to save ownerPSK at provisioning tool end.
@@ -488,60 +567,66 @@ static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandl
     (void)UNUSED;
     OCStackResult res = OC_STACK_OK;
     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
-    if  (OC_STACK_OK == clientResponse->result)
+
+    if(OC_STACK_OK == clientResponse->result)
     {
-        if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
+        if(otmCtx && otmCtx->selectedDeviceInfo)
         {
-            res = RemoveCredential(&otmCtx->subIdForPinOxm);
-            if(OC_STACK_RESOURCE_DELETED != res)
+            if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
             {
-                OC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
-                return OC_STACK_DELETE_TRANSACTION;
+                res = RemoveCredential(&otmCtx->subIdForPinOxm);
+                if(OC_STACK_RESOURCE_DELETED != res)
+                {
+                    OC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
+                    return OC_STACK_DELETE_TRANSACTION;
+                }
             }
-        }
 
-        res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
-        if(OC_STACK_OK != res)
-        {
-            OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to owner PSK generation");
-            SetResult(otmCtx, res);
-            return OC_STACK_DELETE_TRANSACTION;
-        }
+            res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
+            if(OC_STACK_OK != res)
+            {
+                OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to owner PSK generation");
+                SetResult(otmCtx, res);
+                return OC_STACK_DELETE_TRANSACTION;
+            }
 
-        CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
-        endpoint->port = otmCtx->selectedDeviceInfo->securePort;
-        CAResult_t caResult = CACloseDtlsSession(endpoint);
-        if(CA_STATUS_OK != caResult)
-        {
-            OC_LOG(ERROR, TAG, "Failed to close DTLS session");
-            SetResult(otmCtx, caResult);
-            return OC_STACK_DELETE_TRANSACTION;
-        }
+            CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
+            endpoint->port = otmCtx->selectedDeviceInfo->securePort;
+            CAResult_t caResult = CACloseDtlsSession(endpoint);
+            if(CA_STATUS_OK != caResult)
+            {
+                OC_LOG(ERROR, TAG, "Failed to close DTLS session");
+                SetResult(otmCtx, caResult);
+                return OC_STACK_DELETE_TRANSACTION;
+            }
 
-        /**
-         * If we select NULL cipher,
-         * client will select appropriate cipher suite according to server's cipher-suite list.
-         */
-        caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL);
-        if(CA_STATUS_OK != caResult)
-        {
-            OC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
-            SetResult(otmCtx, caResult);
-            return OC_STACK_DELETE_TRANSACTION;
-        }
+            /**
+             * If we select NULL cipher,
+             * client will select appropriate cipher suite according to server's cipher-suite list.
+             */
+            caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL);
+            if(CA_STATUS_OK != caResult)
+            {
+                OC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
+                SetResult(otmCtx, caResult);
+                return OC_STACK_DELETE_TRANSACTION;
+            }
 
-        OC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
-        OC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
+            OC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
+            OC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
 
-        res = FinalizeProvisioning(otmCtx);
-        if(OC_STACK_OK != res)
-        {
-            SetResult(otmCtx, res);
+            res = FinalizeProvisioning(otmCtx);
+            if(OC_STACK_OK != res)
+            {
+                SetResult(otmCtx, res);
+            }
         }
     }
     else
     {
         res = clientResponse->result;
+        OC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
+        SetResult(otmCtx, res);
     }
 
     OC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
@@ -586,6 +671,9 @@ static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle
             }
         }
 
+        //It will be used in handshake event handler
+        g_otmCtx = otmCtx;
+
         //Try DTLS handshake to generate secure session
         if(g_OTMDatas[selOxm].createSecureSessionCB)
         {
@@ -597,14 +685,6 @@ static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle
                 return OC_STACK_DELETE_TRANSACTION;
             }
         }
-
-        //Send request : PUT /oic/sec/doxm [{"Owned":"True", .. , "Owner":"PT's UUID"}]
-        res = PutOwnershipInformation(otmCtx);
-        if(OC_STACK_OK != res)
-        {
-            OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
-            SetResult(otmCtx, res);
-        }
     }
     else
     {
@@ -757,6 +837,7 @@ static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx)
     cbData.cb = &OwnershipInformationHandler;
     cbData.context = (void *)otmCtx;
     cbData.cd = NULL;
+
     OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
                                      deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
     if (res != OC_STACK_OK)
@@ -851,6 +932,12 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
         return res;
     }
 
+    //Register DTLS event handler to catch the dtls event while handshake
+    if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DTLSHandshakeCB))
+    {
+        OC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register DTLS handshake callback.");
+    }
+
     OC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
 
     return res;
@@ -925,24 +1012,22 @@ OCStackResult OTMDoOwnershipTransfer(void* ctx,
     }
     pCurDev = selectedDevicelist;
 
+    OCStackResult res = OC_STACK_OK;
     //Fill the device UUID for result array.
     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
     {
         //Checking duplication of Device ID.
         bool isDuplicate = true;
-        OCStackResult res = PDMIsDuplicateDevice(&pCurDev->doxm->deviceID, &isDuplicate);
+        res = PDMIsDuplicateDevice(&pCurDev->doxm->deviceID, &isDuplicate);
         if (OC_STACK_OK != res)
         {
-            OICFree(otmCtx->ctxResultArray);
-            OICFree(otmCtx);
-            return res;
+            goto error;
         }
         if (isDuplicate)
         {
             OC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Device ID is duplicated");
-            OICFree(otmCtx->ctxResultArray);
-            OICFree(otmCtx);
-            return OC_STACK_INVALID_PARAM;
+            res = OC_STACK_INVALID_PARAM;
+            goto error;
         }
         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
                pCurDev->doxm->deviceID.id,
@@ -950,10 +1035,17 @@ OCStackResult OTMDoOwnershipTransfer(void* ctx,
         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
         pCurDev = pCurDev->next;
     }
+
     StartOwnershipTransfer(otmCtx, selectedDevicelist);
 
     OC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
     return OC_STACK_OK;
+
+error:
+    OICFree(otmCtx->ctxResultArray);
+    OICFree(otmCtx);
+    return res;
+
 }
 
 /**
index 8cf3c16..bea5b00 100644 (file)
@@ -705,6 +705,12 @@ typedef enum
     OC_STACK_DUPLICATE_UUID,
     OC_STACK_INCONSISTENT_DB,
 
+    /**
+     * Error code from OTM
+     * This error is plused from DTLS interface when handshake failure happens
+     */
+    OC_STACK_AUTHENTICATION_FAILURE,
+
     /** Insert all new error codes here!.*/
     #ifdef WITH_PRESENCE
     OC_STACK_PRESENCE_STOPPED = 128,
old mode 100755 (executable)
new mode 100644 (file)