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