Cloud Client
[platform/upstream/iotivity.git] / resource / csdk / security / src / aclresource.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH 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 "iotivity_config.h"
22 #ifdef HAVE_STRING_H
23 #include <string.h>
24 #elif defined(HAVE_STRINGS_H)
25 #include <strings.h>
26 #endif
27 #include <stdlib.h>
28
29 #include "utlist.h"
30 #include "ocstack.h"
31 #include "octypes.h"
32 #include "ocserverrequest.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "ocrandom.h"
36 #include "ocpayload.h"
37 #include "utlist.h"
38 #include "payload_logging.h"
39 #include "srmresourcestrings.h"
40 #include "aclresource.h"
41 #include "doxmresource.h"
42 #include "resourcemanager.h"
43 #include "srmutility.h"
44 #include "psinterface.h"
45 #include "ocpayloadcbor.h"
46
47 #include "security_internals.h"
48
49 #define TAG  "SRM-ACL"
50 #define NUMBER_OF_SEC_PROV_RSCS 4
51 #define NUMBER_OF_DEFAULT_SEC_RSCS 2
52 #define STRING_UUID_SIZE (UUID_LENGTH * 2 + 5)
53
54 static const uint8_t ACL_MAP_SIZE = 4;
55 static const uint8_t ACL_ACLIST_MAP_SIZE = 1;
56 static const uint8_t ACL_ACES_MAP_SIZE = 3;
57 static const uint8_t ACL_RESOURCE_MAP_SIZE = 3;
58
59
60 // CborSize is the default cbor payload size being used.
61 static const uint16_t CBOR_SIZE = 2048;
62
63 static OicSecAcl_t *gAcl = NULL;
64 static OCResourceHandle gAclHandle = NULL;
65
66 /**
67  * This function frees OicSecRsrc_t object's fields and object itself.
68  */
69 static void FreeRsrc(OicSecRsrc_t *rsrc)
70 {
71     //Clean each member of resource
72     OICFree(rsrc->href);
73     OICFree(rsrc->rel);
74     //Clean "rt"
75     if(0 < rsrc->typeLen && rsrc->types)
76     {
77         for(size_t i = 0; i < rsrc->typeLen; i++)
78         {
79             OICFree(rsrc->types[i]);
80         }
81         OICFree(rsrc->types);
82         rsrc->types = NULL;
83     }
84     //Clean "if"
85     if(0 < rsrc->interfaceLen && rsrc->interfaces)
86     {
87         for(size_t i = 0; i < rsrc->interfaceLen; i++)
88         {
89             OICFree(rsrc->interfaces[i]);
90         }
91         OICFree(rsrc->interfaces);
92         rsrc->interfaces = NULL;
93     }
94     OICFree(rsrc);
95     rsrc = NULL;
96 }
97
98 /**
99  * This function frees OicSecAcl_t object's fields and object itself.
100  */
101 static void FreeACE(OicSecAce_t *ace)
102 {
103     if (NULL == ace)
104     {
105         OIC_LOG(ERROR, TAG, "Invalid Parameter");
106         return;
107     }
108
109     //Clean Resources
110     OicSecRsrc_t* rsrc = NULL;
111     OicSecRsrc_t* tmpRsrc = NULL;
112     LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
113     {
114         LL_DELETE(ace->resources, rsrc);
115         FreeRsrc(rsrc);
116     }
117
118     //Clean Validities
119     OicSecValidity_t *validity = NULL;
120     OicSecValidity_t *tmpValidity = NULL;
121     LL_FOREACH_SAFE(ace->validities, validity, tmpValidity)
122     {
123         LL_DELETE(ace->validities, validity);
124
125         //Clean period
126         OICFree(validity->period);
127
128         //Clean recurrence
129         for(size_t i = 0; i < validity->recurrenceLen; i++)
130         {
131             OICFree(validity->recurrences[i]);
132         }
133         OICFree(validity->recurrences);
134         OICFree(validity);
135         validity = NULL;
136     }
137
138     //Clean ACE
139     OICFree(ace);
140     ace = NULL;
141 }
142
143 void DeleteACLList(OicSecAcl_t* acl)
144 {
145     if (acl)
146     {
147         OicSecAce_t *ace = NULL;
148         OicSecAce_t *tmpAce = NULL;
149         LL_FOREACH_SAFE(acl->aces, ace, tmpAce)
150         {
151             LL_DELETE(acl->aces, ace);
152             FreeACE(ace);
153         }
154         acl->aces = NULL;
155         OICFree(acl);
156     }
157 }
158
159 OicSecAce_t* DuplicateACE(const OicSecAce_t* ace)
160 {
161     OicSecAce_t* newAce = NULL;
162     size_t allocateSize = 0;
163
164     if(ace)
165     {
166         newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
167         VERIFY_NON_NULL(TAG, newAce, ERROR);
168
169         //Subject uuid
170         memcpy(&newAce->subjectuuid, &ace->subjectuuid, sizeof(OicUuid_t));
171
172         OicSecRsrc_t* rsrc = NULL;
173         LL_FOREACH(ace->resources, rsrc)
174         {
175             OicSecRsrc_t* newRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
176             VERIFY_NON_NULL(TAG, newRsrc, ERROR);
177             LL_APPEND(newAce->resources, newRsrc);
178
179             //href is mandatory
180             VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
181             allocateSize = strlen(rsrc->href) + 1;
182             newRsrc->href = (char*)OICMalloc(sizeof(char) * allocateSize);
183             VERIFY_NON_NULL(TAG, newRsrc->href, ERROR);
184             OICStrcpy(newRsrc->href, allocateSize, rsrc->href);
185
186             if(rsrc->rel)
187             {
188                 allocateSize = strlen(rsrc->rel) + 1;
189                 newRsrc->rel = (char*)OICMalloc(sizeof(char) * allocateSize);
190                 VERIFY_NON_NULL(TAG, newRsrc->rel, ERROR);
191                 OICStrcpy(newRsrc->rel, allocateSize, rsrc->rel);
192             }
193
194             if(rsrc->types && 0 < rsrc->typeLen)
195             {
196                 newRsrc->typeLen = rsrc->typeLen;
197                 newRsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
198                 VERIFY_NON_NULL(TAG, (newRsrc->types), ERROR);
199                 for(size_t i = 0; i < rsrc->typeLen; i++)
200                 {
201                     newRsrc->types[i] = OICStrdup(rsrc->types[i]);
202                     VERIFY_NON_NULL(TAG, (newRsrc->types[i]), ERROR);
203                 }
204             }
205
206             if(rsrc->interfaces && 0 < rsrc->interfaceLen)
207             {
208                 newRsrc->interfaceLen = rsrc->interfaceLen;
209                 newRsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
210                 VERIFY_NON_NULL(TAG, (newRsrc->interfaces), ERROR);
211                 for(size_t i = 0; i < rsrc->interfaceLen; i++)
212                 {
213                     newRsrc->interfaces[i] = OICStrdup(rsrc->interfaces[i]);
214                     VERIFY_NON_NULL(TAG, (newRsrc->interfaces[i]), ERROR);
215                 }
216             }
217         }
218
219         //Permission
220         newAce->permission = ace->permission;
221
222         //Validity
223         if(ace->validities)
224         {
225             OicSecValidity_t* validity = NULL;
226             LL_FOREACH(ace->validities, validity)
227             {
228                 OicSecValidity_t* newValidity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
229                 VERIFY_NON_NULL(TAG, newValidity, ERROR);
230                 LL_APPEND(newAce->validities, newValidity);
231
232                 if(validity->period)
233                 {
234                     allocateSize = strlen(validity->period) + 1;
235                     newValidity->period = (char*)OICMalloc(sizeof(char) * allocateSize);
236                     VERIFY_NON_NULL(TAG, newValidity->period, ERROR);
237                     OICStrcpy(newValidity->period, allocateSize, validity->period);
238                 }
239
240                 if(validity->recurrences && 0 < validity->recurrenceLen)
241                 {
242                     newValidity->recurrenceLen = validity->recurrenceLen;
243
244                     newValidity->recurrences = (char**)OICMalloc(sizeof(char*) * validity->recurrenceLen);
245                     VERIFY_NON_NULL(TAG, newValidity->recurrences, ERROR);
246
247                     for(size_t i = 0; i < validity->recurrenceLen; i++)
248                     {
249                         allocateSize = strlen(validity->recurrences[i]) + 1;
250                         newValidity->recurrences[i] = (char*)OICMalloc(sizeof(char) * allocateSize);
251                         VERIFY_NON_NULL(TAG, (newValidity->recurrences[i]), ERROR);
252                         OICStrcpy(newValidity->recurrences[i], allocateSize, validity->recurrences[i]);
253                     }
254                 }
255             }
256         }
257
258         newAce->next = NULL;
259     }
260
261     return newAce;
262
263 exit:
264     FreeACE(newAce);
265     return NULL;
266 }
267
268 static size_t OicSecAclSize(const OicSecAcl_t *secAcl)
269 {
270     if (!secAcl)
271     {
272         return 0;
273     }
274     OicSecAce_t *ace= (OicSecAce_t *)secAcl->aces;
275     size_t size = 0;
276     while (ace)
277     {
278        size++;
279        ace = ace->next;
280     }
281     return size;
282 }
283
284 OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, size_t *size)
285 {
286      if (NULL == secAcl || NULL == payload || NULL != *payload || NULL == size)
287     {
288         return OC_STACK_INVALID_PARAM;
289     }
290
291     OCStackResult ret = OC_STACK_ERROR;
292     CborError cborEncoderResult = CborNoError;
293     OicSecAcl_t *acl = (OicSecAcl_t *)secAcl;
294     OicSecAce_t* ace = NULL;
295     CborEncoder encoder;
296     CborEncoder aclMap;
297     CborEncoder aclListMap;
298     CborEncoder acesArray;
299     uint8_t *outPayload = NULL;
300     size_t cborLen = *size;
301     *size = 0;
302     *payload = NULL;
303
304     if (cborLen == 0)
305     {
306         cborLen = CBOR_SIZE;
307     }
308
309     outPayload = (uint8_t *)OICCalloc(1, cborLen);
310     VERIFY_NON_NULL(TAG, outPayload, ERROR);
311     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
312
313     // Create ACL Map (aclist, rownerid)
314     cborEncoderResult = cbor_encoder_create_map(&encoder, &aclMap, ACL_MAP_SIZE);
315     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACL Map.");
316
317     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ACLIST_NAME,
318         strlen(OIC_JSON_ACLIST_NAME));
319     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding aclist Name Tag.");
320
321     // Create ACLIST Map (aces)
322     cborEncoderResult = cbor_encoder_create_map(&aclMap, &aclListMap, ACL_ACLIST_MAP_SIZE);
323     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACLIST Map.");
324
325     cborEncoderResult = cbor_encode_text_string(&aclListMap, OIC_JSON_ACES_NAME,
326         strlen(OIC_JSON_ACES_NAME));
327     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACES Name Tag.");
328
329     // Create ACES Array
330     cborEncoderResult = cbor_encoder_create_array(&aclListMap, &acesArray, OicSecAclSize(secAcl));
331     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Array.");
332
333     ace = NULL;
334     LL_FOREACH (acl->aces, ace)
335     {
336         CborEncoder oicSecAclMap;
337         // ACL Map size - Number of mandatory items
338         uint8_t aclMapSize = ACL_ACES_MAP_SIZE;
339         size_t inLen = 0;
340
341         OicSecValidity_t* validityElts = ace->validities;
342         while(validityElts)
343         {
344             if(validityElts->period)
345             {
346                 aclMapSize++;
347             }
348             if(validityElts->recurrences)
349             {
350                 aclMapSize++;
351             }
352         }
353
354         cborEncoderResult = cbor_encoder_create_map(&acesArray, &oicSecAclMap, aclMapSize);
355         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Map");
356
357         // Subject -- Mandatory
358         cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_SUBJECTID_NAME,
359             strlen(OIC_JSON_SUBJECTID_NAME));
360         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Name Tag.");
361         inLen = (memcmp(&(ace->subjectuuid), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
362             WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
363         if(inLen == WILDCARD_SUBJECT_ID_LEN)
364         {
365             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, WILDCARD_RESOURCE_URI,
366                 strlen(WILDCARD_RESOURCE_URI));
367             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
368         }
369         else
370         {
371             char *subject = NULL;
372             ret = ConvertUuidToStr(&ace->subjectuuid, &subject);
373             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
374             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, subject, strlen(subject));
375             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject UUID Value.");
376             OICFree(subject);
377         }
378
379         // Resources
380         {
381             CborEncoder resources;
382             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_RESOURCES_NAME,
383                 strlen(OIC_JSON_RESOURCES_NAME));
384             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Tag.");
385
386             size_t rsrcLen = 0;
387             OicSecRsrc_t* rsrcElts = NULL;
388             LL_FOREACH(ace->resources, rsrcElts)
389             {
390                 rsrcLen++;
391             }
392
393             cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &resources, rsrcLen);
394             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Array.");
395
396             OicSecRsrc_t* rsrc = NULL;
397             LL_FOREACH(ace->resources, rsrc)
398             {
399
400                 CborEncoder rMap;
401                 size_t rsrcMapSize = ACL_RESOURCE_MAP_SIZE;
402                 if(rsrc->rel)
403                 {
404                     rsrcMapSize++;
405                 }
406
407                 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, rsrcMapSize);
408                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
409
410                 //href -- Mandatory
411                 VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
412                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
413                         strlen(OIC_JSON_HREF_NAME));
414                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
415                 cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->href, strlen(rsrc->href));
416                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
417
418                 //resource type -- Mandatory
419                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
420                         strlen(OIC_JSON_RT_NAME));
421                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
422
423                 CborEncoder resourceTypes;
424                 cborEncoderResult = cbor_encoder_create_array(&rMap, &resourceTypes, rsrc->typeLen);
425                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Array.");
426                 for(size_t i = 0; i < rsrc->typeLen; i++)
427                 {
428                     cborEncoderResult = cbor_encode_text_string(&resourceTypes, rsrc->types[i], strlen(rsrc->types[i]));
429                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
430                 }
431                 cborEncoderResult = cbor_encoder_close_container(&rMap, &resourceTypes);
432                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing resourceTypes.");
433
434                 //interface -- Mandatory
435                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
436                         strlen(OIC_JSON_IF_NAME));
437                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
438
439                 CborEncoder interfaces;
440                 cborEncoderResult = cbor_encoder_create_array(&rMap, &interfaces, rsrc->interfaceLen);
441                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Array.");
442                 for(size_t i = 0; i < rsrc->interfaceLen; i++)
443                 {
444                     cborEncoderResult = cbor_encode_text_string(&interfaces, rsrc->interfaces[i], strlen(rsrc->interfaces[i]));
445                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
446                 }
447                 cborEncoderResult = cbor_encoder_close_container(&rMap, &interfaces);
448                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing interfaces.");
449
450                 //rel
451                 if(rsrc->rel)
452                 {
453                     cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
454                             strlen(OIC_JSON_REL_NAME));
455                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
456                     cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->rel, strlen(rsrc->rel));
457                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
458                 }
459
460                 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
461                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
462             }
463             cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &resources);
464             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Name Array.");
465         }
466
467         // Permissions -- Mandatory
468         cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_PERMISSION_NAME,
469             strlen(OIC_JSON_PERMISSION_NAME));
470         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Tag.");
471         cborEncoderResult = cbor_encode_int(&oicSecAclMap, ace->permission);
472         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Value.");
473
474         // TODO: Need to verfication for validity
475         // Validity(Time-interval) -- Not Mandatory
476         if(ace->validities)
477         {
478             size_t validityLen = 0;
479             validityElts = NULL;
480             LL_FOREACH(ace->validities, validityElts)
481             {
482                 validityLen++;
483             }
484
485             CborEncoder validities;
486             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_VALIDITY_NAME,
487                 strlen(OIC_JSON_VALIDITY_NAME));
488             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Tag.");
489             cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &validities, validityLen);
490             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validities Array.");
491
492             //How to add the value w/o "title" using tinycobr...? :(
493
494             validityElts = NULL;
495             LL_FOREACH(ace->validities, validityElts)
496             {
497                  CborEncoder validity;
498                  size_t validitySize = 0;
499                  if(validityElts->period)
500                 {
501                     validitySize++;
502                 }
503                 if(validityElts->recurrences)
504                 {
505                     validitySize++;
506                 }
507
508                 cborEncoderResult = cbor_encoder_create_array(&validities, &validity, validitySize);
509                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Array.");
510
511                 // Period
512                 if (validityElts->period)
513                 {
514                     cborEncoderResult = cbor_encode_text_string(&validity, validityElts->period,
515                         strlen(validityElts->period));
516                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Value.");
517                 }
518
519                 // Recurrence
520                 if (validityElts->recurrences)
521                 {
522                     CborEncoder recurrences;
523                     cborEncoderResult = cbor_encoder_create_array(&validity, &recurrences, validityElts->recurrenceLen);
524                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array.");
525
526                     for (size_t i = 0; i < validityElts->recurrenceLen; i++)
527                     {
528                         cborEncoderResult = cbor_encode_text_string(&recurrences, validityElts->recurrences[i],
529                             strlen(validityElts->recurrences[i]));
530                         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array Value.");
531                     }
532                     cborEncoderResult = cbor_encoder_close_container(&validity, &recurrences);
533                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Recurrence Array");
534                 }
535
536                 cborEncoderResult = cbor_encoder_close_container(&validities, &validity);
537                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validity Array.");
538             }
539
540             cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &validities);
541             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validities Array.");
542         }
543
544         cborEncoderResult = cbor_encoder_close_container(&acesArray, &oicSecAclMap);
545         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Map.");
546     }
547
548     // Close ACES Array
549     cborEncoderResult = cbor_encoder_close_container(&aclListMap, &acesArray);
550     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Array.");
551
552     // Close ACLIST Map
553     cborEncoderResult = cbor_encoder_close_container(&aclMap, &aclListMap);
554     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACLIST Map.");
555
556     // Rownerid
557     {
558         char *rowner = NULL;
559         cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ROWNERID_NAME,
560             strlen(OIC_JSON_ROWNERID_NAME));
561         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
562         ret = ConvertUuidToStr(&secAcl->rownerID, &rowner);
563         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
564         cborEncoderResult = cbor_encode_text_string(&aclMap, rowner, strlen(rowner));
565         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
566         OICFree(rowner);
567     }
568
569     //RT -- Mandatory
570     CborEncoder rtArray;
571     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_RT_NAME,
572             strlen(OIC_JSON_RT_NAME));
573     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
574     cborEncoderResult = cbor_encoder_create_array(&aclMap, &rtArray, 1);
575     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
576     for (size_t i = 0; i < 1; i++)
577     {
578         cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_ACL,
579                 strlen(OIC_RSRC_TYPE_SEC_ACL));
580         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
581     }
582     cborEncoderResult = cbor_encoder_close_container(&aclMap, &rtArray);
583     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
584
585     //IF-- Mandatory
586     CborEncoder ifArray;
587     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_IF_NAME,
588              strlen(OIC_JSON_IF_NAME));
589     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
590     cborEncoderResult = cbor_encoder_create_array(&aclMap, &ifArray, 1);
591     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
592     for (size_t i = 0; i < 1; i++)
593     {
594         cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
595                 strlen(OC_RSRVD_INTERFACE_DEFAULT));
596         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
597     }
598     cborEncoderResult = cbor_encoder_close_container(&aclMap, &ifArray);
599     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
600
601     // Close ACL Map
602     cborEncoderResult = cbor_encoder_close_container(&encoder, &aclMap);
603     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACL Map.");
604
605     if (CborNoError == cborEncoderResult)
606     {
607         OIC_LOG(DEBUG, TAG, "AclToCBORPayload Successed");
608         *size = encoder.ptr - outPayload;
609         *payload = outPayload;
610         ret = OC_STACK_OK;
611     }
612 exit:
613     if (CborErrorOutOfMemory == cborEncoderResult)
614     {
615         OIC_LOG(DEBUG, TAG, "AclToCBORPayload:CborErrorOutOfMemory : retry with more memory");
616
617         // reallocate and try again!
618         OICFree(outPayload);
619         // Since the allocated initial memory failed, double the memory.
620         cborLen += encoder.ptr - encoder.end;
621         cborEncoderResult = CborNoError;
622         ret = AclToCBORPayload(secAcl, payload, &cborLen);
623         *size = cborLen;
624     }
625     else if (cborEncoderResult != CborNoError)
626     {
627         OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
628         OICFree(outPayload);
629         outPayload = NULL;
630         *size = 0;
631         *payload = NULL;
632         ret = OC_STACK_ERROR;
633     }
634
635     return ret;
636 }
637
638 // This function converts CBOR format to ACL data.
639 // Caller needs to invoke 'free' when done using
640 // It parses { "aclist" : [ { ... } ] } instead of { "aclist" : { "aces" : [ ] } }
641 OicSecAcl_t* CBORPayloadToAcl2(const uint8_t *cborPayload, const size_t size)
642 {
643     if (NULL == cborPayload || 0 == size)
644     {
645         return NULL;
646     }
647     OCStackResult ret = OC_STACK_ERROR;
648     CborValue aclCbor = { .parser = NULL };
649     CborParser parser = { .end = NULL };
650     CborError cborFindResult = CborNoError;
651     cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
652
653     OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
654
655     // Enter ACL Map
656     CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
657     cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap);
658     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
659
660     while (cbor_value_is_valid(&aclMap))
661     {
662         char* tagName = NULL;
663         size_t len = 0;
664         CborType type = cbor_value_get_type(&aclMap);
665         if (type == CborTextStringType)
666         {
667             cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL);
668             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
669             cborFindResult = cbor_value_advance(&aclMap);
670             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
671         }
672         if(tagName)
673         {
674             if (strcmp(tagName, OIC_JSON_ACLIST_NAME)  == 0)
675             {
676                 // Enter ACES Array
677                 CborValue acesArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
678                 cborFindResult = cbor_value_enter_container(&aclMap, &acesArray);
679                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACES Array.");
680
681                 int acesCount = 0;
682                 while (cbor_value_is_valid(&acesArray))
683                 {
684                     acesCount++;
685                     CborValue aceMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
686                     cborFindResult = cbor_value_enter_container(&acesArray, &aceMap);
687                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACE Map.");
688
689                     OicSecAce_t *ace = NULL;
690                     ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
691                     VERIFY_NON_NULL(TAG, ace, ERROR);
692                     LL_APPEND(acl->aces, ace);
693
694                     VERIFY_NON_NULL(TAG, acl, ERROR);
695
696                     while (cbor_value_is_valid(&aceMap))
697                     {
698                         char* name = NULL;
699                         size_t len = 0;
700                         CborType type = cbor_value_get_type(&aceMap);
701                         if (type == CborTextStringType)
702                         {
703                             cborFindResult = cbor_value_dup_text_string(&aceMap, &name, &len, NULL);
704                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACE Map.");
705                             cborFindResult = cbor_value_advance(&aceMap);
706                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACE Map.");
707                         }
708                         if (name)
709                         {
710                             // Subject -- Mandatory
711                             if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
712                             {
713                                 char *subject = NULL;
714                                 cborFindResult = cbor_value_dup_text_string(&aceMap, &subject, &len, NULL);
715                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value.");
716                                 if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0)
717                                 {
718                                     ace->subjectuuid.id[0] = '*';
719                                 }
720                                 else
721                                 {
722                                     OIC_LOG_V(DEBUG, TAG, "Converting subjectuuid = %s to uuid...", subject);
723                                     ret = ConvertStrToUuid(subject, &ace->subjectuuid);
724                                     VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
725                                 }
726                                 OICFree(subject);
727                             }
728
729                             // Resources -- Mandatory
730                             if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
731                             {
732                                 CborValue resources = { .parser = NULL };
733                                 cborFindResult = cbor_value_enter_container(&aceMap, &resources);
734                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array.");
735
736                                 while (cbor_value_is_valid(&resources))
737                                 {
738                                     // rMap
739                                     CborValue rMap = { .parser = NULL  };
740                                     cborFindResult = cbor_value_enter_container(&resources, &rMap);
741                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
742
743                                     OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
744                                     VERIFY_NON_NULL(TAG, rsrc, ERROR);
745                                     LL_APPEND(ace->resources, rsrc);
746
747                                     while(cbor_value_is_valid(&rMap))
748                                     {
749                                         char *rMapName = NULL;
750                                         size_t rMapNameLen = 0;
751                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
752                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
753                                         cborFindResult = cbor_value_advance(&rMap);
754                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
755
756                                         // "href"
757                                         if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
758                                         {
759                                             cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &len, NULL);
760                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
761                                         }
762
763                                         // "rt"
764                                         if (0 == strcmp(OIC_JSON_RT_NAME, rMapName) && cbor_value_is_array(&rMap))
765                                         {
766                                             cbor_value_get_array_length(&rMap, &rsrc->typeLen);
767                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length.");
768                                             VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR);
769
770                                             rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
771                                             VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
772
773                                             CborValue resourceTypes;
774                                             cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes);
775                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array.");
776
777                                             for(size_t i = 0; cbor_value_is_valid(&resourceTypes) && cbor_value_is_text_string(&resourceTypes); i++)
778                                             {
779                                                 size_t readLen = 0;
780                                                 cborFindResult = cbor_value_dup_text_string(&resourceTypes, &(rsrc->types[i]), &readLen, NULL);
781                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding resource type.");
782                                                 cborFindResult = cbor_value_advance(&resourceTypes);
783                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing resource type.");
784                                             }
785                                         }
786
787                                         // "if"
788                                         if (0 == strcmp(OIC_JSON_IF_NAME, rMapName) && cbor_value_is_array(&rMap))
789                                         {
790                                             cbor_value_get_array_length(&rMap, &rsrc->interfaceLen);
791                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length.");
792                                             VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR);
793
794                                             rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
795                                             VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
796
797                                             CborValue interfaces;
798                                             cborFindResult = cbor_value_enter_container(&rMap, &interfaces);
799                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array.");
800
801                                             for(size_t i = 0; cbor_value_is_valid(&interfaces) && cbor_value_is_text_string(&interfaces); i++)
802                                             {
803                                                 size_t readLen = 0;
804                                                 cborFindResult = cbor_value_dup_text_string(&interfaces, &(rsrc->interfaces[i]), &readLen, NULL);
805                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF type.");
806                                                 cborFindResult = cbor_value_advance(&interfaces);
807                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing IF type.");
808                                             }
809                                         }
810
811                                         // "rel"
812                                         if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
813                                         {
814                                             cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->rel, &len, NULL);
815                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
816                                         }
817
818                                         if (cbor_value_is_valid(&rMap))
819                                         {
820                                             cborFindResult = cbor_value_advance(&rMap);
821                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
822                                         }
823                                         OICFree(rMapName);
824                                     }
825
826                                     if (cbor_value_is_valid(&resources))
827                                     {
828                                         cborFindResult = cbor_value_advance(&resources);
829                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
830                                     }
831                                 }
832                             }
833
834                             // Permissions -- Mandatory
835                             if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
836                             {
837                                 uint64_t tmp64;
838                                 cborFindResult = cbor_value_get_uint64(&aceMap, &tmp64);
839                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value.");
840                                 ace->permission = (uint16_t)tmp64;
841                             }
842
843                             // TODO: Need to verfication for validity
844                             // Validity -- Not mandatory
845                             if(strcmp(name, OIC_JSON_VALIDITY_NAME) == 0)
846                             {
847                                 CborValue validitiesMap = {.parser = NULL};
848                                 size_t validitySize = 0;
849
850                                 cborFindResult = cbor_value_get_array_length(&aceMap, &validitySize);
851                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Validity Array Length.");
852
853                                 cborFindResult = cbor_value_enter_container(&aceMap, &validitiesMap);
854                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Array Map.");
855
856                                 while(cbor_value_is_valid(&validitiesMap))
857                                 {
858                                     OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
859                                     VERIFY_NON_NULL(TAG, validity, ERROR);
860                                     LL_APPEND(ace->validities, validity);
861
862                                     CborValue validityMap  = {.parser = NULL};
863                                     //period (string)
864                                     cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap);
865                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map.");
866
867                                     size_t len = 0;
868                                     cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &len, NULL);
869                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value.");
870
871                                     //recurrence (string array)
872                                     CborValue recurrenceMap  = {.parser = NULL};
873                                     cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap);
874                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array.");
875
876                                     cborFindResult = cbor_value_get_array_length(&recurrenceMap, &validity->recurrenceLen);
877                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array.");
878
879                                     validity->recurrences = (char**)OICCalloc(validity->recurrenceLen, sizeof(char*));
880                                     VERIFY_NON_NULL(TAG, validity->recurrences, ERROR);
881
882                                     for(size_t i = 0; cbor_value_is_text_string(&recurrenceMap) && i < validity->recurrenceLen; i++)
883                                     {
884                                         cborFindResult = cbor_value_dup_text_string(&recurrenceMap, &validity->recurrences[i], &len, NULL);
885                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence Value.");
886
887                                         cborFindResult = cbor_value_advance(&recurrenceMap);
888                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a recurrences Array.");
889                                     }
890
891                                     cborFindResult = cbor_value_advance(&validitiesMap);
892                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array.");
893                                 }
894                             }
895                             OICFree(name);
896                         }
897
898                         if (type != CborMapType && cbor_value_is_valid(&aceMap))
899                         {
900                             cborFindResult = cbor_value_advance(&aceMap);
901                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array.");
902                         }
903                     }
904
905                     if (cbor_value_is_valid(&acesArray))
906                     {
907                         cborFindResult = cbor_value_advance(&acesArray);
908                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array.");
909                     }
910                 }
911             }
912
913             //rownerID -- Mandatory
914             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0)
915             {
916                 char *stRowner = NULL;
917                 cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
918                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
919                 OIC_LOG_V(DEBUG, TAG, "Converting rownerid = %s to uuid...", stRowner);
920                 ret = ConvertStrToUuid(stRowner, &acl->rownerID);
921                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
922                 OICFree(stRowner);
923             }
924             OICFree(tagName);
925         }
926         if (cbor_value_is_valid(&aclMap))
927         {
928             cborFindResult = cbor_value_advance(&aclMap);
929             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map.");
930         }
931     }
932
933 exit:
934     if (cborFindResult != CborNoError)
935     {
936         OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl");
937         DeleteACLList(acl);
938         acl = NULL;
939     }
940
941     return acl;
942 }
943
944 // This function converts CBOR format to ACL data.
945 // Caller needs to invoke 'free' when done using
946 // note: This function is used in unit test hence not declared static,
947 OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
948 {
949     if (NULL == cborPayload || 0 == size)
950     {
951         return NULL;
952     }
953     OCStackResult ret = OC_STACK_ERROR;
954     CborValue aclCbor = { .parser = NULL };
955     CborParser parser = { .end = NULL };
956     CborError cborFindResult = CborNoError;
957     cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
958
959     OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
960
961     // Enter ACL Map
962     CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
963     cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap);
964     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
965
966     while (cbor_value_is_valid(&aclMap))
967     {
968         char* tagName = NULL;
969         size_t len = 0;
970         CborType type = cbor_value_get_type(&aclMap);
971         if (type == CborTextStringType)
972         {
973             cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL);
974             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
975             cborFindResult = cbor_value_advance(&aclMap);
976             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
977         }
978         if(tagName)
979         {
980             if (strcmp(tagName, OIC_JSON_ACLIST_NAME)  == 0)
981             {
982                 // Enter ACLIST Map
983                 CborValue aclistMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
984                 cborFindResult = cbor_value_enter_container(&aclMap, &aclistMap);
985                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACLIST Map.");
986
987
988                 while (cbor_value_is_valid(&aclistMap))
989                 {
990                     char* acName = NULL;
991                     size_t readLen = 0;
992                     CborType acType = cbor_value_get_type(&aclistMap);
993                     if (acType == CborTextStringType)
994                     {
995                         cborFindResult = cbor_value_dup_text_string(&aclistMap, &acName, &readLen, NULL);
996                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACLIST Map.");
997                         cborFindResult = cbor_value_advance(&aclistMap);
998                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACLIST Map.");
999                     }
1000
1001                     if(acName)
1002                     {
1003                         if (strcmp(acName, OIC_JSON_ACES_NAME)  == 0)
1004                         {
1005                             // Enter ACES Array
1006                             CborValue acesArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
1007                             cborFindResult = cbor_value_enter_container(&aclistMap, &acesArray);
1008                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACES Array.");
1009
1010                             int acesCount = 0;
1011                             while (cbor_value_is_valid(&acesArray))
1012                             {
1013                                 acesCount++;
1014                                 CborValue aceMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
1015                                 cborFindResult = cbor_value_enter_container(&acesArray, &aceMap);
1016                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACE Map.");
1017
1018                                 OicSecAce_t *ace = NULL;
1019                                 ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
1020                                 VERIFY_NON_NULL(TAG, ace, ERROR);
1021                                 LL_APPEND(acl->aces, ace);
1022
1023                                 VERIFY_NON_NULL(TAG, acl, ERROR);
1024
1025                                 while (cbor_value_is_valid(&aceMap))
1026                                 {
1027                                     char* name = NULL;
1028                                     size_t len = 0;
1029                                     CborType type = cbor_value_get_type(&aceMap);
1030                                     if (type == CborTextStringType)
1031                                     {
1032                                         cborFindResult = cbor_value_dup_text_string(&aceMap, &name, &len, NULL);
1033                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACE Map.");
1034                                         cborFindResult = cbor_value_advance(&aceMap);
1035                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACE Map.");
1036                                     }
1037                                     if (name)
1038                                     {
1039                                         // Subject -- Mandatory
1040                                         if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
1041                                         {
1042                                             char *subject = NULL;
1043                                             cborFindResult = cbor_value_dup_text_string(&aceMap, &subject, &len, NULL);
1044                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value.");
1045                                             if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0)
1046                                             {
1047                                                 ace->subjectuuid.id[0] = '*';
1048                                             }
1049                                             else
1050                                             {
1051                                                 ret = ConvertStrToUuid(subject, &ace->subjectuuid);
1052                                                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1053                                             }
1054                                             OICFree(subject);
1055                                         }
1056
1057                                         // Resources -- Mandatory
1058                                         if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
1059                                         {
1060                                             CborValue resources = { .parser = NULL };
1061                                             cborFindResult = cbor_value_enter_container(&aceMap, &resources);
1062                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array.");
1063
1064                                             while (cbor_value_is_valid(&resources))
1065                                             {
1066                                                 // rMap
1067                                                 CborValue rMap = { .parser = NULL  };
1068                                                 cborFindResult = cbor_value_enter_container(&resources, &rMap);
1069                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
1070
1071                                                 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1072                                                 VERIFY_NON_NULL(TAG, rsrc, ERROR);
1073                                                 LL_APPEND(ace->resources, rsrc);
1074
1075                                                 while(cbor_value_is_valid(&rMap))
1076                                                 {
1077                                                     char *rMapName = NULL;
1078                                                     size_t rMapNameLen = 0;
1079                                                     cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
1080                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
1081                                                     cborFindResult = cbor_value_advance(&rMap);
1082                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
1083
1084                                                     // "href"
1085                                                     if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
1086                                                     {
1087                                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &len, NULL);
1088                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
1089                                                     }
1090
1091                                                     // "rt"
1092                                                     if (0 == strcmp(OIC_JSON_RT_NAME, rMapName) && cbor_value_is_array(&rMap))
1093                                                     {
1094                                                         cbor_value_get_array_length(&rMap, &rsrc->typeLen);
1095                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length.");
1096                                                         VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR);
1097
1098                                                         rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
1099                                                         VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
1100
1101                                                         CborValue resourceTypes;
1102                                                         cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes);
1103                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array.");
1104
1105                                                         for(size_t i = 0; cbor_value_is_valid(&resourceTypes) && cbor_value_is_text_string(&resourceTypes); i++)
1106                                                         {
1107                                                             cborFindResult = cbor_value_dup_text_string(&resourceTypes, &(rsrc->types[i]), &readLen, NULL);
1108                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding resource type.");
1109                                                             cborFindResult = cbor_value_advance(&resourceTypes);
1110                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing resource type.");
1111                                                         }
1112                                                     }
1113
1114                                                     // "if"
1115                                                     if (0 == strcmp(OIC_JSON_IF_NAME, rMapName) && cbor_value_is_array(&rMap))
1116                                                     {
1117                                                         cbor_value_get_array_length(&rMap, &rsrc->interfaceLen);
1118                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length.");
1119                                                         VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR);
1120
1121                                                         rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
1122                                                         VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
1123
1124                                                         CborValue interfaces;
1125                                                         cborFindResult = cbor_value_enter_container(&rMap, &interfaces);
1126                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array.");
1127
1128                                                         for(size_t i = 0; cbor_value_is_valid(&interfaces) && cbor_value_is_text_string(&interfaces); i++)
1129                                                         {
1130                                                             cborFindResult = cbor_value_dup_text_string(&interfaces, &(rsrc->interfaces[i]), &readLen, NULL);
1131                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF type.");
1132                                                             cborFindResult = cbor_value_advance(&interfaces);
1133                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing IF type.");
1134                                                         }
1135                                                     }
1136
1137                                                     // "rel"
1138                                                     if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
1139                                                     {
1140                                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->rel, &len, NULL);
1141                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
1142                                                     }
1143
1144                                                     if (cbor_value_is_valid(&rMap))
1145                                                     {
1146                                                         cborFindResult = cbor_value_advance(&rMap);
1147                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
1148                                                     }
1149                                                     OICFree(rMapName);
1150                                                 }
1151
1152                                                 if (cbor_value_is_valid(&resources))
1153                                                 {
1154                                                     cborFindResult = cbor_value_advance(&resources);
1155                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
1156                                                 }
1157                                             }
1158                                         }
1159
1160                                         // Permissions -- Mandatory
1161                                         if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
1162                                         {
1163                                             uint64_t tmp64;
1164                                             cborFindResult = cbor_value_get_uint64(&aceMap, &tmp64);
1165                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value.");
1166                                             ace->permission = (uint16_t)tmp64;
1167                                         }
1168
1169                                         // TODO: Need to verfication for validity
1170                                         // Validity -- Not mandatory
1171                                         if(strcmp(name, OIC_JSON_VALIDITY_NAME) == 0)
1172                                         {
1173                                             CborValue validitiesMap = {.parser = NULL};
1174                                             size_t validitySize = 0;
1175
1176                                             cborFindResult = cbor_value_get_array_length(&aceMap, &validitySize);
1177                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Validity Array Length.");
1178
1179                                             cborFindResult = cbor_value_enter_container(&aceMap, &validitiesMap);
1180                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Array Map.");
1181
1182                                             while(cbor_value_is_valid(&validitiesMap))
1183                                             {
1184                                                 OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
1185                                                 VERIFY_NON_NULL(TAG, validity, ERROR);
1186                                                 LL_APPEND(ace->validities, validity);
1187
1188                                                 CborValue validityMap  = {.parser = NULL};
1189                                                 //period (string)
1190                                                 cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap);
1191                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map.");
1192
1193                                                 size_t len = 0;
1194                                                 cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &len, NULL);
1195                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value.");
1196
1197                                                 //recurrence (string array)
1198                                                 CborValue recurrenceMap  = {.parser = NULL};
1199                                                 cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap);
1200                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array.");
1201
1202                                                 cborFindResult = cbor_value_get_array_length(&recurrenceMap, &validity->recurrenceLen);
1203                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array.");
1204
1205                                                 validity->recurrences = (char**)OICCalloc(validity->recurrenceLen, sizeof(char*));
1206                                                 VERIFY_NON_NULL(TAG, validity->recurrences, ERROR);
1207
1208                                                 for(size_t i = 0; cbor_value_is_text_string(&recurrenceMap) && i < validity->recurrenceLen; i++)
1209                                                 {
1210                                                     cborFindResult = cbor_value_dup_text_string(&recurrenceMap, &validity->recurrences[i], &len, NULL);
1211                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence Value.");
1212
1213                                                     cborFindResult = cbor_value_advance(&recurrenceMap);
1214                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a recurrences Array.");
1215                                                 }
1216
1217                                                 cborFindResult = cbor_value_advance(&validitiesMap);
1218                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array.");
1219                                             }
1220                                         }
1221                                         OICFree(name);
1222                                     }
1223
1224                                     if (type != CborMapType && cbor_value_is_valid(&aceMap))
1225                                     {
1226                                         cborFindResult = cbor_value_advance(&aceMap);
1227                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array.");
1228                                     }
1229                                 }
1230
1231                                 if (cbor_value_is_valid(&acesArray))
1232                                 {
1233                                     cborFindResult = cbor_value_advance(&acesArray);
1234                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array.");
1235                                 }
1236                             }
1237                         }
1238                         OICFree(acName);
1239                     }
1240
1241                     if (cbor_value_is_valid(&aclistMap))
1242                     {
1243                         cborFindResult = cbor_value_advance(&aclistMap);
1244                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACLIST Map.");
1245                     }
1246                 }
1247             }
1248
1249             //rownerID -- Mandatory
1250             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0)
1251             {
1252                 char *stRowner = NULL;
1253                 cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
1254                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
1255                 ret = ConvertStrToUuid(stRowner, &acl->rownerID);
1256                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1257                 OICFree(stRowner);
1258             }
1259             OICFree(tagName);
1260         }
1261         if (cbor_value_is_valid(&aclMap))
1262         {
1263             cborFindResult = cbor_value_advance(&aclMap);
1264             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map.");
1265         }
1266     }
1267
1268 exit:
1269     if (cborFindResult != CborNoError)
1270     {
1271         OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl");
1272         DeleteACLList(acl);
1273         acl = NULL;
1274     }
1275
1276     return acl;
1277 }
1278
1279 /**
1280  * This method removes ACE for the subject and resource from the ACL
1281  *
1282  * @param subject of the ACE
1283  * @param resource of the ACE
1284  *
1285  * @return
1286  *     ::OC_STACK_RESOURCE_DELETED on success
1287  *     ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
1288  *     ::OC_STACK_INVALID_PARAM on invalid parameter
1289  */
1290 OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
1291 {
1292     OIC_LOG(DEBUG, TAG, "IN RemoveACE");
1293
1294     OicSecAce_t *ace = NULL;
1295     OicSecAce_t *tempAce = NULL;
1296     bool deleteFlag = false;
1297     OCStackResult ret = OC_STACK_NO_RESOURCE;
1298
1299     if (memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
1300     {
1301         OIC_LOG_V(ERROR, TAG, "%s received invalid parameter", __func__ );
1302         return  OC_STACK_INVALID_PARAM;
1303     }
1304
1305     //If resource is NULL then delete all the ACE for the subject.
1306     if (NULL == resource || resource[0] == '\0')
1307     {
1308         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1309         {
1310             if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
1311             {
1312                 LL_DELETE(gAcl->aces, ace);
1313                 FreeACE(ace);
1314                 deleteFlag = true;
1315             }
1316         }
1317     }
1318     else
1319     {
1320         //Looping through ACL to find the right ACE to delete. If the required resource is the only
1321         //resource in the ACE for the subject then delete the whole ACE. If there are more resources
1322         //than the required resource in the ACE, for the subject then just delete the resource from
1323         //the resource array
1324         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1325         {
1326             if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
1327             {
1328                 OicSecRsrc_t* rsrc = NULL;
1329                 OicSecRsrc_t* tempRsrc = NULL;
1330                 LL_FOREACH_SAFE(ace->resources, rsrc, tempRsrc)
1331                 {
1332                     if(strcmp(rsrc->href, resource) == 0)
1333                     {
1334                         LL_DELETE(ace->resources, rsrc);
1335                         FreeRsrc(rsrc);
1336                         deleteFlag = true;
1337                     }
1338                 }
1339
1340                 //If resource list is empty
1341                 if(NULL == ace->resources && true == deleteFlag)
1342                 {
1343                     //Remove the ACE from ACL
1344                     LL_DELETE(gAcl->aces, ace);
1345                     FreeACE(ace);
1346                 }
1347             }
1348         }
1349     }
1350
1351     if (deleteFlag)
1352     {
1353         // In case of unit test do not update persistant storage.
1354         if (memcmp(subject->id, &WILDCARD_SUBJECT_B64_ID, sizeof(subject->id)) == 0)
1355         {
1356             ret = OC_STACK_RESOURCE_DELETED;
1357         }
1358         else
1359         {
1360             uint8_t *payload = NULL;
1361             size_t size = 0;
1362             if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1363             {
1364                 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size))
1365                 {
1366                     ret = OC_STACK_RESOURCE_DELETED;
1367                 }
1368                 OICFree(payload);
1369             }
1370         }
1371     }
1372     return ret;
1373 }
1374
1375 /**
1376  * This method parses the query string received for REST requests and
1377  * retrieves the 'subject' field.
1378  *
1379  * @param query querystring passed in REST request
1380  * @param subject subject UUID parsed from query string
1381  *
1382  * @return true if query parsed successfully and found 'subject', else false.
1383  */
1384 static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
1385 {
1386     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1387
1388     ParseQueryIterInit((unsigned char *) query, &parseIter);
1389
1390     while (GetNextQuery (&parseIter))
1391     {
1392         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, parseIter.attrLen) == 0)
1393         {
1394             char strUuid[STRING_UUID_SIZE] = {0};
1395             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1396             memcpy(strUuid, parseIter.valPos, parseIter.valLen);
1397             OCStackResult res = ConvertStrToUuid(strUuid, subject);
1398             VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
1399             return true;
1400         }
1401     }
1402
1403 exit:
1404     return false;
1405 }
1406
1407 /**
1408  * This method parses the query string received for REST requests and
1409  * retrieves the 'resource' field.
1410  *
1411  * @param query querystring passed in REST request
1412  * @param resource resource parsed from query string
1413  * @param resourceSize size of the memory pointed to resource
1414  *
1415  * @return true if query parsed successfully and found 'resource', else false.
1416  */
1417 static bool GetResourceFromQueryString(const char *query, char *resource, size_t resourceSize)
1418 {
1419     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1420
1421     ParseQueryIterInit((unsigned char *) query, &parseIter);
1422
1423     while (GetNextQuery (&parseIter))
1424     {
1425         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen)
1426                 == 0)
1427         {
1428             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1429             OICStrcpy(resource, resourceSize, (char *) parseIter.valPos);
1430
1431             return true;
1432         }
1433     }
1434
1435 exit:
1436    return false;
1437 }
1438
1439 static size_t GetNumberOfResource(OicSecRsrc_t* resources)
1440 {
1441     size_t ret = 0;
1442     if(resources)
1443     {
1444         OicSecRsrc_t* rsrc = NULL;
1445         LL_FOREACH(resources, rsrc)
1446         {
1447             ret++;
1448         }
1449     }
1450     return ret;
1451 }
1452
1453 static size_t GetNumberOfValidity(OicSecValidity_t* val)
1454 {
1455     size_t ret = 0;
1456
1457     if(val)
1458     {
1459         OicSecValidity_t* temp = NULL;
1460         LL_FOREACH(val, temp)
1461         {
1462             ret++;
1463         }
1464     }
1465     return ret;
1466 }
1467
1468
1469 static bool IsSameStringArray(char** strArr1, size_t strArr1Len,
1470                               char** strArr2, size_t strArr2Len)
1471 {
1472
1473     if(NULL == strArr1 && NULL == strArr2)
1474     {
1475         return true;
1476     }
1477
1478     if(strArr1 && strArr2 && NULL == *strArr1 && NULL == *strArr2)
1479     {
1480         return true;
1481     }
1482
1483     if(strArr1 && strArr2)
1484     {
1485         if(*strArr1 && *strArr2 && strArr1Len == strArr2Len)
1486         {
1487             size_t matchedStr = 0;
1488             for(size_t i = 0; i < strArr1Len; i++)
1489             {
1490                 for(size_t j = 0; j < strArr2Len; j++)
1491                 {
1492                     if(strcmp(strArr1[i], strArr2[j]) == 0)
1493                     {
1494                         matchedStr++;
1495                     }
1496                 }
1497             }
1498             if(matchedStr == strArr1Len)
1499             {
1500                 return true;
1501             }
1502         }
1503     }
1504
1505     return false;
1506 }
1507
1508 static bool IsSameResources(OicSecRsrc_t* resources1, OicSecRsrc_t* resources2)
1509 {
1510     size_t numOfRsrc1 = 0;
1511     size_t numOfRsrc2 = 0;
1512     size_t numOfMatchedRsrc = 0;
1513     OicSecRsrc_t* rsrc1 = NULL;
1514     OicSecRsrc_t* rsrc2 = NULL;
1515
1516     if(NULL == resources1 && NULL == resources2)
1517     {
1518         return true;
1519     }
1520
1521     if(resources1 && resources2)
1522     {
1523         numOfRsrc1 = GetNumberOfResource(resources1);
1524         numOfRsrc2 = GetNumberOfResource(resources2);
1525
1526         if(0 == numOfRsrc1 && 0 == numOfRsrc2)
1527         {
1528             return true;
1529         }
1530
1531         LL_FOREACH(resources1, rsrc1)
1532         {
1533             rsrc2 = NULL;
1534             LL_FOREACH(resources2, rsrc2)
1535             {
1536                 if(rsrc1 && rsrc2)
1537                 {
1538                     if(strcmp(rsrc1->href, rsrc2->href) == 0 &&
1539                         IsSameStringArray(rsrc1->interfaces, rsrc1->interfaceLen,
1540                                           rsrc2->interfaces, rsrc2->interfaceLen) &&
1541                         IsSameStringArray(rsrc1->types, rsrc1->typeLen,
1542                                           rsrc2->types, rsrc2->typeLen))
1543                     {
1544                         // TODO: Update codes to compare 'rel' property
1545                         numOfMatchedRsrc++;
1546                     }
1547                 }
1548             }
1549         }
1550
1551         if(numOfMatchedRsrc == numOfRsrc1)
1552         {
1553             return true;
1554         }
1555     }
1556
1557     return false;
1558 }
1559
1560 static bool IsSameValidities(OicSecValidity_t* validities1, OicSecValidity_t* validities2)
1561 {
1562     size_t numOfVal1 = 0;
1563     size_t numOfVal2 = 0;
1564     size_t numOfMatchedVal = 0;
1565     OicSecValidity_t* val1 = NULL;
1566     OicSecValidity_t* val2 = NULL;
1567
1568     if(NULL == validities1 && NULL == validities2)
1569     {
1570         return true;
1571     }
1572
1573     if(validities1 && validities2)
1574     {
1575         numOfVal1 = GetNumberOfValidity(validities1);
1576         numOfVal2 = GetNumberOfValidity(validities2);
1577         if(0 == numOfVal1 && 0 == numOfVal2)
1578         {
1579             return true;
1580         }
1581
1582         if(numOfVal1 == numOfVal2)
1583         {
1584             LL_FOREACH(validities1, val1)
1585             {
1586                 LL_FOREACH(validities2, val2)
1587                 {
1588                     if(strcmp(val1->period, val2->period) == 0 &&
1589                         IsSameStringArray(val1->recurrences, val1->recurrenceLen,
1590                                           val2->recurrences, val2->recurrenceLen))
1591                     {
1592                         numOfMatchedVal++;
1593                     }
1594                 }
1595             }
1596             if(numOfVal1 == numOfMatchedVal)
1597             {
1598                 return true;
1599             }
1600         }
1601     }
1602
1603     return false;
1604 }
1605
1606 static bool IsSameACE(OicSecAce_t* ace1, OicSecAce_t* ace2)
1607 {
1608     if(ace1 && ace2)
1609     {
1610         if(memcmp(ace1->subjectuuid.id, ace2->subjectuuid.id, sizeof(ace1->subjectuuid.id)) != 0)
1611         {
1612             return false;
1613         }
1614
1615         if(false == IsSameResources(ace1->resources, ace2->resources))
1616         {
1617             return false;
1618         }
1619
1620         if(ace1->permission != ace2->permission)
1621         {
1622             return false;
1623         }
1624
1625         if(false == IsSameValidities(ace1->validities, ace2->validities))
1626         {
1627             return false;
1628         }
1629
1630         return true;
1631     }
1632
1633     return false;
1634 }
1635
1636 static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
1637 {
1638     OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
1639     uint8_t* payload = NULL;
1640     size_t size = 0;
1641     OCEntityHandlerResult ehRet;
1642
1643     OicUuid_t subject = {.id= { 0 } };
1644
1645     // In case, 'subject' field is included in REST request.
1646     if (ehRequest->query && GetSubjectFromQueryString(ehRequest->query, &subject))
1647     {
1648         OIC_LOG(DEBUG,TAG,"'subject' field is inculded in REST request.");
1649         OIC_LOG(DEBUG, TAG, "HandleACLGetRequest processing query");
1650
1651         char resource[MAX_URI_LENGTH] = { 0 };
1652
1653         OicSecAce_t *savePtr = NULL;
1654         const OicSecAce_t *currentAce = NULL;
1655         OicSecAcl_t targetAcl;
1656
1657         memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t));
1658         targetAcl.aces = NULL;
1659
1660         // 'Subject' field is MUST for processing a querystring in REST request.
1661         GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1662
1663         /*
1664          * TODO : Currently, this code only provides one ACE for a Subject.
1665          * Below code needs to be updated for scenarios when Subject have
1666          * multiple ACE's in ACL resource.
1667          */
1668         while ((currentAce = GetACLResourceData(&subject, &savePtr)))
1669         {
1670             targetAcl.aces = (OicSecAce_t*)currentAce;
1671
1672             /*
1673              * If REST querystring contains a specific resource, we need
1674              * to search for that resource in ACE.
1675              */
1676             if (resource[0] != '\0')
1677             {
1678                 OicSecRsrc_t *rsrc = NULL;
1679                 LL_FOREACH(currentAce->resources, rsrc)
1680                 {
1681                     if(0 == strcmp(rsrc->href, resource) ||
1682                         0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
1683                     {
1684                         // Convert ACL data into CBOR format for transmission
1685                         if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1686                         {
1687                             ehRet = OC_EH_ERROR;
1688                         }
1689                         goto exit;
1690                     }
1691                 }
1692             }
1693             else
1694             {
1695                 // Convert ACL data into CBOR format for transmission
1696                 if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1697                 {
1698                     ehRet = OC_EH_ERROR;
1699                 }
1700                 goto exit;
1701             }
1702         }
1703     }
1704     // In case, 'subject' field is not included in REST request.
1705     else
1706     {
1707         OIC_LOG(DEBUG,TAG,"'subject' field is not inculded in REST request.");
1708         // Convert ACL data into CBOR format for transmission.
1709         if (OC_STACK_OK != AclToCBORPayload(gAcl, &payload, &size))
1710         {
1711             ehRet = OC_EH_ERROR;
1712         }
1713     }
1714 exit:
1715     // A device should always have a default acl. Therefore, payload should never be NULL.
1716     ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
1717     OIC_LOG(DEBUG, TAG, "ACL payload with GET response");
1718     OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
1719
1720     //Send payload to request originator
1721     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1722                    OC_EH_OK : OC_EH_ERROR;
1723
1724     OICFree(payload);
1725
1726     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1727     return ehRet;
1728 }
1729
1730 static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *ehRequest)
1731 {
1732     OIC_LOG(INFO, TAG, "HandleACLPostRequest processing the request");
1733     OCEntityHandlerResult ehRet = OC_EH_OK;
1734
1735     // Convert CBOR into ACL data and update to SVR buffers. This will also validate the ACL data received.
1736     uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
1737     size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
1738     if (payload)
1739     {
1740         OicSecAcl_t *newAcl = NULL;
1741         OIC_LOG(DEBUG, TAG, "ACL payload from POST request << ");
1742         OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
1743
1744         newAcl = CBORPayloadToAcl(payload, size);
1745         if (newAcl)
1746         {
1747             bool isNewAce = true;
1748             OicSecAce_t* existAce = NULL;
1749             OicSecAce_t* newAce = NULL;
1750             OicSecAce_t* tempAce1 = NULL;
1751             OicSecAce_t* tempAce2 = NULL;
1752
1753             LL_FOREACH_SAFE(newAcl->aces, newAce, tempAce1)
1754             {
1755                 isNewAce = true;
1756                 LL_FOREACH_SAFE(gAcl->aces, existAce, tempAce2)
1757                 {
1758                     if(IsSameACE(newAce, existAce))
1759                     {
1760                         isNewAce = false;
1761                     }
1762                 }
1763                 if(isNewAce)
1764                 {
1765                     OIC_LOG(DEBUG, TAG, "NEW ACE dectected.");
1766
1767                     OicSecAce_t* insertAce = DuplicateACE(newAce);
1768                     if(insertAce)
1769                     {
1770                         OIC_LOG(DEBUG, TAG, "Appending new ACE..");
1771                         LL_PREPEND(gAcl->aces, insertAce);
1772                     }
1773                     else
1774                     {
1775                         OIC_LOG(ERROR, TAG, "Failed to duplicate ACE.");
1776                         ehRet = OC_EH_ERROR;
1777                     }
1778                 }
1779             }
1780
1781             DeleteACLList(newAcl);
1782
1783             if(OC_EH_OK == ehRet)
1784             {
1785                 size_t size = 0;
1786                 uint8_t *cborPayload = NULL;
1787                 if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size))
1788                 {
1789                     if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK)
1790                     {
1791                         ehRet = OC_EH_CHANGED;
1792                     }
1793                     OICFree(cborPayload);
1794                 }
1795
1796                 if(OC_EH_CHANGED != ehRet)
1797                 {
1798                     ehRet = OC_EH_ERROR;
1799                 }
1800             }
1801         }
1802     }
1803
1804     //Send response to request originator
1805     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1806                    OC_EH_OK : OC_EH_ERROR;
1807
1808     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1809     return ehRet;
1810 }
1811
1812 static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1813 {
1814     OIC_LOG(DEBUG, TAG, "Processing ACLDeleteRequest");
1815     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1816     OicUuid_t subject = { .id= { 0 } };
1817     char resource[MAX_URI_LENGTH] = { 0 };
1818
1819     VERIFY_NON_NULL(TAG, ehRequest->query, ERROR);
1820
1821     // 'Subject' field is MUST for processing a querystring in REST request.
1822     VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR);
1823
1824     GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1825
1826     if (OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
1827     {
1828         ehRet = OC_EH_RESOURCE_DELETED;
1829     }
1830
1831 exit:
1832     //Send response to request originator
1833     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1834                    OC_EH_OK : OC_EH_ERROR;
1835
1836     return ehRet;
1837 }
1838
1839 OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest,
1840         void* callbackParameter)
1841 {
1842     OIC_LOG(DEBUG, TAG, "Received request ACLEntityHandler");
1843     (void)callbackParameter;
1844     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1845
1846     if (!ehRequest)
1847     {
1848         return ehRet;
1849     }
1850
1851     if (flag & OC_REQUEST_FLAG)
1852     {
1853         // TODO :  Handle PUT method
1854         OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1855         switch (ehRequest->method)
1856         {
1857             case OC_REST_GET:
1858                 ehRet = HandleACLGetRequest(ehRequest);
1859                 break;
1860
1861             case OC_REST_POST:
1862                 ehRet = HandleACLPostRequest(ehRequest);
1863                 break;
1864
1865             case OC_REST_DELETE:
1866                 ehRet = HandleACLDeleteRequest(ehRequest);
1867                 break;
1868
1869             default:
1870                 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1871                                OC_EH_OK : OC_EH_ERROR;
1872         }
1873     }
1874
1875     return ehRet;
1876 }
1877
1878 /**
1879  * This internal method is used to create '/oic/sec/acl' resource.
1880  */
1881 static OCStackResult CreateACLResource()
1882 {
1883     OCStackResult ret;
1884
1885     ret = OCCreateResource(&gAclHandle,
1886                            OIC_RSRC_TYPE_SEC_ACL,
1887                            OC_RSRVD_INTERFACE_DEFAULT,
1888                            OIC_RSRC_ACL_URI,
1889                            ACLEntityHandler,
1890                            NULL,
1891                            OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
1892
1893     if (OC_STACK_OK != ret)
1894     {
1895         OIC_LOG(FATAL, TAG, "Unable to instantiate ACL resource");
1896         DeInitACLResource();
1897     }
1898     return ret;
1899 }
1900
1901 // This function sets the default ACL and is defined for the unit test only.
1902 OCStackResult SetDefaultACL(OicSecAcl_t *acl)
1903 {
1904     gAcl = acl;
1905     return OC_STACK_OK;
1906 }
1907
1908 OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
1909 {
1910     OCStackResult ret = OC_STACK_ERROR;
1911     OicUuid_t ownerId = { .id = { 0 } };
1912     OicSecAcl_t *acl = NULL;
1913     OicSecAce_t *ace = NULL;
1914     OicSecRsrc_t* resRsrc = NULL;
1915     OicSecRsrc_t* deviceRsrc = NULL;
1916     OicSecRsrc_t* platformRsrc = NULL;
1917     OicSecRsrc_t* aclRsrc = NULL;
1918     OicSecRsrc_t* doxmRsrc = NULL;
1919     OicSecRsrc_t* pstatRsrc = NULL;
1920
1921     /*
1922      * TODO In future, when new virtual resources will be added in OIC
1923      * specification, Iotivity stack should be able to add them in
1924      * existing SVR database. To support this, we need to add 'versioning'
1925      * mechanism in SVR database.
1926      */
1927
1928     if (!defaultAcl)
1929     {
1930         return OC_STACK_INVALID_PARAM;
1931     }
1932
1933     acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
1934     VERIFY_NON_NULL(TAG, acl, ERROR);
1935
1936     ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
1937     VERIFY_NON_NULL(TAG, ace, ERROR);
1938
1939     LL_APPEND(acl->aces, ace);
1940
1941     // Subject -- Mandatory
1942     memcpy(ace->subjectuuid.id, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t));
1943
1944     // Resources -- Mandatory
1945     // /oic/res
1946     resRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1947     VERIFY_NON_NULL(TAG, resRsrc, ERROR);
1948     LL_APPEND(ace->resources, resRsrc);
1949     resRsrc->href = OICStrdup(OC_RSRVD_WELL_KNOWN_URI);
1950     VERIFY_NON_NULL(TAG, (resRsrc->href), ERROR);
1951     resRsrc->typeLen = 1;
1952     resRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1953     VERIFY_NON_NULL(TAG, resRsrc->types, ERROR);
1954     resRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
1955     VERIFY_NON_NULL(TAG, resRsrc->types[0], ERROR);
1956     resRsrc->interfaceLen = 2;
1957     resRsrc->interfaces = (char**)OICCalloc(resRsrc->interfaceLen, sizeof(char*));
1958     VERIFY_NON_NULL(TAG, resRsrc->interfaces, ERROR);
1959     resRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1960     VERIFY_NON_NULL(TAG, resRsrc->interfaces[0], ERROR);
1961     resRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1962     VERIFY_NON_NULL(TAG, resRsrc->interfaces[1], ERROR);
1963
1964     // /oic/d
1965     deviceRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1966     VERIFY_NON_NULL(TAG, deviceRsrc, ERROR);
1967     LL_APPEND(ace->resources, deviceRsrc);
1968     deviceRsrc->href = OICStrdup(OC_RSRVD_DEVICE_URI);
1969     VERIFY_NON_NULL(TAG, (deviceRsrc->href), ERROR);
1970     deviceRsrc->typeLen = 1;
1971     deviceRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1972     VERIFY_NON_NULL(TAG, deviceRsrc->types, ERROR);
1973     deviceRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_DEVICE);
1974     VERIFY_NON_NULL(TAG, deviceRsrc->types[0], ERROR);
1975     deviceRsrc->interfaceLen = 2;
1976     deviceRsrc->interfaces = (char**)OICCalloc(deviceRsrc->interfaceLen, sizeof(char*));
1977     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces, ERROR);
1978     deviceRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1979     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[0], ERROR);
1980     deviceRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1981     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[1], ERROR);
1982
1983     // /oic/p
1984     platformRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1985     VERIFY_NON_NULL(TAG, platformRsrc, ERROR);
1986     LL_APPEND(ace->resources, platformRsrc);
1987     platformRsrc->href = OICStrdup(OC_RSRVD_PLATFORM_URI);
1988     VERIFY_NON_NULL(TAG, (platformRsrc->href), ERROR);
1989     platformRsrc->typeLen = 1;
1990     platformRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1991     VERIFY_NON_NULL(TAG, platformRsrc->types, ERROR);
1992     platformRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1993     VERIFY_NON_NULL(TAG, platformRsrc->types[0], ERROR);
1994     platformRsrc->interfaceLen = 2;
1995     platformRsrc->interfaces = (char**)OICCalloc(platformRsrc->interfaceLen, sizeof(char*));
1996     VERIFY_NON_NULL(TAG, platformRsrc->interfaces, ERROR);
1997     platformRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1998     VERIFY_NON_NULL(TAG, platformRsrc->interfaces[0], ERROR);
1999     platformRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
2000     VERIFY_NON_NULL(TAG, platformRsrc->interfaces[1], ERROR);
2001
2002     // /oic/sec/acl
2003     aclRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2004     VERIFY_NON_NULL(TAG, aclRsrc, ERROR);
2005     LL_APPEND(ace->resources, aclRsrc);
2006     aclRsrc->href = OICStrdup(OIC_RSRC_ACL_URI);
2007     VERIFY_NON_NULL(TAG, (aclRsrc->href), ERROR);
2008     aclRsrc->typeLen = 1;
2009     aclRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2010     VERIFY_NON_NULL(TAG, aclRsrc->types, ERROR);
2011     aclRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_ACL);
2012     VERIFY_NON_NULL(TAG, aclRsrc->types[0], ERROR);
2013     aclRsrc->interfaceLen = 1;
2014     aclRsrc->interfaces = (char**)OICCalloc(aclRsrc->interfaceLen, sizeof(char*));
2015     VERIFY_NON_NULL(TAG, aclRsrc->interfaces, ERROR);
2016     aclRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2017     VERIFY_NON_NULL(TAG, aclRsrc->interfaces[0], ERROR);
2018
2019     // /oic/sec/doxm
2020     doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2021     VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
2022     LL_APPEND(ace->resources, doxmRsrc);
2023     doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
2024     VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
2025     doxmRsrc->typeLen = 1;
2026     doxmRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2027     VERIFY_NON_NULL(TAG, doxmRsrc->types, ERROR);
2028     doxmRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_DOXM);
2029     VERIFY_NON_NULL(TAG, doxmRsrc->types[0], ERROR);
2030     doxmRsrc->interfaceLen = 1;
2031     doxmRsrc->interfaces = (char**)OICCalloc(doxmRsrc->interfaceLen, sizeof(char*));
2032     VERIFY_NON_NULL(TAG, doxmRsrc->interfaces, ERROR);
2033     doxmRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2034     VERIFY_NON_NULL(TAG, doxmRsrc->interfaces[0], ERROR);
2035
2036     // /oic/sec/pstat
2037     pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2038     VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
2039     LL_APPEND(ace->resources, pstatRsrc);
2040     pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
2041     VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
2042     pstatRsrc->typeLen = 1;
2043     pstatRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2044     VERIFY_NON_NULL(TAG, pstatRsrc->types, ERROR);
2045     pstatRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_PSTAT);
2046     VERIFY_NON_NULL(TAG, pstatRsrc->types[0], ERROR);
2047     pstatRsrc->interfaceLen = 1;
2048     pstatRsrc->interfaces = (char**)OICCalloc(pstatRsrc->interfaceLen, sizeof(char*));
2049     VERIFY_NON_NULL(TAG, pstatRsrc->interfaces, ERROR);
2050     pstatRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2051     VERIFY_NON_NULL(TAG, pstatRsrc->interfaces[0], ERROR);
2052
2053     ace->permission = PERMISSION_READ;
2054     ace->validities = NULL;
2055
2056     // Device ID is the owner of this default ACL
2057     if (GetDoxmResourceData() != NULL)
2058     {
2059         ret = GetDoxmDeviceID(&ownerId);
2060         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
2061     }
2062     else
2063     {
2064         OCRandomUuidResult rdm = OCGenerateUuid(ownerId.id);
2065         VERIFY_SUCCESS(TAG, RAND_UUID_OK == rdm, FATAL);
2066     }
2067
2068     memcpy(&acl->rownerID, &ownerId, sizeof(OicUuid_t));
2069
2070     *defaultAcl = acl;
2071     ret = OC_STACK_OK;
2072
2073 exit:
2074
2075     if (ret != OC_STACK_OK)
2076     {
2077         DeleteACLList(acl);
2078         acl = NULL;
2079     }
2080
2081     return ret;
2082 }
2083
2084 OCStackResult InitACLResource()
2085 {
2086     OCStackResult ret = OC_STACK_ERROR;
2087
2088     uint8_t *data = NULL;
2089     size_t size = 0;
2090     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &data, &size);
2091     // If database read failed
2092     if (OC_STACK_OK != ret)
2093     {
2094         OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
2095     }
2096     if (data)
2097     {
2098         // Read ACL resource from PS
2099         gAcl = CBORPayloadToAcl(data, size);
2100     }
2101     /*
2102      * If SVR database in persistent storage got corrupted or
2103      * is not available for some reason, a default ACL is created
2104      * which allows user to initiate ACL provisioning again.
2105      */
2106     if (!gAcl)
2107     {
2108         ret = GetDefaultACL(&gAcl);
2109         if (OC_STACK_OK != ret)
2110         {
2111             OIC_LOG(ERROR, TAG, "Failed to create default ACL");
2112         }
2113         // TODO Needs to update persistent storage
2114     }
2115     VERIFY_NON_NULL(TAG, gAcl, FATAL);
2116
2117     // Instantiate 'oic.sec.acl'
2118     ret = CreateACLResource();
2119
2120 exit:
2121     if (OC_STACK_OK != ret)
2122     {
2123         DeInitACLResource();
2124     }
2125     return ret;
2126 }
2127
2128 OCStackResult DeInitACLResource()
2129 {
2130     OCStackResult ret =  OCDeleteResource(gAclHandle);
2131     gAclHandle = NULL;
2132
2133     if (gAcl)
2134     {
2135         DeleteACLList(gAcl);
2136         gAcl = NULL;
2137     }
2138     return ret;
2139 }
2140
2141 const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t **savePtr)
2142 {
2143     OicSecAce_t *ace = NULL;
2144     OicSecAce_t *begin = NULL;
2145
2146     if (NULL == subjectId)
2147     {
2148         return NULL;
2149     }
2150
2151     /*
2152      * savePtr MUST point to NULL if this is the 'first' call to retrieve ACL for
2153      * subjectID.
2154      */
2155     if (NULL == *savePtr)
2156     {
2157         begin = gAcl->aces;
2158     }
2159     else
2160     {
2161         /*
2162          * If this is a 'successive' call, search for location pointed by
2163          * savePtr and assign 'begin' to the next ACL after it in the linked
2164          * list and start searching from there.
2165          */
2166         LL_FOREACH(gAcl->aces, ace)
2167         {
2168             if (ace == *savePtr)
2169             {
2170                 begin = ace->next;
2171             }
2172         }
2173     }
2174
2175     // Find the next ACL corresponding to the 'subjectID' and return it.
2176     LL_FOREACH(begin, ace)
2177     {
2178         if (memcmp(&(ace->subjectuuid), subjectId, sizeof(OicUuid_t)) == 0)
2179         {
2180             *savePtr = ace;
2181             return ace;
2182         }
2183     }
2184
2185     // Cleanup in case no ACL is found
2186     *savePtr = NULL;
2187     return NULL;
2188 }
2189
2190 OCStackResult InstallNewACL2(const OicSecAcl_t* acl)
2191 {
2192     OCStackResult ret = OC_STACK_ERROR;
2193
2194     if (!acl)
2195     {
2196         return OC_STACK_INVALID_PARAM;
2197     }
2198
2199     // Append the new ACL to existing ACL
2200     OicSecAce_t* newAce = NULL;
2201     LL_FOREACH(acl->aces, newAce)
2202     {
2203         LL_APPEND(gAcl->aces, newAce);
2204     }
2205
2206     size_t size = 0;
2207     uint8_t *payload = NULL;
2208     ret = AclToCBORPayload(gAcl, &payload, &size);
2209     if (OC_STACK_OK == ret)
2210     {
2211         ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size);
2212         OICFree(payload);
2213     }
2214
2215     return ret;
2216 }
2217
2218 OCStackResult InstallNewACL(const uint8_t *cborPayload, const size_t size)
2219 {
2220     // Convert CBOR format to ACL data. This will also validate the ACL data received.
2221     OicSecAcl_t* newAcl = CBORPayloadToAcl(cborPayload, size);
2222
2223     return InstallNewACL2(newAcl);
2224 }
2225
2226 /**
2227  * This function generates default ACE for security resource in case of owned status.
2228  *
2229  * @return Default ACE for security resource.
2230  */
2231 static OicSecAce_t* GetSecDefaultACE()
2232 {
2233     const int NUM_OF_DOXM_RT = 1;
2234     const int NUM_OF_DOXM_IF  = 1;
2235     const int NUM_OF_PSTAT_RT = 1;
2236     const int NUM_OF_PSTAT_IF = 1;
2237     const char *doxmRt[] = { OIC_RSRC_TYPE_SEC_DOXM };
2238     const char *pstatRt[] = { OIC_RSRC_TYPE_SEC_PSTAT };
2239     const char *doxmIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
2240     const char *pstatIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
2241     OicSecRsrc_t* doxmRsrc = NULL;
2242     OicSecRsrc_t* pstatRsrc = NULL;
2243
2244     //Generate default ACE
2245     OicSecAce_t* newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
2246     VERIFY_NON_NULL(TAG, newAce, ERROR);
2247
2248     // Subject -- Mandatory
2249     memcpy(newAce->subjectuuid.id, &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN);
2250
2251     //Resources -- Mandatory
2252     //Add doxm
2253     doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2254     VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
2255     LL_APPEND(newAce->resources, doxmRsrc);
2256     // pstat-href
2257     doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
2258     VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
2259     // pstat-rt
2260     doxmRsrc->typeLen = NUM_OF_DOXM_RT;
2261     doxmRsrc->types = (char**)OICCalloc(NUM_OF_DOXM_RT, sizeof(char*));
2262     VERIFY_NON_NULL(TAG, (doxmRsrc->types), ERROR);
2263     for(int i = 0; i < NUM_OF_DOXM_RT; i++)
2264     {
2265         doxmRsrc->types[i] = OICStrdup(doxmRt[i]);
2266         VERIFY_NON_NULL(TAG, (doxmRsrc->types[i]), ERROR);
2267     }
2268     // pstat-if
2269     doxmRsrc->interfaceLen = NUM_OF_DOXM_IF;
2270     doxmRsrc->interfaces = (char**)OICCalloc(NUM_OF_DOXM_IF, sizeof(char*));
2271     VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces), ERROR);
2272     for(int i = 0; i < NUM_OF_DOXM_IF; i++)
2273     {
2274         doxmRsrc->interfaces[i] = OICStrdup(doxmIf[i]);
2275         VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces[i]), ERROR);
2276     }
2277
2278     //Add pstat
2279     pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2280     VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
2281     LL_APPEND(newAce->resources, pstatRsrc);
2282     //pstat-href
2283     pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
2284     VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
2285     //pstat-rt
2286     pstatRsrc->typeLen = NUM_OF_PSTAT_RT;
2287     pstatRsrc->types = (char**)OICCalloc(NUM_OF_PSTAT_RT, sizeof(char*));
2288     VERIFY_NON_NULL(TAG, (pstatRsrc->types), ERROR);
2289     for(int i = 0; i < NUM_OF_PSTAT_RT; i++)
2290     {
2291         pstatRsrc->types[i] = OICStrdup(pstatRt[i]);
2292         VERIFY_NON_NULL(TAG, (pstatRsrc->types[i]), ERROR);
2293     }
2294     // pstat-if
2295     pstatRsrc->interfaceLen = NUM_OF_PSTAT_IF;
2296     pstatRsrc->interfaces = (char**)OICCalloc(NUM_OF_PSTAT_IF, sizeof(char*));
2297     VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces), ERROR);
2298     for(int i = 0; i < NUM_OF_PSTAT_IF; i++)
2299     {
2300         pstatRsrc->interfaces[i] = OICStrdup(pstatIf[i]);
2301         VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces[i]), ERROR);
2302     }
2303
2304     // Permissions -- Mandatory
2305     newAce->permission = PERMISSION_READ;
2306
2307     //Period -- Not Mandatory
2308     newAce->validities = NULL;
2309
2310     return newAce;
2311 exit:
2312     FreeACE(newAce);
2313     return NULL;
2314
2315 }
2316
2317 OCStackResult UpdateDefaultSecProvACE()
2318 {
2319     OCStackResult ret = OC_STACK_OK;
2320     OicSecAce_t *ace = NULL;
2321     OicSecAce_t *tempAce = NULL;
2322
2323     if(gAcl)
2324     {
2325         int matchedRsrc = 0;
2326         bool isRemoved = false;
2327
2328         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
2329         {
2330             //Find default security resource ACL
2331             if(memcmp(&ace->subjectuuid, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0 &&
2332                 ((PERMISSION_READ | PERMISSION_WRITE) == ace->permission))
2333             {
2334                 matchedRsrc = 0;
2335
2336                 OicSecRsrc_t* rsrc = NULL;
2337                 LL_FOREACH(ace->resources, rsrc)
2338                 {
2339                     if(strncmp(rsrc->href, OIC_RSRC_DOXM_URI,
2340                                strlen(OIC_RSRC_DOXM_URI) + 1) == 0 ||
2341                        strncmp(rsrc->href, OIC_RSRC_CRED_URI,
2342                                strlen(OIC_RSRC_CRED_URI) + 1) == 0 ||
2343                        strncmp(rsrc->href, OIC_RSRC_ACL_URI,
2344                                strlen(OIC_RSRC_ACL_URI) + 1) == 0 ||
2345                        strncmp(rsrc->href, OIC_RSRC_PSTAT_URI,
2346                                strlen(OIC_RSRC_PSTAT_URI) + 1) == 0)
2347                     {
2348                         matchedRsrc++;
2349                     }
2350                 }
2351
2352                 //If default security resource ACL is detected, delete it.
2353                 if(NUMBER_OF_SEC_PROV_RSCS == matchedRsrc)
2354                 {
2355                     LL_DELETE(gAcl->aces, ace);
2356                     FreeACE(ace);
2357                     isRemoved = true;
2358                 }
2359             }
2360         }
2361
2362         if(isRemoved)
2363         {
2364             /*
2365              * Generate new security resource ACE as follows :
2366              *      subject : "*"
2367              *      resources :  '/oic/sec/doxm', '/oic/sec/pstat'
2368              *      permission : READ
2369              */
2370             OicSecAce_t *secDefaultAce = GetSecDefaultACE();
2371             if (secDefaultAce)
2372             {
2373                 LL_APPEND(gAcl->aces, secDefaultAce);
2374
2375                 size_t size = 0;
2376                 uint8_t *payload = NULL;
2377                 if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
2378                 {
2379                     if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
2380                     {
2381                         ret = OC_STACK_OK;
2382                     }
2383                     OICFree(payload);
2384                 }
2385             }
2386         }
2387     }
2388
2389     return ret;
2390 }
2391
2392 OCStackResult SetAclRownerId(const OicUuid_t* newROwner)
2393 {
2394     OCStackResult ret = OC_STACK_ERROR;
2395     uint8_t *cborPayload = NULL;
2396     size_t size = 0;
2397     OicUuid_t prevId = {.id={0}};
2398
2399     if(NULL == newROwner)
2400     {
2401         ret = OC_STACK_INVALID_PARAM;
2402     }
2403     if(NULL == gAcl)
2404     {
2405         ret = OC_STACK_NO_RESOURCE;
2406     }
2407
2408     if(newROwner && gAcl)
2409     {
2410         memcpy(prevId.id, gAcl->rownerID.id, sizeof(prevId.id));
2411         memcpy(gAcl->rownerID.id, newROwner->id, sizeof(newROwner->id));
2412
2413         ret = AclToCBORPayload(gAcl, &cborPayload, &size);
2414         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2415
2416         ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size);
2417         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2418
2419         OICFree(cborPayload);
2420     }
2421
2422     return ret;
2423
2424 exit:
2425     OICFree(cborPayload);
2426     memcpy(gAcl->rownerID.id, prevId.id, sizeof(prevId.id));
2427     return ret;
2428 }
2429
2430 OCStackResult GetAclRownerId(OicUuid_t *rowneruuid)
2431 {
2432     OCStackResult retVal = OC_STACK_ERROR;
2433     if (gAcl)
2434     {
2435         *rowneruuid = gAcl->rownerID;
2436         retVal = OC_STACK_OK;
2437     }
2438     return retVal;
2439 }