Fixed bug of pstat during OTM
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / ownershiptransfermanager.c
1 /* *****************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * *****************************************************************/
20
21 // Defining _POSIX_C_SOURCE macro with 199309L (or greater) as value
22 // causes header files to expose definitions
23 // corresponding to the POSIX.1b, Real-time extensions
24 // (IEEE Std 1003.1b-1993) specification
25 //
26 // For this specific file, see use of clock_gettime,
27 // Refer to http://pubs.opengroup.org/stage7tc1/functions/clock_gettime.html
28 // and to http://man7.org/linux/man-pages/man2/clock_gettime.2.html
29 #ifndef _POSIX_C_SOURCE
30 #define _POSIX_C_SOURCE 200809L
31 #endif
32
33 #include <time.h>
34 #include <unistd.h>
35 #include <sys/time.h>
36 #include <stdbool.h>
37 #include <string.h>
38
39 #include "logger.h"
40 #include "oic_malloc.h"
41 #include "oic_string.h"
42 #include "cacommon.h"
43 #include "cainterface.h"
44 #include "base64.h"
45 #include "cJSON.h"
46 #include "global.h"
47
48 #include "srmresourcestrings.h"
49 #include "doxmresource.h"
50 #include "pstatresource.h"
51 #include "credresource.h"
52 #include "aclresource.h"
53 #include "ownershiptransfermanager.h"
54 #include "securevirtualresourcetypes.h"
55 #include "oxmjustworks.h"
56 #include "pmtypes.h"
57 #include "pmutility.h"
58 #include "srmutility.h"
59 #include "provisioningdatabasemanager.h"
60 #include "oxmrandompin.h"
61 #include "ocpayload.h"
62 #include "payload_logging.h"
63
64 #define TAG "OTM"
65
66 /**
67  * Array to store the callbacks for each owner transfer method.
68  */
69 static OTMCallbackData_t g_OTMDatas[OIC_OXM_COUNT];
70
71 /**
72  * Variable for storing provisioning tool's provisioning capabilities
73  * Must be in decreasing order of preference. More prefered method should
74  * have lower array index.
75  */
76 static OicSecDpom_t gProvisioningToolCapability[] = { SINGLE_SERVICE_CLIENT_DRIVEN };
77
78 /**
79  * Number of supported provisioning methods
80  * current version supports only one.
81  */
82 static size_t gNumOfProvisioningMethodsPT = 1;
83
84 /**
85  * Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
86  */
87 static OTMContext_t* g_otmCtx = NULL;
88
89 /**
90  * Function to select appropriate  provisioning method.
91  *
92  * @param[in] supportedMethods   Array of supported methods
93  * @param[in] numberOfMethods   number of supported methods
94  * @param[out]  selectedMethod         Selected methods
95  * @return  OC_STACK_OK on success
96  */
97 static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
98         size_t numberOfMethods, OicSecOxm_t *selectedMethod)
99 {
100     OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
101
102     if(numberOfMethods == 0 || !supportedMethods)
103     {
104         OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
105         return OC_STACK_ERROR;
106     }
107
108     *selectedMethod  = supportedMethods[0];
109     for(size_t i = 0; i < numberOfMethods; i++)
110     {
111         if(*selectedMethod < supportedMethods[i])
112         {
113             *selectedMethod =  supportedMethods[i];
114         }
115     }
116
117     return OC_STACK_OK;
118 }
119
120 /**
121  * Function to select operation mode.This function will return most secure common operation mode.
122  *
123  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
124  * @param[out]   selectedMode   selected operation mode
125  * @return  OC_STACK_OK on success
126  */
127 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
128                                 OicSecDpom_t *selectedMode)
129 {
130     OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
131
132     size_t i = 0;
133     size_t j = 0;
134
135     while (i < gNumOfProvisioningMethodsPT && j < selectedDeviceInfo->pstat->smLen)
136     {
137         if (gProvisioningToolCapability[i] < selectedDeviceInfo->pstat->sm[j])
138         {
139             i++;
140         }
141         else if (selectedDeviceInfo->pstat->sm[j] < gProvisioningToolCapability[i])
142         {
143             j++;
144         }
145         else /* if gProvisioningToolCapability[i] == deviceSupportedMethods[j] */
146         {
147             *selectedMode = gProvisioningToolCapability[j];
148             break;
149         }
150     }
151     OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
152
153     OIC_LOG(DEBUG, TAG, "OUT SelectOperationMode");
154 }
155
156 /**
157  * Function to start ownership transfer.
158  * This function will send the first request for provisioning,
159  * The next request message is sent from the response handler for this request.
160  *
161  * @param[in] ctx   context value passed to callback from calling function.
162  * @param[in] selectedDevice   selected device information to performing provisioning.
163  * @return  OC_STACK_OK on success
164  */
165 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
166
167 /**
168  * Function to update owner transfer mode
169  *
170  * @param[in]  otmCtx  Context value of ownership transfer.
171  * @return  OC_STACK_OK on success
172  */
173 static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx);
174
175 /**
176  * Function to send request to resource to get its pstat resource information.
177  *
178  * @param[in]  otmCtx  Context value of ownership transfer.
179  * @return  OC_STACK_OK on success
180  */
181 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
182
183
184 /**
185  * Function to send  uuid of owner device to new device.
186  * This function would update 'owner of doxm' as UUID for provisioning tool.
187  *
188  * @param[in]  otmCtx  Context value of ownership transfer.
189  * @return  OC_STACK_OK on success
190  */
191 static OCStackResult PutOwnerUuid(OTMContext_t* otmCtx);
192
193 /**
194  * Function to update the operation mode. As per the spec. Operation mode in client driven
195  * single service provisioning it will be updated to 0x3
196  *
197  * @param[in]  otmCtx  Context value of ownership transfer.
198  * @return  OC_STACK_OK on success
199  */
200 static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx);
201
202 /**
203  * Function to update the owner credential to new device
204  *
205  * @param[in]  otmCtx  Context value of ownership transfer.
206  * @param[in] selectedOperationMode selected operation mode
207  * @return  OC_STACK_OK on success
208  */
209 static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx);
210
211 /**
212  * Function to send ownerShip info.
213  * This function would update 'owned of doxm' as true.
214  *
215  * @param[in]  otmCtx  Context value of ownership transfer.
216  * @return  OC_STACK_OK on success
217  */
218 static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx);
219
220 /**
221  * Function to update pstat when finalize provisioning.
222  * This function would update 'cm' as bx0011,1100 and 'tm' as bx0000,0000.
223  *
224  * @param[in] ctx   context value passed to callback from calling function.
225  * @param[in] selectedDevice   selected device information to performing provisioning.
226  * @return  OC_STACK_OK on success
227  */
228 static OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx);
229
230 static bool IsComplete(OTMContext_t* otmCtx)
231 {
232     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
233     {
234         if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
235         {
236             return false;
237         }
238     }
239
240     return true;
241 }
242
243 /**
244  * Function to save the result of provisioning.
245  *
246  * @param[in,out] otmCtx   Context value of ownership transfer.
247  * @param[in] res   result of provisioning
248  */
249 static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
250 {
251     OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
252
253     if(!otmCtx)
254     {
255         OIC_LOG(WARNING, TAG, "OTMContext is NULL");
256         return;
257     }
258
259     if(otmCtx->selectedDeviceInfo)
260     {
261         //Revert psk_info callback and new deivce uuid in case of random PIN OxM
262         if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
263         {
264             if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
265             {
266                 OIC_LOG(WARNING, TAG, "Failed to revert  is DTLS credential handler.");
267             }
268             OicUuid_t emptyUuid = { .id={0}};
269             SetUuidForRandomPinOxm(&emptyUuid);
270         }
271
272         for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
273         {
274             if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
275                       otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
276             {
277                 otmCtx->ctxResultArray[i].res = res;
278                 if(OC_STACK_OK != res)
279                 {
280                     otmCtx->ctxHasError = true;
281                 }
282             }
283         }
284
285         g_otmCtx = NULL;
286
287         //If all request is completed, invoke the user callback.
288         if(IsComplete(otmCtx))
289         {
290             otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
291                                        otmCtx->ctxResultArray, otmCtx->ctxHasError);
292             OICFree(otmCtx->ctxResultArray);
293             OICFree(otmCtx);
294         }
295         else
296         {
297             if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
298                                                      otmCtx->selectedDeviceInfo->next))
299             {
300                 OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
301             }
302         }
303     }
304
305     OIC_LOG(DEBUG, TAG, "OUT SetResult");
306 }
307
308 /**
309  * Function to handle the handshake result in OTM.
310  * This function will be invoked after DTLS handshake
311  * @param   endPoint  [IN] The remote endpoint.
312  * @param   errorInfo [IN] Error information from the endpoint.
313  * @return  NONE
314  */
315 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
316 {
317     if(NULL != g_otmCtx && NULL != g_otmCtx->selectedDeviceInfo &&
318        NULL != endpoint && NULL != info)
319     {
320         OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
321                  endpoint->addr, endpoint->port, info->result);
322
323         OicSecDoxm_t* newDevDoxm = g_otmCtx->selectedDeviceInfo->doxm;
324
325         if(NULL != newDevDoxm)
326         {
327             OicUuid_t emptyUuid = {.id={0}};
328
329             //Make sure the address matches.
330             if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr,
331                endpoint->addr,
332                sizeof(endpoint->addr)) == 0 &&
333                g_otmCtx->selectedDeviceInfo->securePort == endpoint->port)
334             {
335                 OCStackResult res = OC_STACK_ERROR;
336
337                 //If temporal secure sesstion established successfully
338                 if(CA_STATUS_OK == info->result &&
339                    false == newDevDoxm->owned &&
340                    memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0)
341                 {
342                     //Send request : PUT /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
343                     res = PutOwnerUuid(g_otmCtx);
344                     if(OC_STACK_OK != res)
345                     {
346                         OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
347                         SetResult(g_otmCtx, res);
348                     }
349                 }
350                 //In case of authentication failure
351                 else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
352                 {
353                     //in case of error from owner credential
354                     if(memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0 &&
355                         true == newDevDoxm->owned)
356                     {
357                         OIC_LOG(ERROR, TAG, "The owner credential may incorrect.");
358
359                         if(OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID)))
360                         {
361                             OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
362                         }
363                         SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
364                     }
365                     //in case of error from wrong PIN, re-start the ownership transfer
366                     else if(OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel)
367                     {
368                         OIC_LOG(ERROR, TAG, "The PIN number may incorrect.");
369
370                         memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
371                         newDevDoxm->owned = false;
372                         g_otmCtx->attemptCnt++;
373
374                         if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt)
375                         {
376                             res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo);
377                             if(OC_STACK_OK != res)
378                             {
379                                 SetResult(g_otmCtx, res);
380                                 OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
381                             }
382                         }
383                         else
384                         {
385                             OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
386                             SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
387                         }
388                     }
389                     else
390                     {
391                         OIC_LOG(ERROR, TAG, "Failed to establish secure session.");
392                         SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
393                     }
394                 }
395             }
396         }
397     }
398 }
399
400 /**
401  * Function to save ownerPSK at provisioning tool end.
402  *
403  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
404  * @return  OC_STACK_OK on success
405  */
406 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
407 {
408     OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
409
410     OCStackResult res = OC_STACK_ERROR;
411
412     CAEndpoint_t endpoint;
413     memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
414     OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
415     endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
416     endpoint.port = selectedDeviceInfo->securePort;
417
418     OicUuid_t ptDeviceID = {.id={0}};
419     if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
420     {
421         OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
422         return res;
423     }
424
425     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
426     OicSecKey_t ownerKey = {ownerPSK, OWNER_PSK_LENGTH_128};
427
428     //Generating OwnerPSK
429     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
430             (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
431             strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
432             ptDeviceID.id, sizeof(ptDeviceID.id),
433             selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
434             ownerPSK, OWNER_PSK_LENGTH_128);
435
436     if (CA_STATUS_OK == pskRet)
437     {
438         OIC_LOG(INFO, TAG,"ownerPSK dump:\n");
439         OIC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
440         //Generating new credential for provisioning tool
441         size_t ownLen = 1;
442
443         OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
444                 SYMMETRIC_PAIR_WISE_KEY, NULL,
445                 &ownerKey, ownLen, &ptDeviceID);
446         VERIFY_NON_NULL(TAG, cred, ERROR);
447
448         res = AddCredential(cred);
449         if(res != OC_STACK_OK)
450         {
451             DeleteCredList(cred);
452             return res;
453         }
454     }
455     else
456     {
457         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
458     }
459
460     OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
461 exit:
462     return res;
463 }
464
465 /**
466  * Callback handler for OwnerShipTransferModeHandler API.
467  *
468  * @param[in] ctx             ctx value passed to callback from calling function.
469  * @param[in] UNUSED          handle to an invocation
470  * @param[in] clientResponse  Response from queries to remote servers.
471  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
472  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
473  */
474 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
475                                                          OCClientResponse *clientResponse)
476 {
477     OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
478
479     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
480     VERIFY_NON_NULL(TAG, ctx, WARNING);
481
482     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
483     (void)UNUSED;
484     if(clientResponse->result == OC_STACK_OK)
485     {
486         OIC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
487         //Send request : GET /oic/sec/pstat
488         OCStackResult res = GetProvisioningStatusResource(otmCtx);
489         if(OC_STACK_OK != res)
490         {
491             OIC_LOG(WARNING, TAG, "Failed to get pstat information");
492             SetResult(otmCtx, res);
493         }
494     }
495     else
496     {
497         OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
498         clientResponse->result);
499         SetResult(otmCtx, clientResponse->result);
500     }
501
502     OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
503
504 exit:
505     return  OC_STACK_DELETE_TRANSACTION;
506 }
507
508 /**
509  * Callback handler for ProvisioningStatusResouceHandler API.
510  *
511  * @param[in] ctx             ctx value passed to callback from calling function.
512  * @param[in] UNUSED          handle to an invocation
513  * @param[in] clientResponse  Response from queries to remote servers.
514  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
515  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
516  */
517 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
518                                                     OCClientResponse *clientResponse)
519 {
520     OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
521
522     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
523     VERIFY_NON_NULL(TAG, ctx, WARNING);
524
525     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
526     (void)UNUSED;
527     if  (OC_STACK_OK == clientResponse->result)
528     {
529         if  (NULL == clientResponse->payload)
530         {
531             OIC_LOG(INFO, TAG, "Skiping Null payload");
532             SetResult(otmCtx, OC_STACK_ERROR);
533             return OC_STACK_DELETE_TRANSACTION;
534         }
535
536         if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
537         {
538             OIC_LOG(INFO, TAG, "Unknown payload type");
539             SetResult(otmCtx, OC_STACK_ERROR);
540             return OC_STACK_DELETE_TRANSACTION;
541         }
542         OicSecPstat_t* pstat = NULL;
543         OCStackResult result = CBORPayloadToPstat(
544                 ((OCSecurityPayload*)clientResponse->payload)->securityData1,
545                 ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
546                 &pstat);
547         if(NULL == pstat && result != OC_STACK_OK)
548         {
549             OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
550             SetResult(otmCtx, OC_STACK_ERROR);
551             return OC_STACK_DELETE_TRANSACTION;
552         }
553         if(false == (TAKE_OWNER & pstat->cm))
554         {
555             OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
556             SetResult(otmCtx, OC_STACK_ERROR);
557             return OC_STACK_DELETE_TRANSACTION;
558         }
559         otmCtx->selectedDeviceInfo->pstat = pstat;
560
561         //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
562         SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
563
564         //Send request : PUT /oic/sec/pstat [{"om":"bx11", .. }]
565         OCStackResult res = PutUpdateOperationMode(otmCtx);
566         if (OC_STACK_OK != res)
567         {
568             OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
569             SetResult(otmCtx, res);
570         }
571     }
572     else
573     {
574         OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
575             clientResponse->result);
576         SetResult(otmCtx, clientResponse->result);
577     }
578
579     OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
580 exit:
581     return  OC_STACK_DELETE_TRANSACTION;
582 }
583
584 /**
585  * Response handler for update owner uuid request.
586  *
587  * @param[in] ctx             ctx value passed to callback from calling function.
588  * @param[in] UNUSED          handle to an invocation
589  * @param[in] clientResponse  Response from queries to remote servers.
590  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
591  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
592  */
593 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
594                                 OCClientResponse *clientResponse)
595 {
596     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
597     VERIFY_NON_NULL(TAG, ctx, WARNING);
598
599     OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
600     (void)UNUSED;
601     OCStackResult res = OC_STACK_OK;
602     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
603
604     if(OC_STACK_OK == clientResponse->result)
605     {
606         if(otmCtx && otmCtx->selectedDeviceInfo)
607         {
608             res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
609             if(OC_STACK_OK != res)
610             {
611                 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
612                 SetResult(otmCtx, res);
613                 return OC_STACK_DELETE_TRANSACTION;
614             }
615
616             //PUT owner credential to new device according to security spec B.
617             res = PutOwnerCredential(otmCtx);
618             if(OC_STACK_OK != res)
619             {
620                 OIC_LOG(ERROR, TAG,
621                         "OwnerUuidUpdateHandler:Failed to send PUT request for onwer credential");
622                 SetResult(otmCtx, res);
623                 return OC_STACK_DELETE_TRANSACTION;
624             }
625         }
626     }
627     else
628     {
629         res = clientResponse->result;
630         OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
631         SetResult(otmCtx, res);
632     }
633
634     OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
635
636 exit:
637     return  OC_STACK_DELETE_TRANSACTION;
638 }
639
640 /**
641  * Response handler for update operation mode.
642  *
643  * @param[in] ctx             ctx value passed to callback from calling function.
644  * @param[in] UNUSED          handle to an invocation
645  * @param[in] clientResponse  Response from queries to remote servers.
646  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
647  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
648  */
649 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
650                                 OCClientResponse *clientResponse)
651 {
652     OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
653
654     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
655     VERIFY_NON_NULL(TAG, ctx, WARNING);
656
657     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
658     (void) UNUSED;
659     if  (OC_STACK_OK == clientResponse->result)
660     {
661         OCStackResult res = OC_STACK_ERROR;
662         OicSecOxm_t selOxm = otmCtx->selectedDeviceInfo->doxm->oxmSel;
663         //DTLS Handshake
664         //Load secret for temporal secure session.
665         if(g_OTMDatas[selOxm].loadSecretCB)
666         {
667             res = g_OTMDatas[selOxm].loadSecretCB(otmCtx);
668             if(OC_STACK_OK != res)
669             {
670                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
671                 SetResult(otmCtx, res);
672                 return  OC_STACK_DELETE_TRANSACTION;
673             }
674         }
675
676         //It will be used in handshake event handler
677         g_otmCtx = otmCtx;
678
679         //Try DTLS handshake to generate secure session
680         if(g_OTMDatas[selOxm].createSecureSessionCB)
681         {
682             res = g_OTMDatas[selOxm].createSecureSessionCB(otmCtx);
683             if(OC_STACK_OK != res)
684             {
685                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
686                 SetResult(otmCtx, res);
687                 return OC_STACK_DELETE_TRANSACTION;
688             }
689         }
690     }
691     else
692     {
693         OIC_LOG(ERROR, TAG, "Error while update operation mode");
694         SetResult(otmCtx, clientResponse->result);
695     }
696
697     OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
698
699 exit:
700     return  OC_STACK_DELETE_TRANSACTION;
701 }
702
703 /**
704  * Response handler for update owner crendetial request.
705  *
706  * @param[in] ctx             ctx value passed to callback from calling function.
707  * @param[in] UNUSED          handle to an invocation
708  * @param[in] clientResponse  Response from queries to remote servers.
709  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
710  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
711  */
712 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
713                                 OCClientResponse *clientResponse)
714 {
715     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
716     VERIFY_NON_NULL(TAG, ctx, WARNING);
717
718     OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
719     (void)UNUSED;
720     OCStackResult res = OC_STACK_OK;
721     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
722
723     if(OC_STACK_RESOURCE_CREATED == clientResponse->result)
724     {
725         if(otmCtx && otmCtx->selectedDeviceInfo)
726         {
727             //Close the temporal secure session to verify the owner credential
728             CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
729             endpoint->port = otmCtx->selectedDeviceInfo->securePort;
730             CAResult_t caResult = CACloseDtlsSession(endpoint);
731             if(CA_STATUS_OK != caResult)
732             {
733                 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
734                 SetResult(otmCtx, caResult);
735                 return OC_STACK_DELETE_TRANSACTION;
736             }
737
738             /**
739              * If we select NULL cipher,
740              * client will select appropriate cipher suite according to server's cipher-suite list.
741              */
742             caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL);
743             if(CA_STATUS_OK != caResult)
744             {
745                 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
746                 SetResult(otmCtx, caResult);
747                 return OC_STACK_DELETE_TRANSACTION;
748             }
749
750             /**
751              * in case of random PIN based OxM,
752              * revert get_psk_info callback of tinyDTLS to use owner credential.
753              */
754             if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
755             {
756                 OicUuid_t emptyUuid = { .id={0}};
757                 SetUuidForRandomPinOxm(&emptyUuid);
758
759                 if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
760                 {
761                     OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
762                     SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
763                     return OC_STACK_DELETE_TRANSACTION;
764                 }
765             }
766
767             //PUT /oic/sec/doxm [{ ..., "owned":"TRUE" }]
768             res = PutOwnershipInformation(otmCtx);
769             if(OC_STACK_OK != res)
770             {
771                 OIC_LOG(ERROR, TAG, "Failed to put ownership information to new device");
772                 SetResult(otmCtx, res);
773                 return OC_STACK_DELETE_TRANSACTION;
774             }
775         }
776     }
777     else
778     {
779         res = clientResponse->result;
780         OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
781         SetResult(otmCtx, res);
782     }
783
784     OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
785
786 exit:
787     return  OC_STACK_DELETE_TRANSACTION;
788 }
789
790
791 /**
792  * Response handler for update owner information request.
793  *
794  * @param[in] ctx             ctx value passed to callback from calling function.
795  * @param[in] UNUSED          handle to an invocation
796  * @param[in] clientResponse  Response from queries to remote servers.
797  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
798  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
799  */
800 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
801                                 OCClientResponse *clientResponse)
802 {
803     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
804     VERIFY_NON_NULL(TAG, ctx, WARNING);
805
806     OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
807     (void)UNUSED;
808     OCStackResult res = OC_STACK_OK;
809     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
810
811     if(OC_STACK_OK == clientResponse->result)
812     {
813         if(otmCtx && otmCtx->selectedDeviceInfo)
814         {
815             OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
816             OIC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
817
818             res = PutProvisioningStatus(otmCtx);
819             if(OC_STACK_OK != res)
820             {
821                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
822                 SetResult(otmCtx, res);
823             }
824         }
825     }
826     else
827     {
828         res = clientResponse->result;
829         OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
830         SetResult(otmCtx, res);
831     }
832
833     OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
834
835 exit:
836     return  OC_STACK_DELETE_TRANSACTION;
837 }
838
839 /**
840  * Response handler of update provisioning status.
841  *
842  * @param[in] ctx             ctx value passed to callback from calling function.
843  * @param[in] UNUSED          handle to an invocation
844  * @param[in] clientResponse  Response from queries to remote servers.
845  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
846  *          and OC_STACK_KEEP_TRANSACTION to keep it.
847  */
848 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
849                                                        OCClientResponse *clientResponse)
850 {
851     OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
852
853     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
854     VERIFY_NON_NULL(TAG, ctx, ERROR);
855
856     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
857     (void)UNUSED;
858
859     if (OC_STACK_OK == clientResponse->result)
860     {
861         OCStackResult res = PDMAddDevice(&otmCtx->selectedDeviceInfo->doxm->deviceID);
862          if (OC_STACK_OK == res)
863          {
864                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
865                 SetResult(otmCtx, OC_STACK_OK);
866                 return OC_STACK_DELETE_TRANSACTION;
867          }
868           else
869          {
870               OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
871          }
872     }
873     else
874     {
875         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
876                             clientResponse->result);
877         SetResult(otmCtx, clientResponse->result);
878     }
879
880
881 exit:
882     OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
883     return OC_STACK_DELETE_TRANSACTION;
884 }
885
886 static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx)
887 {
888     OIC_LOG(DEBUG, TAG, "IN PutOwnerCredential");
889
890     if(!otmCtx || !otmCtx->selectedDeviceInfo)
891     {
892         OIC_LOG(ERROR, TAG, "Invalid parameters");
893         return OC_STACK_INVALID_PARAM;
894     }
895
896     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
897     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
898
899     if(!PMGenerateQuery(true,
900                         deviceInfo->endpoint.addr, deviceInfo->securePort,
901                         deviceInfo->connType,
902                         query, sizeof(query), OIC_RSRC_CRED_URI))
903     {
904         OIC_LOG(ERROR, TAG, "PutOwnerCredential : Failed to generate query");
905         return OC_STACK_ERROR;
906     }
907     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
908     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
909     if(!secPayload)
910     {
911         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
912         return OC_STACK_NO_MEMORY;
913     }
914
915     //Generate owner credential for new device
916     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
917     OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
918     if(!ownerCredential)
919     {
920         OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
921         return OC_STACK_NO_RESOURCE;
922     }
923
924     OicUuid_t credSubjectId = {.id={0}};
925     if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
926     {
927         OicSecCred_t newCredential;
928         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
929         newCredential.next = NULL;
930
931         //Set subject ID as PT's ID
932         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
933
934         //Fill private data as empty string
935         newCredential.privateData.data = NULL;
936         newCredential.privateData.len = 0;
937 #ifdef __WITH_X509__
938         newCredential.publicData.data = NULL;
939         newCredential.publicData.len = 0;
940 #endif
941
942         //Send owner credential to new device : PUT /oic/sec/cred [ owner credential ]
943         if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData1, &secPayload->payloadSize))
944         {
945             OICFree(secPayload);
946             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
947             return OC_STACK_ERROR;
948         }
949         OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData1);
950
951         OCCallbackData cbData;
952         cbData.cb = &OwnerCredentialHandler;
953         cbData.context = (void *)otmCtx;
954         cbData.cd = NULL;
955         OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query,
956                                          &deviceInfo->endpoint, (OCPayload*)secPayload,
957                                          deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
958         if (res != OC_STACK_OK)
959         {
960             OIC_LOG(ERROR, TAG, "OCStack resource error");
961         }
962     }
963     else
964     {
965         OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
966         return OC_STACK_NO_RESOURCE;
967     }
968
969     OIC_LOG(DEBUG, TAG, "OUT PutOwnerCredential");
970
971     return OC_STACK_OK;
972 }
973
974 static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx)
975 {
976     OIC_LOG(DEBUG, TAG, "IN PutOwnerTransferModeToResource");
977
978     if(!otmCtx || !otmCtx->selectedDeviceInfo)
979     {
980         OIC_LOG(ERROR, TAG, "Invalid parameters");
981         return OC_STACK_INVALID_PARAM;
982     }
983
984     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
985     OicSecOxm_t selectedOxm = deviceInfo->doxm->oxmSel;
986     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
987
988     if(!PMGenerateQuery(false,
989                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
990                         deviceInfo->connType,
991                         query, sizeof(query), OIC_RSRC_DOXM_URI))
992     {
993         OIC_LOG(ERROR, TAG, "PutOwnerTransferModeToResource : Failed to generate query");
994         return OC_STACK_ERROR;
995     }
996     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
997     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
998     if(!secPayload)
999     {
1000         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1001         return OC_STACK_NO_MEMORY;
1002     }
1003     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1004     OCStackResult res = g_OTMDatas[selectedOxm].createSelectOxmPayloadCB(otmCtx,
1005             &secPayload->securityData1, &secPayload->payloadSize);
1006     if (OC_STACK_OK != res && NULL == secPayload->securityData1)
1007     {
1008         OCPayloadDestroy((OCPayload *)secPayload);
1009         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
1010         return OC_STACK_ERROR;
1011     }
1012
1013     OCCallbackData cbData;
1014     cbData.cb = &OwnerTransferModeHandler;
1015     cbData.context = (void *)otmCtx;
1016     cbData.cd = NULL;
1017     res = OCDoResource(NULL, OC_REST_PUT, query,
1018                        &deviceInfo->endpoint, (OCPayload *)secPayload,
1019                        deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1020     if (res != OC_STACK_OK)
1021     {
1022         OIC_LOG(ERROR, TAG, "OCStack resource error");
1023     }
1024
1025     OIC_LOG(DEBUG, TAG, "OUT PutOwnerTransferModeToResource");
1026
1027     return res;
1028 }
1029
1030 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1031 {
1032     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1033
1034     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1035     {
1036         OIC_LOG(ERROR, TAG, "Invailed parameters");
1037         return OC_STACK_INVALID_PARAM;
1038     }
1039
1040     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1041     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1042     if(!PMGenerateQuery(false,
1043                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1044                         deviceInfo->connType,
1045                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1046     {
1047         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1048         return OC_STACK_ERROR;
1049     }
1050     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1051
1052     OCCallbackData cbData;
1053     cbData.cb = &ListMethodsHandler;
1054     cbData.context = (void *)otmCtx;
1055     cbData.cd = NULL;
1056     OCStackResult res = OCDoResource(NULL, OC_REST_GET, query, NULL, NULL,
1057                                      deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1058     if (res != OC_STACK_OK)
1059     {
1060         OIC_LOG(ERROR, TAG, "OCStack resource error");
1061     }
1062
1063     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1064
1065     return res;
1066 }
1067
1068 static OCStackResult PutOwnerUuid(OTMContext_t* otmCtx)
1069 {
1070     OIC_LOG(DEBUG, TAG, "IN PutOwnerUuid");
1071
1072     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1073     {
1074         OIC_LOG(ERROR, TAG, "Invailed parameters");
1075         return OC_STACK_INVALID_PARAM;
1076     }
1077
1078     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1079     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1080     if(!PMGenerateQuery(true,
1081                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1082                         deviceInfo->connType,
1083                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1084     {
1085         OIC_LOG(ERROR, TAG, "PutOwnershipInformation : Failed to generate query");
1086         return OC_STACK_ERROR;
1087     }
1088     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1089
1090     //PUT PT's uuid to new device
1091     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1092     if(!secPayload)
1093     {
1094         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1095         return OC_STACK_NO_MEMORY;
1096     }
1097     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1098     OCStackResult res =  g_OTMDatas[deviceInfo->doxm->oxmSel].createOwnerTransferPayloadCB(
1099             otmCtx, &secPayload->securityData1, &secPayload->payloadSize);
1100     if (NULL == secPayload->securityData1)
1101     {
1102         OCPayloadDestroy((OCPayload *)secPayload);
1103         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
1104         return OC_STACK_INVALID_PARAM;
1105     }
1106     OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData1);
1107
1108     OCCallbackData cbData;
1109     cbData.cb = &OwnerUuidUpdateHandler;
1110     cbData.context = (void *)otmCtx;
1111     cbData.cd = NULL;
1112
1113     res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload *)secPayload,
1114             deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1115     if (res != OC_STACK_OK)
1116     {
1117         OIC_LOG(ERROR, TAG, "OCStack resource error");
1118     }
1119
1120     OIC_LOG(DEBUG, TAG, "OUT PutOwnerUuid");
1121
1122     return res;
1123 }
1124
1125 static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx)
1126 {
1127     OIC_LOG(DEBUG, TAG, "IN PutOwnershipInformation");
1128
1129     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1130     {
1131         OIC_LOG(ERROR, TAG, "Invailed parameters");
1132         return OC_STACK_INVALID_PARAM;
1133     }
1134
1135     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1136     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1137     if(!PMGenerateQuery(true,
1138                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1139                         deviceInfo->connType,
1140                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1141     {
1142         OIC_LOG(ERROR, TAG, "PutOwnershipInformation : Failed to generate query");
1143         return OC_STACK_ERROR;
1144     }
1145     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1146
1147     //OwnershipInformationHandler
1148     OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1149     if (!secPayload)
1150     {
1151         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1152         return OC_STACK_NO_MEMORY;
1153     }
1154
1155     otmCtx->selectedDeviceInfo->doxm->owned = true;
1156
1157     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1158     OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
1159             &secPayload->securityData1, &secPayload->payloadSize);
1160     if (OC_STACK_OK != res && NULL == secPayload->securityData1)
1161     {
1162         OCPayloadDestroy((OCPayload *)secPayload);
1163         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1164         return OC_STACK_INVALID_PARAM;
1165     }
1166
1167     OCCallbackData cbData;
1168     cbData.cb = &OwnershipInformationHandler;
1169     cbData.context = (void *)otmCtx;
1170     cbData.cd = NULL;
1171
1172     res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1173                        deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1174     if (res != OC_STACK_OK)
1175     {
1176         OIC_LOG(ERROR, TAG, "OCStack resource error");
1177     }
1178
1179     OIC_LOG(DEBUG, TAG, "OUT PutOwnershipInformation");
1180
1181     return res;
1182 }
1183
1184 static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx)
1185 {
1186     OIC_LOG(DEBUG, TAG, "IN PutUpdateOperationMode");
1187
1188     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1189     {
1190         return OC_STACK_INVALID_PARAM;
1191     }
1192
1193     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1194     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1195     if(!PMGenerateQuery(false,
1196                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1197                         deviceInfo->connType,
1198                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1199     {
1200         OIC_LOG(ERROR, TAG, "PutUpdateOperationMode : Failed to generate query");
1201         return OC_STACK_ERROR;
1202     }
1203     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1204
1205     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1206     if(!secPayload)
1207     {
1208         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1209         return OC_STACK_NO_MEMORY;
1210     }
1211     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1212     OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData1,
1213                                            &secPayload->payloadSize);
1214    if (OC_STACK_OK != res)
1215     {
1216         OCPayloadDestroy((OCPayload *)secPayload);
1217         OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
1218         return OC_STACK_INVALID_PARAM;
1219     }
1220
1221     OCCallbackData cbData;
1222     cbData.cb = &OperationModeUpdateHandler;
1223     cbData.context = (void *)otmCtx;
1224     cbData.cd = NULL;
1225     res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload *)secPayload,
1226                        deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1227     if (res != OC_STACK_OK)
1228     {
1229         OIC_LOG(ERROR, TAG, "OCStack resource error");
1230     }
1231
1232     OIC_LOG(DEBUG, TAG, "OUT PutUpdateOperationMode");
1233
1234     return res;
1235 }
1236
1237 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
1238 {
1239     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
1240     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1241     otmCtx->selectedDeviceInfo = selectedDevice;
1242
1243     //Set to the lowest level OxM, and then find more higher level OxM.
1244     OCStackResult res = SelectProvisioningMethod(selectedDevice->doxm->oxm,
1245                                                  selectedDevice->doxm->oxmLen,
1246                                                  &selectedDevice->doxm->oxmSel);
1247     if(OC_STACK_OK != res)
1248     {
1249         OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
1250         SetResult(otmCtx, res);
1251         return res;
1252     }
1253     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
1254
1255     //Send Req: PUT /oic/sec/doxm [{..."OxmSel" :g_OTMDatas[Index of Selected OxM].OXMString,...}]
1256     res = PutOwnerTransferModeToResource(otmCtx);
1257     if(OC_STACK_OK != res)
1258     {
1259         OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
1260         SetResult(otmCtx, res);
1261         return res;
1262     }
1263
1264     //Register DTLS event handler to catch the dtls event while handshake
1265     if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DTLSHandshakeCB))
1266     {
1267         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register DTLS handshake callback.");
1268     }
1269
1270     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
1271
1272     return res;
1273
1274 }
1275
1276 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
1277 {
1278     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
1279
1280     if(!data)
1281     {
1282         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
1283         return OC_STACK_INVALID_PARAM;
1284     }
1285     if(oxmType >= OIC_OXM_COUNT)
1286     {
1287         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
1288         return OC_STACK_INVALID_PARAM;
1289     }
1290
1291     g_OTMDatas[oxmType].loadSecretCB= data->loadSecretCB;
1292     g_OTMDatas[oxmType].createSecureSessionCB = data->createSecureSessionCB;
1293     g_OTMDatas[oxmType].createSelectOxmPayloadCB = data->createSelectOxmPayloadCB;
1294     g_OTMDatas[oxmType].createOwnerTransferPayloadCB = data->createOwnerTransferPayloadCB;
1295
1296     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
1297
1298     return OC_STACK_OK;
1299 }
1300
1301 /**
1302  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
1303  */
1304 OCStackResult OTMDoOwnershipTransfer(void* ctx,
1305                                      OCProvisionDev_t *selectedDevicelist,
1306                                      OCProvisionResultCB resultCallback)
1307 {
1308     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
1309
1310     if (NULL == selectedDevicelist)
1311     {
1312         return OC_STACK_INVALID_PARAM;
1313     }
1314     if (NULL == resultCallback)
1315     {
1316         return OC_STACK_INVALID_CALLBACK;
1317     }
1318
1319     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
1320     if(!otmCtx)
1321     {
1322         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
1323         return OC_STACK_NO_MEMORY;
1324     }
1325     otmCtx->ctxResultCallback = resultCallback;
1326     otmCtx->ctxHasError = false;
1327     otmCtx->userCtx = ctx;
1328     OCProvisionDev_t* pCurDev = selectedDevicelist;
1329
1330     //Counting number of selected devices.
1331     otmCtx->ctxResultArraySize = 0;
1332     while(NULL != pCurDev)
1333     {
1334         otmCtx->ctxResultArraySize++;
1335         pCurDev = pCurDev->next;
1336     }
1337
1338     otmCtx->ctxResultArray =
1339         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
1340     if(NULL == otmCtx->ctxResultArray)
1341     {
1342         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
1343         OICFree(otmCtx);
1344         return OC_STACK_NO_MEMORY;
1345     }
1346     pCurDev = selectedDevicelist;
1347
1348     OCStackResult res = OC_STACK_OK;
1349     //Fill the device UUID for result array.
1350     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
1351     {
1352         //Checking duplication of Device ID.
1353         bool isDuplicate = true;
1354         res = PDMIsDuplicateDevice(&pCurDev->doxm->deviceID, &isDuplicate);
1355         if (OC_STACK_OK != res)
1356         {
1357             goto error;
1358         }
1359         if (isDuplicate)
1360         {
1361             OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Device ID is duplicated");
1362             res = OC_STACK_INVALID_PARAM;
1363             goto error;
1364         }
1365         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
1366                pCurDev->doxm->deviceID.id,
1367                UUID_LENGTH);
1368         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
1369         pCurDev = pCurDev->next;
1370     }
1371
1372     StartOwnershipTransfer(otmCtx, selectedDevicelist);
1373
1374     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
1375     return OC_STACK_OK;
1376
1377 error:
1378     OICFree(otmCtx->ctxResultArray);
1379     OICFree(otmCtx);
1380     return res;
1381 }
1382
1383 /**
1384  * Callback handler of SRPFinalizeProvisioning.
1385  *
1386  * @param[in] ctx             ctx value passed to callback from calling function.
1387  * @param[in] UNUSED          handle to an invocation
1388  * @param[in] clientResponse  Response from queries to remote servers.
1389  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1390  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1391  */
1392 static OCStackApplicationResult FinalizeProvisioningCB(void *ctx, OCDoHandle UNUSED,
1393                                                        OCClientResponse *clientResponse)
1394 {
1395     OIC_LOG_V(INFO, TAG, "IN FinalizeProvisioningCB.");
1396
1397     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1398     VERIFY_NON_NULL(TAG, ctx, ERROR);
1399
1400     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1401     (void)UNUSED;
1402     if(OC_STACK_OK == clientResponse->result)
1403     {
1404         OCStackResult res = PDMAddDevice(&otmCtx->selectedDeviceInfo->doxm->deviceID);
1405
1406          if (OC_STACK_OK == res)
1407          {
1408                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1409                 SetResult(otmCtx, OC_STACK_OK);
1410                 return OC_STACK_DELETE_TRANSACTION;
1411          }
1412          else
1413          {
1414               OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1415          }
1416     }
1417 exit:
1418     return OC_STACK_DELETE_TRANSACTION;
1419 }
1420
1421 /**
1422  * Callback handler of default ACL provisioning.
1423  *
1424  * @param[in] ctx             ctx value passed to callback from calling function.
1425  * @param[in] UNUSED          handle to an invocation
1426  * @param[in] clientResponse  Response from queries to remote servers.
1427  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1428  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1429  */
1430 static OCStackApplicationResult ProvisionDefaultACLCB(void *ctx, OCDoHandle UNUSED,
1431                                                        OCClientResponse *clientResponse)
1432 {
1433     OIC_LOG_V(INFO, TAG, "IN ProvisionDefaultACLCB.");
1434
1435     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1436     VERIFY_NON_NULL(TAG, ctx, ERROR);
1437
1438     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1439     (void)UNUSED;
1440
1441     if (OC_STACK_RESOURCE_CREATED == clientResponse->result)
1442     {
1443         OIC_LOG_V(INFO, TAG, "Staring commit hash task.");
1444         // TODO hash currently have fixed value 0.
1445         uint16_t aclHash = 0;
1446         otmCtx->selectedDeviceInfo->pstat->commitHash = aclHash;
1447         otmCtx->selectedDeviceInfo->pstat->tm = NORMAL;
1448         OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1449         if(!secPayload)
1450         {
1451             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1452             return OC_STACK_NO_MEMORY;
1453         }
1454         secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1455         OCStackResult res = PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
1456                 &secPayload->securityData1, &secPayload->payloadSize);
1457         if (OC_STACK_OK != res || NULL == secPayload->securityData1)
1458         {
1459             OICFree(secPayload);
1460             SetResult(otmCtx, OC_STACK_INVALID_JSON);
1461             return OC_STACK_DELETE_TRANSACTION;
1462         }
1463
1464         char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1465         if(!PMGenerateQuery(true,
1466                             otmCtx->selectedDeviceInfo->endpoint.addr,
1467                             otmCtx->selectedDeviceInfo->securePort,
1468                             otmCtx->selectedDeviceInfo->connType,
1469                             query, sizeof(query), OIC_RSRC_PSTAT_URI))
1470         {
1471             OIC_LOG(ERROR, TAG, "ProvisionDefaultACLCB : Failed to generate query");
1472             return OC_STACK_ERROR;
1473         }
1474         OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1475
1476         OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1477         cbData.cb = &FinalizeProvisioningCB;
1478         cbData.context = (void*)otmCtx;
1479         cbData.cd = NULL;
1480         OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1481                 otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1482         OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
1483         if (ret != OC_STACK_OK)
1484         {
1485             OIC_LOG(ERROR, TAG, "OCStack resource error");
1486             SetResult(otmCtx, ret);
1487         }
1488     }
1489     else
1490     {
1491         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1492                             clientResponse->result);
1493         SetResult(otmCtx, clientResponse->result);
1494     }
1495 exit:
1496     return OC_STACK_DELETE_TRANSACTION;
1497 }
1498
1499 OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx)
1500 {
1501     OIC_LOG(INFO, TAG, "IN PutProvisioningStatus");
1502
1503     if(!otmCtx)
1504     {
1505         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
1506         return OC_STACK_INVALID_PARAM;
1507     }
1508     if(!otmCtx->selectedDeviceInfo)
1509     {
1510         OIC_LOG(ERROR, TAG, "Can't find device information in OTMContext");
1511         OICFree(otmCtx);
1512         return OC_STACK_INVALID_PARAM;
1513     }
1514
1515     //Change the TAKE_OWNER bit of CM to 0.
1516     otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
1517
1518     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
1519     if (!secPayload)
1520     {
1521         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1522         return OC_STACK_NO_MEMORY;
1523     }
1524     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1525     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
1526             &secPayload->securityData1, &secPayload->payloadSize))
1527     {
1528         OCPayloadDestroy((OCPayload *)secPayload);
1529         SetResult(otmCtx, OC_STACK_INVALID_JSON);
1530         return OC_STACK_INVALID_JSON;
1531     }
1532     OIC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData1);
1533
1534     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1535     if(!PMGenerateQuery(true,
1536                         otmCtx->selectedDeviceInfo->endpoint.addr,
1537                         otmCtx->selectedDeviceInfo->securePort,
1538                         otmCtx->selectedDeviceInfo->connType,
1539                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1540     {
1541         OIC_LOG(ERROR, TAG, "PutProvisioningStatus : Failed to generate query");
1542         return OC_STACK_ERROR;
1543     }
1544     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1545
1546     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1547     cbData.cb = &ProvisioningStatusHandler;
1548     cbData.context = (void*)otmCtx;
1549     cbData.cd = NULL;
1550     OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1551             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1552     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
1553     if (ret != OC_STACK_OK)
1554     {
1555         OIC_LOG(ERROR, TAG, "OCStack resource error");
1556         SetResult(otmCtx, ret);
1557     }
1558
1559     OIC_LOG(INFO, TAG, "OUT PutProvisioningStatus");
1560
1561     return ret;
1562 }