Update snapshot(2018-01-17)
[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 static void deleteCallback(void *ctx)
959 {
960     OC_UNUSED(ctx);
961     OIC_LOG_V(DEBUG, TAG, "%s: otm context deleted", __func__);
962 }
963
964
965 /**
966  * Response handler for update owner uuid request.
967  *
968  * @param[in] ctx             ctx value passed to callback from calling function.
969  * @param[in] UNUSED          handle to an invocation
970  * @param[in] clientResponse  Response from queries to remote servers.
971  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
972  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
973  */
974 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
975                                 OCClientResponse *clientResponse)
976 {
977     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
978     VERIFY_NON_NULL(TAG, ctx, WARNING);
979
980     OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
981     (void)UNUSED;
982     OCStackResult res = OC_STACK_OK;
983     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
984     otmCtx->ocDoHandle = NULL;
985
986     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
987     {
988         if(otmCtx && otmCtx->selectedDeviceInfo)
989         {
990             //In case of Mutual Verified Just-Works, wait for user confirmation
991             if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel)
992             {
993                 res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
994                 if (OC_STACK_OK != res)
995                 {
996                     if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, deleteCallback))
997                     {
998                         OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error");
999                     }
1000                     OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to verify user confirm");
1001                     SetResult(otmCtx, res);
1002                     return OC_STACK_DELETE_TRANSACTION;
1003                 }
1004             }
1005
1006             res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
1007             if(OC_STACK_OK != res)
1008             {
1009                 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
1010                 SetResult(otmCtx, res);
1011                 return OC_STACK_DELETE_TRANSACTION;
1012             }
1013
1014             //POST owner credential to new device according to security spec B.
1015             res = PostOwnerCredential(otmCtx);
1016             if(OC_STACK_OK != res)
1017             {
1018                 OIC_LOG(ERROR, TAG,
1019                         "OwnerUuidUpdateHandler:Failed to send PosT request for onwer credential");
1020                 SetResult(otmCtx, res);
1021                 return OC_STACK_DELETE_TRANSACTION;
1022             }
1023         }
1024     }
1025     else
1026     {
1027         if (((OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel) ||
1028             (OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)) &&
1029                     OC_STACK_NOT_ACCEPTABLE == clientResponse->result)
1030         {
1031             res = OC_STACK_USER_DENIED_REQ;
1032             OIC_LOG_V(ERROR, TAG,
1033                     "OwnerUuidUpdateHandler : Denied Request(%d)", res);
1034         }
1035         else if (OC_STACK_GATEWAY_TIMEOUT == clientResponse->result)
1036         {
1037             res = clientResponse->result;
1038             OIC_LOG_V(ERROR, TAG,
1039                     "OwnerUuidUpdateHandler : Timeout:No Response Received(%d)", res);
1040         }
1041         else
1042         {
1043             res = clientResponse->result;
1044             OIC_LOG_V(ERROR, TAG, "OwnerUuidUpdateHandler : Unexpected result(%d)", res);
1045         }
1046         SetResult(otmCtx, res);
1047     }
1048
1049     OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
1050
1051 exit:
1052     return  OC_STACK_DELETE_TRANSACTION;
1053 }
1054
1055 /*
1056  * Invokes Callback to load Random PIN
1057  */
1058 void *LoadRandomPin(void *ctx)
1059 {
1060     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1061     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1062     OCStackResult res = OC_STACK_ERROR;
1063     res = otmCtx->otmCallback.loadSecretCB(otmCtx);
1064
1065     if(OC_STACK_OK != res)
1066     {
1067         OIC_LOG_V(ERROR, TAG, "%s : Failed to load secret", __func__);
1068         SetResult(otmCtx, res);
1069         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1070         return NULL;
1071     }
1072
1073     //Save the current context instance to use on the dtls handshake callback
1074     if(OC_STACK_OK != AddOTMContext(otmCtx,
1075                                      otmCtx->selectedDeviceInfo->endpoint.addr,
1076                                      otmCtx->selectedDeviceInfo->securePort))
1077     {
1078         OIC_LOG_V(ERROR, TAG, "%s : Failed to add OTM Context into OTM List.", __func__);
1079         SetResult(otmCtx, res);
1080         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1081         return NULL;
1082     }
1083
1084     //Try DTLS handshake to generate secure session
1085     if(otmCtx->otmCallback.createSecureSessionCB)
1086     {
1087         res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
1088         if(OC_STACK_OK != res)
1089         {
1090             OIC_LOG_V(ERROR, TAG, "%s : Failed to create DTLS session", __func__);
1091             SetResult(otmCtx, res);
1092         }
1093     }
1094     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1095     return NULL;
1096 }
1097
1098 /**
1099  * Response handler for update operation mode.
1100  *
1101  * @param[in] ctx             ctx value passed to callback from calling function.
1102  * @param[in] UNUSED          handle to an invocation
1103  * @param[in] clientResponse  Response from queries to remote servers.
1104  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1105  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1106  */
1107 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
1108                                 OCClientResponse *clientResponse)
1109 {
1110     OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
1111
1112     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1113     VERIFY_NON_NULL(TAG, ctx, WARNING);
1114
1115     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1116     otmCtx->ocDoHandle = NULL;
1117     (void) UNUSED;
1118     if  (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1119     {
1120         OCStackResult res = OC_STACK_ERROR;
1121
1122         //DTLS Handshake
1123         //Load secret for temporal secure session.
1124         if(otmCtx->otmCallback.loadSecretCB)
1125         {
1126             if (OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1127             {
1128                 pthread_t p_thread;
1129                 int thr_result;
1130                 thr_result = pthread_create(&p_thread, NULL, LoadRandomPin, (void *) otmCtx);
1131                 if (0 != thr_result)
1132                 {
1133                     OIC_LOG_V(ERROR, TAG, "pthread_create Error with code %d", thr_result);
1134                     SetResult(otmCtx, res);
1135                     return  OC_STACK_DELETE_TRANSACTION;
1136                 }
1137                 OIC_LOG(INFO, TAG, "Random Pin loadSecretCB Thread Created");
1138             }
1139             else
1140             {
1141                 res = otmCtx->otmCallback.loadSecretCB(otmCtx);
1142                 if(OC_STACK_OK != res)
1143                 {
1144                     OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
1145                     SetResult(otmCtx, res);
1146                     return  OC_STACK_DELETE_TRANSACTION;
1147                 }
1148
1149                 //Save the current context instance to use on the dtls handshake callback
1150                 if(OC_STACK_OK != AddOTMContext(otmCtx,
1151                                                  otmCtx->selectedDeviceInfo->endpoint.addr,
1152                                                  otmCtx->selectedDeviceInfo->securePort))
1153                 {
1154                     OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List.");
1155                     SetResult(otmCtx, res);
1156                     return OC_STACK_DELETE_TRANSACTION;
1157                 }
1158
1159                 //Try DTLS handshake to generate secure session
1160                 if(otmCtx->otmCallback.createSecureSessionCB)
1161                 {
1162                     res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
1163                     if(OC_STACK_OK != res)
1164                     {
1165                         OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
1166                         SetResult(otmCtx, res);
1167                         return OC_STACK_DELETE_TRANSACTION;
1168                     }
1169                 }
1170             }
1171         }
1172     }
1173     else
1174     {
1175         OIC_LOG(ERROR, TAG, "Error while update operation mode");
1176         SetResult(otmCtx, clientResponse->result);
1177     }
1178
1179     OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
1180
1181 exit:
1182     return  OC_STACK_DELETE_TRANSACTION;
1183 }
1184
1185 /**
1186  * Response handler for update owner crendetial request.
1187  *
1188  * @param[in] ctx             ctx value passed to callback from calling function.
1189  * @param[in] UNUSED          handle to an invocation
1190  * @param[in] clientResponse  Response from queries to remote servers.
1191  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1192  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1193  */
1194 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
1195                                 OCClientResponse *clientResponse)
1196 {
1197     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1198     VERIFY_NON_NULL(TAG, ctx, WARNING);
1199
1200     OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
1201     (void)UNUSED;
1202     OCStackResult res = OC_STACK_OK;
1203     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1204     otmCtx->ocDoHandle = NULL;
1205
1206     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1207     {
1208         if(otmCtx && otmCtx->selectedDeviceInfo)
1209         {
1210             //Close the temporal secure session to verify the owner credential
1211             CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
1212             endpoint->port = otmCtx->selectedDeviceInfo->securePort;
1213             CAResult_t caResult = CA_STATUS_OK;
1214             caResult = CAcloseSslConnection(endpoint);
1215
1216             if(CA_STATUS_OK != caResult)
1217             {
1218                 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
1219                 SetResult(otmCtx, caResult);
1220                 return OC_STACK_DELETE_TRANSACTION;
1221             }
1222
1223             /**
1224              * If we select NULL cipher,
1225              * client will select appropriate cipher suite according to server's cipher-suite list.
1226              */
1227             // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
1228             caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
1229             if(CA_STATUS_OK != caResult)
1230             {
1231                 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
1232                 SetResult(otmCtx, caResult);
1233                 return OC_STACK_DELETE_TRANSACTION;
1234             }
1235
1236             /**
1237              * in case of random PIN based OxM,
1238              * revert get_psk_info callback of tinyDTLS to use owner credential.
1239              */
1240             if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1241             {
1242                 OicUuid_t emptyUuid = { .id={0}};
1243                 SetUuidForPinBasedOxm(&emptyUuid);
1244
1245                 caResult = CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
1246
1247                 if(CA_STATUS_OK != caResult)
1248                 {
1249                     OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1250                     SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
1251                     return OC_STACK_DELETE_TRANSACTION;
1252                 }
1253             }
1254 #ifdef __WITH_TLS__
1255            otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
1256 #endif
1257             res = PostOwnerAcl(otmCtx);
1258             if(OC_STACK_OK != res)
1259             {
1260                 OIC_LOG(ERROR, TAG, "Failed to update owner ACL to new device");
1261                 SetResult(otmCtx, res);
1262                 return OC_STACK_DELETE_TRANSACTION;
1263             }
1264         }
1265     }
1266     else
1267     {
1268         res = clientResponse->result;
1269         OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
1270         SetResult(otmCtx, res);
1271     }
1272
1273     OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
1274
1275 exit:
1276     return  OC_STACK_DELETE_TRANSACTION;
1277 }
1278
1279 /**
1280  * Response handler for update owner ACL request.
1281  *
1282  * @param[in] ctx             ctx value passed to callback from calling function.
1283  * @param[in] UNUSED          handle to an invocation
1284  * @param[in] clientResponse  Response from queries to remote servers.
1285  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1286  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1287  */
1288 static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle UNUSED,
1289                                 OCClientResponse *clientResponse)
1290 {
1291     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1292     VERIFY_NON_NULL(TAG, ctx, WARNING);
1293
1294     OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler");
1295     (void)UNUSED;
1296     OCStackResult res = OC_STACK_OK;
1297     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1298     otmCtx->ocDoHandle = NULL;
1299
1300     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1301     {
1302         if(otmCtx && otmCtx->selectedDeviceInfo)
1303         {
1304             //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }]
1305             res = PostOwnershipInformation(otmCtx);
1306             if(OC_STACK_OK != res)
1307             {
1308                 OIC_LOG(ERROR, TAG, "Failed to update ownership information to new device");
1309                 SetResult(otmCtx, res);
1310             }
1311         }
1312     }
1313     else
1314     {
1315         res = clientResponse->result;
1316         OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res);
1317         SetResult(otmCtx, res);
1318     }
1319
1320     OIC_LOG(DEBUG, TAG, "OUT OwnerAclHandler");
1321
1322 exit:
1323     return  OC_STACK_DELETE_TRANSACTION;
1324 }
1325
1326
1327 /**
1328  * Response handler for update owner information request.
1329  *
1330  * @param[in] ctx             ctx value passed to callback from calling function.
1331  * @param[in] UNUSED          handle to an invocation
1332  * @param[in] clientResponse  Response from queries to remote servers.
1333  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1334  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1335  */
1336 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
1337                                 OCClientResponse *clientResponse)
1338 {
1339     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1340     VERIFY_NON_NULL(TAG, ctx, WARNING);
1341
1342     OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
1343     (void)UNUSED;
1344     OCStackResult res = OC_STACK_OK;
1345     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1346     otmCtx->ocDoHandle = NULL;
1347
1348     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1349     {
1350         if(otmCtx && otmCtx->selectedDeviceInfo)
1351         {
1352             OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
1353             OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
1354
1355             res = PostProvisioningStatus(otmCtx);
1356             if(OC_STACK_OK != res)
1357             {
1358                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1359                 SetResult(otmCtx, res);
1360             }
1361         }
1362     }
1363     else
1364     {
1365         res = clientResponse->result;
1366         OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
1367         SetResult(otmCtx, res);
1368     }
1369
1370     OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
1371
1372 exit:
1373     return  OC_STACK_DELETE_TRANSACTION;
1374 }
1375
1376 /**
1377  * Response handler of update provisioning status.
1378  *
1379  * @param[in] ctx             ctx value passed to callback from calling function.
1380  * @param[in] UNUSED          handle to an invocation
1381  * @param[in] clientResponse  Response from queries to remote servers.
1382  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1383  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1384  */
1385 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
1386                                                        OCClientResponse *clientResponse)
1387 {
1388     OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
1389
1390     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1391     VERIFY_NON_NULL(TAG, ctx, ERROR);
1392
1393     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1394     otmCtx->ocDoHandle = NULL;
1395     (void)UNUSED;
1396     OCStackResult res = OC_STACK_OK;
1397
1398     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1399     {
1400         if(otmCtx && otmCtx->selectedDeviceInfo)
1401         {
1402             OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
1403
1404             res = PostNormalOperationStatus(otmCtx);
1405             if(OC_STACK_OK != res)
1406             {
1407                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1408                 SetResult(otmCtx, res);
1409             }
1410         }
1411     }
1412     else
1413     {
1414         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1415                             clientResponse->result);
1416         SetResult(otmCtx, clientResponse->result);
1417     }
1418
1419 exit:
1420     OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
1421     return OC_STACK_DELETE_TRANSACTION;
1422 }
1423
1424 /**
1425  * Response handler of update provisioning status to Ready for Normal..
1426  *
1427  * @param[in] ctx             ctx value passed to callback from calling function.
1428  * @param[in] UNUSED          handle to an invocation
1429  * @param[in] clientResponse  Response from queries to remote servers.
1430  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1431  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1432  */
1433 static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
1434                                                        OCClientResponse *clientResponse)
1435 {
1436     OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
1437
1438     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1439     VERIFY_NON_NULL(TAG, ctx, ERROR);
1440
1441     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1442     otmCtx->ocDoHandle = NULL;
1443     (void)UNUSED;
1444
1445     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1446     {
1447         OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
1448         OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
1449                                               PDM_DEVICE_ACTIVE);
1450          if (OC_STACK_OK == res)
1451          {
1452                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1453                 SetResult(otmCtx, OC_STACK_OK);
1454                 return OC_STACK_DELETE_TRANSACTION;
1455          }
1456           else
1457          {
1458               OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1459          }
1460     }
1461     else
1462     {
1463         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1464                             clientResponse->result);
1465         SetResult(otmCtx, clientResponse->result);
1466     }
1467
1468 exit:
1469     OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
1470     return OC_STACK_DELETE_TRANSACTION;
1471 }
1472
1473 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx)
1474 {
1475     OIC_LOG(DEBUG, TAG, "IN PostOwnerCredential");
1476
1477     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1478     {
1479         OIC_LOG(ERROR, TAG, "Invalid parameters");
1480         return OC_STACK_INVALID_PARAM;
1481     }
1482
1483     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1484     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1485
1486     if(!PMGenerateQuery(true,
1487                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1488                         deviceInfo->connType,
1489                         query, sizeof(query), OIC_RSRC_CRED_URI))
1490     {
1491         OIC_LOG(ERROR, TAG, "PostOwnerCredential : Failed to generate query");
1492         return OC_STACK_ERROR;
1493     }
1494     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1495     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1496     if(!secPayload)
1497     {
1498         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1499         return OC_STACK_NO_MEMORY;
1500     }
1501
1502     //Generate owner credential for new device
1503     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1504     const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
1505     if(!ownerCredential)
1506     {
1507         OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
1508         return OC_STACK_NO_RESOURCE;
1509     }
1510
1511     OicUuid_t credSubjectId = {.id={0}};
1512     if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
1513     {
1514         OicSecCred_t newCredential;
1515         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
1516         newCredential.next = NULL;
1517
1518         //Set subject ID as PT's ID
1519         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
1520
1521         //Fill private data as empty string
1522         newCredential.privateData.data = (uint8_t*)"";
1523         newCredential.privateData.len = 0;
1524         newCredential.privateData.encoding = ownerCredential->privateData.encoding;
1525
1526         newCredential.publicData.data = NULL;
1527         newCredential.publicData.len = 0;
1528         newCredential.publicData.encoding = ownerCredential->publicData.encoding;
1529
1530         int secureFlag = 0;
1531         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
1532         if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
1533                                         &secPayload->payloadSize, secureFlag))
1534         {
1535             OICFree(secPayload);
1536             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1537             return OC_STACK_ERROR;
1538         }
1539         OIC_LOG(DEBUG, TAG, "Cred Payload:");
1540         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1541
1542         OCCallbackData cbData;
1543         cbData.cb = &OwnerCredentialHandler;
1544         cbData.context = (void *)otmCtx;
1545         cbData.cd = NULL;
1546         OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1547                                          &deviceInfo->endpoint, (OCPayload*)secPayload,
1548                                          deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1549         if (res != OC_STACK_OK)
1550         {
1551             OIC_LOG(ERROR, TAG, "OCStack resource error");
1552         }
1553     }
1554     else
1555     {
1556         OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
1557         return OC_STACK_NO_RESOURCE;
1558     }
1559
1560     OIC_LOG(DEBUG, TAG, "OUT PostOwnerCredential");
1561
1562     return OC_STACK_OK;
1563 }
1564
1565 static OicSecAcl_t* GenerateOwnerAcl(const OicUuid_t* owner)
1566 {
1567     OicSecAcl_t* ownerAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
1568     OicSecAce_t* ownerAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1569     OicSecRsrc_t* wildcardRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1570     if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1571     {
1572         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1573         goto error;
1574     }
1575     LL_APPEND(ownerAcl->aces, ownerAce);
1576     LL_APPEND(ownerAce->resources, wildcardRsrc);
1577
1578     //Set resource owner as PT
1579     memcpy(ownerAcl->rownerID.id, owner->id, sizeof(owner->id));
1580
1581     //PT has full permission.
1582     ownerAce->permission = PERMISSION_FULL_CONTROL;
1583
1584     //Set subject as PT's UUID
1585     memcpy(ownerAce->subjectuuid.id, owner->id, sizeof(owner->id));
1586
1587     wildcardRsrc->href = OICStrdup(WILDCARD_RESOURCE_URI);
1588     if(NULL == wildcardRsrc->href)
1589     {
1590         goto error;
1591     }
1592
1593     wildcardRsrc->interfaceLen = 1;
1594     wildcardRsrc->interfaces = (char**)OICMalloc(wildcardRsrc->interfaceLen * sizeof(char*));
1595     if(NULL == wildcardRsrc->interfaces)
1596     {
1597         goto error;
1598     }
1599     wildcardRsrc->interfaces[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1600     if(NULL == wildcardRsrc->interfaces[0])
1601     {
1602         goto error;
1603     }
1604
1605     wildcardRsrc->typeLen = 1;
1606     wildcardRsrc->types = (char**)OICMalloc(wildcardRsrc->typeLen * sizeof(char*));
1607     if(NULL == wildcardRsrc->types)
1608     {
1609         goto error;
1610     }
1611     wildcardRsrc->types[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1612     if(NULL == wildcardRsrc->types[0])
1613     {
1614         goto error;
1615     }
1616
1617     return ownerAcl;
1618
1619 error:
1620     //in case of memory allocation failed, each resource should be removed individually.
1621     if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1622     {
1623         OICFree(ownerAcl);
1624         OICFree(ownerAce);
1625         OICFree(wildcardRsrc);
1626     }
1627     else
1628     {
1629         DeleteACLList(ownerAcl);
1630     }
1631     return NULL;
1632 }
1633
1634 /**
1635  * Function to update the owner ACL to new device.
1636  *
1637  * @param[in]  otmCtx  Context value of ownership transfer.
1638  * @return  OC_STACK_OK on success
1639  */
1640 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx)
1641 {
1642     OCStackResult res = OC_STACK_ERROR;
1643
1644     OIC_LOG(DEBUG, TAG, "IN PostOwnerAcl");
1645
1646     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1647     {
1648         OIC_LOG(ERROR, TAG, "Invalid parameters");
1649         return OC_STACK_INVALID_PARAM;
1650     }
1651
1652     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1653     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1654     OicSecAcl_t* ownerAcl = NULL;
1655
1656     if(!PMGenerateQuery(true,
1657                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1658                         deviceInfo->connType,
1659                         query, sizeof(query), OIC_RSRC_ACL_URI))
1660     {
1661         OIC_LOG(ERROR, TAG, "Failed to generate query");
1662         return OC_STACK_ERROR;
1663     }
1664     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1665
1666     OicUuid_t ownerID;
1667     res = GetDoxmDeviceID(&ownerID);
1668     if(OC_STACK_OK != res)
1669     {
1670         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1671         return res;
1672     }
1673
1674     //Generate owner ACL for new device
1675     ownerAcl = GenerateOwnerAcl(&ownerID);
1676     if(NULL == ownerAcl)
1677     {
1678         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1679         return OC_STACK_NO_MEMORY;
1680     }
1681
1682     //Generate ACL payload
1683     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1684     if(!secPayload)
1685     {
1686         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1687         res = OC_STACK_NO_MEMORY;
1688         goto error;
1689     }
1690
1691     res = AclToCBORPayload(ownerAcl, &secPayload->securityData, &secPayload->payloadSize);
1692     if (OC_STACK_OK != res)
1693     {
1694         OICFree(secPayload);
1695         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1696         goto error;
1697     }
1698     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1699
1700     OIC_LOG(DEBUG, TAG, "Owner ACL Payload:");
1701     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1702
1703     //Send owner ACL to new device : POST /oic/sec/cred [ owner credential ]
1704     OCCallbackData cbData;
1705     cbData.cb = &OwnerAclHandler;
1706     cbData.context = (void *)otmCtx;
1707     cbData.cd = NULL;
1708     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1709                                      &deviceInfo->endpoint, (OCPayload*)secPayload,
1710                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1711     if (res != OC_STACK_OK)
1712     {
1713         OIC_LOG(ERROR, TAG, "OCStack resource error");
1714         goto error;
1715     }
1716
1717     OIC_LOG(DEBUG, TAG, "OUT PostOwnerAcl");
1718
1719 error:
1720     DeleteACLList(ownerAcl);
1721
1722     return OC_STACK_OK;
1723 }
1724
1725 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx)
1726 {
1727     OIC_LOG(DEBUG, TAG, "IN PostOwnerTransferModeToResource");
1728
1729     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1730     {
1731         OIC_LOG(ERROR, TAG, "Invalid parameters");
1732         return OC_STACK_INVALID_PARAM;
1733     }
1734
1735     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1736     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1737
1738     if(!PMGenerateQuery(false,
1739                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1740                         deviceInfo->connType,
1741                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1742     {
1743         OIC_LOG(ERROR, TAG, "PostOwnerTransferModeToResource : Failed to generate query");
1744         return OC_STACK_ERROR;
1745     }
1746     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1747
1748     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1749     if(!secPayload)
1750     {
1751         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1752         return OC_STACK_NO_MEMORY;
1753     }
1754
1755     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1756     OCStackResult res = otmCtx->otmCallback.createSelectOxmPayloadCB(otmCtx,
1757             &secPayload->securityData, &secPayload->payloadSize);
1758     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1759     {
1760         OCPayloadDestroy((OCPayload *)secPayload);
1761         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
1762         return OC_STACK_ERROR;
1763     }
1764
1765     OCCallbackData cbData;
1766     cbData.cb = &OwnerTransferModeHandler;
1767     cbData.context = (void *)otmCtx;
1768     cbData.cd = NULL;
1769     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1770                        &deviceInfo->endpoint, (OCPayload *)secPayload,
1771                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1772     if (res != OC_STACK_OK)
1773     {
1774         OIC_LOG(ERROR, TAG, "OCStack resource error");
1775     }
1776
1777     OIC_LOG(DEBUG, TAG, "OUT PostOwnerTransferModeToResource");
1778
1779     return res;
1780 }
1781
1782 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1783 {
1784     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1785
1786     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1787     {
1788         OIC_LOG(ERROR, TAG, "Invailed parameters");
1789         return OC_STACK_INVALID_PARAM;
1790     }
1791
1792     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1793     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1794     if(!PMGenerateQuery(false,
1795                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1796                         deviceInfo->connType,
1797                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1798     {
1799         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1800         return OC_STACK_ERROR;
1801     }
1802     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1803
1804     OCCallbackData cbData;
1805     cbData.cb = &ListMethodsHandler;
1806     cbData.context = (void *)otmCtx;
1807     cbData.cd = NULL;
1808     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
1809                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1810     if (res != OC_STACK_OK)
1811     {
1812         OIC_LOG(ERROR, TAG, "OCStack resource error");
1813     }
1814
1815     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1816
1817     return res;
1818 }
1819
1820 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
1821 {
1822     OIC_LOG(DEBUG, TAG, "IN PostOwnerUuid");
1823
1824     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1825     {
1826         OIC_LOG(ERROR, TAG, "Invailed parameters");
1827         return OC_STACK_INVALID_PARAM;
1828     }
1829
1830     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1831     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1832     if(!PMGenerateQuery(true,
1833                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1834                         deviceInfo->connType,
1835                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1836     {
1837         OIC_LOG(ERROR, TAG, "PostOwnerUuid : Failed to generate query");
1838         return OC_STACK_ERROR;
1839     }
1840     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1841
1842     //Post PT's uuid to new device
1843     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1844     if(!secPayload)
1845     {
1846         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1847         return OC_STACK_NO_MEMORY;
1848     }
1849     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1850     OCStackResult res = otmCtx->otmCallback.createOwnerTransferPayloadCB(
1851             otmCtx, &secPayload->securityData, &secPayload->payloadSize);
1852     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1853     {
1854         OCPayloadDestroy((OCPayload *)secPayload);
1855         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
1856         return OC_STACK_INVALID_PARAM;
1857     }
1858     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1859
1860     OCCallbackData cbData;
1861     cbData.cb = &OwnerUuidUpdateHandler;
1862     cbData.context = (void *)otmCtx;
1863     cbData.cd = NULL;
1864
1865     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1866             deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1867     if (res != OC_STACK_OK)
1868     {
1869         OIC_LOG(ERROR, TAG, "OCStack resource error");
1870     }
1871
1872     OIC_LOG(DEBUG, TAG, "OUT PostOwnerUuid");
1873
1874     return res;
1875 }
1876
1877 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
1878 {
1879     OIC_LOG(DEBUG, TAG, "IN PostOwnershipInformation");
1880
1881     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1882     {
1883         OIC_LOG(ERROR, TAG, "Invailed parameters");
1884         return OC_STACK_INVALID_PARAM;
1885     }
1886
1887     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1888     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1889     if(!PMGenerateQuery(true,
1890                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1891                         deviceInfo->connType,
1892                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1893     {
1894         OIC_LOG(ERROR, TAG, "PostOwnershipInformation : Failed to generate query");
1895         return OC_STACK_ERROR;
1896     }
1897     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1898
1899     //OwnershipInformationHandler
1900     OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1901     if (!secPayload)
1902     {
1903         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1904         return OC_STACK_NO_MEMORY;
1905     }
1906
1907     otmCtx->selectedDeviceInfo->doxm->owned = true;
1908
1909     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1910     OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
1911             &secPayload->securityData, &secPayload->payloadSize, true);
1912     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1913     {
1914         OCPayloadDestroy((OCPayload *)secPayload);
1915         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1916         return OC_STACK_INVALID_PARAM;
1917     }
1918
1919     OCCallbackData cbData;
1920     cbData.cb = &OwnershipInformationHandler;
1921     cbData.context = (void *)otmCtx;
1922     cbData.cd = NULL;
1923
1924     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
1925                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1926     if (res != OC_STACK_OK)
1927     {
1928         OIC_LOG(ERROR, TAG, "OCStack resource error");
1929     }
1930
1931     OIC_LOG(DEBUG, TAG, "OUT PostOwnershipInformation");
1932
1933     return res;
1934 }
1935
1936 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
1937 {
1938     OIC_LOG(DEBUG, TAG, "IN PostUpdateOperationMode");
1939
1940     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1941     {
1942         return OC_STACK_INVALID_PARAM;
1943     }
1944
1945     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1946     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1947     if(!PMGenerateQuery(false,
1948                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1949                         deviceInfo->connType,
1950                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1951     {
1952         OIC_LOG(ERROR, TAG, "PostUpdateOperationMode : Failed to generate query");
1953         return OC_STACK_ERROR;
1954     }
1955     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1956
1957     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1958     if(!secPayload)
1959     {
1960         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1961         return OC_STACK_NO_MEMORY;
1962     }
1963     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1964     OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
1965                                            &secPayload->payloadSize, true);
1966    if (OC_STACK_OK != res)
1967     {
1968         OCPayloadDestroy((OCPayload *)secPayload);
1969         OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
1970         return OC_STACK_INVALID_PARAM;
1971     }
1972
1973     OCCallbackData cbData;
1974     cbData.cb = &OperationModeUpdateHandler;
1975     cbData.context = (void *)otmCtx;
1976     cbData.cd = NULL;
1977     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1978                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1979     if (res != OC_STACK_OK)
1980     {
1981         OIC_LOG(ERROR, TAG, "OCStack resource error");
1982     }
1983
1984     OIC_LOG(DEBUG, TAG, "OUT PostUpdateOperationMode");
1985
1986     return res;
1987 }
1988
1989 static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice)
1990 {
1991     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1992
1993     PdmDeviceState_t pdmState = PDM_DEVICE_UNKNOWN;
1994     OCStackResult res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState);
1995     if (OC_STACK_OK != res)
1996     {
1997         OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res);
1998         return res;
1999     }
2000
2001     char* strUuid = NULL;
2002     bool removeCredReq = false;
2003     if (OC_STACK_OK != ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid))
2004     {
2005         OIC_LOG(WARNING, TAG, "Failed to covert uuid to string");
2006         return OC_STACK_NO_MEMORY;
2007     }
2008
2009     if (PDM_DEVICE_UNKNOWN == pdmState && !selectedDevice->doxm->owned)
2010     {
2011         removeCredReq = true;
2012     }
2013     else if (PDM_DEVICE_ACTIVE == pdmState && !selectedDevice->doxm->owned)
2014     {
2015         OIC_LOG_V(WARNING, TAG, "Unowned device[%s] dectected from PDM.", strUuid);
2016         OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", strUuid);
2017         res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
2018         if(OC_STACK_OK != res)
2019         {
2020             OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", strUuid);
2021             goto exit;
2022         }
2023
2024         removeCredReq = true;
2025     }
2026
2027     if (removeCredReq)
2028     {
2029         OIC_LOG_V(WARNING, TAG, "[%s]'s credential will be removed.", strUuid);
2030         res = RemoveCredential(&selectedDevice->doxm->deviceID);
2031         if (OC_STACK_RESOURCE_DELETED != res)
2032         {
2033             OIC_LOG_V(WARNING, TAG, "Can not find [%s]'s credential.", strUuid);
2034         }
2035     }
2036
2037     //Checking duplication of Device ID.
2038     bool isDuplicate = true;
2039     res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
2040     if (OC_STACK_OK != res)
2041     {
2042         OIC_LOG_V(ERROR, TAG, "Internal error in PDMIsDuplicateDevice : %d", res);
2043         goto exit;
2044     }
2045
2046     if (isDuplicate)
2047     {
2048         char* strUuid = NULL;
2049         res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
2050         if (OC_STACK_OK != res)
2051         {
2052             OIC_LOG_V(ERROR, TAG, "Failed to convert UUID to str : %d", res);
2053             goto exit;
2054         }
2055
2056         if (PDM_DEVICE_STALE == pdmState)
2057         {
2058             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
2059                                "device status will revert back to initial status.");
2060             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
2061             if (OC_STACK_OK != res)
2062             {
2063                 OIC_LOG_V(ERROR, TAG, "Internal error in PDMSetDeviceState : %d", res);
2064                 goto exit;
2065             }
2066         }
2067         else if (PDM_DEVICE_INIT == pdmState)
2068         {
2069             OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
2070             OICFree(strUuid);
2071             res = OC_STACK_DUPLICATE_REQUEST;
2072             goto exit;
2073         }
2074         else
2075         {
2076             OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
2077             OICFree(strUuid);
2078             res = OC_STACK_ERROR;
2079             goto exit;
2080         }
2081     }
2082     else
2083     {
2084         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
2085         if (OC_STACK_OK != res)
2086         {
2087             OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res);
2088             goto exit;
2089         }
2090     }
2091
2092 exit:
2093     OICFree(strUuid);
2094     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2095     return res;
2096 }
2097
2098 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
2099 {
2100     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
2101     OCStackResult res = OC_STACK_INVALID_PARAM;
2102     OicUuid_t emptyOwner = {.id = {0} };
2103
2104     VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
2105     VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
2106
2107     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
2108     otmCtx->selectedDeviceInfo = selectedDevice;
2109
2110     //If devowneruuid of selectedDevice is not emtry, PostOwnerUuid does not triggered in DTLSHandshakeCB
2111     if (memcmp(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
2112     {
2113         OIC_LOG(DEBUG, TAG, "Set devowneruuid of selectedDevice to empty for OwnershipTransfer");
2114         memcpy(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t));
2115     }
2116
2117     //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
2118     res = SetupPDM(selectedDevice);
2119     if(OC_STACK_OK != res)
2120     {
2121         OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
2122         SetResult(otmCtx, res);
2123         return res;
2124     }
2125
2126     //Select the OxM to performing ownership transfer
2127     res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
2128                                           selectedDevice->doxm->oxmLen,
2129                                           &selectedDevice->doxm->oxmSel,
2130                                           SUPER_OWNER);
2131     if(OC_STACK_OK != res)
2132     {
2133         OIC_LOG_V(ERROR, TAG, "Failed to select the provisioning method : %d", res);
2134         SetResult(otmCtx, res);
2135         return res;
2136     }
2137     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
2138
2139     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
2140     if(OC_STACK_OK != res)
2141     {
2142         OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
2143         return res;
2144     }
2145
2146     //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
2147     res = PostOwnerTransferModeToResource(otmCtx);
2148     if(OC_STACK_OK != res)
2149     {
2150         OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
2151         SetResult(otmCtx, res);
2152         return res;
2153     }
2154
2155 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2156     //Register TLS event handler to catch the tls event while handshake
2157     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2158     {
2159         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2160     }
2161 #endif // __WITH_DTLS__ or __WITH_TLS__
2162     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2163
2164 exit:
2165     return res;
2166 }
2167
2168 static OCStackResult StartCustomOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice,const OicSecOxm_t method)
2169 {
2170     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
2171     OCStackResult res = OC_STACK_INVALID_PARAM;
2172
2173     VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
2174     VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
2175
2176     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
2177     otmCtx->selectedDeviceInfo = selectedDevice;
2178
2179     //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
2180     res = SetupPDM(selectedDevice);
2181     if(OC_STACK_OK != res)
2182     {
2183         OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
2184         SetResult(otmCtx, res);
2185         return res;
2186     }
2187
2188     //Select the OxM to performing ownership transfer
2189     selectedDevice->doxm->oxmSel = method;
2190     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
2191
2192     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
2193     if(OC_STACK_OK != res)
2194     {
2195         OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
2196         return res;
2197     }
2198
2199 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2200     //Register TLS event handler, to catch the TLS handshake event
2201     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2202     {
2203         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2204     }
2205 #endif // __WITH_DTLS__ or __WITH_TLS__
2206
2207     //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
2208     res = PostOwnerTransferModeToResource(otmCtx);
2209     if(OC_STACK_OK != res)
2210     {
2211         OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
2212         SetResult(otmCtx, res);
2213         return res;
2214     }
2215
2216     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2217
2218 exit:
2219     return res;
2220 }
2221
2222 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
2223 {
2224     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
2225
2226     if(!data)
2227     {
2228         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
2229         return OC_STACK_INVALID_PARAM;
2230     }
2231     if(oxmType >= OIC_OXM_COUNT)
2232     {
2233         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
2234         return OC_STACK_INVALID_PARAM;
2235     }
2236
2237     // TODO: Remove this API, Please see the jira ticket IOT-1484
2238
2239     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
2240
2241     return OC_STACK_OK;
2242 }
2243
2244 OCStackResult OTMDoCustomOwnershipTransfer(void* ctx,
2245                                      OCProvisionDev_t *selectedDevice,
2246                                      OCProvisionResultCB resultCallback,
2247                                      const OicSecOxm_t method)
2248 {
2249     OIC_LOG(DEBUG, TAG, "IN OTMDoCustomOwnershipTransfer");
2250
2251     if (NULL == selectedDevice)
2252     {
2253         return OC_STACK_INVALID_PARAM;
2254     }
2255     if (NULL == resultCallback)
2256     {
2257         return OC_STACK_INVALID_CALLBACK;
2258     }
2259
2260     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2261     if(!otmCtx)
2262     {
2263         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2264         return OC_STACK_NO_MEMORY;
2265     }
2266
2267     otmCtx->ctxResultCallback = resultCallback;
2268     otmCtx->ctxHasError = false;
2269     otmCtx->userCtx = ctx;
2270
2271     //Setting number of selected device.
2272     otmCtx->ctxResultArraySize = 1;
2273
2274     otmCtx->ctxResultArray =
2275         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2276     if(NULL == otmCtx->ctxResultArray)
2277     {
2278         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2279         OICFree(otmCtx);
2280         return OC_STACK_NO_MEMORY;
2281     }
2282
2283     //Fill the device UUID for result array.
2284         memcpy(otmCtx->ctxResultArray[0].deviceId.id,
2285                selectedDevice->doxm->deviceID.id,
2286                UUID_LENGTH);
2287         otmCtx->ctxResultArray[0].res = OC_STACK_CONTINUE;
2288
2289     OCStackResult res = StartCustomOwnershipTransfer(otmCtx, selectedDevice, method);
2290
2291     OIC_LOG(DEBUG, TAG, "OUT OTMDoCustomOwnershipTransfer");
2292
2293     return res;
2294 }
2295
2296 /**
2297  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
2298  */
2299 OCStackResult OTMDoOwnershipTransfer(void* ctx,
2300                                      OCProvisionDev_t *selectedDevicelist,
2301                                      OCProvisionResultCB resultCallback)
2302 {
2303     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
2304
2305     if (NULL == selectedDevicelist)
2306     {
2307         return OC_STACK_INVALID_PARAM;
2308     }
2309     if (NULL == resultCallback)
2310     {
2311         return OC_STACK_INVALID_CALLBACK;
2312     }
2313
2314     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2315     if(!otmCtx)
2316     {
2317         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2318         return OC_STACK_NO_MEMORY;
2319     }
2320     otmCtx->ctxResultCallback = resultCallback;
2321     otmCtx->ctxHasError = false;
2322     otmCtx->userCtx = ctx;
2323     OCProvisionDev_t* pCurDev = selectedDevicelist;
2324
2325     //Counting number of selected devices.
2326     otmCtx->ctxResultArraySize = 0;
2327     while(NULL != pCurDev)
2328     {
2329         otmCtx->ctxResultArraySize++;
2330         pCurDev = pCurDev->next;
2331     }
2332
2333     otmCtx->ctxResultArray =
2334         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2335     if(NULL == otmCtx->ctxResultArray)
2336     {
2337         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2338         OICFree(otmCtx);
2339         return OC_STACK_NO_MEMORY;
2340     }
2341     pCurDev = selectedDevicelist;
2342
2343     //Fill the device UUID for result array.
2344     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
2345     {
2346         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
2347                pCurDev->doxm->deviceID.id,
2348                UUID_LENGTH);
2349         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
2350         pCurDev = pCurDev->next;
2351     }
2352
2353     OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist);
2354
2355     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
2356
2357     return res;
2358 }
2359
2360 OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
2361 {
2362     OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
2363               __func__, oxm, (allowStatus ? "true" : "false"));
2364
2365 #ifdef MULTIPLE_OWNER
2366     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
2367 #else
2368     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
2369 #endif
2370     {
2371         return OC_STACK_INVALID_PARAM;
2372     }
2373
2374     OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
2375     if(OXM_IDX_COUNT <= oxmIdx)
2376     {
2377         OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
2378         return OC_STACK_ERROR;
2379     }
2380     g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
2381
2382     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2383
2384     return OC_STACK_OK;
2385 }
2386
2387 OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
2388 {
2389     OIC_LOG(INFO, TAG, "IN PostProvisioningStatus");
2390
2391     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2392     {
2393         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2394         return OC_STACK_INVALID_PARAM;
2395     }
2396
2397     //Change the TAKE_OWNER bit of CM to 0.
2398     otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
2399
2400     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2401     if (!secPayload)
2402     {
2403         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2404         return OC_STACK_NO_MEMORY;
2405     }
2406     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2407     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2408             &secPayload->securityData, &secPayload->payloadSize, true))
2409     {
2410         OCPayloadDestroy((OCPayload *)secPayload);
2411         return OC_STACK_INVALID_JSON;
2412     }
2413     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2414     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2415
2416     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2417     if(!PMGenerateQuery(true,
2418                         otmCtx->selectedDeviceInfo->endpoint.addr,
2419                         otmCtx->selectedDeviceInfo->securePort,
2420                         otmCtx->selectedDeviceInfo->connType,
2421                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2422     {
2423         OIC_LOG(ERROR, TAG, "PostProvisioningStatus : Failed to generate query");
2424         return OC_STACK_ERROR;
2425     }
2426     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2427
2428     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2429     cbData.cb = &ProvisioningStatusHandler;
2430     cbData.context = (void*)otmCtx;
2431     cbData.cd = NULL;
2432     OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2433             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2434     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2435     if (ret != OC_STACK_OK)
2436     {
2437         OIC_LOG(ERROR, TAG, "OCStack resource error");
2438     }
2439
2440     OIC_LOG(INFO, TAG, "OUT PostProvisioningStatus");
2441
2442     return ret;
2443 }
2444
2445 OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
2446 {
2447     OIC_LOG(INFO, TAG, "IN PostNormalOperationStatus");
2448
2449     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2450     {
2451         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2452         return OC_STACK_INVALID_PARAM;
2453     }
2454
2455     //Set isop to true.
2456     otmCtx->selectedDeviceInfo->pstat->isOp = true;
2457
2458     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2459     if (!secPayload)
2460     {
2461         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2462         return OC_STACK_NO_MEMORY;
2463     }
2464     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2465     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2466             &secPayload->securityData, &secPayload->payloadSize, true))
2467     {
2468         OCPayloadDestroy((OCPayload *)secPayload);
2469         return OC_STACK_INVALID_JSON;
2470     }
2471     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2472     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2473
2474     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2475     if(!PMGenerateQuery(true,
2476                         otmCtx->selectedDeviceInfo->endpoint.addr,
2477                         otmCtx->selectedDeviceInfo->securePort,
2478                         otmCtx->selectedDeviceInfo->connType,
2479                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2480     {
2481         OIC_LOG(ERROR, TAG, "PostNormalOperationStatus : Failed to generate query");
2482         return OC_STACK_ERROR;
2483     }
2484     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2485
2486     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2487     cbData.cb = &ReadyForNomalStatusHandler;
2488     cbData.context = (void*)otmCtx;
2489     cbData.cd = NULL;
2490     OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2491             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2492     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2493     if (ret != OC_STACK_OK)
2494     {
2495         OIC_LOG(ERROR, TAG, "OCStack resource error");
2496     }
2497
2498     OIC_LOG(INFO, TAG, "OUT PostNormalOperationStatus");
2499
2500     return ret;
2501 }
2502
2503 OCStackResult ConfigSelfOwnership(void)
2504 {
2505     OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership");
2506
2507     bool isDeviceOwned = true;
2508     if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned))
2509     {
2510         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state");
2511         return OC_STACK_ERROR;
2512     }
2513     if( (true == isDeviceOwned) ||(true == GetPstatIsop()) )
2514     {
2515         OIC_LOG(ERROR, TAG, "The state of device is not Ready for Ownership transfer.");
2516         return OC_STACK_ERROR;
2517     }
2518     OicUuid_t deviceID = {.id={0}};
2519     if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2520     {
2521         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2522         return OC_STACK_ERROR;
2523     }
2524
2525     OCStackResult ret = OC_STACK_OK;
2526     //Update the pstat resource as Normal Operation.
2527     ret = SetPstatSelfOwnership(&deviceID);
2528     if(OC_STACK_OK != ret)
2529     {
2530         OIC_LOG (ERROR, TAG, "Unable to update pstat resource as Normal Operation");
2531         goto exit;
2532     }
2533     //Update the doxm resource as Normal Operation.
2534     ret = SetDoxmSelfOwnership(&deviceID);
2535     if(OC_STACK_OK != ret)
2536     {
2537         OIC_LOG (ERROR, TAG, "Unable to update doxm resource as Normal Operation");
2538         goto exit;
2539     }
2540     //Update default ACE of security resource to prevent anonymous user access.
2541     ret = UpdateDefaultSecProvACE();
2542     if(OC_STACK_OK != ret)
2543     {
2544         OIC_LOG (ERROR, TAG, "Unable to update default ace in ConfigSelfOwnership");
2545         goto exit;
2546     }
2547     //Update the acl resource owner as owner device.
2548     ret = SetAclRownerId(&deviceID);
2549     if(OC_STACK_OK != ret)
2550     {
2551         OIC_LOG (ERROR, TAG, "Unable to update acl resource in ConfigSelfOwnership");
2552         goto exit;
2553     }
2554     //Update the cred resource owner as owner device.
2555     ret = SetCredRownerId(&deviceID);
2556     if(OC_STACK_OK != ret)
2557     {
2558         // Cred resouce may be empty in Ready for Ownership transfer state.
2559         if (OC_STACK_NO_RESOURCE == ret)
2560         {
2561             OIC_LOG (INFO, TAG, "Cred resource is empty");
2562             ret = OC_STACK_OK;
2563             goto exit;
2564         }
2565         OIC_LOG (ERROR, TAG, "Unable to update cred resource in ConfigSelfOwnership");
2566     }
2567
2568 exit:
2569     if(OC_STACK_OK != ret)
2570     {
2571         /*
2572          * If some error is occured while configure self-ownership,
2573          * ownership related resource should be revert back to initial status.
2574         */
2575         ResetSecureResourceInPS();
2576     }
2577
2578     return ret;
2579 }
2580
2581
2582 void OTMTerminate()
2583 {
2584     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2585     DeleteOTMContextList();
2586
2587 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2588     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(NULL))
2589     {
2590         OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback.");
2591     }
2592 #endif // __WITH_DTLS__ or __WITH_TLS__
2593
2594     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2595 }