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