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