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