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