1 /* *****************************************************************
3 * Copyright 2016 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * *****************************************************************/
21 #include "iotivity_config.h"
26 #include "oic_malloc.h"
27 #include "oic_string.h"
28 #if defined (__TIZENRT__)
29 #include <apps/netutils/cJSON.h>
34 #include "ocpayload.h"
35 #include "ocpayloadcbor.h"
36 #include "payload_logging.h"
37 #include "resourcemanager.h"
38 #include "pconfresource.h"
39 #include "psinterface.h"
41 #include "srmresourcestrings.h"
42 #include "doxmresource.h"
43 #include "srmutility.h"
44 #include "ocserverrequest.h"
45 #include "psinterface.h"
46 #include "security_internals.h"
51 #define TAG "OIC_SRM_PCONF"
53 static const uint16_t CBOR_SIZE = 1024;
54 static const uint64_t CBOR_MAX_SIZE = 4400;
55 static const uint8_t PCONF_MAP_SIZE = 4;
56 static const uint8_t PCONF_RESOURCE_MAP_SIZE = 4;
58 static OicSecPconf_t *gPconf = NULL;
59 static OCResourceHandle gPconfHandle = NULL;
60 static OicSecPconf_t gDefaultPconf =
63 NULL, /* OicSecPrm *prm */
64 0, /* size_t prmLen */
65 {.val = {0}}, /* OicDpPin_t pin */
66 NULL, /* OicSecPdAcl_t *pdacls */
67 NULL, /* OicUuid_t *pddevs */
68 0, /* size_t pddevLen */
69 {.id = {0}}, /* OicUuid_t deviceID */
70 {.id = {0}}, /* OicUuid_t rowner */
74 * This function frees OicSecPdAcl_t object's fields and object itself.
76 void FreePdAclList(OicSecPdAcl_t* pdacls)
83 OicSecPdAcl_t *aclTmp1 = NULL;
84 OicSecPdAcl_t *aclTmp2 = NULL;
85 LL_FOREACH_SAFE(pdacls, aclTmp1, aclTmp2)
87 LL_DELETE(pdacls, aclTmp1);
90 for (i = 0; i < aclTmp1->resourcesLen; i++)
92 OICFree(aclTmp1->resources[i]);
94 OICFree(aclTmp1->resources);
99 for(i = 0; i < aclTmp1->prdRecrLen; i++)
101 OICFree(aclTmp1->periods[i]);
103 OICFree(aclTmp1->periods);
107 if(aclTmp1->recurrences)
109 for(i = 0; i < aclTmp1->prdRecrLen; i++)
111 OICFree(aclTmp1->recurrences[i]);
113 OICFree(aclTmp1->recurrences);
122 void DeletePconfBinData(OicSecPconf_t* pconf)
132 FreePdAclList(pconf->pdacls);
136 OICFree(pconf->pddevs);
143 static size_t OicPdAclSize(const OicSecPdAcl_t *pdAcl)
150 OicSecPdAcl_t *tmp = (OicSecPdAcl_t *)pdAcl;
160 OCStackResult PconfToCBORPayload(const OicSecPconf_t *pconf,uint8_t **payload,size_t *size)
162 if (NULL == pconf || NULL == payload || NULL != *payload || NULL == size)
164 return OC_STACK_INVALID_PARAM;
166 size_t cborLen = *size;
173 OCStackResult ret = OC_STACK_ERROR;
175 CborEncoder pconfMap;
177 int64_t cborEncoderResult = CborNoError;
178 uint8_t mapSize = PCONF_MAP_SIZE;
180 if (pconf->prmLen > 0)
193 uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
194 VERIFY_NON_NULL(TAG, outPayload, ERROR);
196 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
197 cborEncoderResult = cbor_encoder_create_map(&encoder, &pconfMap, mapSize);
198 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating Pconf Map.");
201 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_EDP_NAME,
202 strlen(OIC_JSON_EDP_NAME));
203 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Encode EDP String.");
204 cborEncoderResult = cbor_encode_boolean(&pconfMap, pconf->edp);
205 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert PconfEDP value");
207 //PRM type -- Not Mandatory
208 if(pconf->prmLen > 0)
211 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PRM_NAME,
212 strlen(OIC_JSON_PRM_NAME));
213 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM NAME");
214 cborEncoderResult = cbor_encoder_create_array(&pconfMap, &prm, pconf->prmLen);
215 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM value");
217 for (size_t i = 0; i < pconf->prmLen; i++)
219 cborEncoderResult = cbor_encode_int(&prm, pconf->prm[i]);
220 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM Array");
222 cborEncoderResult = cbor_encoder_close_container(&pconfMap, &prm);
223 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close encode array");
227 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PIN_NAME,
228 strlen(OIC_JSON_PIN_NAME));
229 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create OIC_JSON_PIN_NAME");
230 cborEncoderResult = cbor_encode_byte_string(&pconfMap, pconf->pin.val, sizeof(pconf->pin.val));
231 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to convert pin value");
236 OicSecPdAcl_t *pdacl = pconf->pdacls;
237 CborEncoder pdAclArray;
238 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDACL_NAME,
239 strlen(OIC_JSON_PDACL_NAME));
240 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create OIC_JSON_PDACL_NAME");
241 cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pdAclArray,
242 OicPdAclSize(pconf->pdacls));
243 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to creeate _pdacl array");
247 CborEncoder pdAclMap;
248 // PDACL Map size - Number of mandatory items
249 uint8_t aclMapSize = 2;
251 if (pdacl->prdRecrLen)
255 if (pdacl->recurrences)
260 cborEncoderResult = cbor_encoder_create_map(&pdAclArray, &pdAclMap, aclMapSize);
261 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to creeate _pdacl array");
263 // Resources -- Mandatory
264 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RESOURCES_NAME,
265 strlen(OIC_JSON_RESOURCES_NAME));
266 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode resource result");
268 CborEncoder resources;
269 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &resources,
270 pdacl->resourcesLen);
271 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create resource array");
273 for (size_t i = 0; i < pdacl->resourcesLen; i++)
276 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap,
277 PCONF_RESOURCE_MAP_SIZE);
278 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
280 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
281 strlen(OIC_JSON_HREF_NAME));
282 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
283 cborEncoderResult = cbor_encode_text_string(&rMap, pdacl->resources[i],
284 strlen(pdacl->resources[i]));
285 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
287 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
288 strlen(OIC_JSON_REL_NAME));
289 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
291 // TODO : Need to assign real value of REL
292 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
293 strlen(OIC_JSON_EMPTY_STRING));
294 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
296 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
297 strlen(OIC_JSON_RT_NAME));
298 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
300 // TODO : Need to assign real value of RT
301 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
302 strlen(OIC_JSON_EMPTY_STRING));
303 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
305 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
306 strlen(OIC_JSON_IF_NAME));
307 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
309 // TODO : Need to assign real value of IF
310 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
311 strlen(OIC_JSON_EMPTY_STRING));
312 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
314 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
315 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
318 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &resources);
319 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close resource array");
321 // Permissions -- Mandatory
322 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERMISSION_NAME,
323 strlen(OIC_JSON_PERMISSION_NAME));
324 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create permition string");
325 cborEncoderResult = cbor_encode_int(&pdAclMap, pdacl->permission);
326 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode permition calue");
328 // Period -- Not Mandatory
332 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERIODS_NAME,
333 strlen(OIC_JSON_PERIODS_NAME));
334 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period value");
335 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &period,
337 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
339 for (size_t i = 0; i < pdacl->prdRecrLen; i++)
341 cborEncoderResult = cbor_encode_text_string(&period, pdacl->periods[i],
342 strlen(pdacl->periods[i]));
343 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period");
345 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &period);
346 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to close period array");
349 // Period -- Not Mandatory
350 if(0 != pdacl->prdRecrLen && pdacl->recurrences)
352 CborEncoder recurrences;
353 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RECURRENCES_NAME,
354 strlen(OIC_JSON_RECURRENCES_NAME));
355 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to encode recurrences");
356 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &recurrences,
358 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create rec array");
360 for (size_t i = 0; i < pdacl->prdRecrLen; i++)
362 cborEncoderResult = cbor_encode_text_string(&recurrences,
363 pdacl->recurrences[i], strlen(pdacl->recurrences[i]));
364 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode recurrences");
366 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &recurrences);
367 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close rec array");
369 cborEncoderResult = cbor_encoder_close_container(&pdAclArray, &pdAclMap);
370 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl map");
375 cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pdAclArray);
376 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl array");
380 //There may not be paired devices if it did not pairing before
381 if (pconf->pddevs && 0 < pconf->pddevLen)
384 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDDEV_LIST_NAME,
385 strlen(OIC_JSON_PDDEV_LIST_NAME));
386 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode pddev");
387 cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pddev, pconf->pddevLen);
388 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
390 for (size_t i = 0; i < pconf->pddevLen; i++)
392 char *pddevId = NULL;
393 ret = ConvertUuidToStr(&pconf->pddevs[i], &pddevId);
394 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
395 cborEncoderResult = cbor_encode_text_string(&pddev, pddevId, strlen(pddevId));
396 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding pddev Id Value.");
399 cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pddev);
400 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pddev array");
403 //DeviceId -- Mandatory
404 //There may not be devicd id if caller is provisioning tool
405 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_DEVICE_ID_NAME,
406 strlen(OIC_JSON_DEVICE_ID_NAME));
407 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode device id");
409 char *deviceId = NULL;
410 ret = ConvertUuidToStr(&pconf->deviceID, &deviceId);
411 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
412 cborEncoderResult = cbor_encode_text_string(&pconfMap, deviceId, strlen(deviceId));
413 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode deviceID value");
417 //ROwner -- Mandatory
420 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_ROWNERID_NAME,
421 strlen(OIC_JSON_ROWNERID_NAME));
422 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rowner string");
423 ret = ConvertUuidToStr(&pconf->rownerID, &rowner);
424 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
425 cborEncoderResult = cbor_encode_text_string(&pconfMap, rowner, strlen(rowner));
426 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rwoner value");
430 cborEncoderResult = cbor_encoder_close_container(&encoder, &pconfMap);
431 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pconfMap");
433 *size = cbor_encoder_get_buffer_size(&encoder, outPayload);
434 *payload = outPayload;
437 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
439 // reallocate and try again!
441 // Since the allocated initial memory failed, double the memory.
442 cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
443 cborEncoderResult = CborNoError;
444 ret = PconfToCBORPayload(pconf, payload, &cborLen);
447 if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
453 ret = OC_STACK_ERROR;
458 OCStackResult CBORPayloadToPconf(const uint8_t *cborPayload, size_t size, OicSecPconf_t **secPconf)
460 if (NULL == cborPayload || NULL == secPconf || NULL != *secPconf || 0 == size)
462 return OC_STACK_INVALID_PARAM;
464 OCStackResult ret = OC_STACK_ERROR;
466 CborValue pconfCbor = { .parser = NULL };
467 CborParser parser = { .end = NULL };
468 CborError cborFindResult = CborNoError;
470 cbor_parser_init(cborPayload, size, 0, &parser, &pconfCbor);
471 CborValue pconfMap = { .parser = NULL } ;
472 OicSecPconf_t *pconf = NULL;
473 cborFindResult = cbor_value_enter_container(&pconfCbor, &pconfMap);
474 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter map");
475 pconf = (OicSecPconf_t *)OICCalloc(1, sizeof(*pconf));
476 VERIFY_NON_NULL(TAG, pconf, ERROR);
477 while (cbor_value_is_valid(&pconfMap))
481 CborType type = cbor_value_get_type(&pconfMap);
482 if (type == CborTextStringType && cbor_value_is_text_string(&pconfMap))
484 cborFindResult = cbor_value_dup_text_string(&pconfMap, &name, &len, NULL);
485 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
486 cborFindResult = cbor_value_advance(&pconfMap);
487 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
493 if(0 == strcmp(OIC_JSON_EDP_NAME, name) && cbor_value_is_boolean(&pconfMap))
495 cborFindResult = cbor_value_get_boolean(&pconfMap, &pconf->edp);
496 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
498 if (0 == strcmp(OIC_JSON_PRM_NAME, name))
501 CborValue prm = { .parser = NULL };
502 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->prmLen);
503 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
504 VERIFY_SUCCESS(TAG, pconf->prmLen != 0, ERROR);
506 pconf->prm = (OicSecPrm_t *)OICCalloc(pconf->prmLen, sizeof(OicSecPrm_t));
507 VERIFY_NON_NULL(TAG, pconf->prm, ERROR);
508 cborFindResult = cbor_value_enter_container(&pconfMap, &prm);
509 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to eneter array");
511 while (cbor_value_is_valid(&prm) && cbor_value_is_integer(&prm))
515 cborFindResult = cbor_value_get_int(&prm, &prm_val);
516 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
517 pconf->prm[i++] = (OicSecPrm_t)prm_val;
518 cborFindResult = cbor_value_advance(&prm);
519 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
523 if (0 == strcmp(OIC_JSON_PIN_NAME, name) && cbor_value_is_byte_string(&pconfMap))
526 cborFindResult = cbor_value_dup_byte_string(&pconfMap, &pin, &len, NULL);
527 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
528 memcpy(pconf->pin.val, pin, len);
533 if (0 == strcmp(OIC_JSON_PDACL_NAME, name))
535 CborValue pdAclArray = { .parser = NULL};
536 OicSecPdAcl_t *headPdacl = NULL;
538 cborFindResult = cbor_value_enter_container(&pconfMap, &pdAclArray);
539 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
541 while (cbor_value_is_valid(&pdAclArray))
543 CborValue pdAclMap = { .parser = NULL};
544 OicSecPdAcl_t *pdacl = (OicSecPdAcl_t *) OICCalloc(1, sizeof(OicSecPdAcl_t));
545 VERIFY_NON_NULL(TAG, pdacl, ERROR);
547 cborFindResult = cbor_value_enter_container(&pdAclArray, &pdAclMap);
548 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
550 while (cbor_value_is_valid(&pdAclMap))
554 CborType type = cbor_value_get_type(&pdAclMap);
555 if (type == CborTextStringType && cbor_value_is_text_string(&pdAclMap))
557 cborFindResult = cbor_value_dup_text_string(&pdAclMap, &name,
559 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
560 cborFindResult = cbor_value_advance(&pdAclMap);
561 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
565 // Resources -- Mandatory
566 if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0 && cbor_value_is_array(&pdAclMap))
569 CborValue resources = { .parser = NULL };
570 cborFindResult = cbor_value_get_array_length(&pdAclMap,
571 &pdacl->resourcesLen);
572 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
573 cborFindResult = cbor_value_enter_container(&pdAclMap, &resources);
574 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
575 pdacl->resources = (char **) OICCalloc(pdacl->resourcesLen,
577 VERIFY_NON_NULL(TAG, pdacl->resources, ERROR);
579 while (cbor_value_is_valid(&resources))
581 CborValue rMap = { .parser = NULL };
582 cborFindResult = cbor_value_enter_container(&resources, &rMap);
583 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
585 while(cbor_value_is_valid(&rMap) && cbor_value_is_text_string(&rMap))
587 char *rMapName = NULL;
588 size_t rMapNameLen = 0;
589 cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
590 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
591 cborFindResult = cbor_value_advance(&rMap);
592 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
595 if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
597 // TODO : Need to check data structure of OicSecPdAcl_t based on RAML spec.
598 cborFindResult = cbor_value_dup_text_string(&rMap, &pdacl->resources[i++], &len, NULL);
599 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
603 if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
605 // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
606 char *relData = NULL;
607 cborFindResult = cbor_value_dup_text_string(&rMap, &relData, &len, NULL);
608 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
613 if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
615 // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
617 cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
618 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
623 if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
625 // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
627 cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
628 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
632 if (cbor_value_is_valid(&rMap))
634 cborFindResult = cbor_value_advance(&rMap);
635 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
640 if (cbor_value_is_valid(&resources))
642 cborFindResult = cbor_value_advance(&resources);
643 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
648 // Permissions -- Mandatory
649 if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0 && cbor_value_is_unsigned_integer(&pdAclMap))
651 uint64_t permission = 0;
652 cborFindResult = cbor_value_get_uint64(&pdAclMap, &permission);
653 pdacl->permission = (uint16_t)permission;
654 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
657 // Period -- Not mandatory
658 if (strcmp(name, OIC_JSON_PERIODS_NAME) == 0 && cbor_value_is_array(&pdAclMap))
661 CborValue period = { .parser = NULL };
662 cborFindResult = cbor_value_get_array_length(&pdAclMap,
664 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
665 cborFindResult = cbor_value_enter_container(&pdAclMap, &period);
666 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
667 pdacl->periods = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
668 VERIFY_NON_NULL(TAG, pdacl->periods, ERROR);
670 while (cbor_value_is_text_string(&period) && cbor_value_is_text_string(&period))
672 cborFindResult = cbor_value_dup_text_string(&period,
673 &pdacl->periods[i++], &len, NULL);
674 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
675 cborFindResult = cbor_value_advance(&period);
676 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
681 // Recurrence -- Not mandatory
682 if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0 && cbor_value_is_array(&pdAclMap))
685 CborValue recurrences = { .parser = NULL };
686 cborFindResult = cbor_value_get_array_length(&pdAclMap, &pdacl->prdRecrLen);
687 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
688 cborFindResult = cbor_value_enter_container(&pdAclMap, &recurrences);
689 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
690 pdacl->recurrences = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
691 VERIFY_NON_NULL(TAG, pdacl->recurrences, ERROR);
693 while (cbor_value_is_text_string(&recurrences) && cbor_value_is_text_string(&recurrences))
695 cborFindResult = cbor_value_dup_text_string(&recurrences,
696 &pdacl->recurrences[i++], &len, NULL);
697 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
698 cborFindResult = cbor_value_advance(&recurrences);
699 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
702 if (type != CborMapType && cbor_value_is_valid(&pdAclMap))
704 cborFindResult = cbor_value_advance(&pdAclMap);
705 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
708 if (cbor_value_is_valid(&pdAclArray))
710 cborFindResult = cbor_value_advance(&pdAclArray);
711 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
717 if (headPdacl == NULL)
723 OicSecPdAcl_t *temp = headPdacl;
731 pconf->pdacls = headPdacl;
735 if (strcmp(name, OIC_JSON_PDDEV_LIST_NAME) == 0 && cbor_value_is_array(&pconfMap))
738 CborValue pddevs = { .parser = NULL };
739 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->pddevLen);
740 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
741 cborFindResult = cbor_value_enter_container(&pconfMap, &pddevs);
742 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
744 pconf->pddevs = (OicUuid_t *)OICMalloc(pconf->pddevLen * sizeof(OicUuid_t));
745 VERIFY_NON_NULL(TAG, pconf->pddevs, ERROR);
746 while (cbor_value_is_valid(&pddevs) && cbor_value_is_text_string(&pddevs))
749 cborFindResult = cbor_value_dup_text_string(&pddevs, &pddev, &len, NULL);
750 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
751 cborFindResult = cbor_value_advance(&pddevs);
752 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
753 ret = ConvertStrToUuid(pddev, &pconf->pddevs[i++]);
754 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
759 //Mandatory - Device Id
760 if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name) && cbor_value_is_text_string(&pconfMap))
762 char *deviceId = NULL;
763 cborFindResult = cbor_value_dup_text_string(&pconfMap, &deviceId, &len, NULL);
764 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get deviceID");
765 ret = ConvertStrToUuid(deviceId, &pconf->deviceID);
766 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
770 // ROwner -- Mandatory
771 if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name) && cbor_value_is_text_string(&pconfMap))
774 cborFindResult = cbor_value_dup_text_string(&pconfMap, &rowner, &len, NULL);
775 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get rowner");
776 ret = ConvertStrToUuid(rowner, &pconf->rownerID);
777 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
781 if (CborMapType != type && cbor_value_is_valid(&pconfMap))
783 cborFindResult = cbor_value_advance(&pconfMap);
784 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
792 if (CborNoError != cborFindResult)
794 OIC_LOG (ERROR, TAG, "CBORPayloadToPconf failed");
795 DeletePconfBinData(pconf);
798 ret = OC_STACK_ERROR;
803 static bool UpdatePersistentStorage(const OicSecPconf_t * pconf)
807 // Convert PCONF data into Cborpayload for update to persistent storage
808 uint8_t *payload = NULL;
810 if (OC_STACK_OK == PconfToCBORPayload(pconf, &payload, &size) && NULL !=payload)
812 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, payload, size))
821 static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest * ehRequest)
823 uint8_t* payload = NULL;
825 const OicSecDoxm_t *m_doxm = NULL;
826 OCEntityHandlerResult ehRet = OC_EH_OK;
829 memset(&pconf, 0, sizeof(OicSecPconf_t));
831 OIC_LOG (DEBUG, TAG, "Pconf EntityHandle processing GET request");
833 m_doxm = GetDoxmResourceData();
836 OIC_LOG (DEBUG, TAG, "Doxm resource Data is NULL");
839 if ((m_doxm) && (true == m_doxm->dpc))
841 //Making response elements for Get request
842 if( (true == gPconf->edp) &&
843 (gPconf->prm && 0 < gPconf->prmLen) &&
844 (0 < strlen((const char*)gPconf->deviceID.id)) &&
845 (0 < strlen((const char*)gPconf->rownerID.id)))
848 pconf.prm = gPconf->prm;
849 pconf.prmLen = gPconf->prmLen;
850 memcpy(&pconf.deviceID, &gPconf->deviceID, sizeof(OicUuid_t));
851 memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
852 OIC_LOG (DEBUG, TAG, "PCONF - direct pairing enabled");
854 else if (false == gPconf->edp)
857 memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
858 OIC_LOG (DEBUG, TAG, "PCONF - direct pairing disable");
863 OIC_LOG (DEBUG, TAG, "PCONF - error");
868 OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
872 if (OC_STACK_OK != PconfToCBORPayload(gPconf, &payload, &size))
877 if(OC_EH_OK == ehRet)
879 ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
888 // Send response payload to request originator
889 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
892 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfGetRequest");
894 OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
900 static OCEntityHandlerResult HandlePconfPostRequest (const OCEntityHandlerRequest * ehRequest)
902 OCEntityHandlerResult ehRet = OC_EH_OK;
903 OCStackResult res=OC_STACK_OK;
904 OicSecPconf_t* newPconf = NULL;
906 if (NULL != GetDoxmResourceData() && true == GetDoxmResourceData()->dpc)
908 // Convert CBOR PCONF data into binary. This will also validate the PCONF data received.
909 uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
910 size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
913 res = CBORPayloadToPconf(payload, size, &newPconf);
918 OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
922 if (newPconf && res == OC_STACK_OK)
924 // Check if valid Post request
925 if ((true == newPconf->edp) && (0 < newPconf->prmLen) &&
926 DP_PIN_LENGTH == sizeof(newPconf->pin.val))
928 OicSecPrm_t *oldPrm = gPconf->prm;
929 OicSecPdAcl_t *oldPdacl = gPconf->pdacls;
931 // Update local PCONF with new PCONF
933 memcpy(&gPconf->pin, &newPconf->pin, sizeof(OicDpPin_t));
934 gPconf->prm = newPconf->prm;
935 gPconf->prmLen = newPconf->prmLen;
936 gPconf->pdacls = newPconf->pdacls;
937 memcpy(&gPconf->rownerID, &newPconf->rownerID, sizeof(OicUuid_t));
939 // to delete old value(prm, pdacl)
940 newPconf->prm = oldPrm;
941 newPconf->pdacls = oldPdacl;
943 else if (false == newPconf->edp)
953 if(OC_EH_ERROR != ehRet && true == UpdatePersistentStorage(gPconf))
955 ehRet = OC_EH_CHANGED;
958 DeletePconfBinData(newPconf);
965 // Send payload to request originator
966 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
969 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfPostRequest");
972 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
977 * This internal method is the entity handler for PCONF resources and
978 * will handle REST request (POST) for them.
980 OCEntityHandlerResult PconfEntityHandler (OCEntityHandlerFlag flag,
981 OCEntityHandlerRequest * ehRequest,
982 void* callbackParameter)
984 OIC_LOG(DEBUG, TAG, "Received request PconfEntityHandler");
985 (void)callbackParameter;
986 OCEntityHandlerResult ehRet = OC_EH_ERROR;
993 if (flag & OC_REQUEST_FLAG)
995 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
996 switch (ehRequest->method)
999 ehRet = HandlePconfGetRequest(ehRequest);
1003 ehRet = HandlePconfPostRequest(ehRequest);
1006 case OC_REST_DELETE:
1010 ehRet = OC_EH_ERROR;
1011 SendSRMResponse(ehRequest, ehRet, NULL, 0);
1019 * This internal method is used to create '/oic/sec/pconf' resource.
1021 OCStackResult CreatePconfResource()
1025 ret = OCCreateResource(&gPconfHandle,
1026 OIC_RSRC_TYPE_SEC_PCONF,
1027 OC_RSRVD_INTERFACE_DEFAULT,
1031 OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
1033 if (OC_STACK_OK != ret)
1035 OIC_LOG (ERROR, TAG, "Unable to instantiate PCONF resource");
1036 DeInitPconfResource();
1042 * Get the default value.
1043 * @retval the gDefaultPconf pointer;
1045 static OicSecPconf_t* GetPconfDefault()
1047 OIC_LOG (DEBUG, TAG, "GetPconfDefault");
1049 return &gDefaultPconf;
1053 * This method is used by SRM to retrieve PCONF resource data..
1055 * @retval reference to @ref OicSecPconf_t, binary format of Pconf resource data
1057 const OicSecPconf_t* GetPconfResourceData()
1063 * Initialize PCONF resource by loading data from persistent storage.
1065 * @retval OC_STACK_OK for Success, otherwise some error value
1067 OCStackResult InitPconfResource()
1069 OCStackResult ret = OC_STACK_ERROR;
1071 uint8_t *data = NULL;
1074 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PCONF_NAME, &data, &size);
1075 // If database read failed
1076 if (ret != OC_STACK_OK)
1078 OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
1082 CBORPayloadToPconf(data, size, &gPconf);
1085 if (!data || !gPconf)
1087 gPconf = GetPconfDefault();
1089 // device id from doxm
1090 OicUuid_t deviceId = {.id = {0}};
1091 OCStackResult ret = GetDoxmDeviceID( &deviceId);
1092 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1093 memcpy(&gPconf->deviceID, &deviceId, sizeof(OicUuid_t));
1095 VERIFY_NON_NULL(TAG, gPconf, ERROR);
1097 // Instantiate 'oic.sec.pconf'
1098 ret = CreatePconfResource();
1101 if (OC_STACK_OK != ret)
1103 DeInitPconfResource();
1110 * Perform cleanup for PCONF resources.
1113 * OC_STACK_OK - no error
1114 * OC_STACK_ERROR - stack process error
1117 OCStackResult DeInitPconfResource()
1119 OCStackResult ret = OCDeleteResource(gPconfHandle);
1120 if(gPconf!= &gDefaultPconf)
1122 DeletePconfBinData(gPconf);
1126 if(OC_STACK_OK == ret)
1132 return OC_STACK_ERROR;
1137 * This method might be used to add a paired device id after direct-pairing process complete.
1139 * @param pdeviceId ID of the paired device.
1141 * @retval OC_STACK_OK for Success, otherwise some error value
1143 OCStackResult AddPairedDevice(OicUuid_t *pdeviceId)
1145 if (!gPconf || !pdeviceId)
1147 return OC_STACK_INVALID_PARAM;
1151 OicUuid_t *prevList = gPconf->pddevs;
1152 gPconf->pddevs = (OicUuid_t *)OICCalloc(gPconf->pddevLen+1, sizeof(OicUuid_t));
1155 return OC_STACK_NO_MEMORY;
1157 for (size_t i=0; i<gPconf->pddevLen; i++)
1159 memcpy(&gPconf->pddevs[i], &prevList[i], sizeof(OicUuid_t));
1162 // add new paired device id
1163 memcpy(&gPconf->pddevs[gPconf->pddevLen], pdeviceId, sizeof(OicUuid_t));
1167 if(true != UpdatePersistentStorage(gPconf))
1169 OIC_LOG (ERROR, TAG, "Fail to update pconf resource");
1170 return OC_STACK_ERROR;
1173 OIC_LOG (ERROR, TAG, "Add paired device success");
1178 * This method might be used by PolicyEngine to retrieve PDACL for a Subject.
1180 * @param subjectId ID of the subject for which PDACL is required.
1181 * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
1182 * successive calls for same subjectId.
1184 * @retval reference to @ref OicSecPdAcl_t if PDACL is found, else NULL
1186 const OicSecPdAcl_t* GetPdAclData(const OicUuid_t* subjectId, OicSecPdAcl_t **savePtr)
1188 OicSecPdAcl_t *pdacl = NULL;
1190 if ( NULL == subjectId)
1196 * savePtr MUST point to NULL if this is the 'first' call to retrieve PDACL for
1199 if (NULL == *savePtr)
1201 pdacl = gPconf->pdacls;
1203 // Find if 'subjectID' is in paired device list.
1204 for(size_t i=0; i<gPconf->pddevLen; i++)
1206 if (memcmp(&(gPconf->pddevs[i]), subjectId, sizeof(OicUuid_t)) == 0)
1215 OicSecPdAcl_t *temp = NULL;
1218 * If this is a 'successive' call, search for location pointed by
1219 * savePtr and assign 'begin' to the next PDACL after it in the linked
1220 * list and start searching from there.
1222 LL_FOREACH(gPconf->pdacls, temp)
1224 if (temp == *savePtr)
1233 // Cleanup in case no PDACL is found
1239 * This method return whether device is paired or not.
1241 * @param pdeviceId Target device ID to find in paired list.
1242 * @retval ture if device is already paired, else false
1244 bool IsPairedDevice(const OicUuid_t* pdeviceId)
1246 // Find if 'pdeviceId' is in paired device list.
1247 for(size_t i=0; i<gPconf->pddevLen; i++)
1249 if (memcmp(&(gPconf->pddevs[i]), pdeviceId, sizeof(OicUuid_t)) == 0)
1257 OCStackResult SetPconfRownerId(const OicUuid_t* newROwner)
1259 OCStackResult ret = OC_STACK_ERROR;
1260 uint8_t *cborPayload = NULL;
1262 OicUuid_t prevId = {.id={0}};
1264 if(NULL == newROwner)
1266 ret = OC_STACK_INVALID_PARAM;
1270 ret = OC_STACK_NO_RESOURCE;
1273 if(newROwner && gPconf)
1275 memcpy(prevId.id, gPconf->rownerID.id, sizeof(prevId.id));
1276 memcpy(gPconf->rownerID.id, newROwner->id, sizeof(newROwner->id));
1278 ret = PconfToCBORPayload(gPconf, &cborPayload, &size);
1279 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1281 ret = UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, cborPayload, size);
1282 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1284 OICFree(cborPayload);
1290 OICFree(cborPayload);
1291 memcpy(gPconf->rownerID.id, prevId.id, sizeof(prevId.id));
1295 OCStackResult GetPconfRownerId(OicUuid_t *rowneruuid)
1297 OCStackResult retVal = OC_STACK_ERROR;
1300 *rowneruuid = gPconf->rownerID;
1301 retVal = OC_STACK_OK;