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