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"
30 #include "ocpayload.h"
31 #include "ocpayloadcbor.h"
32 #include "payload_logging.h"
33 #include "resourcemanager.h"
34 #include "pconfresource.h"
35 #include "psinterface.h"
37 #include "srmresourcestrings.h"
38 #include "doxmresource.h"
39 #include "srmutility.h"
40 #include "ocserverrequest.h"
41 #include "psinterface.h"
42 #include "security_internals.h"
47 #define TAG "OIC_SRM_PCONF"
49 static const uint16_t CBOR_SIZE = 1024;
50 static const uint64_t CBOR_MAX_SIZE = 4400;
51 static const uint8_t PCONF_MAP_SIZE = 4;
52 static const uint8_t PCONF_RESOURCE_MAP_SIZE = 4;
54 static OicSecPconf_t *gPconf = NULL;
55 static OCResourceHandle gPconfHandle = NULL;
56 static OicSecPconf_t gDefaultPconf =
59 NULL, /* OicSecPrm *prm */
60 0, /* size_t prmLen */
61 {.val = {0}}, /* OicDpPin_t pin */
62 NULL, /* OicSecPdAcl_t *pdacls */
63 NULL, /* OicUuid_t *pddevs */
64 0, /* size_t pddevLen */
65 {.id = {0}}, /* OicUuid_t deviceID */
66 {.id = {0}}, /* OicUuid_t rowner */
70 * This function frees OicSecPdAcl_t object's fields and object itself.
72 void FreePdAclList(OicSecPdAcl_t* pdacls)
79 OicSecPdAcl_t *aclTmp1 = NULL;
80 OicSecPdAcl_t *aclTmp2 = NULL;
81 LL_FOREACH_SAFE(pdacls, aclTmp1, aclTmp2)
83 LL_DELETE(pdacls, aclTmp1);
86 for (i = 0; i < aclTmp1->resourcesLen; i++)
88 OICFree(aclTmp1->resources[i]);
90 OICFree(aclTmp1->resources);
95 for(i = 0; i < aclTmp1->prdRecrLen; i++)
97 OICFree(aclTmp1->periods[i]);
99 OICFree(aclTmp1->periods);
103 if(aclTmp1->recurrences)
105 for(i = 0; i < aclTmp1->prdRecrLen; i++)
107 OICFree(aclTmp1->recurrences[i]);
109 OICFree(aclTmp1->recurrences);
118 void DeletePconfBinData(OicSecPconf_t* pconf)
128 FreePdAclList(pconf->pdacls);
132 OICFree(pconf->pddevs);
139 static size_t OicPdAclSize(const OicSecPdAcl_t *pdAcl)
146 OicSecPdAcl_t *tmp = (OicSecPdAcl_t *)pdAcl;
156 OCStackResult PconfToCBORPayload(const OicSecPconf_t *pconf,uint8_t **payload,size_t *size)
158 if (NULL == pconf || NULL == payload || NULL != *payload || NULL == size)
160 return OC_STACK_INVALID_PARAM;
162 size_t cborLen = *size;
169 OCStackResult ret = OC_STACK_ERROR;
171 CborEncoder pconfMap;
173 int64_t cborEncoderResult = CborNoError;
174 uint8_t mapSize = PCONF_MAP_SIZE;
176 if (pconf->prmLen > 0)
189 uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
190 VERIFY_NON_NULL(TAG, outPayload, ERROR);
192 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
193 cborEncoderResult = cbor_encoder_create_map(&encoder, &pconfMap, mapSize);
194 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating Pconf Map.");
197 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_EDP_NAME,
198 strlen(OIC_JSON_EDP_NAME));
199 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Encode EDP String.");
200 cborEncoderResult = cbor_encode_boolean(&pconfMap, pconf->edp);
201 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert PconfEDP value");
203 //PRM type -- Not Mandatory
204 if(pconf->prmLen > 0)
207 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PRM_NAME,
208 strlen(OIC_JSON_PRM_NAME));
209 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM NAME");
210 cborEncoderResult = cbor_encoder_create_array(&pconfMap, &prm, pconf->prmLen);
211 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM value");
213 for (size_t i = 0; i < pconf->prmLen; i++)
215 cborEncoderResult = cbor_encode_int(&prm, pconf->prm[i]);
216 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM Array");
218 cborEncoderResult = cbor_encoder_close_container(&pconfMap, &prm);
219 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close encode array");
223 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PIN_NAME,
224 strlen(OIC_JSON_PIN_NAME));
225 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create OIC_JSON_PIN_NAME");
226 cborEncoderResult = cbor_encode_byte_string(&pconfMap, pconf->pin.val, sizeof(pconf->pin.val));
227 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to convert pin value");
232 OicSecPdAcl_t *pdacl = pconf->pdacls;
233 CborEncoder pdAclArray;
234 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDACL_NAME,
235 strlen(OIC_JSON_PDACL_NAME));
236 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create OIC_JSON_PDACL_NAME");
237 cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pdAclArray,
238 OicPdAclSize(pconf->pdacls));
239 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to creeate _pdacl array");
243 CborEncoder pdAclMap;
244 // PDACL Map size - Number of mandatory items
245 uint8_t aclMapSize = 2;
247 if (pdacl->prdRecrLen)
251 if (pdacl->recurrences)
256 cborEncoderResult = cbor_encoder_create_map(&pdAclArray, &pdAclMap, aclMapSize);
257 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to creeate _pdacl array");
259 // Resources -- Mandatory
260 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RESOURCES_NAME,
261 strlen(OIC_JSON_RESOURCES_NAME));
262 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode resource result");
264 CborEncoder resources;
265 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &resources,
266 pdacl->resourcesLen);
267 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create resource array");
269 for (size_t i = 0; i < pdacl->resourcesLen; i++)
272 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap,
273 PCONF_RESOURCE_MAP_SIZE);
274 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
276 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
277 strlen(OIC_JSON_HREF_NAME));
278 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
279 cborEncoderResult = cbor_encode_text_string(&rMap, pdacl->resources[i],
280 strlen(pdacl->resources[i]));
281 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
283 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
284 strlen(OIC_JSON_REL_NAME));
285 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
287 // TODO : Need to assign real value of REL
288 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
289 strlen(OIC_JSON_EMPTY_STRING));
290 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
292 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
293 strlen(OIC_JSON_RT_NAME));
294 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
296 // TODO : Need to assign real value of RT
297 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
298 strlen(OIC_JSON_EMPTY_STRING));
299 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
301 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
302 strlen(OIC_JSON_IF_NAME));
303 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
305 // TODO : Need to assign real value of IF
306 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
307 strlen(OIC_JSON_EMPTY_STRING));
308 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
310 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
311 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
314 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &resources);
315 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close resource array");
317 // Permissions -- Mandatory
318 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERMISSION_NAME,
319 strlen(OIC_JSON_PERMISSION_NAME));
320 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create permition string");
321 cborEncoderResult = cbor_encode_int(&pdAclMap, pdacl->permission);
322 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode permition calue");
324 // Period -- Not Mandatory
328 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERIODS_NAME,
329 strlen(OIC_JSON_PERIODS_NAME));
330 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period value");
331 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &period,
333 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
335 for (size_t i = 0; i < pdacl->prdRecrLen; i++)
337 cborEncoderResult = cbor_encode_text_string(&period, pdacl->periods[i],
338 strlen(pdacl->periods[i]));
339 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period");
341 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &period);
342 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to close period array");
345 // Period -- Not Mandatory
346 if(0 != pdacl->prdRecrLen && pdacl->recurrences)
348 CborEncoder recurrences;
349 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RECURRENCES_NAME,
350 strlen(OIC_JSON_RECURRENCES_NAME));
351 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to encode recurrences");
352 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &recurrences,
354 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create rec array");
356 for (size_t i = 0; i < pdacl->prdRecrLen; i++)
358 cborEncoderResult = cbor_encode_text_string(&recurrences,
359 pdacl->recurrences[i], strlen(pdacl->recurrences[i]));
360 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode recurrences");
362 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &recurrences);
363 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close rec array");
365 cborEncoderResult = cbor_encoder_close_container(&pdAclArray, &pdAclMap);
366 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl map");
371 cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pdAclArray);
372 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl array");
376 //There may not be paired devices if it did not pairing before
377 if (pconf->pddevs && 0 < pconf->pddevLen)
380 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDDEV_LIST_NAME,
381 strlen(OIC_JSON_PDDEV_LIST_NAME));
382 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode pddev");
383 cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pddev, pconf->pddevLen);
384 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
386 for (size_t i = 0; i < pconf->pddevLen; i++)
388 char *pddevId = NULL;
389 ret = ConvertUuidToStr(&pconf->pddevs[i], &pddevId);
390 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
391 cborEncoderResult = cbor_encode_text_string(&pddev, pddevId, strlen(pddevId));
392 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding pddev Id Value.");
395 cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pddev);
396 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pddev array");
399 //DeviceId -- Mandatory
400 //There may not be devicd id if caller is provisoning tool
401 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_DEVICE_ID_NAME,
402 strlen(OIC_JSON_DEVICE_ID_NAME));
403 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode device id");
405 char *deviceId = NULL;
406 ret = ConvertUuidToStr(&pconf->deviceID, &deviceId);
407 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
408 cborEncoderResult = cbor_encode_text_string(&pconfMap, deviceId, strlen(deviceId));
409 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode deviceID value");
413 //ROwner -- Mandatory
416 cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_ROWNERID_NAME,
417 strlen(OIC_JSON_ROWNERID_NAME));
418 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rowner string");
419 ret = ConvertUuidToStr(&pconf->rownerID, &rowner);
420 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
421 cborEncoderResult = cbor_encode_text_string(&pconfMap, rowner, strlen(rowner));
422 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rwoner value");
426 cborEncoderResult = cbor_encoder_close_container(&encoder, &pconfMap);
427 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pconfMap");
429 *size = cbor_encoder_get_buffer_size(&encoder, outPayload);
430 *payload = outPayload;
433 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
435 // reallocate and try again!
437 // Since the allocated initial memory failed, double the memory.
438 cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
439 cborEncoderResult = CborNoError;
440 ret = PconfToCBORPayload(pconf, payload, &cborLen);
443 if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
449 ret = OC_STACK_ERROR;
454 OCStackResult CBORPayloadToPconf(const uint8_t *cborPayload, size_t size, OicSecPconf_t **secPconf)
456 if (NULL == cborPayload || NULL == secPconf || NULL != *secPconf || 0 == size)
458 return OC_STACK_INVALID_PARAM;
460 OCStackResult ret = OC_STACK_ERROR;
462 CborValue pconfCbor = { .parser = NULL };
463 CborParser parser = { .end = NULL };
464 CborError cborFindResult = CborNoError;
466 cbor_parser_init(cborPayload, size, 0, &parser, &pconfCbor);
467 CborValue pconfMap = { .parser = NULL } ;
468 OicSecPconf_t *pconf = NULL;
469 cborFindResult = cbor_value_enter_container(&pconfCbor, &pconfMap);
470 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter map");
471 pconf = (OicSecPconf_t *)OICCalloc(1, sizeof(*pconf));
472 VERIFY_NON_NULL(TAG, pconf, ERROR);
473 while (cbor_value_is_valid(&pconfMap))
477 CborType type = cbor_value_get_type(&pconfMap);
478 if (type == CborTextStringType && cbor_value_is_text_string(&pconfMap))
480 cborFindResult = cbor_value_dup_text_string(&pconfMap, &name, &len, NULL);
481 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
482 cborFindResult = cbor_value_advance(&pconfMap);
483 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
489 if(0 == strcmp(OIC_JSON_EDP_NAME, name) && cbor_value_is_boolean(&pconfMap))
491 cborFindResult = cbor_value_get_boolean(&pconfMap, &pconf->edp);
492 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
494 if (0 == strcmp(OIC_JSON_PRM_NAME, name))
497 CborValue prm = { .parser = NULL };
498 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->prmLen);
499 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
500 VERIFY_SUCCESS(TAG, pconf->prmLen != 0, ERROR);
502 pconf->prm = (OicSecPrm_t *)OICCalloc(pconf->prmLen, sizeof(OicSecPrm_t));
503 VERIFY_NON_NULL(TAG, pconf->prm, ERROR);
504 cborFindResult = cbor_value_enter_container(&pconfMap, &prm);
505 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to eneter array");
507 while (cbor_value_is_valid(&prm) && cbor_value_is_integer(&prm))
511 cborFindResult = cbor_value_get_int(&prm, &prm_val);
512 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
513 pconf->prm[i++] = (OicSecPrm_t)prm_val;
514 cborFindResult = cbor_value_advance(&prm);
515 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
519 if (0 == strcmp(OIC_JSON_PIN_NAME, name) && cbor_value_is_byte_string(&pconfMap))
522 cborFindResult = cbor_value_dup_byte_string(&pconfMap, &pin, &len, NULL);
523 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
524 memcpy(pconf->pin.val, pin, len);
529 if (0 == strcmp(OIC_JSON_PDACL_NAME, name))
531 CborValue pdAclArray = { .parser = NULL};
532 OicSecPdAcl_t *headPdacl = NULL;
534 cborFindResult = cbor_value_enter_container(&pconfMap, &pdAclArray);
535 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
537 while (cbor_value_is_valid(&pdAclArray))
539 CborValue pdAclMap = { .parser = NULL};
540 OicSecPdAcl_t *pdacl = (OicSecPdAcl_t *) OICCalloc(1, sizeof(OicSecPdAcl_t));
541 VERIFY_NON_NULL(TAG, pdacl, ERROR);
543 cborFindResult = cbor_value_enter_container(&pdAclArray, &pdAclMap);
544 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
546 while (cbor_value_is_valid(&pdAclMap))
550 CborType type = cbor_value_get_type(&pdAclMap);
551 if (type == CborTextStringType && cbor_value_is_text_string(&pdAclMap))
553 cborFindResult = cbor_value_dup_text_string(&pdAclMap, &name,
555 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
556 cborFindResult = cbor_value_advance(&pdAclMap);
557 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
561 // Resources -- Mandatory
562 if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0 && cbor_value_is_array(&pdAclMap))
565 CborValue resources = { .parser = NULL };
566 cborFindResult = cbor_value_get_array_length(&pdAclMap,
567 &pdacl->resourcesLen);
568 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
569 cborFindResult = cbor_value_enter_container(&pdAclMap, &resources);
570 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
571 pdacl->resources = (char **) OICCalloc(pdacl->resourcesLen,
573 VERIFY_NON_NULL(TAG, pdacl->resources, ERROR);
575 while (cbor_value_is_valid(&resources))
577 CborValue rMap = { .parser = NULL };
578 cborFindResult = cbor_value_enter_container(&resources, &rMap);
579 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
581 while(cbor_value_is_valid(&rMap) && cbor_value_is_text_string(&rMap))
583 char *rMapName = NULL;
584 size_t rMapNameLen = 0;
585 cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
586 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
587 cborFindResult = cbor_value_advance(&rMap);
588 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
591 if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
593 // TODO : Need to check data structure of OicSecPdAcl_t based on RAML spec.
594 cborFindResult = cbor_value_dup_text_string(&rMap, &pdacl->resources[i++], &len, NULL);
595 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
599 if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
601 // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
602 char *relData = NULL;
603 cborFindResult = cbor_value_dup_text_string(&rMap, &relData, &len, NULL);
604 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
609 if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
611 // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
613 cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
614 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
619 if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
621 // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
623 cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
624 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
628 if (cbor_value_is_valid(&rMap))
630 cborFindResult = cbor_value_advance(&rMap);
631 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
636 if (cbor_value_is_valid(&resources))
638 cborFindResult = cbor_value_advance(&resources);
639 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
644 // Permissions -- Mandatory
645 if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0 && cbor_value_is_unsigned_integer(&pdAclMap))
647 uint64_t permission = 0;
648 cborFindResult = cbor_value_get_uint64(&pdAclMap, &permission);
649 pdacl->permission = (uint16_t)permission;
650 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
653 // Period -- Not mandatory
654 if (strcmp(name, OIC_JSON_PERIODS_NAME) == 0 && cbor_value_is_array(&pdAclMap))
657 CborValue period = { .parser = NULL };
658 cborFindResult = cbor_value_get_array_length(&pdAclMap,
660 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
661 cborFindResult = cbor_value_enter_container(&pdAclMap, &period);
662 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
663 pdacl->periods = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
664 VERIFY_NON_NULL(TAG, pdacl->periods, ERROR);
666 while (cbor_value_is_text_string(&period) && cbor_value_is_text_string(&period))
668 cborFindResult = cbor_value_dup_text_string(&period,
669 &pdacl->periods[i++], &len, NULL);
670 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
671 cborFindResult = cbor_value_advance(&period);
672 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
677 // Recurrence -- Not mandatory
678 if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0 && cbor_value_is_array(&pdAclMap))
681 CborValue recurrences = { .parser = NULL };
682 cborFindResult = cbor_value_get_array_length(&pdAclMap, &pdacl->prdRecrLen);
683 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
684 cborFindResult = cbor_value_enter_container(&pdAclMap, &recurrences);
685 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
686 pdacl->recurrences = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
687 VERIFY_NON_NULL(TAG, pdacl->recurrences, ERROR);
689 while (cbor_value_is_text_string(&recurrences) && cbor_value_is_text_string(&recurrences))
691 cborFindResult = cbor_value_dup_text_string(&recurrences,
692 &pdacl->recurrences[i++], &len, NULL);
693 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
694 cborFindResult = cbor_value_advance(&recurrences);
695 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
698 if (type != CborMapType && cbor_value_is_valid(&pdAclMap))
700 cborFindResult = cbor_value_advance(&pdAclMap);
701 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
704 if (cbor_value_is_valid(&pdAclArray))
706 cborFindResult = cbor_value_advance(&pdAclArray);
707 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
713 if (headPdacl == NULL)
719 OicSecPdAcl_t *temp = headPdacl;
727 pconf->pdacls = headPdacl;
731 if (strcmp(name, OIC_JSON_PDDEV_LIST_NAME) == 0 && cbor_value_is_array(&pconfMap))
734 CborValue pddevs = { .parser = NULL };
735 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->pddevLen);
736 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
737 cborFindResult = cbor_value_enter_container(&pconfMap, &pddevs);
738 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
740 pconf->pddevs = (OicUuid_t *)OICMalloc(pconf->pddevLen * sizeof(OicUuid_t));
741 VERIFY_NON_NULL(TAG, pconf->pddevs, ERROR);
742 while (cbor_value_is_valid(&pddevs) && cbor_value_is_text_string(&pddevs))
745 cborFindResult = cbor_value_dup_text_string(&pddevs, &pddev, &len, NULL);
746 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
747 cborFindResult = cbor_value_advance(&pddevs);
748 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
749 ret = ConvertStrToUuid(pddev, &pconf->pddevs[i++]);
750 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
755 //Mandatory - Device Id
756 if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name) && cbor_value_is_text_string(&pconfMap))
758 char *deviceId = NULL;
759 cborFindResult = cbor_value_dup_text_string(&pconfMap, &deviceId, &len, NULL);
760 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get deviceID");
761 ret = ConvertStrToUuid(deviceId, &pconf->deviceID);
762 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
766 // ROwner -- Mandatory
767 if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name) && cbor_value_is_text_string(&pconfMap))
770 cborFindResult = cbor_value_dup_text_string(&pconfMap, &rowner, &len, NULL);
771 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get rowner");
772 ret = ConvertStrToUuid(rowner, &pconf->rownerID);
773 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
777 if (CborMapType != type && cbor_value_is_valid(&pconfMap))
779 cborFindResult = cbor_value_advance(&pconfMap);
780 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
788 if (CborNoError != cborFindResult)
790 OIC_LOG (ERROR, TAG, "CBORPayloadToPconf failed");
791 DeletePconfBinData(pconf);
794 ret = OC_STACK_ERROR;
799 static bool UpdatePersistentStorage(const OicSecPconf_t * pconf)
803 // Convert PCONF data into Cborpayload for update to persistent storage
804 uint8_t *payload = NULL;
806 if (OC_STACK_OK == PconfToCBORPayload(pconf, &payload, &size) && NULL !=payload)
808 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, payload, size))
817 static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest * ehRequest)
819 uint8_t* payload = NULL;
821 OCEntityHandlerResult ehRet = OC_EH_OK;
824 memset(&pconf, 0, sizeof(OicSecPconf_t));
826 OIC_LOG (DEBUG, TAG, "Pconf EntityHandle processing GET request");
828 if (true == GetDoxmResourceData()->dpc)
830 //Making response elements for Get request
831 if( (true == gPconf->edp) &&
832 (gPconf->prm && 0 < gPconf->prmLen) &&
833 (0 < strlen((const char*)gPconf->deviceID.id)) &&
834 (0 < strlen((const char*)gPconf->rownerID.id)))
837 pconf.prm = gPconf->prm;
838 pconf.prmLen = gPconf->prmLen;
839 memcpy(&pconf.deviceID, &gPconf->deviceID, sizeof(OicUuid_t));
840 memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
841 OIC_LOG (DEBUG, TAG, "PCONF - direct pairing enabled");
843 else if (false == gPconf->edp)
846 memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
847 OIC_LOG (DEBUG, TAG, "PCONF - direct pairing disable");
852 OIC_LOG (DEBUG, TAG, "PCONF - error");
857 OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
861 if (OC_STACK_OK != PconfToCBORPayload(gPconf, &payload, &size))
866 if(OC_EH_OK == ehRet)
868 ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
877 // Send response payload to request originator
878 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
881 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfGetRequest");
883 OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
889 static OCEntityHandlerResult HandlePconfPostRequest (const OCEntityHandlerRequest * ehRequest)
891 OCEntityHandlerResult ehRet = OC_EH_OK;
892 OCStackResult res=OC_STACK_OK;
893 OicSecPconf_t* newPconf = NULL;
895 if (NULL != GetDoxmResourceData() && true == GetDoxmResourceData()->dpc)
897 // Convert CBOR PCONF data into binary. This will also validate the PCONF data received.
898 uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
899 size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
902 res = CBORPayloadToPconf(payload, size, &newPconf);
907 OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
911 if (newPconf && res == OC_STACK_OK)
913 // Check if valid Post request
914 if ((true == newPconf->edp) && (0 < newPconf->prmLen) &&
915 DP_PIN_LENGTH == sizeof(newPconf->pin.val))
917 OicSecPrm_t *oldPrm = gPconf->prm;
918 OicSecPdAcl_t *oldPdacl = gPconf->pdacls;
920 // Update local PCONF with new PCONF
922 memcpy(&gPconf->pin, &newPconf->pin, sizeof(OicDpPin_t));
923 gPconf->prm = newPconf->prm;
924 gPconf->prmLen = newPconf->prmLen;
925 gPconf->pdacls = newPconf->pdacls;
926 memcpy(&gPconf->rownerID, &newPconf->rownerID, sizeof(OicUuid_t));
928 // to delete old value(prm, pdacl)
929 newPconf->prm = oldPrm;
930 newPconf->pdacls = oldPdacl;
932 else if (false == newPconf->edp)
942 if(OC_EH_ERROR != ehRet && true == UpdatePersistentStorage(gPconf))
944 ehRet = OC_EH_CHANGED;
947 DeletePconfBinData(newPconf);
954 // Send payload to request originator
955 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
958 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfPostRequest");
961 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
966 * This internal method is the entity handler for PCONF resources and
967 * will handle REST request (POST) for them.
969 OCEntityHandlerResult PconfEntityHandler (OCEntityHandlerFlag flag,
970 OCEntityHandlerRequest * ehRequest,
971 void* callbackParameter)
973 OIC_LOG(DEBUG, TAG, "Received request PconfEntityHandler");
974 (void)callbackParameter;
975 OCEntityHandlerResult ehRet = OC_EH_ERROR;
982 if (flag & OC_REQUEST_FLAG)
984 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
985 switch (ehRequest->method)
988 ehRet = HandlePconfGetRequest(ehRequest);
992 ehRet = HandlePconfPostRequest(ehRequest);
1000 SendSRMResponse(ehRequest, ehRet, NULL, 0);
1008 * This internal method is used to create '/oic/sec/pconf' resource.
1010 OCStackResult CreatePconfResource()
1014 ret = OCCreateResource(&gPconfHandle,
1015 OIC_RSRC_TYPE_SEC_PCONF,
1016 OC_RSRVD_INTERFACE_DEFAULT,
1020 OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
1022 if (OC_STACK_OK != ret)
1024 OIC_LOG (ERROR, TAG, "Unable to instantiate PCONF resource");
1025 DeInitPconfResource();
1031 * Get the default value.
1032 * @retval the gDefaultPconf pointer;
1034 static OicSecPconf_t* GetPconfDefault()
1036 OIC_LOG (DEBUG, TAG, "GetPconfDefault");
1038 return &gDefaultPconf;
1042 * This method is used by SRM to retrieve PCONF resource data..
1044 * @retval reference to @ref OicSecPconf_t, binary format of Pconf resource data
1046 const OicSecPconf_t* GetPconfResourceData()
1052 * Initialize PCONF resource by loading data from persistent storage.
1054 * @retval OC_STACK_OK for Success, otherwise some error value
1056 OCStackResult InitPconfResource()
1058 OCStackResult ret = OC_STACK_ERROR;
1060 uint8_t *data = NULL;
1063 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PCONF_NAME, &data, &size);
1064 // If database read failed
1065 if (ret != OC_STACK_OK)
1067 OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
1071 CBORPayloadToPconf(data, size, &gPconf);
1074 if (!data || !gPconf)
1076 gPconf = GetPconfDefault();
1078 // device id from doxm
1079 OicUuid_t deviceId = {.id = {0}};
1080 OCStackResult ret = GetDoxmDeviceID( &deviceId);
1081 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1082 memcpy(&gPconf->deviceID, &deviceId, sizeof(OicUuid_t));
1084 VERIFY_NON_NULL(TAG, gPconf, ERROR);
1086 // Instantiate 'oic.sec.pconf'
1087 ret = CreatePconfResource();
1090 if (OC_STACK_OK != ret)
1092 DeInitPconfResource();
1099 * Perform cleanup for PCONF resources.
1102 * OC_STACK_OK - no error
1103 * OC_STACK_ERROR - stack process error
1106 OCStackResult DeInitPconfResource()
1108 OCStackResult ret = OCDeleteResource(gPconfHandle);
1109 if(gPconf!= &gDefaultPconf)
1111 DeletePconfBinData(gPconf);
1115 if(OC_STACK_OK == ret)
1121 return OC_STACK_ERROR;
1126 * This method might be used to add a paired device id after direct-pairing process complete.
1128 * @param pdeviceId ID of the paired device.
1130 * @retval OC_STACK_OK for Success, otherwise some error value
1132 OCStackResult AddPairedDevice(OicUuid_t *pdeviceId)
1134 if (!gPconf || !pdeviceId)
1136 return OC_STACK_INVALID_PARAM;
1140 OicUuid_t *prevList = gPconf->pddevs;
1141 gPconf->pddevs = (OicUuid_t *)OICCalloc(gPconf->pddevLen+1, sizeof(OicUuid_t));
1144 return OC_STACK_NO_MEMORY;
1146 for (size_t i=0; i<gPconf->pddevLen; i++)
1148 memcpy(&gPconf->pddevs[i], &prevList[i], sizeof(OicUuid_t));
1151 // add new paired device id
1152 memcpy(&gPconf->pddevs[gPconf->pddevLen], pdeviceId, sizeof(OicUuid_t));
1156 if(true != UpdatePersistentStorage(gPconf))
1158 OIC_LOG (ERROR, TAG, "Fail to update pconf resource");
1159 return OC_STACK_ERROR;
1162 OIC_LOG (ERROR, TAG, "Add paired device success");
1167 * This method might be used by PolicyEngine to retrieve PDACL for a Subject.
1169 * @param subjectId ID of the subject for which PDACL is required.
1170 * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
1171 * successive calls for same subjectId.
1173 * @retval reference to @ref OicSecPdAcl_t if PDACL is found, else NULL
1175 const OicSecPdAcl_t* GetPdAclData(const OicUuid_t* subjectId, OicSecPdAcl_t **savePtr)
1177 OicSecPdAcl_t *pdacl = NULL;
1179 if ( NULL == subjectId)
1185 * savePtr MUST point to NULL if this is the 'first' call to retrieve PDACL for
1188 if (NULL == *savePtr)
1190 pdacl = gPconf->pdacls;
1192 // Find if 'subjectID' is in paired device list.
1193 for(size_t i=0; i<gPconf->pddevLen; i++)
1195 if (memcmp(&(gPconf->pddevs[i]), subjectId, sizeof(OicUuid_t)) == 0)
1204 OicSecPdAcl_t *temp = NULL;
1207 * If this is a 'successive' call, search for location pointed by
1208 * savePtr and assign 'begin' to the next PDACL after it in the linked
1209 * list and start searching from there.
1211 LL_FOREACH(gPconf->pdacls, temp)
1213 if (temp == *savePtr)
1222 // Cleanup in case no PDACL is found
1228 * This method return whether device is paired or not.
1230 * @param pdeviceId Target device ID to find in paired list.
1231 * @retval ture if device is already paired, else false
1233 bool IsPairedDevice(const OicUuid_t* pdeviceId)
1235 // Find if 'pdeviceId' is in paired device list.
1236 for(size_t i=0; i<gPconf->pddevLen; i++)
1238 if (memcmp(&(gPconf->pddevs[i]), pdeviceId, sizeof(OicUuid_t)) == 0)
1246 OCStackResult SetPconfRownerId(const OicUuid_t* newROwner)
1248 OCStackResult ret = OC_STACK_ERROR;
1249 uint8_t *cborPayload = NULL;
1251 OicUuid_t prevId = {.id={0}};
1253 if(NULL == newROwner)
1255 ret = OC_STACK_INVALID_PARAM;
1259 ret = OC_STACK_NO_RESOURCE;
1262 if(newROwner && gPconf)
1264 memcpy(prevId.id, gPconf->rownerID.id, sizeof(prevId.id));
1265 memcpy(gPconf->rownerID.id, newROwner->id, sizeof(newROwner->id));
1267 ret = PconfToCBORPayload(gPconf, &cborPayload, &size);
1268 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1270 ret = UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, cborPayload, size);
1271 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1273 OICFree(cborPayload);
1279 OICFree(cborPayload);
1280 memcpy(gPconf->rownerID.id, prevId.id, sizeof(prevId.id));
1284 OCStackResult GetPconfRownerId(OicUuid_t *rowneruuid)
1286 OCStackResult retVal = OC_STACK_ERROR;
1289 *rowneruuid = gPconf->rownerID;
1290 retVal = OC_STACK_OK;