[IOT-1045] Remove the CborEncoder initialization in security modules to remove compil...
[platform/upstream/iotivity.git] / resource / csdk / security / src / dpairingresource.c
1 /* *****************************************************************
2  *
3  * Copyright 2016 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 #include <stdlib.h>
22 #include <string.h>
23 #include "ocstack.h"
24 #include "logger.h"
25 #include "oic_malloc.h"
26 #include "oic_string.h"
27 #include "cJSON.h"
28 #include "base64.h"
29 #include "resourcemanager.h"
30 #include "dpairingresource.h"
31 #include "psinterface.h"
32 #include "utlist.h"
33 #include "srmresourcestrings.h"
34 #include "cainterface.h"
35 #include "doxmresource.h"
36 #include "pconfresource.h"
37 #include "credresource.h"
38 #include "aclresource.h"
39 #include "srmutility.h"
40 #include "ocserverrequest.h"
41 #include "ocpayloadcbor.h"
42 #include "ocpayload.h"
43 #include "payload_logging.h"
44 #include <stdlib.h>
45 #ifdef WITH_ARDUINO
46 #include <string.h>
47 #else
48 #include <strings.h>
49 #endif
50
51 #ifdef __WITH_DTLS__
52 #include "global.h"
53 #endif
54
55 #define TAG  "SRM-DPAIRING"
56
57 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
58  * The value of payload size is increased until reaching belox max cbor size. */
59 static const uint16_t CBOR_SIZE = 1024;
60
61 /** Max cbor size payload. */
62 static const uint16_t CBOR_MAX_SIZE = 4400;
63
64 /** DOXM Map size - Number of mandatory items. */
65 static const uint8_t DPAIR_MAP_SIZE = 3;
66
67 static OicSecDpairing_t     *gDpair = NULL;
68 static OCResourceHandle   gDpairHandle = NULL;
69 static OicSecDpairing_t      gDefaultDpair =
70 {
71     PRM_NOT_ALLOWED,       /* OicSecPrm_t spm */
72     {.id = {0}},                   /* OicUuid_t pdeviceID */
73     {.id = {0}},                   /* OicUuid_t rowner */
74 };
75
76 void DeleteDpairingBinData(OicSecDpairing_t* dpair)
77 {
78     if (dpair)
79     {
80         //Clean dpairing itself
81         OICFree(dpair);
82     }
83 }
84
85 /**
86  * Get the default value.
87  * @retval  the gDefaultDpair pointer;
88  */
89 static OicSecDpairing_t* GetDpairingDefault()
90 {
91     OIC_LOG (DEBUG, TAG, "GetDpairingDefault");
92
93     return &gDefaultDpair;
94 }
95
96 /**
97  * This method is used by SRM to retrieve Dpairing resource data..
98  */
99 void SetDpairingResourceOwner(OicUuid_t *rowner)
100 {
101     OIC_LOG (DEBUG, TAG, "SetDpairingResourceOwner");
102     if (gDpair)
103     {
104         memcpy(&gDpair->rownerID, rowner, sizeof(OicUuid_t));
105     }
106 }
107
108 #ifdef __WITH_DTLS__
109 /**
110  * Function to save PairingPSK.
111  *
112  * @param[in] endpoint   current endpoint.
113  * @param[in] peerDevID   peer device indentitiy.
114  * @param[in] isPairingServer   indicate if it generates PairingPSK for server or client.
115  *
116  * @return  OC_STACK_OK on success
117  */
118 OCStackResult SavePairingPSK(OCDevAddr *endpoint,
119             OicUuid_t *peerDevID, OicUuid_t *owner, bool isPairingServer)
120 {
121     OIC_LOG(DEBUG, TAG, "IN SavePairingPSK");
122
123     if(NULL == endpoint || NULL == peerDevID || NULL == owner)
124     {
125         OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);
126         return OC_STACK_INVALID_PARAM;
127     }
128
129     OCStackResult res = OC_STACK_ERROR;
130
131     OicUuid_t ptDeviceID = {.id={0}};
132     if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
133     {
134         OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
135         return res;
136     }
137
138     uint8_t pairingPSK[OWNER_PSK_LENGTH_128] = {0};
139     OicSecKey_t pairingKey = {pairingPSK, OWNER_PSK_LENGTH_128};
140
141     //Generating PairingPSK using OwnerPSK scheme
142     CAResult_t pskRet = CAGenerateOwnerPSK((const CAEndpoint_t *)endpoint,
143             (uint8_t *)OIC_RSRC_TYPE_SEC_DPAIRING,
144             strlen(OIC_RSRC_TYPE_SEC_DPAIRING),
145             (isPairingServer ? ptDeviceID.id : peerDevID->id), sizeof(OicUuid_t), // server
146             (isPairingServer ? peerDevID->id : ptDeviceID.id), sizeof(OicUuid_t), // client
147             pairingPSK, OWNER_PSK_LENGTH_128);
148
149     if (CA_STATUS_OK == pskRet)
150     {
151         OIC_LOG(INFO, TAG, "pairingPSK dump:\n");
152         OIC_LOG_BUFFER(INFO, TAG, pairingPSK, OWNER_PSK_LENGTH_128);
153         //Generating new credential for direct-pairing client
154
155         OicSecCred_t *cred = GenerateCredential(peerDevID,
156                 SYMMETRIC_PAIR_WISE_KEY, NULL,
157                 &pairingKey, owner);
158         VERIFY_NON_NULL(TAG, cred, ERROR);
159
160         res = AddCredential(cred);
161         if(res != OC_STACK_OK)
162         {
163             DeleteCredList(cred);
164             return res;
165         }
166     }
167     else
168     {
169         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
170     }
171
172     OIC_LOG(DEBUG, TAG, "OUT SavePairingPSK");
173 exit:
174     return res;
175 }
176 #endif // __WITH_DTLS__
177
178 OCStackResult DpairingToCBORPayload(const OicSecDpairing_t *dpair, uint8_t **payload, size_t *size)
179 {
180     if (NULL == dpair || NULL == payload || NULL != *payload || NULL == size)
181     {
182         return OC_STACK_INVALID_PARAM;
183     }
184
185     size_t cborLen = *size;
186     if (0 == cborLen)
187     {
188         cborLen = CBOR_SIZE;
189     }
190
191     *payload = NULL;
192     *size = 0;
193
194     OCStackResult ret = OC_STACK_ERROR;
195
196     CborEncoder encoder;
197     CborEncoder dpairMap;
198
199     int64_t cborEncoderResult = CborNoError;
200     uint8_t mapSize = DPAIR_MAP_SIZE;
201
202     uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
203     VERIFY_NON_NULL(TAG, outPayload, ERROR);
204     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
205
206     cborEncoderResult = cbor_encoder_create_map(&encoder, &dpairMap, mapSize);
207     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating DPAIRING Map");
208
209     //spm -- Mandatory
210     cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_SPM_NAME,
211         strlen(OIC_JSON_SPM_NAME));
212     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SPM name tag");
213     cborEncoderResult = cbor_encode_int(&dpairMap, dpair->spm);
214     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SPM value");
215
216     //PDEVICEID -- Mandatory
217     cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_PDEVICE_ID_NAME,
218         strlen(OIC_JSON_PDEVICE_ID_NAME));
219     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PDeviceID tag");
220     {
221         char *deviceId = NULL;
222         ret = ConvertUuidToStr(&dpair->pdeviceID, &deviceId);
223         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
224         cborEncoderResult = cbor_encode_text_string(&dpairMap, deviceId, strlen(deviceId));
225         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode PDeviceID value");
226         OICFree(deviceId);
227     }
228
229     //ROWNER -- Mandatory
230     {
231         char *rowner = NULL;
232         cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_ROWNERID_NAME,
233             strlen(OIC_JSON_ROWNERID_NAME));
234         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROWNER tag");
235         ret = ConvertUuidToStr(&dpair->rownerID, &rowner);
236         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
237         cborEncoderResult = cbor_encode_text_string(&dpairMap, rowner, strlen(rowner));
238         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Rowner ID value");
239         OICFree(rowner);
240     }
241
242     cborEncoderResult = cbor_encoder_close_container(&encoder, &dpairMap);
243     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close dpairMap");
244
245      if (CborNoError == cborEncoderResult)
246     {
247         *size = encoder.ptr - outPayload;
248         *payload = outPayload;
249         ret = OC_STACK_OK;
250     }
251
252 exit:
253     if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
254     {
255        // reallocate and try again!
256        OICFree(outPayload);
257        // Since the allocated initial memory failed, double the memory.
258        cborLen += encoder.ptr - encoder.end;
259        cborEncoderResult = CborNoError;
260        ret = DpairingToCBORPayload(dpair, payload, &cborLen);
261        *size = cborLen;
262     }
263
264     if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
265     {
266        OICFree(outPayload);
267        outPayload = NULL;
268        *payload = NULL;
269        *size = 0;
270        ret = OC_STACK_ERROR;
271     }
272
273     return ret;
274 }
275
276 OCStackResult CBORPayloadToDpair(const uint8_t *cborPayload, size_t size,
277                                 OicSecDpairing_t **secDpair)
278 {
279     if (NULL == cborPayload || NULL == secDpair || NULL != *secDpair || 0 == size)
280     {
281         return OC_STACK_INVALID_PARAM;
282     }
283
284     OCStackResult ret = OC_STACK_ERROR;
285     *secDpair = NULL;
286
287     CborValue dpairCbor = { .parser = NULL };
288     CborParser parser = { .end = NULL };
289     CborError cborFindResult = CborNoError;
290     int cborLen = size;
291
292     cbor_parser_init(cborPayload, cborLen, 0, &parser, &dpairCbor);
293     CborValue dpairMap = { .parser = NULL };
294     OicSecDpairing_t *dpair = NULL;
295     cborFindResult = cbor_value_enter_container(&dpairCbor, &dpairMap);
296     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering DPairing Map");
297
298     dpair = (OicSecDpairing_t *)OICCalloc(1, sizeof(*dpair));
299     VERIFY_NON_NULL(TAG, dpair, ERROR);
300
301     while (cbor_value_is_valid(&dpairMap))
302     {
303         char *name = NULL;
304         size_t len = 0;
305         CborType type = CborInvalidType;
306         cborFindResult = cbor_value_dup_text_string(&dpairMap, &name, &len, NULL);
307         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding tag name");
308         cborFindResult = cbor_value_advance(&dpairMap);
309         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a value in DPair map");
310
311         type = cbor_value_get_type(&dpairMap);
312         if (0 == strcmp(OIC_JSON_SPM_NAME, name))
313         {
314             cborFindResult = cbor_value_get_int(&dpairMap, (int *) &dpair->spm);
315             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SPM Value");
316         }
317
318         if (0 == strcmp(OIC_JSON_PDEVICE_ID_NAME, name))
319         {
320             char *id = NULL;
321             cborFindResult = cbor_value_dup_text_string(&dpairMap, &id, &len, NULL);
322             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PDeviceID value");
323             ret = ConvertStrToUuid(id, &dpair->pdeviceID);
324             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
325             OICFree(id);
326         }
327
328         if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name))
329         {
330             char *id = NULL;
331             cborFindResult = cbor_value_dup_text_string(&dpairMap, &id, &len, NULL);
332             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RownerID value");
333             ret = ConvertStrToUuid(id, &dpair->rownerID);
334             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
335             OICFree(id);
336         }
337
338         if (CborMapType != type && cbor_value_is_valid(&dpairMap))
339         {
340             cborFindResult = cbor_value_advance(&dpairMap);
341             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Dpair Map");
342         }
343         OICFree(name);
344     }
345
346     *secDpair = dpair;
347     ret = OC_STACK_OK;
348
349 exit:
350     if (CborNoError != cborFindResult)
351     {
352         OIC_LOG (ERROR, TAG, "CBORPayloadToDoxm failed");
353         DeleteDpairingBinData(dpair);
354         dpair = NULL;
355         *secDpair = NULL;
356         ret = OC_STACK_ERROR;
357     }
358     return ret;
359 }
360 /**
361  * Function to handle the handshake result in Direct-Pairing.
362  * This function will be invoked after DTLS handshake
363  * @param   endPoint  [IN] The remote endpoint.
364  * @param   errorInfo [IN] Error information from the endpoint.
365  * @return  NONE
366  */
367 void DPairingDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
368 {
369     OIC_LOG_V(INFO, TAG, "IN DPairingDTLSHandshakeCB");
370
371     if(gDpair && endpoint && info)
372     {
373         OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
374                  endpoint->addr, endpoint->port, info->result);
375
376         if(CA_STATUS_OK == info->result)
377         {
378             OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Connection success.");
379         }
380         else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
381         {
382             OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Authentication failed");
383
384         }
385
386 #ifdef __WITH_DTLS__
387         CARegisterDTLSHandshakeCallback(NULL);
388 #endif // __WITH_DTLS__
389
390         // delete temporary key
391         RemoveCredential(&gDpair->pdeviceID);
392     }
393
394     OIC_LOG_V(INFO, TAG, "OUT DPairingDTLSHandshakeCB");
395 }
396
397 static OCEntityHandlerResult HandleDpairingPostRequest (const OCEntityHandlerRequest * ehRequest)
398 {
399     OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle  processing POST request");
400     OCEntityHandlerResult ehRet = OC_EH_ERROR;
401     OicSecDpairing_t* newDpair = NULL;
402     OCStackResult res = OC_STACK_OK;
403
404     const OicSecPconf_t *pconf = GetPconfResourceData();
405     if (true == pconf->edp)
406     {
407         uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData1;
408         size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
409         if (payload)
410         {
411             res = CBORPayloadToDpair(payload, size, &newDpair);
412         }
413     }
414     else
415     {
416         OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled");
417         ehRet = OC_EH_ERROR;
418     }
419
420     if (OC_STACK_OK == res && newDpair && false == IsPairedDevice(&newDpair->pdeviceID))
421     {
422         // Check if valid Post request
423         bool prmMached = false;
424         for (size_t i=0; i<pconf->prmLen; i++)
425         {
426             if (newDpair->spm == pconf->prm[i])
427             {
428                 prmMached = true;
429                 break;
430             }
431         }
432         OIC_LOG_V(DEBUG, TAG, "Parsed spm is %s", prmMached ? "valid" :
433                 "invalid, send error response");
434
435         // Update local Dpairing with new Dpairing & prepare dtls session
436         if (prmMached && '\0' != (char)newDpair->pdeviceID.id[0])
437         {
438             if(!gDpair)
439             {
440                 gDpair = GetDpairingDefault();
441             }
442             gDpair->spm = newDpair->spm;
443             memcpy(&gDpair->pdeviceID, &newDpair->pdeviceID, sizeof(OicUuid_t));
444             memcpy(&gDpair->rownerID, &pconf->rownerID, sizeof(OicUuid_t));
445
446 #ifdef __WITH_DTLS__
447             // Add temporary psk
448             OCStackResult res;
449             OicUuid_t subjectId = {.id={0}};
450             res = AddTmpPskWithPIN(&gDpair->pdeviceID,
451                            SYMMETRIC_PAIR_WISE_KEY,
452                            (char*)pconf->pin.val, DP_PIN_LENGTH,
453                            &gDpair->rownerID, &subjectId);
454             if(res != OC_STACK_OK ||
455                     memcmp(&gDpair->pdeviceID, &subjectId, sizeof(OicUuid_t)))
456             {
457                 OIC_LOG_V(ERROR, TAG, "Failed to save the temporal PSK : %d", res);
458                 goto exit;
459             }
460
461             // Prepare to establish a secure channel with Pin-based PSK cipher suite
462             if (CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false) ||
463                 CA_STATUS_OK != CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))
464             {
465                 OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
466                 goto exit;
467             }
468
469             if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DPairingDTLSHandshakeCB))
470             {
471                 OIC_LOG(WARNING, TAG, "DirectPairingHandler : Failed to register"
472                         " DTLS handshake callback.");
473                 goto exit;
474             }
475 #endif // __WITH_DTLS__
476
477             // should be lock /oic/sec/dpairing resource if Direct-Pairing starts normally ?
478             OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource created");
479
480             ehRet = OC_EH_RESOURCE_CREATED;
481         }
482         else
483         {
484             OIC_LOG(ERROR, TAG, "Error in request check");
485         }
486     }
487
488
489 #ifdef __WITH_DTLS__
490 exit:
491 #endif // __WITH_DTLS__
492
493     if (OC_EH_ERROR == ehRet && gDpair)
494     {
495         RemoveCredential(&gDpair->pdeviceID);
496         gDpair = NULL;
497     }
498
499     // Send payload to request originator
500     if(OC_STACK_OK != SendSRMCBORResponse(ehRequest, ehRet, NULL, 0))
501     {
502         OIC_LOG (ERROR, TAG, "SendSRMCBORResponse failed in HandleDpairingPostRequest");
503     }
504
505     DeleteDpairingBinData(newDpair);
506     OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
507     return ehRet;
508 }
509
510 static OCEntityHandlerResult HandleDpairingPutRequest (const OCEntityHandlerRequest * ehRequest)
511 {
512     OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle  processing PUT request (Comfirmation)");
513
514     OCEntityHandlerResult ehRet = OC_EH_ERROR;
515     OicSecDpairing_t* newDpair = NULL;
516     OCStackResult res = OC_STACK_OK;
517
518     const OicSecPconf_t *pconf = GetPconfResourceData();
519     if (true == pconf->edp)
520     {
521         uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData1;
522         size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
523         if (payload)
524         {
525             res = CBORPayloadToDpair(payload, size, &newDpair);
526         }
527
528     }
529     else
530     {
531         OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled");
532         ehRet = OC_EH_ERROR;
533     }
534
535
536     if ((OC_STACK_OK == res) && gDpair && newDpair)
537     {
538         OIC_LOG(DEBUG, TAG, "Received direct-pairing finalization request");
539
540         // Check if valid Put request
541         VERIFY_SUCCESS(TAG, PRM_NOT_ALLOWED == newDpair->spm, ERROR);
542
543         const OicSecPconf_t *pconf = GetPconfResourceData();
544         VERIFY_NON_NULL(TAG, pconf, ERROR);
545
546 #ifdef __WITH_DTLS__
547         OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;
548         VERIFY_SUCCESS(TAG, (request->devAddr.flags | OC_FLAG_SECURE), ERROR);
549
550         //Generate new credential
551         OIC_LOG_V(INFO, TAG, "SavePairingPSK for %s(%d)", request->devAddr.addr,
552                 request->devAddr.port);
553         OCStackResult res = SavePairingPSK(&request->devAddr, &newDpair->pdeviceID,
554                 (OicUuid_t *)&pconf->rownerID, true);
555         VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
556 #endif //__WITH_DTLS__
557
558         //Generate new acl
559         OicSecPdAcl_t *pdAcl;
560         LL_FOREACH(pconf->pdacls, pdAcl)
561         {
562             OicSecAcl_t acl;
563             memset(&acl, 0, sizeof(OicSecAcl_t));
564             memcpy(&acl.subject, &gDpair->pdeviceID, sizeof(OicUuid_t));
565             acl.resources = pdAcl->resources;
566             acl.resourcesLen = pdAcl->resourcesLen;
567             memcpy(&acl.rownerID, &pconf->rownerID, sizeof(OicUuid_t));
568             acl.permission = pdAcl->permission;
569             acl.periods = pdAcl->periods;
570             acl.recurrences = pdAcl->recurrences;
571             acl.prdRecrLen = pdAcl->prdRecrLen;
572
573             size_t size = 0;
574             uint8_t *payload = NULL;
575             if (OC_STACK_OK == AclToCBORPayload(&acl, &payload, &size))
576             {
577                 InstallNewACL(payload, size);
578                 OICFree(payload);
579             }
580         }
581
582         //update pconf device list
583         AddPairedDevice(&newDpair->pdeviceID);
584
585         //Initialize dpairing resource
586         gDpair = NULL;
587
588         OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource updated,"
589                 "direct-pairing finalization success");
590         ehRet = OC_EH_OK;
591     }
592
593 exit:
594
595     //Send payload to request originator
596     if(OC_STACK_OK != SendSRMCBORResponse(ehRequest, ehRet, NULL, 0))
597     {
598         OIC_LOG (ERROR, TAG, "SendSRMCBORResponse failed in HandleDpairingPutRequest");
599     }
600
601     DeleteDpairingBinData(newDpair);
602     OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
603     return ehRet;
604 }
605 /*
606  * This internal method is the entity handler for Dpairing resources and
607  * will handle REST request (GET/POST) for them.
608  */
609 OCEntityHandlerResult DpairingEntityHandler (OCEntityHandlerFlag flag,
610                                         OCEntityHandlerRequest * ehRequest,
611                                         void* callbackParameter)
612 {
613     OIC_LOG(DEBUG, TAG, "Received request DpairingEntityHandler");
614     (void)callbackParameter;
615     OCEntityHandlerResult ehRet = OC_EH_ERROR;
616
617     if (!ehRequest)
618     {
619         return ehRet;
620     }
621
622     if (flag & OC_REQUEST_FLAG)
623     {
624         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
625         switch (ehRequest->method)
626         {
627             case OC_REST_GET:
628                 break;
629
630             case OC_REST_POST:
631                 ehRet = HandleDpairingPostRequest(ehRequest);
632                 break;
633
634             case OC_REST_PUT:
635                 ehRet = HandleDpairingPutRequest(ehRequest);
636                 break;
637
638             case OC_REST_DELETE:
639                 break;
640
641             default:
642                 ehRet = OC_EH_ERROR;
643                 SendSRMCBORResponse(ehRequest, ehRet, NULL, 0);
644         }
645     }
646
647     return ehRet;
648 }
649
650 /*
651  * This internal method is used to create '/oic/sec/dpairing' resource.
652  */
653 OCStackResult CreateDpairingResource()
654 {
655     OCStackResult ret;
656
657     ret = OCCreateResource(&gDpairHandle,
658                            OIC_RSRC_TYPE_SEC_DPAIRING,
659                            OIC_MI_DEF,
660                            OIC_RSRC_DPAIRING_URI,
661                            DpairingEntityHandler,
662                            NULL,
663                            OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
664
665     if (OC_STACK_OK != ret)
666     {
667         OIC_LOG (ERROR, TAG, "Unable to instantiate Dpairing resource");
668         DeInitDpairingResource();
669     }
670     return ret;
671 }
672
673 /**
674  * Initialize Dpairing resource by loading data from persistent storage.
675  *
676  * @retval  OC_STACK_OK for Success, otherwise some error value
677  */
678 OCStackResult InitDpairingResource()
679 {
680     OCStackResult ret = OC_STACK_ERROR;
681
682     // Instantiate 'oic.sec.dpairing'
683     ret = CreateDpairingResource();
684     if (OC_STACK_OK != ret)
685     {
686         DeInitDpairingResource();
687     }
688     return ret;
689 }
690
691 /**
692  * Perform cleanup for Dpairing resources.
693  *
694  * @return
695  * OC_STACK_OK    - no error
696  * OC_STACK_ERROR - stack process error
697  *
698  */
699 OCStackResult DeInitDpairingResource()
700 {
701     OCStackResult ret = OCDeleteResource(gDpairHandle);
702     gDpair = NULL;
703
704     if(OC_STACK_OK == ret)
705     {
706         return OC_STACK_OK;
707     }
708     else
709     {
710         return OC_STACK_ERROR;
711     }
712 }
713
714 OCStackResult SetDpairingRownerId(const OicUuid_t* newROwner)
715 {
716     OCStackResult ret = OC_STACK_ERROR;
717     uint8_t *cborPayload = NULL;
718     size_t size = 0;
719     OicUuid_t prevId = {.id={0}};
720
721     if(NULL == newROwner)
722     {
723         ret = OC_STACK_INVALID_PARAM;
724     }
725     if(NULL == gDpair)
726     {
727         ret = OC_STACK_NO_RESOURCE;
728     }
729
730     if(newROwner && gDpair)
731     {
732         memcpy(prevId.id, gDpair->rownerID.id, sizeof(prevId.id));
733         memcpy(gDpair->rownerID.id, newROwner->id, sizeof(newROwner->id));
734
735         ret = DpairingToCBORPayload(gDpair, &cborPayload, &size);
736         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
737
738         ret = UpdateSecureResourceInPS(OIC_JSON_DPAIRING_NAME, cborPayload, size);
739         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
740
741         OICFree(cborPayload);
742     }
743
744     return ret;
745
746 exit:
747     OICFree(cborPayload);
748     memcpy(gDpair->rownerID.id, prevId.id, sizeof(prevId.id));
749     return ret;
750 }
751
752 OCStackResult GetDpairingRownerId(OicUuid_t *rowneruuid)
753 {
754     OCStackResult retVal = OC_STACK_ERROR;
755     if (gDpair)
756     {
757         *rowneruuid = gDpair->rownerID;
758         retVal = OC_STACK_OK;
759     }
760     return retVal;
761 }