Merge "Merge branch 'master' into easysetup" into easysetup
[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
62 #define TAG "OTM"
63
64 /**
65  * Array to store the callbacks for each owner transfer method.
66  */
67 static OTMCallbackData_t g_OTMDatas[OIC_OXM_COUNT];
68
69 /**
70  * Variable for storing provisioning tool's provisioning capabilities
71  * Must be in decreasing order of preference. More prefered method should
72  * have lower array index.
73  */
74 static OicSecDpom_t gProvisioningToolCapability[] = { SINGLE_SERVICE_CLIENT_DRIVEN };
75
76 /**
77  * Number of supported provisioning methods
78  * current version supports only one.
79  */
80 static size_t gNumOfProvisioningMethodsPT = 1;
81
82 /**
83  * Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
84  */
85 static OTMContext_t* g_otmCtx = NULL;
86
87 /**
88  * Function to getting string of ownership transfer method
89  */
90 static const char* GetOxmString(OicSecOxm_t oxmType)
91 {
92     switch(oxmType)
93     {
94         case OIC_JUST_WORKS:
95             return OXM_JUST_WORKS;
96         case OIC_RANDOM_DEVICE_PIN:
97             return OXM_RANDOM_DEVICE_PIN;
98         case OIC_MANUFACTURER_CERTIFICATE:
99             return OXM_MANUFACTURER_CERTIFICATE;
100         default:
101             return NULL;
102     }
103 }
104
105 /**
106  * Function to select appropriate  provisioning method.
107  *
108  * @param[in] supportedMethods   Array of supported methods
109  * @param[in] numberOfMethods   number of supported methods
110  * @param[out]  selectedMethod         Selected methods
111  * @return  OC_STACK_OK on success
112  */
113 static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
114                                                             size_t numberOfMethods,
115                                                             OicSecOxm_t *selectedMethod)
116 {
117     OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
118
119     if(numberOfMethods == 0 || !supportedMethods)
120     {
121         OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
122         return OC_STACK_ERROR;
123     }
124
125     *selectedMethod  = supportedMethods[0];
126     for(size_t i = 0; i < numberOfMethods; i++)
127     {
128         if(*selectedMethod < supportedMethods[i])
129         {
130             *selectedMethod =  supportedMethods[i];
131         }
132     }
133
134     return OC_STACK_OK;
135 }
136
137 /**
138  * Function to select operation mode.This function will return most secure common operation mode.
139  *
140  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
141  * @param[out]   selectedMode   selected operation mode
142  * @return  OC_STACK_OK on success
143  */
144 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
145                                 OicSecDpom_t *selectedMode)
146 {
147     OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
148
149     size_t i = 0;
150     size_t j = 0;
151
152     while (i < gNumOfProvisioningMethodsPT && j < selectedDeviceInfo->pstat->smLen)
153     {
154         if (gProvisioningToolCapability[i] < selectedDeviceInfo->pstat->sm[j])
155         {
156             i++;
157         }
158         else if (selectedDeviceInfo->pstat->sm[j] < gProvisioningToolCapability[i])
159         {
160             j++;
161         }
162         else /* if gProvisioningToolCapability[i] == deviceSupportedMethods[j] */
163         {
164             *selectedMode = gProvisioningToolCapability[j];
165             break;
166         }
167     }
168     OIC_LOG(DEBUG, TAG, "OUT SelectOperationMode");
169 }
170
171 /**
172  * Function to update owner transfer mode
173  *
174  * @param[in]  otmCtx  Context value of ownership transfer.
175  * @return  OC_STACK_OK on success
176  */
177 static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx);
178
179 /**
180  * Function to send request to resource to get its pstat resource information.
181  *
182  * @param[in]  otmCtx  Context value of ownership transfer.
183  * @return  OC_STACK_OK on success
184  */
185 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
186
187
188 /**
189  * Function to send ownerShip info. This function would update Owned as true and
190  * owner as UUID for provisioning tool
191  *
192  * @param[in]  otmCtx  Context value of ownership transfer.
193  * @return  OC_STACK_OK on success
194  */
195 static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx);
196
197 /**
198  * Function to update the operation mode. As per the spec. Operation mode in client driven
199  * single service provisioning it will be updated to 0x3
200  *
201  * @param[in]  otmCtx  Context value of ownership transfer.
202  * @param[in] selectedOperationMode selected operation mode
203  * @return  OC_STACK_OK on success
204  */
205 static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx,
206                                     OicSecDpom_t selectedOperationMode);
207
208 /**
209  * Function to start ownership transfer.
210  * This function will send the first request for provisioning,
211  * The next request message is sent from the response handler for this request.
212  *
213  * @param[in] ctx   context value passed to callback from calling function.
214  * @param[in] selectedDevice   selected device information to performing provisioning.
215  * @return  OC_STACK_OK on success
216  */
217 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
218
219 /*
220  * Function to finalize provisioning.
221  * This function will send default ACL and commit hash.
222  *
223  * @param[in] otmCtx   Context value of ownership transfer.
224  * @return  OC_STACK_OK on success
225  */
226 static OCStackResult FinalizeProvisioning(OTMContext_t* otmCtx);
227
228 static bool IsComplete(OTMContext_t* otmCtx)
229 {
230     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
231     {
232         if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
233         {
234             return false;
235         }
236     }
237
238     return true;
239 }
240
241 /**
242  * Function to save the result of provisioning.
243  *
244  * @param[in,out] otmCtx   Context value of ownership transfer.
245  * @param[in] res   result of provisioning
246  */
247 static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
248 {
249     OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
250
251     if(!otmCtx)
252     {
253         OIC_LOG(WARNING, TAG, "OTMContext is NULL");
254         return;
255     }
256
257     if(otmCtx->selectedDeviceInfo)
258     {
259         for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
260         {
261             if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
262                       otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
263             {
264                 otmCtx->ctxResultArray[i].res = res;
265                 if(OC_STACK_OK != res)
266                 {
267                     otmCtx->ctxHasError = true;
268                 }
269             }
270         }
271
272         g_otmCtx = NULL;
273
274         //If all request is completed, invoke the user callback.
275         if(IsComplete(otmCtx))
276         {
277             otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
278                                        otmCtx->ctxResultArray, otmCtx->ctxHasError);
279             OICFree(otmCtx->ctxResultArray);
280             OICFree(otmCtx);
281         }
282         else
283         {
284             if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
285                                                      otmCtx->selectedDeviceInfo->next))
286             {
287                 OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
288             }
289         }
290     }
291
292     OIC_LOG(DEBUG, TAG, "OUT SetResult");
293 }
294
295 /**
296  * Function to handle the handshake result in OTM.
297  * This function will be invoked after DTLS handshake
298  * @param   endPoint  [IN] The remote endpoint.
299  * @param   errorInfo [IN] Error information from the endpoint.
300  * @return  NONE
301  */
302 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
303 {
304     if(g_otmCtx && endpoint && info)
305     {
306         OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
307                  endpoint->addr, endpoint->port, info->result);
308
309         //Make sure the address matches.
310         if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr,
311            endpoint->addr,
312            sizeof(endpoint->addr)) == 0 &&
313            g_otmCtx->selectedDeviceInfo->securePort == endpoint->port)
314         {
315             OCStackResult res;
316
317             CARegisterDTLSHandshakeCallback(NULL);
318
319             //In case of success, send next coaps request.
320             if(CA_STATUS_OK == info->result)
321             {
322                 //Send request : PUT /oic/sec/doxm [{"Owned":"True", .. , "Owner":"PT's UUID"}]
323                 res = PutOwnershipInformation(g_otmCtx);
324                 if(OC_STACK_OK != res)
325                 {
326                     OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
327                     SetResult(g_otmCtx, res);
328                 }
329             }
330             //In case of failure, re-start the ownership transfer in case of PIN OxM
331             else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
332             {
333                 g_otmCtx->selectedDeviceInfo->doxm->owned = false;
334                 g_otmCtx->attemptCnt++;
335
336                 if(g_otmCtx->selectedDeviceInfo->doxm->oxmSel == OIC_RANDOM_DEVICE_PIN)
337                 {
338                     res = RemoveCredential(&g_otmCtx->subIdForPinOxm);
339                     if(OC_STACK_RESOURCE_DELETED != res)
340                     {
341                         OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
342                         SetResult(g_otmCtx, res);
343                         return;
344                     }
345
346                     if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt)
347                     {
348                         res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo);
349                         if(OC_STACK_OK != res)
350                         {
351                             SetResult(g_otmCtx, res);
352                             OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
353                         }
354                     }
355                     else
356                     {
357                         SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
358                     }
359                 }
360                 else
361                 {
362                     SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
363                 }
364             }
365         }
366     }
367 }
368
369 /**
370  * Function to save ownerPSK at provisioning tool end.
371  *
372  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
373  * @return  OC_STACK_OK on success
374  */
375 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
376 {
377     OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
378
379     OCStackResult res = OC_STACK_ERROR;
380
381     CAEndpoint_t endpoint;
382     memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
383     OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
384     endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
385     endpoint.port = selectedDeviceInfo->securePort;
386
387     OicUuid_t ptDeviceID = {.id={0}};
388     if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
389     {
390         OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
391         return res;
392     }
393
394     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
395
396     //Generating OwnerPSK
397     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
398             (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
399             strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)), ptDeviceID.id,
400             sizeof(ptDeviceID.id), selectedDeviceInfo->doxm->deviceID.id,
401             sizeof(selectedDeviceInfo->doxm->deviceID.id), ownerPSK,
402             OWNER_PSK_LENGTH_128);
403
404     if (CA_STATUS_OK == pskRet)
405     {
406         OIC_LOG(INFO, TAG,"ownerPSK dump:\n");
407         OIC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
408         //Generating new credential for provisioning tool
409         size_t ownLen = 1;
410         uint32_t outLen = 0;
411
412         char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
413         B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff),
414                 &outLen);
415         VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
416
417         OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
418                 SYMMETRIC_PAIR_WISE_KEY, NULL,
419                 base64Buff, ownLen, &ptDeviceID);
420         VERIFY_NON_NULL(TAG, cred, ERROR);
421
422         res = AddCredential(cred);
423         if(res != OC_STACK_OK)
424         {
425             DeleteCredList(cred);
426             return res;
427         }
428     }
429     else
430     {
431         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
432     }
433
434     OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
435 exit:
436     return res;
437 }
438
439 /**
440  * Callback handler for OwnerShipTransferModeHandler API.
441  *
442  * @param[in] ctx             ctx value passed to callback from calling function.
443  * @param[in] UNUSED          handle to an invocation
444  * @param[in] clientResponse  Response from queries to remote servers.
445  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
446  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
447  */
448 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
449                                                          OCClientResponse *clientResponse)
450 {
451     OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
452
453     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
454     VERIFY_NON_NULL(TAG, ctx, WARNING);
455
456     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
457     (void)UNUSED;
458     if(clientResponse->result == OC_STACK_OK)
459     {
460         OIC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
461         //Send request : GET /oic/sec/pstat
462         OCStackResult res = GetProvisioningStatusResource(otmCtx);
463         if(OC_STACK_OK != res)
464         {
465             OIC_LOG(WARNING, TAG, "Failed to get pstat information");
466             SetResult(otmCtx, res);
467         }
468     }
469     else
470     {
471         OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
472         clientResponse->result);
473         SetResult(otmCtx, clientResponse->result);
474     }
475
476     OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
477
478 exit:
479     return  OC_STACK_DELETE_TRANSACTION;
480 }
481
482 /**
483  * Callback handler for ProvisioningStatusResouceHandler API.
484  *
485  * @param[in] ctx             ctx value passed to callback from calling function.
486  * @param[in] UNUSED          handle to an invocation
487  * @param[in] clientResponse  Response from queries to remote servers.
488  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
489  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
490  */
491 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
492                                                     OCClientResponse *clientResponse)
493 {
494     OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
495
496     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
497     VERIFY_NON_NULL(TAG, ctx, WARNING);
498
499     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
500     (void)UNUSED;
501     if  (OC_STACK_OK == clientResponse->result)
502     {
503         if  (NULL == clientResponse->payload)
504         {
505             OIC_LOG(INFO, TAG, "Skiping Null payload");
506             SetResult(otmCtx, OC_STACK_ERROR);
507             return OC_STACK_DELETE_TRANSACTION;
508         }
509
510         if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
511         {
512             OIC_LOG(INFO, TAG, "Unknown payload type");
513             SetResult(otmCtx, OC_STACK_ERROR);
514             return OC_STACK_DELETE_TRANSACTION;
515         }
516
517         OicSecPstat_t* pstat = JSONToPstatBin(
518                 ((OCSecurityPayload*)clientResponse->payload)->securityData);
519         if(NULL == pstat)
520         {
521             OIC_LOG(ERROR, TAG, "Error while converting json to pstat bin");
522             SetResult(otmCtx, OC_STACK_ERROR);
523             return OC_STACK_DELETE_TRANSACTION;
524         }
525         otmCtx->selectedDeviceInfo->pstat = pstat;
526
527         //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
528         OicSecDpom_t selectedOperationMode;
529         SelectOperationMode(otmCtx->selectedDeviceInfo, &selectedOperationMode);
530
531         //Send request : PUT /oic/sec/pstat [{"OM":"0x11", .. }]
532         OCStackResult res = PutUpdateOperationMode(otmCtx, selectedOperationMode);
533         if (OC_STACK_OK != res)
534         {
535             OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
536             SetResult(otmCtx, res);
537         }
538     }
539     else
540     {
541         OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
542             clientResponse->result);
543         SetResult(otmCtx, clientResponse->result);
544     }
545
546     OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
547 exit:
548     return  OC_STACK_DELETE_TRANSACTION;
549 }
550
551 /**
552  * Callback handler for OwnershipInformationHandler API.
553  *
554  * @param[in] ctx             ctx value passed to callback from calling function.
555  * @param[in] UNUSED          handle to an invocation
556  * @param[in] clientResponse  Response from queries to remote servers.
557  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
558  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
559  */
560 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
561                                 OCClientResponse *clientResponse)
562 {
563     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
564     VERIFY_NON_NULL(TAG, ctx, WARNING);
565
566     OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
567     (void)UNUSED;
568     OCStackResult res = OC_STACK_OK;
569     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
570
571     if(OC_STACK_OK == clientResponse->result)
572     {
573         if(otmCtx && otmCtx->selectedDeviceInfo)
574         {
575             if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
576             {
577                 res = RemoveCredential(&otmCtx->subIdForPinOxm);
578                 if(OC_STACK_RESOURCE_DELETED != res)
579                 {
580                     OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
581                     return OC_STACK_DELETE_TRANSACTION;
582                 }
583             }
584
585             res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
586             if(OC_STACK_OK != res)
587             {
588                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to owner PSK generation");
589                 SetResult(otmCtx, res);
590                 return OC_STACK_DELETE_TRANSACTION;
591             }
592
593             CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
594             endpoint->port = otmCtx->selectedDeviceInfo->securePort;
595             CAResult_t caResult = CACloseDtlsSession(endpoint);
596             if(CA_STATUS_OK != caResult)
597             {
598                 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
599                 SetResult(otmCtx, caResult);
600                 return OC_STACK_DELETE_TRANSACTION;
601             }
602
603             /**
604              * If we select NULL cipher,
605              * client will select appropriate cipher suite according to server's cipher-suite list.
606              */
607             caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL);
608             if(CA_STATUS_OK != caResult)
609             {
610                 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
611                 SetResult(otmCtx, caResult);
612                 return OC_STACK_DELETE_TRANSACTION;
613             }
614
615             OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
616             OIC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
617
618             res = FinalizeProvisioning(otmCtx);
619             if(OC_STACK_OK != res)
620             {
621                 SetResult(otmCtx, res);
622             }
623         }
624     }
625     else
626     {
627         res = clientResponse->result;
628         OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
629         SetResult(otmCtx, res);
630     }
631
632     OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
633
634 exit:
635     return  OC_STACK_DELETE_TRANSACTION;
636 }
637
638 /**
639  * Response handler for update operation mode.
640  *
641  * @param[in] ctx             ctx value passed to callback from calling function.
642  * @param[in] UNUSED          handle to an invocation
643  * @param[in] clientResponse  Response from queries to remote servers.
644  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
645  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
646  */
647 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
648                                 OCClientResponse *clientResponse)
649 {
650     OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
651
652     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
653     VERIFY_NON_NULL(TAG, ctx, WARNING);
654
655     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
656     (void) UNUSED;
657     if  (OC_STACK_OK == clientResponse->result)
658     {
659         OCStackResult res = OC_STACK_ERROR;
660         OicSecOxm_t selOxm = otmCtx->selectedDeviceInfo->doxm->oxmSel;
661         //DTLS Handshake
662         //Load secret for temporal secure session.
663         if(g_OTMDatas[selOxm].loadSecretCB)
664         {
665             res = g_OTMDatas[selOxm].loadSecretCB(otmCtx);
666             if(OC_STACK_OK != res)
667             {
668                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
669                 SetResult(otmCtx, res);
670                 return  OC_STACK_DELETE_TRANSACTION;
671             }
672         }
673
674         //It will be used in handshake event handler
675         g_otmCtx = otmCtx;
676
677         //Try DTLS handshake to generate secure session
678         if(g_OTMDatas[selOxm].createSecureSessionCB)
679         {
680             res = g_OTMDatas[selOxm].createSecureSessionCB(otmCtx);
681             if(OC_STACK_OK != res)
682             {
683                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
684                 SetResult(otmCtx, res);
685                 return OC_STACK_DELETE_TRANSACTION;
686             }
687         }
688     }
689     else
690     {
691         OIC_LOG(ERROR, TAG, "Error while update operation mode");
692         SetResult(otmCtx, clientResponse->result);
693     }
694
695     OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
696
697 exit:
698     return  OC_STACK_DELETE_TRANSACTION;
699 }
700
701
702 static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx)
703 {
704     OIC_LOG(DEBUG, TAG, "IN PutOwnerTransferModeToResource");
705
706     if(!otmCtx || !otmCtx->selectedDeviceInfo)
707     {
708         OIC_LOG(ERROR, TAG, "Invalid parameters");
709         return OC_STACK_INVALID_PARAM;
710     }
711
712     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
713     OicSecOxm_t selectedOxm = deviceInfo->doxm->oxmSel;
714     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
715
716     if(!PMGenerateQuery(false,
717                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
718                         deviceInfo->connType,
719                         query, sizeof(query), OIC_RSRC_DOXM_URI))
720     {
721         OIC_LOG(ERROR, TAG, "PutOwnerTransferModeToResource : Failed to generate query");
722         return OC_STACK_ERROR;
723     }
724     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
725     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
726     if(!secPayload)
727     {
728         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
729         return OC_STACK_NO_MEMORY;
730     }
731     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
732     secPayload->securityData = g_OTMDatas[selectedOxm].createSelectOxmPayloadCB(otmCtx);
733     if (NULL == secPayload->securityData)
734     {
735         OICFree(secPayload);
736         OIC_LOG(ERROR, TAG, "Error while converting bin to json");
737         return OC_STACK_ERROR;
738     }
739     OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData);
740
741     OCCallbackData cbData;
742     cbData.cb = &OwnerTransferModeHandler;
743     cbData.context = (void *)otmCtx;
744     cbData.cd = NULL;
745     OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query,
746                                      &deviceInfo->endpoint, (OCPayload*)secPayload,
747                                      deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
748     if (res != OC_STACK_OK)
749     {
750         OIC_LOG(ERROR, TAG, "OCStack resource error");
751     }
752
753     OIC_LOG(DEBUG, TAG, "OUT PutOwnerTransferModeToResource");
754
755     return res;
756 }
757
758 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
759 {
760     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
761
762     if(!otmCtx || !otmCtx->selectedDeviceInfo)
763     {
764         OIC_LOG(ERROR, TAG, "Invailed parameters");
765         return OC_STACK_INVALID_PARAM;
766     }
767
768     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
769     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
770     if(!PMGenerateQuery(false,
771                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
772                         deviceInfo->connType,
773                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
774     {
775         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
776         return OC_STACK_ERROR;
777     }
778     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
779
780     OCCallbackData cbData;
781     cbData.cb = &ListMethodsHandler;
782     cbData.context = (void *)otmCtx;
783     cbData.cd = NULL;
784     OCStackResult res = OCDoResource(NULL, OC_REST_GET, query, NULL, NULL,
785                                      deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
786     if (res != OC_STACK_OK)
787     {
788         OIC_LOG(ERROR, TAG, "OCStack resource error");
789     }
790
791     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
792
793     return res;
794 }
795
796
797 static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx)
798 {
799     OIC_LOG(DEBUG, TAG, "IN PutOwnershipInformation");
800
801     if(!otmCtx || !otmCtx->selectedDeviceInfo)
802     {
803         OIC_LOG(ERROR, TAG, "Invailed parameters");
804         return OC_STACK_INVALID_PARAM;
805     }
806
807     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
808     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
809     if(!PMGenerateQuery(true,
810                         deviceInfo->endpoint.addr, deviceInfo->securePort,
811                         deviceInfo->connType,
812                         query, sizeof(query), OIC_RSRC_DOXM_URI))
813     {
814         OIC_LOG(ERROR, TAG, "PutOwnershipInformation : Failed to generate query");
815         return OC_STACK_ERROR;
816     }
817     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
818
819     //OwnershipInformationHandler
820     OicSecOxm_t selOxm = deviceInfo->doxm->oxmSel;
821     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
822     if(!secPayload)
823     {
824         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
825         return OC_STACK_NO_MEMORY;
826     }
827     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
828     secPayload->securityData = g_OTMDatas[selOxm].createOwnerTransferPayloadCB(otmCtx);
829     if (NULL == secPayload->securityData)
830     {
831         OICFree(secPayload);
832         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
833         return OC_STACK_INVALID_PARAM;
834     }
835
836     OCCallbackData cbData;
837     cbData.cb = &OwnershipInformationHandler;
838     cbData.context = (void *)otmCtx;
839     cbData.cd = NULL;
840
841     OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
842                                      deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
843     if (res != OC_STACK_OK)
844     {
845         OIC_LOG(ERROR, TAG, "OCStack resource error");
846     }
847
848     OIC_LOG(DEBUG, TAG, "OUT PutOwnershipInformation");
849
850     return res;
851 }
852
853 static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx,
854                                     OicSecDpom_t selectedOperationMode)
855 {
856     OIC_LOG(DEBUG, TAG, "IN PutUpdateOperationMode");
857
858     if(!otmCtx || !otmCtx->selectedDeviceInfo)
859     {
860         return OC_STACK_INVALID_PARAM;
861     }
862
863     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
864     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
865     if(!PMGenerateQuery(false,
866                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
867                         deviceInfo->connType,
868                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
869     {
870         OIC_LOG(ERROR, TAG, "PutUpdateOperationMode : Failed to generate query");
871         return OC_STACK_ERROR;
872     }
873     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
874
875     deviceInfo->pstat->om = selectedOperationMode;
876
877     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
878     if(!secPayload)
879     {
880         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
881         return OC_STACK_NO_MEMORY;
882     }
883     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
884     secPayload->securityData = BinToPstatJSON(deviceInfo->pstat);
885     if (NULL == secPayload->securityData)
886     {
887         OICFree(secPayload);
888         OIC_LOG(ERROR, TAG, "Error while converting pstat bin to json");
889         return OC_STACK_INVALID_PARAM;
890     }
891
892     OCCallbackData cbData;
893     cbData.cb = &OperationModeUpdateHandler;
894     cbData.context = (void *)otmCtx;
895     cbData.cd = NULL;
896     OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
897                                      deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
898     if (res != OC_STACK_OK)
899     {
900         OIC_LOG(ERROR, TAG, "OCStack resource error");
901     }
902
903     OIC_LOG(DEBUG, TAG, "OUT PutUpdateOperationMode");
904
905     return res;
906 }
907
908 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
909 {
910     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
911     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
912     otmCtx->selectedDeviceInfo = selectedDevice;
913
914     //Set to the lowest level OxM, and then find more higher level OxM.
915     OCStackResult res = SelectProvisioningMethod(selectedDevice->doxm->oxm,
916                                                  selectedDevice->doxm->oxmLen,
917                                                  &selectedDevice->doxm->oxmSel);
918     if(OC_STACK_OK != res)
919     {
920         OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
921         SetResult(otmCtx, res);
922         return res;
923     }
924     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
925
926     //Send Req: PUT /oic/sec/doxm [{..."OxmSel" :g_OTMDatas[Index of Selected OxM].OXMString,...}]
927     res = PutOwnerTransferModeToResource(otmCtx);
928     if(OC_STACK_OK != res)
929     {
930         OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
931         SetResult(otmCtx, res);
932         return res;
933     }
934
935     //Register DTLS event handler to catch the dtls event while handshake
936     if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DTLSHandshakeCB))
937     {
938         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register DTLS handshake callback.");
939     }
940
941     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
942
943     return res;
944
945 }
946
947 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
948 {
949     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
950
951     if(!data)
952     {
953         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
954         return OC_STACK_INVALID_PARAM;
955     }
956     if(oxmType >= OIC_OXM_COUNT)
957     {
958         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
959         return OC_STACK_INVALID_PARAM;
960     }
961
962     g_OTMDatas[oxmType].loadSecretCB= data->loadSecretCB;
963     g_OTMDatas[oxmType].createSecureSessionCB = data->createSecureSessionCB;
964     g_OTMDatas[oxmType].createSelectOxmPayloadCB = data->createSelectOxmPayloadCB;
965     g_OTMDatas[oxmType].createOwnerTransferPayloadCB = data->createOwnerTransferPayloadCB;
966
967     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
968
969     return OC_STACK_OK;
970 }
971
972 /**
973  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
974  */
975 OCStackResult OTMDoOwnershipTransfer(void* ctx,
976                                      OCProvisionDev_t *selectedDevicelist,
977                                      OCProvisionResultCB resultCallback)
978 {
979     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
980
981     if (NULL == selectedDevicelist || NULL == resultCallback )
982     {
983         return OC_STACK_INVALID_PARAM;
984     }
985
986     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
987     if(!otmCtx)
988     {
989         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
990         return OC_STACK_NO_MEMORY;
991     }
992     otmCtx->ctxResultCallback = resultCallback;
993     otmCtx->ctxHasError = false;
994     otmCtx->userCtx = ctx;
995     OCProvisionDev_t* pCurDev = selectedDevicelist;
996
997     //Counting number of selected devices.
998     otmCtx->ctxResultArraySize = 0;
999     while(NULL != pCurDev)
1000     {
1001         otmCtx->ctxResultArraySize++;
1002         pCurDev = pCurDev->next;
1003     }
1004
1005     otmCtx->ctxResultArray =
1006         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
1007     if(NULL == otmCtx->ctxResultArray)
1008     {
1009         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
1010         OICFree(otmCtx);
1011         return OC_STACK_NO_MEMORY;
1012     }
1013     pCurDev = selectedDevicelist;
1014
1015     OCStackResult res = OC_STACK_OK;
1016     //Fill the device UUID for result array.
1017     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
1018     {
1019         //Checking duplication of Device ID.
1020         bool isDuplicate = true;
1021         res = PDMIsDuplicateDevice(&pCurDev->doxm->deviceID, &isDuplicate);
1022         if (OC_STACK_OK != res)
1023         {
1024             goto error;
1025         }
1026         if (isDuplicate)
1027         {
1028             OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Device ID is duplicated");
1029             res = OC_STACK_INVALID_PARAM;
1030             goto error;
1031         }
1032         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
1033                pCurDev->doxm->deviceID.id,
1034                UUID_LENGTH);
1035         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
1036         pCurDev = pCurDev->next;
1037     }
1038
1039     StartOwnershipTransfer(otmCtx, selectedDevicelist);
1040
1041     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
1042     return OC_STACK_OK;
1043
1044 error:
1045     OICFree(otmCtx->ctxResultArray);
1046     OICFree(otmCtx);
1047     return res;
1048
1049 }
1050
1051 /**
1052  * Callback handler of SRPFinalizeProvisioning.
1053  *
1054  * @param[in] ctx             ctx value passed to callback from calling function.
1055  * @param[in] UNUSED          handle to an invocation
1056  * @param[in] clientResponse  Response from queries to remote servers.
1057  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1058  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1059  */
1060 static OCStackApplicationResult FinalizeProvisioningCB(void *ctx, OCDoHandle UNUSED,
1061                                                        OCClientResponse *clientResponse)
1062 {
1063     OIC_LOG_V(INFO, TAG, "IN FinalizeProvisioningCB.");
1064
1065     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1066     VERIFY_NON_NULL(TAG, ctx, ERROR);
1067
1068     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1069     (void)UNUSED;
1070     if(OC_STACK_OK == clientResponse->result)
1071     {
1072         OCStackResult res = PDMAddDevice(&otmCtx->selectedDeviceInfo->doxm->deviceID);
1073
1074          if (OC_STACK_OK == res)
1075          {
1076                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1077                 SetResult(otmCtx, OC_STACK_OK);
1078                 return OC_STACK_DELETE_TRANSACTION;
1079          }
1080          else
1081          {
1082               OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1083          }
1084     }
1085 exit:
1086     return OC_STACK_DELETE_TRANSACTION;
1087 }
1088
1089 /**
1090  * Callback handler of default ACL provisioning.
1091  *
1092  * @param[in] ctx             ctx value passed to callback from calling function.
1093  * @param[in] UNUSED          handle to an invocation
1094  * @param[in] clientResponse  Response from queries to remote servers.
1095  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1096  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1097  */
1098 static OCStackApplicationResult ProvisionDefaultACLCB(void *ctx, OCDoHandle UNUSED,
1099                                                        OCClientResponse *clientResponse)
1100 {
1101     OIC_LOG_V(INFO, TAG, "IN ProvisionDefaultACLCB.");
1102
1103     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1104     VERIFY_NON_NULL(TAG, ctx, ERROR);
1105
1106     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1107     (void)UNUSED;
1108
1109     if (OC_STACK_RESOURCE_CREATED == clientResponse->result)
1110     {
1111         OIC_LOG_V(INFO, TAG, "Staring commit hash task.");
1112         // TODO hash currently have fixed value 0.
1113         uint16_t aclHash = 0;
1114         otmCtx->selectedDeviceInfo->pstat->commitHash = aclHash;
1115         otmCtx->selectedDeviceInfo->pstat->tm = NORMAL;
1116         OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1117         if(!secPayload)
1118         {
1119             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1120             return OC_STACK_NO_MEMORY;
1121         }
1122         secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1123         secPayload->securityData = BinToPstatJSON(otmCtx->selectedDeviceInfo->pstat);
1124         if (NULL == secPayload->securityData)
1125         {
1126             OICFree(secPayload);
1127             SetResult(otmCtx, OC_STACK_INVALID_JSON);
1128             return OC_STACK_DELETE_TRANSACTION;
1129         }
1130         OIC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData);
1131
1132         char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1133         if(!PMGenerateQuery(true,
1134                             otmCtx->selectedDeviceInfo->endpoint.addr,
1135                             otmCtx->selectedDeviceInfo->securePort,
1136                             otmCtx->selectedDeviceInfo->connType,
1137                             query, sizeof(query), OIC_RSRC_PSTAT_URI))
1138         {
1139             OIC_LOG(ERROR, TAG, "ProvisionDefaultACLCB : Failed to generate query");
1140             return OC_STACK_ERROR;
1141         }
1142         OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1143
1144         OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1145         cbData.cb = &FinalizeProvisioningCB;
1146         cbData.context = (void*)otmCtx;
1147         cbData.cd = NULL;
1148         OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1149                 otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1150         OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
1151         if (ret != OC_STACK_OK)
1152         {
1153             OIC_LOG(ERROR, TAG, "OCStack resource error");
1154             SetResult(otmCtx, ret);
1155         }
1156     }
1157     else
1158     {
1159         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1160                             clientResponse->result);
1161         SetResult(otmCtx, clientResponse->result);
1162     }
1163 exit:
1164     return OC_STACK_DELETE_TRANSACTION;
1165 }
1166
1167
1168 OCStackResult FinalizeProvisioning(OTMContext_t* otmCtx)
1169 {
1170     OIC_LOG(INFO, TAG, "IN FinalizeProvisioning");
1171
1172     if(!otmCtx)
1173     {
1174         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
1175         return OC_STACK_INVALID_PARAM;
1176     }
1177     if(!otmCtx->selectedDeviceInfo)
1178     {
1179         OIC_LOG(ERROR, TAG, "Can't find device information in OTMContext");
1180         OICFree(otmCtx);
1181         return OC_STACK_INVALID_PARAM;
1182     }
1183     // Provision Default ACL to device
1184     OicSecAcl_t defaultAcl =
1185     { {.id={0}},
1186         1,
1187         NULL,
1188         0x001F,
1189         0,
1190         NULL,
1191         NULL,
1192         1,
1193         NULL,
1194         NULL,
1195     };
1196
1197     OicUuid_t provTooldeviceID = {.id={0}};
1198     if (OC_STACK_OK != GetDoxmDeviceID(&provTooldeviceID))
1199     {
1200         OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
1201         SetResult(otmCtx, OC_STACK_ERROR);
1202         return OC_STACK_ERROR;
1203     }
1204     OIC_LOG(INFO, TAG, "Retieved deviceID");
1205     memcpy(defaultAcl.subject.id, provTooldeviceID.id, sizeof(defaultAcl.subject.id));
1206     char *wildCardResource = "*";
1207     defaultAcl.resources = &wildCardResource;
1208
1209     defaultAcl.owners = (OicUuid_t *) OICCalloc(1, UUID_LENGTH);
1210     if(!defaultAcl.owners)
1211     {
1212         OIC_LOG(ERROR, TAG, "Failed to memory allocation for default ACL");
1213         SetResult(otmCtx, OC_STACK_NO_MEMORY);
1214         return OC_STACK_NO_MEMORY;
1215     }
1216     memcpy(defaultAcl.owners->id, provTooldeviceID.id, UUID_LENGTH);
1217     OIC_LOG(INFO, TAG, "Provisioning default ACL");
1218
1219     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1220     if(!secPayload)
1221     {
1222         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1223         return OC_STACK_NO_MEMORY;
1224     }
1225     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1226     secPayload->securityData = BinToAclJSON(&defaultAcl);
1227     OICFree(defaultAcl.owners);
1228     if(!secPayload->securityData)
1229     {
1230         OICFree(secPayload);
1231         OIC_LOG(INFO, TAG, "FinalizeProvisioning : Failed to BinToAclJSON");
1232         SetResult(otmCtx, OC_STACK_ERROR);
1233         return OC_STACK_ERROR;
1234     }
1235     OIC_LOG_V(INFO, TAG, "Provisioning default ACL : %s",secPayload->securityData);
1236
1237     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1238     if(!PMGenerateQuery(true,
1239                         otmCtx->selectedDeviceInfo->endpoint.addr,
1240                         otmCtx->selectedDeviceInfo->securePort,
1241                         otmCtx->selectedDeviceInfo->connType,
1242                         query, sizeof(query), OIC_RSRC_ACL_URI))
1243     {
1244         OIC_LOG(ERROR, TAG, "FinalizeProvisioning : Failed to generate query");
1245         return OC_STACK_ERROR;
1246     }
1247     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1248
1249     OIC_LOG_V(INFO, TAG, "Request URI for Provisioning default ACL : %s", query);
1250
1251     OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
1252     cbData.cb = &ProvisionDefaultACLCB;
1253     cbData.context = (void *)otmCtx;
1254     cbData.cd = NULL;
1255     OCStackResult ret = OCDoResource(NULL, OC_REST_POST, query,
1256             &otmCtx->selectedDeviceInfo->endpoint, (OCPayload*)secPayload,
1257             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1258     if (OC_STACK_OK != ret)
1259     {
1260         SetResult(otmCtx, ret);
1261         return ret;
1262     }
1263
1264     OIC_LOG(INFO, TAG, "OUT FinalizeProvisioning");
1265
1266     return ret;
1267
1268 }
1269