replace : iotivity -> iotivity-sec
[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 "iotivity_config.h"
34 #ifdef HAVE_TIME_H
35 #include <time.h>
36 #endif
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40 #ifdef HAVE_SYS_TIME_H
41 #include <sys/time.h>
42 #endif
43 #include <stdbool.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <pthread.h>
47
48 #include "logger.h"
49 #include "oic_malloc.h"
50 #include "oic_string.h"
51 #include "cacommon.h"
52 #include "cainterface.h"
53 #include "base64.h"
54 #if defined (__TIZENRT__)
55 #include <apps/netutils/cJSON.h>
56 #else
57 #include "cJSON.h"
58 #endif
59 #include "utlist.h"
60 #include "srmresourcestrings.h"
61 #include "doxmresource.h"
62 #include "pstatresource.h"
63 #include "credresource.h"
64 #include "aclresource.h"
65 #include "ownershiptransfermanager.h"
66 #include "securevirtualresourcetypes.h"
67 #include "oxmjustworks.h"
68 #include "oxmrandompin.h"
69 #include "oxmmanufacturercert.h"
70 #include "secureresourceprovider.h"
71
72 #ifdef MULTIPLE_OWNER
73 #include "oxmpreconfpin.h"
74 #endif //MULTIPLE_OWNER
75 #include "otmcontextlist.h"
76 #include "pmtypes.h"
77 #include "pmutility.h"
78 #include "srmutility.h"
79 #include "provisioningdatabasemanager.h"
80 #include "ocpayload.h"
81 #include "payload_logging.h"
82 #include "pkix_interface.h"
83 #include "oxmverifycommon.h"
84 #include "psinterface.h"
85
86 #define TAG "OIC_OTM"
87
88
89 #define ALLOWED_OXM         1
90 #define NOT_ALLOWED_OXM     0
91
92 /**
93  * List of allowed oxm list.
94  * All oxm methods are allowed as default.
95  */
96 #ifdef MULTIPLE_OWNER
97 static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
98                                                   ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
99                                                   NOT_ALLOWED_OXM};
100 #else
101 static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
102                                                   ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM};
103 #endif
104
105 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
106 {
107     OCStackResult res = OC_STACK_INVALID_PARAM;
108
109     OIC_LOG(INFO, TAG, "IN OTMSetOTCallback");
110
111     VERIFY_NON_NULL(TAG, callbacks, ERROR);
112
113 #ifdef MULTIPLE_OWNER
114     VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm
115                     || OIC_CON_MFG_CERT == oxm), ERROR);
116 #else
117     VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm), ERROR);
118 #endif // MULTIPLE_OWNER
119
120     switch(oxm)
121     {
122     case OIC_JUST_WORKS:
123         callbacks->loadSecretCB = LoadSecretJustWorksCallback;
124         callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
125         callbacks->createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
126         callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
127         break;
128     case OIC_RANDOM_DEVICE_PIN:
129         callbacks->loadSecretCB = InputPinCodeCallback;
130         callbacks->createSecureSessionCB = CreateSecureSessionRandomPinCallback;
131         callbacks->createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
132         callbacks->createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
133         break;
134     case OIC_MANUFACTURER_CERTIFICATE:
135         callbacks->loadSecretCB = PrepareMCertificateCallback;
136         callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
137         callbacks->createSelectOxmPayloadCB = CreateMCertificateBasedSelectOxmPayload;
138         callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
139         break;
140     case OIC_DECENTRALIZED_PUBLIC_KEY:
141         OIC_LOG(ERROR, TAG, "OIC_DECENTRALIZED_PUBLIC_KEY not supported yet.");
142         return OC_STACK_INVALID_METHOD;
143 #ifdef MULTIPLE_OWNER
144     case OIC_PRECONFIG_PIN:
145         callbacks->loadSecretCB = LoadPreconfigPinCodeCallback;
146         callbacks->createSecureSessionCB = CreateSecureSessionPreconfigPinCallback;
147         callbacks->createSelectOxmPayloadCB = CreatePreconfigPinBasedSelectOxmPayload;
148         callbacks->createOwnerTransferPayloadCB = CreatePreconfigPinBasedOwnerTransferPayload;
149         break;
150 #endif //MULTIPLE_OWNER
151     case OIC_MV_JUST_WORKS:
152         callbacks->loadSecretCB = LoadSecretJustWorksCallback;
153         callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
154         callbacks->createSelectOxmPayloadCB = CreateMVJustWorksSelectOxmPayload;
155         callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
156         break;
157     case OIC_CON_MFG_CERT:
158         callbacks->loadSecretCB = PrepareMCertificateCallback;
159         callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
160         callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload;
161         callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
162         break;
163     default:
164         OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
165         return OC_STACK_INVALID_PARAM;
166         break;
167     }
168
169     res = OC_STACK_OK;
170 exit:
171     OIC_LOG(INFO, TAG, "OUT OTMSetOTCallback");
172     return res;
173 }
174
175 /**
176  * Internal API to convert OxM value to index of oxm allow table.
177  */
178 static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm)
179 {
180     switch(oxm)
181     {
182         case OIC_JUST_WORKS:
183             return OXM_IDX_JUST_WORKS;
184         case OIC_RANDOM_DEVICE_PIN:
185             return OXM_IDX_RANDOM_DEVICE_PIN;
186         case OIC_MANUFACTURER_CERTIFICATE:
187             return OXM_IDX_MANUFACTURER_CERTIFICATE;
188         case OIC_DECENTRALIZED_PUBLIC_KEY:
189             return OXM_IDX_DECENTRALIZED_PUBLIC_KEY;
190         case OIC_MV_JUST_WORKS:
191             return OXM_IDX_MV_JUST_WORKS;
192         case OIC_CON_MFG_CERT:
193             return OXM_IDX_CON_MFG_CERT;
194 #ifdef MULTIPLE_OWNER
195         case OIC_PRECONFIG_PIN:
196             return OXM_IDX_PRECONFIG_PIN;
197 #endif
198         default:
199             return OXM_IDX_UNKNOWN;
200     }
201 }
202
203 /**
204  * Function to select appropriate  provisioning method.
205  *
206  * @param[in] supportedMethods   Array of supported methods
207  * @param[in] numberOfMethods   number of supported methods
208  * @param[out]  selectedMethod         Selected methods
209  * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)
210  * @return  OC_STACK_OK on success
211  */
212 OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
213         size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType)
214 {
215     bool isOxmSelected = false;
216     OxmAllowTableIdx_t selectedOxmIdx = OXM_IDX_UNKNOWN;
217
218     OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
219
220     if (numberOfMethods == 0 || !supportedMethods)
221     {
222         OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
223         return OC_STACK_ERROR;
224     }
225
226     switch(ownerType)
227     {
228         case SUPER_OWNER:
229         {
230             for (size_t i = 0; i < numberOfMethods; i++)
231             {
232                 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
233                 if (OXM_IDX_COUNT <= selectedOxmIdx)
234                 {
235                     OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
236                     continue;
237                 }
238
239 #ifdef MULTIPLE_OWNER
240                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
241                    OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
242 #else
243                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
244 #endif //MULTIPLE_OWNER
245                 {
246                     *selectedMethod  = supportedMethods[i];
247                     isOxmSelected = true;
248                 }
249             }
250         }
251         break;
252 #ifdef MULTIPLE_OWNER
253         case SUB_OWNER:
254         {
255             for (size_t i = 0; i < numberOfMethods; i++)
256             {
257                 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
258                 if (OXM_IDX_COUNT <= selectedOxmIdx)
259                 {
260                     OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
261                     continue;
262                 }
263
264                 //in case of MOT, only Random PIN & Preconfigured PIN based OxM is allowed
265                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
266                     (OXM_IDX_RANDOM_DEVICE_PIN == selectedOxmIdx ||
267                      OXM_IDX_PRECONFIG_PIN == selectedOxmIdx))
268                 {
269                     *selectedMethod  = supportedMethods[i];
270                     isOxmSelected = true;
271                 }
272             }
273         }
274         break;
275 #endif
276         default:
277         {
278             OIC_LOG_V(ERROR, TAG, "Unknown owner type or Not supported owner type : %d", ownerType);
279             return OC_STACK_INVALID_PARAM;
280         }
281     }
282
283     if (!isOxmSelected)
284     {
285         OIC_LOG(ERROR, TAG, "Can not find the allowed OxM.");
286         return OC_STACK_NOT_ALLOWED_OXM;
287     }
288
289     OIC_LOG(DEBUG, TAG, "OUT SelectProvisioningMethod");
290
291     return OC_STACK_OK;
292 }
293
294 /**
295  * Function to select operation mode.This function will return most secure common operation mode.
296  *
297  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
298  * @param[out]   selectedMode   selected operation mode
299  * @return  OC_STACK_OK on success
300  */
301 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
302                                 OicSecDpom_t *selectedMode)
303 {
304     OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
305     *selectedMode = selectedDeviceInfo->pstat->sm[0];
306     OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
307 }
308
309 /**
310  * Function to start ownership transfer.
311  * This function will send the first request for provisioning,
312  * The next request message is sent from the response handler for this request.
313  *
314  * @param[in] ctx   context value passed to callback from calling function.
315  * @param[in] selectedDevice   selected device information to performing provisioning.
316  * @return  OC_STACK_OK on success
317  */
318 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
319
320 /*
321  * Internal function to setup & cleanup PDM to performing provisioning.
322  *
323  * @param[in] selectedDevice   selected device information to performing provisioning.
324  * @return  OC_STACK_OK on success
325  */
326 static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice);
327
328 /**
329  * Function to update owner transfer mode
330  *
331  * @param[in]  otmCtx  Context value of ownership transfer.
332  * @return  OC_STACK_OK on success
333  */
334 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx);
335
336 /**
337  * Function to send request to resource to get its pstat resource information.
338  *
339  * @param[in]  otmCtx  Context value of ownership transfer.
340  * @return  OC_STACK_OK on success
341  */
342 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
343
344
345 /**
346  * Function to send  uuid of owner device to new device.
347  * This function would update 'owner of doxm' as UUID for provisioning tool.
348  *
349  * @param[in]  otmCtx  Context value of ownership transfer.
350  * @return  OC_STACK_OK on success
351  */
352 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx);
353
354 /**
355  * Function to update the operation mode. As per the spec. Operation mode in client driven
356  * single service provisioning it will be updated to 0x3
357  *
358  * @param[in]  otmCtx  Context value of ownership transfer.
359  * @return  OC_STACK_OK on success
360  */
361 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx);
362
363 /**
364  * Function to update the owner credential to new device
365  *
366  * @param[in]  otmCtx  Context value of ownership transfer.
367  * @param[in] selectedOperationMode selected operation mode
368  * @return  OC_STACK_OK on success
369  */
370 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx);
371
372 /**
373  * Function to update the owner ACL to new device.
374  *
375  * @param[in]  otmCtx  Context value of ownership transfer.
376  * @return  OC_STACK_OK on success
377  */
378 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx);
379
380 /**
381  * Function to send ownerShip info.
382  * This function would update 'owned of doxm' as true.
383  *
384  * @param[in]  otmCtx  Context value of ownership transfer.
385  * @return  OC_STACK_OK on success
386  */
387 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx);
388
389 /**
390  * Function to update pstat as Ready for provisioning.
391  * This function would update 'cm' from bx0000,0010 to bx0000,0000.
392  *
393  * @param[in] ctx   context value passed to callback from calling function.
394  * @param[in] selectedDevice   selected device information to performing provisioning.
395  * @return  OC_STACK_OK on success
396  */
397 static OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx);
398
399 /**
400  * Function to update pstat as Ready for Normal Operation.
401  * This function would update 'isop' from false to true.
402  *
403  * @param[in] ctx   context value passed to callback from calling function.
404  * @param[in] selectedDevice   selected device information to performing provisioning.
405  * @return  OC_STACK_OK on success
406  */
407 static OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx);
408
409 static bool IsComplete(OTMContext_t* otmCtx)
410 {
411     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
412     {
413         if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
414         {
415             return false;
416         }
417     }
418
419     return true;
420 }
421
422 /**
423  * Function to save the result of provisioning.
424  *
425  * @param[in,out] otmCtx   Context value of ownership transfer.
426  * @param[in] res   result of provisioning
427  */
428 void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
429 {
430     OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
431
432     if(NULL == otmCtx || NULL == otmCtx->selectedDeviceInfo
433             || NULL == otmCtx->selectedDeviceInfo->doxm)
434     {
435         OIC_LOG(WARNING, TAG, "OTMContext is NULL");
436         return;
437     }
438
439     //If OTM Context was removed from previous response handler, just exit the current OTM process.
440     if(NULL == GetOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
441                              otmCtx->selectedDeviceInfo->securePort))
442     {
443         OIC_LOG(WARNING, TAG, "Current OTM Process has already ended.");
444     }
445
446     //Revert psk_info callback and new deivce uuid in case of random PIN OxM
447     if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
448     {
449         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
450         {
451             OIC_LOG(WARNING, TAG, "Failed to revert  is DTLS credential handler.");
452         }
453         OicUuid_t emptyUuid = { .id={0}};
454         SetUuidForPinBasedOxm(&emptyUuid);
455     }
456     else if(OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel ||
457                         OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)
458     {
459         //Revert back certificate related callbacks.
460         if(CA_STATUS_OK != CAregisterPkixInfoHandler(GetPkixInfo))
461         {
462             OIC_LOG(WARNING, TAG, "Failed to revert PkixInfoHandler.");
463         }
464         if(CA_STATUS_OK != CAregisterGetCredentialTypesHandler(InitCipherSuiteList))
465         {
466             OIC_LOG(WARNING, TAG, "Failed to revert CredentialTypesHandler.");
467         }
468     }
469
470     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
471     {
472         if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
473                   otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
474         {
475             otmCtx->ctxResultArray[i].res = res;
476             if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res)
477             {
478                 otmCtx->ctxHasError = true;
479                 if (OC_STACK_OK != PDMDeleteDevice(&otmCtx->ctxResultArray[i].deviceId))
480                 {
481                     OIC_LOG(WARNING, TAG, "Internal error in PDMDeleteDevice");
482                 }
483                 CAEndpoint_t endpoint;
484                 memcpy(&endpoint, &(otmCtx->selectedDeviceInfo->endpoint), sizeof(CAEndpoint_t));
485                 endpoint.port = otmCtx->selectedDeviceInfo->securePort;
486                 if (CA_STATUS_OK != CAcloseSslConnection(&endpoint))
487                 {
488                     OIC_LOG(WARNING, TAG, "Failed to close Secure session");
489                 }
490             }
491         }
492     }
493
494     //In case of duplicated OTM process, OTMContext and OCDoHandle should not be removed.
495     if(OC_STACK_DUPLICATE_REQUEST != res)
496     {
497         //Remove the current OTM Context from OTM queue
498         RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
499                          otmCtx->selectedDeviceInfo->securePort);
500
501         //If there is a request being performed, cancel it to prevent retransmission.
502         if(otmCtx->ocDoHandle)
503         {
504             OIC_LOG_V(DEBUG, TAG, "OCCancel - %s : %d",
505                     otmCtx->selectedDeviceInfo->endpoint.addr,
506                     otmCtx->selectedDeviceInfo->securePort);
507             if(OC_STACK_OK != OCCancel(otmCtx->ocDoHandle, OC_HIGH_QOS, NULL, 0))
508             {
509                 OIC_LOG(WARNING, TAG, "Failed to remove registered callback");
510             }
511             else
512             {
513                 otmCtx->ocDoHandle = NULL;
514             }
515         }
516     }
517
518     //If all OTM process is complete, invoke the user callback.
519     if(IsComplete(otmCtx))
520     {
521         if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res)
522         {
523             // Reset doxm and pstat properties to pre-Ownership Transfer state
524             OIC_LOG(DEBUG, TAG, "Resetting doxm and pstat properties");
525             if(otmCtx->selectedDeviceInfo->doxm)
526             {
527                 OicUuid_t emptyUuid = {.id = {0}};
528                 memcpy(&(otmCtx->selectedDeviceInfo->doxm->owner), &emptyUuid, sizeof(OicUuid_t));
529                 otmCtx->selectedDeviceInfo->doxm->owned = false;
530             }
531             if(otmCtx->selectedDeviceInfo->pstat)
532             {
533                 otmCtx->selectedDeviceInfo->pstat->isOp = false;
534                 otmCtx->selectedDeviceInfo->pstat->cm |= TAKE_OWNER;
535             }
536         }
537
538         otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
539                                    otmCtx->ctxResultArray, otmCtx->ctxHasError);
540         OICFree(otmCtx->ctxResultArray);
541         OICFree(otmCtx);
542     }
543     else
544     {
545         if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
546                                                  otmCtx->selectedDeviceInfo->next))
547         {
548             OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
549         }
550     }
551
552     OIC_LOG(DEBUG, TAG, "OUT SetResult");
553 }
554
555 /**
556  * Function to handle the handshake result in OTM.
557  * This function will be invoked after DTLS handshake
558  * @param   endPoint  [IN] The remote endpoint.
559  * @param   errorInfo [IN] Error information from the endpoint.
560  * @return  NONE
561  */
562 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
563 {
564     OIC_LOG(DEBUG, TAG, "IN DTLSHandshakeCB");
565     if(NULL != endpoint && NULL != info)
566     {
567         OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
568                  endpoint->addr, endpoint->port, info->result);
569
570         OTMContext_t* otmCtx = GetOTMContext(endpoint->addr, endpoint->port);
571         if(otmCtx)
572         {
573             OicSecDoxm_t* newDevDoxm = otmCtx->selectedDeviceInfo->doxm;
574             if(NULL != newDevDoxm)
575             {
576                 OicUuid_t emptyUuid = {.id={0}};
577
578                 //Make sure the address matches.
579                 if(strncmp(otmCtx->selectedDeviceInfo->endpoint.addr,
580                    endpoint->addr,
581                    sizeof(endpoint->addr)) == 0 &&
582                    otmCtx->selectedDeviceInfo->securePort == endpoint->port)
583                 {
584                     OCStackResult res = OC_STACK_ERROR;
585
586                     //If temporal secure sesstion established successfully
587                     if(CA_STATUS_OK == info->result &&
588                        false == newDevDoxm->owned &&
589                        memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0)
590                     {
591                         //In case of Mutual Verified Just-Works, display mutualVerifNum
592                         if (OIC_MV_JUST_WORKS == newDevDoxm->oxmSel)
593                         {
594                             uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
595                             uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
596                             OicUuid_t deviceID = {.id = {0}};
597
598                             //Generate mutualVerifNum
599                             char label[LABEL_LEN] = {0};
600                             snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS);
601                             res = GetDoxmDeviceID(&deviceID);
602                             if (OC_STACK_OK != res)
603                             {
604                                 OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
605                                 SetResult(otmCtx, res);
606                                 return;
607                             }
608
609                             CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
610                                     (uint8_t *)label,
611                                     strlen(label),
612                                     deviceID.id, sizeof(deviceID.id),
613                                     newDevDoxm->deviceID.id, sizeof(newDevDoxm->deviceID.id),
614                                     preMutualVerifNum, OWNER_PSK_LENGTH_128);
615                             if (CA_STATUS_OK != pskRet)
616                             {
617                                 OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
618                                 SetResult(otmCtx, OC_STACK_ERROR);
619                                 return;
620                             }
621
622                             memcpy(mutualVerifNum, preMutualVerifNum + OWNER_PSK_LENGTH_128 - sizeof(mutualVerifNum),
623                                     sizeof(mutualVerifNum));
624                             res = VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM);
625                             if (OC_STACK_OK != res)
626                             {
627                                 OIC_LOG(ERROR, TAG, "Error while displaying mutualVerifNum");
628                                 SetResult(otmCtx, res);
629                                 return;
630                             }
631                         }
632                         //In case of confirmed manufacturer cert, display message
633                         else if (OIC_MANUFACTURER_CERTIFICATE == newDevDoxm->oxmSel || OIC_CON_MFG_CERT == newDevDoxm->oxmSel)
634                         {
635                             res = VerifyOwnershipTransfer(NULL, DISPLAY_NUM);
636                             if (OC_STACK_OK != res)
637                             {
638                                 OIC_LOG(ERROR, TAG, "Error while displaying message");
639                                 SetResult(otmCtx, res);
640                                 return;
641                             }
642                         }
643
644                         //Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
645                         res = PostOwnerUuid(otmCtx);
646                         if(OC_STACK_OK != res)
647                         {
648                             OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
649                             SetResult(otmCtx, res);
650                         }
651                     }
652                     //In case of authentication failure
653                     else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
654                     {
655                         //in case of error from owner credential
656                         if(memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0 &&
657                             true == newDevDoxm->owned)
658                         {
659                             OIC_LOG(ERROR, TAG, "The owner credential may incorrect.");
660
661                             if(OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID)))
662                             {
663                                 OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
664                             }
665                             SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
666                         }
667                         //in case of error from wrong PIN, re-start the ownership transfer
668                         else if(OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel)
669                         {
670                             OIC_LOG(ERROR, TAG, "The PIN number may incorrect.");
671
672                             memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
673                             newDevDoxm->owned = false;
674                             otmCtx->attemptCnt++;
675
676                             RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
677                                              otmCtx->selectedDeviceInfo->securePort);
678
679                             // In order to re-start ownership transfer, device information should be deleted from PDM.
680                             res = PDMDeleteDevice(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
681                             if (OC_STACK_OK != res)
682                             {
683                                 SetResult(otmCtx, res);
684                                 OIC_LOG(ERROR, TAG, "Failed to PDMDeleteDevice");
685                             }
686                             else
687                             {
688                                 if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
689                                 {
690                                     res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
691                                     if(OC_STACK_OK != res)
692                                     {
693                                         SetResult(otmCtx, res);
694                                         OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
695                                     }
696                                 }
697                                 else
698                                 {
699                                     OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
700                                     SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
701                                 }
702                             }
703                         }
704                         else
705                         {
706                             OIC_LOG(ERROR, TAG, "Failed to establish secure session.");
707                             SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
708                         }
709                     }
710                 }
711             }
712         }
713         else
714         {
715             OIC_LOG(ERROR, TAG, "Can not find the OTM Context.");
716         }
717     }
718     OIC_LOG(DEBUG, TAG, "OUT DTLSHandshakeCB");
719 }
720
721 /**
722  * Function to save the Owner/SubOwner PSK.
723  *
724  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
725  * @return  OC_STACK_OK on success
726  */
727 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
728 {
729     OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
730
731     OCStackResult res = OC_STACK_ERROR;
732
733     CAEndpoint_t endpoint;
734     memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
735     OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
736     endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
737     endpoint.port = selectedDeviceInfo->securePort;
738     endpoint.adapter = selectedDeviceInfo->endpoint.adapter;
739
740     OicUuid_t ownerDeviceID = {.id={0}};
741     if (OC_STACK_OK != GetDoxmDeviceID(&ownerDeviceID))
742     {
743         OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
744         return res;
745     }
746
747     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
748     OicSecKey_t ownerKey = {.data=ownerPSK, .len=OWNER_PSK_LENGTH_128, .encoding=OIC_ENCODING_RAW};
749
750     //Generating OwnerPSK
751     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
752             (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
753             strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
754             ownerDeviceID.id, sizeof(ownerDeviceID.id),
755             selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
756             ownerPSK, OWNER_PSK_LENGTH_128);
757
758     if (CA_STATUS_OK == pskRet)
759     {
760         OIC_LOG(DEBUG, TAG,"Owner PSK dump:\n");
761         OIC_LOG_BUFFER(DEBUG, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
762         //Generating new credential for provisioning tool
763         OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
764                                   SYMMETRIC_PAIR_WISE_KEY, NULL,
765                                   &ownerKey, &ownerDeviceID, NULL);
766         OICClearMemory(ownerPSK, sizeof(ownerPSK));
767         VERIFY_NON_NULL(TAG, cred, ERROR);
768
769         uint32_t outSize = 0;
770         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
771         char* b64Buf = (char *)OICCalloc(1, b64BufSize);
772         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
773         b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize);
774
775         OICFree( cred->privateData.data );
776         cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
777         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
778
779         strncpy((char*)(cred->privateData.data), b64Buf, outSize);
780         cred->privateData.data[outSize] = '\0';
781         cred->privateData.encoding = OIC_ENCODING_BASE64;
782         cred->privateData.len = outSize;
783         OICFree(b64Buf);
784
785         //Finding previous ownerPSK.
786         const OicSecCred_t* credList = GetCredList();
787         const OicSecCred_t* prevCred = NULL;
788         uint16_t credId = 0;
789         LL_FOREACH(credList, prevCred)
790         {
791             //OwnerPSK's type is SYMMETRIC_PAIR_WISE_KEY
792             if (SYMMETRIC_PAIR_WISE_KEY == prevCred->credType &&
793                 0 == memcmp(prevCred->subject.id, cred->subject.id, sizeof(cred->subject.id)))
794             {
795                 credId = prevCred->credId;
796                 break;
797             }
798         }
799
800         //If duplicate owner PSK is exists, remove it.
801         if(0 < credId)
802         {
803             OIC_LOG(WARNING, TAG, "Duplicate OwnerPSK was detected.");
804             OIC_LOG(WARNING, TAG, "[Subject] : ");
805             OIC_LOG_BUFFER(WARNING, TAG, prevCred->subject.id, sizeof(prevCred->subject.id));
806             OIC_LOG_V(WARNING, TAG, "[Encoding Type] : %d", prevCred->privateData.encoding);
807             OIC_LOG(DEBUG, TAG, "[Private Data] : ");
808             OIC_LOG_BUFFER(DEBUG, TAG, prevCred->privateData.data, prevCred->privateData.len);
809             OIC_LOG(WARNING, TAG, "Previous OwnerPSK will be removed.");
810
811             res = RemoveCredentialByCredId(credId);
812             if(OC_STACK_RESOURCE_DELETED != res)
813             {
814                 OIC_LOG(ERROR, TAG, "Failed to remove the previous OwnerPSK");
815                 DeleteCredList(cred);
816                 goto exit;
817             }
818         }
819
820         res = AddCredential(cred);
821         if(res != OC_STACK_OK)
822         {
823             DeleteCredList(cred);
824             return res;
825         }
826     }
827     else
828     {
829         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
830     }
831
832     OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
833 exit:
834     return res;
835 }
836
837 /**
838  * Callback handler for OwnerShipTransferModeHandler API.
839  *
840  * @param[in] ctx             ctx value passed to callback from calling function.
841  * @param[in] UNUSED          handle to an invocation
842  * @param[in] clientResponse  Response from queries to remote servers.
843  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
844  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
845  */
846 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
847                                                          OCClientResponse *clientResponse)
848 {
849     OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
850
851     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
852     VERIFY_NON_NULL(TAG, ctx, WARNING);
853
854     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
855     otmCtx->ocDoHandle = NULL;
856     (void)UNUSED;
857     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
858     {
859         OIC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
860         //Send request : GET /oic/sec/pstat
861         OCStackResult res = GetProvisioningStatusResource(otmCtx);
862         if(OC_STACK_OK != res)
863         {
864             OIC_LOG(WARNING, TAG, "Failed to get pstat information");
865             SetResult(otmCtx, res);
866         }
867     }
868     else
869     {
870         OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
871         clientResponse->result);
872         SetResult(otmCtx, clientResponse->result);
873     }
874
875     OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
876
877 exit:
878     return  OC_STACK_DELETE_TRANSACTION;
879 }
880
881 /**
882  * Callback handler for ProvisioningStatusResouceHandler API.
883  *
884  * @param[in] ctx             ctx value passed to callback from calling function.
885  * @param[in] UNUSED          handle to an invocation
886  * @param[in] clientResponse  Response from queries to remote servers.
887  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
888  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
889  */
890 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
891                                                     OCClientResponse *clientResponse)
892 {
893     OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
894
895     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
896     VERIFY_NON_NULL(TAG, ctx, WARNING);
897
898     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
899     otmCtx->ocDoHandle = NULL;
900     (void)UNUSED;
901     if  (OC_STACK_OK == clientResponse->result)
902     {
903         if  (NULL == clientResponse->payload)
904         {
905             OIC_LOG(INFO, TAG, "Skiping Null payload");
906             SetResult(otmCtx, OC_STACK_ERROR);
907             return OC_STACK_DELETE_TRANSACTION;
908         }
909
910         if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
911         {
912             OIC_LOG(INFO, TAG, "Unknown payload type");
913             SetResult(otmCtx, OC_STACK_ERROR);
914             return OC_STACK_DELETE_TRANSACTION;
915         }
916         OicSecPstat_t* pstat = NULL;
917         OCStackResult result = CBORPayloadToPstat(
918                 ((OCSecurityPayload*)clientResponse->payload)->securityData,
919                 ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
920                 &pstat);
921         if(NULL == pstat || result != OC_STACK_OK)
922         {
923             OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
924             SetResult(otmCtx, OC_STACK_ERROR);
925             return OC_STACK_DELETE_TRANSACTION;
926         }
927         if(false == (TAKE_OWNER & pstat->cm))
928         {
929             OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
930             SetResult(otmCtx, OC_STACK_ERROR);
931             return OC_STACK_DELETE_TRANSACTION;
932         }
933         otmCtx->selectedDeviceInfo->pstat = pstat;
934
935         //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
936         SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
937
938         //Send request : POST /oic/sec/pstat [{"om":"bx11", .. }]
939         OCStackResult res = PostUpdateOperationMode(otmCtx);
940         if (OC_STACK_OK != res)
941         {
942             OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
943             SetResult(otmCtx, res);
944         }
945     }
946     else
947     {
948         OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
949             clientResponse->result);
950         SetResult(otmCtx, clientResponse->result);
951     }
952
953     OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
954 exit:
955     return  OC_STACK_DELETE_TRANSACTION;
956 }
957
958 /**
959  * Response handler for update owner uuid request.
960  *
961  * @param[in] ctx             ctx value passed to callback from calling function.
962  * @param[in] UNUSED          handle to an invocation
963  * @param[in] clientResponse  Response from queries to remote servers.
964  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
965  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
966  */
967 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
968                                 OCClientResponse *clientResponse)
969 {
970     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
971     VERIFY_NON_NULL(TAG, ctx, WARNING);
972
973     OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
974     (void)UNUSED;
975     OCStackResult res = OC_STACK_OK;
976     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
977     otmCtx->ocDoHandle = NULL;
978
979     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
980     {
981         if(otmCtx && otmCtx->selectedDeviceInfo)
982         {
983             //In case of Mutual Verified Just-Works, wait for user confirmation
984             if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel)
985             {
986                 res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
987                 if (OC_STACK_OK != res)
988                 {
989                     if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, otmCtx->ctxResultCallback))
990                     {
991                         OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error");
992                     }
993                     OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to verify user confirm");
994                     SetResult(otmCtx, res);
995                     return OC_STACK_DELETE_TRANSACTION;
996                 }
997             }
998
999             res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
1000             if(OC_STACK_OK != res)
1001             {
1002                 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
1003                 SetResult(otmCtx, res);
1004                 return OC_STACK_DELETE_TRANSACTION;
1005             }
1006
1007             //POST owner credential to new device according to security spec B.
1008             res = PostOwnerCredential(otmCtx);
1009             if(OC_STACK_OK != res)
1010             {
1011                 OIC_LOG(ERROR, TAG,
1012                         "OwnerUuidUpdateHandler:Failed to send PosT request for onwer credential");
1013                 SetResult(otmCtx, res);
1014                 return OC_STACK_DELETE_TRANSACTION;
1015             }
1016         }
1017     }
1018     else
1019     {
1020         if (((OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel) ||
1021             (OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)) &&
1022                     OC_STACK_NOT_ACCEPTABLE == clientResponse->result)
1023         {
1024             res = OC_STACK_USER_DENIED_REQ;
1025             OIC_LOG_V(ERROR, TAG,
1026                     "OwnerUuidUpdateHandler : Denied Request(%d)", res);
1027         }
1028         else if (OC_STACK_GATEWAY_TIMEOUT == clientResponse->result)
1029         {
1030             res = clientResponse->result;
1031             OIC_LOG_V(ERROR, TAG,
1032                     "OwnerUuidUpdateHandler : Timeout:No Response Received(%d)", res);
1033         }
1034         else
1035         {
1036             res = clientResponse->result;
1037             OIC_LOG_V(ERROR, TAG, "OwnerUuidUpdateHandler : Unexpected result(%d)", res);
1038         }
1039         SetResult(otmCtx, res);
1040     }
1041
1042     OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
1043
1044 exit:
1045     return  OC_STACK_DELETE_TRANSACTION;
1046 }
1047
1048 /*
1049  * Invokes Callback to load Random PIN
1050  */
1051 void *LoadRandomPin(void *ctx)
1052 {
1053     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1054     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1055     OCStackResult res = OC_STACK_ERROR;
1056     res = otmCtx->otmCallback.loadSecretCB(otmCtx);
1057
1058     if(OC_STACK_OK != res)
1059     {
1060         OIC_LOG_V(ERROR, TAG, "%s : Failed to load secret", __func__);
1061         SetResult(otmCtx, res);
1062         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1063         return NULL;
1064     }
1065
1066     //Save the current context instance to use on the dtls handshake callback
1067     if(OC_STACK_OK != AddOTMContext(otmCtx,
1068                                      otmCtx->selectedDeviceInfo->endpoint.addr,
1069                                      otmCtx->selectedDeviceInfo->securePort))
1070     {
1071         OIC_LOG_V(ERROR, TAG, "%s : Failed to add OTM Context into OTM List.", __func__);
1072         SetResult(otmCtx, res);
1073         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1074         return NULL;
1075     }
1076
1077     //Try DTLS handshake to generate secure session
1078     if(otmCtx->otmCallback.createSecureSessionCB)
1079     {
1080         res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
1081         if(OC_STACK_OK != res)
1082         {
1083             OIC_LOG_V(ERROR, TAG, "%s : Failed to create DTLS session", __func__);
1084             SetResult(otmCtx, res);
1085         }
1086     }
1087     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1088     return NULL;
1089 }
1090
1091 /**
1092  * Response handler for update operation mode.
1093  *
1094  * @param[in] ctx             ctx value passed to callback from calling function.
1095  * @param[in] UNUSED          handle to an invocation
1096  * @param[in] clientResponse  Response from queries to remote servers.
1097  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1098  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1099  */
1100 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
1101                                 OCClientResponse *clientResponse)
1102 {
1103     OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
1104
1105     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1106     VERIFY_NON_NULL(TAG, ctx, WARNING);
1107
1108     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1109     otmCtx->ocDoHandle = NULL;
1110     (void) UNUSED;
1111     if  (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1112     {
1113         OCStackResult res = OC_STACK_ERROR;
1114
1115         //DTLS Handshake
1116         //Load secret for temporal secure session.
1117         if(otmCtx->otmCallback.loadSecretCB)
1118         {
1119             if (OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1120             {
1121                 pthread_t p_thread;
1122                 int thr_result;
1123                 thr_result = pthread_create(&p_thread, NULL, LoadRandomPin, (void *) otmCtx);
1124                 if (0 != thr_result)
1125                 {
1126                     OIC_LOG_V(ERROR, TAG, "pthread_create Error with code %d", thr_result);
1127                     SetResult(otmCtx, res);
1128                     return  OC_STACK_DELETE_TRANSACTION;
1129                 }
1130                 OIC_LOG(INFO, TAG, "Random Pin loadSecretCB Thread Created");
1131             }
1132             else
1133             {
1134                 res = otmCtx->otmCallback.loadSecretCB(otmCtx);
1135                 if(OC_STACK_OK != res)
1136                 {
1137                     OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
1138                     SetResult(otmCtx, res);
1139                     return  OC_STACK_DELETE_TRANSACTION;
1140                 }
1141
1142                 //Save the current context instance to use on the dtls handshake callback
1143                 if(OC_STACK_OK != AddOTMContext(otmCtx,
1144                                                  otmCtx->selectedDeviceInfo->endpoint.addr,
1145                                                  otmCtx->selectedDeviceInfo->securePort))
1146                 {
1147                     OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List.");
1148                     SetResult(otmCtx, res);
1149                     return OC_STACK_DELETE_TRANSACTION;
1150                 }
1151
1152                 //Try DTLS handshake to generate secure session
1153                 if(otmCtx->otmCallback.createSecureSessionCB)
1154                 {
1155                     res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
1156                     if(OC_STACK_OK != res)
1157                     {
1158                         OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
1159                         SetResult(otmCtx, res);
1160                         return OC_STACK_DELETE_TRANSACTION;
1161                     }
1162                 }
1163             }
1164         }
1165     }
1166     else
1167     {
1168         OIC_LOG(ERROR, TAG, "Error while update operation mode");
1169         SetResult(otmCtx, clientResponse->result);
1170     }
1171
1172     OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
1173
1174 exit:
1175     return  OC_STACK_DELETE_TRANSACTION;
1176 }
1177
1178 /**
1179  * Response handler for update owner crendetial request.
1180  *
1181  * @param[in] ctx             ctx value passed to callback from calling function.
1182  * @param[in] UNUSED          handle to an invocation
1183  * @param[in] clientResponse  Response from queries to remote servers.
1184  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1185  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1186  */
1187 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
1188                                 OCClientResponse *clientResponse)
1189 {
1190     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1191     VERIFY_NON_NULL(TAG, ctx, WARNING);
1192
1193     OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
1194     (void)UNUSED;
1195     OCStackResult res = OC_STACK_OK;
1196     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1197     otmCtx->ocDoHandle = NULL;
1198
1199     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1200     {
1201         if(otmCtx && otmCtx->selectedDeviceInfo)
1202         {
1203             //Close the temporal secure session to verify the owner credential
1204             CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
1205             endpoint->port = otmCtx->selectedDeviceInfo->securePort;
1206             CAResult_t caResult = CA_STATUS_OK;
1207             caResult = CAcloseSslConnection(endpoint);
1208
1209             if(CA_STATUS_OK != caResult)
1210             {
1211                 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
1212                 SetResult(otmCtx, caResult);
1213                 return OC_STACK_DELETE_TRANSACTION;
1214             }
1215
1216             /**
1217              * If we select NULL cipher,
1218              * client will select appropriate cipher suite according to server's cipher-suite list.
1219              */
1220             // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
1221             caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
1222             if(CA_STATUS_OK != caResult)
1223             {
1224                 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
1225                 SetResult(otmCtx, caResult);
1226                 return OC_STACK_DELETE_TRANSACTION;
1227             }
1228
1229             /**
1230              * in case of random PIN based OxM,
1231              * revert get_psk_info callback of tinyDTLS to use owner credential.
1232              */
1233             if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1234             {
1235                 OicUuid_t emptyUuid = { .id={0}};
1236                 SetUuidForPinBasedOxm(&emptyUuid);
1237
1238                 caResult = CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
1239
1240                 if(CA_STATUS_OK != caResult)
1241                 {
1242                     OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1243                     SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
1244                     return OC_STACK_DELETE_TRANSACTION;
1245                 }
1246             }
1247 #ifdef __WITH_TLS__
1248            otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
1249 #endif
1250             res = PostOwnerAcl(otmCtx);
1251             if(OC_STACK_OK != res)
1252             {
1253                 OIC_LOG(ERROR, TAG, "Failed to update owner ACL to new device");
1254                 SetResult(otmCtx, res);
1255                 return OC_STACK_DELETE_TRANSACTION;
1256             }
1257         }
1258     }
1259     else
1260     {
1261         res = clientResponse->result;
1262         OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
1263         SetResult(otmCtx, res);
1264     }
1265
1266     OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
1267
1268 exit:
1269     return  OC_STACK_DELETE_TRANSACTION;
1270 }
1271
1272 /**
1273  * Response handler for update owner ACL request.
1274  *
1275  * @param[in] ctx             ctx value passed to callback from calling function.
1276  * @param[in] UNUSED          handle to an invocation
1277  * @param[in] clientResponse  Response from queries to remote servers.
1278  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1279  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1280  */
1281 static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle UNUSED,
1282                                 OCClientResponse *clientResponse)
1283 {
1284     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1285     VERIFY_NON_NULL(TAG, ctx, WARNING);
1286
1287     OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler");
1288     (void)UNUSED;
1289     OCStackResult res = OC_STACK_OK;
1290     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1291     otmCtx->ocDoHandle = NULL;
1292
1293     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1294     {
1295         if(otmCtx && otmCtx->selectedDeviceInfo)
1296         {
1297             //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }]
1298             res = PostOwnershipInformation(otmCtx);
1299             if(OC_STACK_OK != res)
1300             {
1301                 OIC_LOG(ERROR, TAG, "Failed to update ownership information to new device");
1302                 SetResult(otmCtx, res);
1303             }
1304         }
1305     }
1306     else
1307     {
1308         res = clientResponse->result;
1309         OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res);
1310         SetResult(otmCtx, res);
1311     }
1312
1313     OIC_LOG(DEBUG, TAG, "OUT OwnerAclHandler");
1314
1315 exit:
1316     return  OC_STACK_DELETE_TRANSACTION;
1317 }
1318
1319
1320 /**
1321  * Response handler for update owner information request.
1322  *
1323  * @param[in] ctx             ctx value passed to callback from calling function.
1324  * @param[in] UNUSED          handle to an invocation
1325  * @param[in] clientResponse  Response from queries to remote servers.
1326  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1327  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1328  */
1329 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
1330                                 OCClientResponse *clientResponse)
1331 {
1332     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1333     VERIFY_NON_NULL(TAG, ctx, WARNING);
1334
1335     OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
1336     (void)UNUSED;
1337     OCStackResult res = OC_STACK_OK;
1338     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1339     otmCtx->ocDoHandle = NULL;
1340
1341     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1342     {
1343         if(otmCtx && otmCtx->selectedDeviceInfo)
1344         {
1345             OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
1346             OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
1347
1348             res = PostProvisioningStatus(otmCtx);
1349             if(OC_STACK_OK != res)
1350             {
1351                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1352                 SetResult(otmCtx, res);
1353             }
1354         }
1355     }
1356     else
1357     {
1358         res = clientResponse->result;
1359         OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
1360         SetResult(otmCtx, res);
1361     }
1362
1363     OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
1364
1365 exit:
1366     return  OC_STACK_DELETE_TRANSACTION;
1367 }
1368
1369 /**
1370  * Response handler of update provisioning status.
1371  *
1372  * @param[in] ctx             ctx value passed to callback from calling function.
1373  * @param[in] UNUSED          handle to an invocation
1374  * @param[in] clientResponse  Response from queries to remote servers.
1375  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1376  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1377  */
1378 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
1379                                                        OCClientResponse *clientResponse)
1380 {
1381     OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
1382
1383     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1384     VERIFY_NON_NULL(TAG, ctx, ERROR);
1385
1386     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1387     otmCtx->ocDoHandle = NULL;
1388     (void)UNUSED;
1389     OCStackResult res = OC_STACK_OK;
1390
1391     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1392     {
1393         if(otmCtx && otmCtx->selectedDeviceInfo)
1394         {
1395             OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
1396
1397             res = PostNormalOperationStatus(otmCtx);
1398             if(OC_STACK_OK != res)
1399             {
1400                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1401                 SetResult(otmCtx, res);
1402             }
1403         }
1404     }
1405     else
1406     {
1407         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1408                             clientResponse->result);
1409         SetResult(otmCtx, clientResponse->result);
1410     }
1411
1412 exit:
1413     OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
1414     return OC_STACK_DELETE_TRANSACTION;
1415 }
1416
1417 /**
1418  * Response handler of update provisioning status to Ready for Normal..
1419  *
1420  * @param[in] ctx             ctx value passed to callback from calling function.
1421  * @param[in] UNUSED          handle to an invocation
1422  * @param[in] clientResponse  Response from queries to remote servers.
1423  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1424  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1425  */
1426 static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
1427                                                        OCClientResponse *clientResponse)
1428 {
1429     OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
1430
1431     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1432     VERIFY_NON_NULL(TAG, ctx, ERROR);
1433
1434     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1435     otmCtx->ocDoHandle = NULL;
1436     (void)UNUSED;
1437
1438     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1439     {
1440         OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
1441         OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
1442                                               PDM_DEVICE_ACTIVE);
1443          if (OC_STACK_OK == res)
1444          {
1445                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1446                 SetResult(otmCtx, OC_STACK_OK);
1447                 return OC_STACK_DELETE_TRANSACTION;
1448          }
1449           else
1450          {
1451               OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1452          }
1453     }
1454     else
1455     {
1456         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1457                             clientResponse->result);
1458         SetResult(otmCtx, clientResponse->result);
1459     }
1460
1461 exit:
1462     OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
1463     return OC_STACK_DELETE_TRANSACTION;
1464 }
1465
1466 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx)
1467 {
1468     OIC_LOG(DEBUG, TAG, "IN PostOwnerCredential");
1469
1470     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1471     {
1472         OIC_LOG(ERROR, TAG, "Invalid parameters");
1473         return OC_STACK_INVALID_PARAM;
1474     }
1475
1476     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1477     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1478
1479     if(!PMGenerateQuery(true,
1480                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1481                         deviceInfo->connType,
1482                         query, sizeof(query), OIC_RSRC_CRED_URI))
1483     {
1484         OIC_LOG(ERROR, TAG, "PostOwnerCredential : Failed to generate query");
1485         return OC_STACK_ERROR;
1486     }
1487     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1488     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1489     if(!secPayload)
1490     {
1491         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1492         return OC_STACK_NO_MEMORY;
1493     }
1494
1495     //Generate owner credential for new device
1496     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1497     const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
1498     if(!ownerCredential)
1499     {
1500         OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
1501         return OC_STACK_NO_RESOURCE;
1502     }
1503
1504     OicUuid_t credSubjectId = {.id={0}};
1505     if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
1506     {
1507         OicSecCred_t newCredential;
1508         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
1509         newCredential.next = NULL;
1510
1511         //Set subject ID as PT's ID
1512         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
1513
1514         //Fill private data as empty string
1515         newCredential.privateData.data = (uint8_t*)"";
1516         newCredential.privateData.len = 0;
1517         newCredential.privateData.encoding = ownerCredential->privateData.encoding;
1518
1519         newCredential.publicData.data = NULL;
1520         newCredential.publicData.len = 0;
1521         newCredential.publicData.encoding = ownerCredential->publicData.encoding;
1522
1523         int secureFlag = 0;
1524         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
1525         if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
1526                                         &secPayload->payloadSize, secureFlag))
1527         {
1528             OICFree(secPayload);
1529             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1530             return OC_STACK_ERROR;
1531         }
1532         OIC_LOG(DEBUG, TAG, "Cred Payload:");
1533         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1534
1535         OCCallbackData cbData;
1536         cbData.cb = &OwnerCredentialHandler;
1537         cbData.context = (void *)otmCtx;
1538         cbData.cd = NULL;
1539         OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1540                                          &deviceInfo->endpoint, (OCPayload*)secPayload,
1541                                          deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1542         if (res != OC_STACK_OK)
1543         {
1544             OIC_LOG(ERROR, TAG, "OCStack resource error");
1545         }
1546     }
1547     else
1548     {
1549         OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
1550         return OC_STACK_NO_RESOURCE;
1551     }
1552
1553     OIC_LOG(DEBUG, TAG, "OUT PostOwnerCredential");
1554
1555     return OC_STACK_OK;
1556 }
1557
1558 static OicSecAcl_t* GenerateOwnerAcl(const OicUuid_t* owner)
1559 {
1560     OicSecAcl_t* ownerAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
1561     OicSecAce_t* ownerAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1562     OicSecRsrc_t* wildcardRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1563     if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1564     {
1565         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1566         goto error;
1567     }
1568     LL_APPEND(ownerAcl->aces, ownerAce);
1569     LL_APPEND(ownerAce->resources, wildcardRsrc);
1570
1571     //Set resource owner as PT
1572     memcpy(ownerAcl->rownerID.id, owner->id, sizeof(owner->id));
1573
1574     //PT has full permission.
1575     ownerAce->permission = PERMISSION_FULL_CONTROL;
1576
1577     //Set subject as PT's UUID
1578     memcpy(ownerAce->subjectuuid.id, owner->id, sizeof(owner->id));
1579
1580     wildcardRsrc->href = OICStrdup(WILDCARD_RESOURCE_URI);
1581     if(NULL == wildcardRsrc->href)
1582     {
1583         goto error;
1584     }
1585
1586     wildcardRsrc->interfaceLen = 1;
1587     wildcardRsrc->interfaces = (char**)OICMalloc(wildcardRsrc->interfaceLen * sizeof(char*));
1588     if(NULL == wildcardRsrc->interfaces)
1589     {
1590         goto error;
1591     }
1592     wildcardRsrc->interfaces[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1593     if(NULL == wildcardRsrc->interfaces[0])
1594     {
1595         goto error;
1596     }
1597
1598     wildcardRsrc->typeLen = 1;
1599     wildcardRsrc->types = (char**)OICMalloc(wildcardRsrc->typeLen * sizeof(char*));
1600     if(NULL == wildcardRsrc->types)
1601     {
1602         goto error;
1603     }
1604     wildcardRsrc->types[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1605     if(NULL == wildcardRsrc->types[0])
1606     {
1607         goto error;
1608     }
1609
1610     return ownerAcl;
1611
1612 error:
1613     //in case of memory allocation failed, each resource should be removed individually.
1614     if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1615     {
1616         OICFree(ownerAcl);
1617         OICFree(ownerAce);
1618         OICFree(wildcardRsrc);
1619     }
1620     else
1621     {
1622         DeleteACLList(ownerAcl);
1623     }
1624     return NULL;
1625 }
1626
1627 /**
1628  * Function to update the owner ACL to new device.
1629  *
1630  * @param[in]  otmCtx  Context value of ownership transfer.
1631  * @return  OC_STACK_OK on success
1632  */
1633 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx)
1634 {
1635     OCStackResult res = OC_STACK_ERROR;
1636
1637     OIC_LOG(DEBUG, TAG, "IN PostOwnerAcl");
1638
1639     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1640     {
1641         OIC_LOG(ERROR, TAG, "Invalid parameters");
1642         return OC_STACK_INVALID_PARAM;
1643     }
1644
1645     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1646     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1647     OicSecAcl_t* ownerAcl = NULL;
1648
1649     if(!PMGenerateQuery(true,
1650                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1651                         deviceInfo->connType,
1652                         query, sizeof(query), OIC_RSRC_ACL_URI))
1653     {
1654         OIC_LOG(ERROR, TAG, "Failed to generate query");
1655         return OC_STACK_ERROR;
1656     }
1657     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1658
1659     OicUuid_t ownerID;
1660     res = GetDoxmDeviceID(&ownerID);
1661     if(OC_STACK_OK != res)
1662     {
1663         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1664         return res;
1665     }
1666
1667     //Generate owner ACL for new device
1668     ownerAcl = GenerateOwnerAcl(&ownerID);
1669     if(NULL == ownerAcl)
1670     {
1671         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1672         return OC_STACK_NO_MEMORY;
1673     }
1674
1675     //Generate ACL payload
1676     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1677     if(!secPayload)
1678     {
1679         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1680         res = OC_STACK_NO_MEMORY;
1681         goto error;
1682     }
1683
1684     res = AclToCBORPayload(ownerAcl, &secPayload->securityData, &secPayload->payloadSize);
1685     if (OC_STACK_OK != res)
1686     {
1687         OICFree(secPayload);
1688         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1689         goto error;
1690     }
1691     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1692
1693     OIC_LOG(DEBUG, TAG, "Owner ACL Payload:");
1694     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1695
1696     //Send owner ACL to new device : POST /oic/sec/cred [ owner credential ]
1697     OCCallbackData cbData;
1698     cbData.cb = &OwnerAclHandler;
1699     cbData.context = (void *)otmCtx;
1700     cbData.cd = NULL;
1701     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1702                                      &deviceInfo->endpoint, (OCPayload*)secPayload,
1703                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1704     if (res != OC_STACK_OK)
1705     {
1706         OIC_LOG(ERROR, TAG, "OCStack resource error");
1707         goto error;
1708     }
1709
1710     OIC_LOG(DEBUG, TAG, "OUT PostOwnerAcl");
1711
1712 error:
1713     DeleteACLList(ownerAcl);
1714
1715     return OC_STACK_OK;
1716 }
1717
1718 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx)
1719 {
1720     OIC_LOG(DEBUG, TAG, "IN PostOwnerTransferModeToResource");
1721
1722     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1723     {
1724         OIC_LOG(ERROR, TAG, "Invalid parameters");
1725         return OC_STACK_INVALID_PARAM;
1726     }
1727
1728     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1729     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1730
1731     if(!PMGenerateQuery(false,
1732                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1733                         deviceInfo->connType,
1734                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1735     {
1736         OIC_LOG(ERROR, TAG, "PostOwnerTransferModeToResource : Failed to generate query");
1737         return OC_STACK_ERROR;
1738     }
1739     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1740
1741     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1742     if(!secPayload)
1743     {
1744         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1745         return OC_STACK_NO_MEMORY;
1746     }
1747
1748     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1749     OCStackResult res = otmCtx->otmCallback.createSelectOxmPayloadCB(otmCtx,
1750             &secPayload->securityData, &secPayload->payloadSize);
1751     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1752     {
1753         OCPayloadDestroy((OCPayload *)secPayload);
1754         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
1755         return OC_STACK_ERROR;
1756     }
1757
1758     OCCallbackData cbData;
1759     cbData.cb = &OwnerTransferModeHandler;
1760     cbData.context = (void *)otmCtx;
1761     cbData.cd = NULL;
1762     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1763                        &deviceInfo->endpoint, (OCPayload *)secPayload,
1764                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1765     if (res != OC_STACK_OK)
1766     {
1767         OIC_LOG(ERROR, TAG, "OCStack resource error");
1768     }
1769
1770     OIC_LOG(DEBUG, TAG, "OUT PostOwnerTransferModeToResource");
1771
1772     return res;
1773 }
1774
1775 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1776 {
1777     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1778
1779     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1780     {
1781         OIC_LOG(ERROR, TAG, "Invailed parameters");
1782         return OC_STACK_INVALID_PARAM;
1783     }
1784
1785     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1786     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1787     if(!PMGenerateQuery(false,
1788                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1789                         deviceInfo->connType,
1790                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1791     {
1792         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1793         return OC_STACK_ERROR;
1794     }
1795     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1796
1797     OCCallbackData cbData;
1798     cbData.cb = &ListMethodsHandler;
1799     cbData.context = (void *)otmCtx;
1800     cbData.cd = NULL;
1801     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
1802                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1803     if (res != OC_STACK_OK)
1804     {
1805         OIC_LOG(ERROR, TAG, "OCStack resource error");
1806     }
1807
1808     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1809
1810     return res;
1811 }
1812
1813 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
1814 {
1815     OIC_LOG(DEBUG, TAG, "IN PostOwnerUuid");
1816
1817     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1818     {
1819         OIC_LOG(ERROR, TAG, "Invailed parameters");
1820         return OC_STACK_INVALID_PARAM;
1821     }
1822
1823     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1824     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1825     if(!PMGenerateQuery(true,
1826                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1827                         deviceInfo->connType,
1828                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1829     {
1830         OIC_LOG(ERROR, TAG, "PostOwnerUuid : Failed to generate query");
1831         return OC_STACK_ERROR;
1832     }
1833     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1834
1835     //Post PT's uuid to new device
1836     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1837     if(!secPayload)
1838     {
1839         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1840         return OC_STACK_NO_MEMORY;
1841     }
1842     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1843     OCStackResult res = otmCtx->otmCallback.createOwnerTransferPayloadCB(
1844             otmCtx, &secPayload->securityData, &secPayload->payloadSize);
1845     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1846     {
1847         OCPayloadDestroy((OCPayload *)secPayload);
1848         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
1849         return OC_STACK_INVALID_PARAM;
1850     }
1851     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1852
1853     OCCallbackData cbData;
1854     cbData.cb = &OwnerUuidUpdateHandler;
1855     cbData.context = (void *)otmCtx;
1856     cbData.cd = NULL;
1857
1858     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1859             deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1860     if (res != OC_STACK_OK)
1861     {
1862         OIC_LOG(ERROR, TAG, "OCStack resource error");
1863     }
1864
1865     OIC_LOG(DEBUG, TAG, "OUT PostOwnerUuid");
1866
1867     return res;
1868 }
1869
1870 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
1871 {
1872     OIC_LOG(DEBUG, TAG, "IN PostOwnershipInformation");
1873
1874     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1875     {
1876         OIC_LOG(ERROR, TAG, "Invailed parameters");
1877         return OC_STACK_INVALID_PARAM;
1878     }
1879
1880     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1881     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1882     if(!PMGenerateQuery(true,
1883                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1884                         deviceInfo->connType,
1885                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1886     {
1887         OIC_LOG(ERROR, TAG, "PostOwnershipInformation : Failed to generate query");
1888         return OC_STACK_ERROR;
1889     }
1890     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1891
1892     //OwnershipInformationHandler
1893     OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1894     if (!secPayload)
1895     {
1896         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1897         return OC_STACK_NO_MEMORY;
1898     }
1899
1900     otmCtx->selectedDeviceInfo->doxm->owned = true;
1901
1902     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1903     OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
1904             &secPayload->securityData, &secPayload->payloadSize, true);
1905     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1906     {
1907         OCPayloadDestroy((OCPayload *)secPayload);
1908         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1909         return OC_STACK_INVALID_PARAM;
1910     }
1911
1912     OCCallbackData cbData;
1913     cbData.cb = &OwnershipInformationHandler;
1914     cbData.context = (void *)otmCtx;
1915     cbData.cd = NULL;
1916
1917     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
1918                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1919     if (res != OC_STACK_OK)
1920     {
1921         OIC_LOG(ERROR, TAG, "OCStack resource error");
1922     }
1923
1924     OIC_LOG(DEBUG, TAG, "OUT PostOwnershipInformation");
1925
1926     return res;
1927 }
1928
1929 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
1930 {
1931     OIC_LOG(DEBUG, TAG, "IN PostUpdateOperationMode");
1932
1933     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1934     {
1935         return OC_STACK_INVALID_PARAM;
1936     }
1937
1938     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1939     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1940     if(!PMGenerateQuery(false,
1941                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1942                         deviceInfo->connType,
1943                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1944     {
1945         OIC_LOG(ERROR, TAG, "PostUpdateOperationMode : Failed to generate query");
1946         return OC_STACK_ERROR;
1947     }
1948     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1949
1950     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1951     if(!secPayload)
1952     {
1953         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1954         return OC_STACK_NO_MEMORY;
1955     }
1956     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1957     OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
1958                                            &secPayload->payloadSize, true);
1959    if (OC_STACK_OK != res)
1960     {
1961         OCPayloadDestroy((OCPayload *)secPayload);
1962         OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
1963         return OC_STACK_INVALID_PARAM;
1964     }
1965
1966     OCCallbackData cbData;
1967     cbData.cb = &OperationModeUpdateHandler;
1968     cbData.context = (void *)otmCtx;
1969     cbData.cd = NULL;
1970     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1971                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1972     if (res != OC_STACK_OK)
1973     {
1974         OIC_LOG(ERROR, TAG, "OCStack resource error");
1975     }
1976
1977     OIC_LOG(DEBUG, TAG, "OUT PostUpdateOperationMode");
1978
1979     return res;
1980 }
1981
1982 static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice)
1983 {
1984     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1985
1986     PdmDeviceState_t pdmState = PDM_DEVICE_UNKNOWN;
1987     OCStackResult res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState);
1988     if (OC_STACK_OK != res)
1989     {
1990         OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res);
1991         return res;
1992     }
1993
1994     char* strUuid = NULL;
1995     bool removeCredReq = false;
1996     if (OC_STACK_OK != ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid))
1997     {
1998         OIC_LOG(WARNING, TAG, "Failed to covert uuid to string");
1999         return OC_STACK_NO_MEMORY;
2000     }
2001
2002     if (PDM_DEVICE_UNKNOWN == pdmState && !selectedDevice->doxm->owned)
2003     {
2004         removeCredReq = true;
2005     }
2006     else if (PDM_DEVICE_ACTIVE == pdmState && !selectedDevice->doxm->owned)
2007     {
2008         OIC_LOG_V(WARNING, TAG, "Unowned device[%s] dectected from PDM.", strUuid);
2009         OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", strUuid);
2010         res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
2011         if(OC_STACK_OK != res)
2012         {
2013             OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", strUuid);
2014             goto exit;
2015         }
2016
2017         removeCredReq = true;
2018     }
2019
2020     if (removeCredReq)
2021     {
2022         OIC_LOG_V(WARNING, TAG, "[%s]'s credential will be removed.", strUuid);
2023         res = RemoveCredential(&selectedDevice->doxm->deviceID);
2024         if (OC_STACK_RESOURCE_DELETED != res)
2025         {
2026             OIC_LOG_V(WARNING, TAG, "Can not find [%s]'s credential.", strUuid);
2027         }
2028     }
2029
2030     //Checking duplication of Device ID.
2031     bool isDuplicate = true;
2032     res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
2033     if (OC_STACK_OK != res)
2034     {
2035         OIC_LOG_V(ERROR, TAG, "Internal error in PDMIsDuplicateDevice : %d", res);
2036         goto exit;
2037     }
2038
2039     if (isDuplicate)
2040     {
2041         char* strUuid = NULL;
2042         res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
2043         if (OC_STACK_OK != res)
2044         {
2045             OIC_LOG_V(ERROR, TAG, "Failed to convert UUID to str : %d", res);
2046             goto exit;
2047         }
2048
2049         if (PDM_DEVICE_STALE == pdmState)
2050         {
2051             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
2052                                "device status will revert back to initial status.");
2053             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
2054             if (OC_STACK_OK != res)
2055             {
2056                 OIC_LOG_V(ERROR, TAG, "Internal error in PDMSetDeviceState : %d", res);
2057                 goto exit;
2058             }
2059         }
2060         else if (PDM_DEVICE_INIT == pdmState)
2061         {
2062             OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
2063             OICFree(strUuid);
2064             res = OC_STACK_DUPLICATE_REQUEST;
2065             goto exit;
2066         }
2067         else
2068         {
2069             OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
2070             OICFree(strUuid);
2071             res = OC_STACK_ERROR;
2072             goto exit;
2073         }
2074     }
2075     else
2076     {
2077         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
2078         if (OC_STACK_OK != res)
2079         {
2080             OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res);
2081             goto exit;
2082         }
2083     }
2084
2085 exit:
2086     OICFree(strUuid);
2087     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2088     return res;
2089 }
2090
2091 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
2092 {
2093     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
2094     OCStackResult res = OC_STACK_INVALID_PARAM;
2095     OicUuid_t emptyOwner = {.id = {0} };
2096
2097     VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
2098     VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
2099
2100     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
2101     otmCtx->selectedDeviceInfo = selectedDevice;
2102
2103     //If devowneruuid of selectedDevice is not emtry, PostOwnerUuid does not triggered in DTLSHandshakeCB
2104     if (memcmp(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
2105     {
2106         OIC_LOG(DEBUG, TAG, "Set devowneruuid of selectedDevice to empty for OwnershipTransfer");
2107         memcpy(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t));
2108     }
2109
2110     //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
2111     res = SetupPDM(selectedDevice);
2112     if(OC_STACK_OK != res)
2113     {
2114         OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
2115         SetResult(otmCtx, res);
2116         return res;
2117     }
2118
2119     //Select the OxM to performing ownership transfer
2120     res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
2121                                           selectedDevice->doxm->oxmLen,
2122                                           &selectedDevice->doxm->oxmSel,
2123                                           SUPER_OWNER);
2124     if(OC_STACK_OK != res)
2125     {
2126         OIC_LOG_V(ERROR, TAG, "Failed to select the provisioning method : %d", res);
2127         SetResult(otmCtx, res);
2128         return res;
2129     }
2130     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
2131
2132     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
2133     if(OC_STACK_OK != res)
2134     {
2135         OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
2136         return res;
2137     }
2138
2139     //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
2140     res = PostOwnerTransferModeToResource(otmCtx);
2141     if(OC_STACK_OK != res)
2142     {
2143         OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
2144         SetResult(otmCtx, res);
2145         return res;
2146     }
2147
2148 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2149     //Register TLS event handler to catch the tls event while handshake
2150     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2151     {
2152         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2153     }
2154 #endif // __WITH_DTLS__ or __WITH_TLS__
2155     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2156
2157 exit:
2158     return res;
2159 }
2160
2161 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
2162 {
2163     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
2164
2165     if(!data)
2166     {
2167         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
2168         return OC_STACK_INVALID_PARAM;
2169     }
2170     if(oxmType >= OIC_OXM_COUNT)
2171     {
2172         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
2173         return OC_STACK_INVALID_PARAM;
2174     }
2175
2176     // TODO: Remove this API, Please see the jira ticket IOT-1484
2177
2178     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
2179
2180     return OC_STACK_OK;
2181 }
2182
2183 /**
2184  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
2185  */
2186 OCStackResult OTMDoOwnershipTransfer(void* ctx,
2187                                      OCProvisionDev_t *selectedDevicelist,
2188                                      OCProvisionResultCB resultCallback)
2189 {
2190     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
2191
2192     if (NULL == selectedDevicelist)
2193     {
2194         return OC_STACK_INVALID_PARAM;
2195     }
2196     if (NULL == resultCallback)
2197     {
2198         return OC_STACK_INVALID_CALLBACK;
2199     }
2200
2201     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2202     if(!otmCtx)
2203     {
2204         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2205         return OC_STACK_NO_MEMORY;
2206     }
2207     otmCtx->ctxResultCallback = resultCallback;
2208     otmCtx->ctxHasError = false;
2209     otmCtx->userCtx = ctx;
2210     OCProvisionDev_t* pCurDev = selectedDevicelist;
2211
2212     //Counting number of selected devices.
2213     otmCtx->ctxResultArraySize = 0;
2214     while(NULL != pCurDev)
2215     {
2216         otmCtx->ctxResultArraySize++;
2217         pCurDev = pCurDev->next;
2218     }
2219
2220     otmCtx->ctxResultArray =
2221         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2222     if(NULL == otmCtx->ctxResultArray)
2223     {
2224         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2225         OICFree(otmCtx);
2226         return OC_STACK_NO_MEMORY;
2227     }
2228     pCurDev = selectedDevicelist;
2229
2230     //Fill the device UUID for result array.
2231     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
2232     {
2233         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
2234                pCurDev->doxm->deviceID.id,
2235                UUID_LENGTH);
2236         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
2237         pCurDev = pCurDev->next;
2238     }
2239
2240     OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist);
2241
2242     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
2243
2244     return res;
2245 }
2246
2247 OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
2248 {
2249     OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
2250               __func__, oxm, (allowStatus ? "true" : "false"));
2251
2252 #ifdef MULTIPLE_OWNER
2253     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
2254 #else
2255     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
2256 #endif
2257     {
2258         return OC_STACK_INVALID_PARAM;
2259     }
2260
2261     OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
2262     if(OXM_IDX_COUNT <= oxmIdx)
2263     {
2264         OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
2265         return OC_STACK_ERROR;
2266     }
2267     g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
2268
2269     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2270
2271     return OC_STACK_OK;
2272 }
2273
2274 OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
2275 {
2276     OIC_LOG(INFO, TAG, "IN PostProvisioningStatus");
2277
2278     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2279     {
2280         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2281         return OC_STACK_INVALID_PARAM;
2282     }
2283
2284     //Change the TAKE_OWNER bit of CM to 0.
2285     otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
2286
2287     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2288     if (!secPayload)
2289     {
2290         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2291         return OC_STACK_NO_MEMORY;
2292     }
2293     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2294     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2295             &secPayload->securityData, &secPayload->payloadSize, true))
2296     {
2297         OCPayloadDestroy((OCPayload *)secPayload);
2298         return OC_STACK_INVALID_JSON;
2299     }
2300     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2301     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2302
2303     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2304     if(!PMGenerateQuery(true,
2305                         otmCtx->selectedDeviceInfo->endpoint.addr,
2306                         otmCtx->selectedDeviceInfo->securePort,
2307                         otmCtx->selectedDeviceInfo->connType,
2308                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2309     {
2310         OIC_LOG(ERROR, TAG, "PostProvisioningStatus : Failed to generate query");
2311         return OC_STACK_ERROR;
2312     }
2313     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2314
2315     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2316     cbData.cb = &ProvisioningStatusHandler;
2317     cbData.context = (void*)otmCtx;
2318     cbData.cd = NULL;
2319     OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2320             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2321     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2322     if (ret != OC_STACK_OK)
2323     {
2324         OIC_LOG(ERROR, TAG, "OCStack resource error");
2325     }
2326
2327     OIC_LOG(INFO, TAG, "OUT PostProvisioningStatus");
2328
2329     return ret;
2330 }
2331
2332 OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
2333 {
2334     OIC_LOG(INFO, TAG, "IN PostNormalOperationStatus");
2335
2336     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2337     {
2338         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2339         return OC_STACK_INVALID_PARAM;
2340     }
2341
2342     //Set isop to true.
2343     otmCtx->selectedDeviceInfo->pstat->isOp = true;
2344
2345     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2346     if (!secPayload)
2347     {
2348         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2349         return OC_STACK_NO_MEMORY;
2350     }
2351     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2352     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2353             &secPayload->securityData, &secPayload->payloadSize, true))
2354     {
2355         OCPayloadDestroy((OCPayload *)secPayload);
2356         return OC_STACK_INVALID_JSON;
2357     }
2358     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2359     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2360
2361     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2362     if(!PMGenerateQuery(true,
2363                         otmCtx->selectedDeviceInfo->endpoint.addr,
2364                         otmCtx->selectedDeviceInfo->securePort,
2365                         otmCtx->selectedDeviceInfo->connType,
2366                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2367     {
2368         OIC_LOG(ERROR, TAG, "PostNormalOperationStatus : Failed to generate query");
2369         return OC_STACK_ERROR;
2370     }
2371     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2372
2373     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2374     cbData.cb = &ReadyForNomalStatusHandler;
2375     cbData.context = (void*)otmCtx;
2376     cbData.cd = NULL;
2377     OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2378             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2379     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2380     if (ret != OC_STACK_OK)
2381     {
2382         OIC_LOG(ERROR, TAG, "OCStack resource error");
2383     }
2384
2385     OIC_LOG(INFO, TAG, "OUT PostNormalOperationStatus");
2386
2387     return ret;
2388 }
2389
2390 OCStackResult ConfigSelfOwnership(void)
2391 {
2392     OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership");
2393
2394     bool isDeviceOwned = true;
2395     if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned))
2396     {
2397         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state");
2398         return OC_STACK_ERROR;
2399     }
2400     if( (true == isDeviceOwned) ||(true == GetPstatIsop()) )
2401     {
2402         OIC_LOG(ERROR, TAG, "The state of device is not Ready for Ownership transfer.");
2403         return OC_STACK_ERROR;
2404     }
2405     OicUuid_t deviceID = {.id={0}};
2406     if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2407     {
2408         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2409         return OC_STACK_ERROR;
2410     }
2411
2412     OCStackResult ret = OC_STACK_OK;
2413     //Update the pstat resource as Normal Operation.
2414     ret = SetPstatSelfOwnership(&deviceID);
2415     if(OC_STACK_OK != ret)
2416     {
2417         OIC_LOG (ERROR, TAG, "Unable to update pstat resource as Normal Operation");
2418         goto exit;
2419     }
2420     //Update the doxm resource as Normal Operation.
2421     ret = SetDoxmSelfOwnership(&deviceID);
2422     if(OC_STACK_OK != ret)
2423     {
2424         OIC_LOG (ERROR, TAG, "Unable to update doxm resource as Normal Operation");
2425         goto exit;
2426     }
2427     //Update default ACE of security resource to prevent anonymous user access.
2428     ret = UpdateDefaultSecProvACE();
2429     if(OC_STACK_OK != ret)
2430     {
2431         OIC_LOG (ERROR, TAG, "Unable to update default ace in ConfigSelfOwnership");
2432         goto exit;
2433     }
2434     //Update the acl resource owner as owner device.
2435     ret = SetAclRownerId(&deviceID);
2436     if(OC_STACK_OK != ret)
2437     {
2438         OIC_LOG (ERROR, TAG, "Unable to update acl resource in ConfigSelfOwnership");
2439         goto exit;
2440     }
2441     //Update the cred resource owner as owner device.
2442     ret = SetCredRownerId(&deviceID);
2443     if(OC_STACK_OK != ret)
2444     {
2445         // Cred resouce may be empty in Ready for Ownership transfer state.
2446         if (OC_STACK_NO_RESOURCE == ret)
2447         {
2448             OIC_LOG (INFO, TAG, "Cred resource is empty");
2449             ret = OC_STACK_OK;
2450             goto exit;
2451         }
2452         OIC_LOG (ERROR, TAG, "Unable to update cred resource in ConfigSelfOwnership");
2453     }
2454
2455 exit:
2456     if(OC_STACK_OK != ret)
2457     {
2458         /*
2459          * If some error is occured while configure self-ownership,
2460          * ownership related resource should be revert back to initial status.
2461         */
2462         ResetSecureResourceInPS();
2463     }
2464
2465     return ret;
2466 }
2467
2468
2469 void OTMTerminate()
2470 {
2471     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2472     DeleteOTMContextList();
2473
2474 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2475     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(NULL))
2476     {
2477         OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback.");
2478     }
2479 #endif // __WITH_DTLS__ or __WITH_TLS__
2480
2481     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2482 }