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