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