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