c0d94f88c853a4c76935628897e7eba61477843a
[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 && otmCtx->selectedDeviceInfo)
1148         {
1149             //Close the temporal secure session to verify the owner credential
1150             CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
1151             endpoint->port = otmCtx->selectedDeviceInfo->securePort;
1152             CAResult_t caResult = CA_STATUS_OK;
1153             caResult = CAcloseSslConnection(endpoint);
1154
1155             if(CA_STATUS_OK != caResult)
1156             {
1157                 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
1158                 SetResult(otmCtx, caResult);
1159                 return OC_STACK_DELETE_TRANSACTION;
1160             }
1161
1162             /**
1163                 * If we select NULL cipher,
1164                 * client will select appropriate cipher suite according to server's cipher-suite list.
1165                 */
1166                 // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
1167             caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
1168             if(CA_STATUS_OK != caResult)
1169             {
1170                 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
1171                 SetResult(otmCtx, caResult);
1172                 return OC_STACK_DELETE_TRANSACTION;
1173             }
1174
1175             /**
1176                 * in case of random PIN based OxM,
1177                 * revert get_psk_info callback of tinyDTLS to use owner credential.
1178                 */
1179             if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1180             {
1181                 OicUuid_t emptyUuid = { .id={0}};
1182                 SetUuidForPinBasedOxm(&emptyUuid);
1183
1184                 caResult = CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
1185
1186                 if(CA_STATUS_OK != caResult)
1187                 {
1188                     OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1189                     SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
1190                     return OC_STACK_DELETE_TRANSACTION;
1191                 }
1192             }
1193 #ifdef __WITH_TLS__
1194             otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
1195 #endif
1196             res = PostOwnerAcl(otmCtx);
1197             if(OC_STACK_OK != res)
1198             {
1199                 OIC_LOG(ERROR, TAG, "Failed to update owner ACL to new device");
1200                 SetResult(otmCtx, res);
1201                 return OC_STACK_DELETE_TRANSACTION;
1202             }
1203         }
1204     }
1205     else
1206     {
1207         res = clientResponse->result;
1208         OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
1209         SetResult(otmCtx, res);
1210     }
1211
1212     OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
1213
1214 exit:
1215     return  OC_STACK_DELETE_TRANSACTION;
1216 }
1217
1218 /**
1219  * Response handler for update owner ACL request.
1220  *
1221  * @param[in] ctx             ctx value passed to callback from calling function.
1222  * @param[in] UNUSED          handle to an invocation
1223  * @param[in] clientResponse  Response from queries to remote servers.
1224  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1225  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1226  */
1227 static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle UNUSED,
1228                                 OCClientResponse *clientResponse)
1229 {
1230     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1231     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1232
1233     OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler");
1234     (void)UNUSED;
1235     OCStackResult res = OC_STACK_OK;
1236     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1237     otmCtx->ocDoHandle = NULL;
1238
1239     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1240     {
1241         if(otmCtx && otmCtx->selectedDeviceInfo)
1242         {
1243             //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }]
1244             res = PostOwnershipInformation(otmCtx);
1245             if(OC_STACK_OK != res)
1246             {
1247                 OIC_LOG(ERROR, TAG, "Failed to update ownership information to new device");
1248                 SetResult(otmCtx, res);
1249             }
1250         }
1251     }
1252     else
1253     {
1254         res = clientResponse->result;
1255         OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res);
1256         SetResult(otmCtx, res);
1257     }
1258
1259     OIC_LOG(DEBUG, TAG, "OUT OwnerAclHandler");
1260
1261 exit:
1262     return  OC_STACK_DELETE_TRANSACTION;
1263 }
1264
1265
1266 /**
1267  * Response handler for update owner information request.
1268  *
1269  * @param[in] ctx             ctx value passed to callback from calling function.
1270  * @param[in] UNUSED          handle to an invocation
1271  * @param[in] clientResponse  Response from queries to remote servers.
1272  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1273  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1274  */
1275 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
1276                                 OCClientResponse *clientResponse)
1277 {
1278     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1279     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1280
1281     OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
1282     (void)UNUSED;
1283     OCStackResult res = OC_STACK_OK;
1284     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1285     otmCtx->ocDoHandle = NULL;
1286
1287     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1288     {
1289         if(otmCtx && otmCtx->selectedDeviceInfo)
1290         {
1291             OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
1292             OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
1293
1294             res = PostProvisioningStatus(otmCtx);
1295             if(OC_STACK_OK != res)
1296             {
1297                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1298                 SetResult(otmCtx, res);
1299             }
1300         }
1301     }
1302     else
1303     {
1304         res = clientResponse->result;
1305         OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
1306         SetResult(otmCtx, res);
1307     }
1308
1309     OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
1310
1311 exit:
1312     return  OC_STACK_DELETE_TRANSACTION;
1313 }
1314
1315 /**
1316  * Response handler of update provisioning status.
1317  *
1318  * @param[in] ctx             ctx value passed to callback from calling function.
1319  * @param[in] UNUSED          handle to an invocation
1320  * @param[in] clientResponse  Response from queries to remote servers.
1321  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1322  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1323  */
1324 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
1325                                                        OCClientResponse *clientResponse)
1326 {
1327     OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
1328
1329     VERIFY_NOT_NULL(TAG, clientResponse, ERROR);
1330     VERIFY_NOT_NULL(TAG, ctx, ERROR);
1331
1332     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1333     otmCtx->ocDoHandle = NULL;
1334     (void)UNUSED;
1335     OCStackResult res = OC_STACK_OK;
1336
1337     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1338     {
1339         if(otmCtx && otmCtx->selectedDeviceInfo)
1340         {
1341             OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
1342
1343             res = PostNormalOperationStatus(otmCtx);
1344             if(OC_STACK_OK != res)
1345             {
1346                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1347                 SetResult(otmCtx, res);
1348             }
1349         }
1350     }
1351     else
1352     {
1353         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1354                             clientResponse->result);
1355         SetResult(otmCtx, clientResponse->result);
1356     }
1357
1358 exit:
1359     OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
1360     return OC_STACK_DELETE_TRANSACTION;
1361 }
1362
1363 /**
1364  * Response handler of update provisioning status to Ready for Normal..
1365  *
1366  * @param[in] ctx             ctx value passed to callback from calling function.
1367  * @param[in] UNUSED          handle to an invocation
1368  * @param[in] clientResponse  Response from queries to remote servers.
1369  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1370  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1371  */
1372 static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
1373                                                        OCClientResponse *clientResponse)
1374 {
1375     OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
1376
1377     VERIFY_NOT_NULL(TAG, clientResponse, ERROR);
1378     VERIFY_NOT_NULL(TAG, ctx, ERROR);
1379
1380     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1381     otmCtx->ocDoHandle = NULL;
1382     (void)UNUSED;
1383
1384     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1385     {
1386         OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
1387         OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
1388                                               PDM_DEVICE_ACTIVE);
1389          if (OC_STACK_OK == res)
1390          {
1391                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1392                 SetResult(otmCtx, OC_STACK_OK);
1393                 return OC_STACK_DELETE_TRANSACTION;
1394          }
1395           else
1396          {
1397               OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1398          }
1399     }
1400     else
1401     {
1402         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1403                             clientResponse->result);
1404         SetResult(otmCtx, clientResponse->result);
1405     }
1406
1407 exit:
1408     OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
1409     return OC_STACK_DELETE_TRANSACTION;
1410 }
1411
1412 /**
1413  * Callback handler for GetAndVerifyDoxmResource.
1414  *
1415  * @param[in] ctx             ctx value passed to callback from calling function.
1416  * @param[in] UNUSED          handle to an invocation
1417  * @param[in] clientResponse  Response from queries to remote servers.
1418  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1419  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1420  */
1421 static OCStackApplicationResult GetAndVerifyDoxmHandler(void *ctx, OCDoHandle UNUSED,
1422                                                     OCClientResponse *clientResponse)
1423 {
1424     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1425
1426     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1427     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1428
1429     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1430     otmCtx->ocDoHandle = NULL;
1431     (void)UNUSED;
1432
1433     if (OC_STACK_OK != clientResponse->result)
1434     {
1435         OIC_LOG_V(WARNING, TAG, "%s : Client response is incorrect : %d",
1436             __func__, clientResponse->result);
1437         SetResult(otmCtx, clientResponse->result);
1438     }
1439     else
1440     {
1441         //Sanity checks.
1442         OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1443         if (NULL == deviceInfo)
1444         {
1445             OIC_LOG(INFO, TAG, "Selected device info is NULL");
1446             SetResult(otmCtx, OC_STACK_ERROR);
1447             return OC_STACK_DELETE_TRANSACTION;
1448         }
1449
1450         OCSecurityPayload *payload = (OCSecurityPayload*)clientResponse->payload;
1451         if (NULL == payload)
1452         {
1453             OIC_LOG(INFO, TAG, "Skipping Null payload");
1454             SetResult(otmCtx, OC_STACK_ERROR);
1455             return OC_STACK_DELETE_TRANSACTION;
1456         }
1457
1458         if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
1459         {
1460             OIC_LOG(INFO, TAG, "Unknown payload type");
1461             SetResult(otmCtx, OC_STACK_ERROR);
1462             return OC_STACK_DELETE_TRANSACTION;
1463         }
1464
1465         //Compare the doxm property values obtained over this secured session with those
1466         //values obtained before the DTLS handshake.
1467         OicSecDoxm_t *doxm = NULL;
1468         uint8_t *securityData = payload->securityData;
1469         size_t size = payload->payloadSize;
1470
1471         OCStackResult res = CBORPayloadToDoxm(securityData, size, &doxm);
1472         if ((NULL == doxm) || (OC_STACK_OK != res))
1473         {
1474             OIC_LOG(INFO, TAG, "Received malformed CBOR");
1475             SetResult(otmCtx, OC_STACK_ERROR);
1476             return OC_STACK_DELETE_TRANSACTION;
1477         }
1478
1479         bool equal = AreDoxmBinPropertyValuesEqual(doxm, deviceInfo->doxm);
1480         DeleteDoxmBinData(doxm);
1481         if (!equal)
1482         {
1483             SetResult(otmCtx, OC_STACK_ERROR);
1484             return OC_STACK_DELETE_TRANSACTION;
1485         }
1486
1487         //Send request : GET /oic/sec/pstat
1488         res = GetProvisioningStatusResource(otmCtx);
1489         if(OC_STACK_OK != res)
1490         {
1491             OIC_LOG(ERROR, TAG, "Failed to get pstat information");
1492             SetResult(otmCtx, res);
1493         }
1494     }
1495
1496     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1497 exit:
1498     return OC_STACK_DELETE_TRANSACTION;
1499 }
1500
1501 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx)
1502 {
1503     OIC_LOG(DEBUG, TAG, "IN PostOwnerCredential");
1504
1505     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1506     {
1507         OIC_LOG(ERROR, TAG, "Invalid parameters");
1508         return OC_STACK_INVALID_PARAM;
1509     }
1510
1511     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1512     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1513     assert(deviceInfo->connType & CT_FLAG_SECURE);
1514
1515     if(!PMGenerateQuery(true,
1516                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1517                         deviceInfo->connType,
1518                         query, sizeof(query), OIC_RSRC_CRED_URI))
1519     {
1520         OIC_LOG(ERROR, TAG, "PostOwnerCredential : Failed to generate query");
1521         return OC_STACK_ERROR;
1522     }
1523     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1524     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1525     if(!secPayload)
1526     {
1527         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1528         return OC_STACK_NO_MEMORY;
1529     }
1530
1531     //Generate owner credential for new device
1532     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1533     const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
1534     if(!ownerCredential)
1535     {
1536         OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
1537         return OC_STACK_NO_RESOURCE;
1538     }
1539
1540     OicUuid_t credSubjectId = {.id={0}};
1541     if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
1542     {
1543         OicSecCred_t newCredential;
1544         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
1545         newCredential.next = NULL;
1546
1547         //Set subject ID as PT's ID
1548         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
1549
1550         //Fill private data as empty string
1551         newCredential.privateData.data = (uint8_t*)"";
1552         newCredential.privateData.len = 0;
1553         newCredential.privateData.encoding = ownerCredential->privateData.encoding;
1554
1555         newCredential.publicData.data = NULL;
1556         newCredential.publicData.len = 0;
1557         newCredential.publicData.encoding = ownerCredential->publicData.encoding;
1558
1559         int secureFlag = 0;
1560         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
1561         if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
1562                                         &secPayload->payloadSize, secureFlag))
1563         {
1564             OICFree(secPayload);
1565             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1566             return OC_STACK_ERROR;
1567         }
1568         OIC_LOG(DEBUG, TAG, "Cred Payload:");
1569         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1570
1571         OCCallbackData cbData;
1572         cbData.cb = &OwnerCredentialHandler;
1573         cbData.context = (void *)otmCtx;
1574         cbData.cd = NULL;
1575         OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1576                                          &deviceInfo->endpoint, (OCPayload*)secPayload,
1577                                          deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1578         if (res != OC_STACK_OK)
1579         {
1580             OIC_LOG(ERROR, TAG, "OCStack resource error");
1581         }
1582     }
1583     else
1584     {
1585         OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
1586         return OC_STACK_NO_RESOURCE;
1587     }
1588
1589     OIC_LOG(DEBUG, TAG, "OUT PostOwnerCredential");
1590
1591     return OC_STACK_OK;
1592 }
1593
1594 static OicSecAcl_t* GenerateOwnerAcl(const OicUuid_t* owner)
1595 {
1596     OicSecAcl_t* ownerAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
1597     OicSecAce_t* ownerAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1598     OicSecRsrc_t* wildcardRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1599     if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1600     {
1601         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1602         goto error;
1603     }
1604     LL_APPEND(ownerAcl->aces, ownerAce);
1605     LL_APPEND(ownerAce->resources, wildcardRsrc);
1606
1607     //Set resource owner as PT
1608     memcpy(ownerAcl->rownerID.id, owner->id, sizeof(owner->id));
1609
1610     //PT has full permission.
1611     ownerAce->permission = PERMISSION_FULL_CONTROL;
1612
1613     //Set subject as PT's UUID
1614     memcpy(ownerAce->subjectuuid.id, owner->id, sizeof(owner->id));
1615
1616     wildcardRsrc->href = OICStrdup(WILDCARD_RESOURCE_URI);
1617     if(NULL == wildcardRsrc->href)
1618     {
1619         goto error;
1620     }
1621
1622     wildcardRsrc->interfaceLen = 1;
1623     wildcardRsrc->interfaces = (char**)OICMalloc(wildcardRsrc->interfaceLen * sizeof(char*));
1624     if(NULL == wildcardRsrc->interfaces)
1625     {
1626         goto error;
1627     }
1628     wildcardRsrc->interfaces[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1629     if(NULL == wildcardRsrc->interfaces[0])
1630     {
1631         goto error;
1632     }
1633
1634     wildcardRsrc->typeLen = 1;
1635     wildcardRsrc->types = (char**)OICMalloc(wildcardRsrc->typeLen * sizeof(char*));
1636     if(NULL == wildcardRsrc->types)
1637     {
1638         goto error;
1639     }
1640     wildcardRsrc->types[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1641     if(NULL == wildcardRsrc->types[0])
1642     {
1643         goto error;
1644     }
1645
1646     return ownerAcl;
1647
1648 error:
1649     //in case of memory allocation failed, each resource should be removed individually.
1650     if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1651     {
1652         OICFree(ownerAcl);
1653         OICFree(ownerAce);
1654         OICFree(wildcardRsrc);
1655     }
1656     else
1657     {
1658         DeleteACLList(ownerAcl);
1659     }
1660     return NULL;
1661 }
1662
1663 /**
1664  * Function to update the owner ACL to new device.
1665  *
1666  * @param[in]  otmCtx  Context value of ownership transfer.
1667  * @return  OC_STACK_OK on success
1668  */
1669 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx)
1670 {
1671     OCStackResult res = OC_STACK_ERROR;
1672
1673     OIC_LOG(DEBUG, TAG, "IN PostOwnerAcl");
1674
1675     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1676     {
1677         OIC_LOG(ERROR, TAG, "Invalid parameters");
1678         return OC_STACK_INVALID_PARAM;
1679     }
1680
1681     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1682     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1683     OicSecAcl_t* ownerAcl = NULL;
1684     assert(deviceInfo->connType & CT_FLAG_SECURE);
1685
1686     if(!PMGenerateQuery(true,
1687                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1688                         deviceInfo->connType,
1689                         query, sizeof(query), OIC_RSRC_ACL_URI))
1690     {
1691         OIC_LOG(ERROR, TAG, "Failed to generate query");
1692         return OC_STACK_ERROR;
1693     }
1694     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1695
1696     OicUuid_t ownerID;
1697     res = GetDoxmDeviceID(&ownerID);
1698     if(OC_STACK_OK != res)
1699     {
1700         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1701         return res;
1702     }
1703
1704     //Generate owner ACL for new device
1705     ownerAcl = GenerateOwnerAcl(&ownerID);
1706     if(NULL == ownerAcl)
1707     {
1708         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1709         return OC_STACK_NO_MEMORY;
1710     }
1711
1712     //Generate ACL payload
1713     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1714     if(!secPayload)
1715     {
1716         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1717         res = OC_STACK_NO_MEMORY;
1718         goto error;
1719     }
1720
1721     res = AclToCBORPayload(ownerAcl, &secPayload->securityData, &secPayload->payloadSize);
1722     if (OC_STACK_OK != res)
1723     {
1724         OICFree(secPayload);
1725         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1726         goto error;
1727     }
1728     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1729
1730     OIC_LOG(DEBUG, TAG, "Owner ACL Payload:");
1731     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1732
1733     //Send owner ACL to new device : POST /oic/sec/cred [ owner credential ]
1734     OCCallbackData cbData;
1735     cbData.cb = &OwnerAclHandler;
1736     cbData.context = (void *)otmCtx;
1737     cbData.cd = NULL;
1738     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1739                                      &deviceInfo->endpoint, (OCPayload*)secPayload,
1740                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1741     if (res != OC_STACK_OK)
1742     {
1743         OIC_LOG(ERROR, TAG, "OCStack resource error");
1744         goto error;
1745     }
1746
1747     OIC_LOG(DEBUG, TAG, "OUT PostOwnerAcl");
1748
1749 error:
1750     DeleteACLList(ownerAcl);
1751
1752     return OC_STACK_OK;
1753 }
1754
1755 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx)
1756 {
1757     OIC_LOG(DEBUG, TAG, "IN PostOwnerTransferModeToResource");
1758
1759     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1760     {
1761         OIC_LOG(ERROR, TAG, "Invalid parameters");
1762         return OC_STACK_INVALID_PARAM;
1763     }
1764
1765     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1766     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1767
1768     if(!PMGenerateQuery(false,
1769                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1770                         deviceInfo->connType,
1771                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1772     {
1773         OIC_LOG(ERROR, TAG, "PostOwnerTransferModeToResource : Failed to generate query");
1774         return OC_STACK_ERROR;
1775     }
1776     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1777
1778     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1779     if(!secPayload)
1780     {
1781         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1782         return OC_STACK_NO_MEMORY;
1783     }
1784
1785     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1786     OCStackResult res = otmCtx->otmCallback.createSelectOxmPayloadCB(otmCtx,
1787             &secPayload->securityData, &secPayload->payloadSize);
1788     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1789     {
1790         OCPayloadDestroy((OCPayload *)secPayload);
1791         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
1792         return OC_STACK_ERROR;
1793     }
1794
1795     OCCallbackData cbData;
1796     cbData.cb = &OwnerTransferModeHandler;
1797     cbData.context = (void *)otmCtx;
1798     cbData.cd = NULL;
1799     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1800                        &deviceInfo->endpoint, (OCPayload *)secPayload,
1801                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1802     if (res != OC_STACK_OK)
1803     {
1804         OIC_LOG(ERROR, TAG, "OCStack resource error");
1805     }
1806
1807     OIC_LOG(DEBUG, TAG, "OUT PostOwnerTransferModeToResource");
1808
1809     return res;
1810 }
1811
1812 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1813 {
1814     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1815
1816     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1817     {
1818         OIC_LOG(ERROR, TAG, "Invailed parameters");
1819         return OC_STACK_INVALID_PARAM;
1820     }
1821
1822     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1823     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1824     assert(deviceInfo->connType & CT_FLAG_SECURE);
1825
1826     if(!PMGenerateQuery(true,
1827                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1828                         deviceInfo->connType,
1829                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1830     {
1831         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1832         return OC_STACK_ERROR;
1833     }
1834     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1835
1836     OCCallbackData cbData;
1837     cbData.cb = &ListMethodsHandler;
1838     cbData.context = (void *)otmCtx;
1839     cbData.cd = NULL;
1840     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
1841                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1842     if (res != OC_STACK_OK)
1843     {
1844         OIC_LOG(ERROR, TAG, "OCStack resource error");
1845     }
1846
1847     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1848
1849     return res;
1850 }
1851
1852 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
1853 {
1854     OIC_LOG(DEBUG, TAG, "IN PostOwnerUuid");
1855
1856     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1857     {
1858         OIC_LOG(ERROR, TAG, "Invailed parameters");
1859         return OC_STACK_INVALID_PARAM;
1860     }
1861
1862     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1863     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1864     assert(deviceInfo->connType & CT_FLAG_SECURE);
1865
1866     if(!PMGenerateQuery(true,
1867                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1868                         deviceInfo->connType,
1869                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1870     {
1871         OIC_LOG(ERROR, TAG, "PostOwnerUuid : Failed to generate query");
1872         return OC_STACK_ERROR;
1873     }
1874     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1875
1876     //Post PT's uuid to new device
1877     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1878     if(!secPayload)
1879     {
1880         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1881         return OC_STACK_NO_MEMORY;
1882     }
1883     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1884     OCStackResult res = otmCtx->otmCallback.createOwnerTransferPayloadCB(
1885             otmCtx, &secPayload->securityData, &secPayload->payloadSize);
1886     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1887     {
1888         OCPayloadDestroy((OCPayload *)secPayload);
1889         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
1890         return OC_STACK_INVALID_PARAM;
1891     }
1892     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1893
1894     OCCallbackData cbData;
1895     cbData.cb = &OwnerUuidUpdateHandler;
1896     cbData.context = (void *)otmCtx;
1897     cbData.cd = NULL;
1898
1899     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1900             deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1901     if (res != OC_STACK_OK)
1902     {
1903         OIC_LOG(ERROR, TAG, "OCStack resource error");
1904     }
1905
1906     OIC_LOG(DEBUG, TAG, "OUT PostOwnerUuid");
1907
1908     return res;
1909 }
1910
1911 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
1912 {
1913     OIC_LOG(DEBUG, TAG, "IN PostOwnershipInformation");
1914
1915     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1916     {
1917         OIC_LOG(ERROR, TAG, "Invailed parameters");
1918         return OC_STACK_INVALID_PARAM;
1919     }
1920
1921     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1922     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1923     assert(deviceInfo->connType & CT_FLAG_SECURE);
1924
1925     if(!PMGenerateQuery(true,
1926                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1927                         deviceInfo->connType,
1928                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1929     {
1930         OIC_LOG(ERROR, TAG, "PostOwnershipInformation : Failed to generate query");
1931         return OC_STACK_ERROR;
1932     }
1933     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1934
1935     //OwnershipInformationHandler
1936     OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1937     if (!secPayload)
1938     {
1939         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1940         return OC_STACK_NO_MEMORY;
1941     }
1942
1943     otmCtx->selectedDeviceInfo->doxm->owned = true;
1944
1945     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1946     OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
1947             &secPayload->securityData, &secPayload->payloadSize, true);
1948     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1949     {
1950         OCPayloadDestroy((OCPayload *)secPayload);
1951         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1952         return OC_STACK_INVALID_PARAM;
1953     }
1954
1955     OCCallbackData cbData;
1956     cbData.cb = &OwnershipInformationHandler;
1957     cbData.context = (void *)otmCtx;
1958     cbData.cd = NULL;
1959
1960     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
1961                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1962     if (res != OC_STACK_OK)
1963     {
1964         OIC_LOG(ERROR, TAG, "OCStack resource error");
1965     }
1966
1967     OIC_LOG(DEBUG, TAG, "OUT PostOwnershipInformation");
1968
1969     return res;
1970 }
1971
1972 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
1973 {
1974     OIC_LOG(DEBUG, TAG, "IN PostUpdateOperationMode");
1975
1976     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1977     {
1978         return OC_STACK_INVALID_PARAM;
1979     }
1980
1981     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1982     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1983     assert(deviceInfo->connType & CT_FLAG_SECURE);
1984
1985     if(!PMGenerateQuery(true,
1986                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1987                         deviceInfo->connType,
1988                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1989     {
1990         OIC_LOG(ERROR, TAG, "PostUpdateOperationMode : Failed to generate query");
1991         return OC_STACK_ERROR;
1992     }
1993     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1994
1995     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1996     if(!secPayload)
1997     {
1998         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1999         return OC_STACK_NO_MEMORY;
2000     }
2001     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2002     OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
2003                                            &secPayload->payloadSize, true);
2004    if (OC_STACK_OK != res)
2005     {
2006         OCPayloadDestroy((OCPayload *)secPayload);
2007         OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
2008         return OC_STACK_INVALID_PARAM;
2009     }
2010
2011     OCCallbackData cbData;
2012     cbData.cb = &OperationModeUpdateHandler;
2013     cbData.context = (void *)otmCtx;
2014     cbData.cd = NULL;
2015     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
2016                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2017     if (res != OC_STACK_OK)
2018     {
2019         OIC_LOG(ERROR, TAG, "OCStack resource error");
2020     }
2021
2022     OIC_LOG(DEBUG, TAG, "OUT PostUpdateOperationMode");
2023
2024     return res;
2025 }
2026
2027 static OCStackResult GetAndVerifyDoxmResource(OTMContext_t* otmCtx)
2028 {
2029     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2030
2031     if(!otmCtx || !otmCtx->selectedDeviceInfo || !otmCtx->selectedDeviceInfo->doxm)
2032     {
2033         OIC_LOG(ERROR, TAG, "Invalid context");
2034         return OC_STACK_INVALID_PARAM;
2035     }
2036
2037     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2038     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2039     assert(deviceInfo->connType & CT_FLAG_SECURE);
2040
2041     if(!PMGenerateQuery(true,
2042                         deviceInfo->endpoint.addr, deviceInfo->securePort,
2043                         deviceInfo->connType,
2044                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2045     {
2046         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2047         return OC_STACK_ERROR;
2048     }
2049     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2050
2051     OCCallbackData cbData;
2052     cbData.cb = &GetAndVerifyDoxmHandler;
2053     cbData.context = (void *)otmCtx;
2054     cbData.cd = NULL;
2055     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
2056                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2057     if (res != OC_STACK_OK)
2058     {
2059         OIC_LOG(ERROR, TAG, "OCStack resource error");
2060     }
2061
2062     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2063
2064     return res;
2065 }
2066
2067 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
2068 {
2069     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
2070     OCStackResult res = OC_STACK_INVALID_PARAM;
2071
2072     VERIFY_NOT_NULL(TAG, selectedDevice, ERROR);
2073     VERIFY_NOT_NULL(TAG, selectedDevice->doxm, ERROR);
2074
2075     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
2076     otmCtx->selectedDeviceInfo = selectedDevice;
2077
2078     //Checking duplication of Device ID.
2079     bool isDuplicate = true;
2080     res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
2081     if (OC_STACK_OK != res)
2082     {
2083         OIC_LOG(ERROR, TAG, "Internal error in PDMIsDuplicateDevice");
2084         return res;
2085     }
2086     if (isDuplicate)
2087     {
2088         PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
2089         res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &state);
2090         if(OC_STACK_OK != res)
2091         {
2092             OIC_LOG(ERROR, TAG, "Internal error in PDMGetDeviceState");
2093             SetResult(otmCtx, res);
2094             return res;
2095         }
2096
2097         char* strUuid = NULL;
2098         res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
2099         if(OC_STACK_OK != res)
2100         {
2101             OIC_LOG(ERROR, TAG, "Failed to convert UUID to str");
2102             SetResult(otmCtx, res);
2103             return res;
2104         }
2105
2106         if(PDM_DEVICE_STALE == state)
2107         {
2108             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
2109                                "device status will revert back to initial status.");
2110             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
2111             if(OC_STACK_OK != res)
2112             {
2113                 OIC_LOG(ERROR, TAG, "Internal error in PDMSetDeviceState");
2114                 OICFree(strUuid);
2115                 SetResult(otmCtx, res);
2116                 return res;
2117             }
2118         }
2119         else if(PDM_DEVICE_INIT == state)
2120         {
2121             OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
2122             OICFree(strUuid);
2123             SetResult(otmCtx, OC_STACK_DUPLICATE_REQUEST);
2124             return OC_STACK_OK;
2125         }
2126         else
2127         {
2128             OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
2129             OICFree(strUuid);
2130             SetResult(otmCtx, OC_STACK_ERROR);
2131             return OC_STACK_ERROR;
2132         }
2133     }
2134     else
2135     {
2136         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
2137         if(OC_STACK_OK != res)
2138         {
2139             OIC_LOG(ERROR, TAG, "Internal error in PDMAddDevice");
2140             SetResult(otmCtx, res);
2141             return res;
2142         }
2143     }
2144
2145     //Select the OxM to performing ownership transfer
2146     res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
2147                                           selectedDevice->doxm->oxmLen,
2148                                           &selectedDevice->doxm->oxmSel,
2149                                           SUPER_OWNER);
2150     if(OC_STACK_OK != res)
2151     {
2152         OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
2153         SetResult(otmCtx, res);
2154         return res;
2155     }
2156     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
2157
2158     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
2159     if(OC_STACK_OK != res)
2160     {
2161         OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
2162         return res;
2163     }
2164
2165 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2166     //Register TLS event handler, to catch the TLS handshake event
2167     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2168     {
2169         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2170     }
2171 #endif // __WITH_DTLS__ or __WITH_TLS__
2172
2173     //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
2174     res = PostOwnerTransferModeToResource(otmCtx);
2175     if(OC_STACK_OK != res)
2176     {
2177         OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
2178         SetResult(otmCtx, res);
2179         return res;
2180     }
2181
2182     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2183
2184 exit:
2185     return res;
2186 }
2187
2188 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
2189 {
2190     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
2191
2192     if(!data)
2193     {
2194         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
2195         return OC_STACK_INVALID_PARAM;
2196     }
2197     if(oxmType >= OIC_OXM_COUNT)
2198     {
2199         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
2200         return OC_STACK_INVALID_PARAM;
2201     }
2202
2203     // TODO: Remove this API, Please see the jira ticket IOT-1484
2204
2205     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
2206
2207     return OC_STACK_OK;
2208 }
2209
2210 /**
2211  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
2212  */
2213 OCStackResult OTMDoOwnershipTransfer(void* ctx,
2214                                      OCProvisionDev_t *selectedDevicelist,
2215                                      OCProvisionResultCB resultCallback)
2216 {
2217     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
2218
2219     if (NULL == selectedDevicelist)
2220     {
2221         return OC_STACK_INVALID_PARAM;
2222     }
2223     if (NULL == resultCallback)
2224     {
2225         return OC_STACK_INVALID_CALLBACK;
2226     }
2227
2228     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2229     if(!otmCtx)
2230     {
2231         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2232         return OC_STACK_NO_MEMORY;
2233     }
2234     otmCtx->ctxResultCallback = resultCallback;
2235     otmCtx->ctxHasError = false;
2236     otmCtx->userCtx = ctx;
2237     OCProvisionDev_t* pCurDev = selectedDevicelist;
2238
2239     //Counting number of selected devices.
2240     otmCtx->ctxResultArraySize = 0;
2241     while(NULL != pCurDev)
2242     {
2243         otmCtx->ctxResultArraySize++;
2244         pCurDev = pCurDev->next;
2245     }
2246
2247     otmCtx->ctxResultArray =
2248         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2249     if(NULL == otmCtx->ctxResultArray)
2250     {
2251         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2252         OICFree(otmCtx);
2253         return OC_STACK_NO_MEMORY;
2254     }
2255     pCurDev = selectedDevicelist;
2256
2257     //Fill the device UUID for result array.
2258     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
2259     {
2260         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
2261                pCurDev->doxm->deviceID.id,
2262                UUID_LENGTH);
2263         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
2264         pCurDev = pCurDev->next;
2265     }
2266
2267     OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist);
2268
2269     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
2270
2271     return res;
2272 }
2273
2274 OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
2275 {
2276     OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
2277               __func__, oxm, (allowStatus ? "true" : "false"));
2278
2279 #ifdef MULTIPLE_OWNER
2280     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
2281 #else
2282     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
2283 #endif
2284     {
2285         return OC_STACK_INVALID_PARAM;
2286     }
2287
2288     OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
2289     if(OXM_IDX_COUNT <= oxmIdx)
2290     {
2291         OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
2292         return OC_STACK_ERROR;
2293     }
2294     g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
2295
2296     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2297
2298     return OC_STACK_OK;
2299 }
2300
2301 OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
2302 {
2303     OIC_LOG(INFO, TAG, "IN PostProvisioningStatus");
2304
2305     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2306     {
2307         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2308         return OC_STACK_INVALID_PARAM;
2309     }
2310
2311     //Change the TAKE_OWNER bit of CM to 0.
2312     otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
2313
2314     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2315     if (!secPayload)
2316     {
2317         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2318         return OC_STACK_NO_MEMORY;
2319     }
2320     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2321     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2322             &secPayload->securityData, &secPayload->payloadSize, true))
2323     {
2324         OCPayloadDestroy((OCPayload *)secPayload);
2325         return OC_STACK_INVALID_JSON;
2326     }
2327     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2328     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2329
2330     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2331     assert(otmCtx->selectedDeviceInfo->connType & CT_FLAG_SECURE);
2332
2333     if(!PMGenerateQuery(true,
2334                         otmCtx->selectedDeviceInfo->endpoint.addr,
2335                         otmCtx->selectedDeviceInfo->securePort,
2336                         otmCtx->selectedDeviceInfo->connType,
2337                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2338     {
2339         OIC_LOG(ERROR, TAG, "PostProvisioningStatus : Failed to generate query");
2340         return OC_STACK_ERROR;
2341     }
2342     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2343
2344     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2345     cbData.cb = &ProvisioningStatusHandler;
2346     cbData.context = (void*)otmCtx;
2347     cbData.cd = NULL;
2348     OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2349             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2350     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2351     if (ret != OC_STACK_OK)
2352     {
2353         OIC_LOG(ERROR, TAG, "OCStack resource error");
2354     }
2355
2356     OIC_LOG(INFO, TAG, "OUT PostProvisioningStatus");
2357
2358     return ret;
2359 }
2360
2361 OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
2362 {
2363     OIC_LOG(INFO, TAG, "IN PostNormalOperationStatus");
2364
2365     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2366     {
2367         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2368         return OC_STACK_INVALID_PARAM;
2369     }
2370
2371     //Set isop to true.
2372     otmCtx->selectedDeviceInfo->pstat->isOp = true;
2373
2374     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2375     if (!secPayload)
2376     {
2377         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2378         return OC_STACK_NO_MEMORY;
2379     }
2380     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2381     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2382             &secPayload->securityData, &secPayload->payloadSize, true))
2383     {
2384         OCPayloadDestroy((OCPayload *)secPayload);
2385         return OC_STACK_INVALID_JSON;
2386     }
2387     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2388     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2389
2390     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2391     assert(otmCtx->selectedDeviceInfo->connType & CT_FLAG_SECURE);
2392
2393     if(!PMGenerateQuery(true,
2394                         otmCtx->selectedDeviceInfo->endpoint.addr,
2395                         otmCtx->selectedDeviceInfo->securePort,
2396                         otmCtx->selectedDeviceInfo->connType,
2397                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2398     {
2399         OIC_LOG(ERROR, TAG, "PostNormalOperationStatus : Failed to generate query");
2400         return OC_STACK_ERROR;
2401     }
2402     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2403
2404     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2405     cbData.cb = &ReadyForNomalStatusHandler;
2406     cbData.context = (void*)otmCtx;
2407     cbData.cd = NULL;
2408     OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2409             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2410     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2411     if (ret != OC_STACK_OK)
2412     {
2413         OIC_LOG(ERROR, TAG, "OCStack resource error");
2414     }
2415
2416     OIC_LOG(INFO, TAG, "OUT PostNormalOperationStatus");
2417
2418     return ret;
2419 }
2420
2421 OCStackResult ConfigSelfOwnership(void)
2422 {
2423     OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership");
2424
2425     bool isDeviceOwned = true;
2426     if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned))
2427     {
2428         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state");
2429         return OC_STACK_ERROR;
2430     }
2431     if( (true == isDeviceOwned) ||(true == GetPstatIsop()) )
2432     {
2433         OIC_LOG(ERROR, TAG, "The state of device is not Ready for Ownership transfer.");
2434         return OC_STACK_ERROR;
2435     }
2436     OicUuid_t deviceID = {.id={0}};
2437     if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2438     {
2439         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2440         return OC_STACK_ERROR;
2441     }
2442
2443     OCStackResult ret = OC_STACK_OK;
2444     //Update the pstat resource as Normal Operation.
2445     ret = SetPstatSelfOwnership(&deviceID);
2446     if(OC_STACK_OK != ret)
2447     {
2448         OIC_LOG (ERROR, TAG, "Unable to update pstat resource as Normal Operation");
2449         goto exit;
2450     }
2451     //Update the doxm resource as Normal Operation.
2452     ret = SetDoxmSelfOwnership(&deviceID);
2453     if(OC_STACK_OK != ret)
2454     {
2455         OIC_LOG (ERROR, TAG, "Unable to update doxm resource as Normal Operation");
2456         goto exit;
2457     }
2458     //Update default ACE of security resource to prevent anonymous user access.
2459     ret = UpdateDefaultSecProvACE();
2460     if(OC_STACK_OK != ret)
2461     {
2462         OIC_LOG (ERROR, TAG, "Unable to update default ace in ConfigSelfOwnership");
2463         goto exit;
2464     }
2465     //Update the acl resource owner as owner device.
2466     ret = SetAclRownerId(&deviceID);
2467     if(OC_STACK_OK != ret)
2468     {
2469         OIC_LOG (ERROR, TAG, "Unable to update acl resource in ConfigSelfOwnership");
2470         goto exit;
2471     }
2472     //Update the cred resource owner as owner device.
2473     ret = SetCredRownerId(&deviceID);
2474     if(OC_STACK_OK != ret)
2475     {
2476         // Cred resouce may be empty in Ready for Ownership transfer state.
2477         if (OC_STACK_NO_RESOURCE == ret)
2478         {
2479             OIC_LOG (INFO, TAG, "Cred resource is empty");
2480             ret = OC_STACK_OK;
2481             goto exit;
2482         }
2483         OIC_LOG (ERROR, TAG, "Unable to update cred resource in ConfigSelfOwnership");
2484     }
2485
2486 exit:
2487     if(OC_STACK_OK != ret)
2488     {
2489         /*
2490          * If some error is occured while configure self-ownership,
2491          * ownership related resource should be revert back to initial status.
2492         */
2493         ResetSecureResourceInPS();
2494     }
2495
2496     return ret;
2497 }