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