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